@metamask/multichain-network-controller 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/dist/{MultichainNetworkController.cjs → MultichainNetworkController/MultichainNetworkController.cjs} +82 -11
  3. package/dist/MultichainNetworkController/MultichainNetworkController.cjs.map +1 -0
  4. package/dist/MultichainNetworkController/MultichainNetworkController.d.cts +41 -0
  5. package/dist/MultichainNetworkController/MultichainNetworkController.d.cts.map +1 -0
  6. package/dist/MultichainNetworkController/MultichainNetworkController.d.mts +41 -0
  7. package/dist/MultichainNetworkController/MultichainNetworkController.d.mts.map +1 -0
  8. package/dist/{MultichainNetworkController.mjs → MultichainNetworkController/MultichainNetworkController.mjs} +82 -11
  9. package/dist/MultichainNetworkController/MultichainNetworkController.mjs.map +1 -0
  10. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.cjs +3 -0
  11. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.cjs.map +1 -0
  12. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.d.cts +7 -0
  13. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.d.cts.map +1 -0
  14. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.d.mts +7 -0
  15. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.d.mts.map +1 -0
  16. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.mjs +2 -0
  17. package/dist/MultichainNetworkService/AbstractMultichainNetworkService.mjs.map +1 -0
  18. package/dist/MultichainNetworkService/MultichainNetworkService.cjs +63 -0
  19. package/dist/MultichainNetworkService/MultichainNetworkService.cjs.map +1 -0
  20. package/dist/MultichainNetworkService/MultichainNetworkService.d.cts +20 -0
  21. package/dist/MultichainNetworkService/MultichainNetworkService.d.cts.map +1 -0
  22. package/dist/MultichainNetworkService/MultichainNetworkService.d.mts +20 -0
  23. package/dist/MultichainNetworkService/MultichainNetworkService.d.mts.map +1 -0
  24. package/dist/MultichainNetworkService/MultichainNetworkService.mjs +59 -0
  25. package/dist/MultichainNetworkService/MultichainNetworkService.mjs.map +1 -0
  26. package/dist/api/accounts-api.cjs +82 -0
  27. package/dist/api/accounts-api.cjs.map +1 -0
  28. package/dist/api/accounts-api.d.cts +55 -0
  29. package/dist/api/accounts-api.d.cts.map +1 -0
  30. package/dist/api/accounts-api.d.mts +55 -0
  31. package/dist/api/accounts-api.d.mts.map +1 -0
  32. package/dist/api/accounts-api.mjs +76 -0
  33. package/dist/api/accounts-api.mjs.map +1 -0
  34. package/dist/constants.cjs +69 -4
  35. package/dist/constants.cjs.map +1 -1
  36. package/dist/constants.d.cts +26 -1
  37. package/dist/constants.d.cts.map +1 -1
  38. package/dist/constants.d.mts +26 -1
  39. package/dist/constants.d.mts.map +1 -1
  40. package/dist/constants.mjs +68 -3
  41. package/dist/constants.mjs.map +1 -1
  42. package/dist/index.cjs +8 -2
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +4 -2
  45. package/dist/index.d.cts.map +1 -1
  46. package/dist/index.d.mts +4 -2
  47. package/dist/index.d.mts.map +1 -1
  48. package/dist/index.mjs +3 -2
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/types.cjs.map +1 -1
  51. package/dist/types.d.cts +16 -6
  52. package/dist/types.d.cts.map +1 -1
  53. package/dist/types.d.mts +16 -6
  54. package/dist/types.d.mts.map +1 -1
  55. package/dist/types.mjs.map +1 -1
  56. package/dist/utils.cjs +43 -6
  57. package/dist/utils.cjs.map +1 -1
  58. package/dist/utils.d.cts +22 -1
  59. package/dist/utils.d.cts.map +1 -1
  60. package/dist/utils.d.mts +22 -1
  61. package/dist/utils.d.mts.map +1 -1
  62. package/dist/utils.mjs +40 -6
  63. package/dist/utils.mjs.map +1 -1
  64. package/package.json +7 -4
  65. package/dist/MultichainNetworkController.cjs.map +0 -1
  66. package/dist/MultichainNetworkController.d.cts +0 -22
  67. package/dist/MultichainNetworkController.d.cts.map +0 -1
  68. package/dist/MultichainNetworkController.d.mts +0 -22
  69. package/dist/MultichainNetworkController.d.mts.map +0 -1
  70. package/dist/MultichainNetworkController.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0]
11
+
12
+ ### Added
13
+
14
+ - Add method `getNetworksWithTransactionActivityByAccounts` to fetch active networks for multiple accounts in a single request ([#5551](https://github.com/MetaMask/core/pull/5551))
15
+ - Add `MultichainNetworkService` for handling network activity fetching ([#5551](https://github.com/MetaMask/core/pull/5551))
16
+ - Add types for network activity state and responses ([#5551](https://github.com/MetaMask/core/pull/5551))
17
+
18
+ ### Changed
19
+
20
+ - Updated state management for network activity ([#5551](https://github.com/MetaMask/core/pull/5551))
21
+
22
+ ## [0.4.0]
23
+
24
+ ### Added
25
+
26
+ - Add Testnet asset IDs as constants ([#5589](https://github.com/MetaMask/core/pull/5589))
27
+ - Add Network specific decimal values and ticker as constants ([#5589](https://github.com/MetaMask/core/pull/5589))
28
+ - Add new method `removeNetwork` that acts as a proxy to remove an EVM network from the `@metamask/network-controller` ([#5516](https://github.com/MetaMask/core/pull/5516))
29
+
30
+ ### Changed
31
+
32
+ - The `AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS` now includes non-EVM testnets ([#5589](https://github.com/MetaMask/core/pull/5589))
33
+ - Bump `@metamask/keyring-api"` from `^17.2.0` to `^17.4.0` ([#5565](https://github.com/MetaMask/core/pull/5565))
34
+
35
+ ### Fixed
36
+
37
+ - Fix the condition to update the active network based on the `AccountsController:selectedAccountChange` event ([#5642](https://github.com/MetaMask/core/pull/5642))
38
+
10
39
  ## [0.3.0]
11
40
 
12
41
  ### Changed
@@ -32,7 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
32
61
 
33
62
  ### Fixed
34
63
 
35
- - Add `MultichainNetworkController:stateChange` to list of subscribable `MultichainNetworkController` messenger events ([#5331](https://github.com/MetaMask/core.git/pull/5331))
64
+ - Add `MultichainNetworkController:stateChange` to list of subscribable `MultichainNetworkController` messenger events ([#5331](https://github.com/MetaMask/core/pull/5331))
36
65
 
37
66
  ## [0.1.0]
38
67
 
@@ -42,7 +71,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
42
71
  - Handle both EVM and non-EVM network and account switching for the associated network.
43
72
  - Act as a proxy for the `NetworkController` (for EVM network changes).
44
73
 
45
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.3.0...HEAD
74
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.5.0...HEAD
75
+ [0.5.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.4.0...@metamask/multichain-network-controller@0.5.0
76
+ [0.4.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.3.0...@metamask/multichain-network-controller@0.4.0
46
77
  [0.3.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.2.0...@metamask/multichain-network-controller@0.3.0
47
78
  [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.1.2...@metamask/multichain-network-controller@0.2.0
48
79
  [0.1.2]: https://github.com/MetaMask/core/compare/@metamask/multichain-network-controller@0.1.1...@metamask/multichain-network-controller@0.1.2
@@ -1,24 +1,31 @@
1
1
  "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
2
8
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
9
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
12
  };
7
- var _MultichainNetworkController_instances, _MultichainNetworkController_setActiveEvmNetwork, _MultichainNetworkController_setActiveNonEvmNetwork, _MultichainNetworkController_handleOnSelectedAccountChange, _MultichainNetworkController_subscribeToMessageEvents, _MultichainNetworkController_registerMessageHandlers;
13
+ var _MultichainNetworkController_instances, _MultichainNetworkController_networkService, _MultichainNetworkController_setActiveEvmNetwork, _MultichainNetworkController_setActiveNonEvmNetwork, _MultichainNetworkController_removeEvmNetwork, _MultichainNetworkController_removeNonEvmNetwork, _MultichainNetworkController_handleOnSelectedAccountChange, _MultichainNetworkController_subscribeToMessageEvents, _MultichainNetworkController_registerMessageHandlers;
8
14
  Object.defineProperty(exports, "__esModule", { value: true });
9
15
  exports.MultichainNetworkController = void 0;
10
16
  const base_controller_1 = require("@metamask/base-controller");
11
17
  const keyring_api_1 = require("@metamask/keyring-api");
12
18
  const utils_1 = require("@metamask/utils");
13
- const constants_1 = require("./constants.cjs");
14
- const types_1 = require("./types.cjs");
15
- const utils_2 = require("./utils.cjs");
19
+ const accounts_api_1 = require("../api/accounts-api.cjs");
20
+ const constants_1 = require("../constants.cjs");
21
+ const types_1 = require("../types.cjs");
22
+ const utils_2 = require("../utils.cjs");
16
23
  /**
17
24
  * The MultichainNetworkController is responsible for fetching and caching account
18
25
  * balances.
19
26
  */
20
27
  class MultichainNetworkController extends base_controller_1.BaseController {
21
- constructor({ messenger, state, }) {
28
+ constructor({ messenger, state, networkService, }) {
22
29
  super({
23
30
  messenger,
24
31
  name: types_1.MULTICHAIN_NETWORK_CONTROLLER_NAME,
@@ -26,9 +33,14 @@ class MultichainNetworkController extends base_controller_1.BaseController {
26
33
  state: {
27
34
  ...(0, constants_1.getDefaultMultichainNetworkControllerState)(),
28
35
  ...state,
36
+ // We can keep the current network as a hardcoded value
37
+ // since it is not expected to add/remove networks yet.
38
+ multichainNetworkConfigurationsByChainId: constants_1.AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,
29
39
  },
30
40
  });
31
41
  _MultichainNetworkController_instances.add(this);
42
+ _MultichainNetworkController_networkService.set(this, void 0);
43
+ __classPrivateFieldSet(this, _MultichainNetworkController_networkService, networkService, "f");
32
44
  __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_subscribeToMessageEvents).call(this);
33
45
  __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_registerMessageHandlers).call(this);
34
46
  }
@@ -48,9 +60,43 @@ class MultichainNetworkController extends base_controller_1.BaseController {
48
60
  }
49
61
  return await __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_setActiveEvmNetwork).call(this, id);
50
62
  }
63
+ /**
64
+ * Returns the active networks for the available EVM addresses (non-EVM networks will be supported in the future).
65
+ * Fetches the data from the API and caches it in state.
66
+ *
67
+ * @returns A promise that resolves to the active networks for the available addresses
68
+ */
69
+ async getNetworksWithTransactionActivityByAccounts() {
70
+ const accounts = this.messagingSystem.call('AccountsController:listMultichainAccounts');
71
+ if (!accounts || accounts.length === 0) {
72
+ return this.state.networksWithTransactionActivity;
73
+ }
74
+ const formattedAccounts = accounts
75
+ .map((account) => (0, accounts_api_1.toAllowedCaipAccountIds)(account))
76
+ .flat();
77
+ const activeNetworks = await __classPrivateFieldGet(this, _MultichainNetworkController_networkService, "f").fetchNetworkActivity(formattedAccounts);
78
+ const formattedNetworks = (0, accounts_api_1.toActiveNetworksByAddress)(activeNetworks);
79
+ this.update((state) => {
80
+ state.networksWithTransactionActivity = formattedNetworks;
81
+ });
82
+ return this.state.networksWithTransactionActivity;
83
+ }
84
+ /**
85
+ * Removes a network from the list of networks.
86
+ * It only supports EVM networks.
87
+ *
88
+ * @param chainId - The chain ID of the network to remove.
89
+ * @returns - A promise that resolves when the network is removed.
90
+ */
91
+ async removeNetwork(chainId) {
92
+ if ((0, utils_2.isEvmCaipChainId)(chainId)) {
93
+ return await __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_removeEvmNetwork).call(this, chainId);
94
+ }
95
+ return __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_removeNonEvmNetwork).call(this, chainId);
96
+ }
51
97
  }
52
98
  exports.MultichainNetworkController = MultichainNetworkController;
53
- _MultichainNetworkController_instances = new WeakSet(), _MultichainNetworkController_setActiveEvmNetwork =
99
+ _MultichainNetworkController_networkService = new WeakMap(), _MultichainNetworkController_instances = new WeakSet(), _MultichainNetworkController_setActiveEvmNetwork =
54
100
  /**
55
101
  * Sets the active EVM network.
56
102
  *
@@ -90,8 +136,33 @@ async function _MultichainNetworkController_setActiveEvmNetwork(id) {
90
136
  });
91
137
  // Notify listeners that the network changed
92
138
  this.messagingSystem.publish('MultichainNetworkController:networkDidChange', id);
139
+ }, _MultichainNetworkController_removeEvmNetwork =
140
+ /**
141
+ * Removes an EVM network from the list of networks.
142
+ * This method re-directs the request to the network-controller.
143
+ *
144
+ * @param chainId - The chain ID of the network to remove.
145
+ * @returns - A promise that resolves when the network is removed.
146
+ */
147
+ async function _MultichainNetworkController_removeEvmNetwork(chainId) {
148
+ const hexChainId = (0, utils_2.convertEvmCaipToHexChainId)(chainId);
149
+ const selectedChainId = this.messagingSystem.call('NetworkController:getSelectedChainId');
150
+ if (selectedChainId === hexChainId) {
151
+ // We prevent removing the currently selected network.
152
+ if (this.state.isEvmSelected) {
153
+ throw new Error('Cannot remove the currently selected network');
154
+ }
155
+ // If a non-EVM network is selected, we can delete the currently EVM selected network, but
156
+ // we automatically switch to EVM mainnet.
157
+ const ethereumMainnetHexChainId = '0x1'; // TODO: Should probably be a constant.
158
+ const clientId = this.messagingSystem.call('NetworkController:findNetworkClientIdByChainId', ethereumMainnetHexChainId);
159
+ await this.messagingSystem.call('NetworkController:setActiveNetwork', clientId);
160
+ }
161
+ this.messagingSystem.call('NetworkController:removeNetwork', hexChainId);
162
+ }, _MultichainNetworkController_removeNonEvmNetwork = function _MultichainNetworkController_removeNonEvmNetwork(_chainId) {
163
+ throw new Error('Removal of non-EVM networks is not supported');
93
164
  }, _MultichainNetworkController_handleOnSelectedAccountChange = function _MultichainNetworkController_handleOnSelectedAccountChange(account) {
94
- const { type: accountType, address: accountAddress } = account;
165
+ const { type: accountType, address: accountAddress, scopes } = account;
95
166
  const isEvmAccount = (0, keyring_api_1.isEvmAccountType)(accountType);
96
167
  // Handle switching to EVM network
97
168
  if (isEvmAccount) {
@@ -106,15 +177,14 @@ async function _MultichainNetworkController_setActiveEvmNetwork(id) {
106
177
  return;
107
178
  }
108
179
  // Handle switching to non-EVM network
109
- const nonEvmChainId = (0, utils_2.getChainIdForNonEvmAddress)(accountAddress);
110
- const isSameNonEvmNetwork = nonEvmChainId === this.state.selectedMultichainNetworkChainId;
111
- if (isSameNonEvmNetwork) {
112
- // No need to update if already on the same non-EVM network
180
+ if (scopes.includes(this.state.selectedMultichainNetworkChainId)) {
181
+ // No need to update if the account's scope includes the active network
113
182
  this.update((state) => {
114
183
  state.isEvmSelected = false;
115
184
  });
116
185
  return;
117
186
  }
187
+ const nonEvmChainId = (0, utils_2.getChainIdForNonEvmAddress)(accountAddress);
118
188
  this.update((state) => {
119
189
  state.selectedMultichainNetworkChainId = nonEvmChainId;
120
190
  state.isEvmSelected = false;
@@ -126,5 +196,6 @@ async function _MultichainNetworkController_setActiveEvmNetwork(id) {
126
196
  this.messagingSystem.subscribe('AccountsController:selectedAccountChange', (account) => __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_handleOnSelectedAccountChange).call(this, account));
127
197
  }, _MultichainNetworkController_registerMessageHandlers = function _MultichainNetworkController_registerMessageHandlers() {
128
198
  this.messagingSystem.registerActionHandler('MultichainNetworkController:setActiveNetwork', this.setActiveNetwork.bind(this));
199
+ this.messagingSystem.registerActionHandler('MultichainNetworkController:getNetworksWithTransactionActivityByAccounts', this.getNetworksWithTransactionActivityByAccounts.bind(this));
129
200
  };
130
201
  //# sourceMappingURL=MultichainNetworkController.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultichainNetworkController.cjs","sourceRoot":"","sources":["../../src/MultichainNetworkController/MultichainNetworkController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { type CaipChainId, isCaipChainId } from '@metamask/utils';\n\nimport {\n type ActiveNetworksByAddress,\n toAllowedCaipAccountIds,\n toActiveNetworksByAddress,\n} from '../api/accounts-api';\nimport {\n AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,\n MULTICHAIN_NETWORK_CONTROLLER_METADATA,\n getDefaultMultichainNetworkControllerState,\n} from '../constants';\nimport type { AbstractMultichainNetworkService } from '../MultichainNetworkService/AbstractMultichainNetworkService';\nimport {\n MULTICHAIN_NETWORK_CONTROLLER_NAME,\n type MultichainNetworkControllerState,\n type MultichainNetworkControllerMessenger,\n type SupportedCaipChainId,\n} from '../types';\nimport {\n checkIfSupportedCaipChainId,\n getChainIdForNonEvmAddress,\n convertEvmCaipToHexChainId,\n isEvmCaipChainId,\n} from '../utils';\n\n/**\n * The MultichainNetworkController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainNetworkController extends BaseController<\n typeof MULTICHAIN_NETWORK_CONTROLLER_NAME,\n MultichainNetworkControllerState,\n MultichainNetworkControllerMessenger\n> {\n readonly #networkService: AbstractMultichainNetworkService;\n\n constructor({\n messenger,\n state,\n networkService,\n }: {\n messenger: MultichainNetworkControllerMessenger;\n state?: Omit<\n Partial<MultichainNetworkControllerState>,\n 'multichainNetworkConfigurationsByChainId'\n >;\n networkService: AbstractMultichainNetworkService;\n }) {\n super({\n messenger,\n name: MULTICHAIN_NETWORK_CONTROLLER_NAME,\n metadata: MULTICHAIN_NETWORK_CONTROLLER_METADATA,\n state: {\n ...getDefaultMultichainNetworkControllerState(),\n ...state,\n // We can keep the current network as a hardcoded value\n // since it is not expected to add/remove networks yet.\n multichainNetworkConfigurationsByChainId:\n AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,\n },\n });\n\n this.#networkService = networkService;\n this.#subscribeToMessageEvents();\n this.#registerMessageHandlers();\n }\n\n /**\n * Sets the active EVM network.\n *\n * @param id - The client ID of the EVM network to set active.\n */\n async #setActiveEvmNetwork(id: NetworkClientId): Promise<void> {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n const shouldSetEvmActive = !this.state.isEvmSelected;\n const shouldNotifyNetworkChange = id !== selectedNetworkClientId;\n\n // No changes needed if EVM is active and network is already selected\n if (!shouldSetEvmActive && !shouldNotifyNetworkChange) {\n return;\n }\n\n // Update EVM selection state if needed\n if (shouldSetEvmActive) {\n this.update((state) => {\n state.isEvmSelected = true;\n });\n }\n\n // Only notify the network controller if the selected evm network is different\n if (shouldNotifyNetworkChange) {\n await this.messagingSystem.call('NetworkController:setActiveNetwork', id);\n }\n\n // Only publish the networkDidChange event if either the EVM network is different or we're switching between EVM and non-EVM networks\n if (shouldSetEvmActive || shouldNotifyNetworkChange) {\n this.messagingSystem.publish(\n 'MultichainNetworkController:networkDidChange',\n id,\n );\n }\n }\n\n /**\n * Sets the active non-EVM network.\n *\n * @param id - The chain ID of the non-EVM network to set active.\n */\n #setActiveNonEvmNetwork(id: SupportedCaipChainId): void {\n if (\n id === this.state.selectedMultichainNetworkChainId &&\n !this.state.isEvmSelected\n ) {\n // Same non-EVM network is already selected, no need to update\n return;\n }\n\n this.update((state) => {\n state.selectedMultichainNetworkChainId = id;\n state.isEvmSelected = false;\n });\n\n // Notify listeners that the network changed\n this.messagingSystem.publish(\n 'MultichainNetworkController:networkDidChange',\n id,\n );\n }\n\n /**\n * Sets the active network.\n *\n * @param id - The non-EVM Caip chain ID or EVM client ID of the network to set active.\n * @returns - A promise that resolves when the network is set active.\n */\n async setActiveNetwork(\n id: SupportedCaipChainId | NetworkClientId,\n ): Promise<void> {\n if (isCaipChainId(id)) {\n const isSupportedCaipChainId = checkIfSupportedCaipChainId(id);\n if (!isSupportedCaipChainId) {\n throw new Error(`Unsupported Caip chain ID: ${String(id)}`);\n }\n return this.#setActiveNonEvmNetwork(id);\n }\n\n return await this.#setActiveEvmNetwork(id);\n }\n\n /**\n * Returns the active networks for the available EVM addresses (non-EVM networks will be supported in the future).\n * Fetches the data from the API and caches it in state.\n *\n * @returns A promise that resolves to the active networks for the available addresses\n */\n async getNetworksWithTransactionActivityByAccounts(): Promise<ActiveNetworksByAddress> {\n const accounts = this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n if (!accounts || accounts.length === 0) {\n return this.state.networksWithTransactionActivity;\n }\n\n const formattedAccounts = accounts\n .map((account: InternalAccount) => toAllowedCaipAccountIds(account))\n .flat();\n\n const activeNetworks =\n await this.#networkService.fetchNetworkActivity(formattedAccounts);\n const formattedNetworks = toActiveNetworksByAddress(activeNetworks);\n\n this.update((state) => {\n state.networksWithTransactionActivity = formattedNetworks;\n });\n\n return this.state.networksWithTransactionActivity;\n }\n\n /**\n * Removes an EVM network from the list of networks.\n * This method re-directs the request to the network-controller.\n *\n * @param chainId - The chain ID of the network to remove.\n * @returns - A promise that resolves when the network is removed.\n */\n async #removeEvmNetwork(chainId: CaipChainId): Promise<void> {\n const hexChainId = convertEvmCaipToHexChainId(chainId);\n const selectedChainId = this.messagingSystem.call(\n 'NetworkController:getSelectedChainId',\n );\n\n if (selectedChainId === hexChainId) {\n // We prevent removing the currently selected network.\n if (this.state.isEvmSelected) {\n throw new Error('Cannot remove the currently selected network');\n }\n\n // If a non-EVM network is selected, we can delete the currently EVM selected network, but\n // we automatically switch to EVM mainnet.\n const ethereumMainnetHexChainId = '0x1'; // TODO: Should probably be a constant.\n const clientId = this.messagingSystem.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ethereumMainnetHexChainId,\n );\n\n await this.messagingSystem.call(\n 'NetworkController:setActiveNetwork',\n clientId,\n );\n }\n\n this.messagingSystem.call('NetworkController:removeNetwork', hexChainId);\n }\n\n /**\n * Removes a non-EVM network from the list of networks.\n * This method is not supported and throws an error.\n *\n * @param _chainId - The chain ID of the network to remove.\n * @throws - An error indicating that removal of non-EVM networks is not supported.\n */\n #removeNonEvmNetwork(_chainId: CaipChainId): void {\n throw new Error('Removal of non-EVM networks is not supported');\n }\n\n /**\n * Removes a network from the list of networks.\n * It only supports EVM networks.\n *\n * @param chainId - The chain ID of the network to remove.\n * @returns - A promise that resolves when the network is removed.\n */\n async removeNetwork(chainId: CaipChainId): Promise<void> {\n if (isEvmCaipChainId(chainId)) {\n return await this.#removeEvmNetwork(chainId);\n }\n\n return this.#removeNonEvmNetwork(chainId);\n }\n\n /**\n * Handles switching between EVM and non-EVM networks when an account is changed\n *\n * @param account - The account that was changed\n */\n #handleOnSelectedAccountChange(account: InternalAccount) {\n const { type: accountType, address: accountAddress, scopes } = account;\n const isEvmAccount = isEvmAccountType(accountType);\n\n // Handle switching to EVM network\n if (isEvmAccount) {\n if (this.state.isEvmSelected) {\n // No need to update if already on evm network\n return;\n }\n\n // Make EVM network active\n this.update((state) => {\n state.isEvmSelected = true;\n });\n\n return;\n }\n\n // Handle switching to non-EVM network\n if (scopes.includes(this.state.selectedMultichainNetworkChainId)) {\n // No need to update if the account's scope includes the active network\n this.update((state) => {\n state.isEvmSelected = false;\n });\n return;\n }\n\n const nonEvmChainId = getChainIdForNonEvmAddress(accountAddress);\n this.update((state) => {\n state.selectedMultichainNetworkChainId = nonEvmChainId;\n state.isEvmSelected = false;\n });\n\n // No need to publish NetworkController:setActiveNetwork because EVM accounts falls back to use the last selected EVM network\n // DO NOT publish MultichainNetworkController:networkDidChange to prevent circular listener loops\n }\n\n /**\n * Subscribes to message events.\n */\n #subscribeToMessageEvents() {\n // Handle network switch when account is changed\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n (account) => this.#handleOnSelectedAccountChange(account),\n );\n }\n\n /**\n * Registers message handlers.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n 'MultichainNetworkController:setActiveNetwork',\n this.setActiveNetwork.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n 'MultichainNetworkController:getNetworksWithTransactionActivityByAccounts',\n this.getNetworksWithTransactionActivityByAccounts.bind(this),\n );\n }\n}\n"]}
@@ -0,0 +1,41 @@
1
+ import { BaseController } from "@metamask/base-controller";
2
+ import type { NetworkClientId } from "@metamask/network-controller";
3
+ import { type CaipChainId } from "@metamask/utils";
4
+ import { type ActiveNetworksByAddress } from "../api/accounts-api.cjs";
5
+ import type { AbstractMultichainNetworkService } from "../MultichainNetworkService/AbstractMultichainNetworkService.cjs";
6
+ import { MULTICHAIN_NETWORK_CONTROLLER_NAME, type MultichainNetworkControllerState, type MultichainNetworkControllerMessenger, type SupportedCaipChainId } from "../types.cjs";
7
+ /**
8
+ * The MultichainNetworkController is responsible for fetching and caching account
9
+ * balances.
10
+ */
11
+ export declare class MultichainNetworkController extends BaseController<typeof MULTICHAIN_NETWORK_CONTROLLER_NAME, MultichainNetworkControllerState, MultichainNetworkControllerMessenger> {
12
+ #private;
13
+ constructor({ messenger, state, networkService, }: {
14
+ messenger: MultichainNetworkControllerMessenger;
15
+ state?: Omit<Partial<MultichainNetworkControllerState>, 'multichainNetworkConfigurationsByChainId'>;
16
+ networkService: AbstractMultichainNetworkService;
17
+ });
18
+ /**
19
+ * Sets the active network.
20
+ *
21
+ * @param id - The non-EVM Caip chain ID or EVM client ID of the network to set active.
22
+ * @returns - A promise that resolves when the network is set active.
23
+ */
24
+ setActiveNetwork(id: SupportedCaipChainId | NetworkClientId): Promise<void>;
25
+ /**
26
+ * Returns the active networks for the available EVM addresses (non-EVM networks will be supported in the future).
27
+ * Fetches the data from the API and caches it in state.
28
+ *
29
+ * @returns A promise that resolves to the active networks for the available addresses
30
+ */
31
+ getNetworksWithTransactionActivityByAccounts(): Promise<ActiveNetworksByAddress>;
32
+ /**
33
+ * Removes a network from the list of networks.
34
+ * It only supports EVM networks.
35
+ *
36
+ * @param chainId - The chain ID of the network to remove.
37
+ * @returns - A promise that resolves when the network is removed.
38
+ */
39
+ removeNetwork(chainId: CaipChainId): Promise<void>;
40
+ }
41
+ //# sourceMappingURL=MultichainNetworkController.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultichainNetworkController.d.cts","sourceRoot":"","sources":["../../src/MultichainNetworkController/MultichainNetworkController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AACpE,OAAO,EAAE,KAAK,WAAW,EAAiB,wBAAwB;AAElE,OAAO,EACL,KAAK,uBAAuB,EAG7B,gCAA4B;AAM7B,OAAO,KAAK,EAAE,gCAAgC,EAAE,yEAAqE;AACrH,OAAO,EACL,kCAAkC,EAClC,KAAK,gCAAgC,EACrC,KAAK,oCAAoC,EACzC,KAAK,oBAAoB,EAC1B,qBAAiB;AAQlB;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAC7D,OAAO,kCAAkC,EACzC,gCAAgC,EAChC,oCAAoC,CACrC;;gBAGa,EACV,SAAS,EACT,KAAK,EACL,cAAc,GACf,EAAE;QACD,SAAS,EAAE,oCAAoC,CAAC;QAChD,KAAK,CAAC,EAAE,IAAI,CACV,OAAO,CAAC,gCAAgC,CAAC,EACzC,0CAA0C,CAC3C,CAAC;QACF,cAAc,EAAE,gCAAgC,CAAC;KAClD;IAqFD;;;;;OAKG;IACG,gBAAgB,CACpB,EAAE,EAAE,oBAAoB,GAAG,eAAe,GACzC,OAAO,CAAC,IAAI,CAAC;IAYhB;;;;;OAKG;IACG,4CAA4C,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAsEtF;;;;;;OAMG;IACG,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CA2EzD"}
@@ -0,0 +1,41 @@
1
+ import { BaseController } from "@metamask/base-controller";
2
+ import type { NetworkClientId } from "@metamask/network-controller";
3
+ import { type CaipChainId } from "@metamask/utils";
4
+ import { type ActiveNetworksByAddress } from "../api/accounts-api.mjs";
5
+ import type { AbstractMultichainNetworkService } from "../MultichainNetworkService/AbstractMultichainNetworkService.mjs";
6
+ import { MULTICHAIN_NETWORK_CONTROLLER_NAME, type MultichainNetworkControllerState, type MultichainNetworkControllerMessenger, type SupportedCaipChainId } from "../types.mjs";
7
+ /**
8
+ * The MultichainNetworkController is responsible for fetching and caching account
9
+ * balances.
10
+ */
11
+ export declare class MultichainNetworkController extends BaseController<typeof MULTICHAIN_NETWORK_CONTROLLER_NAME, MultichainNetworkControllerState, MultichainNetworkControllerMessenger> {
12
+ #private;
13
+ constructor({ messenger, state, networkService, }: {
14
+ messenger: MultichainNetworkControllerMessenger;
15
+ state?: Omit<Partial<MultichainNetworkControllerState>, 'multichainNetworkConfigurationsByChainId'>;
16
+ networkService: AbstractMultichainNetworkService;
17
+ });
18
+ /**
19
+ * Sets the active network.
20
+ *
21
+ * @param id - The non-EVM Caip chain ID or EVM client ID of the network to set active.
22
+ * @returns - A promise that resolves when the network is set active.
23
+ */
24
+ setActiveNetwork(id: SupportedCaipChainId | NetworkClientId): Promise<void>;
25
+ /**
26
+ * Returns the active networks for the available EVM addresses (non-EVM networks will be supported in the future).
27
+ * Fetches the data from the API and caches it in state.
28
+ *
29
+ * @returns A promise that resolves to the active networks for the available addresses
30
+ */
31
+ getNetworksWithTransactionActivityByAccounts(): Promise<ActiveNetworksByAddress>;
32
+ /**
33
+ * Removes a network from the list of networks.
34
+ * It only supports EVM networks.
35
+ *
36
+ * @param chainId - The chain ID of the network to remove.
37
+ * @returns - A promise that resolves when the network is removed.
38
+ */
39
+ removeNetwork(chainId: CaipChainId): Promise<void>;
40
+ }
41
+ //# sourceMappingURL=MultichainNetworkController.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultichainNetworkController.d.mts","sourceRoot":"","sources":["../../src/MultichainNetworkController/MultichainNetworkController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AACpE,OAAO,EAAE,KAAK,WAAW,EAAiB,wBAAwB;AAElE,OAAO,EACL,KAAK,uBAAuB,EAG7B,gCAA4B;AAM7B,OAAO,KAAK,EAAE,gCAAgC,EAAE,yEAAqE;AACrH,OAAO,EACL,kCAAkC,EAClC,KAAK,gCAAgC,EACrC,KAAK,oCAAoC,EACzC,KAAK,oBAAoB,EAC1B,qBAAiB;AAQlB;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAC7D,OAAO,kCAAkC,EACzC,gCAAgC,EAChC,oCAAoC,CACrC;;gBAGa,EACV,SAAS,EACT,KAAK,EACL,cAAc,GACf,EAAE;QACD,SAAS,EAAE,oCAAoC,CAAC;QAChD,KAAK,CAAC,EAAE,IAAI,CACV,OAAO,CAAC,gCAAgC,CAAC,EACzC,0CAA0C,CAC3C,CAAC;QACF,cAAc,EAAE,gCAAgC,CAAC;KAClD;IAqFD;;;;;OAKG;IACG,gBAAgB,CACpB,EAAE,EAAE,oBAAoB,GAAG,eAAe,GACzC,OAAO,CAAC,IAAI,CAAC;IAYhB;;;;;OAKG;IACG,4CAA4C,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAsEtF;;;;;;OAMG;IACG,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CA2EzD"}
@@ -1,21 +1,28 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
1
7
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
8
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
11
  };
6
- var _MultichainNetworkController_instances, _MultichainNetworkController_setActiveEvmNetwork, _MultichainNetworkController_setActiveNonEvmNetwork, _MultichainNetworkController_handleOnSelectedAccountChange, _MultichainNetworkController_subscribeToMessageEvents, _MultichainNetworkController_registerMessageHandlers;
12
+ var _MultichainNetworkController_instances, _MultichainNetworkController_networkService, _MultichainNetworkController_setActiveEvmNetwork, _MultichainNetworkController_setActiveNonEvmNetwork, _MultichainNetworkController_removeEvmNetwork, _MultichainNetworkController_removeNonEvmNetwork, _MultichainNetworkController_handleOnSelectedAccountChange, _MultichainNetworkController_subscribeToMessageEvents, _MultichainNetworkController_registerMessageHandlers;
7
13
  import { BaseController } from "@metamask/base-controller";
8
14
  import { isEvmAccountType } from "@metamask/keyring-api";
9
15
  import { isCaipChainId } from "@metamask/utils";
10
- import { MULTICHAIN_NETWORK_CONTROLLER_METADATA, getDefaultMultichainNetworkControllerState } from "./constants.mjs";
11
- import { MULTICHAIN_NETWORK_CONTROLLER_NAME } from "./types.mjs";
12
- import { checkIfSupportedCaipChainId, getChainIdForNonEvmAddress } from "./utils.mjs";
16
+ import { toAllowedCaipAccountIds, toActiveNetworksByAddress } from "../api/accounts-api.mjs";
17
+ import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS, MULTICHAIN_NETWORK_CONTROLLER_METADATA, getDefaultMultichainNetworkControllerState } from "../constants.mjs";
18
+ import { MULTICHAIN_NETWORK_CONTROLLER_NAME } from "../types.mjs";
19
+ import { checkIfSupportedCaipChainId, getChainIdForNonEvmAddress, convertEvmCaipToHexChainId, isEvmCaipChainId } from "../utils.mjs";
13
20
  /**
14
21
  * The MultichainNetworkController is responsible for fetching and caching account
15
22
  * balances.
16
23
  */
17
24
  export class MultichainNetworkController extends BaseController {
18
- constructor({ messenger, state, }) {
25
+ constructor({ messenger, state, networkService, }) {
19
26
  super({
20
27
  messenger,
21
28
  name: MULTICHAIN_NETWORK_CONTROLLER_NAME,
@@ -23,9 +30,14 @@ export class MultichainNetworkController extends BaseController {
23
30
  state: {
24
31
  ...getDefaultMultichainNetworkControllerState(),
25
32
  ...state,
33
+ // We can keep the current network as a hardcoded value
34
+ // since it is not expected to add/remove networks yet.
35
+ multichainNetworkConfigurationsByChainId: AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,
26
36
  },
27
37
  });
28
38
  _MultichainNetworkController_instances.add(this);
39
+ _MultichainNetworkController_networkService.set(this, void 0);
40
+ __classPrivateFieldSet(this, _MultichainNetworkController_networkService, networkService, "f");
29
41
  __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_subscribeToMessageEvents).call(this);
30
42
  __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_registerMessageHandlers).call(this);
31
43
  }
@@ -45,8 +57,42 @@ export class MultichainNetworkController extends BaseController {
45
57
  }
46
58
  return await __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_setActiveEvmNetwork).call(this, id);
47
59
  }
60
+ /**
61
+ * Returns the active networks for the available EVM addresses (non-EVM networks will be supported in the future).
62
+ * Fetches the data from the API and caches it in state.
63
+ *
64
+ * @returns A promise that resolves to the active networks for the available addresses
65
+ */
66
+ async getNetworksWithTransactionActivityByAccounts() {
67
+ const accounts = this.messagingSystem.call('AccountsController:listMultichainAccounts');
68
+ if (!accounts || accounts.length === 0) {
69
+ return this.state.networksWithTransactionActivity;
70
+ }
71
+ const formattedAccounts = accounts
72
+ .map((account) => toAllowedCaipAccountIds(account))
73
+ .flat();
74
+ const activeNetworks = await __classPrivateFieldGet(this, _MultichainNetworkController_networkService, "f").fetchNetworkActivity(formattedAccounts);
75
+ const formattedNetworks = toActiveNetworksByAddress(activeNetworks);
76
+ this.update((state) => {
77
+ state.networksWithTransactionActivity = formattedNetworks;
78
+ });
79
+ return this.state.networksWithTransactionActivity;
80
+ }
81
+ /**
82
+ * Removes a network from the list of networks.
83
+ * It only supports EVM networks.
84
+ *
85
+ * @param chainId - The chain ID of the network to remove.
86
+ * @returns - A promise that resolves when the network is removed.
87
+ */
88
+ async removeNetwork(chainId) {
89
+ if (isEvmCaipChainId(chainId)) {
90
+ return await __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_removeEvmNetwork).call(this, chainId);
91
+ }
92
+ return __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_removeNonEvmNetwork).call(this, chainId);
93
+ }
48
94
  }
49
- _MultichainNetworkController_instances = new WeakSet(), _MultichainNetworkController_setActiveEvmNetwork =
95
+ _MultichainNetworkController_networkService = new WeakMap(), _MultichainNetworkController_instances = new WeakSet(), _MultichainNetworkController_setActiveEvmNetwork =
50
96
  /**
51
97
  * Sets the active EVM network.
52
98
  *
@@ -86,8 +132,33 @@ async function _MultichainNetworkController_setActiveEvmNetwork(id) {
86
132
  });
87
133
  // Notify listeners that the network changed
88
134
  this.messagingSystem.publish('MultichainNetworkController:networkDidChange', id);
135
+ }, _MultichainNetworkController_removeEvmNetwork =
136
+ /**
137
+ * Removes an EVM network from the list of networks.
138
+ * This method re-directs the request to the network-controller.
139
+ *
140
+ * @param chainId - The chain ID of the network to remove.
141
+ * @returns - A promise that resolves when the network is removed.
142
+ */
143
+ async function _MultichainNetworkController_removeEvmNetwork(chainId) {
144
+ const hexChainId = convertEvmCaipToHexChainId(chainId);
145
+ const selectedChainId = this.messagingSystem.call('NetworkController:getSelectedChainId');
146
+ if (selectedChainId === hexChainId) {
147
+ // We prevent removing the currently selected network.
148
+ if (this.state.isEvmSelected) {
149
+ throw new Error('Cannot remove the currently selected network');
150
+ }
151
+ // If a non-EVM network is selected, we can delete the currently EVM selected network, but
152
+ // we automatically switch to EVM mainnet.
153
+ const ethereumMainnetHexChainId = '0x1'; // TODO: Should probably be a constant.
154
+ const clientId = this.messagingSystem.call('NetworkController:findNetworkClientIdByChainId', ethereumMainnetHexChainId);
155
+ await this.messagingSystem.call('NetworkController:setActiveNetwork', clientId);
156
+ }
157
+ this.messagingSystem.call('NetworkController:removeNetwork', hexChainId);
158
+ }, _MultichainNetworkController_removeNonEvmNetwork = function _MultichainNetworkController_removeNonEvmNetwork(_chainId) {
159
+ throw new Error('Removal of non-EVM networks is not supported');
89
160
  }, _MultichainNetworkController_handleOnSelectedAccountChange = function _MultichainNetworkController_handleOnSelectedAccountChange(account) {
90
- const { type: accountType, address: accountAddress } = account;
161
+ const { type: accountType, address: accountAddress, scopes } = account;
91
162
  const isEvmAccount = isEvmAccountType(accountType);
92
163
  // Handle switching to EVM network
93
164
  if (isEvmAccount) {
@@ -102,15 +173,14 @@ async function _MultichainNetworkController_setActiveEvmNetwork(id) {
102
173
  return;
103
174
  }
104
175
  // Handle switching to non-EVM network
105
- const nonEvmChainId = getChainIdForNonEvmAddress(accountAddress);
106
- const isSameNonEvmNetwork = nonEvmChainId === this.state.selectedMultichainNetworkChainId;
107
- if (isSameNonEvmNetwork) {
108
- // No need to update if already on the same non-EVM network
176
+ if (scopes.includes(this.state.selectedMultichainNetworkChainId)) {
177
+ // No need to update if the account's scope includes the active network
109
178
  this.update((state) => {
110
179
  state.isEvmSelected = false;
111
180
  });
112
181
  return;
113
182
  }
183
+ const nonEvmChainId = getChainIdForNonEvmAddress(accountAddress);
114
184
  this.update((state) => {
115
185
  state.selectedMultichainNetworkChainId = nonEvmChainId;
116
186
  state.isEvmSelected = false;
@@ -122,5 +192,6 @@ async function _MultichainNetworkController_setActiveEvmNetwork(id) {
122
192
  this.messagingSystem.subscribe('AccountsController:selectedAccountChange', (account) => __classPrivateFieldGet(this, _MultichainNetworkController_instances, "m", _MultichainNetworkController_handleOnSelectedAccountChange).call(this, account));
123
193
  }, _MultichainNetworkController_registerMessageHandlers = function _MultichainNetworkController_registerMessageHandlers() {
124
194
  this.messagingSystem.registerActionHandler('MultichainNetworkController:setActiveNetwork', this.setActiveNetwork.bind(this));
195
+ this.messagingSystem.registerActionHandler('MultichainNetworkController:getNetworksWithTransactionActivityByAccounts', this.getNetworksWithTransactionActivityByAccounts.bind(this));
125
196
  };
126
197
  //# sourceMappingURL=MultichainNetworkController.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultichainNetworkController.mjs","sourceRoot":"","sources":["../../src/MultichainNetworkController/MultichainNetworkController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { type CaipChainId, isCaipChainId } from '@metamask/utils';\n\nimport {\n type ActiveNetworksByAddress,\n toAllowedCaipAccountIds,\n toActiveNetworksByAddress,\n} from '../api/accounts-api';\nimport {\n AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,\n MULTICHAIN_NETWORK_CONTROLLER_METADATA,\n getDefaultMultichainNetworkControllerState,\n} from '../constants';\nimport type { AbstractMultichainNetworkService } from '../MultichainNetworkService/AbstractMultichainNetworkService';\nimport {\n MULTICHAIN_NETWORK_CONTROLLER_NAME,\n type MultichainNetworkControllerState,\n type MultichainNetworkControllerMessenger,\n type SupportedCaipChainId,\n} from '../types';\nimport {\n checkIfSupportedCaipChainId,\n getChainIdForNonEvmAddress,\n convertEvmCaipToHexChainId,\n isEvmCaipChainId,\n} from '../utils';\n\n/**\n * The MultichainNetworkController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainNetworkController extends BaseController<\n typeof MULTICHAIN_NETWORK_CONTROLLER_NAME,\n MultichainNetworkControllerState,\n MultichainNetworkControllerMessenger\n> {\n readonly #networkService: AbstractMultichainNetworkService;\n\n constructor({\n messenger,\n state,\n networkService,\n }: {\n messenger: MultichainNetworkControllerMessenger;\n state?: Omit<\n Partial<MultichainNetworkControllerState>,\n 'multichainNetworkConfigurationsByChainId'\n >;\n networkService: AbstractMultichainNetworkService;\n }) {\n super({\n messenger,\n name: MULTICHAIN_NETWORK_CONTROLLER_NAME,\n metadata: MULTICHAIN_NETWORK_CONTROLLER_METADATA,\n state: {\n ...getDefaultMultichainNetworkControllerState(),\n ...state,\n // We can keep the current network as a hardcoded value\n // since it is not expected to add/remove networks yet.\n multichainNetworkConfigurationsByChainId:\n AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,\n },\n });\n\n this.#networkService = networkService;\n this.#subscribeToMessageEvents();\n this.#registerMessageHandlers();\n }\n\n /**\n * Sets the active EVM network.\n *\n * @param id - The client ID of the EVM network to set active.\n */\n async #setActiveEvmNetwork(id: NetworkClientId): Promise<void> {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n const shouldSetEvmActive = !this.state.isEvmSelected;\n const shouldNotifyNetworkChange = id !== selectedNetworkClientId;\n\n // No changes needed if EVM is active and network is already selected\n if (!shouldSetEvmActive && !shouldNotifyNetworkChange) {\n return;\n }\n\n // Update EVM selection state if needed\n if (shouldSetEvmActive) {\n this.update((state) => {\n state.isEvmSelected = true;\n });\n }\n\n // Only notify the network controller if the selected evm network is different\n if (shouldNotifyNetworkChange) {\n await this.messagingSystem.call('NetworkController:setActiveNetwork', id);\n }\n\n // Only publish the networkDidChange event if either the EVM network is different or we're switching between EVM and non-EVM networks\n if (shouldSetEvmActive || shouldNotifyNetworkChange) {\n this.messagingSystem.publish(\n 'MultichainNetworkController:networkDidChange',\n id,\n );\n }\n }\n\n /**\n * Sets the active non-EVM network.\n *\n * @param id - The chain ID of the non-EVM network to set active.\n */\n #setActiveNonEvmNetwork(id: SupportedCaipChainId): void {\n if (\n id === this.state.selectedMultichainNetworkChainId &&\n !this.state.isEvmSelected\n ) {\n // Same non-EVM network is already selected, no need to update\n return;\n }\n\n this.update((state) => {\n state.selectedMultichainNetworkChainId = id;\n state.isEvmSelected = false;\n });\n\n // Notify listeners that the network changed\n this.messagingSystem.publish(\n 'MultichainNetworkController:networkDidChange',\n id,\n );\n }\n\n /**\n * Sets the active network.\n *\n * @param id - The non-EVM Caip chain ID or EVM client ID of the network to set active.\n * @returns - A promise that resolves when the network is set active.\n */\n async setActiveNetwork(\n id: SupportedCaipChainId | NetworkClientId,\n ): Promise<void> {\n if (isCaipChainId(id)) {\n const isSupportedCaipChainId = checkIfSupportedCaipChainId(id);\n if (!isSupportedCaipChainId) {\n throw new Error(`Unsupported Caip chain ID: ${String(id)}`);\n }\n return this.#setActiveNonEvmNetwork(id);\n }\n\n return await this.#setActiveEvmNetwork(id);\n }\n\n /**\n * Returns the active networks for the available EVM addresses (non-EVM networks will be supported in the future).\n * Fetches the data from the API and caches it in state.\n *\n * @returns A promise that resolves to the active networks for the available addresses\n */\n async getNetworksWithTransactionActivityByAccounts(): Promise<ActiveNetworksByAddress> {\n const accounts = this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n if (!accounts || accounts.length === 0) {\n return this.state.networksWithTransactionActivity;\n }\n\n const formattedAccounts = accounts\n .map((account: InternalAccount) => toAllowedCaipAccountIds(account))\n .flat();\n\n const activeNetworks =\n await this.#networkService.fetchNetworkActivity(formattedAccounts);\n const formattedNetworks = toActiveNetworksByAddress(activeNetworks);\n\n this.update((state) => {\n state.networksWithTransactionActivity = formattedNetworks;\n });\n\n return this.state.networksWithTransactionActivity;\n }\n\n /**\n * Removes an EVM network from the list of networks.\n * This method re-directs the request to the network-controller.\n *\n * @param chainId - The chain ID of the network to remove.\n * @returns - A promise that resolves when the network is removed.\n */\n async #removeEvmNetwork(chainId: CaipChainId): Promise<void> {\n const hexChainId = convertEvmCaipToHexChainId(chainId);\n const selectedChainId = this.messagingSystem.call(\n 'NetworkController:getSelectedChainId',\n );\n\n if (selectedChainId === hexChainId) {\n // We prevent removing the currently selected network.\n if (this.state.isEvmSelected) {\n throw new Error('Cannot remove the currently selected network');\n }\n\n // If a non-EVM network is selected, we can delete the currently EVM selected network, but\n // we automatically switch to EVM mainnet.\n const ethereumMainnetHexChainId = '0x1'; // TODO: Should probably be a constant.\n const clientId = this.messagingSystem.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ethereumMainnetHexChainId,\n );\n\n await this.messagingSystem.call(\n 'NetworkController:setActiveNetwork',\n clientId,\n );\n }\n\n this.messagingSystem.call('NetworkController:removeNetwork', hexChainId);\n }\n\n /**\n * Removes a non-EVM network from the list of networks.\n * This method is not supported and throws an error.\n *\n * @param _chainId - The chain ID of the network to remove.\n * @throws - An error indicating that removal of non-EVM networks is not supported.\n */\n #removeNonEvmNetwork(_chainId: CaipChainId): void {\n throw new Error('Removal of non-EVM networks is not supported');\n }\n\n /**\n * Removes a network from the list of networks.\n * It only supports EVM networks.\n *\n * @param chainId - The chain ID of the network to remove.\n * @returns - A promise that resolves when the network is removed.\n */\n async removeNetwork(chainId: CaipChainId): Promise<void> {\n if (isEvmCaipChainId(chainId)) {\n return await this.#removeEvmNetwork(chainId);\n }\n\n return this.#removeNonEvmNetwork(chainId);\n }\n\n /**\n * Handles switching between EVM and non-EVM networks when an account is changed\n *\n * @param account - The account that was changed\n */\n #handleOnSelectedAccountChange(account: InternalAccount) {\n const { type: accountType, address: accountAddress, scopes } = account;\n const isEvmAccount = isEvmAccountType(accountType);\n\n // Handle switching to EVM network\n if (isEvmAccount) {\n if (this.state.isEvmSelected) {\n // No need to update if already on evm network\n return;\n }\n\n // Make EVM network active\n this.update((state) => {\n state.isEvmSelected = true;\n });\n\n return;\n }\n\n // Handle switching to non-EVM network\n if (scopes.includes(this.state.selectedMultichainNetworkChainId)) {\n // No need to update if the account's scope includes the active network\n this.update((state) => {\n state.isEvmSelected = false;\n });\n return;\n }\n\n const nonEvmChainId = getChainIdForNonEvmAddress(accountAddress);\n this.update((state) => {\n state.selectedMultichainNetworkChainId = nonEvmChainId;\n state.isEvmSelected = false;\n });\n\n // No need to publish NetworkController:setActiveNetwork because EVM accounts falls back to use the last selected EVM network\n // DO NOT publish MultichainNetworkController:networkDidChange to prevent circular listener loops\n }\n\n /**\n * Subscribes to message events.\n */\n #subscribeToMessageEvents() {\n // Handle network switch when account is changed\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n (account) => this.#handleOnSelectedAccountChange(account),\n );\n }\n\n /**\n * Registers message handlers.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n 'MultichainNetworkController:setActiveNetwork',\n this.setActiveNetwork.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n 'MultichainNetworkController:getNetworksWithTransactionActivityByAccounts',\n this.getNetworksWithTransactionActivityByAccounts.bind(this),\n );\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=AbstractMultichainNetworkService.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractMultichainNetworkService.cjs","sourceRoot":"","sources":["../../src/MultichainNetworkService/AbstractMultichainNetworkService.ts"],"names":[],"mappings":"","sourcesContent":["import type { PublicInterface } from '@metamask/utils';\n\nimport type { MultichainNetworkService } from './MultichainNetworkService';\n\n/**\n * A service object which is responsible for fetching network activity data.\n */\nexport type AbstractMultichainNetworkService =\n PublicInterface<MultichainNetworkService>;\n"]}
@@ -0,0 +1,7 @@
1
+ import type { PublicInterface } from "@metamask/utils";
2
+ import type { MultichainNetworkService } from "./MultichainNetworkService.cjs";
3
+ /**
4
+ * A service object which is responsible for fetching network activity data.
5
+ */
6
+ export type AbstractMultichainNetworkService = PublicInterface<MultichainNetworkService>;
7
+ //# sourceMappingURL=AbstractMultichainNetworkService.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractMultichainNetworkService.d.cts","sourceRoot":"","sources":["../../src/MultichainNetworkService/AbstractMultichainNetworkService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAwB;AAEvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,uCAAmC;AAE3E;;GAEG;AACH,MAAM,MAAM,gCAAgC,GAC1C,eAAe,CAAC,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { PublicInterface } from "@metamask/utils";
2
+ import type { MultichainNetworkService } from "./MultichainNetworkService.mjs";
3
+ /**
4
+ * A service object which is responsible for fetching network activity data.
5
+ */
6
+ export type AbstractMultichainNetworkService = PublicInterface<MultichainNetworkService>;
7
+ //# sourceMappingURL=AbstractMultichainNetworkService.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractMultichainNetworkService.d.mts","sourceRoot":"","sources":["../../src/MultichainNetworkService/AbstractMultichainNetworkService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,wBAAwB;AAEvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,uCAAmC;AAE3E;;GAEG;AACH,MAAM,MAAM,gCAAgC,GAC1C,eAAe,CAAC,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AbstractMultichainNetworkService.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractMultichainNetworkService.mjs","sourceRoot":"","sources":["../../src/MultichainNetworkService/AbstractMultichainNetworkService.ts"],"names":[],"mappings":"","sourcesContent":["import type { PublicInterface } from '@metamask/utils';\n\nimport type { MultichainNetworkService } from './MultichainNetworkService';\n\n/**\n * A service object which is responsible for fetching network activity data.\n */\nexport type AbstractMultichainNetworkService =\n PublicInterface<MultichainNetworkService>;\n"]}