Skip to content

feat(scripts): pnpm balances — read treasury USDC across all chains#15

Merged
fielding merged 1 commit into
mainfrom
feat/balances-script
Apr 26, 2026
Merged

feat(scripts): pnpm balances — read treasury USDC across all chains#15
fielding merged 1 commit into
mainfrom
feat/balances-script

Conversation

@fielding

Copy link
Copy Markdown
Owner

Summary

Stacked on top of the multi-EVM stack (#14 → ... → main). Adds a read-only CLI for checking treasury balances across every mainnet chain in the registry.

pnpm balances              # checks the default treasury
pnpm balances 0xAddr       # checks any address (e.g. cold-storage sweep target)

Output

  Address  0x847F640bE052b0700C31F72Dce622F4C6286934E

  Ethereum             0.000000 USDC (HTTP request failed. Status: 429 URL: https://eth.merkle.io/)
  Optimism             0.000000 USDC
  BNB Chain            0.000000 USDC
  Polygon              0.000000 USDC
  Base                 0.050113 USDC
  Arbitrum One         0.000000 USDC
  Avalanche            0.000000 USDC
  ──────────────────────────────────
  Total                0.050113 USDC

(Above is from a real run against the live treasury — Base shows ~$0.05 in real broker fees collected since launch. The Ethereum 429 is the expected behavior of free public RPCs rate-limiting; rerun if you need that one.)

Non-zero balances render in cyan when stdout is a TTY. Zeros and errors are dim. Errors render inline so a single bad RPC doesn't block the rest.

Implementation

  • `packages/app/scripts/treasury-balances.ts` — the script. ~100 lines.
  • Reads `CHAINS` from `packages/app/src/config/chains.ts` and filters to `!isTestnet`. Adding a chain to the registry auto-includes it here.
  • One `balanceOf` read per chain via viem, public RPCs from `viem/chains` (no API key, no env config needed).
  • 8-second timeout, 0 retries — single slow RPC fails fast instead of hanging the whole run.
  • `tsx` added as a devDep so the script runs as TypeScript directly.
  • `pnpm balances` script added at repo root + `packages/app/` for ergonomics.

Why a CLI and not a cron + webhook

You asked for the simplest thing: hourly reads via a script. No cron, no webhook, no state. Run it when you want to know. The user-controlled cadence beats a noisy automated channel for a treasury you sweep manually anyway.

Test plan

  • `pnpm balances` — runs in ~5-8s, prints table, Base shows real USDC
  • `pnpm balances 0x847F640bE052b0700C31F72Dce622F4C6286934E` — explicit address arg works
  • `pnpm --filter app exec tsc --noEmit` — clean
  • `pnpm --filter app test` — 72 tests pass (script doesn't touch test surface)
  • Try with an invalid address: `pnpm balances 0xnotanaddress` should print a clean error and exit 1
  • Try with NO_COLOR=1: `NO_COLOR=1 pnpm balances` should produce plain ASCII

🤖 Generated with Claude Code

@vercel

vercel Bot commented Apr 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ripguard Ready Ready Preview, Comment Apr 26, 2026 8:29am
ripguard-testnet Ready Ready Preview, Comment Apr 26, 2026 8:29am

@fielding

Copy link
Copy Markdown
Owner Author

Reviewer orientation — multi-EVM stack [6/6]

Top of the stack. This PR is independent of the multi-EVM rollout's surface area — it's a dev-only CLI tool. Safe to review last and merge last.

PR Branch What it does
1 #8 feat/chain-registry registry foundation
2 #11 feat/page-refactor switch pages to useChainId
3 #12 feat/wagmi-multichain registry-driven wagmi + wrong-chain guard
4 #13 feat/expand-chains 6 new chains + BNB disclosure
5 #14 feat/landing-chain-chips landing chain chip row
→ 6 #15 feat/balances-script `pnpm balances` CLI (you are here)

You're at the top. No next PR.

Adds a read-only `pnpm balances` script that walks every mainnet chain in the registry and prints `usdc.balanceOf(treasury)` per chain. Used by the maintainer to track broker-fee revenue between manual sweeps. Adds `tsx` as a devDep. No surface change to users.

@fielding fielding left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers in this script layer.

I ran:

NO_COLOR=1 pnpm balances 0x847F640bE052b0700C31F72Dce622F4C6286934E
NO_COLOR=1 pnpm balances 0xnotanaddress

The happy path printed the treasury table and handled the Ethereum public RPC 429 inline without blocking the other chains. The invalid-address path exits 1 and prints a clear script-level error. pnpm adds its normal lifecycle failure wrapper after that, but the script itself is doing the right thing.

This PR is still merge-last and should wait for the lower-stack fixes/smoke test, but I do not see any issues in the CLI change itself.

@fielding fielding force-pushed the feat/landing-chain-chips branch from 49a2f03 to e1fdde5 Compare April 25, 2026 21:58
@fielding fielding force-pushed the feat/balances-script branch from 9da9379 to 4bc3288 Compare April 25, 2026 21:58
@fielding

Copy link
Copy Markdown
Owner Author

Stack rebased on top of all the fixes for #11/#12/#13. No code changes here in this round — the script's logic is unchanged.

Tests + typecheck + production build pass on top of stack. Ready for re-review.

…ains

A read-only CLI for checking the treasury (or any address) on every
mainnet chain in the registry. Run \`pnpm balances\` for the default
treasury, or \`pnpm balances 0xAddr\` for any address (cold-storage
sweep target, etc.).

Reads CHAINS directly from chains.ts, so adding a chain to the
registry auto-includes it here — no parallel list to maintain. Uses
each chain's default public RPC via viem (no API key, no env config).
Short timeout + no retries means a single slow public RPC (Ethereum's
free tier rate-limits aggressively) doesn't block the whole script.

Output: tight table with non-zero balances in cyan, zeros dim, errors
shown inline per chain. Total at the bottom is a sum of displayed
values across chains; treats Binance-Peg USDC on BNB and Circle USDC
elsewhere as 1:1 for the purposes of "did the treasury earn anything".

Refs: RG-644a80 (treasury monitoring helper)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fielding fielding force-pushed the feat/balances-script branch from 4bc3288 to 8c393c2 Compare April 26, 2026 08:12
@fielding fielding merged commit 8a7c0e5 into main Apr 26, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant