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..a5c9186dec89 100644 --- a/app/scripts/messenger-client-init/messengers/multichain/index.ts +++ b/app/scripts/messenger-client-init/messengers/multichain/index.ts @@ -1,5 +1,13 @@ 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 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/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 9d7e46493ed7..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", 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..f5e49ecd7d94 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,64 @@ 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({}, 'TokenListController')).toBe(true); + }); + }); + + describe('outside test environment (IN_TEST unset)', () => { + beforeEach(() => { + delete process.env.IN_TEST; + }); + + it('returns false when remoteFeatureFlags is empty', () => { + expect( + getIsDeprecatedController({}, '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/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": { diff --git a/yarn.lock b/yarn.lock index b02da51b2cfd..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.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