fix: guard wallet RPC calls against undefined result and retry transients#899
Merged
fix: guard wallet RPC calls against undefined result and retry transients#899
Conversation
…ents Consolidate native and ERC20 balance fetchers onto a shared rpcCall helper with exponential backoff for HTTP 429, 5xx, network errors, and malformed gateway responses with missing result fields. The missing-result case was surfacing as BigInt(undefined) on the analytics page.
…ress validation Split rpcCall and helpers out of fetch-balances.ts into lib/wallet/rpc.ts so the retry logic is unit-testable in isolation. Add randomized jitter (up to 30%) to the backoff to avoid lockstep retries, and clamp the absolute maximum delay to 5s regardless of schedule. Validate EVM addresses before encoding balanceOf call data so an oversized input cannot silently produce wrong call data via padStart. Emit a Sentry breadcrumb on every retry attempt so the retry history is attached to any captured exception. Add lib/wallet/rpc.test.ts covering encodeBalanceOfCallData validation, hexWeiToBigInt edge cases, getRpcBackoffMs jitter and cap behavior, and all rpcCall retry/throw branches.
PR Environment DeployedYour PR environment has been deployed! Environment Details:
Components:
The environment will be automatically cleaned up when this PR is closed or merged. |
…fails Wire the chain-level default_fallback_rpc through ChainData so the wallet balance fetchers can fail over when the primary RPC is throttled or down. Add rpcCallWithFailover that walks the URL list in order with a reduced per-URL retry budget so the handoff is fast. Emit rpc.failover breadcrumbs for every hop. The user now sees an error only when every configured RPC is exhausted, not when the primary alone gets a 429.
PR Environment DeployedYour PR environment has been deployed! Environment Details:
Components:
The environment will be automatically cleaned up when this PR is closed or merged. |
PR Environment DeployedYour PR environment has been deployed! Environment Details:
Components:
The environment will be automatically cleaned up when this PR is closed or merged. |
🧹 PR Environment Cleaned UpThe PR environment has been successfully deleted. Deleted Resources:
All resources have been cleaned up and will no longer incur costs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fetchNativeBalance,fetchTokenBalance,fetchSupportedTokenBalance) onto a singlerpcCallhelper with retry/backoff.rpcCallretries on HTTP 429, HTTP 5xx, network errors, and malformed responses (missingresultfield). Skips retry on RPC-reported errors and non-429 4xx.encodeBalanceOfCallDataandhexWeiToBigInthelpers.hexWeiToBigInttreats"0x"as zero soBigInt()never receives an invalid string.RPC_RETRY_CONFIGblock with two schedules: standard (500ms, 1s, 2s, cap 3s) and rate-limit (1s, 2s, 4s, cap 5s).Background
The analytics page was showing
TypeError: Cannot convert undefined to a BigInton the Base chain card. Root cause:fetchNativeBalancecalledBigInt(result.result)without guarding against malformed gateway responses whereresult.resultwasundefined(noerrorfield, noresultfield). The same class of transient failure on the sibling ERC20 fetchers was silently caught and displayed to users as well.Instead of patching just the one call site, this refactor unifies all three fetchers so the fix, the retry behaviour, and the error semantics are consistent across native and ERC20 paths.