@metamask-previews/network-enablement-controller 0.1.0-preview-037d305

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 (52) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +20 -0
  3. package/README.md +182 -0
  4. package/dist/NetworkEnablementController.cjs +178 -0
  5. package/dist/NetworkEnablementController.cjs.map +1 -0
  6. package/dist/NetworkEnablementController.d.cts +102 -0
  7. package/dist/NetworkEnablementController.d.cts.map +1 -0
  8. package/dist/NetworkEnablementController.d.mts +102 -0
  9. package/dist/NetworkEnablementController.d.mts.map +1 -0
  10. package/dist/NetworkEnablementController.mjs +174 -0
  11. package/dist/NetworkEnablementController.mjs.map +1 -0
  12. package/dist/constants.cjs +16 -0
  13. package/dist/constants.cjs.map +1 -0
  14. package/dist/constants.d.cts +2 -0
  15. package/dist/constants.d.cts.map +1 -0
  16. package/dist/constants.d.mts +2 -0
  17. package/dist/constants.d.mts.map +1 -0
  18. package/dist/constants.mjs +13 -0
  19. package/dist/constants.mjs.map +1 -0
  20. package/dist/index.cjs +14 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +4 -0
  23. package/dist/index.d.cts.map +1 -0
  24. package/dist/index.d.mts +4 -0
  25. package/dist/index.d.mts.map +1 -0
  26. package/dist/index.mjs +3 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/selectors.cjs +87 -0
  29. package/dist/selectors.cjs.map +1 -0
  30. package/dist/selectors.d.cts +280 -0
  31. package/dist/selectors.d.cts.map +1 -0
  32. package/dist/selectors.d.mts +280 -0
  33. package/dist/selectors.d.mts.map +1 -0
  34. package/dist/selectors.mjs +81 -0
  35. package/dist/selectors.mjs.map +1 -0
  36. package/dist/types.cjs +13 -0
  37. package/dist/types.cjs.map +1 -0
  38. package/dist/types.d.cts +9 -0
  39. package/dist/types.d.cts.map +1 -0
  40. package/dist/types.d.mts +9 -0
  41. package/dist/types.d.mts.map +1 -0
  42. package/dist/types.mjs +10 -0
  43. package/dist/types.mjs.map +1 -0
  44. package/dist/utils.cjs +80 -0
  45. package/dist/utils.cjs.map +1 -0
  46. package/dist/utils.d.cts +43 -0
  47. package/dist/utils.d.cts.map +1 -0
  48. package/dist/utils.d.mts +43 -0
  49. package/dist/utils.d.mts.map +1 -0
  50. package/dist/utils.mjs +74 -0
  51. package/dist/utils.mjs.map +1 -0
  52. package/package.json +79 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0]
11
+
12
+ ### Added
13
+
14
+ - Initial release ([#6028](https://github.com/MetaMask/core/pull/6028))
15
+
16
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-enablement-controller@0.1.0...HEAD
17
+ [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/network-enablement-controller@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 MetaMask
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # Network Enablement Controller
2
+
3
+ A MetaMask controller for managing network enablement state across different blockchain networks.
4
+
5
+ ## Overview
6
+
7
+ The NetworkEnablementController tracks which networks are enabled/disabled for the user and provides methods to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @metamask/network-enablement-controller
13
+ ```
14
+
15
+ ```bash
16
+ yarn add @metamask/network-enablement-controller
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Basic Controller Usage
22
+
23
+ ```typescript
24
+ import { NetworkEnablementController } from '@metamask/network-enablement-controller';
25
+
26
+ // Create controller instance
27
+ const controller = new NetworkEnablementController({
28
+ messenger,
29
+ state: {
30
+ enabledNetworkMap: {
31
+ eip155: {
32
+ '0x1': true, // Ethereum mainnet enabled
33
+ '0xa': false, // Optimism disabled
34
+ },
35
+ solana: {
36
+ 'solana:mainnet': true,
37
+ },
38
+ },
39
+ },
40
+ });
41
+
42
+ // Enable a network
43
+ controller.setEnabledNetwork('0x1'); // Hex format for EVM
44
+ controller.setEnabledNetwork('eip155:1'); // CAIP-2 format for EVM
45
+ controller.setEnabledNetwork('solana:mainnet'); // CAIP-2 format for Solana
46
+
47
+ // Disable a network
48
+ controller.setDisabledNetwork('0xa');
49
+
50
+ // Check if network is enabled
51
+ const isEnabled = controller.isNetworkEnabled('0x1');
52
+
53
+ // Get all enabled networks for a namespace
54
+ const evmNetworks = controller.getEnabledNetworksForNamespace('eip155');
55
+
56
+ // Get all enabled networks across all namespaces
57
+ const allNetworks = controller.getAllEnabledNetworks();
58
+ ```
59
+
60
+ ### Using Selectors (Redux-style)
61
+
62
+ The controller also provides selectors that can be used in Redux contexts or any state management system:
63
+
64
+ ```typescript
65
+ import {
66
+ selectIsNetworkEnabled,
67
+ selectAllEnabledNetworks,
68
+ selectEnabledNetworksForNamespace,
69
+ selectEnabledEvmNetworks,
70
+ selectEnabledSolanaNetworks,
71
+ } from '@metamask/network-enablement-controller';
72
+
73
+ // Get controller state
74
+ const state = controller.state;
75
+
76
+ // Check if a specific network is enabled
77
+ const isEthereumEnabled = selectIsNetworkEnabled('0x1')(state);
78
+ const isSolanaEnabled = selectIsNetworkEnabled('solana:mainnet')(state);
79
+
80
+ // Get all enabled networks across all namespaces
81
+ const allEnabledNetworks = selectAllEnabledNetworks(state);
82
+ // Returns: { eip155: ['0x1'], solana: ['solana:mainnet'] }
83
+
84
+ // Get enabled networks for a specific namespace
85
+ const evmNetworks = selectEnabledNetworksForNamespace('eip155')(state);
86
+ const solanaNetworks = selectEnabledNetworksForNamespace('solana')(state);
87
+
88
+ // Convenience selectors for specific network types
89
+ const enabledEvmNetworks = selectEnabledEvmNetworks(state);
90
+ const enabledSolanaNetworks = selectEnabledSolanaNetworks(state);
91
+
92
+ // Get total count of enabled networks
93
+ const totalEnabled = selectEnabledNetworksCount(state);
94
+
95
+ // Check if any networks are enabled for a namespace
96
+ const hasEvmNetworks = selectHasEnabledNetworksForNamespace('eip155')(state);
97
+ ```
98
+
99
+ ## API Reference
100
+
101
+ ### Controller Methods
102
+
103
+ #### `setEnabledNetwork(chainId: Hex | CaipChainId): void`
104
+
105
+ Enables a network for the user. Accepts either Hex chain IDs (for EVM networks) or CAIP-2 chain IDs (for any blockchain network).
106
+
107
+ #### `setDisabledNetwork(chainId: Hex | CaipChainId): void`
108
+
109
+ Disables a network for the user. Prevents disabling the last remaining enabled network.
110
+
111
+ #### `isNetworkEnabled(chainId: Hex | CaipChainId): boolean`
112
+
113
+ Checks if a network is currently enabled. Returns false for unknown networks.
114
+
115
+ #### `getEnabledNetworksForNamespace(namespace: CaipNamespace): string[]`
116
+
117
+ Gets all enabled networks for a specific namespace.
118
+
119
+ #### `getAllEnabledNetworks(): Record<CaipNamespace, string[]>`
120
+
121
+ Gets all enabled networks across all namespaces.
122
+
123
+ ### Selectors
124
+
125
+ #### `selectIsNetworkEnabled(chainId: Hex | CaipChainId)`
126
+
127
+ Returns a selector function that checks if a specific network is enabled.
128
+
129
+ #### `selectAllEnabledNetworks`
130
+
131
+ Returns a selector function that gets all enabled networks across all namespaces.
132
+
133
+ #### `selectEnabledNetworksForNamespace(namespace: CaipNamespace)`
134
+
135
+ Returns a selector function that gets enabled networks for a specific namespace.
136
+
137
+ #### `selectEnabledNetworksCount`
138
+
139
+ Returns a selector function that gets the total count of enabled networks.
140
+
141
+ #### `selectHasEnabledNetworksForNamespace(namespace: CaipNamespace)`
142
+
143
+ Returns a selector function that checks if any networks are enabled for a namespace.
144
+
145
+ #### `selectEnabledEvmNetworks`
146
+
147
+ Returns a selector function that gets all enabled EVM networks.
148
+
149
+ #### `selectEnabledSolanaNetworks`
150
+
151
+ Returns a selector function that gets all enabled Solana networks.
152
+
153
+ ## Chain ID Formats
154
+
155
+ The controller supports two chain ID formats:
156
+
157
+ 1. **Hex format**: Traditional EVM chain IDs (e.g., `'0x1'` for Ethereum mainnet)
158
+ 2. **CAIP-2 format**: Chain Agnostic Improvement Proposal format (e.g., `'eip155:1'` for Ethereum mainnet, `'solana:mainnet'` for Solana)
159
+
160
+ ## Network Types
161
+
162
+ ### EVM Networks (eip155 namespace)
163
+
164
+ - Ethereum Mainnet: `'0x1'` or `'eip155:1'`
165
+ - Optimism: `'0xa'` or `'eip155:10'`
166
+ - Arbitrum One: `'0xa4b1'` or `'eip155:42161'`
167
+
168
+ ### Solana Networks (solana namespace)
169
+
170
+ - Solana Mainnet: `'solana:mainnet'`
171
+ - Solana Testnet: `'solana:testnet'`
172
+
173
+ ## State Persistence
174
+
175
+ The controller state is automatically persisted and restored between sessions. The `enabledNetworkMap` is stored anonymously to protect user privacy.
176
+
177
+ ## Safety Features
178
+
179
+ - **At least one network enabled**: The controller ensures at least one network is always enabled
180
+ - **Unknown network protection**: Prevents enabling networks not configured in the system
181
+ - **Exclusive mode**: When enabling non-popular networks, all other networks are disabled
182
+ - **Last network protection**: Prevents disabling the last remaining enabled network
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ 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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _NetworkEnablementController_instances, _NetworkEnablementController_ensureNamespaceBucket, _NetworkEnablementController_removeNetworkEntry, _NetworkEnablementController_onAddNetwork;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.NetworkEnablementController = void 0;
10
+ const base_controller_1 = require("@metamask/base-controller");
11
+ const controller_utils_1 = require("@metamask/controller-utils");
12
+ const utils_1 = require("@metamask/utils");
13
+ const types_1 = require("./types.cjs");
14
+ const utils_2 = require("./utils.cjs");
15
+ const controllerName = 'NetworkEnablementController';
16
+ /**
17
+ * Gets the default state for the NetworkEnablementController.
18
+ *
19
+ * @returns The default state with pre-enabled networks.
20
+ */
21
+ const getDefaultNetworkEnablementControllerState = () => ({
22
+ enabledNetworkMap: {
23
+ [utils_1.KnownCaipNamespace.Eip155]: {
24
+ [controller_utils_1.ChainId[controller_utils_1.BuiltInNetworkName.Mainnet]]: true,
25
+ [controller_utils_1.ChainId[controller_utils_1.BuiltInNetworkName.LineaMainnet]]: true,
26
+ [controller_utils_1.ChainId[controller_utils_1.BuiltInNetworkName.BaseMainnet]]: true,
27
+ },
28
+ [utils_1.KnownCaipNamespace.Solana]: {
29
+ [types_1.SolScope.Mainnet]: true,
30
+ },
31
+ },
32
+ });
33
+ // Metadata for the controller state
34
+ const metadata = {
35
+ enabledNetworkMap: {
36
+ persist: true,
37
+ anonymous: true,
38
+ },
39
+ };
40
+ /**
41
+ * Controller responsible for managing network enablement state across different blockchain networks.
42
+ *
43
+ * This controller tracks which networks are enabled/disabled for the user and provides methods
44
+ * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.
45
+ *
46
+ * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')
47
+ * and provides methods to query and modify network enablement states.
48
+ */
49
+ class NetworkEnablementController extends base_controller_1.BaseController {
50
+ /**
51
+ * Creates a NetworkEnablementController instance.
52
+ *
53
+ * @param args - The arguments to this function.
54
+ * @param args.messenger - Messenger used to communicate with BaseV2 controller.
55
+ * @param args.state - Initial state to set on this controller.
56
+ */
57
+ constructor({ messenger, state, }) {
58
+ super({
59
+ messenger,
60
+ metadata,
61
+ name: controllerName,
62
+ state: {
63
+ ...getDefaultNetworkEnablementControllerState(),
64
+ ...state,
65
+ },
66
+ });
67
+ _NetworkEnablementController_instances.add(this);
68
+ messenger.subscribe('NetworkController:networkAdded', ({ chainId }) => {
69
+ __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_onAddNetwork).call(this, chainId);
70
+ });
71
+ messenger.subscribe('NetworkController:networkRemoved', ({ chainId }) => {
72
+ __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_removeNetworkEntry).call(this, chainId);
73
+ });
74
+ }
75
+ /**
76
+ * Enables or disables a network for the user.
77
+ *
78
+ * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID
79
+ * (for any blockchain network). The method will automatically convert Hex chain IDs
80
+ * to CAIP-2 format internally. This dual parameter support allows for backward
81
+ * compatibility with existing EVM chain ID formats while supporting newer
82
+ * multi-chain standards.
83
+ *
84
+ * When enabling a non-popular network, this method will disable all other networks
85
+ * to ensure only one network is active at a time (exclusive mode).
86
+ *
87
+ * @param chainId - The chain ID of the network to enable or disable. Can be either:
88
+ * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks
89
+ * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)
90
+ */
91
+ enableNetwork(chainId) {
92
+ const { namespace, storageKey, reference } = (0, utils_2.deriveKeys)(chainId);
93
+ const isPopular = (0, utils_2.isPopularNetwork)(reference);
94
+ this.update((s) => {
95
+ // if the namespace bucket does not exist, return
96
+ // new nemespace are added only when a new network is added
97
+ if (!s.enabledNetworkMap[namespace]) {
98
+ return;
99
+ }
100
+ // If enabling a non-popular network, disable all networks in the same namespace
101
+ if (!isPopular) {
102
+ // disable all networks in the same namespace
103
+ Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
104
+ s.enabledNetworkMap[namespace][key] = false;
105
+ });
106
+ }
107
+ else {
108
+ // disable all custom networks
109
+ Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
110
+ const { reference: keyReference } = (0, utils_2.deriveKeys)(key);
111
+ if (!(0, utils_2.isPopularNetwork)(keyReference)) {
112
+ s.enabledNetworkMap[namespace][key] = false;
113
+ }
114
+ });
115
+ }
116
+ s.enabledNetworkMap[namespace][storageKey] = true;
117
+ });
118
+ }
119
+ /**
120
+ * Disables a network for the user.
121
+ *
122
+ * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID
123
+ * (for any blockchain network). The method will automatically convert Hex chain IDs
124
+ * to CAIP-2 format internally.
125
+ *
126
+ * Note: This method will prevent disabling the last remaining enabled network
127
+ * to ensure at least one network is always available.
128
+ *
129
+ * @param chainId - The chain ID of the network to disable. Can be either:
130
+ * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks
131
+ * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)
132
+ */
133
+ disableNetwork(chainId) {
134
+ const derivedKeys = (0, utils_2.deriveKeys)(chainId);
135
+ const { namespace, storageKey } = derivedKeys;
136
+ if ((0, utils_2.isOnlyNetworkEnabledInNamespace)(this.state, derivedKeys)) {
137
+ throw new Error('Cannot disable the last remaining enabled network');
138
+ }
139
+ this.update((s) => {
140
+ s.enabledNetworkMap[namespace][storageKey] = false;
141
+ });
142
+ }
143
+ }
144
+ exports.NetworkEnablementController = NetworkEnablementController;
145
+ _NetworkEnablementController_instances = new WeakSet(), _NetworkEnablementController_ensureNamespaceBucket = function _NetworkEnablementController_ensureNamespaceBucket(state, ns) {
146
+ if (!state.enabledNetworkMap[ns]) {
147
+ state.enabledNetworkMap[ns] = {};
148
+ }
149
+ }, _NetworkEnablementController_removeNetworkEntry = function _NetworkEnablementController_removeNetworkEntry(chainId) {
150
+ const derivedKeys = (0, utils_2.deriveKeys)(chainId);
151
+ const { namespace, storageKey } = derivedKeys;
152
+ this.update((s) => {
153
+ // fallback and enable ethereum mainnet
154
+ if ((0, utils_2.isOnlyNetworkEnabledInNamespace)(this.state, derivedKeys)) {
155
+ s.enabledNetworkMap[namespace][controller_utils_1.ChainId[controller_utils_1.BuiltInNetworkName.Mainnet]] =
156
+ true;
157
+ }
158
+ if (namespace in s.enabledNetworkMap) {
159
+ delete s.enabledNetworkMap[namespace][storageKey];
160
+ }
161
+ });
162
+ }, _NetworkEnablementController_onAddNetwork = function _NetworkEnablementController_onAddNetwork(chainId) {
163
+ const { namespace, storageKey, reference } = (0, utils_2.deriveKeys)(chainId);
164
+ this.update((s) => {
165
+ // Ensure the namespace bucket exists
166
+ __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, s, namespace);
167
+ // If adding a non-popular network, disable all other networks in the same namespace
168
+ // This implements exclusive mode where only one non-popular network can be active
169
+ if (!(0, utils_2.isPopularNetwork)(reference)) {
170
+ Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {
171
+ s.enabledNetworkMap[namespace][key] = false;
172
+ });
173
+ }
174
+ // Add the new network as enabled
175
+ s.enabledNetworkMap[namespace][storageKey] = true;
176
+ });
177
+ };
178
+ //# sourceMappingURL=NetworkEnablementController.cjs.map
@@ -0,0 +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 { CaipChainId, CaipNamespace, Hex } from '@metamask/utils';\nimport { KnownCaipNamespace } from '@metamask/utils';\n\nimport { 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\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 },\n },\n });\n\n// Metadata for the controller state\nconst metadata = {\n enabledNetworkMap: {\n persist: true,\n anonymous: 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, reference } = deriveKeys(chainId);\n\n const isPopular = isPopularNetwork(reference);\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 // If enabling a non-popular network, disable all networks in the same namespace\n if (!isPopular) {\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 } else {\n // disable all custom networks\n Object.keys(s.enabledNetworkMap[namespace]).forEach((key) => {\n const { reference: keyReference } = deriveKeys(key as CaipChainId);\n if (!isPopularNetwork(keyReference)) {\n s.enabledNetworkMap[namespace][key as CaipChainId | Hex] = false;\n }\n });\n }\n s.enabledNetworkMap[namespace][storageKey] = true;\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 if (isOnlyNetworkEnabledInNamespace(this.state, derivedKeys)) {\n throw new Error('Cannot disable the last remaining enabled network');\n }\n\n this.update((s) => {\n s.enabledNetworkMap[namespace][storageKey] = false;\n });\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"]}
@@ -0,0 +1,102 @@
1
+ import { BaseController } from "@metamask/base-controller";
2
+ import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
+ import type { MultichainNetworkControllerGetStateAction } from "@metamask/multichain-network-controller";
4
+ import type { NetworkControllerGetStateAction, NetworkControllerNetworkAddedEvent, NetworkControllerNetworkRemovedEvent, NetworkControllerStateChangeEvent } from "@metamask/network-controller";
5
+ import type { CaipChainId, CaipNamespace, Hex } from "@metamask/utils";
6
+ declare const controllerName = "NetworkEnablementController";
7
+ /**
8
+ * Information about an ordered network.
9
+ */
10
+ export type NetworksInfo = {
11
+ /**
12
+ * The network's chain id
13
+ */
14
+ networkId: CaipChainId;
15
+ };
16
+ /**
17
+ * A map of enabled networks by CAIP namespace and chain ID.
18
+ * For EIP-155 networks, the keys are Hex chain IDs.
19
+ * For other networks, the keys are CAIP chain IDs.
20
+ */
21
+ type EnabledMap = Record<CaipNamespace, Record<CaipChainId | Hex, boolean>>;
22
+ export type NetworkEnablementControllerState = {
23
+ enabledNetworkMap: EnabledMap;
24
+ };
25
+ export type NetworkEnablementControllerGetStateAction = ControllerGetStateAction<typeof controllerName, NetworkEnablementControllerState>;
26
+ export type NetworkEnablementControllerSetEnabledNetworksAction = {
27
+ type: `${typeof controllerName}:enableNetwork`;
28
+ handler: NetworkEnablementController['enableNetwork'];
29
+ };
30
+ export type NetworkEnablementControllerDisableNetworkAction = {
31
+ type: `${typeof controllerName}:disableNetwork`;
32
+ handler: NetworkEnablementController['disableNetwork'];
33
+ };
34
+ /**
35
+ * All actions that {@link NetworkEnablementController} calls internally.
36
+ */
37
+ export type AllowedActions = NetworkControllerGetStateAction | MultichainNetworkControllerGetStateAction;
38
+ export type NetworkEnablementControllerActions = NetworkEnablementControllerGetStateAction | NetworkEnablementControllerSetEnabledNetworksAction | NetworkEnablementControllerDisableNetworkAction;
39
+ export type NetworkEnablementControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, NetworkEnablementControllerState>;
40
+ export type NetworkEnablementControllerEvents = NetworkEnablementControllerStateChangeEvent;
41
+ /**
42
+ * All events that {@link NetworkEnablementController} subscribes to internally.
43
+ */
44
+ export type AllowedEvents = NetworkControllerNetworkAddedEvent | NetworkControllerNetworkRemovedEvent | NetworkControllerStateChangeEvent;
45
+ export type NetworkEnablementControllerMessenger = RestrictedMessenger<typeof controllerName, NetworkEnablementControllerActions | AllowedActions, NetworkEnablementControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
46
+ /**
47
+ * Controller responsible for managing network enablement state across different blockchain networks.
48
+ *
49
+ * This controller tracks which networks are enabled/disabled for the user and provides methods
50
+ * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.
51
+ *
52
+ * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')
53
+ * and provides methods to query and modify network enablement states.
54
+ */
55
+ export declare class NetworkEnablementController extends BaseController<typeof controllerName, NetworkEnablementControllerState, NetworkEnablementControllerMessenger> {
56
+ #private;
57
+ /**
58
+ * Creates a NetworkEnablementController instance.
59
+ *
60
+ * @param args - The arguments to this function.
61
+ * @param args.messenger - Messenger used to communicate with BaseV2 controller.
62
+ * @param args.state - Initial state to set on this controller.
63
+ */
64
+ constructor({ messenger, state, }: {
65
+ messenger: NetworkEnablementControllerMessenger;
66
+ state?: Partial<NetworkEnablementControllerState>;
67
+ });
68
+ /**
69
+ * Enables or disables a network for the user.
70
+ *
71
+ * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID
72
+ * (for any blockchain network). The method will automatically convert Hex chain IDs
73
+ * to CAIP-2 format internally. This dual parameter support allows for backward
74
+ * compatibility with existing EVM chain ID formats while supporting newer
75
+ * multi-chain standards.
76
+ *
77
+ * When enabling a non-popular network, this method will disable all other networks
78
+ * to ensure only one network is active at a time (exclusive mode).
79
+ *
80
+ * @param chainId - The chain ID of the network to enable or disable. Can be either:
81
+ * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks
82
+ * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)
83
+ */
84
+ enableNetwork(chainId: Hex | CaipChainId): void;
85
+ /**
86
+ * Disables a network for the user.
87
+ *
88
+ * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID
89
+ * (for any blockchain network). The method will automatically convert Hex chain IDs
90
+ * to CAIP-2 format internally.
91
+ *
92
+ * Note: This method will prevent disabling the last remaining enabled network
93
+ * to ensure at least one network is always available.
94
+ *
95
+ * @param chainId - The chain ID of the network to disable. Can be either:
96
+ * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks
97
+ * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)
98
+ */
99
+ disableNetwork(chainId: Hex | CaipChainId): void;
100
+ }
101
+ export {};
102
+ //# sourceMappingURL=NetworkEnablementController.d.cts.map
@@ -0,0 +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,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAUvE,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,CAAC;AAEtC,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;AA6BF;;;;;;;;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;IA+B/C;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;CAqFjD"}
@@ -0,0 +1,102 @@
1
+ import { BaseController } from "@metamask/base-controller";
2
+ import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
+ import type { MultichainNetworkControllerGetStateAction } from "@metamask/multichain-network-controller";
4
+ import type { NetworkControllerGetStateAction, NetworkControllerNetworkAddedEvent, NetworkControllerNetworkRemovedEvent, NetworkControllerStateChangeEvent } from "@metamask/network-controller";
5
+ import type { CaipChainId, CaipNamespace, Hex } from "@metamask/utils";
6
+ declare const controllerName = "NetworkEnablementController";
7
+ /**
8
+ * Information about an ordered network.
9
+ */
10
+ export type NetworksInfo = {
11
+ /**
12
+ * The network's chain id
13
+ */
14
+ networkId: CaipChainId;
15
+ };
16
+ /**
17
+ * A map of enabled networks by CAIP namespace and chain ID.
18
+ * For EIP-155 networks, the keys are Hex chain IDs.
19
+ * For other networks, the keys are CAIP chain IDs.
20
+ */
21
+ type EnabledMap = Record<CaipNamespace, Record<CaipChainId | Hex, boolean>>;
22
+ export type NetworkEnablementControllerState = {
23
+ enabledNetworkMap: EnabledMap;
24
+ };
25
+ export type NetworkEnablementControllerGetStateAction = ControllerGetStateAction<typeof controllerName, NetworkEnablementControllerState>;
26
+ export type NetworkEnablementControllerSetEnabledNetworksAction = {
27
+ type: `${typeof controllerName}:enableNetwork`;
28
+ handler: NetworkEnablementController['enableNetwork'];
29
+ };
30
+ export type NetworkEnablementControllerDisableNetworkAction = {
31
+ type: `${typeof controllerName}:disableNetwork`;
32
+ handler: NetworkEnablementController['disableNetwork'];
33
+ };
34
+ /**
35
+ * All actions that {@link NetworkEnablementController} calls internally.
36
+ */
37
+ export type AllowedActions = NetworkControllerGetStateAction | MultichainNetworkControllerGetStateAction;
38
+ export type NetworkEnablementControllerActions = NetworkEnablementControllerGetStateAction | NetworkEnablementControllerSetEnabledNetworksAction | NetworkEnablementControllerDisableNetworkAction;
39
+ export type NetworkEnablementControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, NetworkEnablementControllerState>;
40
+ export type NetworkEnablementControllerEvents = NetworkEnablementControllerStateChangeEvent;
41
+ /**
42
+ * All events that {@link NetworkEnablementController} subscribes to internally.
43
+ */
44
+ export type AllowedEvents = NetworkControllerNetworkAddedEvent | NetworkControllerNetworkRemovedEvent | NetworkControllerStateChangeEvent;
45
+ export type NetworkEnablementControllerMessenger = RestrictedMessenger<typeof controllerName, NetworkEnablementControllerActions | AllowedActions, NetworkEnablementControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
46
+ /**
47
+ * Controller responsible for managing network enablement state across different blockchain networks.
48
+ *
49
+ * This controller tracks which networks are enabled/disabled for the user and provides methods
50
+ * to toggle network states. It supports both EVM (EIP-155) and non-EVM networks like Solana.
51
+ *
52
+ * The controller maintains a map of enabled networks organized by namespace (e.g., 'eip155', 'solana')
53
+ * and provides methods to query and modify network enablement states.
54
+ */
55
+ export declare class NetworkEnablementController extends BaseController<typeof controllerName, NetworkEnablementControllerState, NetworkEnablementControllerMessenger> {
56
+ #private;
57
+ /**
58
+ * Creates a NetworkEnablementController instance.
59
+ *
60
+ * @param args - The arguments to this function.
61
+ * @param args.messenger - Messenger used to communicate with BaseV2 controller.
62
+ * @param args.state - Initial state to set on this controller.
63
+ */
64
+ constructor({ messenger, state, }: {
65
+ messenger: NetworkEnablementControllerMessenger;
66
+ state?: Partial<NetworkEnablementControllerState>;
67
+ });
68
+ /**
69
+ * Enables or disables a network for the user.
70
+ *
71
+ * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID
72
+ * (for any blockchain network). The method will automatically convert Hex chain IDs
73
+ * to CAIP-2 format internally. This dual parameter support allows for backward
74
+ * compatibility with existing EVM chain ID formats while supporting newer
75
+ * multi-chain standards.
76
+ *
77
+ * When enabling a non-popular network, this method will disable all other networks
78
+ * to ensure only one network is active at a time (exclusive mode).
79
+ *
80
+ * @param chainId - The chain ID of the network to enable or disable. Can be either:
81
+ * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks
82
+ * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)
83
+ */
84
+ enableNetwork(chainId: Hex | CaipChainId): void;
85
+ /**
86
+ * Disables a network for the user.
87
+ *
88
+ * This method accepts either a Hex chain ID (for EVM networks) or a CAIP-2 chain ID
89
+ * (for any blockchain network). The method will automatically convert Hex chain IDs
90
+ * to CAIP-2 format internally.
91
+ *
92
+ * Note: This method will prevent disabling the last remaining enabled network
93
+ * to ensure at least one network is always available.
94
+ *
95
+ * @param chainId - The chain ID of the network to disable. Can be either:
96
+ * - A Hex string (e.g., '0x1' for Ethereum mainnet) for EVM networks
97
+ * - A CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet, 'solana:mainnet' for Solana)
98
+ */
99
+ disableNetwork(chainId: Hex | CaipChainId): void;
100
+ }
101
+ export {};
102
+ //# sourceMappingURL=NetworkEnablementController.d.mts.map
@@ -0,0 +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,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAUvE,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,CAAC;AAEtC,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;AA6BF;;;;;;;;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;IA+B/C;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,GAAG,IAAI;CAqFjD"}