get_multiple_token_balances
Retrieve token balances and their USD values for a specified wallet address using SailFish as the price oracle. Supports multiple token contract addresses for efficient balance tracking.
Instructions
Get multiple token balances for a wallet address with USD values using SailFish as price oracle
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tokenAddresses | Yes | List of token contract addresses | |
| walletAddress | Yes | Wallet address to check |
Implementation Reference
- src/blockchain.ts:145-185 (handler)Core handler function that implements the tool logic: fetches balances for multiple ERC20 tokens using getTokenBalance helper, handles individual token errors gracefully, returns array of balance info including metadata and optional USD value from SailFish subgraph.export async function getMultipleTokenBalances( tokenAddresses: string[], walletAddress: string ): Promise<Array<{ tokenAddress: string, balance: string, decimals: number, symbol: string, name: string, formattedBalance: string, usdValue?: string }>> { try { const results = await Promise.all( tokenAddresses.map(async (tokenAddress) => { try { const tokenBalance = await getTokenBalance(tokenAddress, walletAddress); return { tokenAddress, ...tokenBalance }; } catch (error) { console.error(`Error fetching balance for token ${tokenAddress}:`, error); return { tokenAddress, balance: '0', decimals: 18, symbol: 'UNKNOWN', name: 'Unknown Token', formattedBalance: '0' }; } }) ); return results; } catch (error) { console.error('Error fetching multiple token balances:', error); throw error; } }
- src/index.ts:332-351 (registration)Tool registration in ListToolsRequestHandler: defines the tool name, description, and input schema for validation.name: 'get_multiple_token_balances', description: 'Get multiple token balances for a wallet address with USD values using SailFish as price oracle', inputSchema: { type: 'object', properties: { tokenAddresses: { type: 'array', items: { type: 'string', }, description: 'List of token contract addresses', }, walletAddress: { type: 'string', description: 'Wallet address to check', }, }, required: ['tokenAddresses', 'walletAddress'], }, },
- src/index.ts:907-925 (handler)MCP tool dispatch handler in CallToolRequestHandler: validates input params and delegates to blockchain.getMultipleTokenBalances, formats response as MCP content.case 'get_multiple_token_balances': { if (!args.tokenAddresses || !Array.isArray(args.tokenAddresses)) { throw new McpError(ErrorCode.InvalidParams, 'Token addresses array is required'); } if (!args.walletAddress || typeof args.walletAddress !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Wallet address is required'); } const balances = await blockchain.getMultipleTokenBalances(args.tokenAddresses, args.walletAddress); return { content: [ { type: 'text', text: JSON.stringify(balances, null, 2), }, ], };
- src/blockchain.ts:88-142 (helper)Helper function used by getMultipleTokenBalances to fetch individual token balance, metadata, formatted amount, and USD value via SailFish subgraph.export async function getTokenBalance( tokenAddress: string, walletAddress: string ): Promise<{ balance: string, decimals: number, symbol: string, name: string, formattedBalance: string, usdValue?: string }> { try { const provider = getProvider(); const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, provider); // Get token details const [balance, decimals, symbol, name] = await Promise.all([ tokenContract.balanceOf(walletAddress), tokenContract.decimals(), tokenContract.symbol(), tokenContract.name() ]); // Convert BigInt to string and number const balanceStr = bigIntToString(balance); const decimalsNum = Number(decimals); const formattedBalance = ethers.formatUnits(balance, decimalsNum); // Try to get USD value from SailFish let usdValue: string | undefined; try { const tokenPrice = await subgraph.getTokenPrice(tokenAddress); if (tokenPrice) { const valueInUsd = parseFloat(formattedBalance) * parseFloat(tokenPrice); usdValue = valueInUsd.toString(); } } catch (error) { console.error('Error fetching token price:', error); // Continue without USD value } return { balance: balanceStr, decimals: decimalsNum, symbol: String(symbol), name: String(name), formattedBalance, usdValue }; } catch (error) { console.error('Error fetching token balance:', error); throw error; } }