From b2f95215040c8c2661a8ce8fb6605bec444cf55c Mon Sep 17 00:00:00 2001 From: Prithpal Sooriya Date: Mon, 8 Jun 2026 17:01:06 +0000 Subject: [PATCH 1/5] feat(assets): wire isDeprecated for multichain controllers Add isDeprecated callbacks to MultichainAssetsRatesController and MultichainBalancesController initialization, driven by the assetsUnifyState remote feature flag deprecatedControllers list. Uses @metamask-previews/assets-controllers@108.5.0-preview-513faa49e from MetaMask/core#9044. Related: MetaMask/core#9044 Co-authored-by: Prithpal Sooriya --- .../messenger-client-init/messengers/index.ts | 6 +- .../messengers/multichain/index.ts | 10 ++- ...chain-assets-rates-controller-messenger.ts | 33 ++++++++++ ...ultichain-balances-controller-messenger.ts | 33 ++++++++++ ...ultichain-balances-controller-init.test.ts | 16 ++++- .../multichain-balances-controller-init.ts | 17 ++++- ...chain-rates-assets-controller-init.test.ts | 16 ++++- ...multichain-rates-assets-controller-init.ts | 17 ++++- package.json | 3 +- .../remote-feature-flag.test.ts | 65 +++++++++++++++++++ .../assets-unify-state/remote-feature-flag.ts | 30 +++++++++ yarn.lock | 14 ++-- 12 files changed, 238 insertions(+), 22 deletions(-) diff --git a/app/scripts/messenger-client-init/messengers/index.ts b/app/scripts/messenger-client-init/messengers/index.ts index 304ed5bf4264..135ad3e536c0 100644 --- a/app/scripts/messenger-client-init/messengers/index.ts +++ b/app/scripts/messenger-client-init/messengers/index.ts @@ -32,10 +32,12 @@ import { getAccountActivityServiceMessenger, } from './core-backend'; import { + getMultichainBalancesControllerInitMessenger, getMultichainBalancesControllerMessenger, getMultichainTransactionsControllerMessenger, getMultichainAssetsControllerMessenger, getMultichainNetworkControllerMessenger, + getMultichainAssetsRatesControllerInitMessenger, getMultichainAssetsRatesControllerMessenger, } from './multichain'; import { getInstitutionalSnapControllerMessenger } from './accounts/institutional-snap-controller-messenger'; @@ -508,11 +510,11 @@ export const MESSENGER_FACTORIES = { }, MultichainAssetsRatesController: { getMessenger: getMultichainAssetsRatesControllerMessenger, - getInitMessenger: noop, + getInitMessenger: getMultichainAssetsRatesControllerInitMessenger, }, MultichainBalancesController: { getMessenger: getMultichainBalancesControllerMessenger, - getInitMessenger: noop, + getInitMessenger: getMultichainBalancesControllerInitMessenger, }, MultichainTransactionsController: { getMessenger: getMultichainTransactionsControllerMessenger, diff --git a/app/scripts/messenger-client-init/messengers/multichain/index.ts b/app/scripts/messenger-client-init/messengers/multichain/index.ts index 14806235dca2..fac398ba836e 100644 --- a/app/scripts/messenger-client-init/messengers/multichain/index.ts +++ b/app/scripts/messenger-client-init/messengers/multichain/index.ts @@ -1,5 +1,11 @@ export { getMultichainAssetsControllerMessenger } from './multichain-assets-controller-messenger'; -export { getMultichainAssetsRatesControllerMessenger } from './multichain-assets-rates-controller-messenger'; -export { getMultichainBalancesControllerMessenger } from './multichain-balances-controller-messenger'; +export { + getMultichainAssetsRatesControllerInitMessenger, + getMultichainAssetsRatesControllerMessenger, +} from './multichain-assets-rates-controller-messenger'; +export { + getMultichainBalancesControllerInitMessenger, + getMultichainBalancesControllerMessenger, +} from './multichain-balances-controller-messenger'; export { getMultichainTransactionsControllerMessenger } from './multichain-transactions-controller-messenger'; export { getMultichainNetworkControllerMessenger } from './multichain-network-controller-messenger'; diff --git a/app/scripts/messenger-client-init/messengers/multichain/multichain-assets-rates-controller-messenger.ts b/app/scripts/messenger-client-init/messengers/multichain/multichain-assets-rates-controller-messenger.ts index b606036bc98d..f1b8522d8f15 100644 --- a/app/scripts/messenger-client-init/messengers/multichain/multichain-assets-rates-controller-messenger.ts +++ b/app/scripts/messenger-client-init/messengers/multichain/multichain-assets-rates-controller-messenger.ts @@ -4,6 +4,7 @@ import { type MessengerEvents, } from '@metamask/messenger'; import { MultichainAssetsRatesControllerMessenger } from '@metamask/assets-controllers'; +import { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller'; import { RootMessenger } from '../../../lib/messenger'; /** @@ -43,3 +44,35 @@ export function getMultichainAssetsRatesControllerMessenger( }); return controllerMessenger; } + +type AllowedInitializationActions = RemoteFeatureFlagControllerGetStateAction; + +export type MultichainAssetsRatesControllerInitMessenger = ReturnType< + typeof getMultichainAssetsRatesControllerInitMessenger +>; + +/** + * Create a messenger restricted to the allowed actions needed during + * initialization of the Multichain Assets Rates controller. + * + * @param messenger - The base messenger used to create the restricted messenger. + */ +export function getMultichainAssetsRatesControllerInitMessenger( + messenger: RootMessenger, +) { + const controllerInitMessenger = new Messenger< + 'MultichainAssetsRatesControllerInit', + AllowedInitializationActions, + never, + typeof messenger + >({ + namespace: 'MultichainAssetsRatesControllerInit', + parent: messenger, + }); + messenger.delegate({ + messenger: controllerInitMessenger, + actions: ['RemoteFeatureFlagController:getState'], + events: [], + }); + return controllerInitMessenger; +} diff --git a/app/scripts/messenger-client-init/messengers/multichain/multichain-balances-controller-messenger.ts b/app/scripts/messenger-client-init/messengers/multichain/multichain-balances-controller-messenger.ts index d59431992a18..689f5d5aaf22 100644 --- a/app/scripts/messenger-client-init/messengers/multichain/multichain-balances-controller-messenger.ts +++ b/app/scripts/messenger-client-init/messengers/multichain/multichain-balances-controller-messenger.ts @@ -4,6 +4,7 @@ import { type MessengerEvents, } from '@metamask/messenger'; import { MultichainBalancesControllerMessenger } from '@metamask/assets-controllers'; +import { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller'; import { RootMessenger } from '../../../lib/messenger'; /** @@ -41,3 +42,35 @@ export function getMultichainBalancesControllerMessenger( }); return controllerMessenger; } + +type AllowedInitializationActions = RemoteFeatureFlagControllerGetStateAction; + +export type MultichainBalancesControllerInitMessenger = ReturnType< + typeof getMultichainBalancesControllerInitMessenger +>; + +/** + * Create a messenger restricted to the allowed actions needed during + * initialization of the Multichain Balances controller. + * + * @param messenger - The base messenger used to create the restricted messenger. + */ +export function getMultichainBalancesControllerInitMessenger( + messenger: RootMessenger, +) { + const controllerInitMessenger = new Messenger< + 'MultichainBalancesControllerInit', + AllowedInitializationActions, + never, + typeof messenger + >({ + namespace: 'MultichainBalancesControllerInit', + parent: messenger, + }); + messenger.delegate({ + messenger: controllerInitMessenger, + actions: ['RemoteFeatureFlagController:getState'], + events: [], + }); + return controllerInitMessenger; +} diff --git a/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.test.ts b/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.test.ts index 887228c58532..f55453bb51b5 100644 --- a/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.test.ts +++ b/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.test.ts @@ -4,14 +4,21 @@ import { } from '@metamask/assets-controllers'; import { buildControllerInitRequestMock } from '../test/utils'; import { MessengerClientInitRequest } from '../types'; -import { getMultichainBalancesControllerMessenger } from '../messengers/multichain'; +import { + getMultichainBalancesControllerInitMessenger, + getMultichainBalancesControllerMessenger, +} from '../messengers/multichain'; import { getRootMessenger } from '../../lib/messenger'; +import { MultichainBalancesControllerInitMessenger } from '../messengers/multichain/multichain-balances-controller-messenger'; import { MultichainBalancesControllerInit } from './multichain-balances-controller-init'; jest.mock('@metamask/assets-controllers'); function buildInitRequestMock(): jest.Mocked< - MessengerClientInitRequest + MessengerClientInitRequest< + MultichainBalancesControllerMessenger, + MultichainBalancesControllerInitMessenger + > > { const baseControllerMessenger = getRootMessenger(); @@ -20,7 +27,9 @@ function buildInitRequestMock(): jest.Mocked< controllerMessenger: getMultichainBalancesControllerMessenger( baseControllerMessenger, ), - initMessenger: undefined, + initMessenger: getMultichainBalancesControllerInitMessenger( + baseControllerMessenger, + ), }; } @@ -47,6 +56,7 @@ describe('MultichainBalancesControllerInit', () => { expect(multichainBalancesControllerClassMock).toHaveBeenCalledWith({ messenger: requestMock.controllerMessenger, state: requestMock.persistedState.MultichainBalancesController, + isDeprecated: expect.any(Function), }); }); }); diff --git a/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.ts b/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.ts index 17b4418f0955..25bcdb23f102 100644 --- a/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.ts +++ b/app/scripts/messenger-client-init/multichain/multichain-balances-controller-init.ts @@ -2,7 +2,9 @@ import { MultichainBalancesController, MultichainBalancesControllerMessenger, } from '@metamask/assets-controllers'; +import { getIsDeprecatedController } from '../../../../shared/lib/assets-unify-state/remote-feature-flag'; import { MessengerClientInitFunction } from '../types'; +import { MultichainBalancesControllerInitMessenger } from '../messengers/multichain'; /** * Initialize the Multichain Balances controller. @@ -10,15 +12,26 @@ import { MessengerClientInitFunction } from '../types'; * @param request - The request object. * @param request.controllerMessenger - The messenger to use for the controller. * @param request.persistedState - The persisted state of the extension. + * @param request.initMessenger * @returns The initialized controller. */ export const MultichainBalancesControllerInit: MessengerClientInitFunction< MultichainBalancesController, - MultichainBalancesControllerMessenger -> = ({ controllerMessenger, persistedState }) => { + MultichainBalancesControllerMessenger, + MultichainBalancesControllerInitMessenger +> = ({ controllerMessenger, initMessenger, persistedState }) => { const messengerClient = new MultichainBalancesController({ messenger: controllerMessenger, state: persistedState.MultichainBalancesController, + isDeprecated: () => { + const { remoteFeatureFlags } = initMessenger.call( + 'RemoteFeatureFlagController:getState', + ); + return getIsDeprecatedController( + remoteFeatureFlags, + 'MultichainBalancesController', + ); + }, }); return { messengerClient }; diff --git a/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.test.ts b/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.test.ts index 1e8ba794bcc0..3595e9c31a2e 100644 --- a/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.test.ts +++ b/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.test.ts @@ -4,14 +4,21 @@ import { } from '@metamask/assets-controllers'; import { buildControllerInitRequestMock } from '../test/utils'; import { MessengerClientInitRequest } from '../types'; -import { getMultichainAssetsRatesControllerMessenger } from '../messengers/multichain'; +import { + getMultichainAssetsRatesControllerInitMessenger, + getMultichainAssetsRatesControllerMessenger, +} from '../messengers/multichain'; import { getRootMessenger } from '../../lib/messenger'; +import { MultichainAssetsRatesControllerInitMessenger } from '../messengers/multichain/multichain-assets-rates-controller-messenger'; import { MultichainAssetsRatesControllerInit } from './multichain-rates-assets-controller-init'; jest.mock('@metamask/assets-controllers'); function buildInitRequestMock(): jest.Mocked< - MessengerClientInitRequest + MessengerClientInitRequest< + MultichainAssetsRatesControllerMessenger, + MultichainAssetsRatesControllerInitMessenger + > > { const baseControllerMessenger = getRootMessenger(); @@ -20,7 +27,9 @@ function buildInitRequestMock(): jest.Mocked< controllerMessenger: getMultichainAssetsRatesControllerMessenger( baseControllerMessenger, ), - initMessenger: undefined, + initMessenger: getMultichainAssetsRatesControllerInitMessenger( + baseControllerMessenger, + ), }; } @@ -48,6 +57,7 @@ describe('MultichainAssetsRatesControllerInit', () => { messenger: requestMock.controllerMessenger, state: requestMock.persistedState.MultichainAssetsRatesController, interval: 180000, + isDeprecated: expect.any(Function), }); }); }); diff --git a/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.ts b/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.ts index ad4cf7239e76..25d4090a788e 100644 --- a/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.ts +++ b/app/scripts/messenger-client-init/multichain/multichain-rates-assets-controller-init.ts @@ -2,7 +2,9 @@ import { MultichainAssetsRatesController, MultichainAssetsRatesControllerMessenger, } from '@metamask/assets-controllers'; +import { getIsDeprecatedController } from '../../../../shared/lib/assets-unify-state/remote-feature-flag'; import { MessengerClientInitFunction } from '../types'; +import { MultichainAssetsRatesControllerInitMessenger } from '../messengers/multichain'; /** * Initialize the Multichain Assets Rate controller. @@ -10,16 +12,27 @@ import { MessengerClientInitFunction } from '../types'; * @param request - The request object. * @param request.controllerMessenger - The messenger to use for the controller. * @param request.persistedState - The persisted state of the extension. + * @param request.initMessenger * @returns The initialized controller. */ export const MultichainAssetsRatesControllerInit: MessengerClientInitFunction< MultichainAssetsRatesController, - MultichainAssetsRatesControllerMessenger -> = ({ controllerMessenger, persistedState }) => { + MultichainAssetsRatesControllerMessenger, + MultichainAssetsRatesControllerInitMessenger +> = ({ controllerMessenger, initMessenger, persistedState }) => { const messengerClient = new MultichainAssetsRatesController({ messenger: controllerMessenger, state: persistedState.MultichainAssetsRatesController, interval: 1000 * 60 * 3, // 3 mins + isDeprecated: () => { + const { remoteFeatureFlags } = initMessenger.call( + 'RemoteFeatureFlagController:getState', + ); + return getIsDeprecatedController( + remoteFeatureFlags, + 'MultichainAssetsRatesController', + ); + }, }); return { diff --git a/package.json b/package.json index 46dd8a92e31f..e028d5480a31 100644 --- a/package.json +++ b/package.json @@ -161,6 +161,7 @@ "yarn-binary:hydrate": "corepack hydrate .yarn/yarn-corepack.tgz --activate" }, "resolutions": { + "@metamask/assets-controllers": "npm:@metamask-previews/assets-controllers@108.5.0-preview-513faa49e", "@metamask/bridge-controller": "73.2.0", "@metamask/messenger@npm:^0.3.0": "^1.2.0", "@metamask/network-controller": "32.0.0", @@ -339,7 +340,7 @@ "@metamask/announcement-controller": "^8.0.0", "@metamask/approval-controller": "^9.0.0", "@metamask/assets-controller": "^8.3.1", - "@metamask/assets-controllers": "^108.4.0", + "@metamask/assets-controllers": "^108.5.0", "@metamask/base-controller": "^9.0.1", "@metamask/bitcoin-wallet-snap": "^1.12.0", "@metamask/bridge-controller": "^73.2.0", diff --git a/shared/lib/assets-unify-state/remote-feature-flag.test.ts b/shared/lib/assets-unify-state/remote-feature-flag.test.ts index 522c7ea2d0a9..20383cdd4020 100644 --- a/shared/lib/assets-unify-state/remote-feature-flag.test.ts +++ b/shared/lib/assets-unify-state/remote-feature-flag.test.ts @@ -1,4 +1,6 @@ import { + ASSETS_UNIFY_STATE_FLAG, + getIsDeprecatedController, isAssetsUnifyStateFeatureEnabled, ASSETS_UNIFY_STATE_VERSION_1, } from './remote-feature-flag'; @@ -87,3 +89,66 @@ describe('isAssetsUnifyStateFeatureEnabled', () => { }); }); }); + +describe('getIsDeprecatedController', () => { + const originalInTest = process.env.IN_TEST; + + afterEach(() => { + if (originalInTest === undefined) { + delete process.env.IN_TEST; + } else { + process.env.IN_TEST = originalInTest; + } + }); + + describe('in test environment (IN_TEST=true)', () => { + it('returns true regardless of the remote feature flags', () => { + process.env.IN_TEST = 'true'; + expect(getIsDeprecatedController(undefined, 'TokenListController')).toBe( + true, + ); + }); + }); + + describe('outside test environment (IN_TEST unset)', () => { + beforeEach(() => { + delete process.env.IN_TEST; + }); + + it('returns false when remoteFeatureFlags is undefined', () => { + expect( + getIsDeprecatedController(undefined, 'MultichainBalancesController'), + ).toBe(false); + }); + + it('returns false when controller is not in deprecatedControllers', () => { + expect( + getIsDeprecatedController( + { + [ASSETS_UNIFY_STATE_FLAG]: { + enabled: true, + featureVersion: ASSETS_UNIFY_STATE_VERSION_1, + deprecatedControllers: ['TokenListController'], + }, + }, + 'MultichainAssetsRatesController', + ), + ).toBe(false); + }); + + it('returns true when controller is in deprecatedControllers', () => { + expect( + getIsDeprecatedController( + { + [ASSETS_UNIFY_STATE_FLAG]: { + enabled: true, + featureVersion: ASSETS_UNIFY_STATE_VERSION_1, + deprecatedControllers: ['MultichainBalancesController'], + }, + }, + 'MultichainBalancesController', + ), + ).toBe(true); + }); + }); +}); diff --git a/shared/lib/assets-unify-state/remote-feature-flag.ts b/shared/lib/assets-unify-state/remote-feature-flag.ts index 1f5967791aa0..0575e9d9fe91 100644 --- a/shared/lib/assets-unify-state/remote-feature-flag.ts +++ b/shared/lib/assets-unify-state/remote-feature-flag.ts @@ -1,3 +1,5 @@ +import { RemoteFeatureFlagControllerState } from '@metamask/remote-feature-flag-controller'; + export const ASSETS_UNIFY_STATE_FLAG = 'assetsUnifyState'; export const ASSETS_UNIFY_STATE_VERSION_1 = '1'; @@ -5,6 +7,8 @@ export const ASSETS_UNIFY_STATE_VERSION_1 = '1'; export type AssetsUnifyStateFeatureFlag = { enabled: boolean; featureVersion: string | null; + minimumVersion?: string | null; + deprecatedControllers?: string[]; }; /** @@ -30,3 +34,29 @@ export const isAssetsUnifyStateFeatureEnabled = ( featureFlag?.featureVersion === featureVersion ); }; + +/** + * Returns true if the given controller is listed as deprecated in the + * assets-unify-state remote feature flag. + * + * In test environments the controller is always considered deprecated so that + * tests do not need to configure remote feature-flag state. + * + * @param remoteFeatureFlags - The remote feature flags state. + * @param controllerName - The controller name to check (e.g. 'TokenListController'). + * @returns boolean + */ +export const getIsDeprecatedController = ( + remoteFeatureFlags: RemoteFeatureFlagControllerState['remoteFeatureFlags'], + controllerName: string, +): boolean => { + if (process.env.IN_TEST) { + return true; + } + + const flag = remoteFeatureFlags?.[ASSETS_UNIFY_STATE_FLAG] as + | AssetsUnifyStateFeatureFlag + | undefined; + + return flag?.deprecatedControllers?.includes(controllerName) ?? false; +}; diff --git a/yarn.lock b/yarn.lock index 984b57e0e97a..3bb1066dcbac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5797,9 +5797,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:^108.1.0, @metamask/assets-controllers@npm:^108.2.0, @metamask/assets-controllers@npm:^108.4.0, @metamask/assets-controllers@npm:^108.5.0": - version: 108.5.0 - resolution: "@metamask/assets-controllers@npm:108.5.0" +"@metamask/assets-controllers@npm:@metamask-previews/assets-controllers@108.5.0-preview-513faa49e": + version: 108.5.0-preview-513faa49e + resolution: "@metamask-previews/assets-controllers@npm:108.5.0-preview-513faa49e" dependencies: "@ethereumjs/util": "npm:^9.1.0" "@ethersproject/abi": "npm:^5.7.0" @@ -5822,7 +5822,7 @@ __metadata: "@metamask/metamask-eth-abis": "npm:^3.1.1" "@metamask/multichain-account-service": "npm:^10.0.2" "@metamask/network-controller": "npm:^32.0.0" - "@metamask/network-enablement-controller": "npm:^5.2.0" + "@metamask/network-enablement-controller": "npm:^5.3.0" "@metamask/permission-controller": "npm:^13.1.1" "@metamask/phishing-controller": "npm:^17.2.0" "@metamask/polling-controller": "npm:^16.0.6" @@ -5833,7 +5833,7 @@ __metadata: "@metamask/snaps-sdk": "npm:^11.0.0" "@metamask/snaps-utils": "npm:^12.1.2" "@metamask/storage-service": "npm:^1.0.1" - "@metamask/transaction-controller": "npm:^66.0.1" + "@metamask/transaction-controller": "npm:^67.0.0" "@metamask/utils": "npm:^11.9.0" "@tanstack/query-core": "npm:^5.62.16" "@types/bn.js": "npm:^5.1.5" @@ -5850,7 +5850,7 @@ __metadata: peerDependencies: "@metamask/providers": ^22.0.0 webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 - checksum: 10/724c5b0a15d74fb3e28842003c4806a287b3fc31acd68dd40b6fb3eda30e70150d35dc391bd3690c4a0b413a4f215c77af04446bb8f2a348952224bc85541938 + checksum: 10/1fbd097cd35fbb6d6a5e493206a2b1f01f1db1c8feb40e1770c2fab3b4566b48a51a58e4f1bcf4908140b1fc4c25ab3d162ec63a85420ad132bcc09ee807ef99 languageName: node linkType: hard @@ -33186,7 +33186,7 @@ __metadata: "@metamask/api-specs": "npm:^0.13.0" "@metamask/approval-controller": "npm:^9.0.0" "@metamask/assets-controller": "npm:^8.3.1" - "@metamask/assets-controllers": "npm:^108.4.0" + "@metamask/assets-controllers": "npm:^108.5.0" "@metamask/auto-changelog": "npm:^5.3.1" "@metamask/base-controller": "npm:^9.0.1" "@metamask/bitcoin-wallet-snap": "npm:^1.12.0" From b0fec4cb6b78bee9a93843fe67f0d7c77dd1b3e6 Mon Sep 17 00:00:00 2001 From: Prithpal Sooriya Date: Mon, 8 Jun 2026 17:44:32 +0000 Subject: [PATCH 2/5] fix(assets): export init messenger types and fix test typings Co-authored-by: Prithpal Sooriya --- .../messenger-client-init/messengers/multichain/index.ts | 2 ++ shared/lib/assets-unify-state/remote-feature-flag.test.ts | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/scripts/messenger-client-init/messengers/multichain/index.ts b/app/scripts/messenger-client-init/messengers/multichain/index.ts index fac398ba836e..a5c9186dec89 100644 --- a/app/scripts/messenger-client-init/messengers/multichain/index.ts +++ b/app/scripts/messenger-client-init/messengers/multichain/index.ts @@ -3,9 +3,11 @@ export { getMultichainAssetsRatesControllerInitMessenger, getMultichainAssetsRatesControllerMessenger, } from './multichain-assets-rates-controller-messenger'; +export type { MultichainAssetsRatesControllerInitMessenger } from './multichain-assets-rates-controller-messenger'; export { getMultichainBalancesControllerInitMessenger, getMultichainBalancesControllerMessenger, } from './multichain-balances-controller-messenger'; +export type { MultichainBalancesControllerInitMessenger } from './multichain-balances-controller-messenger'; export { getMultichainTransactionsControllerMessenger } from './multichain-transactions-controller-messenger'; export { getMultichainNetworkControllerMessenger } from './multichain-network-controller-messenger'; diff --git a/shared/lib/assets-unify-state/remote-feature-flag.test.ts b/shared/lib/assets-unify-state/remote-feature-flag.test.ts index 20383cdd4020..f5e49ecd7d94 100644 --- a/shared/lib/assets-unify-state/remote-feature-flag.test.ts +++ b/shared/lib/assets-unify-state/remote-feature-flag.test.ts @@ -104,9 +104,7 @@ describe('getIsDeprecatedController', () => { describe('in test environment (IN_TEST=true)', () => { it('returns true regardless of the remote feature flags', () => { process.env.IN_TEST = 'true'; - expect(getIsDeprecatedController(undefined, 'TokenListController')).toBe( - true, - ); + expect(getIsDeprecatedController({}, 'TokenListController')).toBe(true); }); }); @@ -115,9 +113,9 @@ describe('getIsDeprecatedController', () => { delete process.env.IN_TEST; }); - it('returns false when remoteFeatureFlags is undefined', () => { + it('returns false when remoteFeatureFlags is empty', () => { expect( - getIsDeprecatedController(undefined, 'MultichainBalancesController'), + getIsDeprecatedController({}, 'MultichainBalancesController'), ).toBe(false); }); From ececca20e9cd7fc18f8706cecb062d7f77902430 Mon Sep 17 00:00:00 2001 From: Prithpal Sooriya Date: Mon, 8 Jun 2026 17:50:51 +0000 Subject: [PATCH 3/5] chore: retrigger CI Co-authored-by: Prithpal Sooriya From 430a91c5c1650c77b7c079ac61c3327b80faa03d Mon Sep 17 00:00:00 2001 From: Prithpal Sooriya Date: Mon, 8 Jun 2026 19:31:08 +0000 Subject: [PATCH 4/5] test(e2e): update state snapshots for deprecated multichain controllers When isDeprecated is true in test environments, MultichainAssetsRatesController and MultichainBalancesController clear conversionRates, historicalPrices, and balances to empty objects. Update metrics state snapshots and state-logs.json to match, following the TokenListController pattern from #43108. Co-authored-by: Prithpal Sooriya --- ...rs-after-init-opt-in-background-state.json | 6 +- .../errors-after-init-opt-in-ui-state.json | 6 +- ...s-before-init-opt-in-background-state.json | 7 +- .../errors-before-init-opt-in-ui-state.json | 7 +- test/e2e/tests/settings/state-logs.json | 163 +----------------- 5 files changed, 18 insertions(+), 171 deletions(-) diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index 34e8958bebca..edf45ca7bf93 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -201,10 +201,10 @@ "assetsMetadata": "object" }, "MultichainAssetsRatesController": { - "conversionRates": "object", - "historicalPrices": "object" + "conversionRates": {}, + "historicalPrices": {} }, - "MultichainBalancesController": { "balances": "object" }, + "MultichainBalancesController": { "balances": {} }, "MultichainNetworkController": "object", "MultichainRatesController": { "cryptocurrencies": ["btc", "sol"], diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json index 26e5abbf38b5..0b78004c77a1 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -103,7 +103,7 @@ "assetsInfo": "object", "assetsMetadata": "object", "assetsPrice": "object", - "balances": "object", + "balances": {}, "batchSellTrades": null, "batchSellTradesLoadingStatus": null, "browserEnvironment": { "browser": "string", "os": "string" }, @@ -117,7 +117,7 @@ "completedOnboarding": true, "connectedStatusPopoverHasBeenShown": true, "connectivityStatus": "online", - "conversionRates": "object", + "conversionRates": {}, "coverageResults": "object", "cryptocurrencies": ["btc", "sol"], "currencyRates": { @@ -190,7 +190,7 @@ "hasShownMultichainAccountsIntroModal": "boolean", "hiddenAccountList": "object", "hip3ConfigVersion": "number", - "historicalPrices": "object", + "historicalPrices": {}, "ignoredNfts": "object", "initialDelayEndTimestamp": "number", "initialEnqueueCompleted": "boolean", diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json index 48cb3ffa1821..95f36ec435fe 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json @@ -130,8 +130,11 @@ "allIgnoredAssets": "object", "assetsMetadata": "object" }, - "MultichainAssetsRatesController": { "conversionRates": "object" }, - "MultichainBalancesController": { "balances": "object" }, + "MultichainAssetsRatesController": { + "conversionRates": {}, + "historicalPrices": {} + }, + "MultichainBalancesController": { "balances": {} }, "MultichainNetworkController": "object", "MultichainRatesController": { "cryptocurrencies": ["btc", "sol"], diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json index c2602dad4a7a..87897728a179 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json @@ -137,8 +137,11 @@ "allIgnoredAssets": "object", "assetsMetadata": "object" }, - "MultichainAssetsRatesController": { "conversionRates": "object" }, - "MultichainBalancesController": { "balances": "object" }, + "MultichainAssetsRatesController": { + "conversionRates": {}, + "historicalPrices": {} + }, + "MultichainBalancesController": { "balances": {} }, "MultichainNetworkController": "object", "MultichainRatesController": { "cryptocurrencies": ["btc", "sol"], diff --git a/test/e2e/tests/settings/state-logs.json b/test/e2e/tests/settings/state-logs.json index 9828268f1eb4..e31ce6a1cbc4 100644 --- a/test/e2e/tests/settings/state-logs.json +++ b/test/e2e/tests/settings/state-logs.json @@ -485,142 +485,7 @@ "lastUpdated": "number" } }, - "balances": { - "": { - "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501": { - "unit": "string", - "amount": "string" - } - }, - "": { - "tron:728126428/slip44:195": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:195": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:195": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:195-staked-for-bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:195-staked-for-bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:195-staked-for-bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:195-staked-for-energy": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:195-staked-for-energy": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:195-staked-for-energy": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:195-ready-for-withdrawal": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:195-ready-for-withdrawal": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:195-ready-for-withdrawal": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:195-staking-rewards": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:195-staking-rewards": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:195-staking-rewards": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:195-in-lock-period": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:195-in-lock-period": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:195-in-lock-period": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:energy": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:energy": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:energy": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:maximum-energy": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:maximum-energy": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:maximum-energy": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:728126428/slip44:maximum-bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:3448148188/slip44:maximum-bandwidth": { - "unit": "string", - "amount": "string" - }, - "tron:2494104990/slip44:maximum-bandwidth": { - "unit": "string", - "amount": "string" - } - }, - "": { - "bip122:000000000019d6689c085ae165831e93/slip44:0": { - "unit": "string", - "amount": "string" - } - } - }, + "balances": {}, "batchSellTrades": "null", "batchSellTradesLoadingStatus": "null", "browserEnvironment": { @@ -640,31 +505,7 @@ "completedOnboarding": "boolean", "connectedStatusPopoverHasBeenShown": "boolean", "connectivityStatus": "string", - "conversionRates": { - "*": { - "currency": "string", - "rate": "string", - "conversionTime": "number", - "expirationTime": "number", - "marketData": { - "fungible": "boolean", - "allTimeHigh": "string", - "allTimeLow": "string", - "circulatingSupply": "string", - "marketCap": "string", - "totalVolume": "string", - "pricePercentChange": { - "PT1H": "number", - "P1D": "number", - "P7D": "number", - "P14D": "number", - "P30D": "number", - "P200D": "number", - "P1Y": "number" - } - } - } - }, + "conversionRates": {}, "coverageResults": {}, "cryptocurrencies": ["string"], "currencyRates": { From a5f6c157cbf9732816de7379784220b678ead844 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 8 Jun 2026 20:00:40 +0000 Subject: [PATCH 5/5] test(e2e): revert multichain sentry snapshots to object type strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sentry maskObject reports typeof for MultichainBalancesController.balances and MultichainAssetsRatesController rate fields, so deprecated empty state still serializes as "object" — unlike TokenListController.tokensChainsCache which uses an AllProperties sub-mask and snapshots as {}. Co-authored-by: Prithpal Sooriya --- .../errors-after-init-opt-in-background-state.json | 6 +++--- .../state-snapshots/errors-after-init-opt-in-ui-state.json | 6 +++--- .../errors-before-init-opt-in-background-state.json | 7 ++----- .../errors-before-init-opt-in-ui-state.json | 7 ++----- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index edf45ca7bf93..34e8958bebca 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -201,10 +201,10 @@ "assetsMetadata": "object" }, "MultichainAssetsRatesController": { - "conversionRates": {}, - "historicalPrices": {} + "conversionRates": "object", + "historicalPrices": "object" }, - "MultichainBalancesController": { "balances": {} }, + "MultichainBalancesController": { "balances": "object" }, "MultichainNetworkController": "object", "MultichainRatesController": { "cryptocurrencies": ["btc", "sol"], diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json index 0b78004c77a1..26e5abbf38b5 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -103,7 +103,7 @@ "assetsInfo": "object", "assetsMetadata": "object", "assetsPrice": "object", - "balances": {}, + "balances": "object", "batchSellTrades": null, "batchSellTradesLoadingStatus": null, "browserEnvironment": { "browser": "string", "os": "string" }, @@ -117,7 +117,7 @@ "completedOnboarding": true, "connectedStatusPopoverHasBeenShown": true, "connectivityStatus": "online", - "conversionRates": {}, + "conversionRates": "object", "coverageResults": "object", "cryptocurrencies": ["btc", "sol"], "currencyRates": { @@ -190,7 +190,7 @@ "hasShownMultichainAccountsIntroModal": "boolean", "hiddenAccountList": "object", "hip3ConfigVersion": "number", - "historicalPrices": {}, + "historicalPrices": "object", "ignoredNfts": "object", "initialDelayEndTimestamp": "number", "initialEnqueueCompleted": "boolean", diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json index 95f36ec435fe..48cb3ffa1821 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json @@ -130,11 +130,8 @@ "allIgnoredAssets": "object", "assetsMetadata": "object" }, - "MultichainAssetsRatesController": { - "conversionRates": {}, - "historicalPrices": {} - }, - "MultichainBalancesController": { "balances": {} }, + "MultichainAssetsRatesController": { "conversionRates": "object" }, + "MultichainBalancesController": { "balances": "object" }, "MultichainNetworkController": "object", "MultichainRatesController": { "cryptocurrencies": ["btc", "sol"], diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json index 87897728a179..c2602dad4a7a 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json @@ -137,11 +137,8 @@ "allIgnoredAssets": "object", "assetsMetadata": "object" }, - "MultichainAssetsRatesController": { - "conversionRates": {}, - "historicalPrices": {} - }, - "MultichainBalancesController": { "balances": {} }, + "MultichainAssetsRatesController": { "conversionRates": "object" }, + "MultichainBalancesController": { "balances": "object" }, "MultichainNetworkController": "object", "MultichainRatesController": { "cryptocurrencies": ["btc", "sol"],