From b078cc3b3787d9de7da6e8bae1dc901db6f8e41c Mon Sep 17 00:00:00 2001 From: aryan Date: Thu, 19 Dec 2024 05:36:03 +0530 Subject: [PATCH] fix: token address prompt --- src/agent/index.ts | 23 +++++++------ src/langchain/index.ts | 30 ++++------------- src/tools/get_token_data.ts | 64 +++++++++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/agent/index.ts b/src/agent/index.ts index 80b1516..d640eea 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -12,7 +12,8 @@ import { launchPumpFunToken, lendAsset, getTPS, - fetchTokenData, + getTokenDataByAddress, + getTokenDataByTicker, } from "../tools"; import { CollectionOptions, PumpFunTokenOptions } from "../types"; import { DEFAULT_OPTIONS } from "../constants"; @@ -35,7 +36,7 @@ export class SolanaAgentKit { constructor( private_key: string, rpc_url = "https://api.mainnet-beta.solana.com", - openai_api_key: string, + openai_api_key: string ) { this.connection = new Connection(rpc_url); this.wallet = Keypair.fromSecretKey(bs58.decode(private_key)); @@ -49,7 +50,7 @@ export class SolanaAgentKit { } async deployToken( - decimals: number = DEFAULT_OPTIONS.TOKEN_DECIMALS, + decimals: number = DEFAULT_OPTIONS.TOKEN_DECIMALS // initialSupply?: number ) { return deploy_token(this, decimals); @@ -66,7 +67,7 @@ export class SolanaAgentKit { async mintNFT( collectionMint: PublicKey, metadata: Parameters[2], - recipient?: PublicKey, + recipient?: PublicKey ) { return mintCollectionNFT(this, collectionMint, metadata, recipient); } @@ -83,7 +84,7 @@ export class SolanaAgentKit { outputMint: PublicKey, inputAmount: number, inputMint?: PublicKey, - slippageBps: number = DEFAULT_OPTIONS.SLIPPAGE_BPS, + slippageBps: number = DEFAULT_OPTIONS.SLIPPAGE_BPS ) { return trade(this, outputMint, inputAmount, inputMint, slippageBps); } @@ -96,8 +97,12 @@ export class SolanaAgentKit { return getTPS(this); } - async getTokenData(name?: string, symbol?: string, mint?: PublicKey) { - return fetchTokenData(name, symbol, mint); + async getTokenDataByAddress(mint: string) { + return getTokenDataByAddress(new PublicKey(mint)); + } + + async getTokenDataByTicker(ticker: string) { + return getTokenDataByTicker(ticker); } async launchPumpFunToken( @@ -105,7 +110,7 @@ export class SolanaAgentKit { tokenTicker: string, description: string, imageUrl: string, - options?: PumpFunTokenOptions, + options?: PumpFunTokenOptions ) { return launchPumpFunToken( this, @@ -113,7 +118,7 @@ export class SolanaAgentKit { tokenTicker, description, imageUrl, - options, + options ); } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 3d4896d..fb4f94a 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -572,39 +572,21 @@ export class SolanaTPSCalculatorTool extends Tool { export class SolanaTokenDataTool extends Tool { name = "solana_token_data"; - description = `Get the token data for a given token mint address, token name or symbol. + description = `Get the token data for a given token mint address - Inputs: Either one of mintAddress, tokenName or symbol is required. - mintAddress: string, eg "So11111111111111111111111111111111111111112" (optional) - tokenName: string, eg "USD Coin" (optional) - symbol: string, eg "USDC" (optional)`; + Inputs: mintAddress is required. + mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)`; constructor(private solanaKit: SolanaAgentKit) { super(); } - private validateInput(input: any): void { - if (!input.mintAddress && !input.tokenName && !input.symbol) { - throw new Error("Either mintAddress, tokenName or symbol is required"); - } - if ( - input.mintAddress && - typeof input.mintAddress !== "string" && - !PublicKey.isOnCurve(input.mintAddress) - ) { - throw new Error("mintAddress must be a valid base58 string"); - } - } - protected async _call(input: string): Promise { try { - const parsedInput = JSON.parse(input); - this.validateInput(parsedInput); + const parsedInput = input.trim(); - const tokenData = await this.solanaKit.getTokenData( - parsedInput.tokenName, - parsedInput.symbol, - new PublicKey(parsedInput.mintAddress), + const tokenData = await this.solanaKit.getTokenDataByAddress( + parsedInput ); return JSON.stringify({ diff --git a/src/tools/get_token_data.ts b/src/tools/get_token_data.ts index ed8769e..31d6032 100644 --- a/src/tools/get_token_data.ts +++ b/src/tools/get_token_data.ts @@ -1,14 +1,12 @@ import { PublicKey } from "@solana/web3.js"; import { JupiterTokenData } from "../types"; -export async function fetchTokenData( - name?: string, - symbol?: string, - mint?: PublicKey, +export async function getTokenDataByAddress( + mint: PublicKey, ): Promise { try { - if (!mint && !symbol && !name) { - throw new Error("Either mint address, name or symbol is required"); + if (!mint) { + throw new Error("Mint address is required"); } const response = await fetch("https://tokens.jup.ag/tokens?tags=verified", { @@ -20,19 +18,53 @@ export async function fetchTokenData( const data = (await response.json()) as JupiterTokenData[]; const token = data.find((token: JupiterTokenData) => { - if (mint) { - return token.address === mint.toBase58(); - } - if (symbol) { - return token.symbol === symbol; - } - if (name) { - return token.name === name; - } - return false; + return token.address === mint.toBase58(); }); return token; } catch (error: any) { throw new Error(`Error fetching token data: ${error.message}`); } } + +export async function getTokenAddressFromTicker( + ticker: string +): Promise { + try { + const response = await fetch( + `https://api.dexscreener.com/latest/dex/search?q=${ticker}` + ); + const data = await response.json(); + + if (!data.pairs || data.pairs.length === 0) { + return null; + } + + // Filter for Solana pairs only and sort by FDV + let solanaPairs = data.pairs + .filter((pair: any) => pair.chainId === "solana") + .sort((a: any, b: any) => (b.fdv || 0) - (a.fdv || 0)); + + console.log("solanaPairs", solanaPairs); + + solanaPairs = solanaPairs.filter( + (pair: any) => + pair.baseToken.symbol.toLowerCase() === ticker.toLowerCase() + ); + + // Return the address of the highest FDV Solana pair + return solanaPairs[0].baseToken.address; + } catch (error) { + console.error("Error fetching token address from DexScreener:", error); + return null; + } +} + +export async function getTokenDataByTicker( + ticker: string +): Promise { + const address = await getTokenAddressFromTicker(ticker); + if (!address) { + throw new Error(`Token address not found for ticker: ${ticker}`); + } + return getTokenDataByAddress(new PublicKey(address)); +} \ No newline at end of file