@metamask-previews/network-enablement-controller 4.0.0-preview-821afcb8 → 4.0.0-preview-0c691324
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 +7 -0
- package/dist/NetworkEnablementController.cjs +240 -61
- package/dist/NetworkEnablementController.cjs.map +1 -1
- package/dist/NetworkEnablementController.d.cts +52 -2
- package/dist/NetworkEnablementController.d.cts.map +1 -1
- package/dist/NetworkEnablementController.d.mts +52 -2
- package/dist/NetworkEnablementController.d.mts.map +1 -1
- package/dist/NetworkEnablementController.mjs +240 -61
- package/dist/NetworkEnablementController.mjs.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/services/Slip44Service.cjs +176 -0
- package/dist/services/Slip44Service.cjs.map +1 -0
- package/dist/services/Slip44Service.d.cts +74 -0
- package/dist/services/Slip44Service.d.cts.map +1 -0
- package/dist/services/Slip44Service.d.mts +74 -0
- package/dist/services/Slip44Service.d.mts.map +1 -0
- package/dist/services/Slip44Service.mjs +169 -0
- package/dist/services/Slip44Service.mjs.map +1 -0
- package/dist/services/index.cjs +9 -0
- package/dist/services/index.cjs.map +1 -0
- package/dist/services/index.d.cts +6 -0
- package/dist/services/index.d.cts.map +1 -0
- package/dist/services/index.d.mts +6 -0
- package/dist/services/index.d.mts.map +1 -0
- package/dist/services/index.mjs +6 -0
- package/dist/services/index.mjs.map +1 -0
- package/package.json +2 -1
|
@@ -3,14 +3,25 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _NetworkEnablementController_instances, _NetworkEnablementController_ensureNamespaceBucket, _NetworkEnablementController_isInPopularNetworksMode, _NetworkEnablementController_removeNetworkEntry, _NetworkEnablementController_onAddNetwork;
|
|
6
|
+
var _NetworkEnablementController_instances, _NetworkEnablementController_onNativeCurrencyChange, _NetworkEnablementController_ensureNamespaceBucket, _NetworkEnablementController_updateNativeAssetIdentifier, _NetworkEnablementController_isInPopularNetworksMode, _NetworkEnablementController_removeNetworkEntry, _NetworkEnablementController_onAddNetwork;
|
|
7
7
|
import { BaseController } from "@metamask/base-controller";
|
|
8
8
|
import { BuiltInNetworkName, ChainId } from "@metamask/controller-utils";
|
|
9
9
|
import { BtcScope, SolScope, TrxScope } from "@metamask/keyring-api";
|
|
10
10
|
import { KnownCaipNamespace } from "@metamask/utils";
|
|
11
11
|
import { POPULAR_NETWORKS } from "./constants.mjs";
|
|
12
|
+
import { Slip44Service } from "./services/index.mjs";
|
|
12
13
|
import { deriveKeys, isOnlyNetworkEnabledInNamespace, isPopularNetwork } from "./utils.mjs";
|
|
13
14
|
const controllerName = 'NetworkEnablementController';
|
|
15
|
+
/**
|
|
16
|
+
* Builds a native asset identifier in CAIP-19-like format.
|
|
17
|
+
*
|
|
18
|
+
* @param caipChainId - The CAIP-2 chain ID (e.g., 'eip155:1', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')
|
|
19
|
+
* @param slip44CoinType - The SLIP-44 coin type number
|
|
20
|
+
* @returns The native asset identifier string (e.g., 'eip155:1/slip44:60')
|
|
21
|
+
*/
|
|
22
|
+
function buildNativeAssetIdentifier(caipChainId, slip44CoinType) {
|
|
23
|
+
return `${caipChainId}/slip44:${slip44CoinType}`;
|
|
24
|
+
}
|
|
14
25
|
/**
|
|
15
26
|
* Gets the default state for the NetworkEnablementController.
|
|
16
27
|
*
|
|
@@ -44,6 +55,9 @@ const getDefaultNetworkEnablementControllerState = () => ({
|
|
|
44
55
|
[TrxScope.Shasta]: false,
|
|
45
56
|
},
|
|
46
57
|
},
|
|
58
|
+
// nativeAssetIdentifiers is initialized as empty and should be populated
|
|
59
|
+
// by the client using initNativeAssetIdentifiers() during controller init
|
|
60
|
+
nativeAssetIdentifiers: {},
|
|
47
61
|
});
|
|
48
62
|
// Metadata for the controller state
|
|
49
63
|
const metadata = {
|
|
@@ -53,6 +67,12 @@ const metadata = {
|
|
|
53
67
|
includeInDebugSnapshot: true,
|
|
54
68
|
usedInUi: true,
|
|
55
69
|
},
|
|
70
|
+
nativeAssetIdentifiers: {
|
|
71
|
+
includeInStateLogs: true,
|
|
72
|
+
persist: true,
|
|
73
|
+
includeInDebugSnapshot: true,
|
|
74
|
+
usedInUi: true,
|
|
75
|
+
},
|
|
56
76
|
};
|
|
57
77
|
/**
|
|
58
78
|
* Controller responsible for managing network enablement state across different blockchain networks.
|
|
@@ -82,12 +102,20 @@ export class NetworkEnablementController extends BaseController {
|
|
|
82
102
|
},
|
|
83
103
|
});
|
|
84
104
|
_NetworkEnablementController_instances.add(this);
|
|
85
|
-
messenger.subscribe('NetworkController:networkAdded', ({ chainId }) => {
|
|
86
|
-
|
|
105
|
+
messenger.subscribe('NetworkController:networkAdded', ({ chainId, nativeCurrency }) => {
|
|
106
|
+
// eslint-disable-next-line no-void
|
|
107
|
+
void __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_onAddNetwork).call(this, chainId, nativeCurrency);
|
|
87
108
|
});
|
|
88
109
|
messenger.subscribe('NetworkController:networkRemoved', ({ chainId }) => {
|
|
89
110
|
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_removeNetworkEntry).call(this, chainId);
|
|
90
111
|
});
|
|
112
|
+
// Subscribe to nativeCurrency changes using selector approach
|
|
113
|
+
messenger.subscribe('NetworkController:stateChange', (currentNativeCurrencies, previousNativeCurrencies) => {
|
|
114
|
+
// eslint-disable-next-line no-void
|
|
115
|
+
void __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_onNativeCurrencyChange).call(this, currentNativeCurrencies, previousNativeCurrencies);
|
|
116
|
+
},
|
|
117
|
+
// Selector: extract chainId -> nativeCurrency map
|
|
118
|
+
(networkState) => Object.fromEntries(Object.entries(networkState.networkConfigurationsByChainId).map(([chainId, config]) => [chainId, config.nativeCurrency])));
|
|
91
119
|
}
|
|
92
120
|
/**
|
|
93
121
|
* Enables or disables a network for the user.
|
|
@@ -107,20 +135,20 @@ export class NetworkEnablementController extends BaseController {
|
|
|
107
135
|
*/
|
|
108
136
|
enableNetwork(chainId) {
|
|
109
137
|
const { namespace, storageKey } = deriveKeys(chainId);
|
|
110
|
-
this.update((
|
|
138
|
+
this.update((state) => {
|
|
111
139
|
// disable all networks in all namespaces first
|
|
112
|
-
Object.keys(
|
|
113
|
-
Object.keys(
|
|
114
|
-
|
|
140
|
+
Object.keys(state.enabledNetworkMap).forEach((ns) => {
|
|
141
|
+
Object.keys(state.enabledNetworkMap[ns]).forEach((key) => {
|
|
142
|
+
state.enabledNetworkMap[ns][key] = false;
|
|
115
143
|
});
|
|
116
144
|
});
|
|
117
145
|
// if the namespace bucket does not exist, return
|
|
118
146
|
// new nemespace are added only when a new network is added
|
|
119
|
-
if (!
|
|
147
|
+
if (!state.enabledNetworkMap[namespace]) {
|
|
120
148
|
return;
|
|
121
149
|
}
|
|
122
150
|
// enable the network
|
|
123
|
-
|
|
151
|
+
state.enabledNetworkMap[namespace][storageKey] = true;
|
|
124
152
|
});
|
|
125
153
|
}
|
|
126
154
|
/**
|
|
@@ -145,17 +173,17 @@ export class NetworkEnablementController extends BaseController {
|
|
|
145
173
|
if (derivedNamespace !== namespace) {
|
|
146
174
|
throw new Error(`Chain ID ${chainId} belongs to namespace ${derivedNamespace}, but namespace ${namespace} was specified`);
|
|
147
175
|
}
|
|
148
|
-
this.update((
|
|
176
|
+
this.update((state) => {
|
|
149
177
|
// Ensure the namespace bucket exists
|
|
150
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
178
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, namespace);
|
|
151
179
|
// Disable all networks in the specified namespace first
|
|
152
|
-
if (
|
|
153
|
-
Object.keys(
|
|
154
|
-
|
|
180
|
+
if (state.enabledNetworkMap[namespace]) {
|
|
181
|
+
Object.keys(state.enabledNetworkMap[namespace]).forEach((key) => {
|
|
182
|
+
state.enabledNetworkMap[namespace][key] = false;
|
|
155
183
|
});
|
|
156
184
|
}
|
|
157
185
|
// Enable the target network in the specified namespace
|
|
158
|
-
|
|
186
|
+
state.enabledNetworkMap[namespace][storageKey] = true;
|
|
159
187
|
});
|
|
160
188
|
}
|
|
161
189
|
/**
|
|
@@ -169,11 +197,11 @@ export class NetworkEnablementController extends BaseController {
|
|
|
169
197
|
* Popular networks that don't exist in NetworkController or MultichainNetworkController configurations will be skipped silently.
|
|
170
198
|
*/
|
|
171
199
|
enableAllPopularNetworks() {
|
|
172
|
-
this.update((
|
|
200
|
+
this.update((state) => {
|
|
173
201
|
// First disable all networks across all namespaces
|
|
174
|
-
Object.keys(
|
|
175
|
-
Object.keys(
|
|
176
|
-
|
|
202
|
+
Object.keys(state.enabledNetworkMap).forEach((ns) => {
|
|
203
|
+
Object.keys(state.enabledNetworkMap[ns]).forEach((key) => {
|
|
204
|
+
state.enabledNetworkMap[ns][key] = false;
|
|
177
205
|
});
|
|
178
206
|
});
|
|
179
207
|
// Get current network configurations to check if networks exist
|
|
@@ -185,35 +213,36 @@ export class NetworkEnablementController extends BaseController {
|
|
|
185
213
|
// Check if network exists in NetworkController configurations
|
|
186
214
|
if (networkControllerState.networkConfigurationsByChainId[chainId]) {
|
|
187
215
|
// Ensure namespace bucket exists
|
|
188
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
216
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, namespace);
|
|
189
217
|
// Enable the network
|
|
190
|
-
|
|
218
|
+
state.enabledNetworkMap[namespace][storageKey] = true;
|
|
191
219
|
}
|
|
192
220
|
});
|
|
193
221
|
// Enable Solana mainnet if it exists in MultichainNetworkController configurations
|
|
194
222
|
const solanaKeys = deriveKeys(SolScope.Mainnet);
|
|
195
223
|
if (multichainState.multichainNetworkConfigurationsByChainId[SolScope.Mainnet]) {
|
|
196
224
|
// Ensure namespace bucket exists
|
|
197
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
225
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, solanaKeys.namespace);
|
|
198
226
|
// Enable Solana mainnet
|
|
199
|
-
|
|
227
|
+
state.enabledNetworkMap[solanaKeys.namespace][solanaKeys.storageKey] =
|
|
228
|
+
true;
|
|
200
229
|
}
|
|
201
230
|
// Enable Bitcoin mainnet if it exists in MultichainNetworkController configurations
|
|
202
231
|
const bitcoinKeys = deriveKeys(BtcScope.Mainnet);
|
|
203
232
|
if (multichainState.multichainNetworkConfigurationsByChainId[BtcScope.Mainnet]) {
|
|
204
233
|
// Ensure namespace bucket exists
|
|
205
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
234
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, bitcoinKeys.namespace);
|
|
206
235
|
// Enable Bitcoin mainnet
|
|
207
|
-
|
|
236
|
+
state.enabledNetworkMap[bitcoinKeys.namespace][bitcoinKeys.storageKey] =
|
|
208
237
|
true;
|
|
209
238
|
}
|
|
210
239
|
// Enable Tron mainnet if it exists in MultichainNetworkController configurations
|
|
211
240
|
const tronKeys = deriveKeys(TrxScope.Mainnet);
|
|
212
241
|
if (multichainState.multichainNetworkConfigurationsByChainId[TrxScope.Mainnet]) {
|
|
213
242
|
// Ensure namespace bucket exists
|
|
214
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
243
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, tronKeys.namespace);
|
|
215
244
|
// Enable Tron mainnet
|
|
216
|
-
|
|
245
|
+
state.enabledNetworkMap[tronKeys.namespace][tronKeys.storageKey] = true;
|
|
217
246
|
}
|
|
218
247
|
});
|
|
219
248
|
}
|
|
@@ -221,39 +250,124 @@ export class NetworkEnablementController extends BaseController {
|
|
|
221
250
|
* Initializes the network enablement state from network controller configurations.
|
|
222
251
|
*
|
|
223
252
|
* This method reads the current network configurations from both NetworkController
|
|
224
|
-
* and MultichainNetworkController and syncs the enabled network map accordingly.
|
|
253
|
+
* and MultichainNetworkController and syncs the enabled network map and nativeAssetIdentifiers accordingly.
|
|
225
254
|
* It ensures proper namespace buckets exist for all configured networks and only
|
|
226
255
|
* adds missing networks with a default value of false, preserving existing user settings.
|
|
227
256
|
*
|
|
228
257
|
* This method should be called after the NetworkController and MultichainNetworkController
|
|
229
258
|
* have been initialized and their configurations are available.
|
|
230
259
|
*/
|
|
231
|
-
init() {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
260
|
+
async init() {
|
|
261
|
+
// Get network configurations from NetworkController (EVM networks)
|
|
262
|
+
const networkControllerState = this.messenger.call('NetworkController:getState');
|
|
263
|
+
// Get network configurations from MultichainNetworkController (all networks)
|
|
264
|
+
const multichainState = this.messenger.call('MultichainNetworkController:getState');
|
|
265
|
+
// Build nativeAssetIdentifiers for EVM networks using chainid.network
|
|
266
|
+
const evmNativeAssetUpdates = [];
|
|
267
|
+
for (const [chainId, config] of Object.entries(networkControllerState.networkConfigurationsByChainId)) {
|
|
268
|
+
const { caipChainId } = deriveKeys(chainId);
|
|
269
|
+
// Skip if already in state
|
|
270
|
+
if (this.state.nativeAssetIdentifiers[caipChainId] !== undefined) {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
// Parse hex chainId to number for chainid.network lookup
|
|
274
|
+
const numericChainId = parseInt(chainId, 16);
|
|
275
|
+
// EVM networks: use getSlip44ByChainId (chainid.network data)
|
|
276
|
+
// Default to 60 (Ethereum) if no specific mapping is found
|
|
277
|
+
const slip44CoinType = (await Slip44Service.getSlip44ByChainId(numericChainId, config.nativeCurrency)) ?? 60;
|
|
278
|
+
evmNativeAssetUpdates.push({
|
|
279
|
+
caipChainId,
|
|
280
|
+
identifier: buildNativeAssetIdentifier(caipChainId, slip44CoinType),
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
// Update state synchronously
|
|
284
|
+
this.update((state) => {
|
|
237
285
|
// Initialize namespace buckets for EVM networks from NetworkController
|
|
238
|
-
Object.
|
|
286
|
+
Object.entries(networkControllerState.networkConfigurationsByChainId).forEach(([chainId]) => {
|
|
287
|
+
var _a;
|
|
239
288
|
const { namespace, storageKey } = deriveKeys(chainId);
|
|
240
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
289
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, namespace);
|
|
241
290
|
// Only add network if it doesn't already exist in state (preserves user settings)
|
|
242
|
-
|
|
243
|
-
s.enabledNetworkMap[namespace][storageKey] = false;
|
|
244
|
-
}
|
|
291
|
+
(_a = state.enabledNetworkMap[namespace])[storageKey] ?? (_a[storageKey] = false);
|
|
245
292
|
});
|
|
293
|
+
// Apply nativeAssetIdentifier updates
|
|
294
|
+
for (const { caipChainId, identifier } of evmNativeAssetUpdates) {
|
|
295
|
+
state.nativeAssetIdentifiers[caipChainId] = identifier;
|
|
296
|
+
}
|
|
246
297
|
// Initialize namespace buckets for all networks from MultichainNetworkController
|
|
247
298
|
Object.keys(multichainState.multichainNetworkConfigurationsByChainId).forEach((chainId) => {
|
|
299
|
+
var _a;
|
|
248
300
|
const { namespace, storageKey } = deriveKeys(chainId);
|
|
249
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
301
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, namespace);
|
|
250
302
|
// Only add network if it doesn't already exist in state (preserves user settings)
|
|
251
|
-
|
|
252
|
-
s.enabledNetworkMap[namespace][storageKey] = false;
|
|
253
|
-
}
|
|
303
|
+
(_a = state.enabledNetworkMap[namespace])[storageKey] ?? (_a[storageKey] = false);
|
|
254
304
|
});
|
|
255
305
|
});
|
|
256
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Initializes the native asset identifiers from network configurations.
|
|
309
|
+
* This method should be called from the client during controller initialization
|
|
310
|
+
* to populate the nativeAssetIdentifiers state based on actual network configurations.
|
|
311
|
+
*
|
|
312
|
+
* @param networks - Array of network configurations with chainId and nativeCurrency
|
|
313
|
+
* @example
|
|
314
|
+
* ```typescript
|
|
315
|
+
* const evmNetworks = Object.values(networkControllerState.networkConfigurationsByChainId)
|
|
316
|
+
* .map(config => ({
|
|
317
|
+
* chainId: toEvmCaipChainId(config.chainId),
|
|
318
|
+
* nativeCurrency: config.nativeCurrency,
|
|
319
|
+
* }));
|
|
320
|
+
*
|
|
321
|
+
* const multichainNetworks = Object.values(multichainState.multichainNetworkConfigurationsByChainId)
|
|
322
|
+
* .map(config => ({
|
|
323
|
+
* chainId: config.chainId,
|
|
324
|
+
* nativeCurrency: config.nativeCurrency,
|
|
325
|
+
* }));
|
|
326
|
+
*
|
|
327
|
+
* await controller.initNativeAssetIdentifiers([...evmNetworks, ...multichainNetworks]);
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
async initNativeAssetIdentifiers(networks) {
|
|
331
|
+
// Process networks and collect updates
|
|
332
|
+
const updates = [];
|
|
333
|
+
for (const { chainId, nativeCurrency } of networks) {
|
|
334
|
+
// Check if nativeCurrency is already in CAIP-19 format (e.g., "bip122:.../slip44:0")
|
|
335
|
+
// Non-EVM networks from MultichainNetworkController use this format
|
|
336
|
+
if (nativeCurrency.includes('/slip44:')) {
|
|
337
|
+
updates.push({
|
|
338
|
+
chainId,
|
|
339
|
+
identifier: nativeCurrency,
|
|
340
|
+
});
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
// Extract namespace from CAIP-2 chainId
|
|
344
|
+
const [namespace, reference] = chainId.split(':');
|
|
345
|
+
let slip44CoinType;
|
|
346
|
+
if (namespace === 'eip155') {
|
|
347
|
+
// EVM networks: use getSlip44ByChainId (chainid.network data)
|
|
348
|
+
// Default to 60 (Ethereum) if no specific mapping is found
|
|
349
|
+
const numericChainId = parseInt(reference, 10);
|
|
350
|
+
slip44CoinType =
|
|
351
|
+
(await Slip44Service.getSlip44ByChainId(numericChainId, nativeCurrency)) ?? 60;
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
// Non-EVM networks: use getSlip44BySymbol (@metamask/slip44 package)
|
|
355
|
+
slip44CoinType = Slip44Service.getSlip44BySymbol(nativeCurrency);
|
|
356
|
+
}
|
|
357
|
+
if (slip44CoinType !== undefined) {
|
|
358
|
+
updates.push({
|
|
359
|
+
chainId,
|
|
360
|
+
identifier: buildNativeAssetIdentifier(chainId, slip44CoinType),
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// Apply all updates synchronously
|
|
365
|
+
this.update((state) => {
|
|
366
|
+
for (const { chainId, identifier } of updates) {
|
|
367
|
+
state.nativeAssetIdentifiers[chainId] = identifier;
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
257
371
|
/**
|
|
258
372
|
* Disables a network for the user.
|
|
259
373
|
*
|
|
@@ -271,8 +385,8 @@ export class NetworkEnablementController extends BaseController {
|
|
|
271
385
|
disableNetwork(chainId) {
|
|
272
386
|
const derivedKeys = deriveKeys(chainId);
|
|
273
387
|
const { namespace, storageKey } = derivedKeys;
|
|
274
|
-
this.update((
|
|
275
|
-
|
|
388
|
+
this.update((state) => {
|
|
389
|
+
state.enabledNetworkMap[namespace][storageKey] = false;
|
|
276
390
|
});
|
|
277
391
|
}
|
|
278
392
|
/**
|
|
@@ -289,10 +403,53 @@ export class NetworkEnablementController extends BaseController {
|
|
|
289
403
|
return this.state.enabledNetworkMap[namespace]?.[storageKey] ?? false;
|
|
290
404
|
}
|
|
291
405
|
}
|
|
292
|
-
_NetworkEnablementController_instances = new WeakSet(),
|
|
406
|
+
_NetworkEnablementController_instances = new WeakSet(), _NetworkEnablementController_onNativeCurrencyChange =
|
|
407
|
+
/**
|
|
408
|
+
* Handles changes to network nativeCurrency values.
|
|
409
|
+
* Compares current and previous nativeCurrency maps to detect updates.
|
|
410
|
+
*
|
|
411
|
+
* @param currentNativeCurrencies - Current map of chainId to nativeCurrency
|
|
412
|
+
* @param previousNativeCurrencies - Previous map of chainId to nativeCurrency
|
|
413
|
+
*/
|
|
414
|
+
async function _NetworkEnablementController_onNativeCurrencyChange(currentNativeCurrencies, previousNativeCurrencies) {
|
|
415
|
+
// Skip if no previous state (initial subscription)
|
|
416
|
+
if (!previousNativeCurrencies) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
// Find chains where nativeCurrency has changed
|
|
420
|
+
for (const [chainId, currentCurrency] of Object.entries(currentNativeCurrencies)) {
|
|
421
|
+
const previousCurrency = previousNativeCurrencies[chainId];
|
|
422
|
+
// Only update if the nativeCurrency changed (not for new chains - those are handled by networkAdded)
|
|
423
|
+
if (previousCurrency !== undefined &&
|
|
424
|
+
previousCurrency !== currentCurrency) {
|
|
425
|
+
await __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_updateNativeAssetIdentifier).call(this, chainId, currentCurrency);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}, _NetworkEnablementController_ensureNamespaceBucket = function _NetworkEnablementController_ensureNamespaceBucket(state, ns) {
|
|
293
429
|
if (!state.enabledNetworkMap[ns]) {
|
|
294
430
|
state.enabledNetworkMap[ns] = {};
|
|
295
431
|
}
|
|
432
|
+
}, _NetworkEnablementController_updateNativeAssetIdentifier =
|
|
433
|
+
/**
|
|
434
|
+
* Updates the native asset identifier for an EVM network based on its symbol.
|
|
435
|
+
*
|
|
436
|
+
* This method looks up the SLIP-44 coin type using chainid.network data
|
|
437
|
+
* (via getSlip44ByChainId) and updates the nativeAssetIdentifiers state.
|
|
438
|
+
* This is only called for EVM networks from NetworkController state changes.
|
|
439
|
+
*
|
|
440
|
+
* @param chainId - The chain ID of the network (Hex format)
|
|
441
|
+
* @param symbol - The native currency symbol of the network (e.g., 'ETH')
|
|
442
|
+
*/
|
|
443
|
+
async function _NetworkEnablementController_updateNativeAssetIdentifier(chainId, symbol) {
|
|
444
|
+
const { caipChainId, reference } = deriveKeys(chainId);
|
|
445
|
+
// Parse hex chainId to number for chainid.network lookup
|
|
446
|
+
const numericChainId = parseInt(reference, 16);
|
|
447
|
+
// EVM networks: use getSlip44ByChainId (chainid.network data)
|
|
448
|
+
// Default to 60 (Ethereum) if no specific mapping is found
|
|
449
|
+
const slip44CoinType = (await Slip44Service.getSlip44ByChainId(numericChainId, symbol)) ?? 60;
|
|
450
|
+
this.update((state) => {
|
|
451
|
+
state.nativeAssetIdentifiers[caipChainId] = buildNativeAssetIdentifier(caipChainId, slip44CoinType);
|
|
452
|
+
});
|
|
296
453
|
}, _NetworkEnablementController_isInPopularNetworksMode = function _NetworkEnablementController_isInPopularNetworksMode() {
|
|
297
454
|
// Get current network configurations to check which popular networks exist
|
|
298
455
|
const networkControllerState = this.messenger.call('NetworkController:getState');
|
|
@@ -310,22 +467,42 @@ _NetworkEnablementController_instances = new WeakSet(), _NetworkEnablementContro
|
|
|
310
467
|
return enabledPopularNetworksCount > 1;
|
|
311
468
|
}, _NetworkEnablementController_removeNetworkEntry = function _NetworkEnablementController_removeNetworkEntry(chainId) {
|
|
312
469
|
const derivedKeys = deriveKeys(chainId);
|
|
313
|
-
const { namespace, storageKey } = derivedKeys;
|
|
314
|
-
this.update((
|
|
470
|
+
const { namespace, storageKey, caipChainId } = derivedKeys;
|
|
471
|
+
this.update((state) => {
|
|
315
472
|
// fallback and enable ethereum mainnet
|
|
316
473
|
if (isOnlyNetworkEnabledInNamespace(this.state, derivedKeys)) {
|
|
317
|
-
|
|
318
|
-
true;
|
|
474
|
+
state.enabledNetworkMap[namespace][ChainId[BuiltInNetworkName.Mainnet]] = true;
|
|
319
475
|
}
|
|
320
|
-
if (namespace in
|
|
321
|
-
delete
|
|
476
|
+
if (namespace in state.enabledNetworkMap) {
|
|
477
|
+
delete state.enabledNetworkMap[namespace][storageKey];
|
|
322
478
|
}
|
|
479
|
+
// Remove from nativeAssetIdentifiers as well
|
|
480
|
+
delete state.nativeAssetIdentifiers[caipChainId];
|
|
323
481
|
});
|
|
324
|
-
}, _NetworkEnablementController_onAddNetwork =
|
|
325
|
-
|
|
326
|
-
|
|
482
|
+
}, _NetworkEnablementController_onAddNetwork =
|
|
483
|
+
/**
|
|
484
|
+
* Handles the addition of a new EVM network to the controller.
|
|
485
|
+
*
|
|
486
|
+
* @param chainId - The chain ID to add (Hex format)
|
|
487
|
+
* @param nativeCurrency - The native currency symbol of the network (e.g., 'ETH')
|
|
488
|
+
*
|
|
489
|
+
* @description
|
|
490
|
+
* - If in popular networks mode (>2 popular networks enabled) AND adding a popular network:
|
|
491
|
+
* - Keep current selection (add but don't enable the new network)
|
|
492
|
+
* - Otherwise:
|
|
493
|
+
* - Switch to the newly added network (disable all others, enable this one)
|
|
494
|
+
* - Also updates the nativeAssetIdentifiers with the CAIP-19-like identifier
|
|
495
|
+
*/
|
|
496
|
+
async function _NetworkEnablementController_onAddNetwork(chainId, nativeCurrency) {
|
|
497
|
+
const { namespace, storageKey, reference, caipChainId } = deriveKeys(chainId);
|
|
498
|
+
// Parse hex chainId to number for chainid.network lookup
|
|
499
|
+
const numericChainId = parseInt(reference, 16);
|
|
500
|
+
// EVM networks: use getSlip44ByChainId (chainid.network data)
|
|
501
|
+
// Default to 60 (Ethereum) if no specific mapping is found
|
|
502
|
+
const slip44CoinType = (await Slip44Service.getSlip44ByChainId(numericChainId, nativeCurrency)) ?? 60;
|
|
503
|
+
this.update((state) => {
|
|
327
504
|
// Ensure the namespace bucket exists
|
|
328
|
-
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this,
|
|
505
|
+
__classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_ensureNamespaceBucket).call(this, state, namespace);
|
|
329
506
|
// Check if popular networks mode is active (>2 popular networks enabled)
|
|
330
507
|
const inPopularNetworksMode = __classPrivateFieldGet(this, _NetworkEnablementController_instances, "m", _NetworkEnablementController_isInPopularNetworksMode).call(this);
|
|
331
508
|
// Check if the network being added is a popular network
|
|
@@ -334,18 +511,20 @@ _NetworkEnablementController_instances = new WeakSet(), _NetworkEnablementContro
|
|
|
334
511
|
const shouldKeepCurrentSelection = inPopularNetworksMode && isAddedNetworkPopular;
|
|
335
512
|
if (shouldKeepCurrentSelection) {
|
|
336
513
|
// Add the popular network but don't enable it (keep current selection)
|
|
337
|
-
|
|
514
|
+
state.enabledNetworkMap[namespace][storageKey] = true;
|
|
338
515
|
}
|
|
339
516
|
else {
|
|
340
517
|
// Switch to the newly added network (disable all others, enable this one)
|
|
341
|
-
Object.keys(
|
|
342
|
-
Object.keys(
|
|
343
|
-
|
|
518
|
+
Object.keys(state.enabledNetworkMap).forEach((ns) => {
|
|
519
|
+
Object.keys(state.enabledNetworkMap[ns]).forEach((key) => {
|
|
520
|
+
state.enabledNetworkMap[ns][key] = false;
|
|
344
521
|
});
|
|
345
522
|
});
|
|
346
523
|
// Enable the newly added network
|
|
347
|
-
|
|
524
|
+
state.enabledNetworkMap[namespace][storageKey] = true;
|
|
348
525
|
}
|
|
526
|
+
// Update nativeAssetIdentifiers with the CAIP-19-like identifier
|
|
527
|
+
state.nativeAssetIdentifiers[caipChainId] = buildNativeAssetIdentifier(caipChainId, slip44CoinType);
|
|
349
528
|
});
|
|
350
529
|
};
|
|
351
530
|
//# sourceMappingURL=NetworkEnablementController.mjs.map
|