From f10d8590658c1f1442d2ec9f4438d2a2c7bb131a Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Tue, 9 Sep 2025 22:45:53 +0200 Subject: [PATCH 1/2] refactor: migrate MultichainTransactionsController to @metamask/messenger --- .../CHANGELOG.md | 2 + .../package.json | 1 + .../MultichainTransactionsController.test.ts | 157 ++++++++++++------ .../src/MultichainTransactionsController.ts | 36 ++-- .../tsconfig.build.json | 3 +- .../tsconfig.json | 3 +- yarn.lock | 1 + 7 files changed, 126 insertions(+), 77 deletions(-) diff --git a/packages/multichain-transactions-controller/CHANGELOG.md b/packages/multichain-transactions-controller/CHANGELOG.md index f3b5f5d7107..e707efa4dd4 100644 --- a/packages/multichain-transactions-controller/CHANGELOG.md +++ b/packages/multichain-transactions-controller/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6542](https://github.com/MetaMask/core/pull/6542)) + - Previously, `MultichainTransactionsController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`. - Bump `@metamask/base-controller` from `^8.1.0` to `^8.4.0` ([#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632)) - Bump `@metamask/keyring-api` from `^20.1.0` to `^21.0.0` ([#6560](https://github.com/MetaMask/core/pull/6560)) - Bump `@metamask/keyring-internal-api` from `^8.1.0` to `^9.0.0` ([#6560](https://github.com/MetaMask/core/pull/6560)) diff --git a/packages/multichain-transactions-controller/package.json b/packages/multichain-transactions-controller/package.json index 1c47b1add14..29ab419b0db 100644 --- a/packages/multichain-transactions-controller/package.json +++ b/packages/multichain-transactions-controller/package.json @@ -51,6 +51,7 @@ "@metamask/keyring-api": "^21.0.0", "@metamask/keyring-internal-api": "^9.0.0", "@metamask/keyring-snap-client": "^8.0.0", + "@metamask/messenger": "^0.3.0", "@metamask/polling-controller": "^14.0.0", "@metamask/snaps-sdk": "^9.0.0", "@metamask/snaps-utils": "^11.0.0", diff --git a/packages/multichain-transactions-controller/src/MultichainTransactionsController.test.ts b/packages/multichain-transactions-controller/src/MultichainTransactionsController.test.ts index d15208b8b34..cd08a82e923 100644 --- a/packages/multichain-transactions-controller/src/MultichainTransactionsController.test.ts +++ b/packages/multichain-transactions-controller/src/MultichainTransactionsController.test.ts @@ -1,4 +1,4 @@ -import { deriveStateFromMetadata, Messenger } from '@metamask/base-controller'; +import { deriveStateFromMetadata } from '@metamask/base-controller/next'; import type { AccountTransactionsUpdatedEventPayload, CaipAssetType, @@ -15,6 +15,13 @@ import { } from '@metamask/keyring-api'; import { KeyringTypes } from '@metamask/keyring-controller'; import type { InternalAccount } from '@metamask/keyring-internal-api'; +import { + Messenger, + MOCK_ANY_NAMESPACE, + type MessengerActions, + type MessengerEvents, + type MockAnyNamespace, +} from '@metamask/messenger'; import type { CaipChainId } from '@metamask/utils'; import { v4 as uuidv4 } from 'uuid'; @@ -22,8 +29,6 @@ import { MultichainNetwork } from './constants'; import { MultichainTransactionsController, getDefaultMultichainTransactionsControllerState, - type AllowedActions, - type AllowedEvents, type MultichainTransactionsControllerState, type MultichainTransactionsControllerMessenger, } from './MultichainTransactionsController'; @@ -127,6 +132,31 @@ const mockTransactionResult = { next: null, }; +const controllerName = 'MultichainTransactionsController'; + +type AllMultichainTransactionsControllerActions = + MessengerActions; + +type AllMultichainTransactionsControllerEvents = + MessengerEvents; + +type RootMessenger = Messenger< + MockAnyNamespace, + AllMultichainTransactionsControllerActions, + AllMultichainTransactionsControllerEvents +>; + +/** + * Creates and returns a root messenger for testing + * + * @returns A messenger instance + */ +function getRootMessenger(): RootMessenger { + return new Messenger({ + namespace: MOCK_ANY_NAMESPACE, + }); +} + const setupController = ({ state = getDefaultMultichainTransactionsControllerState(), mocks, @@ -136,26 +166,41 @@ const setupController = ({ listMultichainAccounts?: InternalAccount[]; handleRequestReturnValue?: TransactionsPage; }; -} = {}) => { - const messenger = new Messenger(); - - const multichainTransactionsControllerMessenger: MultichainTransactionsControllerMessenger = - messenger.getRestricted({ - name: 'MultichainTransactionsController', - allowedActions: [ - 'SnapController:handleRequest', - 'AccountsController:listMultichainAccounts', - 'KeyringController:getState', - ], - allowedEvents: [ - 'AccountsController:accountAdded', - 'AccountsController:accountRemoved', - 'AccountsController:accountTransactionsUpdated', - ], - }); +} = {}): { + controller: MultichainTransactionsController; + rootMessenger: RootMessenger; + messenger: MultichainTransactionsControllerMessenger; + mockSnapHandleRequest: jest.Mock; + mockListMultichainAccounts: jest.Mock; + mockGetKeyringState: jest.Mock; +} => { + const rootMessenger = getRootMessenger(); + + const multichainTransactionsControllerMessenger = new Messenger< + typeof controllerName, + AllMultichainTransactionsControllerActions, + AllMultichainTransactionsControllerEvents, + RootMessenger + >({ + namespace: controllerName, + parent: rootMessenger, + }); + rootMessenger.delegate({ + messenger: multichainTransactionsControllerMessenger, + actions: [ + 'SnapController:handleRequest', + 'AccountsController:listMultichainAccounts', + 'KeyringController:getState', + ], + events: [ + 'AccountsController:accountAdded', + 'AccountsController:accountRemoved', + 'AccountsController:accountTransactionsUpdated', + ], + }); const mockSnapHandleRequest = jest.fn(); - messenger.registerActionHandler( + rootMessenger.registerActionHandler( 'SnapController:handleRequest', mockSnapHandleRequest.mockReturnValue( mocks?.handleRequestReturnValue ?? mockTransactionResult, @@ -163,7 +208,7 @@ const setupController = ({ ); const mockListMultichainAccounts = jest.fn(); - messenger.registerActionHandler( + rootMessenger.registerActionHandler( 'AccountsController:listMultichainAccounts', mockListMultichainAccounts.mockReturnValue( mocks?.listMultichainAccounts ?? [mockBtcAccount, mockEthAccount], @@ -173,7 +218,7 @@ const setupController = ({ const mockGetKeyringState = jest.fn().mockReturnValue({ isUnlocked: true, }); - messenger.registerActionHandler( + rootMessenger.registerActionHandler( 'KeyringController:getState', mockGetKeyringState, ); @@ -185,7 +230,8 @@ const setupController = ({ return { controller, - messenger, + rootMessenger, + messenger: multichainTransactionsControllerMessenger, mockSnapHandleRequest, mockListMultichainAccounts, mockGetKeyringState, @@ -216,7 +262,7 @@ describe('MultichainTransactionsController', () => { }); it('updates transactions when "AccountsController:accountAdded" is fired', async () => { - const { controller, messenger, mockListMultichainAccounts } = + const { controller, rootMessenger, mockListMultichainAccounts } = setupController({ mocks: { listMultichainAccounts: [], @@ -224,7 +270,7 @@ describe('MultichainTransactionsController', () => { }); mockListMultichainAccounts.mockReturnValue([mockBtcAccount]); - messenger.publish('AccountsController:accountAdded', mockBtcAccount); + rootMessenger.publish('AccountsController:accountAdded', mockBtcAccount); await waitForAllPromises(); @@ -239,7 +285,7 @@ describe('MultichainTransactionsController', () => { }); it('updates transactions when "AccountsController:accountRemoved" is fired', async () => { - const { controller, messenger, mockListMultichainAccounts } = + const { controller, rootMessenger, mockListMultichainAccounts } = setupController(); await controller.updateTransactionsForAccount(mockBtcAccount.id); @@ -253,14 +299,17 @@ describe('MultichainTransactionsController', () => { lastUpdated: expect.any(Number), }); - messenger.publish('AccountsController:accountRemoved', mockBtcAccount.id); + rootMessenger.publish( + 'AccountsController:accountRemoved', + mockBtcAccount.id, + ); mockListMultichainAccounts.mockReturnValue([]); expect(controller.state.nonEvmTransactions).toStrictEqual({}); }); it('does not track balances for EVM accounts', async () => { - const { controller, messenger, mockListMultichainAccounts } = + const { controller, rootMessenger, mockListMultichainAccounts } = setupController({ mocks: { listMultichainAccounts: [], @@ -268,7 +317,7 @@ describe('MultichainTransactionsController', () => { }); mockListMultichainAccounts.mockReturnValue([mockEthAccount]); - messenger.publish('AccountsController:accountAdded', mockEthAccount); + rootMessenger.publish('AccountsController:accountAdded', mockEthAccount); expect(controller.state).toStrictEqual({ nonEvmTransactions: {}, @@ -503,7 +552,7 @@ describe('MultichainTransactionsController', () => { chain, }; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: { [mockSolAccountWithId.id]: { @@ -517,7 +566,7 @@ describe('MultichainTransactionsController', () => { }, }); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [mockSolAccountWithId.id]: [updatedExistingTransaction, newTransaction], }, @@ -536,7 +585,7 @@ describe('MultichainTransactionsController', () => { it('handles empty transaction updates gracefully', async () => { const { chain } = mockTransactionResult.data[0]; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: { [TEST_ACCOUNT_ID]: { @@ -550,7 +599,7 @@ describe('MultichainTransactionsController', () => { }, }); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: {}, }); @@ -568,13 +617,13 @@ describe('MultichainTransactionsController', () => { it('initializes new accounts with empty transactions array when receiving updates', async () => { const { chain } = mockTransactionResult.data[0]; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: {}, }, }); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [NEW_ACCOUNT_ID]: mockTransactionResult.data, }, @@ -592,7 +641,7 @@ describe('MultichainTransactionsController', () => { it('handles undefined transactions in update payload', async () => { const { chain } = mockTransactionResult.data[0]; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: { [TEST_ACCOUNT_ID]: { @@ -622,7 +671,7 @@ describe('MultichainTransactionsController', () => { }, }; - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: undefined, } as unknown as AccountTransactionsUpdatedEventPayload); @@ -646,7 +695,7 @@ describe('MultichainTransactionsController', () => { timestamp: 2000, }; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: { [TEST_ACCOUNT_ID]: { @@ -660,7 +709,7 @@ describe('MultichainTransactionsController', () => { }, }); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [TEST_ACCOUNT_ID]: [newerTransaction], }, @@ -694,7 +743,7 @@ describe('MultichainTransactionsController', () => { timestamp: 1000, }; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: { [TEST_ACCOUNT_ID]: { @@ -708,7 +757,7 @@ describe('MultichainTransactionsController', () => { }, }); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [TEST_ACCOUNT_ID]: [withTimestampTx, nullTimestampTx2], }, @@ -783,7 +832,7 @@ describe('MultichainTransactionsController', () => { chain: MultichainNetwork.SolanaDevnet, }; - const { controller, messenger } = setupController({ + const { controller, rootMessenger } = setupController({ state: { nonEvmTransactions: { [mockSolAccountWithId.id]: { @@ -797,7 +846,7 @@ describe('MultichainTransactionsController', () => { }, }); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [mockSolAccountWithId.id]: [mainnetTransaction, devnetTransaction], }, @@ -833,7 +882,7 @@ describe('MultichainTransactionsController', () => { }); it('publishes transactionConfirmed event when transaction is confirmed', async () => { - const { messenger } = setupController(); + const { rootMessenger, messenger } = setupController(); const confirmedTransaction = { ...mockTransactionResult.data[0], @@ -843,7 +892,7 @@ describe('MultichainTransactionsController', () => { const publishSpy = jest.spyOn(messenger, 'publish'); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [mockBtcAccount.id]: [confirmedTransaction], }, @@ -858,7 +907,7 @@ describe('MultichainTransactionsController', () => { }); it('publishes transactionSubmitted event when transaction is submitted', async () => { - const { messenger } = setupController(); + const { rootMessenger, messenger } = setupController(); const submittedTransaction = { ...mockTransactionResult.data[0], @@ -868,7 +917,7 @@ describe('MultichainTransactionsController', () => { const publishSpy = jest.spyOn(messenger, 'publish'); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [mockBtcAccount.id]: [submittedTransaction], }, @@ -883,7 +932,7 @@ describe('MultichainTransactionsController', () => { }); it('does not publish events for other transaction statuses', async () => { - const { messenger } = setupController(); + const { rootMessenger } = setupController(); const pendingTransaction = { ...mockTransactionResult.data[0], @@ -891,9 +940,9 @@ describe('MultichainTransactionsController', () => { status: 'unconfirmed' as const, }; - const publishSpy = jest.spyOn(messenger, 'publish'); + const publishSpy = jest.spyOn(rootMessenger, 'publish'); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [mockBtcAccount.id]: [pendingTransaction], }, @@ -912,7 +961,7 @@ describe('MultichainTransactionsController', () => { }); it('publishes correct events for multiple transactions with different statuses', async () => { - const { messenger } = setupController(); + const { rootMessenger, messenger } = setupController(); const transactions = [ { @@ -934,7 +983,7 @@ describe('MultichainTransactionsController', () => { const publishSpy = jest.spyOn(messenger, 'publish'); - messenger.publish('AccountsController:accountTransactionsUpdated', { + rootMessenger.publish('AccountsController:accountTransactionsUpdated', { transactions: { [mockBtcAccount.id]: transactions, }, @@ -960,7 +1009,7 @@ describe('MultichainTransactionsController', () => { deriveStateFromMetadata( controller.state, controller.metadata, - 'anonymous', + 'includeInDebugSnapshot', ), ).toMatchInlineSnapshot(`Object {}`); }); diff --git a/packages/multichain-transactions-controller/src/MultichainTransactionsController.ts b/packages/multichain-transactions-controller/src/MultichainTransactionsController.ts index 021f3fce71a..43527357518 100644 --- a/packages/multichain-transactions-controller/src/MultichainTransactionsController.ts +++ b/packages/multichain-transactions-controller/src/MultichainTransactionsController.ts @@ -8,8 +8,7 @@ import { BaseController, type ControllerGetStateAction, type ControllerStateChangeEvent, - type RestrictedMessenger, -} from '@metamask/base-controller'; +} from '@metamask/base-controller/next'; import { isEvmAccountType, type Transaction, @@ -19,6 +18,7 @@ import { import type { KeyringControllerGetStateAction } from '@metamask/keyring-controller'; import type { InternalAccount } from '@metamask/keyring-internal-api'; import { KeyringClient } from '@metamask/keyring-snap-client'; +import type { Messenger } from '@metamask/messenger'; import type { HandleSnapRequest } from '@metamask/snaps-controllers'; import type { SnapId } from '@metamask/snaps-sdk'; import { HandlerType } from '@metamask/snaps-utils'; @@ -116,18 +116,16 @@ export type MultichainTransactionsControllerEvents = /** * Messenger type for the MultichainTransactionsController. */ -export type MultichainTransactionsControllerMessenger = RestrictedMessenger< +export type MultichainTransactionsControllerMessenger = Messenger< typeof controllerName, MultichainTransactionsControllerActions | AllowedActions, - MultichainTransactionsControllerEvents | AllowedEvents, - AllowedActions['type'], - AllowedEvents['type'] + MultichainTransactionsControllerEvents | AllowedEvents >; /** * Actions that this controller is allowed to call. */ -export type AllowedActions = +type AllowedActions = | HandleSnapRequest | KeyringControllerGetStateAction | AccountsControllerListMultichainAccountsAction; @@ -135,7 +133,7 @@ export type AllowedActions = /** * Events that this controller is allowed to subscribe. */ -export type AllowedEvents = +type AllowedEvents = | AccountsControllerAccountAddedEvent | AccountsControllerAccountRemovedEvent | AccountsControllerAccountTransactionsUpdatedEvent; @@ -151,7 +149,7 @@ const multichainTransactionsControllerMetadata = { nonEvmTransactions: { includeInStateLogs: true, persist: true, - anonymous: false, + includeInDebugSnapshot: false, usedInUi: true, }, }; @@ -201,15 +199,15 @@ export class MultichainTransactionsController extends BaseController< }); } - this.messagingSystem.subscribe( + this.messenger.subscribe( 'AccountsController:accountAdded', (account: InternalAccount) => this.#handleOnAccountAdded(account), ); - this.messagingSystem.subscribe( + this.messenger.subscribe( 'AccountsController:accountRemoved', (accountId: string) => this.#handleOnAccountRemoved(accountId), ); - this.messagingSystem.subscribe( + this.messenger.subscribe( 'AccountsController:accountTransactionsUpdated', (transactionsUpdate: AccountTransactionsUpdatedEventPayload) => this.#handleOnAccountTransactionsUpdated(transactionsUpdate), @@ -222,9 +220,7 @@ export class MultichainTransactionsController extends BaseController< * @returns A list of multichain accounts. */ #listMultichainAccounts(): InternalAccount[] { - return this.messagingSystem.call( - 'AccountsController:listMultichainAccounts', - ); + return this.messenger.call('AccountsController:listMultichainAccounts'); } /** @@ -266,9 +262,7 @@ export class MultichainTransactionsController extends BaseController< * @param accountId - The ID of the account to get transactions for. */ async updateTransactionsForAccount(accountId: string) { - const { isUnlocked } = this.messagingSystem.call( - 'KeyringController:getState', - ); + const { isUnlocked } = this.messenger.call('KeyringController:getState'); if (!isUnlocked) { return; @@ -373,14 +367,14 @@ export class MultichainTransactionsController extends BaseController< */ #publishTransactionUpdateEvent(updatedTransaction: Transaction) { if (updatedTransaction.status === TransactionStatus.Confirmed) { - this.messagingSystem.publish( + this.messenger.publish( 'MultichainTransactionsController:transactionConfirmed', updatedTransaction, ); } if (updatedTransaction.status === TransactionStatus.Submitted) { - this.messagingSystem.publish( + this.messenger.publish( 'MultichainTransactionsController:transactionSubmitted', updatedTransaction, ); @@ -481,7 +475,7 @@ export class MultichainTransactionsController extends BaseController< #getClient(snapId: string): KeyringClient { return new KeyringClient({ send: async (request: JsonRpcRequest) => - (await this.messagingSystem.call('SnapController:handleRequest', { + (await this.messenger.call('SnapController:handleRequest', { snapId: snapId as SnapId, origin: 'metamask', handler: HandlerType.OnKeyringRequest, diff --git a/packages/multichain-transactions-controller/tsconfig.build.json b/packages/multichain-transactions-controller/tsconfig.build.json index 048cb0e3bef..695c01cd3df 100644 --- a/packages/multichain-transactions-controller/tsconfig.build.json +++ b/packages/multichain-transactions-controller/tsconfig.build.json @@ -9,7 +9,8 @@ { "path": "../accounts-controller/tsconfig.build.json" }, { "path": "../base-controller/tsconfig.build.json" }, { "path": "../keyring-controller/tsconfig.build.json" }, - { "path": "../polling-controller/tsconfig.build.json" } + { "path": "../polling-controller/tsconfig.build.json" }, + { "path": "../messenger/tsconfig.build.json" } ], "include": ["../../types", "./src"] } diff --git a/packages/multichain-transactions-controller/tsconfig.json b/packages/multichain-transactions-controller/tsconfig.json index e0331deb7e0..ce215a73944 100644 --- a/packages/multichain-transactions-controller/tsconfig.json +++ b/packages/multichain-transactions-controller/tsconfig.json @@ -7,7 +7,8 @@ { "path": "../accounts-controller" }, { "path": "../base-controller" }, { "path": "../keyring-controller" }, - { "path": "../polling-controller" } + { "path": "../polling-controller" }, + { "path": "../messenger" } ], "include": ["../../types", "./src"] } diff --git a/yarn.lock b/yarn.lock index 8dbaec41939..eab8a135357 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3961,6 +3961,7 @@ __metadata: "@metamask/keyring-controller": "npm:^23.1.0" "@metamask/keyring-internal-api": "npm:^9.0.0" "@metamask/keyring-snap-client": "npm:^8.0.0" + "@metamask/messenger": "npm:^0.3.0" "@metamask/polling-controller": "npm:^14.0.0" "@metamask/snaps-controllers": "npm:^14.0.1" "@metamask/snaps-sdk": "npm:^9.0.0" From 83f388baa2ac1cb811baf9171e501e1d513e0980 Mon Sep 17 00:00:00 2001 From: Michele Esposito Date: Fri, 24 Oct 2025 19:32:11 +0200 Subject: [PATCH 2/2] update readme and changelog --- README.md | 1 + packages/multichain-transactions-controller/CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index ba3b7ae26f8..9f86c278243 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,7 @@ linkStyle default opacity:0.5 multichain_network_controller --> keyring_controller; multichain_network_controller --> network_controller; multichain_transactions_controller --> base_controller; + multichain_transactions_controller --> messenger; multichain_transactions_controller --> polling_controller; multichain_transactions_controller --> accounts_controller; multichain_transactions_controller --> keyring_controller; diff --git a/packages/multichain-transactions-controller/CHANGELOG.md b/packages/multichain-transactions-controller/CHANGELOG.md index 0bcf93dc0c0..186af6f545d 100644 --- a/packages/multichain-transactions-controller/CHANGELOG.md +++ b/packages/multichain-transactions-controller/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6542](https://github.com/MetaMask/core/pull/6542)) - Previously, `MultichainTransactionsController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`. +- **BREAKING:** Metadata property `anonymous` renamed to `includeInDebugSnapshot` ([#6542](https://github.com/MetaMask/core/pull/6542)) ## [5.1.0]