feat(assets-controller): guard BackendWebsocketDataSource chains by feature flag#9647
feat(assets-controller): guard BackendWebsocketDataSource chains by feature flag#9647stanleyyconsensys wants to merge 8 commits into
BackendWebsocketDataSource chains by feature flag#9647Conversation
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 5baa62b. Configure here.
| ); | ||
| return response.fullSupport | ||
| .map(decimalToChainId) | ||
| .filter((chainId) => shouldSupportChain(chainId, remoteFeatureFlags)); |
There was a problem hiding this comment.
WebSocket ignores live flag changes
Medium Severity
BackendWebsocketDataSource now filters active chains with shouldSupportChain and RemoteFeatureFlagController:getState, but unlike AccountsApiDataSource it never subscribes to RemoteFeatureFlagController:stateChange. After a migration flag turns off, the websocket source can keep claiming gated chains until the 20-minute refresh or reconnect, so account-activity ingestion may continue when it should not.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5baa62b. Configure here.
There was a problem hiding this comment.
will fix in other PR
There was a problem hiding this comment.
Pull request overview
This PR updates @metamask/assets-controller to normalize supported-network chain identifiers into CAIP-2 ChainIds and to gate which supported networks are surfaced as “active chains” for the backend WebSocket data source based on the Snaps → AssetsController migration remote feature flags.
Changes:
- Added a shared
decimalToChainIdutility to normalize numeric/string chain identifiers into CAIP-2ChainIdvalues (with CAIP pass-through). - Updated
BackendWebsocketDataSourceto filter its supported networks viashouldSupportChain(..., remoteFeatureFlags)before surfacing them as active chains. - Added unit tests for chain-id normalization and for migration-stage gating behavior in the WebSocket data source.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/assets-controller/src/utils/index.ts | Exposes the new CAIP/chain-id normalization helper from the utils entrypoint. |
| packages/assets-controller/src/utils/caip.ts | Adds decimalToChainId helper for converting API “decimal” chain identifiers into CAIP-2. |
| packages/assets-controller/src/utils/caip.test.ts | Adds tests for decimal/string conversion and CAIP pass-through. |
| packages/assets-controller/src/data-sources/BackendWebsocketDataSource.ts | Gates active-chain surfacing using migration feature flags and reuses the shared chain-id normalization helper. |
| packages/assets-controller/src/data-sources/BackendWebsocketDataSource.test.ts | Adds coverage for migration gating behavior and chain-id conversion inputs. |
| packages/assets-controller/src/data-sources/AccountsApiDataSource.ts | Removes duplicated helper by importing the shared decimalToChainId. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const { remoteFeatureFlags } = this.#messenger.call( | ||
| 'RemoteFeatureFlagController:getState', | ||
| ); | ||
| return response.fullSupport | ||
| .map(decimalToChainId) |
There was a problem hiding this comment.
it is the same for accounts API
| // are always surfaced, while migration networks (Solana, Stellar, Tron) are | ||
| // only surfaced once their per-network stage reaches | ||
| // ReadAssetsControllerWithFallback. | ||
| const { remoteFeatureFlags } = this.#messenger.call( |
There was a problem hiding this comment.
out of scope:
if client doesnt register the remote feature flag, the whole fetchActiveChains will be drop, and it impacted to client:
EVM: call RPC as fallback
SNAP: call SNAP as fallback if there is one
| * @param chainIdOrDecimal - Chain ID string (CAIP-2 or decimal) or decimal number. | ||
| * @returns CAIP-2 ChainId. | ||
| */ | ||
| function toChainId(chainIdOrDecimal: number | string): ChainId { |
There was a problem hiding this comment.
move to caip.ts for share method
| // HELPER FUNCTIONS | ||
| // ============================================================================ | ||
|
|
||
| function decimalToChainId(decimalChainId: number | string): ChainId { |
There was a problem hiding this comment.
move to caip.ts for share method
BackendWebsocketDataSource chains by feature flag
BackendWebsocketDataSource chains by feature flagBackendWebsocketDataSource chains by feature flag
| // PhishingController | ||
| | PhishingControllerBulkScanTokensAction | ||
| // AccountsApiDataSource (Accounts API v6 balances feature flag) | ||
| // AccountsApiDataSource / BackendWebsocketDataSource (Accounts API v6 balances feature flag) |
There was a problem hiding this comment.
update doc, it is outdated
|
@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. |


Explanation
References
Checklist
Note
Medium Risk
Changes which chains get websocket subscriptions and active-chain claims during a staged migration; hosts must delegate the new messenger action, but behavior is flag-gated with the same fail-safe as Accounts API.
Overview
Extends the existing Snaps → AssetsController migration gating so
BackendWebsocketDataSourceno longer treats Solana, Stellar, and Tron as active chains until each network’s remote flag reachesReadAssetsControllerWithFallback—matchingAccountsApiDataSource.On supported-network refresh, the websocket data source now reads
RemoteFeatureFlagController:getStateand filtersfullSupportchains withshouldSupportChain. EVM (eip155) chains stay ungated; missing orOffflags keep migration networks on the Snap path.decimalToChainIdis moved into sharedutils/caip.ts(replacing duplicate local helpers).BackendWebsocketDataSourceAllowedActionsandAssetsControllermessenger wiring now requireRemoteFeatureFlagController:getState. Tests cover unset flags and per-namespace independence.Reviewed by Cursor Bugbot for commit e2b065b. Bugbot is set up for automated code reviews on this repo. Configure here.