EVM
The EVM integration provides direct access to live on-chain state via viem. Unlike Blockscout (which queries an indexed database), EVM tools talk to RPC nodes and return the current state of the chain at the latest block.
All EVM tools use the evm_ prefix. No configuration is required beyond having a valid RPC endpoint, which defaults to public nodes for each supported chain.
When to Use EVM Tools
EVM tools are the right choice when you need:
- Current balances (native or ERC-20)
- Live contract storage reads
- Contract function calls (view functions)
- State-changing transactions (transfers, contract writes)
- Gas estimation before submitting a transaction
- ENS name resolution
- Multicall batching for efficiency
For historical data (transaction history, past balances, token transfers), use Blockscout instead.
Tools
Balance Queries
| Tool | Description |
|---|---|
evm_get_balance | Native token balance (ETH, MATIC, etc.) for an address |
evm_get_token_balance | ERC-20 token balance for an address |
evm_get_balances_batch | Multiple balances in a single multicall |
// Native balance
evm_get_balance({
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
chainId: 1,
})
// Returns: { balance: "1234567890000000000", formatted: "1.234567890", symbol: "ETH" }
// ERC-20 balance
evm_get_token_balance({
tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
walletAddress: "0xYourAddress",
chainId: 8453,
})
// Returns: { balance: "1500000000", formatted: "1500.0", symbol: "USDC", decimals: 6 }
Contract Reads
| Tool | Description |
|---|---|
evm_read_contract | Call a view/pure function on any contract |
evm_multicall | Batch multiple read calls into a single RPC request |
evm_get_storage_at | Read raw storage slot value |
// Read a contract function
evm_read_contract({
contractAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
abi: [{ name: "totalSupply", type: "function", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" }],
functionName: "totalSupply",
chainId: 8453,
})
// Returns: { result: "4500000000000000" }
// Multicall: batch reads
evm_multicall({
calls: [
{
contractAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
functionName: "balanceOf",
args: ["0xYourAddress"],
},
{
contractAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
functionName: "totalSupply",
args: [],
},
],
chainId: 8453,
})
Multicall batches all reads into a single RPC call, which is significantly faster than sequential reads when you need multiple values.
Contract Writes
| Tool | Description |
|---|---|
evm_write_contract | Call a state-changing function on a contract |
evm_send_transaction | Send a raw transaction with custom calldata |
evm_write_contract({
contractAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
abi: [{ name: "approve", type: "function", inputs: [{ name: "spender", type: "address" }, { name: "amount", type: "uint256" }], outputs: [{ type: "bool" }], stateMutability: "nonpayable" }],
functionName: "approve",
args: ["0xSpenderAddress", "1000000000"],
chainId: 8453,
})
Write operations require a configured wallet (PRIVATE_KEY or MNEMONIC). They go through the confirmation queue when CONFIRM_WRITES=true.
Transfers
| Tool | Description |
|---|---|
evm_transfer | Send native tokens (ETH, MATIC, etc.) to an address |
evm_transfer_token | Send ERC-20 tokens to an address |
// Send ETH
evm_transfer({
to: "0xRecipientAddress",
amount: "0.1", // in ETH, not wei
chainId: 1,
})
// Send USDC
evm_transfer_token({
tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
to: "0xRecipientAddress",
amount: "100", // in token units (100 USDC)
chainId: 8453,
})
ENS Resolution
| Tool | Description |
|---|---|
evm_resolve_ens | Resolve an ENS name to an Ethereum address |
evm_reverse_ens | Find the primary ENS name for an address |
evm_resolve_ens({
name: "vitalik.eth",
})
// Returns: { address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" }
evm_reverse_ens({
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
})
// Returns: { name: "vitalik.eth" }
ENS resolution always queries Ethereum mainnet regardless of the chainId parameter, since ENS is deployed on Ethereum.
Gas Estimation
| Tool | Description |
|---|---|
evm_estimate_gas | Estimate gas for a transaction |
evm_get_gas_price | Current gas price (base fee + priority fee) |
evm_get_fee_history | Historical fee data for gas price analysis |
evm_estimate_gas({
to: "0xContractAddress",
data: "0xabcdef...",
value: "0",
chainId: 8453,
})
// Returns: { gasLimit: "85000", gasPriceGwei: "0.05", estimatedCostEth: "0.00000425" }
evm_get_gas_price({
chainId: 8453,
})
// Returns: { baseFeeGwei: "0.04", maxPriorityFeeGwei: "0.01", maxFeeGwei: "0.09" }
Chain and Block Info
| Tool | Description |
|---|---|
evm_get_block_number | Current block number |
evm_get_block | Block details by number or hash |
evm_get_chain_id | Chain ID of the connected network |
RPC Configuration
By default, web3agent uses public RPC endpoints for each supported chain. These work for most use cases but may have rate limits under heavy load.
Override the RPC for the default chain:
RPC_URL=https://mainnet.infura.io/v3/your_key npx web3agent
For multi-chain setups, set chain-specific RPC URLs:
RPC_URL_1=https://mainnet.infura.io/v3/your_key # Ethereum
RPC_URL_8453=https://base-mainnet.infura.io/v3/your_key # Base
RPC_URL_42161=https://arbitrum-mainnet.infura.io/v3/your_key # Arbitrum
Write Operations and Confirmation
All state-changing EVM tools (writes, transfers, contract calls) are gated by the confirmation system when CONFIRM_WRITES=true (the default).
The flow:
1. AI agent calls evm_transfer or evm_write_contract
2. Tool queues the operation and returns a confirmation ID
3. AI agent calls transaction_confirm with the ID
4. Transaction executes and returns the tx hash
For autonomous agents that don't need human approval:
CONFIRM_WRITES=false npx web3agent
Policy Engine
When POLICY_ENABLED=true, write operations are also evaluated against spending limits before execution:
POLICY_ENABLED=true
POLICY_MAX_SINGLE_TX_USD=1000 # max per transaction
POLICY_MAX_DAILY_USD=5000 # max per day
Transactions that exceed the limits are rejected with a clear error message. The policy engine tracks USD value using live token prices.
Supported Chains
EVM tools work on all 17 chains that web3agent supports:
Ethereum (1), Base (8453), Arbitrum (42161), Optimism (10), Polygon (137), Linea (59144), BSC (56), Avalanche (43114), zkSync Era (324), Scroll (534352), Mode (34443), Blast (81457), Mantle (5000), Celo (42220), Gnosis (100), Sepolia (11155111), Base Sepolia (84532).
The default chain is Base (8453). Override per-call with chainId or globally with the CHAIN_ID environment variable.