@metamask-previews/network-enablement-controller 0.6.0-preview-0684712d → 1.0.0-preview-1f079244

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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.0]
11
+
12
+ ### Changed
13
+
14
+ - Bump `@metamask/utils` from `^11.4.2` to `^11.8.0` ([#6588](https://github.com/MetaMask/core/pull/6588))
15
+ - **BREAKING:** `enableNetwork()` and `enableAllPopularNetworks()` now disable networks across all namespaces instead of only within the same namespace, implementing truly exclusive network selection across all blockchain types ([#6591](https://github.com/MetaMask/core/pull/6591))
16
+
10
17
  ## [0.6.0]
11
18
 
12
19
  ### Added
@@ -74,7 +81,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
74
81
 
75
82
  - Initial release ([#6028](https://github.com/MetaMask/core/pull/6028))
76
83
 
77
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@0.6.0...HEAD
84
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@1.0.0...HEAD
85
+ [1.0.0]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@0.6.0...@metamask/network-enablement-controller@1.0.0
78
86
  [0.6.0]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@0.5.0...@metamask/network-enablement-controller@0.6.0
79
87
  [0.5.0]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@0.4.0...@metamask/network-enablement-controller@0.5.0
80
88
  [0.4.0]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@0.3.0...@metamask/network-enablement-controller@0.4.0
@@ -101,15 +101,17 @@ class NetworkEnablementController extends base_controller_1.BaseController {
101
101
  enableNetwork(chainId) {
102
102
  const { namespace, storageKey } = (0, utils_2.deriveKeys)(chainId);
103
103
  this.update((s) => {
104
+ // disable all networks in all namespaces first
105
+ Object.keys(s.enabledNetworkMap).forEach((ns) => {
106
+ Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {
107
+ s.enabledNetworkMap[ns][key] = false;
108
+ });
109
+ });
104
110
  // if the namespace bucket does not exist, return
105
111
  // new nemespace are added only when a new network is added
106
112
  if (!s.enabledNetworkMap[namespace]) {
107
113
  return;
108
114
  }
109
- // disable all networks in the same namespace
110
- Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
111
- s.enabledNetworkMap[namespace][key] = false;
112
- });
113
115
  // enable the network
114
116
  s.enabledNetworkMap[namespace][storageKey] = true;
115
117
  });
@@ -117,14 +119,21 @@ class NetworkEnablementController extends base_controller_1.BaseController {
117
119
  /**
118
120
  * Enables all popular networks and Solana mainnet.
119
121
  *
120
- * This method enables all networks defined in POPULAR_NETWORKS (EVM networks)
121
- * and Solana mainnet. Unlike the enableNetwork method which has exclusive behavior,
122
- * this method enables multiple networks across namespaces simultaneously.
122
+ * This method first disables all networks across all namespaces, then enables
123
+ * all networks defined in POPULAR_NETWORKS (EVM networks), Solana mainnet, and
124
+ * Bitcoin mainnet. This provides exclusive behavior - only popular networks will
125
+ * be enabled after calling this method.
123
126
  *
124
127
  * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.
125
128
  */
126
129
  enableAllPopularNetworks() {
127
130
  this.update((s) => {
131
+ // First disable all networks across all namespaces
132
+ Object.keys(s.enabledNetworkMap).forEach((ns) => {
133
+ Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {
134
+ s.enabledNetworkMap[ns][key] = false;
135
+ });
136
+ });
128
137
  // Get current network configurations to check if networks exist
129
138
  const networkControllerState = this.messagingSystem.call('NetworkController:getState');
130
139
  const multichainState = this.messagingSystem.call('MultichainNetworkController:getState');
@@ -279,11 +288,13 @@ _NetworkEnablementController_instances = new WeakSet(), _NetworkEnablementContro
279
288
  this.update((s) => {
280
289
  // Ensure the namespace bucket exists
281
290
  __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, s, namespace);
282
- // If adding a non-popular network, disable all other networks in the same namespace
291
+ // If adding a non-popular network, disable all other networks in all namespaces
283
292
  // This implements exclusive mode where only one non-popular network can be active
284
293
  if (!(0, utils_2.isPopularNetwork)(reference)) {
285
- Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
286
- s.enabledNetworkMap[namespace][key] = false;
294
+ Object.keys(s.enabledNetworkMap).forEach((ns) => {
295
+ Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {
296
+ s.enabledNetworkMap[ns][key] = false;
297
+ });
287
298
  });
288
299
  }
289
300
  // Add the new network as enabled
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkEnablementController.cjs","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BuiltInNetworkName, ChainId } from '@metamask/controller-utils';\nimport type { MultichainNetworkControllerGetStateAction } from '@metamask/multichain-network-controller';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkRemovedEvent,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { TransactionControllerTransactionSubmittedEvent } from '@metamask/transaction-controller';\nimport type { CaipChainId, CaipNamespace, Hex } from '@metamask/utils';\nimport { KnownCaipNamespace } from '@metamask/utils';\n\nimport { POPULAR_NETWORKS } from './constants';\nimport { BtcScope, SolScope } from './types';\nimport {\n deriveKeys,\n isOnlyNetworkEnabledInNamespace,\n isPopularNetwork,\n} from './utils';\n\nconst controllerName = 'NetworkEnablementController';\n\n/**\n * Information about an ordered network.\n */\nexport type NetworksInfo = {\n /**\n * The network's chain id\n */\n networkId: CaipChainId;\n};\n\n/**\n * A map of enabled networks by CAIP namespace and chain ID.\n * For EIP-155 networks, the keys are Hex chain IDs.\n * For other networks, the keys are CAIP chain IDs.\n */\ntype EnabledMap = Record<CaipNamespace, Record<CaipChainId | Hex, boolean>>;\n\n// State shape for NetworkEnablementController\nexport type NetworkEnablementControllerState = {\n enabledNetworkMap: EnabledMap;\n};\n\nexport type NetworkEnablementControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerSetEnabledNetworksAction = {\n type: `${typeof controllerName}:enableNetwork`;\n handler: NetworkEnablementController['enableNetwork'];\n};\n\nexport type NetworkEnablementControllerDisableNetworkAction = {\n type: `${typeof controllerName}:disableNetwork`;\n handler: NetworkEnablementController['disableNetwork'];\n};\n\n/**\n * All actions that {@link NetworkEnablementController} calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetStateAction\n | MultichainNetworkControllerGetStateAction;\n\nexport type NetworkEnablementControllerActions =\n | NetworkEnablementControllerGetStateAction\n | NetworkEnablementControllerSetEnabledNetworksAction\n | NetworkEnablementControllerDisableNetworkAction;\n\nexport type NetworkEnablementControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerEvents =\n NetworkEnablementControllerStateChangeEvent;\n\n/**\n * All events that {@link NetworkEnablementController} subscribes to internally.\n */\nexport type AllowedEvents =\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkRemovedEvent\n | NetworkControllerStateChangeEvent\n | TransactionControllerTransactionSubmittedEvent;\n\nexport type NetworkEnablementControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n NetworkEnablementControllerActions | AllowedActions,\n NetworkEnablementControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Gets the default state for the NetworkEnablementController.\n *\n * @returns The default state with pre-enabled networks.\n */\nconst getDefaultNetworkEnablementControllerState =\n (): NetworkEnablementControllerState => ({\n enabledNetworkMap: {\n [KnownCaipNamespace.Eip155]: {\n [ChainId[BuiltInNetworkName.Mainnet]]: true,\n [ChainId[BuiltInNetworkName.LineaMainnet]]: true,\n [ChainId[BuiltInNetworkName.BaseMainnet]]: true,\n },\n [KnownCaipNamespace.Solana]: {\n [SolScope.Mainnet]: true,\n [SolScope.Testnet]: false,\n [SolScope.Devnet]: false,\n },\n [KnownCaipNamespace.Bip122]: {\n [BtcScope.Mainnet]: true,\n [BtcScope.Testnet]: false,\n [BtcScope.Signet]: false,\n },\n },\n });\n\n// Metadata for the controller state\nconst metadata = {\n enabledNetworkMap: {\n includeInStateLogs: true,\n persist: true,\n anonymous: true,\n usedInUi: true,\n },\n};\n\n/**\n * Controller responsible for managing network enablement state across different blockchain networks.\n *\n * This controller tracks which networks are enabled/disabled for the user and provides methods\n * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.\n *\n * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')\n * and provides methods to query and modify network enablement states.\n */\nexport class NetworkEnablementController extends BaseController<\n typeof controllerName,\n NetworkEnablementControllerState,\n NetworkEnablementControllerMessenger\n> {\n /**\n * Creates a NetworkEnablementController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: NetworkEnablementControllerMessenger;\n state?: Partial<NetworkEnablementControllerState>;\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: {\n ...getDefaultNetworkEnablementControllerState(),\n ...state,\n },\n });\n\n messenger.subscribe('NetworkController:networkAdded', ({ chainId }) => {\n this.#onAddNetwork(chainId);\n });\n\n messenger.subscribe('NetworkController:networkRemoved', ({ chainId }) => {\n this.#removeNetworkEntry(chainId);\n });\n }\n\n /**\n * Enables or disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally. This dual parameter support allows for backward\n * compatibility with existing EVM chain ID formats while supporting newer\n * multi-chain standards.\n *\n * When enabling a non-popular network, this method will disable all other networks\n * to ensure only one network is active at a time (exclusive mode).\n *\n * @param chainId - The chain ID of the network to enable or disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n enableNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey } = deriveKeys(chainId);\n\n this.update((s) => {\n // if the namespace bucket does not exist, return\n // new nemespace are added only when a new network is added\n if (!s.enabledNetworkMap[namespace]) {\n return;\n }\n\n // disable all networks in the same namespace\n Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {\n s.enabledNetworkMap[namespace][key as CaipChainId | Hex] = false;\n });\n\n // enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n\n /**\n * Enables all popular networks and Solana mainnet.\n *\n * This method enables all networks defined in POPULAR_NETWORKS (EVM networks)\n * and Solana mainnet. Unlike the enableNetwork method which has exclusive behavior,\n * this method enables multiple networks across namespaces simultaneously.\n *\n * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.\n */\n enableAllPopularNetworks(): void {\n this.update((s) => {\n // Get current network configurations to check if networks exist\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Enable all popular EVM networks that exist in NetworkController configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n // Enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in MultichainNetworkController configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, solanaKeys.namespace);\n // Enable Solana mainnet\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in MultichainNetworkController configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, bitcoinKeys.namespace);\n // Enable Bitcoin mainnet\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n });\n }\n\n /**\n * Initializes the network enablement state from network controller configurations.\n *\n * This method reads the current network configurations from both NetworkController\n * and MultichainNetworkController and initializes the enabled network map accordingly.\n * It ensures proper namespace buckets exist for all configured networks and enables\n * popular networks by default.\n *\n * This method should be called after the NetworkController and MultichainNetworkController\n * have been initialized and their configurations are available.\n */\n init(): void {\n this.update((s) => {\n // Get network configurations from NetworkController (EVM networks)\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n // Get network configurations from MultichainNetworkController (all networks)\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Initialize namespace buckets for EVM networks from NetworkController\n Object.keys(\n networkControllerState.networkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as Hex);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Initialize namespace buckets for all networks from MultichainNetworkController\n Object.keys(\n multichainState.multichainNetworkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as CaipChainId);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Enable popular networks that exist in the configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n s.enabledNetworkMap[namespace] &&\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[solanaKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n\n // Enable Bitcoin testnet if it exists in configurations\n const bitcoinTestnetKeys = deriveKeys(BtcScope.Testnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Testnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace][\n bitcoinTestnetKeys.storageKey\n ] = false;\n }\n\n // Enable Bitcoin signet testnet if it exists in configurations\n const bitcoinSignetKeys = deriveKeys(BtcScope.Signet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinSignetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Signet\n ]\n ) {\n s.enabledNetworkMap[bitcoinSignetKeys.namespace][\n bitcoinSignetKeys.storageKey\n ] = false;\n }\n });\n }\n\n /**\n * Disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally.\n *\n * Note: This method will prevent disabling the last remaining enabled network\n * to ensure at least one network is always available.\n *\n * @param chainId - The chain ID of the network to disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n disableNetwork(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n s.enabledNetworkMap[namespace][storageKey] = false;\n });\n }\n\n /**\n * Checks if a network is enabled.\n *\n * @param chainId - The chain ID of the network to check. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n * @returns True if the network is enabled, false otherwise\n */\n isNetworkEnabled(chainId: Hex | CaipChainId): boolean {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n return this.state.enabledNetworkMap[namespace]?.[storageKey] ?? false;\n }\n\n /**\n * Ensures that a namespace bucket exists in the state.\n *\n * This method creates the namespace entry in the enabledNetworkMap if it doesn't\n * already exist. This is used to prepare the state structure before adding\n * network entries.\n *\n * @param state - The current controller state\n * @param ns - The CAIP namespace to ensure exists\n */\n #ensureNamespaceBucket(\n state: NetworkEnablementControllerState,\n ns: CaipNamespace,\n ) {\n if (!state.enabledNetworkMap[ns]) {\n state.enabledNetworkMap[ns] = {};\n }\n }\n\n /**\n * Removes a network entry from the state.\n *\n * This method is called when a network is removed from the system. It cleans up\n * the network entry and ensures that at least one network remains enabled.\n *\n * @param chainId - The chain ID to remove (Hex or CAIP-2 format)\n */\n #removeNetworkEntry(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n // fallback and enable ethereum mainnet\n if (isOnlyNetworkEnabledInNamespace(this.state, derivedKeys)) {\n s.enabledNetworkMap[namespace][ChainId[BuiltInNetworkName.Mainnet]] =\n true;\n }\n\n if (namespace in s.enabledNetworkMap) {\n delete s.enabledNetworkMap[namespace][storageKey];\n }\n });\n }\n\n /**\n * Handles the addition of a new network to the controller.\n *\n * This method is called when a network is added to the system. It automatically\n * enables the new network and implements exclusive mode for non-popular networks.\n * If the network already exists, no changes are made.\n *\n * @param chainId - The chain ID of the network being added (Hex or CAIP-2 format)\n */\n #onAddNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey, reference } = deriveKeys(chainId);\n\n this.update((s) => {\n // Ensure the namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n\n // If adding a non-popular network, disable all other networks in the same namespace\n // This implements exclusive mode where only one non-popular network can be active\n if (!isPopularNetwork(reference)) {\n Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {\n s.enabledNetworkMap[namespace][key as CaipChainId | Hex] = false;\n });\n }\n\n // Add the new network as enabled\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n}\n"]}
1
+ {"version":3,"file":"NetworkEnablementController.cjs","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BuiltInNetworkName, ChainId } from '@metamask/controller-utils';\nimport type { MultichainNetworkControllerGetStateAction } from '@metamask/multichain-network-controller';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkRemovedEvent,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { TransactionControllerTransactionSubmittedEvent } from '@metamask/transaction-controller';\nimport type { CaipChainId, CaipNamespace, Hex } from '@metamask/utils';\nimport { KnownCaipNamespace } from '@metamask/utils';\n\nimport { POPULAR_NETWORKS } from './constants';\nimport { BtcScope, SolScope } from './types';\nimport {\n deriveKeys,\n isOnlyNetworkEnabledInNamespace,\n isPopularNetwork,\n} from './utils';\n\nconst controllerName = 'NetworkEnablementController';\n\n/**\n * Information about an ordered network.\n */\nexport type NetworksInfo = {\n /**\n * The network's chain id\n */\n networkId: CaipChainId;\n};\n\n/**\n * A map of enabled networks by CAIP namespace and chain ID.\n * For EIP-155 networks, the keys are Hex chain IDs.\n * For other networks, the keys are CAIP chain IDs.\n */\ntype EnabledMap = Record<CaipNamespace, Record<CaipChainId | Hex, boolean>>;\n\n// State shape for NetworkEnablementController\nexport type NetworkEnablementControllerState = {\n enabledNetworkMap: EnabledMap;\n};\n\nexport type NetworkEnablementControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerSetEnabledNetworksAction = {\n type: `${typeof controllerName}:enableNetwork`;\n handler: NetworkEnablementController['enableNetwork'];\n};\n\nexport type NetworkEnablementControllerDisableNetworkAction = {\n type: `${typeof controllerName}:disableNetwork`;\n handler: NetworkEnablementController['disableNetwork'];\n};\n\n/**\n * All actions that {@link NetworkEnablementController} calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetStateAction\n | MultichainNetworkControllerGetStateAction;\n\nexport type NetworkEnablementControllerActions =\n | NetworkEnablementControllerGetStateAction\n | NetworkEnablementControllerSetEnabledNetworksAction\n | NetworkEnablementControllerDisableNetworkAction;\n\nexport type NetworkEnablementControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerEvents =\n NetworkEnablementControllerStateChangeEvent;\n\n/**\n * All events that {@link NetworkEnablementController} subscribes to internally.\n */\nexport type AllowedEvents =\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkRemovedEvent\n | NetworkControllerStateChangeEvent\n | TransactionControllerTransactionSubmittedEvent;\n\nexport type NetworkEnablementControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n NetworkEnablementControllerActions | AllowedActions,\n NetworkEnablementControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Gets the default state for the NetworkEnablementController.\n *\n * @returns The default state with pre-enabled networks.\n */\nconst getDefaultNetworkEnablementControllerState =\n (): NetworkEnablementControllerState => ({\n enabledNetworkMap: {\n [KnownCaipNamespace.Eip155]: {\n [ChainId[BuiltInNetworkName.Mainnet]]: true,\n [ChainId[BuiltInNetworkName.LineaMainnet]]: true,\n [ChainId[BuiltInNetworkName.BaseMainnet]]: true,\n },\n [KnownCaipNamespace.Solana]: {\n [SolScope.Mainnet]: true,\n [SolScope.Testnet]: false,\n [SolScope.Devnet]: false,\n },\n [KnownCaipNamespace.Bip122]: {\n [BtcScope.Mainnet]: true,\n [BtcScope.Testnet]: false,\n [BtcScope.Signet]: false,\n },\n },\n });\n\n// Metadata for the controller state\nconst metadata = {\n enabledNetworkMap: {\n includeInStateLogs: true,\n persist: true,\n anonymous: true,\n usedInUi: true,\n },\n};\n\n/**\n * Controller responsible for managing network enablement state across different blockchain networks.\n *\n * This controller tracks which networks are enabled/disabled for the user and provides methods\n * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.\n *\n * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')\n * and provides methods to query and modify network enablement states.\n */\nexport class NetworkEnablementController extends BaseController<\n typeof controllerName,\n NetworkEnablementControllerState,\n NetworkEnablementControllerMessenger\n> {\n /**\n * Creates a NetworkEnablementController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: NetworkEnablementControllerMessenger;\n state?: Partial<NetworkEnablementControllerState>;\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: {\n ...getDefaultNetworkEnablementControllerState(),\n ...state,\n },\n });\n\n messenger.subscribe('NetworkController:networkAdded', ({ chainId }) => {\n this.#onAddNetwork(chainId);\n });\n\n messenger.subscribe('NetworkController:networkRemoved', ({ chainId }) => {\n this.#removeNetworkEntry(chainId);\n });\n }\n\n /**\n * Enables or disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally. This dual parameter support allows for backward\n * compatibility with existing EVM chain ID formats while supporting newer\n * multi-chain standards.\n *\n * When enabling a non-popular network, this method will disable all other networks\n * to ensure only one network is active at a time (exclusive mode).\n *\n * @param chainId - The chain ID of the network to enable or disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n enableNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey } = deriveKeys(chainId);\n\n this.update((s) => {\n // disable all networks in all namespaces first\n Object.keys(s.enabledNetworkMap).forEach((ns) => {\n Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {\n s.enabledNetworkMap[ns][key as CaipChainId | Hex] = false;\n });\n });\n\n // if the namespace bucket does not exist, return\n // new nemespace are added only when a new network is added\n if (!s.enabledNetworkMap[namespace]) {\n return;\n }\n\n // enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n\n /**\n * Enables all popular networks and Solana mainnet.\n *\n * This method first disables all networks across all namespaces, then enables\n * all networks defined in POPULAR_NETWORKS (EVM networks), Solana mainnet, and\n * Bitcoin mainnet. This provides exclusive behavior - only popular networks will\n * be enabled after calling this method.\n *\n * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.\n */\n enableAllPopularNetworks(): void {\n this.update((s) => {\n // First disable all networks across all namespaces\n Object.keys(s.enabledNetworkMap).forEach((ns) => {\n Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {\n s.enabledNetworkMap[ns][key as CaipChainId | Hex] = false;\n });\n });\n\n // Get current network configurations to check if networks exist\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Enable all popular EVM networks that exist in NetworkController configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n // Enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in MultichainNetworkController configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, solanaKeys.namespace);\n // Enable Solana mainnet\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in MultichainNetworkController configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, bitcoinKeys.namespace);\n // Enable Bitcoin mainnet\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n });\n }\n\n /**\n * Initializes the network enablement state from network controller configurations.\n *\n * This method reads the current network configurations from both NetworkController\n * and MultichainNetworkController and initializes the enabled network map accordingly.\n * It ensures proper namespace buckets exist for all configured networks and enables\n * popular networks by default.\n *\n * This method should be called after the NetworkController and MultichainNetworkController\n * have been initialized and their configurations are available.\n */\n init(): void {\n this.update((s) => {\n // Get network configurations from NetworkController (EVM networks)\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n // Get network configurations from MultichainNetworkController (all networks)\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Initialize namespace buckets for EVM networks from NetworkController\n Object.keys(\n networkControllerState.networkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as Hex);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Initialize namespace buckets for all networks from MultichainNetworkController\n Object.keys(\n multichainState.multichainNetworkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as CaipChainId);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Enable popular networks that exist in the configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n s.enabledNetworkMap[namespace] &&\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[solanaKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n\n // Enable Bitcoin testnet if it exists in configurations\n const bitcoinTestnetKeys = deriveKeys(BtcScope.Testnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Testnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace][\n bitcoinTestnetKeys.storageKey\n ] = false;\n }\n\n // Enable Bitcoin signet testnet if it exists in configurations\n const bitcoinSignetKeys = deriveKeys(BtcScope.Signet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinSignetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Signet\n ]\n ) {\n s.enabledNetworkMap[bitcoinSignetKeys.namespace][\n bitcoinSignetKeys.storageKey\n ] = false;\n }\n });\n }\n\n /**\n * Disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally.\n *\n * Note: This method will prevent disabling the last remaining enabled network\n * to ensure at least one network is always available.\n *\n * @param chainId - The chain ID of the network to disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n disableNetwork(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n s.enabledNetworkMap[namespace][storageKey] = false;\n });\n }\n\n /**\n * Checks if a network is enabled.\n *\n * @param chainId - The chain ID of the network to check. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n * @returns True if the network is enabled, false otherwise\n */\n isNetworkEnabled(chainId: Hex | CaipChainId): boolean {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n return this.state.enabledNetworkMap[namespace]?.[storageKey] ?? false;\n }\n\n /**\n * Ensures that a namespace bucket exists in the state.\n *\n * This method creates the namespace entry in the enabledNetworkMap if it doesn't\n * already exist. This is used to prepare the state structure before adding\n * network entries.\n *\n * @param state - The current controller state\n * @param ns - The CAIP namespace to ensure exists\n */\n #ensureNamespaceBucket(\n state: NetworkEnablementControllerState,\n ns: CaipNamespace,\n ) {\n if (!state.enabledNetworkMap[ns]) {\n state.enabledNetworkMap[ns] = {};\n }\n }\n\n /**\n * Removes a network entry from the state.\n *\n * This method is called when a network is removed from the system. It cleans up\n * the network entry and ensures that at least one network remains enabled.\n *\n * @param chainId - The chain ID to remove (Hex or CAIP-2 format)\n */\n #removeNetworkEntry(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n // fallback and enable ethereum mainnet\n if (isOnlyNetworkEnabledInNamespace(this.state, derivedKeys)) {\n s.enabledNetworkMap[namespace][ChainId[BuiltInNetworkName.Mainnet]] =\n true;\n }\n\n if (namespace in s.enabledNetworkMap) {\n delete s.enabledNetworkMap[namespace][storageKey];\n }\n });\n }\n\n /**\n * Handles the addition of a new network to the controller.\n *\n * This method is called when a network is added to the system. It automatically\n * enables the new network and implements exclusive mode for non-popular networks.\n * If the network already exists, no changes are made.\n *\n * @param chainId - The chain ID of the network being added (Hex or CAIP-2 format)\n */\n #onAddNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey, reference } = deriveKeys(chainId);\n\n this.update((s) => {\n // Ensure the namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n\n // If adding a non-popular network, disable all other networks in all namespaces\n // This implements exclusive mode where only one non-popular network can be active\n if (!isPopularNetwork(reference)) {\n Object.keys(s.enabledNetworkMap).forEach((ns) => {\n Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {\n s.enabledNetworkMap[ns][key as CaipChainId | Hex] = false;\n });\n });\n }\n\n // Add the new network as enabled\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n}\n"]}
@@ -86,9 +86,10 @@ export declare class NetworkEnablementController extends BaseController<typeof c
86
86
  /**
87
87
  * Enables all popular networks and Solana mainnet.
88
88
  *
89
- * This method enables all networks defined in POPULAR_NETWORKS (EVM networks)
90
- * and Solana mainnet. Unlike the enableNetwork method which has exclusive behavior,
91
- * this method enables multiple networks across namespaces simultaneously.
89
+ * This method first disables all networks across all namespaces, then enables
90
+ * all networks defined in POPULAR_NETWORKS (EVM networks), Solana mainnet, and
91
+ * Bitcoin mainnet. This provides exclusive behavior - only popular networks will
92
+ * be enabled after calling this method.
92
93
  *
93
94
  * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.
94
95
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkEnablementController.d.cts","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AAEnC,OAAO,KAAK,EAAE,yCAAyC,EAAE,gDAAgD;AACzG,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EAClC,oCAAoC,EACpC,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,KAAK,EAAE,8CAA8C,EAAE,yCAAyC;AACvG,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAWvE,QAAA,MAAM,cAAc,gCAAgC,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAG5E,MAAM,MAAM,gCAAgC,GAAG;IAC7C,iBAAiB,EAAE,UAAU,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,yCAAyC,GACnD,wBAAwB,CACtB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,2BAA2B,CAAC,eAAe,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;CACxD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,+BAA+B,GAC/B,yCAAyC,CAAC;AAE9C,MAAM,MAAM,kCAAkC,GAC1C,yCAAyC,GACzC,mDAAmD,GACnD,+CAA+C,CAAC;AAEpD,MAAM,MAAM,2CAA2C,GACrD,0BAA0B,CACxB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,iCAAiC,GAC3C,2CAA2C,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,kCAAkC,GAClC,oCAAoC,GACpC,iCAAiC,GACjC,8CAA8C,CAAC;AAEnD,MAAM,MAAM,oCAAoC,GAAG,mBAAmB,CACpE,OAAO,cAAc,EACrB,kCAAkC,GAAG,cAAc,EACnD,iCAAiC,GAAG,aAAa,EACjD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAsCF;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAC7D,OAAO,cAAc,EACrB,gCAAgC,EAChC,oCAAoC,CACrC;;IACC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,oCAAoC,CAAC;QAChD,KAAK,CAAC,EAAE,OAAO,CAAC,gCAAgC,CAAC,CAAC;KACnD;IAoBD;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAoB/C;;;;;;;;OAQG;IACH,wBAAwB,IAAI,IAAI;IAsDhC;;;;;;;;;;OAUG;IACH,IAAI,IAAI,IAAI;IA4FZ;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAShD;;;;;;;OAOG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,OAAO;CA8EtD"}
1
+ {"version":3,"file":"NetworkEnablementController.d.cts","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AAEnC,OAAO,KAAK,EAAE,yCAAyC,EAAE,gDAAgD;AACzG,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EAClC,oCAAoC,EACpC,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,KAAK,EAAE,8CAA8C,EAAE,yCAAyC;AACvG,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAWvE,QAAA,MAAM,cAAc,gCAAgC,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAG5E,MAAM,MAAM,gCAAgC,GAAG;IAC7C,iBAAiB,EAAE,UAAU,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,yCAAyC,GACnD,wBAAwB,CACtB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,2BAA2B,CAAC,eAAe,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;CACxD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,+BAA+B,GAC/B,yCAAyC,CAAC;AAE9C,MAAM,MAAM,kCAAkC,GAC1C,yCAAyC,GACzC,mDAAmD,GACnD,+CAA+C,CAAC;AAEpD,MAAM,MAAM,2CAA2C,GACrD,0BAA0B,CACxB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,iCAAiC,GAC3C,2CAA2C,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,kCAAkC,GAClC,oCAAoC,GACpC,iCAAiC,GACjC,8CAA8C,CAAC;AAEnD,MAAM,MAAM,oCAAoC,GAAG,mBAAmB,CACpE,OAAO,cAAc,EACrB,kCAAkC,GAAG,cAAc,EACnD,iCAAiC,GAAG,aAAa,EACjD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAsCF;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAC7D,OAAO,cAAc,EACrB,gCAAgC,EAChC,oCAAoC,CACrC;;IACC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,oCAAoC,CAAC;QAChD,KAAK,CAAC,EAAE,OAAO,CAAC,gCAAgC,CAAC,CAAC;KACnD;IAoBD;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAsB/C;;;;;;;;;OASG;IACH,wBAAwB,IAAI,IAAI;IA6DhC;;;;;;;;;;OAUG;IACH,IAAI,IAAI,IAAI;IA4FZ;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAShD;;;;;;;OAOG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,OAAO;CAgFtD"}
@@ -86,9 +86,10 @@ export declare class NetworkEnablementController extends BaseController<typeof c
86
86
  /**
87
87
  * Enables all popular networks and Solana mainnet.
88
88
  *
89
- * This method enables all networks defined in POPULAR_NETWORKS (EVM networks)
90
- * and Solana mainnet. Unlike the enableNetwork method which has exclusive behavior,
91
- * this method enables multiple networks across namespaces simultaneously.
89
+ * This method first disables all networks across all namespaces, then enables
90
+ * all networks defined in POPULAR_NETWORKS (EVM networks), Solana mainnet, and
91
+ * Bitcoin mainnet. This provides exclusive behavior - only popular networks will
92
+ * be enabled after calling this method.
92
93
  *
93
94
  * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.
94
95
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkEnablementController.d.mts","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AAEnC,OAAO,KAAK,EAAE,yCAAyC,EAAE,gDAAgD;AACzG,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EAClC,oCAAoC,EACpC,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,KAAK,EAAE,8CAA8C,EAAE,yCAAyC;AACvG,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAWvE,QAAA,MAAM,cAAc,gCAAgC,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAG5E,MAAM,MAAM,gCAAgC,GAAG;IAC7C,iBAAiB,EAAE,UAAU,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,yCAAyC,GACnD,wBAAwB,CACtB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,2BAA2B,CAAC,eAAe,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;CACxD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,+BAA+B,GAC/B,yCAAyC,CAAC;AAE9C,MAAM,MAAM,kCAAkC,GAC1C,yCAAyC,GACzC,mDAAmD,GACnD,+CAA+C,CAAC;AAEpD,MAAM,MAAM,2CAA2C,GACrD,0BAA0B,CACxB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,iCAAiC,GAC3C,2CAA2C,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,kCAAkC,GAClC,oCAAoC,GACpC,iCAAiC,GACjC,8CAA8C,CAAC;AAEnD,MAAM,MAAM,oCAAoC,GAAG,mBAAmB,CACpE,OAAO,cAAc,EACrB,kCAAkC,GAAG,cAAc,EACnD,iCAAiC,GAAG,aAAa,EACjD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAsCF;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAC7D,OAAO,cAAc,EACrB,gCAAgC,EAChC,oCAAoC,CACrC;;IACC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,oCAAoC,CAAC;QAChD,KAAK,CAAC,EAAE,OAAO,CAAC,gCAAgC,CAAC,CAAC;KACnD;IAoBD;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAoB/C;;;;;;;;OAQG;IACH,wBAAwB,IAAI,IAAI;IAsDhC;;;;;;;;;;OAUG;IACH,IAAI,IAAI,IAAI;IA4FZ;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAShD;;;;;;;OAOG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,OAAO;CA8EtD"}
1
+ {"version":3,"file":"NetworkEnablementController.d.mts","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AAEnC,OAAO,KAAK,EAAE,yCAAyC,EAAE,gDAAgD;AACzG,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EAClC,oCAAoC,EACpC,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,KAAK,EAAE,8CAA8C,EAAE,yCAAyC;AACvG,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAWvE,QAAA,MAAM,cAAc,gCAAgC,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAG5E,MAAM,MAAM,gCAAgC,GAAG;IAC7C,iBAAiB,EAAE,UAAU,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,yCAAyC,GACnD,wBAAwB,CACtB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,2BAA2B,CAAC,eAAe,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;CACxD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,+BAA+B,GAC/B,yCAAyC,CAAC;AAE9C,MAAM,MAAM,kCAAkC,GAC1C,yCAAyC,GACzC,mDAAmD,GACnD,+CAA+C,CAAC;AAEpD,MAAM,MAAM,2CAA2C,GACrD,0BAA0B,CACxB,OAAO,cAAc,EACrB,gCAAgC,CACjC,CAAC;AAEJ,MAAM,MAAM,iCAAiC,GAC3C,2CAA2C,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,kCAAkC,GAClC,oCAAoC,GACpC,iCAAiC,GACjC,8CAA8C,CAAC;AAEnD,MAAM,MAAM,oCAAoC,GAAG,mBAAmB,CACpE,OAAO,cAAc,EACrB,kCAAkC,GAAG,cAAc,EACnD,iCAAiC,GAAG,aAAa,EACjD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAsCF;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAC7D,OAAO,cAAc,EACrB,gCAAgC,EAChC,oCAAoC,CACrC;;IACC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,oCAAoC,CAAC;QAChD,KAAK,CAAC,EAAE,OAAO,CAAC,gCAAgC,CAAC,CAAC;KACnD;IAoBD;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAsB/C;;;;;;;;;OASG;IACH,wBAAwB,IAAI,IAAI;IA6DhC;;;;;;;;;;OAUG;IACH,IAAI,IAAI,IAAI;IA4FZ;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;IAShD;;;;;;;OAOG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,OAAO;CAgFtD"}
@@ -98,15 +98,17 @@ export class NetworkEnablementController extends BaseController {
98
98
  enableNetwork(chainId) {
99
99
  const { namespace, storageKey } = deriveKeys(chainId);
100
100
  this.update((s) => {
101
+ // disable all networks in all namespaces first
102
+ Object.keys(s.enabledNetworkMap).forEach((ns) => {
103
+ Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {
104
+ s.enabledNetworkMap[ns][key] = false;
105
+ });
106
+ });
101
107
  // if the namespace bucket does not exist, return
102
108
  // new nemespace are added only when a new network is added
103
109
  if (!s.enabledNetworkMap[namespace]) {
104
110
  return;
105
111
  }
106
- // disable all networks in the same namespace
107
- Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
108
- s.enabledNetworkMap[namespace][key] = false;
109
- });
110
112
  // enable the network
111
113
  s.enabledNetworkMap[namespace][storageKey] = true;
112
114
  });
@@ -114,14 +116,21 @@ export class NetworkEnablementController extends BaseController {
114
116
  /**
115
117
  * Enables all popular networks and Solana mainnet.
116
118
  *
117
- * This method enables all networks defined in POPULAR_NETWORKS (EVM networks)
118
- * and Solana mainnet. Unlike the enableNetwork method which has exclusive behavior,
119
- * this method enables multiple networks across namespaces simultaneously.
119
+ * This method first disables all networks across all namespaces, then enables
120
+ * all networks defined in POPULAR_NETWORKS (EVM networks), Solana mainnet, and
121
+ * Bitcoin mainnet. This provides exclusive behavior - only popular networks will
122
+ * be enabled after calling this method.
120
123
  *
121
124
  * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.
122
125
  */
123
126
  enableAllPopularNetworks() {
124
127
  this.update((s) => {
128
+ // First disable all networks across all namespaces
129
+ Object.keys(s.enabledNetworkMap).forEach((ns) => {
130
+ Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {
131
+ s.enabledNetworkMap[ns][key] = false;
132
+ });
133
+ });
125
134
  // Get current network configurations to check if networks exist
126
135
  const networkControllerState = this.messagingSystem.call('NetworkController:getState');
127
136
  const multichainState = this.messagingSystem.call('MultichainNetworkController:getState');
@@ -275,11 +284,13 @@ _NetworkEnablementController_instances = new WeakSet(), _NetworkEnablementContro
275
284
  this.update((s) => {
276
285
  // Ensure the namespace bucket exists
277
286
  __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, s, namespace);
278
- // If adding a non-popular network, disable all other networks in the same namespace
287
+ // If adding a non-popular network, disable all other networks in all namespaces
279
288
  // This implements exclusive mode where only one non-popular network can be active
280
289
  if (!isPopularNetwork(reference)) {
281
- Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
282
- s.enabledNetworkMap[namespace][key] = false;
290
+ Object.keys(s.enabledNetworkMap).forEach((ns) => {
291
+ Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {
292
+ s.enabledNetworkMap[ns][key] = false;
293
+ });
283
294
  });
284
295
  }
285
296
  // Add the new network as enabled
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkEnablementController.mjs","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BuiltInNetworkName, ChainId } from '@metamask/controller-utils';\nimport type { MultichainNetworkControllerGetStateAction } from '@metamask/multichain-network-controller';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkRemovedEvent,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { TransactionControllerTransactionSubmittedEvent } from '@metamask/transaction-controller';\nimport type { CaipChainId, CaipNamespace, Hex } from '@metamask/utils';\nimport { KnownCaipNamespace } from '@metamask/utils';\n\nimport { POPULAR_NETWORKS } from './constants';\nimport { BtcScope, SolScope } from './types';\nimport {\n deriveKeys,\n isOnlyNetworkEnabledInNamespace,\n isPopularNetwork,\n} from './utils';\n\nconst controllerName = 'NetworkEnablementController';\n\n/**\n * Information about an ordered network.\n */\nexport type NetworksInfo = {\n /**\n * The network's chain id\n */\n networkId: CaipChainId;\n};\n\n/**\n * A map of enabled networks by CAIP namespace and chain ID.\n * For EIP-155 networks, the keys are Hex chain IDs.\n * For other networks, the keys are CAIP chain IDs.\n */\ntype EnabledMap = Record<CaipNamespace, Record<CaipChainId | Hex, boolean>>;\n\n// State shape for NetworkEnablementController\nexport type NetworkEnablementControllerState = {\n enabledNetworkMap: EnabledMap;\n};\n\nexport type NetworkEnablementControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerSetEnabledNetworksAction = {\n type: `${typeof controllerName}:enableNetwork`;\n handler: NetworkEnablementController['enableNetwork'];\n};\n\nexport type NetworkEnablementControllerDisableNetworkAction = {\n type: `${typeof controllerName}:disableNetwork`;\n handler: NetworkEnablementController['disableNetwork'];\n};\n\n/**\n * All actions that {@link NetworkEnablementController} calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetStateAction\n | MultichainNetworkControllerGetStateAction;\n\nexport type NetworkEnablementControllerActions =\n | NetworkEnablementControllerGetStateAction\n | NetworkEnablementControllerSetEnabledNetworksAction\n | NetworkEnablementControllerDisableNetworkAction;\n\nexport type NetworkEnablementControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerEvents =\n NetworkEnablementControllerStateChangeEvent;\n\n/**\n * All events that {@link NetworkEnablementController} subscribes to internally.\n */\nexport type AllowedEvents =\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkRemovedEvent\n | NetworkControllerStateChangeEvent\n | TransactionControllerTransactionSubmittedEvent;\n\nexport type NetworkEnablementControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n NetworkEnablementControllerActions | AllowedActions,\n NetworkEnablementControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Gets the default state for the NetworkEnablementController.\n *\n * @returns The default state with pre-enabled networks.\n */\nconst getDefaultNetworkEnablementControllerState =\n (): NetworkEnablementControllerState => ({\n enabledNetworkMap: {\n [KnownCaipNamespace.Eip155]: {\n [ChainId[BuiltInNetworkName.Mainnet]]: true,\n [ChainId[BuiltInNetworkName.LineaMainnet]]: true,\n [ChainId[BuiltInNetworkName.BaseMainnet]]: true,\n },\n [KnownCaipNamespace.Solana]: {\n [SolScope.Mainnet]: true,\n [SolScope.Testnet]: false,\n [SolScope.Devnet]: false,\n },\n [KnownCaipNamespace.Bip122]: {\n [BtcScope.Mainnet]: true,\n [BtcScope.Testnet]: false,\n [BtcScope.Signet]: false,\n },\n },\n });\n\n// Metadata for the controller state\nconst metadata = {\n enabledNetworkMap: {\n includeInStateLogs: true,\n persist: true,\n anonymous: true,\n usedInUi: true,\n },\n};\n\n/**\n * Controller responsible for managing network enablement state across different blockchain networks.\n *\n * This controller tracks which networks are enabled/disabled for the user and provides methods\n * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.\n *\n * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')\n * and provides methods to query and modify network enablement states.\n */\nexport class NetworkEnablementController extends BaseController<\n typeof controllerName,\n NetworkEnablementControllerState,\n NetworkEnablementControllerMessenger\n> {\n /**\n * Creates a NetworkEnablementController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: NetworkEnablementControllerMessenger;\n state?: Partial<NetworkEnablementControllerState>;\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: {\n ...getDefaultNetworkEnablementControllerState(),\n ...state,\n },\n });\n\n messenger.subscribe('NetworkController:networkAdded', ({ chainId }) => {\n this.#onAddNetwork(chainId);\n });\n\n messenger.subscribe('NetworkController:networkRemoved', ({ chainId }) => {\n this.#removeNetworkEntry(chainId);\n });\n }\n\n /**\n * Enables or disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally. This dual parameter support allows for backward\n * compatibility with existing EVM chain ID formats while supporting newer\n * multi-chain standards.\n *\n * When enabling a non-popular network, this method will disable all other networks\n * to ensure only one network is active at a time (exclusive mode).\n *\n * @param chainId - The chain ID of the network to enable or disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n enableNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey } = deriveKeys(chainId);\n\n this.update((s) => {\n // if the namespace bucket does not exist, return\n // new nemespace are added only when a new network is added\n if (!s.enabledNetworkMap[namespace]) {\n return;\n }\n\n // disable all networks in the same namespace\n Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {\n s.enabledNetworkMap[namespace][key as CaipChainId | Hex] = false;\n });\n\n // enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n\n /**\n * Enables all popular networks and Solana mainnet.\n *\n * This method enables all networks defined in POPULAR_NETWORKS (EVM networks)\n * and Solana mainnet. Unlike the enableNetwork method which has exclusive behavior,\n * this method enables multiple networks across namespaces simultaneously.\n *\n * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.\n */\n enableAllPopularNetworks(): void {\n this.update((s) => {\n // Get current network configurations to check if networks exist\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Enable all popular EVM networks that exist in NetworkController configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n // Enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in MultichainNetworkController configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, solanaKeys.namespace);\n // Enable Solana mainnet\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in MultichainNetworkController configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, bitcoinKeys.namespace);\n // Enable Bitcoin mainnet\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n });\n }\n\n /**\n * Initializes the network enablement state from network controller configurations.\n *\n * This method reads the current network configurations from both NetworkController\n * and MultichainNetworkController and initializes the enabled network map accordingly.\n * It ensures proper namespace buckets exist for all configured networks and enables\n * popular networks by default.\n *\n * This method should be called after the NetworkController and MultichainNetworkController\n * have been initialized and their configurations are available.\n */\n init(): void {\n this.update((s) => {\n // Get network configurations from NetworkController (EVM networks)\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n // Get network configurations from MultichainNetworkController (all networks)\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Initialize namespace buckets for EVM networks from NetworkController\n Object.keys(\n networkControllerState.networkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as Hex);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Initialize namespace buckets for all networks from MultichainNetworkController\n Object.keys(\n multichainState.multichainNetworkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as CaipChainId);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Enable popular networks that exist in the configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n s.enabledNetworkMap[namespace] &&\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[solanaKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n\n // Enable Bitcoin testnet if it exists in configurations\n const bitcoinTestnetKeys = deriveKeys(BtcScope.Testnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Testnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace][\n bitcoinTestnetKeys.storageKey\n ] = false;\n }\n\n // Enable Bitcoin signet testnet if it exists in configurations\n const bitcoinSignetKeys = deriveKeys(BtcScope.Signet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinSignetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Signet\n ]\n ) {\n s.enabledNetworkMap[bitcoinSignetKeys.namespace][\n bitcoinSignetKeys.storageKey\n ] = false;\n }\n });\n }\n\n /**\n * Disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally.\n *\n * Note: This method will prevent disabling the last remaining enabled network\n * to ensure at least one network is always available.\n *\n * @param chainId - The chain ID of the network to disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n disableNetwork(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n s.enabledNetworkMap[namespace][storageKey] = false;\n });\n }\n\n /**\n * Checks if a network is enabled.\n *\n * @param chainId - The chain ID of the network to check. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n * @returns True if the network is enabled, false otherwise\n */\n isNetworkEnabled(chainId: Hex | CaipChainId): boolean {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n return this.state.enabledNetworkMap[namespace]?.[storageKey] ?? false;\n }\n\n /**\n * Ensures that a namespace bucket exists in the state.\n *\n * This method creates the namespace entry in the enabledNetworkMap if it doesn't\n * already exist. This is used to prepare the state structure before adding\n * network entries.\n *\n * @param state - The current controller state\n * @param ns - The CAIP namespace to ensure exists\n */\n #ensureNamespaceBucket(\n state: NetworkEnablementControllerState,\n ns: CaipNamespace,\n ) {\n if (!state.enabledNetworkMap[ns]) {\n state.enabledNetworkMap[ns] = {};\n }\n }\n\n /**\n * Removes a network entry from the state.\n *\n * This method is called when a network is removed from the system. It cleans up\n * the network entry and ensures that at least one network remains enabled.\n *\n * @param chainId - The chain ID to remove (Hex or CAIP-2 format)\n */\n #removeNetworkEntry(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n // fallback and enable ethereum mainnet\n if (isOnlyNetworkEnabledInNamespace(this.state, derivedKeys)) {\n s.enabledNetworkMap[namespace][ChainId[BuiltInNetworkName.Mainnet]] =\n true;\n }\n\n if (namespace in s.enabledNetworkMap) {\n delete s.enabledNetworkMap[namespace][storageKey];\n }\n });\n }\n\n /**\n * Handles the addition of a new network to the controller.\n *\n * This method is called when a network is added to the system. It automatically\n * enables the new network and implements exclusive mode for non-popular networks.\n * If the network already exists, no changes are made.\n *\n * @param chainId - The chain ID of the network being added (Hex or CAIP-2 format)\n */\n #onAddNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey, reference } = deriveKeys(chainId);\n\n this.update((s) => {\n // Ensure the namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n\n // If adding a non-popular network, disable all other networks in the same namespace\n // This implements exclusive mode where only one non-popular network can be active\n if (!isPopularNetwork(reference)) {\n Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {\n s.enabledNetworkMap[namespace][key as CaipChainId | Hex] = false;\n });\n }\n\n // Add the new network as enabled\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n}\n"]}
1
+ {"version":3,"file":"NetworkEnablementController.mjs","sourceRoot":"","sources":["../src/NetworkEnablementController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BuiltInNetworkName, ChainId } from '@metamask/controller-utils';\nimport type { MultichainNetworkControllerGetStateAction } from '@metamask/multichain-network-controller';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkRemovedEvent,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { TransactionControllerTransactionSubmittedEvent } from '@metamask/transaction-controller';\nimport type { CaipChainId, CaipNamespace, Hex } from '@metamask/utils';\nimport { KnownCaipNamespace } from '@metamask/utils';\n\nimport { POPULAR_NETWORKS } from './constants';\nimport { BtcScope, SolScope } from './types';\nimport {\n deriveKeys,\n isOnlyNetworkEnabledInNamespace,\n isPopularNetwork,\n} from './utils';\n\nconst controllerName = 'NetworkEnablementController';\n\n/**\n * Information about an ordered network.\n */\nexport type NetworksInfo = {\n /**\n * The network's chain id\n */\n networkId: CaipChainId;\n};\n\n/**\n * A map of enabled networks by CAIP namespace and chain ID.\n * For EIP-155 networks, the keys are Hex chain IDs.\n * For other networks, the keys are CAIP chain IDs.\n */\ntype EnabledMap = Record<CaipNamespace, Record<CaipChainId | Hex, boolean>>;\n\n// State shape for NetworkEnablementController\nexport type NetworkEnablementControllerState = {\n enabledNetworkMap: EnabledMap;\n};\n\nexport type NetworkEnablementControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerSetEnabledNetworksAction = {\n type: `${typeof controllerName}:enableNetwork`;\n handler: NetworkEnablementController['enableNetwork'];\n};\n\nexport type NetworkEnablementControllerDisableNetworkAction = {\n type: `${typeof controllerName}:disableNetwork`;\n handler: NetworkEnablementController['disableNetwork'];\n};\n\n/**\n * All actions that {@link NetworkEnablementController} calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetStateAction\n | MultichainNetworkControllerGetStateAction;\n\nexport type NetworkEnablementControllerActions =\n | NetworkEnablementControllerGetStateAction\n | NetworkEnablementControllerSetEnabledNetworksAction\n | NetworkEnablementControllerDisableNetworkAction;\n\nexport type NetworkEnablementControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n NetworkEnablementControllerState\n >;\n\nexport type NetworkEnablementControllerEvents =\n NetworkEnablementControllerStateChangeEvent;\n\n/**\n * All events that {@link NetworkEnablementController} subscribes to internally.\n */\nexport type AllowedEvents =\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkRemovedEvent\n | NetworkControllerStateChangeEvent\n | TransactionControllerTransactionSubmittedEvent;\n\nexport type NetworkEnablementControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n NetworkEnablementControllerActions | AllowedActions,\n NetworkEnablementControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Gets the default state for the NetworkEnablementController.\n *\n * @returns The default state with pre-enabled networks.\n */\nconst getDefaultNetworkEnablementControllerState =\n (): NetworkEnablementControllerState => ({\n enabledNetworkMap: {\n [KnownCaipNamespace.Eip155]: {\n [ChainId[BuiltInNetworkName.Mainnet]]: true,\n [ChainId[BuiltInNetworkName.LineaMainnet]]: true,\n [ChainId[BuiltInNetworkName.BaseMainnet]]: true,\n },\n [KnownCaipNamespace.Solana]: {\n [SolScope.Mainnet]: true,\n [SolScope.Testnet]: false,\n [SolScope.Devnet]: false,\n },\n [KnownCaipNamespace.Bip122]: {\n [BtcScope.Mainnet]: true,\n [BtcScope.Testnet]: false,\n [BtcScope.Signet]: false,\n },\n },\n });\n\n// Metadata for the controller state\nconst metadata = {\n enabledNetworkMap: {\n includeInStateLogs: true,\n persist: true,\n anonymous: true,\n usedInUi: true,\n },\n};\n\n/**\n * Controller responsible for managing network enablement state across different blockchain networks.\n *\n * This controller tracks which networks are enabled/disabled for the user and provides methods\n * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.\n *\n * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')\n * and provides methods to query and modify network enablement states.\n */\nexport class NetworkEnablementController extends BaseController<\n typeof controllerName,\n NetworkEnablementControllerState,\n NetworkEnablementControllerMessenger\n> {\n /**\n * Creates a NetworkEnablementController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: NetworkEnablementControllerMessenger;\n state?: Partial<NetworkEnablementControllerState>;\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: {\n ...getDefaultNetworkEnablementControllerState(),\n ...state,\n },\n });\n\n messenger.subscribe('NetworkController:networkAdded', ({ chainId }) => {\n this.#onAddNetwork(chainId);\n });\n\n messenger.subscribe('NetworkController:networkRemoved', ({ chainId }) => {\n this.#removeNetworkEntry(chainId);\n });\n }\n\n /**\n * Enables or disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally. This dual parameter support allows for backward\n * compatibility with existing EVM chain ID formats while supporting newer\n * multi-chain standards.\n *\n * When enabling a non-popular network, this method will disable all other networks\n * to ensure only one network is active at a time (exclusive mode).\n *\n * @param chainId - The chain ID of the network to enable or disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n enableNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey } = deriveKeys(chainId);\n\n this.update((s) => {\n // disable all networks in all namespaces first\n Object.keys(s.enabledNetworkMap).forEach((ns) => {\n Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {\n s.enabledNetworkMap[ns][key as CaipChainId | Hex] = false;\n });\n });\n\n // if the namespace bucket does not exist, return\n // new nemespace are added only when a new network is added\n if (!s.enabledNetworkMap[namespace]) {\n return;\n }\n\n // enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n\n /**\n * Enables all popular networks and Solana mainnet.\n *\n * This method first disables all networks across all namespaces, then enables\n * all networks defined in POPULAR_NETWORKS (EVM networks), Solana mainnet, and\n * Bitcoin mainnet. This provides exclusive behavior - only popular networks will\n * be enabled after calling this method.\n *\n * Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.\n */\n enableAllPopularNetworks(): void {\n this.update((s) => {\n // First disable all networks across all namespaces\n Object.keys(s.enabledNetworkMap).forEach((ns) => {\n Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {\n s.enabledNetworkMap[ns][key as CaipChainId | Hex] = false;\n });\n });\n\n // Get current network configurations to check if networks exist\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Enable all popular EVM networks that exist in NetworkController configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n // Enable the network\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in MultichainNetworkController configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, solanaKeys.namespace);\n // Enable Solana mainnet\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in MultichainNetworkController configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n // Ensure namespace bucket exists\n this.#ensureNamespaceBucket(s, bitcoinKeys.namespace);\n // Enable Bitcoin mainnet\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n });\n }\n\n /**\n * Initializes the network enablement state from network controller configurations.\n *\n * This method reads the current network configurations from both NetworkController\n * and MultichainNetworkController and initializes the enabled network map accordingly.\n * It ensures proper namespace buckets exist for all configured networks and enables\n * popular networks by default.\n *\n * This method should be called after the NetworkController and MultichainNetworkController\n * have been initialized and their configurations are available.\n */\n init(): void {\n this.update((s) => {\n // Get network configurations from NetworkController (EVM networks)\n const networkControllerState = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n // Get network configurations from MultichainNetworkController (all networks)\n const multichainState = this.messagingSystem.call(\n 'MultichainNetworkController:getState',\n );\n\n // Initialize namespace buckets for EVM networks from NetworkController\n Object.keys(\n networkControllerState.networkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as Hex);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Initialize namespace buckets for all networks from MultichainNetworkController\n Object.keys(\n multichainState.multichainNetworkConfigurationsByChainId,\n ).forEach((chainId) => {\n const { namespace } = deriveKeys(chainId as CaipChainId);\n this.#ensureNamespaceBucket(s, namespace);\n });\n\n // Enable popular networks that exist in the configurations\n POPULAR_NETWORKS.forEach((chainId) => {\n const { namespace, storageKey } = deriveKeys(chainId as Hex);\n\n // Check if network exists in NetworkController configurations\n if (\n s.enabledNetworkMap[namespace] &&\n networkControllerState.networkConfigurationsByChainId[chainId as Hex]\n ) {\n s.enabledNetworkMap[namespace][storageKey] = true;\n }\n });\n\n // Enable Solana mainnet if it exists in configurations\n const solanaKeys = deriveKeys(SolScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[solanaKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n SolScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] = true;\n }\n\n // Enable Bitcoin mainnet if it exists in configurations\n const bitcoinKeys = deriveKeys(BtcScope.Mainnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Mainnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =\n true;\n }\n\n // Enable Bitcoin testnet if it exists in configurations\n const bitcoinTestnetKeys = deriveKeys(BtcScope.Testnet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Testnet\n ]\n ) {\n s.enabledNetworkMap[bitcoinTestnetKeys.namespace][\n bitcoinTestnetKeys.storageKey\n ] = false;\n }\n\n // Enable Bitcoin signet testnet if it exists in configurations\n const bitcoinSignetKeys = deriveKeys(BtcScope.Signet as CaipChainId);\n if (\n s.enabledNetworkMap[bitcoinSignetKeys.namespace] &&\n multichainState.multichainNetworkConfigurationsByChainId[\n BtcScope.Signet\n ]\n ) {\n s.enabledNetworkMap[bitcoinSignetKeys.namespace][\n bitcoinSignetKeys.storageKey\n ] = false;\n }\n });\n }\n\n /**\n * Disables a network for the user.\n *\n * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID\n * (for any blockchain network). The method will automatically convert Hex chain IDs\n * to CAIP-2 format internally.\n *\n * Note: This method will prevent disabling the last remaining enabled network\n * to ensure at least one network is always available.\n *\n * @param chainId - The chain ID of the network to disable. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n */\n disableNetwork(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n s.enabledNetworkMap[namespace][storageKey] = false;\n });\n }\n\n /**\n * Checks if a network is enabled.\n *\n * @param chainId - The chain ID of the network to check. Can be either:\n * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks\n * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)\n * @returns True if the network is enabled, false otherwise\n */\n isNetworkEnabled(chainId: Hex | CaipChainId): boolean {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n return this.state.enabledNetworkMap[namespace]?.[storageKey] ?? false;\n }\n\n /**\n * Ensures that a namespace bucket exists in the state.\n *\n * This method creates the namespace entry in the enabledNetworkMap if it doesn't\n * already exist. This is used to prepare the state structure before adding\n * network entries.\n *\n * @param state - The current controller state\n * @param ns - The CAIP namespace to ensure exists\n */\n #ensureNamespaceBucket(\n state: NetworkEnablementControllerState,\n ns: CaipNamespace,\n ) {\n if (!state.enabledNetworkMap[ns]) {\n state.enabledNetworkMap[ns] = {};\n }\n }\n\n /**\n * Removes a network entry from the state.\n *\n * This method is called when a network is removed from the system. It cleans up\n * the network entry and ensures that at least one network remains enabled.\n *\n * @param chainId - The chain ID to remove (Hex or CAIP-2 format)\n */\n #removeNetworkEntry(chainId: Hex | CaipChainId): void {\n const derivedKeys = deriveKeys(chainId);\n const { namespace, storageKey } = derivedKeys;\n\n this.update((s) => {\n // fallback and enable ethereum mainnet\n if (isOnlyNetworkEnabledInNamespace(this.state, derivedKeys)) {\n s.enabledNetworkMap[namespace][ChainId[BuiltInNetworkName.Mainnet]] =\n true;\n }\n\n if (namespace in s.enabledNetworkMap) {\n delete s.enabledNetworkMap[namespace][storageKey];\n }\n });\n }\n\n /**\n * Handles the addition of a new network to the controller.\n *\n * This method is called when a network is added to the system. It automatically\n * enables the new network and implements exclusive mode for non-popular networks.\n * If the network already exists, no changes are made.\n *\n * @param chainId - The chain ID of the network being added (Hex or CAIP-2 format)\n */\n #onAddNetwork(chainId: Hex | CaipChainId): void {\n const { namespace, storageKey, reference } = deriveKeys(chainId);\n\n this.update((s) => {\n // Ensure the namespace bucket exists\n this.#ensureNamespaceBucket(s, namespace);\n\n // If adding a non-popular network, disable all other networks in all namespaces\n // This implements exclusive mode where only one non-popular network can be active\n if (!isPopularNetwork(reference)) {\n Object.keys(s.enabledNetworkMap).forEach((ns) => {\n Object.keys(s.enabledNetworkMap[ns]).forEach((key) => {\n s.enabledNetworkMap[ns][key as CaipChainId | Hex] = false;\n });\n });\n }\n\n // Add the new network as enabled\n s.enabledNetworkMap[namespace][storageKey] = true;\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/network-enablement-controller",
3
- "version": "0.6.0-preview-0684712d",
3
+ "version": "1.0.0-preview-1f079244",
4
4
  "description": "Provides an interface to the currently enabled network using a MetaMask-compatible provider object",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -63,7 +63,7 @@
63
63
  "dependencies": {
64
64
  "@metamask/base-controller": "^8.3.0",
65
65
  "@metamask/controller-utils": "^11.12.0",
66
- "@metamask/utils": "^11.4.2",
66
+ "@metamask/utils": "^11.8.0",
67
67
  "reselect": "^5.1.1"
68
68
  },
69
69
  "peerDependencies": {