Token & NFT balances
The native addressBalance() only returns the chain's native coin (ETH, AVAX, etc.). To list every ERC-20, ERC-721, and ERC-1155 an address holds — without having to know the contract addresses up front — connect to an EVM network and call .addressTokenBalances(). ChainGate discovers the contracts the address has interacted with and returns each holding enriched with token metadata (name, symbol, decimals, logo) and, for NFTs, the list of owned token IDs.
addressTokenBalances() is available on Ethereum and Avalanche connectors. It is not available on UTXO networks (Bitcoin, Litecoin, Dogecoin, Bitcoin Cash) or on custom EVM RPC networks (cg.networks.evmRpc(...)), since contract discovery requires ChainGate's indexer.
Example usage
import { importWallet, ChainGate } from 'chaingate'
const wallet = importWallet({ phrase: 'some bip39 phrase ...' })
const cg = new ChainGate()
const ethereum = cg.connect(cg.networks.ethereum, wallet)
const tokens = await ethereum.addressTokenBalances()
for (const token of tokens) {
console.log(token.standard, token.symbol, token.base().toString())
}
What each entry contains
Every item in the returned array is an Amount enriched with token-specific fields:
.standard—'ERC-20','ERC-721','ERC-1155', or'unknown'..contractAddress— Token contract address (with0xprefix)..symbol— Token symbol (e.g.,'USDC','BAYC')..name— Human-readable token name (e.g.,'USD Coin')..base()— Balance in base units as aDecimal(for ERC-20: divided by10^decimals; for ERC-721/1155: token count)..min()— Balance in minimal units as abigint..logoUrl— Token logo URL (when available)..ownedTokens— (ERC-721 / ERC-1155 only) Array of{ id, uri }for each owned token. The rawtokenURIis included; usegetNftMetadata()to decode it.
Filter by token standard
A common pattern is to split holdings into fungible tokens and NFTs:
const tokens = await ethereum.addressTokenBalances()
const erc20s = tokens.filter(t => t.standard === 'ERC-20')
const nfts = tokens.filter(t => t.standard === 'ERC-721' || t.standard === 'ERC-1155')
console.log('Fungible holdings:', erc20s.length)
console.log('NFT collections:', nfts.length)
NFT holdings — list owned token IDs
For ERC-721 / ERC-1155 entries, ownedTokens lists the token IDs the address holds, each with the raw tokenURI string from the contract:
const nfts = (await ethereum.addressTokenBalances())
.filter(t => t.standard === 'ERC-721' || t.standard === 'ERC-1155')
for (const collection of nfts) {
console.log(collection.name, '×', collection.base().toString())
for (const owned of collection.ownedTokens ?? []) {
console.log(' token', owned.id, '→', owned.uri)
}
}
For ERC-721 contracts that don't implement ERC721Enumerable, the balance count is still accurate but ownedTokens may come back empty — the contract simply doesn't expose a way to list IDs.
Decode NFT metadata
ownedTokens[].uri is the raw tokenURI — often an IPFS or data: URI. To get the decoded JSON metadata (name, image, attributes), use the explorer:
const eth = cg.explore(cg.networks.ethereum)
for (const owned of collection.ownedTokens ?? []) {
const meta = await eth.getNftMetadata(collection.contractAddress, owned.id)
console.log(meta.metadata.name, meta.metadata.image)
}
The image field returned by getNftMetadata() is a ChainGate proxy URL that resolves IPFS / data: / HTTPS URIs transparently — drop it directly into an <img src> without writing custom resolution logic.
Different address index
For HD wallets, query a different derivation index:
const tokens = await ethereum.addressTokenBalances({ index: 1 })
Without a wallet — query any address
If you don't need to derive the address from a wallet (e.g., showing the holdings of a third-party address in an explorer UI), use the EVM explorer directly:
const eth = cg.explore(cg.networks.ethereum)
const tokens = await eth.getAddressTokenBalances('0xVitalik...')
The return shape is identical to the connector method.
Key points
- Discovery built in: ChainGate's indexer finds every contract the address has interacted with — no contract list to maintain.
- One call, three standards: ERC-20, ERC-721, and ERC-1155 are returned in the same array; filter by
.standard. - Amount-compatible: Each entry behaves like an
Amount—.base(),.min(), and.symbolall work. - NFT IDs included: ERC-721 / ERC-1155 entries expose
ownedTokens; pair withgetNftMetadata()to fetch decoded JSON. - Native EVM only: Available on Ethereum and Avalanche connectors. Not available on UTXO chains or
evmRpc(...)networks.