feat(chains): expand registry to 7 EVM mainnet chains + BNB disclosure#13
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Reviewer orientation — multi-EVM stack [4/6]This PR is part of a 6-PR stacked multi-EVM rollout. Review #8, #11, and #12 first — this PR fills in chain data on top of that foundation.
Move to #14 when done. This is the user-facing PR. Sablier addresses pulled directly from `sablier-labs/sdk` deployment broadcasts (canonical Foundry output, verified against the 2 known-good Base values which match exactly). USDC addresses from Circle's official docs. BNB sharp edge: USDC on BNB is Binance-Peg, 18 decimals, custodied by Binance — disclosed via `usdcNote` in the registry, surfaced on `/create` and `/vaults`. Test enforces BNB stays at 18 decimals. Smoke test before merging this: one Arbitrum lock+claim cycle (cheapest gas), one BNB lock+claim cycle (validates 18-decimal handling). Full checklist at `.handoff/SMOKE_TEST_MULTI_EVM.md`. |
fielding
left a comment
There was a problem hiding this comment.
Requesting changes before this layer exposes the new chains.
The chain data itself looks good. I checked the Sablier Lockup v2.0 addresses against Sablier's docs, and the entries in this PR match the published v2.0 deployments. The BNB 18-decimal disclosure is also the right call.
The issue is that enabling non-Base chains makes the existing hardcoded BaseScan copy wrong. The URLs are chain-derived now, but labels and explanatory text still say BaseScan in several places:
/createtx toast/link labels/vaultsclaim toast label- landing verification copy and FAQ copy
- footer explorer nav label
On Arbitrum, Polygon, BNB, etc. those links go to the right explorer but the UI says BaseScan. Please switch these to generic copy like "View transaction", "block explorer", or a chain-derived explorer label before exposing the chains.
Also, this PR inherits the lower-stack blockers I left on #11 and #12:
- active tx flows need to handle chain changes safely
- wrong-chain support needs to be deployment-aware, not just registry-aware
Non-blocking: Object.values(CHAINS) gives numeric-key order, so the effective order is Ethereum, Optimism, BNB, Polygon, Base, Arbitrum, Avalanche. If you want Base first, use an explicit ordered chain list and reuse it for wagmi/chips/scripts.
Validation I ran on the top of the stack:
pnpm --filter app test
pnpm --filter app exec tsc --noEmit
NODE_ENV=production pnpm --filter app buildAll passed. I could not run the Vercel preview smoke checklist because the preview URL redirected me to Vercel login from this environment.
c2e6c29 to
1da66b7
Compare
Addresses review feedback on #13: enabling non-Base chains made every hardcoded "BaseScan" reference wrong. The URLs were already chain- derived, but the labels weren't, so a user on Arbitrum saw "View on BaseScan" linking to Arbiscan. Adds explorerName to ChainConfig (Etherscan, BaseScan, Arbiscan, Optimistic Etherscan, PolygonScan, Snowtrace, BscScan, Base Sepolia BaseScan) and threads it through: - /create toast: "Lock created!" → "View on {explorerName}" - /create approve confirming link: "View on {explorerName}" - /create lock confirming link: "View on {explorerName}" - /create SuccessView: "View transaction on {explorerName}" (now takes explorerName as a prop alongside explorerUrl) - /vaults claim toast: "View on {explorerName}" - landing footer link: "{explorerName}" instead of literal "BaseScan" Static landing copy that doesn't sit next to a connected chain (TRUST_POINTS, FAQ, footer disclaimer) is generalized to "the chain's block explorer" since it's marketing copy, not a per-chain label. The hardcoded "on Base" in the footer disclaimer also goes away — RipGuard now runs on 7 chains. Lock success effect deps now include explorerName so the toast picks up the active chain's value when the user changes networks. Refs: RG-644a80 (review feedback) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
03252aa to
458e6dd
Compare
|
Pushed fix addressing your changes-requested review. Replaced every hardcoded "BaseScan" with chain-aware copy. Added `explorerName` to `ChainConfig` (Etherscan, BaseScan, Arbiscan, Optimistic Etherscan, PolygonScan, Snowtrace, BscScan, Base Sepolia BaseScan) and threaded it through:
Static landing copy (TRUST_POINTS, FAQ, footer disclaimer) is generalized to "the chain's block explorer" since it's marketing copy not tied to a connected chain. The hardcoded "on Base" in the footer disclaimer also goes away. Lock-success effect deps include `explorerName` so the toast picks up the active chain's name when the user changes networks. The two lower-stack blockers you flagged are also fixed — see updates on #11 (chain-aware deps + chain-change guard + namespaced localStorage key) and #12 (deployment-aware support check). Stack rebased clean on top of those. Non-blocking ordering note: the chip row's Object.values order is also affecting #14's PR description. Holding on the explicit-ordered-chains list change for now since it's non-blocking and would be one more rebase round across the stack — happy to add it as a follow-up if you'd rather see it now. Tests + typecheck + production build pass on top of stack. Ready for re-review. |
fielding
left a comment
There was a problem hiding this comment.
Re-reviewed after the explorer-name copy fix. The blocker from my prior review is addressed.
The tx links now use explorerName, landing copy is generalized where it should be, and the footer explorer label is chain-aware. The lower-stack blockers from #11 and #12 are also fixed in the current stack.
I do not see remaining code blockers in this layer. The manual Arbitrum and BNB smoke tests are still the merge gate for this user-facing chain expansion.
1da66b7 to
f9db0a0
Compare
Expands the registry from Base + Base Sepolia to all 7 target EVM mainnet chains plus Base Sepolia. Sablier Lockup v2.0 addresses sourced directly from sablier-labs/sdk's deployment broadcasts; verified against the two known-good values (Base mainnet + Base Sepolia) which match exactly. Native USDC addresses sourced from Circle's official contract addresses page. Sharp edges captured: 1. BNB Chain "USDC" is Binance-Peg, NOT Circle-native. The token at 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d is custodied by Binance and uses 18 decimals (every other chain's USDC is 6). The chain entry carries a usdcNote field disclosing this; /create and /vaults render the note when chainId === 56 so users see the distinction before they lock. Test enforces that BNB stays at 18 decimals and every other chain stays at 6. 2. Treasury is the same EOA on every mainnet chain. EVM addresses derive from public keys, so the same private key gives the same address everywhere. The Base treasury has an EIP-7702 delegation, but that's per-chain and doesn't change token-receipt behavior. Test asserts treasury parity across mainnet chains. 3. Sablier streamStartBlock is set to each chain's exact v2.0 deployment block (pulled from Sablier's deployment broadcasts). Tightest safe value for the on-chain getLogs fallback when the indexer is unavailable. wagmi.ts auto-picks up the new entries via the chainIdToWagmiChain map — no further config change needed. Wallet picker now shows all 7 mainnet chains; testnet deployment still shows only Base Sepolia. Refs: RG-644a80 (data wiring portion; smoke testing remains) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses review feedback on #13: enabling non-Base chains made every hardcoded "BaseScan" reference wrong. The URLs were already chain- derived, but the labels weren't, so a user on Arbitrum saw "View on BaseScan" linking to Arbiscan. Adds explorerName to ChainConfig (Etherscan, BaseScan, Arbiscan, Optimistic Etherscan, PolygonScan, Snowtrace, BscScan, Base Sepolia BaseScan) and threads it through: - /create toast: "Lock created!" → "View on {explorerName}" - /create approve confirming link: "View on {explorerName}" - /create lock confirming link: "View on {explorerName}" - /create SuccessView: "View transaction on {explorerName}" (now takes explorerName as a prop alongside explorerUrl) - /vaults claim toast: "View on {explorerName}" - landing footer link: "{explorerName}" instead of literal "BaseScan" Static landing copy that doesn't sit next to a connected chain (TRUST_POINTS, FAQ, footer disclaimer) is generalized to "the chain's block explorer" since it's marketing copy, not a per-chain label. The hardcoded "on Base" in the footer disclaimer also goes away — RipGuard now runs on 7 chains. Lock success effect deps now include explorerName so the toast picks up the active chain's value when the user changes networks. Refs: RG-644a80 (review feedback) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
458e6dd to
d98faf9
Compare
Summary
Stacked on #12. Expands the registry from Base + Base Sepolia to all 7 target EVM mainnet chains plus Base Sepolia. Closes the data-wiring portion of `RG-644a80`; smoke testing remains.
Verification trail
Sablier Lockup v2.0 — sourced from `sablier-labs/sdk`'s deployment broadcasts (their canonical Foundry output). I read each chain's `deployments/lockup/v2.0/broadcasts/.json` directly via the GitHub API. The two values that already existed in our codebase (Base mainnet `0xb5D78DD3...` and Base Sepolia `0xa4777CA5...`) match the canonical source byte-for-byte — strong evidence the unknown 6 are also right. Spot-checked the BNB broadcast JSON and confirmed `contractName === "SablierLockup"` and `chain === 56`. All deployments use CREATE2 with deterministic salts (per the v2.0 README), which is why Base mainnet's address is the same one already serving production.
Native USDC — sourced from Circle's official contract addresses page. All 6 mainnet chains except BNB have Circle-issued native USDC at 6 decimals.
BNB Chain USDC — Circle does NOT issue native USDC on BNB. The token at `0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d` is Binance-Peg USD Coin, custodied by Binance, with 18 decimals. Verified on Bscscan (the page literally warns "this token's displayed name does not match its contract's Name function"). The new `usdcNote` field on the chain entry disclosures this; `/create` and `/vaults` render the note when active.
Sablier deployment blocks — pulled from each chain's broadcast JSON (`min(receipts[].blockNumber)`). These are the tightest safe `streamStartBlock` values for the on-chain `getLogs` fallback. Base mainnet stays at the existing `22_000_000` (already-shipped value, no behavior change there).
Final addresses
Treasury — same EOA across all 7 mainnet chains
`0x847F640bE052b0700C31F72Dce622F4C6286934E` is an EOA with an EIP-7702 delegation set on Base mainnet only. Underlying key gives the same address on every EVM chain; the 7702 delegation is per-chain and doesn't change token-receipt behavior. Confirmed via `viem.getCode()` against the Base mainnet RPC. Test asserts treasury parity across mainnet entries.
What changes for users
Test plan
Note on the next PR
Now that the registry is full, PR 4 (`RG-213ce7`, landing chain chip row) has real data to render. I'll stack that next.
🤖 Generated with Claude Code