81 lines
2.4 KiB
JavaScript
81 lines
2.4 KiB
JavaScript
import { tool } from 'ai';
|
|
import { z } from "zod";
|
|
import { queryBirdeye } from "./client.js";
|
|
|
|
|
|
const searchTokens = async ({
|
|
keyword,
|
|
verifyToken,
|
|
offset = 0,
|
|
limit = 20
|
|
}) => {
|
|
limit = Math.min(limit, 20);
|
|
|
|
const params = {
|
|
keyword,
|
|
chain: "solana",
|
|
target: "token",
|
|
sort_by: "liquidity",
|
|
sort_type: "desc",
|
|
offset,
|
|
limit
|
|
};
|
|
|
|
if (verifyToken !== undefined) {
|
|
params.verify_token = verifyToken.toString();
|
|
}
|
|
|
|
const response = await queryBirdeye("defi/v3/search", params);
|
|
|
|
const filteredTokens = response.items
|
|
.filter(item => item.type === "token")
|
|
.flatMap(item =>
|
|
item.result
|
|
.filter(token => token.network === "solana")
|
|
.map(({ decimals, ...rest }) => rest)
|
|
);
|
|
|
|
return filteredTokens.length > 0 ? filteredTokens.slice(0, 20) : [];
|
|
};
|
|
|
|
|
|
export const getSearchTokensTool = (userId, chatId,responseId, dataStream) => tool({
|
|
description: "Search for tokens using name or ticker with options to filter verified tokens and paginate. When a user asks about ticker on-chain data and doesn't provide the contract address, look up verified tokens, unless the user says it's a new token.",
|
|
parameters: z.object({
|
|
keyword: z.string().describe("name or ticker to search for tokens"),
|
|
isVerified: z
|
|
.boolean()
|
|
.optional()
|
|
.describe("Optional filter to return only verified tokens"),
|
|
offset: z
|
|
.number()
|
|
.optional()
|
|
.describe("Offset for pagination"),
|
|
limit: z
|
|
.number()
|
|
.optional()
|
|
.describe("Limit for the number of results (max: 20)")
|
|
}),
|
|
execute: async ({ keyword, isVerified, offset, limit }) => {
|
|
try {
|
|
console.log(`${userId} ${chatId} called searchTokens with keyword: ${keyword} | isVerified: ${isVerified} | offset: ${offset} | limit: ${limit}`);
|
|
const verifyToken = isVerified !== undefined ? isVerified : true;
|
|
const tokens = await searchTokens({ keyword, verifyToken, offset, limit });
|
|
if (tokens) {
|
|
tokens.forEach(token => {
|
|
dataStream.writeMessageAnnotation({
|
|
id: responseId,
|
|
tool_type: 'chart',
|
|
content: token.address.toString(),
|
|
});
|
|
});
|
|
|
|
}
|
|
return tokens;
|
|
} catch (error) {
|
|
console.error(`Error occurred while searching for tokens: ${error.message}`);
|
|
return 'Failed to search for tokens.';
|
|
}
|
|
},
|
|
});
|