--- name: etherscan-api description: This skill should be used when the user asks to "check ETH balance", "query ERC-20 balance", "get wallet balance", "check token holdings", "query Etherscan", or mentions Etherscan API, blockchain balance queries, or multi-chain balance lookups. --- # Etherscan API V2 ## Overview Query blockchain balances using Etherscan's unified API V2. This skill covers: - Native ETH balance queries - ERC-20 token balance queries - Multi-chain support via the `chainid` parameter **Scope:** This skill focuses on balance queries for free-tier accounts. For other Etherscan API features, consult the fallback documentation. ## Prerequisites ### API Key Validation Before making any API call, verify the `ETHERSCAN_API_KEY` environment variable is set: ```bash if [ -z "$ETHERSCAN_API_KEY" ]; then echo "Error: ETHERSCAN_API_KEY environment variable is not set." echo "Get a free API key at: https://etherscan.io/myapikey" exit 1 fi ``` If the environment variable is missing, inform the user and halt execution. ## Chain Inference Do not default to Ethereum Mainnet. Always infer the chain from the user's prompt before making any API call. ### Inference Rules 1. **Explicit chain mention** — If the user mentions a chain name (e.g., "on Polygon", "Arbitrum balance", "Base chain"), use that chain. 2. **Chain-specific tokens** — Some tokens exist primarily on specific chains: - POL → Polygon (137) - ARB → Arbitrum One (42161) - OP → OP Mainnet (10) - AVAX → Avalanche C-Chain (43114) - BNB → BNB Smart Chain (56) - SONIC → Sonic (146) - SEI → Sei (1329) - MON → Monad (143) 3. **Contract address patterns** — If the user provides a contract address, consider asking which chain it's deployed on (many contracts exist on multiple chains). 4. **Testnet keywords** — Words like "testnet", "Sepolia", "Holesky", "Amoy" indicate testnet chains. 5. **Ambiguous cases** — If the chain cannot be inferred, **ask the user** before proceeding. Do not assume Ethereum Mainnet. ### Unsupported Chains If the user references a chain not supported by Etherscan (e.g., Solana, Bitcoin), inform them: ``` The chain "[chain name]" is not supported by Etherscan API V2. Etherscan supports EVM-compatible chains only. For the full list, see: https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains ``` For the complete list of supported chains and their IDs, see `./references/CHAINS.md`. ## API Base URL All requests use the unified V2 endpoint: ``` https://api.etherscan.io/v2/api ``` The `chainid` parameter determines which blockchain to query. ## ETH Balance Query Query native ETH (or native token) balance for an address. ### Endpoint Parameters | Parameter | Required | Default | Description | | --------- | -------- | -------- | ---------------------------------------------------- | | `chainid` | No | `1` | Chain ID (see CHAINS.md) | | `module` | Yes | - | Set to `account` | | `action` | Yes | - | Set to `balance` | | `address` | Yes | - | Wallet address (supports up to 20 comma-separated) | | `tag` | No | `latest` | Block tag (`latest`, `pending`, or hex block number) | | `apikey` | Yes | - | API key from `$ETHERSCAN_API_KEY` | ### Single Address Query ```bash curl -s "https://api.etherscan.io/v2/api?chainid=1&module=account&action=balance&address=0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe&tag=latest&apikey=$ETHERSCAN_API_KEY" ``` ### Multi-Address Query (up to 20) ```bash curl -s "https://api.etherscan.io/v2/api?chainid=1&module=account&action=balancemulti&address=0xaddress1,0xaddress2,0xaddress3&tag=latest&apikey=$ETHERSCAN_API_KEY" ``` ### Response Format **Single address:** ```json { "status": "1", "message": "OK", "result": "172774397764084972158218" } ``` **Multi-address:** ```json { "status": "1", "message": "OK", "result": [ {"account": "0xaddress1", "balance": "1000000000000000000"}, {"account": "0xaddress2", "balance": "2500000000000000000"} ] } ``` ## ERC-20 Token Balance Query Query ERC-20 token balance for an address. ### Endpoint Parameters | Parameter | Required | Default | Description | | ----------------- | -------- | -------- | --------------------------------- | | `chainid` | No | `1` | Chain ID (see CHAINS.md) | | `module` | Yes | - | Set to `account` | | `action` | Yes | - | Set to `tokenbalance` | | `contractaddress` | Yes | - | ERC-20 token contract address | | `address` | Yes | - | Wallet address to query | | `tag` | No | `latest` | Block tag | | `apikey` | Yes | - | API key from `$ETHERSCAN_API_KEY` | ### Example Query ```bash curl -s "https://api.etherscan.io/v2/api?chainid=1&module=account&action=tokenbalance&contractaddress=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&address=0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe&tag=latest&apikey=$ETHERSCAN_API_KEY" ``` ### Response Format ```json { "status": "1", "message": "OK", "result": "135499000000" } ``` ## Multi-Chain Usage Specify the `chainid` parameter to query different blockchains. ### Common Chain IDs (Free Tier) | Chain | Chain ID | | ------------ | -------- | | Ethereum | `1` | | Polygon | `137` | | Arbitrum One | `42161` | | Linea | `59144` | | Scroll | `534352` | | zkSync | `324` | ### Example: Polygon Query ```bash curl -s "https://api.etherscan.io/v2/api?chainid=137&module=account&action=balance&address=0x...&tag=latest&apikey=$ETHERSCAN_API_KEY" ``` For the complete list of supported chains, see `./references/CHAINS.md`. ## Wei to Human-Readable Conversion API responses return balances in the smallest unit (wei for ETH, smallest decimals for tokens). ### ETH Conversion Divide by 10^18: ```bash # Using bc for precision echo "scale=18; 172774397764084972158218 / 1000000000000000000" | bc # Result: 172774.397764084972158218 ``` ### ERC-20 Conversion Divide by 10^decimals (typically 18, but varies per token): | Token | Decimals | | ----------- | -------- | | Most tokens | 18 | | USDC, USDT | 6 | | WBTC | 8 | ```bash # USDC example (6 decimals) echo "scale=6; 135499000000 / 1000000" | bc # Result: 135499.000000 ``` ## Output Formatting **Default behavior:** Present results in a Markdown table: ```markdown | Address | Balance (ETH) | Chain | |---------|---------------|-------| | 0xde0B...7BAe | 172,774.40 | Ethereum | | 0xabc1...2def | 50.25 | Polygon | ``` **User preference:** If the user requests a specific format (JSON, CSV, plain text, etc.), use that format instead. Do not generate a Markdown table when the user specifies an alternative output format. ## Free Tier Limitations The following chains require a paid Etherscan plan and are **not available** on free tier: - Base (`8453`) - OP Mainnet (`10`) - Avalanche C-Chain (`43114`) - BNB Smart Chain (`56`) If a user requests a query on these chains, inform them that a paid plan is required. ## Error Handling ### Common Error Responses | Status | Message | Cause | | ------ | ------------------------ | ------------------------------- | | `0` | `NOTOK` | Invalid API key or rate limited | | `0` | `Invalid address format` | Malformed address | | `0` | `No transactions found` | Address has no activity | ### Rate Limits (Free Tier) - 5 calls/second - 100,000 calls/day If rate limited, wait briefly and retry. ## Reference Files - **`./references/CHAINS.md`** - Complete list of supported chains with chain IDs ## Fallback Documentation For use cases not covered by this skill (transaction history, contract verification, gas estimates, etc.), fetch the AI-friendly documentation: ``` https://docs.etherscan.io/llms.txt ``` Use `WebFetch` to retrieve this documentation for extended API capabilities.