Field notes
How to check every token in a wallet across 9 chains, from the terminal
by Arya Rahimi · · 8 min read
To list every token in a crypto wallet from the command line, run glnc balance <address>. You get a per-token table with amounts and USD values, no browser, no account, and no API key. glnc reads the chain from the address format and discovers tokens for you, so a single line answers the question that usually takes a dozen explorer tabs. The rest of this note is precise about what the totals do and do not include, so you can quote the command and the caveats without being wrong.
The one-liner and what the table shows
Paste an address after glnc balance and you get a table per chain, grouped by asset:
glnc balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045The columns are the asset symbol (with a truncated contract address for tokens), the on-chain amount as a precise string, and the USD value at the price glnc could find. Each chain prints its own header with a token count, and the run ends with a grand total. The numbers here are example output, not a claim about a live wallet. If glnc is not installed yet, brew install aryarahimi1/glnc/glnc drops in a prebuilt binary; the quickstart covers the alternatives.
No --chain flag needed: address auto-detection
You did not pass --chain above because glnc reads the chain from the address format. An 0x address followed by 40 hex characters is queried on all seven EVM chains in one shot. An ENS name resolves first, then runs the same way. A Bitcoin address routes to Bitcoin; a base58 Solana address routes to Solana.
glnc balance vitalik.ethWorth being exact: one EVM address covers the seven EVM chains (Ethereum, Polygon, Arbitrum, Base, Optimism, zkSync, Linea), not Bitcoin or Solana, because those use different address formats. To touch all nine chains in a single command, pass an EVM address, a Bitcoin address, and a Solana address together (see the multi-wallet section below). The flags you will reach for most:
| Flag | Description |
|---|---|
--chain <name> | Query one chain instead of auto-detecting from the address. Accepts aliases like eth, arb, op, zk. |
--show-unpriced | Show balances whose price was withheld (Linea and zkSync ERC-20 tokens are fail-closed by default). |
--json | Emit the stable, versioned envelope on stdout instead of the human table. |
--verbose / -v | Print full addresses instead of the truncated 0xA0b8…eB48 form. |
--no-color | Disable ANSI color. NO_COLOR and --json also turn it off. |
How token discovery actually works
glnc does not just check USDC and USDT. On first run it fetches the Uniswap default token list and caches it at ~/.glnc/token-cache.json, refreshed every 24 hours. That covers about 1,400 tokens across the supported EVM chains, each a standard ERC-20 (EIP-20) contract. The token-list format itself is the community Token Lists standard, which is why the same approach works uniformly across EVM chains.
Two filters shape what you see. Tokens with a known price below $1.00 are treated as dust and hidden, so a wallet full of airdropped junk stays readable. Tokens with an unknown price are always shown, with a dash in the USD column, so nothing priced is silently dropped.
Solana works differently and better. Instead of a curated list, glnc calls getTokenAccountsByOwner, which enumerates every SPL token account the wallet owns directly from the RPC. On Solana, discovery is effectively complete; on EVM chains it is bounded by the token list.
Multiple wallets at once
Pass more than one address and glnc prints a table per wallet, then a single portfolio total across all of them. This is also how you cover all nine chains in one command: mix an EVM address, a Bitcoin address, and a Solana address.
glnc balance vitalik.eth bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh 7v91N7iZ9mNicL8WfG6cgSCKyRXydQjLh6UYBWwm6y1QIn the JSON form, each wallet is an entry under data.wallets[] with its own grandTotalUsd, and the portfolio figure is data.totalUsd at the top level.
Reading the totals honestly
The grand total is a sum of the priced balances glnc could see, and the interface is careful to tell you when that sum is incomplete. The + suffix on $663,208.68+ means at least one held asset had no price, so the real figure is at least that much. Treat a total with a + as a floor, not an exact number.
Unpriced assets are not dropped; they print their amount with a dash where the USD value would be. There is also a deliberate safety choice on two chains: native balances on Linea and zkSync are priced normally, but ERC-20 token prices there are fail-closed until canonical token addresses are independently verified. That prevents a spoofed token from inheriting a real token's price. When you want to see those withheld balances anyway, add --show-unpriced:
glnc balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --chain linea --show-unpricedPipe it: JSON into jq, and a CSV in one line
Add --json and stdout becomes a stable, versioned envelope, documented in the JSON reference. All the human chatter moves to stderr, so the pipe stays clean. Pull a single number with jq:
glnc balance vitalik.eth --json | jq '.data.wallets[0].grandTotalUsd'Flatten every holding across every chain into a CSV with one line. Each row is chain, symbol, amount, USD value:
glnc balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --json | jq -r '.data.wallets[].chains[] as $c | $c.assets[] | [$c.chain, .symbol, .amount, .valueUsd] | @csv' > holdings.csvWhen a script needs to know which symbols came back without a price, the envelope tells you directly under meta:
glnc balance vitalik.eth --json | jq -r '.meta.sources.prices.unpriced[]'Gate any automation on meta.partial before you trust the numbers; it flips to true when an RPC, price feed, or the token list degraded for that call.
Caveats worth stating plainly
Two honest limits keep this from being magic. First, on EVM chains a token that is not on the Uniswap default token list is not shown at all. A token could sit in the wallet and never appear, because glnc only asks about contracts it knows. True full discovery would require an archive node or a paid indexer; that is an explicit trade for staying free and keyless.
Second, USD prices come from the CoinGecko free public API, with a short in-memory cache to stay under its rate limit. A token CoinGecko does not know shows a dash, not a wrong number, and a sudden market move is visible on the next call rather than the current one.
None of that requires a key. NFT holdings and transaction history can take an optional key to lift rate limits, but listing tokens never does. That is the whole point: one command, any wallet, no account.
FAQ
Do I need an API key or an account to check wallet tokens? No. The core balance command runs against free public RPC endpoints with no account and nothing phoned home. Optional extras like NFT holdings or history can take a key to lift rate limits; listing tokens does not.
How many tokens and which chains does it cover? Nine chains: Ethereum, Polygon, Arbitrum, Base, Optimism, zkSync, Linea, Solana, and Bitcoin. On EVM chains it auto-discovers about 1,400 tokens per chain from the Uniswap default token list; on Solana it finds every SPL token via getTokenAccountsByOwner.
Why are some of my tokens missing from the output? Two reasons. Tokens with a known price under $1.00 are dust-filtered, and tokens not on the Uniswap default token list are not shown at all. Full discovery would need an archive node or a paid indexer.
What does the + on the grand total mean? Some asset prices were unavailable, so the total is a floor, not an exact figure. Unpriced tokens print a dash in the USD column and still show their amount.
Can I get the data as JSON for a script? Yes. Add --json for a stable, versioned envelope on stdout that pipes cleanly into jq; the one-liner above turns it into a holdings CSV.
Next, read the full balance command reference, the chain support matrix, or how glnc compares to Etherscan.