Skip to content

Conversation

@milos-ethernal
Copy link

@milos-ethernal milos-ethernal commented Feb 9, 2026

Explanation

At this moment the custom token balances on chains like Base and BNB are not showing correct token amounts on MetaMask token section. I traced the error to TokenBalancesController where AccountsAPI fetcher returns balances but misses custom tokens. The controller now detects this and triggers an RPC fallback for those specific tokens

Screenshot from 2026-02-06 13-13-22 Screenshot from 2026-02-06 13-17-34 Screenshot from 2026-02-06 13-17-42 Screenshot from 2026-02-06 13-17-51

This change fixes the problem that I was facing on Base and BNB chains

References

This fixes the problem that I faced and submitted the ticket #74726250 to Technical Support

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Touches token-balance aggregation and fetcher fallback logic, which can affect balance correctness and RPC/API call volume across chains/accounts.

Overview
Fixes missing custom token balances on Accounts API-supported chains by detecting when the API response omits balances for tokens present in controller state and re-adding those chains to remainingChains so the RPC fetcher can backfill them (scoped to only the accounts actually queried, respecting queryAllAccounts).

Adds a focused unit test covering multi-account vs selected-account behavior for custom token balance fetching, updates the nock import style in tests, and documents the fix in the package changelog.

Written by Cursor Bugbot for commit 33db82d. This will update automatically on new commits. Configure here.

@milos-ethernal milos-ethernal requested review from a team as code owners February 9, 2026 21:56
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

const balanceKey = `${chainId}-${checksummedAccount}-${tokenAddress}`;
const hasBalance = balanceKeys.has(balanceKey);
if (!hasBalance) {
chainsWithMissingTokens.add(chainId);
Copy link

Choose a reason for hiding this comment

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

Fallback detection defeated by API fetcher's zero-fill entries

High Severity

The balanceKeys set is built from all of result.balances, which includes zero-fill entries that the AccountsApiBalanceFetcher adds (via getUserTokens / this.state.tokenBalances) for tokens the API didn't return. After the first successful RPC fallback stores a real balance in state, every subsequent poll sees the custom token in balanceKeys (as a zero entry), so chainsWithMissingTokens is never populated and RPC fallback never triggers again. The custom token balance then reverts to 0x0 permanently.

Fix in Cursor Fix in Web

Copy link
Author

@milos-ethernal milos-ethernal Feb 10, 2026

Choose a reason for hiding this comment

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

Great catch, tokens with aggregators: ["Dynamic"] are treated as custom tokens and are not returned by the Accounts API balance endpoint. ApiBalanceFetcher zero-fills these tokens to maintain a consistent token list.

Because of this, result.balances contains synthetic entries for custom tokens, and using it to detect missing balances prevents RPC fallback from triggering after the first successful fetch. The fallback decision must be derived from API-returned balances prior to zero-fill.

@milos-ethernal milos-ethernal changed the title Custom token balances fix fix: custom token balances Feb 10, 2026
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