Skip to content

Commit 9857fad

Browse files
feat: add NetworkController NetworkConfiguration actions and events (#4698)
## Explanation This adds and exposes some new actions and events inside the network controller. Events: - `NetworkController:networkRemoved` Actions - `NetworkController:updateNetwork` - `NetworkController:addNetwork` - `NetworkController:removeNetwork` These will be used for the network syncing feature (see references) ## References https://consensyssoftware.atlassian.net/browse/NOTIFY-1089 ## Changelog <!-- If you're making any consumer-facing changes, list those changes here as if you were updating a changelog, using the template below as a guide. (CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or FIXED. For security-related issues, follow the Security Advisory process.) Please take care to name the exact pieces of the API you've added or changed (e.g. types, interfaces, functions, or methods). If there are any breaking changes, make sure to offer a solution for consumers to follow once they upgrade to the changes. Finally, if you're only making changes to development scripts or tests, you may replace the template below with "None". --> ### `@metamask/network-controller` - **ADDED**: **(BREAKING)** add new event `NetworkController:networkRemoved` - **ADDED**: **(BREAKING)** add new actions `NetworkController:addNetwork`; `NetworkController:removeNetwork`; `NetworkController:updateNetwork` ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've highlighted breaking changes using the "BREAKING" category above as appropriate --------- Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
1 parent e2cdac9 commit 9857fad

File tree

3 files changed

+214
-2
lines changed

3 files changed

+214
-2
lines changed

packages/network-controller/src/NetworkController.ts

+56-2
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,23 @@ export type NetworkControllerNetworkAddedEvent = {
413413
payload: [networkConfiguration: NetworkConfiguration];
414414
};
415415

416+
/**
417+
* `networkRemoved` is published after a network configuration is removed from the
418+
* network configuration registry and once the network clients have been removed.
419+
*/
420+
export type NetworkControllerNetworkRemovedEvent = {
421+
type: 'NetworkController:networkRemoved';
422+
payload: [networkConfiguration: NetworkConfiguration];
423+
};
424+
416425
export type NetworkControllerEvents =
417426
| NetworkControllerStateChangeEvent
418427
| NetworkControllerNetworkWillChangeEvent
419428
| NetworkControllerNetworkDidChangeEvent
420429
| NetworkControllerInfuraIsBlockedEvent
421430
| NetworkControllerInfuraIsUnblockedEvent
422-
| NetworkControllerNetworkAddedEvent;
431+
| NetworkControllerNetworkAddedEvent
432+
| NetworkControllerNetworkRemovedEvent;
423433

424434
export type NetworkControllerGetStateAction = ControllerGetStateAction<
425435
typeof controllerName,
@@ -477,6 +487,21 @@ export type NetworkControllerGetNetworkConfigurationByNetworkClientId = {
477487
handler: NetworkController['getNetworkConfigurationByNetworkClientId'];
478488
};
479489

490+
export type NetworkControllerAddNetworkAction = {
491+
type: 'NetworkController:addNetwork';
492+
handler: NetworkController['addNetwork'];
493+
};
494+
495+
export type NetworkControllerRemoveNetworkAction = {
496+
type: 'NetworkController:removeNetwork';
497+
handler: NetworkController['removeNetwork'];
498+
};
499+
500+
export type NetworkControllerUpdateNetworkAction = {
501+
type: 'NetworkController:updateNetwork';
502+
handler: NetworkController['updateNetwork'];
503+
};
504+
480505
export type NetworkControllerActions =
481506
| NetworkControllerGetStateAction
482507
| NetworkControllerGetEthQueryAction
@@ -487,7 +512,10 @@ export type NetworkControllerActions =
487512
| NetworkControllerSetActiveNetworkAction
488513
| NetworkControllerSetProviderTypeAction
489514
| NetworkControllerGetNetworkConfigurationByChainId
490-
| NetworkControllerGetNetworkConfigurationByNetworkClientId;
515+
| NetworkControllerGetNetworkConfigurationByNetworkClientId
516+
| NetworkControllerAddNetworkAction
517+
| NetworkControllerRemoveNetworkAction
518+
| NetworkControllerUpdateNetworkAction;
491519

492520
export type NetworkControllerMessenger = RestrictedControllerMessenger<
493521
typeof controllerName,
@@ -958,6 +986,27 @@ export class NetworkController extends BaseController<
958986
`${this.name}:getSelectedNetworkClient`,
959987
this.getSelectedNetworkClient.bind(this),
960988
);
989+
990+
this.messagingSystem.registerActionHandler(
991+
// ESLint is mistaken here; `name` is a string.
992+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
993+
`${this.name}:addNetwork`,
994+
this.addNetwork.bind(this),
995+
);
996+
997+
this.messagingSystem.registerActionHandler(
998+
// ESLint is mistaken here; `name` is a string.
999+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1000+
`${this.name}:removeNetwork`,
1001+
this.removeNetwork.bind(this),
1002+
);
1003+
1004+
this.messagingSystem.registerActionHandler(
1005+
// ESLint is mistaken here; `name` is a string.
1006+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1007+
`${this.name}:updateNetwork`,
1008+
this.updateNetwork.bind(this),
1009+
);
9611010
}
9621011

9631012
/**
@@ -1938,6 +1987,11 @@ export class NetworkController extends BaseController<
19381987
buildNetworkConfigurationsByNetworkClientId(
19391988
this.state.networkConfigurationsByChainId,
19401989
);
1990+
1991+
this.messagingSystem.publish(
1992+
'NetworkController:networkRemoved',
1993+
existingNetworkConfiguration,
1994+
);
19411995
}
19421996

19431997
/**

packages/network-controller/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export type {
1717
NetworkControllerNetworkDidChangeEvent,
1818
NetworkControllerInfuraIsBlockedEvent,
1919
NetworkControllerInfuraIsUnblockedEvent,
20+
NetworkControllerNetworkAddedEvent,
21+
NetworkControllerNetworkRemovedEvent,
2022
NetworkControllerEvents,
2123
NetworkControllerGetStateAction,
2224
NetworkControllerGetEthQueryAction,
@@ -26,6 +28,9 @@ export type {
2628
NetworkControllerFindNetworkClientIdByChainIdAction,
2729
NetworkControllerSetProviderTypeAction,
2830
NetworkControllerSetActiveNetworkAction,
31+
NetworkControllerAddNetworkAction,
32+
NetworkControllerRemoveNetworkAction,
33+
NetworkControllerUpdateNetworkAction,
2934
NetworkControllerGetNetworkConfigurationByNetworkClientId,
3035
NetworkControllerActions,
3136
NetworkControllerMessenger,

packages/network-controller/tests/NetworkController.test.ts

+153
Original file line numberDiff line numberDiff line change
@@ -3857,6 +3857,56 @@ describe('NetworkController', () => {
38573857
});
38583858
});
38593859
});
3860+
3861+
it('is callable from the controller messenger', async () => {
3862+
uuidV4Mock.mockReturnValueOnce('AAAA-AAAA-AAAA-AAAA');
3863+
3864+
await withController(({ messenger }) => {
3865+
const networkAddedEventListener = jest.fn();
3866+
messenger.subscribe(
3867+
'NetworkController:networkAdded',
3868+
networkAddedEventListener,
3869+
);
3870+
3871+
const newNetworkConfiguration = messenger.call(
3872+
'NetworkController:addNetwork',
3873+
{
3874+
blockExplorerUrls: ['https://block.explorer'],
3875+
chainId: '0x1337',
3876+
defaultBlockExplorerUrlIndex: 0,
3877+
defaultRpcEndpointIndex: 0,
3878+
name: 'Some Network',
3879+
nativeCurrency: 'TOKEN',
3880+
rpcEndpoints: [
3881+
{
3882+
name: 'Test Network',
3883+
type: RpcEndpointType.Custom,
3884+
url: 'https://test.endpoint',
3885+
},
3886+
],
3887+
lastUpdatedAt: FAKE_DATE_NOW_MS,
3888+
},
3889+
);
3890+
3891+
expect(newNetworkConfiguration).toStrictEqual({
3892+
blockExplorerUrls: ['https://block.explorer'],
3893+
chainId: '0x1337',
3894+
defaultBlockExplorerUrlIndex: 0,
3895+
defaultRpcEndpointIndex: 0,
3896+
name: 'Some Network',
3897+
nativeCurrency: 'TOKEN',
3898+
rpcEndpoints: [
3899+
{
3900+
name: 'Test Network',
3901+
networkClientId: 'AAAA-AAAA-AAAA-AAAA',
3902+
type: RpcEndpointType.Custom,
3903+
url: 'https://test.endpoint',
3904+
},
3905+
],
3906+
lastUpdatedAt: FAKE_DATE_NOW_MS,
3907+
});
3908+
});
3909+
});
38603910
});
38613911
});
38623912

@@ -4548,6 +4598,59 @@ describe('NetworkController', () => {
45484598
);
45494599
});
45504600

4601+
it('is callable from the controller messenger', async () => {
4602+
const originalNetwork = buildCustomNetworkConfiguration({
4603+
chainId: '0x1337',
4604+
rpcEndpoints: [
4605+
buildCustomRpcEndpoint({
4606+
networkClientId: 'AAAA-AAAA-AAAA-AAAA',
4607+
url: 'https://rpc.network',
4608+
}),
4609+
],
4610+
});
4611+
4612+
const networkToUpdate = buildCustomNetworkConfiguration({
4613+
chainId: '0x1337',
4614+
rpcEndpoints: [
4615+
buildCustomRpcEndpoint({
4616+
name: 'Custom Name',
4617+
networkClientId: 'AAAA-AAAA-AAAA-AAAA',
4618+
url: 'https://rpc.network',
4619+
}),
4620+
],
4621+
});
4622+
4623+
const controllerState =
4624+
buildNetworkControllerStateWithDefaultSelectedNetworkClientId({
4625+
networkConfigurationsByChainId: {
4626+
[originalNetwork.chainId]: originalNetwork,
4627+
},
4628+
networksMetadata: {
4629+
'AAAA-AAAA-AAAA-AAAA': {
4630+
EIPS: {
4631+
'1559': true,
4632+
},
4633+
status: NetworkStatus.Available,
4634+
},
4635+
},
4636+
});
4637+
4638+
await withController(
4639+
{ state: controllerState },
4640+
async ({ controller, messenger }) => {
4641+
await messenger.call(
4642+
'NetworkController:updateNetwork',
4643+
networkToUpdate.chainId,
4644+
networkToUpdate,
4645+
);
4646+
expect(
4647+
controller.state.networkConfigurationsByChainId['0x1337']
4648+
.rpcEndpoints[0].name,
4649+
).toBe('Custom Name');
4650+
},
4651+
);
4652+
});
4653+
45514654
for (const infuraNetworkType of Object.values(InfuraNetworkType)) {
45524655
const infuraChainId = ChainId[infuraNetworkType];
45534656
const infuraNativeTokenName = NetworksTicker[infuraNetworkType];
@@ -11446,6 +11549,56 @@ describe('NetworkController', () => {
1144611549
},
1144711550
);
1144811551
});
11552+
11553+
it('is callable from the controller messenger', async () => {
11554+
await withController(
11555+
{
11556+
state: {
11557+
selectedNetworkClientId: InfuraNetworkType.goerli,
11558+
networkConfigurationsByChainId: {
11559+
'0x1337': buildCustomNetworkConfiguration(),
11560+
[ChainId.goerli]: buildInfuraNetworkConfiguration(
11561+
InfuraNetworkType.goerli,
11562+
),
11563+
},
11564+
},
11565+
},
11566+
({ controller, messenger }) => {
11567+
messenger.call('NetworkController:removeNetwork', '0x1337');
11568+
expect(
11569+
controller.state.networkConfigurationsByChainId,
11570+
).not.toHaveProperty('0x1337');
11571+
},
11572+
);
11573+
});
11574+
11575+
it('emits the NetworkController:networkRemoved event', async () => {
11576+
const networkConfig = buildCustomNetworkConfiguration();
11577+
await withController(
11578+
{
11579+
state: {
11580+
selectedNetworkClientId: InfuraNetworkType.goerli,
11581+
networkConfigurationsByChainId: {
11582+
'0x1337': networkConfig,
11583+
[ChainId.goerli]: buildInfuraNetworkConfiguration(
11584+
InfuraNetworkType.goerli,
11585+
),
11586+
},
11587+
},
11588+
},
11589+
({ controller, messenger }) => {
11590+
const networkRemovedListener = jest.fn();
11591+
messenger.subscribe(
11592+
'NetworkController:networkRemoved',
11593+
networkRemovedListener,
11594+
);
11595+
11596+
controller.removeNetwork('0x1337');
11597+
11598+
expect(networkRemovedListener).toHaveBeenCalledWith(networkConfig);
11599+
},
11600+
);
11601+
});
1144911602
});
1145011603
});
1145111604

0 commit comments

Comments
 (0)