Skip to content

Commit 320f696

Browse files
refactor: migrate MultichainNetworkController to @metamask/messenger (#6543)
## Explanation <!-- Thanks for your contribution! Take a moment to answer these questions so that reviewers have the information they need to properly understand your changes: * What is the current state of things and why does it need to change? * What is the solution your changes offer and how does it work? * Are there any changes whose purpose might not obvious to those unfamiliar with the domain? * If your primary goal was to update one package but you found you had to update another one along the way, why did you do so? * If you had to upgrade a dependency, why did you do so? --> This PR migrates `MultichainNetworkController` to the new `@metamask/messenger` message bus, as opposed to the one exported from `@metamask/base-controller`. ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? For example: * Fixes #12345 * Related to #67890 --> * Related to #5626 ## 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](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [ ] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Migrates `MultichainNetworkController` to the new `@metamask/messenger`, updates types/imports to `@metamask/base-controller/next`, renames metadata flag, and refactors tests and deps accordingly. > > - **MultichainNetworkController**: > - Migrate from `RestrictedMessenger` to new `Messenger` (`@metamask/messenger`), replacing `messagingSystem.*` with `messenger.*` calls. > - Register/subscribe via `messenger.registerActionHandler` and `messenger.subscribe`; publish `MultichainNetworkController:networkDidChange` via new messenger. > - **Types/Constants**: > - Switch imports to `@metamask/base-controller/next`. > - Update `MultichainNetworkControllerMessenger` type to use `Messenger` and adjust allowed actions/events. > - Rename metadata property `anonymous` to `includeInDebugSnapshot` in `MULTICHAIN_NETWORK_CONTROLLER_METADATA` and tests. > - **Tests**: > - Refactor to construct root/child messengers (`MOCK_ANY_NAMESPACE`, `delegate`) and update spies/mocks accordingly. > - **Dependencies/Docs**: > - Add `@metamask/messenger` dependency in `package.json` and reflect in README dependency graph. > - Update changelog with breaking changes. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8067340. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Michele Esposito <[email protected]>
1 parent 2bdfdea commit 320f696

File tree

8 files changed

+86
-63
lines changed

8 files changed

+86
-63
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ linkStyle default opacity:0.5
272272
multichain_api_middleware --> multichain_transactions_controller;
273273
multichain_network_controller --> base_controller;
274274
multichain_network_controller --> controller_utils;
275+
multichain_network_controller --> messenger;
275276
multichain_network_controller --> accounts_controller;
276277
multichain_network_controller --> keyring_controller;
277278
multichain_network_controller --> network_controller;

packages/multichain-network-controller/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6543](https://github.com/MetaMask/core/pull/6543))
13+
- Previously, `MultichainNetworkController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`.
14+
- **BREAKING:** Metadata property `anonymous` renamed to `includeInDebugSnapshot` ([#6543](https://github.com/MetaMask/core/pull/6543))
15+
1016
## [1.0.2]
1117

1218
### Changed

packages/multichain-network-controller/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"@metamask/controller-utils": "^11.14.1",
5252
"@metamask/keyring-api": "^21.0.0",
5353
"@metamask/keyring-internal-api": "^9.0.0",
54+
"@metamask/messenger": "^0.3.0",
5455
"@metamask/superstruct": "^3.1.0",
5556
"@metamask/utils": "^11.8.1",
5657
"@solana/addresses": "^2.0.0",

packages/multichain-network-controller/src/MultichainNetworkController/MultichainNetworkController.test.ts

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Messenger, deriveStateFromMetadata } from '@metamask/base-controller';
1+
import { deriveStateFromMetadata } from '@metamask/base-controller/next';
22
import { InfuraNetworkType } from '@metamask/controller-utils';
33
import type { AnyAccountType } from '@metamask/keyring-api';
44
import {
@@ -12,6 +12,13 @@ import {
1212
EthScope,
1313
TrxAccountType,
1414
} from '@metamask/keyring-api';
15+
import {
16+
Messenger,
17+
MOCK_ANY_NAMESPACE,
18+
type MessengerActions,
19+
type MessengerEvents,
20+
type MockAnyNamespace,
21+
} from '@metamask/messenger';
1522
import type {
1623
NetworkControllerGetStateAction,
1724
NetworkControllerSetActiveNetworkAction,
@@ -26,13 +33,7 @@ import { createMockInternalAccount } from '../../tests/utils';
2633
import { type ActiveNetworksResponse } from '../api/accounts-api';
2734
import { getDefaultMultichainNetworkControllerState } from '../constants';
2835
import type { AbstractMultichainNetworkService } from '../MultichainNetworkService/AbstractMultichainNetworkService';
29-
import {
30-
type AllowedActions,
31-
type AllowedEvents,
32-
type MultichainNetworkControllerAllowedActions,
33-
type MultichainNetworkControllerAllowedEvents,
34-
MULTICHAIN_NETWORK_CONTROLLER_NAME,
35-
} from '../types';
36+
import type { MultichainNetworkControllerMessenger } from '../types';
3637

3738
// We exclude the generic account type, since it's used for testing purposes.
3839
type TestKeyringAccountType = Exclude<
@@ -56,6 +57,32 @@ function createMockNetworkService(
5657
};
5758
}
5859

60+
const controllerName = 'MultichainNetworkController';
61+
62+
type AllMultichainNetworkControllerActions =
63+
MessengerActions<MultichainNetworkControllerMessenger>;
64+
65+
type AllMultichainNetworkControllerEvents =
66+
MessengerEvents<MultichainNetworkControllerMessenger>;
67+
68+
type RootMessenger = Messenger<
69+
MockAnyNamespace,
70+
AllMultichainNetworkControllerActions,
71+
AllMultichainNetworkControllerEvents,
72+
RootMessenger
73+
>;
74+
75+
/**
76+
* Creates and returns a root messenger for testing
77+
*
78+
* @returns A messenger instance
79+
*/
80+
function getRootMessenger(): RootMessenger {
81+
return new Messenger({
82+
namespace: MOCK_ANY_NAMESPACE,
83+
});
84+
}
85+
5986
/**
6087
* Setup a test controller instance.
6188
*
@@ -103,12 +130,7 @@ function setupController({
103130
>;
104131
mockNetworkService?: AbstractMultichainNetworkService;
105132
} = {}) {
106-
const messenger = new Messenger<
107-
MultichainNetworkControllerAllowedActions,
108-
MultichainNetworkControllerAllowedEvents
109-
>();
110-
111-
const publishSpy = jest.spyOn(messenger, 'publish');
133+
const messenger = getRootMessenger();
112134

113135
// Register action handlers
114136
const mockGetNetworkState =
@@ -168,21 +190,27 @@ function setupController({
168190
mockFindNetworkClientIdByChainId,
169191
);
170192

171-
const controllerMessenger = messenger.getRestricted<
172-
typeof MULTICHAIN_NETWORK_CONTROLLER_NAME,
173-
AllowedActions['type'],
174-
AllowedEvents['type']
193+
const controllerMessenger = new Messenger<
194+
typeof controllerName,
195+
AllMultichainNetworkControllerActions,
196+
AllMultichainNetworkControllerEvents,
197+
RootMessenger
175198
>({
176-
name: MULTICHAIN_NETWORK_CONTROLLER_NAME,
177-
allowedActions: [
199+
namespace: controllerName,
200+
parent: messenger,
201+
});
202+
203+
messenger.delegate({
204+
messenger: controllerMessenger,
205+
actions: [
178206
'NetworkController:setActiveNetwork',
179207
'NetworkController:getState',
180208
'NetworkController:removeNetwork',
181209
'NetworkController:getSelectedChainId',
182210
'NetworkController:findNetworkClientIdByChainId',
183211
'AccountsController:listMultichainAccounts',
184212
],
185-
allowedEvents: ['AccountsController:selectedAccountChange'],
213+
events: ['AccountsController:selectedAccountChange'],
186214
});
187215

188216
const defaultNetworkService = createMockNetworkService();
@@ -224,6 +252,8 @@ function setupController({
224252
messenger.publish('AccountsController:selectedAccountChange', mockAccount);
225253
};
226254

255+
const publishSpy = jest.spyOn(controllerMessenger, 'publish');
256+
227257
return {
228258
messenger,
229259
controller,
@@ -662,7 +692,7 @@ describe('MultichainNetworkController', () => {
662692
deriveStateFromMetadata(
663693
controller.state,
664694
controller.metadata,
665-
'anonymous',
695+
'includeInDebugSnapshot',
666696
),
667697
).toMatchInlineSnapshot(`
668698
Object {

packages/multichain-network-controller/src/MultichainNetworkController/MultichainNetworkController.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BaseController } from '@metamask/base-controller';
1+
import { BaseController } from '@metamask/base-controller/next';
22
import { isEvmAccountType } from '@metamask/keyring-api';
33
import type { InternalAccount } from '@metamask/keyring-internal-api';
44
import type { NetworkClientId } from '@metamask/network-controller';
@@ -76,7 +76,7 @@ export class MultichainNetworkController extends BaseController<
7676
* @param id - The client ID of the EVM network to set active.
7777
*/
7878
async #setActiveEvmNetwork(id: NetworkClientId): Promise<void> {
79-
const { selectedNetworkClientId } = this.messagingSystem.call(
79+
const { selectedNetworkClientId } = this.messenger.call(
8080
'NetworkController:getState',
8181
);
8282

@@ -97,12 +97,12 @@ export class MultichainNetworkController extends BaseController<
9797

9898
// Only notify the network controller if the selected evm network is different
9999
if (shouldNotifyNetworkChange) {
100-
await this.messagingSystem.call('NetworkController:setActiveNetwork', id);
100+
await this.messenger.call('NetworkController:setActiveNetwork', id);
101101
}
102102

103103
// Only publish the networkDidChange event if either the EVM network is different or we're switching between EVM and non-EVM networks
104104
if (shouldSetEvmActive || shouldNotifyNetworkChange) {
105-
this.messagingSystem.publish(
105+
this.messenger.publish(
106106
'MultichainNetworkController:networkDidChange',
107107
id,
108108
);
@@ -129,10 +129,7 @@ export class MultichainNetworkController extends BaseController<
129129
});
130130

131131
// Notify listeners that the network changed
132-
this.messagingSystem.publish(
133-
'MultichainNetworkController:networkDidChange',
134-
id,
135-
);
132+
this.messenger.publish('MultichainNetworkController:networkDidChange', id);
136133
}
137134

138135
/**
@@ -164,7 +161,7 @@ export class MultichainNetworkController extends BaseController<
164161
async getNetworksWithTransactionActivityByAccounts(): Promise<ActiveNetworksByAddress> {
165162
// TODO: We are filtering out non-EVN accounts for now
166163
// Support for non-EVM networks will be added in the coming weeks
167-
const evmAccounts = this.messagingSystem
164+
const evmAccounts = this.messenger
168165
.call('AccountsController:listMultichainAccounts')
169166
.filter((account) => isEvmAccountType(account.type));
170167

@@ -196,7 +193,7 @@ export class MultichainNetworkController extends BaseController<
196193
*/
197194
async #removeEvmNetwork(chainId: CaipChainId): Promise<void> {
198195
const hexChainId = convertEvmCaipToHexChainId(chainId);
199-
const selectedChainId = this.messagingSystem.call(
196+
const selectedChainId = this.messenger.call(
200197
'NetworkController:getSelectedChainId',
201198
);
202199

@@ -209,18 +206,15 @@ export class MultichainNetworkController extends BaseController<
209206
// If a non-EVM network is selected, we can delete the currently EVM selected network, but
210207
// we automatically switch to EVM mainnet.
211208
const ethereumMainnetHexChainId = '0x1'; // TODO: Should probably be a constant.
212-
const clientId = this.messagingSystem.call(
209+
const clientId = this.messenger.call(
213210
'NetworkController:findNetworkClientIdByChainId',
214211
ethereumMainnetHexChainId,
215212
);
216213

217-
await this.messagingSystem.call(
218-
'NetworkController:setActiveNetwork',
219-
clientId,
220-
);
214+
await this.messenger.call('NetworkController:setActiveNetwork', clientId);
221215
}
222216

223-
this.messagingSystem.call('NetworkController:removeNetwork', hexChainId);
217+
this.messenger.call('NetworkController:removeNetwork', hexChainId);
224218
}
225219

226220
/**
@@ -297,7 +291,7 @@ export class MultichainNetworkController extends BaseController<
297291
*/
298292
#subscribeToMessageEvents() {
299293
// Handle network switch when account is changed
300-
this.messagingSystem.subscribe(
294+
this.messenger.subscribe(
301295
'AccountsController:selectedAccountChange',
302296
(account) => this.#handleOnSelectedAccountChange(account),
303297
);
@@ -307,11 +301,11 @@ export class MultichainNetworkController extends BaseController<
307301
* Registers message handlers.
308302
*/
309303
#registerMessageHandlers() {
310-
this.messagingSystem.registerActionHandler(
304+
this.messenger.registerActionHandler(
311305
'MultichainNetworkController:setActiveNetwork',
312306
this.setActiveNetwork.bind(this),
313307
);
314-
this.messagingSystem.registerActionHandler(
308+
this.messenger.registerActionHandler(
315309
'MultichainNetworkController:getNetworksWithTransactionActivityByAccounts',
316310
this.getNetworksWithTransactionActivityByAccounts.bind(this),
317311
);

packages/multichain-network-controller/src/constants.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type StateMetadata } from '@metamask/base-controller';
1+
import { type StateMetadata } from '@metamask/base-controller/next';
22
import {
33
type CaipChainId,
44
BtcScope,
@@ -160,25 +160,25 @@ export const MULTICHAIN_NETWORK_CONTROLLER_METADATA = {
160160
multichainNetworkConfigurationsByChainId: {
161161
includeInStateLogs: true,
162162
persist: true,
163-
anonymous: true,
163+
includeInDebugSnapshot: true,
164164
usedInUi: true,
165165
},
166166
selectedMultichainNetworkChainId: {
167167
includeInStateLogs: true,
168168
persist: true,
169-
anonymous: true,
169+
includeInDebugSnapshot: true,
170170
usedInUi: true,
171171
},
172172
isEvmSelected: {
173173
includeInStateLogs: true,
174174
persist: true,
175-
anonymous: true,
175+
includeInDebugSnapshot: true,
176176
usedInUi: true,
177177
},
178178
networksWithTransactionActivity: {
179179
includeInStateLogs: true,
180180
persist: true,
181-
anonymous: true,
181+
includeInDebugSnapshot: true,
182182
usedInUi: true,
183183
},
184184
} satisfies StateMetadata<MultichainNetworkControllerState>;

packages/multichain-network-controller/src/types.ts

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import type { AccountsControllerListMultichainAccountsAction } from '@metamask/a
22
import {
33
type ControllerGetStateAction,
44
type ControllerStateChangeEvent,
5-
type RestrictedMessenger,
6-
} from '@metamask/base-controller';
5+
} from '@metamask/base-controller/next';
76
import type {
87
BtcScope,
98
CaipAssetType,
@@ -12,6 +11,7 @@ import type {
1211
TrxScope,
1312
} from '@metamask/keyring-api';
1413
import type { InternalAccount } from '@metamask/keyring-internal-api';
14+
import type { Messenger } from '@metamask/messenger';
1515
import type {
1616
NetworkStatus,
1717
NetworkControllerSetActiveNetworkAction,
@@ -178,7 +178,7 @@ export type MultichainNetworkControllerEvents =
178178
/**
179179
* Actions that this controller is allowed to call.
180180
*/
181-
export type AllowedActions =
181+
type AllowedActions =
182182
| NetworkControllerGetStateAction
183183
| NetworkControllerSetActiveNetworkAction
184184
| AccountsControllerListMultichainAccountsAction
@@ -195,23 +195,13 @@ export type AccountsControllerSelectedAccountChangeEvent = {
195195
/**
196196
* Events that this controller is allowed to subscribe.
197197
*/
198-
export type AllowedEvents = AccountsControllerSelectedAccountChangeEvent;
199-
200-
export type MultichainNetworkControllerAllowedActions =
201-
| MultichainNetworkControllerActions
202-
| AllowedActions;
203-
204-
export type MultichainNetworkControllerAllowedEvents =
205-
| MultichainNetworkControllerEvents
206-
| AllowedEvents;
198+
type AllowedEvents = AccountsControllerSelectedAccountChangeEvent;
207199

208200
/**
209201
* Messenger type for the MultichainNetworkController.
210202
*/
211-
export type MultichainNetworkControllerMessenger = RestrictedMessenger<
203+
export type MultichainNetworkControllerMessenger = Messenger<
212204
typeof MULTICHAIN_NETWORK_CONTROLLER_NAME,
213-
MultichainNetworkControllerAllowedActions,
214-
MultichainNetworkControllerAllowedEvents,
215-
AllowedActions['type'],
216-
AllowedEvents['type']
205+
MultichainNetworkControllerActions | AllowedActions,
206+
MultichainNetworkControllerEvents | AllowedEvents
217207
>;

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4178,6 +4178,7 @@ __metadata:
41784178
"@metamask/keyring-api": "npm:^21.0.0"
41794179
"@metamask/keyring-controller": "npm:^23.2.0"
41804180
"@metamask/keyring-internal-api": "npm:^9.0.0"
4181+
"@metamask/messenger": "npm:^0.3.0"
41814182
"@metamask/network-controller": "npm:^24.3.1"
41824183
"@metamask/superstruct": "npm:^3.1.0"
41834184
"@metamask/utils": "npm:^11.8.1"

0 commit comments

Comments
 (0)