Skip to content

fix(AssetsController): Remove messenger in Data sources#7859

Merged
salimtb merged 1 commit intomainfrom
fix/AssetsControllerCleanMessenger
Feb 9, 2026
Merged

fix(AssetsController): Remove messenger in Data sources#7859
salimtb merged 1 commit intomainfrom
fix/AssetsControllerCleanMessenger

Conversation

@Kriys94
Copy link
Contributor

@Kriys94 Kriys94 commented Feb 6, 2026

Explanation

References

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 core asset fetching/subscription plumbing and introduces a new required constructor dependency (queryApiClient), which can break consumers or subtly change subscription behavior. Logic changes around request shaping and WebSocket channel construction may affect which updates are received.

Overview
BREAKING: Removes the external initDataSources/messenger-driven data source setup and makes AssetsController require a queryApiClient, instantiating all balance/price/metadata data sources and middleware internally.

Data sources are refactored to stop exposing messenger actions/events; instead the controller calls instance methods/middlewares directly and subscriptions push updates via SubscriptionRequest.onAssetsUpdate (with optional getAssetsState for price polling). Lifecycle wiring is simplified to keyring lock/unlock only, request building is centralized via accountsWithSupportedChains, and WebSocket subscriptions are updated to always include eip155+solana channels with namespace-appropriate address formatting.

Tests/docs are updated to match the new construction/subscription model, and controller action types are moved to an auto-generated AssetsController-method-action-types.ts.

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

@Kriys94 Kriys94 force-pushed the fix/AssetsControllerCleanMessenger branch 4 times, most recently from 438667d to ef1c35d Compare February 6, 2026 16:38
@Kriys94 Kriys94 marked this pull request as ready for review February 6, 2026 16:45
@Kriys94 Kriys94 requested review from a team as code owners February 6, 2026 16:45
this.#dataSources.set('BackendWebsocketDataSource', new Set());
this.#dataSources.set('AccountsApiDataSource', new Set());
this.#dataSources.set('SnapDataSource', new Set());
this.#dataSources.set('RpcDataSource', new Set());
Copy link

Choose a reason for hiding this comment

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

Data sources instantiated before disabled check causes side effects

High Severity

All data sources (BackendWebsocketDataSource, AccountsApiDataSource, SnapDataSource, RpcDataSource, TokenDataSource, PriceDataSource, DetectionMiddleware) are instantiated at lines 428–457, before the #isEnabled check at line 464. Their constructors have significant side effects: AccountsApiDataSource and BackendWebsocketDataSource fire off API calls (fetchV2SupportedNetworks) and start 20-minute setInterval refresh timers; RpcDataSource subscribes to NetworkController:stateChange and reads NetworkController:getState; SnapDataSource discovers snaps and subscribes to balance events. When isEnabled is false, the early return at line 466 skips initialization but all these resources are already running and never cleaned up.

Fix in Cursor Fix in Web

.catch(console.error);
for (const subscription of this.activeSubscriptions.values()) {
subscription.onAssetsUpdate(response)?.catch(console.error);
}
Copy link

Choose a reason for hiding this comment

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

Snap balance events silently dropped before controller subscribes

Medium Severity

SnapDataSource subscribes to AccountsController:accountBalancesUpdated in its constructor (line 240), but #handleSnapBalancesUpdated now delivers updates by iterating this.activeSubscriptions and calling each onAssetsUpdate callback. Subscriptions are only created later when AssetsController.#start() calls #subscribeToDataSources() (triggered by KeyringController:unlock). Any snap balance events arriving between construction and subscription are silently dropped because activeSubscriptions is empty. The old messenger-based approach called AssetsController:assetsUpdate directly, which always reached the controller regardless of subscription state. The same pattern exists in RpcDataSource.#handleBalanceUpdate.

Additional Locations (1)

Fix in Cursor Fix in Web

@Kriys94 Kriys94 force-pushed the fix/AssetsControllerCleanMessenger branch from ef1c35d to 429bf06 Compare February 6, 2026 22:46
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.

this.#backendWebsocketDataSource.setActiveChainsFromAccountsApi(
activeChains,
);
}
Copy link

Choose a reason for hiding this comment

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

Wrong condition prevents BackendWebsocketDataSource chain sync

Medium Severity

The comment says "When BackendWebsocketDataSource is updated via AccountsApiDataSource callback, sync its state," but the condition checks dataSourceId === 'BackendWebsocketDataSource'. This means setActiveChainsFromAccountsApi is called when BackendWebsocketDataSource reports its own chains (a no-op, since they're already set internally), but is never called when AccountsApiDataSource reports chains. If the intent is to sync BackendWebsocketDataSource from AccountsApiDataSource, the condition needs to check for 'AccountsApiDataSource' instead.

Additional Locations (1)

Fix in Cursor Fix in Web

@salimtb
Copy link
Contributor

salimtb commented Feb 8, 2026

@metamaskbot publish-preview

@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "4.0.0-preview-429bf064c",
  "@metamask-previews/accounts-controller": "35.0.2-preview-429bf064c",
  "@metamask-previews/address-book-controller": "7.0.1-preview-429bf064c",
  "@metamask-previews/ai-controllers": "0.0.0-preview-429bf064c",
  "@metamask-previews/analytics-controller": "1.0.0-preview-429bf064c",
  "@metamask-previews/analytics-data-regulation-controller": "0.0.0-preview-429bf064c",
  "@metamask-previews/announcement-controller": "8.0.0-preview-429bf064c",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-429bf064c",
  "@metamask-previews/approval-controller": "8.0.0-preview-429bf064c",
  "@metamask-previews/assets-controller": "0.2.0-preview-429bf064c",
  "@metamask-previews/assets-controllers": "99.2.0-preview-429bf064c",
  "@metamask-previews/base-controller": "9.0.0-preview-429bf064c",
  "@metamask-previews/bridge-controller": "65.3.0-preview-429bf064c",
  "@metamask-previews/bridge-status-controller": "66.0.0-preview-429bf064c",
  "@metamask-previews/build-utils": "3.0.4-preview-429bf064c",
  "@metamask-previews/chain-agnostic-permission": "1.4.0-preview-429bf064c",
  "@metamask-previews/claims-controller": "0.4.2-preview-429bf064c",
  "@metamask-previews/composable-controller": "12.0.0-preview-429bf064c",
  "@metamask-previews/connectivity-controller": "0.1.0-preview-429bf064c",
  "@metamask-previews/controller-utils": "11.18.0-preview-429bf064c",
  "@metamask-previews/core-backend": "5.1.0-preview-429bf064c",
  "@metamask-previews/delegation-controller": "2.0.0-preview-429bf064c",
  "@metamask-previews/earn-controller": "11.1.0-preview-429bf064c",
  "@metamask-previews/eip-5792-middleware": "2.1.0-preview-429bf064c",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-429bf064c",
  "@metamask-previews/eip1193-permission-middleware": "1.0.3-preview-429bf064c",
  "@metamask-previews/ens-controller": "19.0.2-preview-429bf064c",
  "@metamask-previews/error-reporting-service": "3.0.1-preview-429bf064c",
  "@metamask-previews/eth-block-tracker": "15.0.1-preview-429bf064c",
  "@metamask-previews/eth-json-rpc-middleware": "23.1.0-preview-429bf064c",
  "@metamask-previews/eth-json-rpc-provider": "6.0.0-preview-429bf064c",
  "@metamask-previews/foundryup": "1.0.1-preview-429bf064c",
  "@metamask-previews/gas-fee-controller": "26.0.2-preview-429bf064c",
  "@metamask-previews/gator-permissions-controller": "1.1.2-preview-429bf064c",
  "@metamask-previews/json-rpc-engine": "10.2.1-preview-429bf064c",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-429bf064c",
  "@metamask-previews/keyring-controller": "25.1.0-preview-429bf064c",
  "@metamask-previews/logging-controller": "7.0.1-preview-429bf064c",
  "@metamask-previews/message-manager": "14.1.0-preview-429bf064c",
  "@metamask-previews/messenger": "0.3.0-preview-429bf064c",
  "@metamask-previews/multichain-account-service": "5.1.0-preview-429bf064c",
  "@metamask-previews/multichain-api-middleware": "1.2.6-preview-429bf064c",
  "@metamask-previews/multichain-network-controller": "3.0.2-preview-429bf064c",
  "@metamask-previews/multichain-transactions-controller": "7.0.0-preview-429bf064c",
  "@metamask-previews/name-controller": "9.0.0-preview-429bf064c",
  "@metamask-previews/network-controller": "29.0.0-preview-429bf064c",
  "@metamask-previews/network-enablement-controller": "4.1.0-preview-429bf064c",
  "@metamask-previews/notification-services-controller": "21.0.0-preview-429bf064c",
  "@metamask-previews/permission-controller": "12.2.0-preview-429bf064c",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-429bf064c",
  "@metamask-previews/perps-controller": "0.0.0-preview-429bf064c",
  "@metamask-previews/phishing-controller": "16.1.0-preview-429bf064c",
  "@metamask-previews/polling-controller": "16.0.2-preview-429bf064c",
  "@metamask-previews/preferences-controller": "22.1.0-preview-429bf064c",
  "@metamask-previews/profile-metrics-controller": "3.0.0-preview-429bf064c",
  "@metamask-previews/profile-sync-controller": "27.1.0-preview-429bf064c",
  "@metamask-previews/ramps-controller": "7.0.0-preview-429bf064c",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-429bf064c",
  "@metamask-previews/remote-feature-flag-controller": "4.0.0-preview-429bf064c",
  "@metamask-previews/sample-controllers": "4.0.2-preview-429bf064c",
  "@metamask-previews/seedless-onboarding-controller": "7.1.0-preview-429bf064c",
  "@metamask-previews/selected-network-controller": "26.0.2-preview-429bf064c",
  "@metamask-previews/shield-controller": "5.0.1-preview-429bf064c",
  "@metamask-previews/signature-controller": "39.0.1-preview-429bf064c",
  "@metamask-previews/storage-service": "1.0.0-preview-429bf064c",
  "@metamask-previews/subscription-controller": "5.4.2-preview-429bf064c",
  "@metamask-previews/transaction-controller": "62.14.0-preview-429bf064c",
  "@metamask-previews/transaction-pay-controller": "12.2.0-preview-429bf064c",
  "@metamask-previews/user-operation-controller": "41.0.2-preview-429bf064c"
}

@salimtb
Copy link
Contributor

salimtb commented Feb 9, 2026

changes test on the UI through the PR below:
MetaMask/metamask-extension#39789
works as expected

@salimtb salimtb added this pull request to the merge queue Feb 9, 2026
Merged via the queue into main with commit e1737d8 Feb 9, 2026
302 checks passed
@salimtb salimtb deleted the fix/AssetsControllerCleanMessenger branch February 9, 2026 09:00
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.

2 participants