feat: disable token list - #8945
Conversation
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
|
||
| #abortController: AbortController; | ||
|
|
||
| readonly #isDisabled: () => boolean; |
There was a problem hiding this comment.
when this is true , tokenList will be an empty object
There was a problem hiding this comment.
@salimtb since we are planning to use this pattern for all other old controllers, should we rename this to something else? (I think some old controllers already have an isDisabled property)
There was a problem hiding this comment.
isRemoved / isDeprecated?
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b155dbc. Configure here.
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
…etaMask#9044) <!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Summary Adds the optional `isDeprecated` constructor callback to `MultichainAssetsRatesController` and `MultichainBalancesController`, following the same pattern introduced in [MetaMask#9033](MetaMask#9033) for `TokenRatesController`, `TokenBalancesController`, and `AccountTrackerController`, and [MetaMask#8945](MetaMask#8945) for `TokenListController`. https://consensyssoftware.atlassian.net/browse/ASSETS-3331 https://consensyssoftware.atlassian.net/browse/ASSETS-3332 When `isDeprecated()` returns `true`: - **MultichainAssetsRatesController** — no Snap requests are issued; `conversionRates` and `historicalPrices` are reset to `{}` at construction and at every entry point (`updateAssetsRates`, `fetchHistoricalPricesForAsset`, `_executePoll`, `CurrencyRateController:stateChange`, and `MultichainAssetsController:accountAssetListUpdated`). - **MultichainBalancesController** — no Snap requests are issued; `balances` is reset to `{}` at construction and at every entry point (`updateBalance`, `MultichainAssetsController:accountAssetListUpdated`, `AccountsController:accountBalancesUpdated`, and `AccountsController:accountRemoved`). The callback is re-evaluated on each entry point so deprecation can be toggled at runtime without reconstructing the controller — intended for use when `AssetsController` supersedes these legacy multichain controllers. ## Test plan - [x] Added unit tests for construction, runtime toggles, and no-fetch guarantees for both controllers - [x] `yarn workspace @metamask/assets-controllers run jest --no-coverage src/MultichainAssetsRatesController/MultichainAssetsRatesController.test.ts src/MultichainBalancesController/MultichainBalancesController.test.ts` <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-e39569e0-56f8-4ce0-af31-2d0cada86844"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-e39569e0-56f8-4ce0-af31-2d0cada86844"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
## Summary Adds the optional `isDeprecated` constructor callback to `CurrencyRateController`, following the same pattern introduced in [MetaMask#9044](MetaMask#9044) for `MultichainAssetsRatesController` and `MultichainBalancesController`, [MetaMask#9033](MetaMask#9033) for `TokenRatesController`, `TokenBalancesController`, and `AccountTrackerController`, and [MetaMask#8945](MetaMask#8945) for `TokenListController`. When `isDeprecated()` returns `true`: - **CurrencyRateController** — no API requests are issued; `currencyRates` is reset to `{}` at construction and at every entry point (`setCurrentCurrency`, `updateExchangeRate`, and `_executePoll`). The callback is re-evaluated on each entry point so deprecation can be toggled at runtime without reconstructing the controller — intended for use when `AssetsController` supersedes this controller. Ticket: https://consensyssoftware.atlassian.net/browse/ASSETS-3328 ## Test plan - [x] Added unit tests for construction, runtime toggles, and no-fetch guarantees - [x] `yarn workspace @metamask/assets-controllers run jest --no-coverage src/CurrencyRateController.test.ts` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches fiat conversion state and polling entry points; wrong wiring could leave UI without rates or clear persisted rates unexpectedly, but behavior is gated and matches an established controller pattern. > > **Overview** > Adds an optional **`isDeprecated`** constructor callback to **`CurrencyRateController`**, aligned with the same deprecation pattern used on other assets controllers. > > When **`isDeprecated()`** is true, the controller skips exchange-rate API work and clears **`currencyRates`** via **`#enforceDisabledState()`** at construction and on **`setCurrentCurrency`**, **`updateExchangeRate`**, and **`_executePoll`**. The callback is checked on each entry point so deprecation can flip at runtime without recreating the controller (for when **`AssetsController`** owns rates). > > **`CHANGELOG`** documents the behavior; tests cover construction, no-fetch guarantees, and runtime toggles. Test helpers gain explicit return types and the **`CurrencyRateController.test.ts`** ESLint suppression entry is removed. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit aad45b9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Juanmi <juanmigdr@users.noreply.github.com>
…ler (MetaMask#9310) <!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Explanation `MultichainAssetsController` is being superseded by the unified `AssetsController` (feature flag `assets-unify-state`). To allow it to be turned off without tearing down the controller, this PR adds an optional `isDeprecated` constructor callback, following the same pattern already introduced for `TokenListController` ([MetaMask#8945](MetaMask#8945)) and the sibling multichain controllers `MultichainAssetsRatesController` / `MultichainBalancesController` ([MetaMask#9044](MetaMask#9044)). When `isDeprecated()` returns `true`: - No Snap requests are issued. - `accountsAssets`, `assetsMetadata`, and `allIgnoredAssets` are reset to `{}` at construction and re-enforced at every entry point (`addAssets`, `ignoreAssets`, `_executePoll`, and the `AccountsController:accountAdded` / `accountRemoved` / `accountAssetListUpdated` subscriptions), so no stale asset data remains in state. The callback is re-evaluated on each entry point, so deprecation can be toggled at runtime without reconstructing the controller. The default (`() => false`) preserves existing behavior, so this is a non-breaking, additive change. ## References - https://consensyssoftware.atlassian.net/browse/ASSETS-3333 - Follows [MetaMask#9044](MetaMask#9044) and [MetaMask#8945](MetaMask#8945) ## Manual testing steps N/A — behavior-preserving by default (the new option defaults to disabled). New behavior is covered by unit tests. ## Changed files - `packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.ts` — Added the optional `isDeprecated` constructor option, a private `#enforceDisabledState()` helper that clears the three state maps, and guards at every entry point. Verified with lint (`eslint`, clean), typecheck (`yarn build`, clean), and unit tests. - `packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.test.ts` — Added an `isDeprecated` describe block (construction, runtime-toggle, and no-Snap-request guarantees) and threaded the option through the `setupController` helper. Verified via `jest` (59/59 passing). - `packages/assets-controllers/CHANGELOG.md` — Added an entry under `Unreleased > Added`. Verified with `yarn workspace @metamask/assets-controllers run changelog:validate`. ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [ ] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-3c4f01e1-c3e5-448b-a761-51061d5bace6"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-3c4f01e1-c3e5-448b-a761-51061d5bace6"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>

Explanation
References
Checklist
Note
Medium Risk
Changes token list fetch, cache, and StorageService persistence paths; mistakes could leave stale token data or block legitimate refreshes, but behavior is gated behind an opt-in callback with extensive tests.
Overview
Adds an optional
isDeprecatedconstructor callback so hosts can turn off token list fetching without tearing down the controller. When it returns true,TokenListControllerclears in-memorytokensChainsCache, skips token API calls oninitialize,start,restart,_executePoll, andfetchTokenList, and wipes persistedtokensChainsCache:*keys to{ data: {}, timestamp: 0 }.The flag is re-checked on every entry point, so it can be flipped at runtime (including while legacy polling is still scheduled).
#enforceDisabledStatealso cancels pending debounced persists so stale writes cannot repopulate storage after a disable. Changelog and broad unit coverage document the behavior.Reviewed by Cursor Bugbot for commit c00433f. Bugbot is set up for automated code reviews on this repo. Configure here.