Check native or token contract balances for an address using viem. Use when the user asks for wallet balance, native coin balance, ERC-20/token balance, or balance verification for an address.
viemRPC_URLaddress, RPC_URL, chaintokenAddress, decimals, symboladdressrpcUrlchain (for example mainnet, sepolia, or a custom chain object)tokenAddress (contract address)decimals and symbol (if known)isAddress.publicClient.tokenAddress is provided, check native balance:
publicClient.getBalance({ address })formatEthertokenAddress is provided, check contract token balance:
tokenAddress with isAddresspublicClient.readContract with ERC-20 balanceOfdecimals/symbol, then format with formatUnitsimport { createPublicClient, http, isAddress, formatEther } from 'viem'
import { sepolia } from 'viem/chains'
const address = '0xabc...'
if (!isAddress(address)) throw new Error('Invalid address')
const publicClient = createPublicClient({
chain: sepolia,
transport: http(process.env.RPC_URL!),
})
const wei = await publicClient.getBalance({ address })
const eth = formatEther(wei)
console.log({ address, wei: wei.toString(), eth })
import { createPublicClient, http, isAddress, formatUnits } from 'viem'
import { sepolia } from 'viem/chains'
const erc20Abi = [
{
type: 'function',
name: 'balanceOf',
stateMutability: 'view',
inputs: [{ name: 'owner', type: 'address' }],
outputs: [{ name: '', type: 'uint256' }],
},
{
type: 'function',
name: 'decimals',
stateMutability: 'view',
inputs: [],
outputs: [{ name: '', type: 'uint8' }],
},
] as const
const address = '0xabc...'
const tokenAddress = '0xdef...'
if (!isAddress(address) || !isAddress(tokenAddress)) throw new Error('Invalid address')
const publicClient = createPublicClient({
chain: sepolia,
transport: http(process.env.RPC_URL!),
})
const raw = await publicClient.readContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'balanceOf',
args: [address],
})
const decimals = await publicClient.readContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'decimals',
})
const formatted = formatUnits(raw, decimals)
console.log({ address, tokenAddress, raw: raw.toString(), formatted })
<address><chain>native or token<wei> (when mode is native)<formatted> (when mode is native)<tokenAddress> (when mode is token)<raw> (when mode is token)<formatted> (when mode is token)success | failed<verify token decimals|switch RPC|recheck address>action: balancechain: chain id/name usedaddress: queried wallet addresstxHash: nullstatus: success | failednext_step: one clear follow-up actiontokenAddress when token mode is requested.decimals -> return raw amount and optionally format with user-supplied decimals.