I built a CLI that does the read-side of Etherscan — balances, tx decoding, gas — so I'd stop opening 14 browser tabs
glnc is a single-binary CLI that does the read-side of Etherscan (balances, tx decoding, gas, positions, history, alerts) from your shell. MIT, free, open source. No
account, no API key required, no telemetry. Install via Homebrew or curl.
$ glnc balance vitalik.eth
$ glnc balance 0xAbc... 0xDef... --watch --positions --nfts
$ glnc tx 0x7c... --json | jq '.data.decoded.calls[] | select(.protocol=="UniswapV3")'
$ glnc gas --json | jq '.data.chains.ethereum.priority.p50'
$ glnc history 0xAbc... --csv > out.csv
What it actually does
balance— 6 chains (Ethereum, Polygon, Arbitrum, Base, plus Solana and Bitcoin as a bonus). Auto-detects chain from address format. ENS resolves. Token auto-discovery via the Uniswap default token list (~1,400 per chain, 24h disk-cached). Solana usesgetTokenAccountsByOwnerfor true full SPL discovery. Multi-wallet portfolios with per-wallet tables + grand total.--watch— re-polls on an interval, prints in-place+0.5 ETH/-100 USDCdeltas, runs in the alternate screen buffer so your scrollback survives Ctrl+C. Snapshots
persisted to~/.glnc/snapshots.json.tx <hash>— decodes calldata for Uniswap V2/V3, Universal Router, ERC-20, WETH, and decodes receipt logs into token movements fromtx.from's perspective.gas— live gas across 9 chains. EVM tiers are p10/p50/p90 priority percentiles from the last 64 blocks viaeth_feeHistory. Includes BTC mempool fees and Solana priority fees.--positions— Aave V3 health factor viagetUserAccountData, Uniswap V3 LP NFT enumeration.--nfts— top collections via Reservoir's public API.history— CSV/JSON export via the Etherscan V2 unified endpoint. Works keyless; optionalGLNC_ETHERSCAN_KEYraises the rate limit.alert— conditional alerts to a webhook. SSRF hardening: scheme allowlist, then DNS-resolved IP checked against RFC1918 / IMDS (169.254.169.254) / loopback / CGNAT /
link-local / IPv6-ULA / IPv4-mapped / 6to4 / NAT64 before every fire. Redirects blocked. Re-validated each invocation, not just at config time.
Dev angle
All RPCs are free public endpoints (publicnode, mainnet.base.org, blockstream, mempool.space, etc.). Prices via CoinGecko with a 60s in-memory cache. Output is stable
versioned JSON envelopes (glnc.balance/v1, glnc.tx/v1, etc.), NDJSON when streaming. --json makes stdout data-only; all chatter goes to stderr, so it pipes cleanly into
jq / xargs / cron without contamination.
Honest tradeoffs
- Token discovery is bounded by the Uniswap default list. Truly exhaustive ERC-20 discovery for an arbitrary wallet needs an archive node or a paid indexer (Alchemy/Moralis) — this is the conscious tradeoff for "no API keys."
- CoinGecko free tier is ~30 req/min. The 60s cache absorbs most of it but you can hit the wall on big portfolios.
- No test framework in the repo yet. It's in the README, calling it out here too.
- BTC and Solana support is in there; not the headline for this sub, just useful if you have a multi-chain treasury.
Repo: https://github.com/aryarahimi1/glnc
Looking for feedback on the JSON envelope shape (before I have to start versioning it for real), additional protocols worth decoding in tx, and whether the SSRF blocklist is
missing anything. Issues and PRs welcome.