Keep USD fee estimates available on rate-limited RPCs #13

Merged
backmeupplz merged 1 commit from fix/usd-fee-rate-limit into main 2026-10-04 01:27:11 +00:00
backmeupplz commented 2026-10-04 01:18:50 +00:00 (Migrated from github.com)

Approval reviews showed USD unavailable next to the network fee on Base. There were two causes:

  1. Expiry. A quote lives at most 30 s. After that the review switched to "USD unavailable" and stayed there. Now it shows "USD loading…" and reads the price again while the review is open, including on focus or visibility changes. An expired price is still never shown as current, and a detached review stops reading.
  2. RPC rate limit. mainnet.base.org limits eth_call per IP (-32016 "over rate limit", sent inside an HTTP 200). Opening a review screen, plus the dapp's own reads, uses up that quota. The three oracle reads are now one Multicall3 call, the same approach as balances() in lib/chain.ts. It retries after 1 s and 2 s, all within the existing 5 s timeout, and each attempt aborts its own pending requests. The chain-ID check and all quote validation are unchanged.

Display only. This doesn't touch transaction preparation, signing or approval.

Checks

  • npm test, tsc --noEmit and npm run build pass.
  • test-fees.js has new checks for the re-read after expiry and for rate-limited reads being retried. The retry check fails without the fix. The mock now answers Multicall3 aggregate3.
  • Tested against the live Base RPC in a throwaway LibreWolf profile with the built add-on. With 3 competing eth_calls, the old code was unavailable in 1 of 3 runs and the new code worked in 3 of 3. The real fee row showed ≈ $0.01123 and was still showing it 36 s later. Also checked in Chromium with the built extension.
  • Remaining limitation: a dapp that exhausts the public RPC's quota can still cause "USD unavailable". A better RPC for the network is the real fix for that.

🤖 Generated with Claude Code

Approval reviews showed **USD unavailable** next to the network fee on Base. There were two causes: 1. **Expiry.** A quote lives at most 30 s. After that the review switched to "USD unavailable" and stayed there. Now it shows "USD loading…" and reads the price again while the review is open, including on focus or visibility changes. An expired price is still never shown as current, and a detached review stops reading. 2. **RPC rate limit.** `mainnet.base.org` limits `eth_call` per IP (`-32016 "over rate limit"`, sent inside an HTTP 200). Opening a review screen, plus the dapp's own reads, uses up that quota. The three oracle reads are now **one Multicall3 call**, the same approach as `balances()` in `lib/chain.ts`. It retries after 1 s and 2 s, all within the existing 5 s timeout, and each attempt aborts its own pending requests. The chain-ID check and all quote validation are unchanged. Display only. This doesn't touch transaction preparation, signing or approval. ## Checks - `npm test`, `tsc --noEmit` and `npm run build` pass. - `test-fees.js` has new checks for the re-read after expiry and for rate-limited reads being retried. The retry check fails without the fix. The mock now answers Multicall3 `aggregate3`. - Tested against the live Base RPC in a throwaway LibreWolf profile with the built add-on. With 3 competing `eth_call`s, the old code was unavailable in 1 of 3 runs and the new code worked in 3 of 3. The real fee row showed `≈ $0.01123` and was still showing it 36 s later. Also checked in Chromium with the built extension. - Remaining limitation: a dapp that exhausts the public RPC's quota can still cause "USD unavailable". A better RPC for the network is the real fix for that. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No description provided.