Guide

Tokens

getTokenBalances and getTokenTransfers and where they exist. The nonZeroOnly flag. The transfers that never show up in native history.

Holdings

ts
const tokens = await provider.getTokenBalances?.(address, "ethereum", { nonZeroOnly: true });

Etherscan and Blockscout serve it on EVM chains, Helius on Solana through DAS searchAssets, Koios on Cardano for native assets, Horizon on Stellar for the account's trustlines, where contract is the SEP-11 CODE:ISSUER and every asset has seven decimals. Everyone else leaves the method absent and capabilities.tokenBalances false.

ts
interface TokenBalance {
  contract: string;
  symbol: string;
  name?: string;
  decimals: number;
  balance: string; // raw, exact
  balanceFormatted: string;
  priceUsd?: number; // when the explorer quotes one
  valueUsd?: number;
}

nonZeroOnly drops holdings with a zero balance, which is most of them on a wallet that's been airdropped at. Two sizes to know: Blockscout returns the complete holding array in one answer, and a busy wallet makes that several megabytes, so that one read gets sixty seconds unless ProviderConfig.timeout says otherwise. Helius pages a thousand assets at a time and stops after twenty pages.

Transfers

ts
const transfers = await provider.getTokenTransfers?.(address, "ethereum", {
  token: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
  limit: 20,
});

Etherscan, Blockscout and Horizon. The options are TxHistoryOptions plus token, which narrows the list to one contract, on Stellar one CODE:ISSUER. Horizon has no asset filter, so it reads up to five pages of 200 payments and keeps the issued-asset ones. Blockscout walks its cursor to your page like it does for history, up to page * limit <= 1000. Each row is a TokenTransfer with the contract, symbol, decimals, exact value, valueFormatted, from, to, the txHash it happened in, the block and the timestamp.

Why this read exists next to getTxHistory: an ERC-20 transfer somebody sent you is their transaction, not yours. It never shows up in your native history. explorers_token_transfers says as much in its description, so an agent asked "what did this wallet receive" reaches for the right tool instead of reporting an empty list with a straight face.

CLI

shell
explorers tokens vitalik.eth
explorers tokens vitalik.eth -n 100
explorers transfers vitalik.eth -t 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 -n 20

tokens prints fifty holdings unless -n says otherwise, a hundred at most, and its first line counts every one, so 6766 tokens for … on ethereum, 50 listed is a wallet that has been airdropped at, not a short list.

In the explorer

The Explorer caps holdings at fifty rows and transfers at 25 a page, and says how many there were. The agent tools cut holdings at the same fifty. Read the rest with the library.