get_token_balance
Check ERC-20 or SPL token balances for wallets across EVM and Solana chains, returning both raw and human-readable amounts.
Instructions
Get the ERC-20 or SPL token balance for a wallet on a specific chain. Returns the raw balance and human-readable balance. Use get_chains to find stablecoin addresses for each chain.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| wallet_id | Yes | Wallet ID to check | |
| token | Yes | Token address (0x-prefixed ERC-20 contract for EVM, Base58 mint for Solana) | |
| chain_id | Yes | Chain ID to check on | |
| decimals | No | Token decimals (6 for USDC, 18 for most tokens) |
Implementation Reference
- src/index.ts:557-595 (handler)The complete get_token_balance tool implementation including registration, schema validation, and handler logic. The handler validates the token address format, makes an API call to fetch the token balance from the AgentWallet API, and formats the response appropriately for both EVM (ERC-20) and Solana (SPL) tokens.
server.tool( 'get_token_balance', 'Get the ERC-20 or SPL token balance for a wallet on a specific chain. ' + 'Returns the raw balance and human-readable balance. ' + 'Use get_chains to find stablecoin addresses for each chain.', { wallet_id: z.number().int().describe('Wallet ID to check'), token: z.string().describe('Token address (0x-prefixed ERC-20 contract for EVM, Base58 mint for Solana)'), chain_id: z.number().int().describe('Chain ID to check on'), decimals: z.number().int().default(18).describe('Token decimals (6 for USDC, 18 for most tokens)'), }, async ({ wallet_id, token, chain_id, decimals }) => { // Validate token address format if (!isValidAddress(token)) { throw new Error(`Invalid token address "${token}". Use 0x-prefixed hex for EVM or Base58 for Solana.`); } const params = `?chain_id=${chain_id}&token=${token}`; const data = await api(`/wallets/${wallet_id}/token-balance${params}`) as { balance_raw?: string; balance_formatted?: string; decimals?: number }; // Solana API returns balance_formatted + decimals directly if (isSolanaChain(chain_id) && data.balance_formatted !== undefined) { return jsonResponse({ ...data, balance: data.balance_formatted, decimals: data.decimals ?? decimals, }); } // EVM: format from raw const balanceFormatted = formatUnits(data.balance_raw || '0', decimals); return jsonResponse({ ...data, balance: balanceFormatted, decimals, }); }, ); - src/index.ts:562-566 (schema)Input schema definition for get_token_balance tool using Zod validation. Defines four parameters: wallet_id (required integer), token (required string for token address), chain_id (required integer), and decimals (optional integer with default value of 18).
{ wallet_id: z.number().int().describe('Wallet ID to check'), token: z.string().describe('Token address (0x-prefixed ERC-20 contract for EVM, Base58 mint for Solana)'), chain_id: z.number().int().describe('Chain ID to check on'), decimals: z.number().int().default(18).describe('Token decimals (6 for USDC, 18 for most tokens)'), - src/index.ts:557-566 (registration)Tool registration with server.tool() call, defining the tool name 'get_token_balance', its description, and input schema.
server.tool( 'get_token_balance', 'Get the ERC-20 or SPL token balance for a wallet on a specific chain. ' + 'Returns the raw balance and human-readable balance. ' + 'Use get_chains to find stablecoin addresses for each chain.', { wallet_id: z.number().int().describe('Wallet ID to check'), token: z.string().describe('Token address (0x-prefixed ERC-20 contract for EVM, Base58 mint for Solana)'), chain_id: z.number().int().describe('Chain ID to check on'), decimals: z.number().int().default(18).describe('Token decimals (6 for USDC, 18 for most tokens)'), - src/index.ts:568-594 (handler)Handler function that executes the get_token_balance logic: validates the token address using isValidAddress(), constructs API query parameters, calls the AgentWallet API endpoint, and formats the response differently for Solana (direct formatted balance) vs EVM (uses formatUnits to convert raw balance).
async ({ wallet_id, token, chain_id, decimals }) => { // Validate token address format if (!isValidAddress(token)) { throw new Error(`Invalid token address "${token}". Use 0x-prefixed hex for EVM or Base58 for Solana.`); } const params = `?chain_id=${chain_id}&token=${token}`; const data = await api(`/wallets/${wallet_id}/token-balance${params}`) as { balance_raw?: string; balance_formatted?: string; decimals?: number }; // Solana API returns balance_formatted + decimals directly if (isSolanaChain(chain_id) && data.balance_formatted !== undefined) { return jsonResponse({ ...data, balance: data.balance_formatted, decimals: data.decimals ?? decimals, }); } // EVM: format from raw const balanceFormatted = formatUnits(data.balance_raw || '0', decimals); return jsonResponse({ ...data, balance: balanceFormatted, decimals, }); }, - src/index.ts:179-185 (helper)Helper function isValidAddress() used by get_token_balance to validate token addresses. Supports both EVM addresses (0x-prefixed 42-character hex) and Solana addresses (Base58 format, 32-44 characters).
function isValidAddress(address: string): boolean { // EVM: 0x + 40 hex chars if (/^0x[a-fA-F0-9]{40}$/.test(address)) return true; // Solana: 32-44 chars, Base58 alphabet (no 0, O, I, l) if (/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address)) return true; return false; }