Skip to content

feat(assets-controller): guard BackendWebsocketDataSource chains by feature flag#9647

Open
stanleyyconsensys wants to merge 8 commits into
mainfrom
fix/guard-ws-asset-ctrl
Open

feat(assets-controller): guard BackendWebsocketDataSource chains by feature flag#9647
stanleyyconsensys wants to merge 8 commits into
mainfrom
fix/guard-ws-asset-ctrl

Conversation

@stanleyyconsensys

@stanleyyconsensys stanleyyconsensys commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

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
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 BackendWebsocketDataSource no longer treats Solana, Stellar, and Tron as active chains until each network’s remote flag reaches ReadAssetsControllerWithFallback—matching AccountsApiDataSource.

On supported-network refresh, the websocket data source now reads RemoteFeatureFlagController:getState and filters fullSupport chains with shouldSupportChain. EVM (eip155) chains stay ungated; missing or Off flags keep migration networks on the Snap path.

decimalToChainId is moved into shared utils/caip.ts (replacing duplicate local helpers). BackendWebsocketDataSourceAllowedActions and AssetsController messenger wiring now require RemoteFeatureFlagController: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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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.

Fix All in Cursor

❌ 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));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5baa62b. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will fix in other PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 decimalToChainId utility to normalize numeric/string chain identifiers into CAIP-2 ChainId values (with CAIP pass-through).
  • Updated BackendWebsocketDataSource to filter its supported networks via shouldSupportChain(..., 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.

Comment on lines +357 to +361
const { remoteFeatureFlags } = this.#messenger.call(
'RemoteFeatureFlagController:getState',
);
return response.fullSupport
.map(decimalToChainId)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it is the same for accounts API

@stanleyyconsensys
stanleyyconsensys requested a review from a team as a code owner July 24, 2026 09:00
// are always surfaced, while migration networks (Solana, Stellar, Tron) are
// only surfaced once their per-network stage reaches
// ReadAssetsControllerWithFallback.
const { remoteFeatureFlags } = this.#messenger.call(

@stanleyyconsensys stanleyyconsensys Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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 {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

move to caip.ts for share method

// HELPER FUNCTIONS
// ============================================================================

function decimalToChainId(decimalChainId: number | string): ChainId {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

move to caip.ts for share method

@stanleyyconsensys stanleyyconsensys changed the title fix: guard ws by feature flag fix: guard BackendWebsocketDataSource chains by feature flag Jul 27, 2026
@stanleyyconsensys stanleyyconsensys changed the title fix: guard BackendWebsocketDataSource chains by feature flag feat(assets-controller): guard BackendWebsocketDataSource chains by feature flag Jul 27, 2026
// PhishingController
| PhishingControllerBulkScanTokensAction
// AccountsApiDataSource (Accounts API v6 balances feature flag)
// AccountsApiDataSource / BackendWebsocketDataSource (Accounts API v6 balances feature flag)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

update doc, it is outdated

@stanleyyconsensys

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.5-preview-e2b065b23
@metamask-previews/accounts-controller@39.0.5-preview-e2b065b23
@metamask-previews/address-book-controller@7.1.2-preview-e2b065b23
@metamask-previews/ai-controllers@0.8.0-preview-e2b065b23
@metamask-previews/analytics-controller@1.2.1-preview-e2b065b23
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-e2b065b23
@metamask-previews/announcement-controller@8.1.0-preview-e2b065b23
@metamask-previews/app-metadata-controller@2.0.1-preview-e2b065b23
@metamask-previews/approval-controller@9.0.2-preview-e2b065b23
@metamask-previews/assets-controller@11.2.1-preview-e2b065b23
@metamask-previews/assets-controllers@110.0.0-preview-e2b065b23
@metamask-previews/authenticated-user-storage@3.0.1-preview-e2b065b23
@metamask-previews/base-controller@9.1.0-preview-e2b065b23
@metamask-previews/base-data-service@0.1.3-preview-e2b065b23
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-e2b065b23
@metamask-previews/bridge-controller@78.0.0-preview-e2b065b23
@metamask-previews/bridge-status-controller@74.5.0-preview-e2b065b23
@metamask-previews/build-utils@3.0.4-preview-e2b065b23
@metamask-previews/chain-agnostic-permission@1.7.0-preview-e2b065b23
@metamask-previews/chomp-api-service@4.0.0-preview-e2b065b23
@metamask-previews/claims-controller@0.5.3-preview-e2b065b23
@metamask-previews/client-controller@1.0.1-preview-e2b065b23
@metamask-previews/client-utils@1.2.1-preview-e2b065b23
@metamask-previews/compliance-controller@2.1.0-preview-e2b065b23
@metamask-previews/composable-controller@12.0.1-preview-e2b065b23
@metamask-previews/config-registry-controller@0.4.1-preview-e2b065b23
@metamask-previews/connectivity-controller@0.3.0-preview-e2b065b23
@metamask-previews/controller-utils@12.3.0-preview-e2b065b23
@metamask-previews/core-backend@7.0.0-preview-e2b065b23
@metamask-previews/delegation-controller@3.0.2-preview-e2b065b23
@metamask-previews/earn-controller@12.2.2-preview-e2b065b23
@metamask-previews/eip-5792-middleware@3.0.5-preview-e2b065b23
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-e2b065b23
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-e2b065b23
@metamask-previews/ens-controller@19.1.5-preview-e2b065b23
@metamask-previews/eth-block-tracker@15.0.1-preview-e2b065b23
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-e2b065b23
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-e2b065b23
@metamask-previews/foundryup@1.0.1-preview-e2b065b23
@metamask-previews/gas-fee-controller@26.3.0-preview-e2b065b23
@metamask-previews/gator-permissions-controller@4.2.3-preview-e2b065b23
@metamask-previews/geolocation-controller@0.1.3-preview-e2b065b23
@metamask-previews/java-tron-up@1.0.0-preview-e2b065b23
@metamask-previews/json-rpc-engine@10.5.0-preview-e2b065b23
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-e2b065b23
@metamask-previews/keyring-controller@27.1.0-preview-e2b065b23
@metamask-previews/local-node-utils@1.0.0-preview-e2b065b23
@metamask-previews/logging-controller@8.0.2-preview-e2b065b23
@metamask-previews/message-manager@14.1.2-preview-e2b065b23
@metamask-previews/messenger@2.0.0-preview-e2b065b23
@metamask-previews/messenger-cli@0.2.0-preview-e2b065b23
@metamask-previews/money-account-api-data-service@0.3.0-preview-e2b065b23
@metamask-previews/money-account-balance-service@2.3.0-preview-e2b065b23
@metamask-previews/money-account-controller@0.3.3-preview-e2b065b23
@metamask-previews/money-account-upgrade-controller@3.0.0-preview-e2b065b23
@metamask-previews/multichain-account-service@13.0.0-preview-e2b065b23
@metamask-previews/multichain-api-middleware@4.0.1-preview-e2b065b23
@metamask-previews/multichain-network-controller@3.2.1-preview-e2b065b23
@metamask-previews/multichain-transactions-controller@7.1.1-preview-e2b065b23
@metamask-previews/name-controller@9.1.2-preview-e2b065b23
@metamask-previews/network-connection-banner-controller@0.1.0-preview-e2b065b23
@metamask-previews/network-controller@34.0.0-preview-e2b065b23
@metamask-previews/network-enablement-controller@5.6.0-preview-e2b065b23
@metamask-previews/notification-services-controller@26.0.0-preview-e2b065b23
@metamask-previews/passkey-controller@3.0.0-preview-e2b065b23
@metamask-previews/permission-controller@13.1.1-preview-e2b065b23
@metamask-previews/permission-log-controller@5.1.0-preview-e2b065b23
@metamask-previews/perps-controller@10.0.0-preview-e2b065b23
@metamask-previews/phishing-controller@17.3.0-preview-e2b065b23
@metamask-previews/platform-api-docs@0.0.0-preview-e2b065b23
@metamask-previews/polling-controller@16.0.8-preview-e2b065b23
@metamask-previews/preferences-controller@23.1.0-preview-e2b065b23
@metamask-previews/profile-metrics-controller@4.0.2-preview-e2b065b23
@metamask-previews/profile-sync-controller@28.3.0-preview-e2b065b23
@metamask-previews/ramps-controller@17.2.0-preview-e2b065b23
@metamask-previews/rate-limit-controller@7.0.1-preview-e2b065b23
@metamask-previews/react-data-query@0.2.2-preview-e2b065b23
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-e2b065b23
@metamask-previews/sample-controllers@5.0.3-preview-e2b065b23
@metamask-previews/seedless-onboarding-controller@10.1.0-preview-e2b065b23
@metamask-previews/selected-network-controller@26.1.5-preview-e2b065b23
@metamask-previews/sentinel-api-service@1.0.0-preview-e2b065b23
@metamask-previews/shield-controller@5.1.3-preview-e2b065b23
@metamask-previews/signature-controller@39.2.7-preview-e2b065b23
@metamask-previews/smart-transactions-controller@25.0.1-preview-e2b065b23
@metamask-previews/snap-account-service@2.0.0-preview-e2b065b23
@metamask-previews/social-controllers@2.6.0-preview-e2b065b23
@metamask-previews/solana-test-validator-up@1.0.0-preview-e2b065b23
@metamask-previews/stellar-quickstart-up@0.0.0-preview-e2b065b23
@metamask-previews/storage-service@1.0.2-preview-e2b065b23
@metamask-previews/subscription-controller@6.2.1-preview-e2b065b23
@metamask-previews/transaction-controller@69.2.1-preview-e2b065b23
@metamask-previews/transaction-pay-controller@26.0.0-preview-e2b065b23
@metamask-previews/user-operation-controller@41.2.7-preview-e2b065b23
@metamask-previews/wallet@8.1.0-preview-e2b065b23
@metamask-previews/wallet-cli@0.0.0-preview-e2b065b23

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