Terminal-first portfolio viewer for EVM wallets. Shows native + ERC-20 balances across 12 chains with live USD valuations from CoinGecko, in seconds.
npx multichain-portfolio-cli 0xYourAddressOr clone:
git clone https://github.com/swiftnodes/multichain-portfolio-cli
cd multichain-portfolio-cli
cp .env.example .env # add your SwiftNodes API key
npm install
node src/cli.js 0xVitalik...Sample output:
Wallet: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Generated: 2026-05-13T16:01:18.452Z
TOTAL USD: $43,217.86
Ethereum 7.234861 ETH $25,341.21
└─USDC 150.00 $150.00
└─USDT 5000.00 $5,000.05
└─WBTC 0.0500 $4,328.50
Base 0.024100 ETH $84.42
└─USDC 82.50 $82.50
Arbitrum One 1.502000 ETH $5,259.50
Optimism 0.001000 ETH $3.50
BNB Smart Chain 0.000000 BNB $0.00
└─USDT 10.00 $10.00
Polygon 0.000000 POL $0.00
Avalanche 0.000000 AVAX $0.00
Scroll 0.000000 ETH $0.00
Linea 0.000000 ETH $0.00
zkSync Era 0.000000 ETH $0.00
Blast 0.000000 ETH $0.00
Mantle 0.000000 MNT $0.00
- ✅ 12 EVM chains scanned in parallel
- ✅ Native + common ERC-20 token balances (USDC, USDT, DAI, WBTC, etc.)
- ✅ Live USD valuations via CoinGecko's free API
- ✅ Total portfolio value at top
- ✅
--watch <seconds>for refreshing dashboard - ✅
--jsonfor piping into scripts or storing snapshots - ✅
--csvfor spreadsheet imports - ✅
--hide-emptyto focus on chains with holdings - ✅ Falls back gracefully if CoinGecko times out
swiftnodes.io — no email, no KYC, free tier covers this use.
cp .env.example .env
# edit: SWIFTNODES_API_KEY=sn_...npm install
node src/cli.js 0xYourAddressportfolio <address> # one-shot
portfolio <address> --watch 30 # refresh every 30s (dashboard mode)
portfolio <address> --json # JSON output
portfolio <address> --csv > out.csv # CSV output
portfolio <address> --hide-empty # only show chains with holdingsportfolio 0x... --watch 60Clears the screen and refreshes every 60 seconds. Good for a small monitor or a screen tab while you're working.
portfolio 0x... --json | jq '.totalUsd'
# 43217.86
portfolio 0x... --json | jq '.chains[] | select(.error == null) | "\(.chain): \(.tokens | length) tokens"'portfolio 0x... --csv > snapshot.csv
# chain,asset,balance,symbol,priceUsd,valueUsd
# Ethereum,native,7.234861,ETH,3500.5,25325.21
# Ethereum,token,150,USDC,1.0,150.00
# ...Edit src/chains.js and append a new entry:
import { sonic } from "viem/chains";
export const CHAINS = [
// ... existing 12 ...
{
viem: sonic,
slug: "sonic",
nativeId: "sonic-3", // CoinGecko ID for the native token
tokens: { USDC: "0x..." },
},
];SwiftNodes supports 75+ chains. The CoinGecko ID can be found at coingecko.com — search the chain's native token and look at the URL slug.
Each chain's tokens map can hold any ERC-20:
{
viem: base,
slug: "base",
nativeId: "ethereum",
tokens: {
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
DAI: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
cbETH: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22",
AERO: "0x940181a94A35A4569E4529A3CDfB74e38FD98631",
DEGEN: "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed",
},
}- Daily portfolio glance — keep
portfolio 0x... --watch 600in a terminal tab - Snapshot archive — cron to save daily JSON for historical analysis
- CSV export for tax prep —
--csv > 2026-q1.csv - Multi-wallet dashboards — loop over addresses in a shell script
- Onchain net-worth tracking — pipe to a database, build trend charts
12 chains scanned in parallel + 1-3 CoinGecko price calls = typical run time 800ms – 2s.
If you'd rather skip prices (faster, no external dependency on CoinGecko):
portfolio 0x... --json | jq 'del(.chains[].nativePriceUsd, .chains[].nativeValueUsd, .chains[].tokens[].priceUsd, .chains[].tokens[].valueUsd, .totalUsd)'Or fork and remove the prices.js calls in src/portfolio.js.
This tool fires 60+ JSON-RPC calls per run (12 chains × 5 reads each). Most paid providers either:
- Limit you to a few chains per account (you'd need 3-4 accounts to cover 12 chains)
- Charge per request (so a portfolio check costs real money on usage-billed plans)
- Don't support the newer chains here (Blast, Scroll, Mantle, zkSync Era)
SwiftNodes' flat-rate, multi-chain, single-API-key approach is what makes this kind of CLI economically free to run as often as you want.
- Pre-configured tokens only — no automatic ERC-20 discovery. For full coverage, you'd need an indexer (Etherscan API, Alchemy
getTokenBalances, etc.) - No NFTs
- No DeFi positions (Aave deposits, Uniswap V3 LP, staked tokens) — would need protocol-specific code
- CoinGecko free tier rate-limits at ~10-30 calls/minute. For high-frequency portfolio checks, you'd want a paid CoinGecko key or your own price oracle
PRs welcome for any of these.
MIT