historical_token_balances
Retrieve historical token balances for any wallet address at a specific block height or date, supporting native tokens, ERC20 tokens, and optional NFTs across multiple blockchain networks.
Instructions
Commonly used to fetch the historical native and fungible (ERC20) tokens held by an address at a given block height or dateRequired: chainName (blockchain network), address (wallet address). Optional: quoteCurrency for value conversion, blockHeight or date to specify point in time, nft (include NFTs, default false), noNftFetch, noSpam, and noNftAssetMetadata (all default true). Returns token balances as they existed at the specified historical point.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chainName | Yes | The blockchain network to query (e.g., 'eth-mainnet', 'matic-mainnet', 'bsc-mainnet'). | |
| address | Yes | The wallet address to get historical token balances for. Must be a valid blockchain address. | |
| quoteCurrency | No | Currency to quote token values in (e.g., 'USD', 'EUR'). If not specified, uses default quote currency. | |
| nft | No | Include NFT token balances in the response. Default is false. | |
| noNftFetch | No | Skip fetching NFT metadata. Default is true for better performance. | |
| noSpam | No | Filter out spam/scam tokens from results. Default is true. | |
| noNftAssetMetadata | No | Skip fetching NFT asset metadata. Default is true for better performance. | |
| blockHeight | No | Specific block height to get historical balances from. Cannot be used with date parameter. | |
| date | No | Specific date to get historical balances from (YYYY-MM-DD format). Cannot be used with blockHeight parameter. |
Implementation Reference
- src/services/BalanceService.ts:115-211 (handler)The 'historical_token_balances' tool handler definition and implementation using the GoldRush SDK.
server.tool( "historical_token_balances", "Commonly used to fetch the historical native and fungible (ERC20) tokens held by an address at a given block height or date" + "Required: chainName (blockchain network), address (wallet address). " + "Optional: quoteCurrency for value conversion, blockHeight or date to specify point in time, " + "nft (include NFTs, default false), noNftFetch, noSpam, and noNftAssetMetadata (all default true). " + "Returns token balances as they existed at the specified historical point.", { chainName: z .enum(Object.values(ChainName) as [string, ...string[]]) .describe( "The blockchain network to query (e.g., 'eth-mainnet', 'matic-mainnet', 'bsc-mainnet')." ), address: z .string() .describe( "The wallet address to get historical token balances for. Must be a valid blockchain address." ), quoteCurrency: z .enum(Object.values(validQuoteValues) as [string, ...string[]]) .optional() .describe( "Currency to quote token values in (e.g., 'USD', 'EUR'). If not specified, uses default quote currency." ), nft: z .boolean() .optional() .default(false) .describe( "Include NFT token balances in the response. Default is false." ), noNftFetch: z .boolean() .optional() .default(true) .describe( "Skip fetching NFT metadata. Default is true for better performance." ), noSpam: z .boolean() .optional() .default(true) .describe( "Filter out spam/scam tokens from results. Default is true." ), noNftAssetMetadata: z .boolean() .optional() .default(true) .describe( "Skip fetching NFT asset metadata. Default is true for better performance." ), blockHeight: z .number() .optional() .describe( "Specific block height to get historical balances from. Cannot be used with date parameter." ), date: z .string() .optional() .describe( "Specific date to get historical balances from (YYYY-MM-DD format). Cannot be used with blockHeight parameter." ), }, async (params) => { try { const response = await goldRushClient.BalanceService.getHistoricalTokenBalancesForWalletAddress( params.chainName as Chain, params.address, { quoteCurrency: params.quoteCurrency as Quote, nft: params.nft, noNftFetch: params.noNftFetch, noSpam: params.noSpam, noNftAssetMetadata: params.noNftAssetMetadata, blockHeight: params.blockHeight, date: params.date, } ); return { content: [ { type: "text", text: stringifyWithBigInt(response.data), }, ], }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error}` }], isError: true, }; } } ); - Zod schema definition for the 'historical_token_balances' tool inputs.
{ chainName: z .enum(Object.values(ChainName) as [string, ...string[]]) .describe( "The blockchain network to query (e.g., 'eth-mainnet', 'matic-mainnet', 'bsc-mainnet')." ), address: z .string() .describe( "The wallet address to get historical token balances for. Must be a valid blockchain address." ), quoteCurrency: z .enum(Object.values(validQuoteValues) as [string, ...string[]]) .optional() .describe( "Currency to quote token values in (e.g., 'USD', 'EUR'). If not specified, uses default quote currency." ), nft: z .boolean() .optional() .default(false) .describe( "Include NFT token balances in the response. Default is false." ), noNftFetch: z .boolean() .optional() .default(true) .describe( "Skip fetching NFT metadata. Default is true for better performance." ), noSpam: z .boolean() .optional() .default(true) .describe( "Filter out spam/scam tokens from results. Default is true." ), noNftAssetMetadata: z .boolean() .optional() .default(true) .describe( "Skip fetching NFT asset metadata. Default is true for better performance." ), blockHeight: z .number() .optional() .describe( "Specific block height to get historical balances from. Cannot be used with date parameter." ), date: z .string() .optional() .describe( "Specific date to get historical balances from (YYYY-MM-DD format). Cannot be used with blockHeight parameter." ), }, - src/services/BalanceService.ts:115-211 (registration)Registration of the 'historical_token_balances' tool within the MCP server.
server.tool( "historical_token_balances", "Commonly used to fetch the historical native and fungible (ERC20) tokens held by an address at a given block height or date" + "Required: chainName (blockchain network), address (wallet address). " + "Optional: quoteCurrency for value conversion, blockHeight or date to specify point in time, " + "nft (include NFTs, default false), noNftFetch, noSpam, and noNftAssetMetadata (all default true). " + "Returns token balances as they existed at the specified historical point.", { chainName: z .enum(Object.values(ChainName) as [string, ...string[]]) .describe( "The blockchain network to query (e.g., 'eth-mainnet', 'matic-mainnet', 'bsc-mainnet')." ), address: z .string() .describe( "The wallet address to get historical token balances for. Must be a valid blockchain address." ), quoteCurrency: z .enum(Object.values(validQuoteValues) as [string, ...string[]]) .optional() .describe( "Currency to quote token values in (e.g., 'USD', 'EUR'). If not specified, uses default quote currency." ), nft: z .boolean() .optional() .default(false) .describe( "Include NFT token balances in the response. Default is false." ), noNftFetch: z .boolean() .optional() .default(true) .describe( "Skip fetching NFT metadata. Default is true for better performance." ), noSpam: z .boolean() .optional() .default(true) .describe( "Filter out spam/scam tokens from results. Default is true." ), noNftAssetMetadata: z .boolean() .optional() .default(true) .describe( "Skip fetching NFT asset metadata. Default is true for better performance." ), blockHeight: z .number() .optional() .describe( "Specific block height to get historical balances from. Cannot be used with date parameter." ), date: z .string() .optional() .describe( "Specific date to get historical balances from (YYYY-MM-DD format). Cannot be used with blockHeight parameter." ), }, async (params) => { try { const response = await goldRushClient.BalanceService.getHistoricalTokenBalancesForWalletAddress( params.chainName as Chain, params.address, { quoteCurrency: params.quoteCurrency as Quote, nft: params.nft, noNftFetch: params.noNftFetch, noSpam: params.noSpam, noNftAssetMetadata: params.noNftAssetMetadata, blockHeight: params.blockHeight, date: params.date, } ); return { content: [ { type: "text", text: stringifyWithBigInt(response.data), }, ], }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error}` }], isError: true, }; } } );