@metamask-previews/network-controller 36.0.0-preview-8bfa290fb → 37.0.0-preview-0a30e47
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 +24 -3
- package/dist/{NetworkController-method-action-types.d.mts → NetworkController-method-action-types.d.ts} +2 -2
- package/dist/NetworkController-method-action-types.d.ts.map +1 -0
- package/dist/{NetworkController-method-action-types.mjs → NetworkController-method-action-types.js} +1 -1
- package/dist/NetworkController-method-action-types.js.map +1 -0
- package/dist/{NetworkController.d.cts → NetworkController.d.ts} +37 -29
- package/dist/NetworkController.d.ts.map +1 -0
- package/dist/{NetworkController.mjs → NetworkController.js} +717 -615
- package/dist/NetworkController.js.map +1 -0
- package/dist/{constants.d.cts → constants.d.ts} +1 -1
- package/dist/constants.d.ts.map +1 -0
- package/dist/{constants.mjs → constants.js} +1 -1
- package/dist/constants.js.map +1 -0
- package/dist/{create-auto-managed-network-client.d.cts → create-auto-managed-network-client.d.ts} +7 -7
- package/dist/create-auto-managed-network-client.d.ts.map +1 -0
- package/dist/{create-auto-managed-network-client.mjs → create-auto-managed-network-client.js} +4 -4
- package/dist/create-auto-managed-network-client.js.map +1 -0
- package/dist/{create-network-client.d.cts → create-network-client.d.ts} +7 -7
- package/dist/create-network-client.d.ts.map +1 -0
- package/dist/{create-network-client.mjs → create-network-client.js} +17 -14
- package/dist/create-network-client.js.map +1 -0
- package/dist/{index.d.cts → index.d.ts} +16 -16
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -0
- package/dist/rpc-service/{abstract-rpc-service.d.cts → abstract-rpc-service.d.ts} +2 -2
- package/dist/rpc-service/abstract-rpc-service.d.ts.map +1 -0
- package/dist/rpc-service/abstract-rpc-service.js +2 -0
- package/dist/rpc-service/abstract-rpc-service.js.map +1 -0
- package/dist/rpc-service/{rpc-service-chain.d.cts → rpc-service-chain.d.ts} +6 -6
- package/dist/rpc-service/rpc-service-chain.d.ts.map +1 -0
- package/dist/rpc-service/{rpc-service-chain.mjs → rpc-service-chain.js} +57 -70
- package/dist/rpc-service/rpc-service-chain.js.map +1 -0
- package/dist/rpc-service/{rpc-service-requestable.d.cts → rpc-service-requestable.d.ts} +4 -4
- package/dist/rpc-service/rpc-service-requestable.d.ts.map +1 -0
- package/dist/rpc-service/rpc-service-requestable.js +2 -0
- package/dist/rpc-service/rpc-service-requestable.js.map +1 -0
- package/dist/rpc-service/{rpc-service.d.mts → rpc-service.d.ts} +6 -6
- package/dist/rpc-service/rpc-service.d.ts.map +1 -0
- package/dist/rpc-service/{rpc-service.mjs → rpc-service.js} +206 -197
- package/dist/rpc-service/rpc-service.js.map +1 -0
- package/dist/rpc-service/{shared.d.cts → shared.d.ts} +2 -2
- package/dist/rpc-service/shared.d.ts.map +1 -0
- package/dist/rpc-service/shared.js +2 -0
- package/dist/rpc-service/shared.js.map +1 -0
- package/dist/{rpc-service-analytics.d.mts → rpc-service-analytics.d.ts} +3 -3
- package/dist/rpc-service-analytics.d.ts.map +1 -0
- package/dist/{rpc-service-analytics.mjs → rpc-service-analytics.js} +4 -4
- package/dist/rpc-service-analytics.js.map +1 -0
- package/dist/{selectors.d.mts → selectors.d.ts} +2 -2
- package/dist/selectors.d.ts.map +1 -0
- package/dist/{selectors.mjs → selectors.js} +1 -1
- package/dist/selectors.js.map +1 -0
- package/dist/{types.d.cts → types.d.ts} +5 -5
- package/dist/types.d.ts.map +1 -0
- package/dist/{types.mjs → types.js} +1 -1
- package/dist/types.js.map +1 -0
- package/package.json +26 -30
- package/dist/NetworkController-method-action-types.cjs +0 -7
- package/dist/NetworkController-method-action-types.cjs.map +0 -1
- package/dist/NetworkController-method-action-types.d.cts +0 -268
- package/dist/NetworkController-method-action-types.d.cts.map +0 -1
- package/dist/NetworkController-method-action-types.d.mts.map +0 -1
- package/dist/NetworkController-method-action-types.mjs.map +0 -1
- package/dist/NetworkController.cjs +0 -1599
- package/dist/NetworkController.cjs.map +0 -1
- package/dist/NetworkController.d.cts.map +0 -1
- package/dist/NetworkController.d.mts +0 -956
- package/dist/NetworkController.d.mts.map +0 -1
- package/dist/NetworkController.mjs.map +0 -1
- package/dist/constants.cjs +0 -46
- package/dist/constants.cjs.map +0 -1
- package/dist/constants.d.cts.map +0 -1
- package/dist/constants.d.mts +0 -42
- package/dist/constants.d.mts.map +0 -1
- package/dist/constants.mjs.map +0 -1
- package/dist/create-auto-managed-network-client.cjs +0 -149
- package/dist/create-auto-managed-network-client.cjs.map +0 -1
- package/dist/create-auto-managed-network-client.d.cts.map +0 -1
- package/dist/create-auto-managed-network-client.d.mts +0 -74
- package/dist/create-auto-managed-network-client.d.mts.map +0 -1
- package/dist/create-auto-managed-network-client.mjs.map +0 -1
- package/dist/create-network-client.cjs +0 -439
- package/dist/create-network-client.cjs.map +0 -1
- package/dist/create-network-client.d.cts.map +0 -1
- package/dist/create-network-client.d.mts +0 -60
- package/dist/create-network-client.d.mts.map +0 -1
- package/dist/create-network-client.mjs.map +0 -1
- package/dist/index.cjs +0 -31
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.mts +0 -16
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -6
- package/dist/index.mjs.map +0 -1
- package/dist/logger.cjs +0 -7
- package/dist/logger.cjs.map +0 -1
- package/dist/logger.d.cts +0 -5
- package/dist/logger.d.cts.map +0 -1
- package/dist/logger.d.mts +0 -5
- package/dist/logger.d.mts.map +0 -1
- package/dist/logger.mjs +0 -4
- package/dist/logger.mjs.map +0 -1
- package/dist/rpc-service/abstract-rpc-service.cjs +0 -3
- package/dist/rpc-service/abstract-rpc-service.cjs.map +0 -1
- package/dist/rpc-service/abstract-rpc-service.d.cts.map +0 -1
- package/dist/rpc-service/abstract-rpc-service.d.mts +0 -17
- package/dist/rpc-service/abstract-rpc-service.d.mts.map +0 -1
- package/dist/rpc-service/abstract-rpc-service.mjs +0 -2
- package/dist/rpc-service/abstract-rpc-service.mjs.map +0 -1
- package/dist/rpc-service/rpc-service-chain.cjs +0 -304
- package/dist/rpc-service/rpc-service-chain.cjs.map +0 -1
- package/dist/rpc-service/rpc-service-chain.d.cts.map +0 -1
- package/dist/rpc-service/rpc-service-chain.d.mts +0 -169
- package/dist/rpc-service/rpc-service-chain.d.mts.map +0 -1
- package/dist/rpc-service/rpc-service-chain.mjs.map +0 -1
- package/dist/rpc-service/rpc-service-requestable.cjs +0 -3
- package/dist/rpc-service/rpc-service-requestable.cjs.map +0 -1
- package/dist/rpc-service/rpc-service-requestable.d.cts.map +0 -1
- package/dist/rpc-service/rpc-service-requestable.d.mts +0 -63
- package/dist/rpc-service/rpc-service-requestable.d.mts.map +0 -1
- package/dist/rpc-service/rpc-service-requestable.mjs +0 -2
- package/dist/rpc-service/rpc-service-requestable.mjs.map +0 -1
- package/dist/rpc-service/rpc-service.cjs +0 -540
- package/dist/rpc-service/rpc-service.cjs.map +0 -1
- package/dist/rpc-service/rpc-service.d.cts +0 -247
- package/dist/rpc-service/rpc-service.d.cts.map +0 -1
- package/dist/rpc-service/rpc-service.d.mts.map +0 -1
- package/dist/rpc-service/rpc-service.mjs.map +0 -1
- package/dist/rpc-service/shared.cjs +0 -3
- package/dist/rpc-service/shared.cjs.map +0 -1
- package/dist/rpc-service/shared.d.cts.map +0 -1
- package/dist/rpc-service/shared.d.mts +0 -32
- package/dist/rpc-service/shared.d.mts.map +0 -1
- package/dist/rpc-service/shared.mjs +0 -2
- package/dist/rpc-service/shared.mjs.map +0 -1
- package/dist/rpc-service-analytics.cjs +0 -180
- package/dist/rpc-service-analytics.cjs.map +0 -1
- package/dist/rpc-service-analytics.d.cts +0 -85
- package/dist/rpc-service-analytics.d.cts.map +0 -1
- package/dist/rpc-service-analytics.d.mts.map +0 -1
- package/dist/rpc-service-analytics.mjs.map +0 -1
- package/dist/selectors.cjs +0 -16
- package/dist/selectors.cjs.map +0 -1
- package/dist/selectors.d.cts +0 -22
- package/dist/selectors.d.cts.map +0 -1
- package/dist/selectors.d.mts.map +0 -1
- package/dist/selectors.mjs.map +0 -1
- package/dist/types.cjs +0 -12
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts +0 -49
- package/dist/types.d.mts.map +0 -1
- package/dist/types.mjs.map +0 -1
|
@@ -1,43 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
import {
|
|
20
|
-
import { selectEvmAutoEnabledNetworksChainIds } from "@metamask/config-registry-controller";
|
|
21
|
-
import { InfuraNetworkType, CustomNetworkType, NetworkType, isSafeChainId, isInfuraNetworkType, ChainId, NetworksTicker, NetworkNickname, BUILT_IN_CUSTOM_NETWORKS_RPC, BUILT_IN_NETWORKS, DEFAULT_INFURA_NETWORKS } from "@metamask/controller-utils";
|
|
22
|
-
import $EthQuery from "@metamask/eth-query";
|
|
23
|
-
const EthQuery = $importDefault($EthQuery);
|
|
24
|
-
import { errorCodes } from "@metamask/rpc-errors";
|
|
25
|
-
import { createEventEmitterProxy, createSwappableProxy } from "@metamask/swappable-obj-proxy";
|
|
26
|
-
import { hasProperty, isPlainObject, isStrictHexString, numberToHex, parseCaipChainId } from "@metamask/utils";
|
|
27
|
-
import $deepEqual from "fast-deep-equal";
|
|
28
|
-
const deepEqual = $importDefault($deepEqual);
|
|
29
|
-
import { produce } from "immer";
|
|
30
|
-
import $lodash from "lodash";
|
|
31
|
-
const { cloneDeep } = $lodash;
|
|
32
|
-
import { createSelector } from "reselect";
|
|
33
|
-
import * as URI from "uri-js";
|
|
34
|
-
import { v4 as uuidV4 } from "uuid";
|
|
35
|
-
import { DEPRECATED_NETWORKS, INFURA_BLOCKED_KEY, NetworkStatus } from "./constants.mjs";
|
|
36
|
-
import { createAutoManagedNetworkClient } from "./create-auto-managed-network-client.mjs";
|
|
37
|
-
import { projectLogger, createModuleLogger } from "./logger.mjs";
|
|
38
|
-
import { trackRpcServiceDegraded, trackRpcServiceUnavailable } from "./rpc-service-analytics.mjs";
|
|
39
|
-
import { getRpcFailoverMode } from "./selectors.mjs";
|
|
40
|
-
import { NetworkClientType } from "./types.mjs";
|
|
1
|
+
import { BaseController } from '@metamask/base-controller';
|
|
2
|
+
import { selectEvmAutoEnabledNetworksChainIds } from '@metamask/config-registry-controller';
|
|
3
|
+
import { InfuraNetworkType, CustomNetworkType, NetworkType, isSafeChainId, isInfuraNetworkType, ChainId, NetworksTicker, NetworkNickname, BUILT_IN_CUSTOM_NETWORKS_RPC, BUILT_IN_NETWORKS, DEFAULT_INFURA_NETWORKS, } from '@metamask/controller-utils';
|
|
4
|
+
import EthQuery from '@metamask/eth-query';
|
|
5
|
+
import { errorCodes } from '@metamask/rpc-errors';
|
|
6
|
+
import { createEventEmitterProxy, createSwappableProxy, } from '@metamask/swappable-obj-proxy';
|
|
7
|
+
import { hasProperty, isPlainObject, isStrictHexString, numberToHex, parseCaipChainId, } from '@metamask/utils';
|
|
8
|
+
import deepEqual from 'fast-deep-equal';
|
|
9
|
+
import { produce } from 'immer';
|
|
10
|
+
import { cloneDeep } from 'lodash-es';
|
|
11
|
+
import { createSelector } from 'reselect';
|
|
12
|
+
import * as URI from 'uri-js';
|
|
13
|
+
import { v4 as uuidV4 } from 'uuid';
|
|
14
|
+
import { DEPRECATED_NETWORKS, INFURA_BLOCKED_KEY, NetworkStatus, } from './constants.js';
|
|
15
|
+
import { createAutoManagedNetworkClient } from './create-auto-managed-network-client.js';
|
|
16
|
+
import { projectLogger, createModuleLogger } from './logger.js';
|
|
17
|
+
import { trackRpcServiceDegraded, trackRpcServiceUnavailable, } from './rpc-service-analytics.js';
|
|
18
|
+
import { getRpcFailoverMode } from './selectors.js';
|
|
19
|
+
import { NetworkClientType } from './types.js';
|
|
41
20
|
const debugLog = createModuleLogger(projectLogger, 'NetworkController');
|
|
42
21
|
const INFURA_URL_REGEX = /^https:\/\/(?<networkName>[^.]+)\.infura\.io\/v\d+\/(?<apiKey>.+)$/u;
|
|
43
22
|
/**
|
|
@@ -359,6 +338,20 @@ function buildNetworkConfigurationsByNetworkClientId(networkConfigurationsByChai
|
|
|
359
338
|
* Controller that creates and manages an Ethereum network provider.
|
|
360
339
|
*/
|
|
361
340
|
export class NetworkController extends BaseController {
|
|
341
|
+
#ethQuery;
|
|
342
|
+
#infuraProjectId;
|
|
343
|
+
#failoverUrls;
|
|
344
|
+
#previouslySelectedNetworkClientId;
|
|
345
|
+
#providerProxy;
|
|
346
|
+
#blockTrackerProxy;
|
|
347
|
+
#autoManagedNetworkClientRegistry;
|
|
348
|
+
#autoManagedNetworkClient;
|
|
349
|
+
#log;
|
|
350
|
+
#getRpcServiceOptions;
|
|
351
|
+
#getBlockTrackerOptions;
|
|
352
|
+
#analyticsOptions;
|
|
353
|
+
#networkConfigurationsByNetworkClientId;
|
|
354
|
+
#rpcFailoverMode = 'disabled';
|
|
362
355
|
/**
|
|
363
356
|
* Constructs a NetworkController.
|
|
364
357
|
*
|
|
@@ -400,57 +393,42 @@ export class NetworkController extends BaseController {
|
|
|
400
393
|
messenger,
|
|
401
394
|
state: correctedInitialState,
|
|
402
395
|
});
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
_NetworkController_blockTrackerProxy.set(this, void 0);
|
|
410
|
-
_NetworkController_autoManagedNetworkClientRegistry.set(this, void 0);
|
|
411
|
-
_NetworkController_autoManagedNetworkClient.set(this, void 0);
|
|
412
|
-
_NetworkController_log.set(this, void 0);
|
|
413
|
-
_NetworkController_getRpcServiceOptions.set(this, void 0);
|
|
414
|
-
_NetworkController_getBlockTrackerOptions.set(this, void 0);
|
|
415
|
-
_NetworkController_analyticsOptions.set(this, void 0);
|
|
416
|
-
_NetworkController_networkConfigurationsByNetworkClientId.set(this, void 0);
|
|
417
|
-
_NetworkController_rpcFailoverMode.set(this, 'disabled');
|
|
418
|
-
__classPrivateFieldSet(this, _NetworkController_infuraProjectId, infuraProjectId, "f");
|
|
419
|
-
__classPrivateFieldSet(this, _NetworkController_failoverUrls, failoverUrls, "f");
|
|
420
|
-
__classPrivateFieldSet(this, _NetworkController_log, log, "f");
|
|
421
|
-
__classPrivateFieldSet(this, _NetworkController_getRpcServiceOptions, getRpcServiceOptions, "f");
|
|
422
|
-
__classPrivateFieldSet(this, _NetworkController_getBlockTrackerOptions, getBlockTrackerOptions, "f");
|
|
423
|
-
__classPrivateFieldSet(this, _NetworkController_analyticsOptions, {
|
|
396
|
+
this.#infuraProjectId = infuraProjectId;
|
|
397
|
+
this.#failoverUrls = failoverUrls;
|
|
398
|
+
this.#log = log;
|
|
399
|
+
this.#getRpcServiceOptions = getRpcServiceOptions;
|
|
400
|
+
this.#getBlockTrackerOptions = getBlockTrackerOptions;
|
|
401
|
+
this.#analyticsOptions = {
|
|
424
402
|
isRpcEndpointUrlPublic: () => false,
|
|
425
403
|
rpcServiceEventsSampleRate: 0,
|
|
426
404
|
...analyticsOptions,
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
|
|
405
|
+
};
|
|
406
|
+
this.#previouslySelectedNetworkClientId =
|
|
407
|
+
this.state.selectedNetworkClientId;
|
|
408
|
+
this.#networkConfigurationsByNetworkClientId =
|
|
409
|
+
buildNetworkConfigurationsByNetworkClientId(this.state.networkConfigurationsByChainId);
|
|
430
410
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
431
411
|
this.messenger.subscribe(`${this.name}:rpcEndpointChainUnavailable`, ({ networkClientId }) => {
|
|
432
|
-
|
|
412
|
+
this.#updateMetadataForNetwork(networkClientId, {
|
|
433
413
|
networkStatus: NetworkStatus.Unavailable,
|
|
434
414
|
});
|
|
435
415
|
});
|
|
436
416
|
this.messenger.subscribe(`${this.name}:rpcEndpointChainDegraded`, ({ networkClientId }) => {
|
|
437
|
-
|
|
417
|
+
this.#updateMetadataForNetwork(networkClientId, {
|
|
438
418
|
networkStatus: NetworkStatus.Degraded,
|
|
439
419
|
});
|
|
440
420
|
});
|
|
441
421
|
this.messenger.subscribe(`${this.name}:rpcEndpointChainAvailable`, ({ networkClientId }) => {
|
|
442
|
-
|
|
422
|
+
this.#updateMetadataForNetwork(networkClientId, {
|
|
443
423
|
networkStatus: NetworkStatus.Available,
|
|
444
424
|
});
|
|
445
425
|
});
|
|
446
|
-
this.messenger.subscribe(`${this.name}:rpcEndpointUnavailable`, (payload) => trackRpcServiceUnavailable(this.messenger,
|
|
447
|
-
this.messenger.subscribe(`${this.name}:rpcEndpointDegraded`, (payload) => trackRpcServiceDegraded(this.messenger,
|
|
448
|
-
this.messenger.subscribe(
|
|
449
|
-
|
|
450
|
-
'RemoteFeatureFlagController:stateChange', (rpcFailoverMode) => {
|
|
451
|
-
__classPrivateFieldGet(this, _NetworkController_instances, "m", _NetworkController_updateRpcFailover).call(this, rpcFailoverMode);
|
|
426
|
+
this.messenger.subscribe(`${this.name}:rpcEndpointUnavailable`, (payload) => trackRpcServiceUnavailable(this.messenger, this.#analyticsOptions, payload));
|
|
427
|
+
this.messenger.subscribe(`${this.name}:rpcEndpointDegraded`, (payload) => trackRpcServiceDegraded(this.messenger, this.#analyticsOptions, payload));
|
|
428
|
+
this.messenger.subscribe('RemoteFeatureFlagController:stateChange', (rpcFailoverMode) => {
|
|
429
|
+
this.#updateRpcFailover(rpcFailoverMode);
|
|
452
430
|
}, getRpcFailoverMode);
|
|
453
|
-
this.messenger.subscribe('ConfigRegistryController:stateChanged', (caipChainIds) =>
|
|
431
|
+
this.messenger.subscribe('ConfigRegistryController:stateChanged', (caipChainIds) => this.#autoAddNetworksFromConfigRegistry(caipChainIds), selectEvmAutoEnabledNetworksChainIds);
|
|
454
432
|
}
|
|
455
433
|
/**
|
|
456
434
|
* Returns the EthQuery instance for the currently selected network.
|
|
@@ -459,7 +437,31 @@ export class NetworkController extends BaseController {
|
|
|
459
437
|
* initialized.
|
|
460
438
|
*/
|
|
461
439
|
getEthQuery() {
|
|
462
|
-
return
|
|
440
|
+
return this.#ethQuery;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Applies the given RPC failover mode by reconstructing all network clients
|
|
444
|
+
* that were configured with failover URLs so that the new mode takes effect.
|
|
445
|
+
* Network client IDs are preserved so as not to invalidate state in other
|
|
446
|
+
* controllers.
|
|
447
|
+
*
|
|
448
|
+
* @param newMode - The RPC failover mode to apply.
|
|
449
|
+
*/
|
|
450
|
+
#updateRpcFailover(newMode) {
|
|
451
|
+
if (this.#rpcFailoverMode === newMode) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const autoManagedNetworkClientRegistry = this.#ensureAutoManagedNetworkClientRegistryPopulated();
|
|
455
|
+
for (const networkClientsById of Object.values(autoManagedNetworkClientRegistry)) {
|
|
456
|
+
for (const networkClientId of Object.keys(networkClientsById)) {
|
|
457
|
+
const networkClient = networkClientsById[networkClientId];
|
|
458
|
+
if (networkClient.configuration.failoverRpcUrls &&
|
|
459
|
+
networkClient.configuration.failoverRpcUrls.length > 0) {
|
|
460
|
+
networkClient.setRpcFailoverMode(newMode);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
this.#rpcFailoverMode = newMode;
|
|
463
465
|
}
|
|
464
466
|
/**
|
|
465
467
|
* Accesses the provider and block tracker for the currently selected network.
|
|
@@ -469,8 +471,8 @@ export class NetworkController extends BaseController {
|
|
|
469
471
|
*/
|
|
470
472
|
getProviderAndBlockTracker() {
|
|
471
473
|
return {
|
|
472
|
-
provider:
|
|
473
|
-
blockTracker:
|
|
474
|
+
provider: this.#providerProxy,
|
|
475
|
+
blockTracker: this.#blockTrackerProxy,
|
|
474
476
|
};
|
|
475
477
|
}
|
|
476
478
|
/**
|
|
@@ -479,10 +481,10 @@ export class NetworkController extends BaseController {
|
|
|
479
481
|
* @returns an object with the provider and block tracker proxies for the currently selected network.
|
|
480
482
|
*/
|
|
481
483
|
getSelectedNetworkClient() {
|
|
482
|
-
if (
|
|
484
|
+
if (this.#providerProxy && this.#blockTrackerProxy) {
|
|
483
485
|
return {
|
|
484
|
-
provider:
|
|
485
|
-
blockTracker:
|
|
486
|
+
provider: this.#providerProxy,
|
|
487
|
+
blockTracker: this.#blockTrackerProxy,
|
|
486
488
|
};
|
|
487
489
|
}
|
|
488
490
|
return undefined;
|
|
@@ -506,14 +508,14 @@ export class NetworkController extends BaseController {
|
|
|
506
508
|
* @returns The network clients registered so far, keyed by ID.
|
|
507
509
|
*/
|
|
508
510
|
getNetworkClientRegistry() {
|
|
509
|
-
const autoManagedNetworkClientRegistry =
|
|
511
|
+
const autoManagedNetworkClientRegistry = this.#ensureAutoManagedNetworkClientRegistryPopulated();
|
|
510
512
|
return Object.assign({}, autoManagedNetworkClientRegistry[NetworkClientType.Infura], autoManagedNetworkClientRegistry[NetworkClientType.Custom]);
|
|
511
513
|
}
|
|
512
514
|
getNetworkClientById(networkClientId) {
|
|
513
515
|
if (!networkClientId) {
|
|
514
516
|
throw new Error('No network client ID was provided.');
|
|
515
517
|
}
|
|
516
|
-
const autoManagedNetworkClientRegistry =
|
|
518
|
+
const autoManagedNetworkClientRegistry = this.#ensureAutoManagedNetworkClientRegistryPopulated();
|
|
517
519
|
const infuraNetworkClient = autoManagedNetworkClientRegistry[NetworkClientType.Infura][networkClientId];
|
|
518
520
|
if (infuraNetworkClient) {
|
|
519
521
|
return infuraNetworkClient;
|
|
@@ -524,6 +526,30 @@ export class NetworkController extends BaseController {
|
|
|
524
526
|
}
|
|
525
527
|
return customNetworkClient;
|
|
526
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Executes a series of steps to switch the network:
|
|
531
|
+
*
|
|
532
|
+
* 1. Notifies subscribers via the messenger that the network is about to be
|
|
533
|
+
* switched (and, really, that the global provider and block tracker proxies
|
|
534
|
+
* will be re-pointed to a new network).
|
|
535
|
+
* 2. Looks up a known and preinitialized network client matching the given
|
|
536
|
+
* ID and uses it to re-point the aforementioned provider and block tracker
|
|
537
|
+
* proxies.
|
|
538
|
+
* 3. Notifies subscribers via the messenger that the network has switched.
|
|
539
|
+
* 4. Captures metadata for the newly switched network in state.
|
|
540
|
+
*
|
|
541
|
+
* @param networkClientId - The ID of a network client that requests will be
|
|
542
|
+
* routed through (either the name of an Infura network or the ID of a custom
|
|
543
|
+
* network configuration).
|
|
544
|
+
* @param options - Options for this method.
|
|
545
|
+
* @param options.updateState - Allows for updating state.
|
|
546
|
+
*/
|
|
547
|
+
async #refreshNetwork(networkClientId, options = {}) {
|
|
548
|
+
this.messenger.publish('NetworkController:networkWillChange', this.state);
|
|
549
|
+
this.#applyNetworkSelection(networkClientId, options);
|
|
550
|
+
this.messenger.publish('NetworkController:networkDidChange', this.state);
|
|
551
|
+
await this.lookupNetwork();
|
|
552
|
+
}
|
|
527
553
|
/**
|
|
528
554
|
* Initialize the NetworkController:
|
|
529
555
|
* - Apply the RPC failover mode from the `corePlatformRpcFailoverMode` remote feature flag;
|
|
@@ -532,9 +558,68 @@ export class NetworkController extends BaseController {
|
|
|
532
558
|
*/
|
|
533
559
|
init() {
|
|
534
560
|
const state = this.messenger.call('RemoteFeatureFlagController:getState');
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
561
|
+
this.#updateRpcFailover(getRpcFailoverMode(state));
|
|
562
|
+
this.#applyNetworkSelection(this.state.selectedNetworkClientId);
|
|
563
|
+
this.#autoAddNetworksFromConfigRegistry(selectEvmAutoEnabledNetworksChainIds(this.messenger.call('ConfigRegistryController:getState')));
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Uses a request for the latest block to gather the following information on
|
|
567
|
+
* the given network:
|
|
568
|
+
*
|
|
569
|
+
* - The connectivity status: whether it is available, geo-blocked (Infura
|
|
570
|
+
* only), unavailable, or unknown
|
|
571
|
+
* - The capabilities status: whether it supports EIP-1559, whether it does
|
|
572
|
+
* not, or whether it is unknown
|
|
573
|
+
*
|
|
574
|
+
* @param networkClientId - The ID of the network client to inspect.
|
|
575
|
+
* If no ID is provided, uses the currently selected network.
|
|
576
|
+
* @returns The resulting metadata for the network.
|
|
577
|
+
*/
|
|
578
|
+
async #determineNetworkMetadata(networkClientId) {
|
|
579
|
+
const networkClient = this.getNetworkClientById(networkClientId);
|
|
580
|
+
const isInfura = networkClient.configuration.type === NetworkClientType.Infura;
|
|
581
|
+
let networkStatus;
|
|
582
|
+
let isEIP1559Compatible;
|
|
583
|
+
try {
|
|
584
|
+
isEIP1559Compatible =
|
|
585
|
+
await this.#determineEIP1559Compatibility(networkClientId);
|
|
586
|
+
networkStatus = NetworkStatus.Available;
|
|
587
|
+
}
|
|
588
|
+
catch (error) {
|
|
589
|
+
debugLog('NetworkController: lookupNetwork: ', error);
|
|
590
|
+
if (isErrorWithCode(error)) {
|
|
591
|
+
let responseBody;
|
|
592
|
+
if (isInfura &&
|
|
593
|
+
hasProperty(error, 'message') &&
|
|
594
|
+
typeof error.message === 'string') {
|
|
595
|
+
try {
|
|
596
|
+
responseBody = JSON.parse(error.message);
|
|
597
|
+
}
|
|
598
|
+
catch {
|
|
599
|
+
// error.message must not be JSON
|
|
600
|
+
this.#log?.warn('NetworkController: lookupNetwork: json parse error: ', error);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (isPlainObject(responseBody) &&
|
|
604
|
+
responseBody.error === INFURA_BLOCKED_KEY) {
|
|
605
|
+
networkStatus = NetworkStatus.Blocked;
|
|
606
|
+
}
|
|
607
|
+
else if (error.code === errorCodes.rpc.internal) {
|
|
608
|
+
networkStatus = NetworkStatus.Unknown;
|
|
609
|
+
this.#log?.warn('NetworkController: lookupNetwork: rpc internal error: ', error);
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
networkStatus = NetworkStatus.Unavailable;
|
|
613
|
+
this.#log?.warn('NetworkController: lookupNetwork: ', error);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
debugLog('NetworkController - could not determine network status', error);
|
|
618
|
+
networkStatus = NetworkStatus.Unknown;
|
|
619
|
+
this.#log?.warn('NetworkController: lookupNetwork: ', error);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return { isInfura, networkStatus, isEIP1559Compatible };
|
|
538
623
|
}
|
|
539
624
|
/**
|
|
540
625
|
* Uses a request for the latest block to gather the following information on
|
|
@@ -550,10 +635,10 @@ export class NetworkController extends BaseController {
|
|
|
550
635
|
*/
|
|
551
636
|
async lookupNetwork(networkClientId) {
|
|
552
637
|
if (networkClientId) {
|
|
553
|
-
await
|
|
638
|
+
await this.#lookupGivenNetwork(networkClientId);
|
|
554
639
|
}
|
|
555
640
|
else {
|
|
556
|
-
await
|
|
641
|
+
await this.#lookupSelectedNetwork();
|
|
557
642
|
}
|
|
558
643
|
}
|
|
559
644
|
/**
|
|
@@ -573,7 +658,129 @@ export class NetworkController extends BaseController {
|
|
|
573
658
|
// right now.
|
|
574
659
|
/* istanbul ignore next */
|
|
575
660
|
async lookupNetworkByClientId(networkClientId) {
|
|
576
|
-
await
|
|
661
|
+
await this.#lookupGivenNetwork(networkClientId);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Uses a request for the latest block to gather the following information on
|
|
665
|
+
* the given network, persisting it to state:
|
|
666
|
+
*
|
|
667
|
+
* - The connectivity status: whether the network is available, geo-blocked
|
|
668
|
+
* (Infura only), unavailable, or unknown
|
|
669
|
+
* - The feature compatibility status: whether the network supports EIP-1559,
|
|
670
|
+
* whether it does not, or whether it is unknown
|
|
671
|
+
*
|
|
672
|
+
* @param networkClientId - The ID of the network client to inspect.
|
|
673
|
+
*/
|
|
674
|
+
async #lookupGivenNetwork(networkClientId) {
|
|
675
|
+
const { networkStatus, isEIP1559Compatible } = await this.#determineNetworkMetadata(networkClientId);
|
|
676
|
+
this.#updateMetadataForNetwork(networkClientId, {
|
|
677
|
+
networkStatus,
|
|
678
|
+
isEIP1559Compatible,
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Uses a request for the latest block to gather the following information on
|
|
683
|
+
* the currently selected network, persisting it to state:
|
|
684
|
+
*
|
|
685
|
+
* - The connectivity status: whether the network is available, geo-blocked
|
|
686
|
+
* (Infura only), unavailable, or unknown
|
|
687
|
+
* - The feature compatibility status: whether the network supports EIP-1559,
|
|
688
|
+
* whether it does not, or whether it is unknown
|
|
689
|
+
*
|
|
690
|
+
* Note that it is possible for the current network to be switched while this
|
|
691
|
+
* method is running. If that is the case, it will exit early (as this method
|
|
692
|
+
* will also run for the new network).
|
|
693
|
+
*/
|
|
694
|
+
async #lookupSelectedNetwork() {
|
|
695
|
+
if (!this.#ethQuery) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
let networkChanged = false;
|
|
699
|
+
const listener = () => {
|
|
700
|
+
networkChanged = true;
|
|
701
|
+
try {
|
|
702
|
+
this.messenger.unsubscribe('NetworkController:networkDidChange', listener);
|
|
703
|
+
}
|
|
704
|
+
catch (error) {
|
|
705
|
+
// In theory, this `catch` should not be necessary given that this error
|
|
706
|
+
// would occur "inside" of the call to `#determineEIP1559Compatibility`
|
|
707
|
+
// below and so it should be caught by the `try`/`catch` below (it is
|
|
708
|
+
// impossible to reproduce in tests for that reason). However, somehow
|
|
709
|
+
// it occurs within Mobile and so we have to add our own `try`/`catch`
|
|
710
|
+
// here.
|
|
711
|
+
/* istanbul ignore next */
|
|
712
|
+
if (!(error instanceof Error) ||
|
|
713
|
+
error.message !==
|
|
714
|
+
'Subscription not found for event: NetworkController:networkDidChange') {
|
|
715
|
+
// Again, this error should not happen and is impossible to reproduce
|
|
716
|
+
// in tests.
|
|
717
|
+
/* istanbul ignore next */
|
|
718
|
+
throw error;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
this.messenger.subscribe('NetworkController:networkDidChange', listener);
|
|
723
|
+
const { isInfura, networkStatus, isEIP1559Compatible } = await this.#determineNetworkMetadata(this.state.selectedNetworkClientId);
|
|
724
|
+
if (networkChanged) {
|
|
725
|
+
// If the network has changed, then `lookupNetwork` either has been or is
|
|
726
|
+
// in the process of being called, so we don't need to go further.
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
try {
|
|
730
|
+
this.messenger.unsubscribe('NetworkController:networkDidChange', listener);
|
|
731
|
+
}
|
|
732
|
+
catch (error) {
|
|
733
|
+
if (!(error instanceof Error) ||
|
|
734
|
+
error.message !==
|
|
735
|
+
'Subscription not found for event: NetworkController:networkDidChange') {
|
|
736
|
+
throw error;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
this.#updateMetadataForNetwork(this.state.selectedNetworkClientId, {
|
|
740
|
+
networkStatus,
|
|
741
|
+
isEIP1559Compatible,
|
|
742
|
+
});
|
|
743
|
+
if (isInfura) {
|
|
744
|
+
if (networkStatus === NetworkStatus.Available) {
|
|
745
|
+
this.messenger.publish('NetworkController:infuraIsUnblocked');
|
|
746
|
+
}
|
|
747
|
+
else if (networkStatus === NetworkStatus.Blocked) {
|
|
748
|
+
this.messenger.publish('NetworkController:infuraIsBlocked');
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
// Always publish infuraIsUnblocked regardless of network status to
|
|
753
|
+
// prevent consumers from being stuck in a blocked state if they were
|
|
754
|
+
// previously connected to an Infura network that was blocked
|
|
755
|
+
this.messenger.publish('NetworkController:infuraIsUnblocked');
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Updates the metadata for the given network in state.
|
|
760
|
+
*
|
|
761
|
+
* @param networkClientId - The associated network client ID.
|
|
762
|
+
* @param metadata - The metadata to store in state.
|
|
763
|
+
* @param metadata.networkStatus - The network status to store in state.
|
|
764
|
+
* @param metadata.isEIP1559Compatible - The EIP-1559 compatibility status to
|
|
765
|
+
* store in state.
|
|
766
|
+
*/
|
|
767
|
+
#updateMetadataForNetwork(networkClientId, metadata) {
|
|
768
|
+
this.update((state) => {
|
|
769
|
+
state.networksMetadata[networkClientId] ??= {
|
|
770
|
+
status: NetworkStatus.Unknown,
|
|
771
|
+
EIPS: {},
|
|
772
|
+
};
|
|
773
|
+
const newMetadata = state.networksMetadata[networkClientId];
|
|
774
|
+
newMetadata.status = metadata.networkStatus;
|
|
775
|
+
if ('isEIP1559Compatible' in metadata) {
|
|
776
|
+
if (metadata.isEIP1559Compatible === undefined) {
|
|
777
|
+
delete newMetadata.EIPS[1559];
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
newMetadata.EIPS[1559] = metadata.isEIP1559Compatible;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
});
|
|
577
784
|
}
|
|
578
785
|
/**
|
|
579
786
|
* Convenience method to update provider network type settings.
|
|
@@ -602,8 +809,33 @@ export class NetworkController extends BaseController {
|
|
|
602
809
|
* network client ID.
|
|
603
810
|
*/
|
|
604
811
|
async setActiveNetwork(networkClientId, options = {}) {
|
|
605
|
-
|
|
606
|
-
|
|
812
|
+
this.#previouslySelectedNetworkClientId =
|
|
813
|
+
this.state.selectedNetworkClientId;
|
|
814
|
+
await this.#refreshNetwork(networkClientId, options);
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Fetches the latest block for the network.
|
|
818
|
+
*
|
|
819
|
+
* @param networkClientId - The networkClientId to fetch the correct provider against which to check the latest block. Defaults to the selectedNetworkClientId.
|
|
820
|
+
* @returns A promise that either resolves to the block header or null if
|
|
821
|
+
* there is no latest block, or rejects with an error.
|
|
822
|
+
*/
|
|
823
|
+
#getLatestBlock(networkClientId = this.state.selectedNetworkClientId) {
|
|
824
|
+
const networkClient = this.getNetworkClientById(networkClientId);
|
|
825
|
+
const ethQuery = new EthQuery(networkClient.provider);
|
|
826
|
+
return new Promise((resolve, reject) => {
|
|
827
|
+
ethQuery.sendAsync({ method: 'eth_getBlockByNumber', params: ['latest', false] }, (error, block) => {
|
|
828
|
+
if (error) {
|
|
829
|
+
// This error comes from JsonRpcEngine, we don't control it.
|
|
830
|
+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
831
|
+
reject(error);
|
|
832
|
+
}
|
|
833
|
+
else {
|
|
834
|
+
// TODO: Validate this type
|
|
835
|
+
resolve(block);
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
});
|
|
607
839
|
}
|
|
608
840
|
/**
|
|
609
841
|
* Determines whether the network supports EIP-1559 by checking whether the
|
|
@@ -618,14 +850,14 @@ export class NetworkController extends BaseController {
|
|
|
618
850
|
if (networkClientId) {
|
|
619
851
|
return this.get1559CompatibilityWithNetworkClientId(networkClientId);
|
|
620
852
|
}
|
|
621
|
-
if (!
|
|
853
|
+
if (!this.#ethQuery) {
|
|
622
854
|
return false;
|
|
623
855
|
}
|
|
624
856
|
const { EIPS } = this.state.networksMetadata[this.state.selectedNetworkClientId];
|
|
625
857
|
if (EIPS[1559] !== undefined) {
|
|
626
858
|
return EIPS[1559];
|
|
627
859
|
}
|
|
628
|
-
const isEIP1559Compatible = await
|
|
860
|
+
const isEIP1559Compatible = await this.#determineEIP1559Compatibility(this.state.selectedNetworkClientId);
|
|
629
861
|
this.update((state) => {
|
|
630
862
|
if (isEIP1559Compatible !== undefined) {
|
|
631
863
|
state.networksMetadata[state.selectedNetworkClientId].EIPS[1559] =
|
|
@@ -644,12 +876,28 @@ export class NetworkController extends BaseController {
|
|
|
644
876
|
// may want to include some 'freshness' value - something to make sure we refetch this from time to time
|
|
645
877
|
return EIPS[1559];
|
|
646
878
|
}
|
|
879
|
+
/**
|
|
880
|
+
* Retrieves and checks the latest block from the currently selected
|
|
881
|
+
* network; if the block has a `baseFeePerGas` property, then we know
|
|
882
|
+
* that the network supports EIP-1559; otherwise it doesn't.
|
|
883
|
+
*
|
|
884
|
+
* @param networkClientId - The networkClientId to fetch the correct provider against which to check 1559 compatibility
|
|
885
|
+
* @returns A promise that resolves to `true` if the network supports EIP-1559,
|
|
886
|
+
* `false` otherwise, or `undefined` if unable to retrieve the last block.
|
|
887
|
+
*/
|
|
888
|
+
async #determineEIP1559Compatibility(networkClientId) {
|
|
889
|
+
const latestBlock = await this.#getLatestBlock(networkClientId);
|
|
890
|
+
if (!latestBlock) {
|
|
891
|
+
return undefined;
|
|
892
|
+
}
|
|
893
|
+
return latestBlock.baseFeePerGas !== undefined;
|
|
894
|
+
}
|
|
647
895
|
/**
|
|
648
896
|
* Ensures that the provider and block tracker proxies are pointed to the
|
|
649
897
|
* currently selected network and refreshes the metadata for the
|
|
650
898
|
*/
|
|
651
899
|
async resetConnection() {
|
|
652
|
-
await
|
|
900
|
+
await this.#refreshNetwork(this.state.selectedNetworkClientId);
|
|
653
901
|
}
|
|
654
902
|
/**
|
|
655
903
|
* Returns the network configuration that has been filed under the given chain
|
|
@@ -669,7 +917,7 @@ export class NetworkController extends BaseController {
|
|
|
669
917
|
* @returns The network configuration if one exists, or undefined.
|
|
670
918
|
*/
|
|
671
919
|
getNetworkConfigurationByNetworkClientId(networkClientId) {
|
|
672
|
-
return
|
|
920
|
+
return this.#networkConfigurationsByNetworkClientId.get(networkClientId);
|
|
673
921
|
}
|
|
674
922
|
/**
|
|
675
923
|
* Creates and registers network clients for the collection of Infura and
|
|
@@ -684,8 +932,8 @@ export class NetworkController extends BaseController {
|
|
|
684
932
|
*/
|
|
685
933
|
addNetwork(fields) {
|
|
686
934
|
const { rpcEndpoints: setOfRpcEndpointFields } = fields;
|
|
687
|
-
const autoManagedNetworkClientRegistry =
|
|
688
|
-
|
|
935
|
+
const autoManagedNetworkClientRegistry = this.#ensureAutoManagedNetworkClientRegistryPopulated();
|
|
936
|
+
this.#validateNetworkFields({
|
|
689
937
|
mode: 'add',
|
|
690
938
|
networkFields: fields,
|
|
691
939
|
autoManagedNetworkClientRegistry,
|
|
@@ -702,17 +950,17 @@ export class NetworkController extends BaseController {
|
|
|
702
950
|
rpcEndpoint,
|
|
703
951
|
};
|
|
704
952
|
});
|
|
705
|
-
const newNetworkConfiguration =
|
|
953
|
+
const newNetworkConfiguration = this.#determineNetworkConfigurationToPersist({
|
|
706
954
|
networkFields: fields,
|
|
707
955
|
networkClientOperations,
|
|
708
956
|
});
|
|
709
|
-
|
|
957
|
+
this.#registerNetworkClientsAsNeeded({
|
|
710
958
|
networkFields: fields,
|
|
711
959
|
networkClientOperations,
|
|
712
960
|
autoManagedNetworkClientRegistry,
|
|
713
961
|
});
|
|
714
962
|
this.update((state) => {
|
|
715
|
-
|
|
963
|
+
this.#updateNetworkConfigurations({
|
|
716
964
|
state,
|
|
717
965
|
mode: 'add',
|
|
718
966
|
networkFields: fields,
|
|
@@ -753,8 +1001,8 @@ export class NetworkController extends BaseController {
|
|
|
753
1001
|
}
|
|
754
1002
|
const existingChainId = chainId;
|
|
755
1003
|
const { chainId: newChainId, rpcEndpoints: setOfNewRpcEndpointFields } = fields;
|
|
756
|
-
const autoManagedNetworkClientRegistry =
|
|
757
|
-
|
|
1004
|
+
const autoManagedNetworkClientRegistry = this.#ensureAutoManagedNetworkClientRegistryPopulated();
|
|
1005
|
+
this.#validateNetworkFields({
|
|
758
1006
|
mode: 'update',
|
|
759
1007
|
networkFields: fields,
|
|
760
1008
|
existingNetworkConfiguration,
|
|
@@ -862,7 +1110,7 @@ export class NetworkController extends BaseController {
|
|
|
862
1110
|
networkClientOperations.push(networkClientOperation);
|
|
863
1111
|
}
|
|
864
1112
|
}
|
|
865
|
-
const updatedNetworkConfiguration =
|
|
1113
|
+
const updatedNetworkConfiguration = this.#determineNetworkConfigurationToPersist({
|
|
866
1114
|
networkFields: fields,
|
|
867
1115
|
networkClientOperations,
|
|
868
1116
|
});
|
|
@@ -879,7 +1127,7 @@ export class NetworkController extends BaseController {
|
|
|
879
1127
|
})) {
|
|
880
1128
|
throw new Error(`Could not update network: Cannot update RPC endpoints in such a way that the selected network '${this.state.selectedNetworkClientId}' would be removed without a replacement. Choose a different RPC endpoint as the selected network via the \`replacementSelectedRpcEndpointIndex\` option.`);
|
|
881
1129
|
}
|
|
882
|
-
|
|
1130
|
+
this.#registerNetworkClientsAsNeeded({
|
|
883
1131
|
networkFields: fields,
|
|
884
1132
|
networkClientOperations,
|
|
885
1133
|
autoManagedNetworkClientRegistry,
|
|
@@ -905,7 +1153,7 @@ export class NetworkController extends BaseController {
|
|
|
905
1153
|
rpcEndpointToSelect.networkClientId !== this.state.selectedNetworkClientId) {
|
|
906
1154
|
await this.setActiveNetwork(rpcEndpointToSelect.networkClientId, {
|
|
907
1155
|
updateState: (state) => {
|
|
908
|
-
|
|
1156
|
+
this.#updateNetworkConfigurations({
|
|
909
1157
|
state,
|
|
910
1158
|
mode: 'update',
|
|
911
1159
|
networkFields: fields,
|
|
@@ -917,7 +1165,7 @@ export class NetworkController extends BaseController {
|
|
|
917
1165
|
}
|
|
918
1166
|
else {
|
|
919
1167
|
this.update((state) => {
|
|
920
|
-
|
|
1168
|
+
this.#updateNetworkConfigurations({
|
|
921
1169
|
state,
|
|
922
1170
|
mode: 'update',
|
|
923
1171
|
networkFields: fields,
|
|
@@ -926,7 +1174,7 @@ export class NetworkController extends BaseController {
|
|
|
926
1174
|
});
|
|
927
1175
|
});
|
|
928
1176
|
}
|
|
929
|
-
|
|
1177
|
+
this.#unregisterNetworkClientsAsNeeded({
|
|
930
1178
|
networkClientOperations,
|
|
931
1179
|
autoManagedNetworkClientRegistry,
|
|
932
1180
|
});
|
|
@@ -949,19 +1197,19 @@ export class NetworkController extends BaseController {
|
|
|
949
1197
|
if (existingNetworkConfiguration.rpcEndpoints.some((rpcEndpoint) => rpcEndpoint.networkClientId === this.state.selectedNetworkClientId)) {
|
|
950
1198
|
throw new Error(`Cannot remove the currently selected network`);
|
|
951
1199
|
}
|
|
952
|
-
const autoManagedNetworkClientRegistry =
|
|
1200
|
+
const autoManagedNetworkClientRegistry = this.#ensureAutoManagedNetworkClientRegistryPopulated();
|
|
953
1201
|
const networkClientOperations = existingNetworkConfiguration.rpcEndpoints.map((rpcEndpoint) => {
|
|
954
1202
|
return {
|
|
955
1203
|
type: 'remove',
|
|
956
1204
|
rpcEndpoint,
|
|
957
1205
|
};
|
|
958
1206
|
});
|
|
959
|
-
|
|
1207
|
+
this.#unregisterNetworkClientsAsNeeded({
|
|
960
1208
|
networkClientOperations,
|
|
961
1209
|
autoManagedNetworkClientRegistry,
|
|
962
1210
|
});
|
|
963
1211
|
this.update((state) => {
|
|
964
|
-
|
|
1212
|
+
this.#updateNetworkConfigurations({
|
|
965
1213
|
state,
|
|
966
1214
|
mode: 'remove',
|
|
967
1215
|
existingNetworkConfiguration,
|
|
@@ -980,7 +1228,7 @@ export class NetworkController extends BaseController {
|
|
|
980
1228
|
* to {@link resetConnection}.
|
|
981
1229
|
*/
|
|
982
1230
|
async rollbackToPreviousProvider() {
|
|
983
|
-
await
|
|
1231
|
+
await this.#refreshNetwork(this.#previouslySelectedNetworkClientId);
|
|
984
1232
|
}
|
|
985
1233
|
/**
|
|
986
1234
|
* Deactivates the controller, stopping any ongoing polling.
|
|
@@ -990,7 +1238,7 @@ export class NetworkController extends BaseController {
|
|
|
990
1238
|
// We're intentionally changing the signature of an extended method.
|
|
991
1239
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
992
1240
|
async destroy() {
|
|
993
|
-
await
|
|
1241
|
+
await this.#blockTrackerProxy?.destroy();
|
|
994
1242
|
}
|
|
995
1243
|
/**
|
|
996
1244
|
* Merges the given backup data into controller state.
|
|
@@ -1024,551 +1272,405 @@ export class NetworkController extends BaseController {
|
|
|
1024
1272
|
const { networkClientId } = networkConfiguration.rpcEndpoints[networkConfiguration.defaultRpcEndpointIndex];
|
|
1025
1273
|
return networkClientId;
|
|
1026
1274
|
}
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1275
|
+
/**
|
|
1276
|
+
* Ensure that the given fields which will be used to either add or update a
|
|
1277
|
+
* network are valid.
|
|
1278
|
+
*
|
|
1279
|
+
* @param args - The arguments.
|
|
1280
|
+
*/
|
|
1281
|
+
#validateNetworkFields(args) {
|
|
1282
|
+
const { mode, networkFields, autoManagedNetworkClientRegistry } = args;
|
|
1283
|
+
const existingNetworkConfiguration = 'existingNetworkConfiguration' in args
|
|
1284
|
+
? args.existingNetworkConfiguration
|
|
1285
|
+
: null;
|
|
1286
|
+
const errorMessagePrefix = mode === 'update' ? 'Could not update network' : 'Could not add network';
|
|
1287
|
+
if (!isStrictHexString(networkFields.chainId) ||
|
|
1288
|
+
!isSafeChainId(networkFields.chainId)) {
|
|
1289
|
+
throw new Error(`${errorMessagePrefix}: Invalid \`chainId\` '${networkFields.chainId}' (must start with "0x" and not exceed the maximum)`);
|
|
1040
1290
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
*
|
|
1047
|
-
* 1. Notifies subscribers via the messenger that the network is about to be
|
|
1048
|
-
* switched (and, really, that the global provider and block tracker proxies
|
|
1049
|
-
* will be re-pointed to a new network).
|
|
1050
|
-
* 2. Looks up a known and preinitialized network client matching the given
|
|
1051
|
-
* ID and uses it to re-point the aforementioned provider and block tracker
|
|
1052
|
-
* proxies.
|
|
1053
|
-
* 3. Notifies subscribers via the messenger that the network has switched.
|
|
1054
|
-
* 4. Captures metadata for the newly switched network in state.
|
|
1055
|
-
*
|
|
1056
|
-
* @param networkClientId - The ID of a network client that requests will be
|
|
1057
|
-
* routed through (either the name of an Infura network or the ID of a custom
|
|
1058
|
-
* network configuration).
|
|
1059
|
-
* @param options - Options for this method.
|
|
1060
|
-
* @param options.updateState - Allows for updating state.
|
|
1061
|
-
*/
|
|
1062
|
-
async function _NetworkController_refreshNetwork(networkClientId, options = {}) {
|
|
1063
|
-
this.messenger.publish('NetworkController:networkWillChange', this.state);
|
|
1064
|
-
__classPrivateFieldGet(this, _NetworkController_instances, "m", _NetworkController_applyNetworkSelection).call(this, networkClientId, options);
|
|
1065
|
-
this.messenger.publish('NetworkController:networkDidChange', this.state);
|
|
1066
|
-
await this.lookupNetwork();
|
|
1067
|
-
}, _NetworkController_determineNetworkMetadata =
|
|
1068
|
-
/**
|
|
1069
|
-
* Uses a request for the latest block to gather the following information on
|
|
1070
|
-
* the given network:
|
|
1071
|
-
*
|
|
1072
|
-
* - The connectivity status: whether it is available, geo-blocked (Infura
|
|
1073
|
-
* only), unavailable, or unknown
|
|
1074
|
-
* - The capabilities status: whether it supports EIP-1559, whether it does
|
|
1075
|
-
* not, or whether it is unknown
|
|
1076
|
-
*
|
|
1077
|
-
* @param networkClientId - The ID of the network client to inspect.
|
|
1078
|
-
* If no ID is provided, uses the currently selected network.
|
|
1079
|
-
* @returns The resulting metadata for the network.
|
|
1080
|
-
*/
|
|
1081
|
-
async function _NetworkController_determineNetworkMetadata(networkClientId) {
|
|
1082
|
-
const networkClient = this.getNetworkClientById(networkClientId);
|
|
1083
|
-
const isInfura = networkClient.configuration.type === NetworkClientType.Infura;
|
|
1084
|
-
let networkStatus;
|
|
1085
|
-
let isEIP1559Compatible;
|
|
1086
|
-
try {
|
|
1087
|
-
isEIP1559Compatible =
|
|
1088
|
-
await __classPrivateFieldGet(this, _NetworkController_instances, "m", _NetworkController_determineEIP1559Compatibility).call(this, networkClientId);
|
|
1089
|
-
networkStatus = NetworkStatus.Available;
|
|
1090
|
-
}
|
|
1091
|
-
catch (error) {
|
|
1092
|
-
debugLog('NetworkController: lookupNetwork: ', error);
|
|
1093
|
-
if (isErrorWithCode(error)) {
|
|
1094
|
-
let responseBody;
|
|
1095
|
-
if (isInfura &&
|
|
1096
|
-
hasProperty(error, 'message') &&
|
|
1097
|
-
typeof error.message === 'string') {
|
|
1098
|
-
try {
|
|
1099
|
-
responseBody = JSON.parse(error.message);
|
|
1291
|
+
if (networkFields.chainId !== existingNetworkConfiguration?.chainId) {
|
|
1292
|
+
const existingNetworkConfigurationViaChainId = this.state.networkConfigurationsByChainId[networkFields.chainId];
|
|
1293
|
+
if (existingNetworkConfigurationViaChainId !== undefined) {
|
|
1294
|
+
if (existingNetworkConfiguration === null) {
|
|
1295
|
+
throw new Error(`Could not add network for chain ${args.networkFields.chainId} as another network for that chain already exists ('${existingNetworkConfigurationViaChainId.name}')`);
|
|
1100
1296
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
__classPrivateFieldGet(this, _NetworkController_log, "f")?.warn('NetworkController: lookupNetwork: json parse error: ', error);
|
|
1297
|
+
else {
|
|
1298
|
+
throw new Error(`Cannot move network from chain ${existingNetworkConfiguration.chainId} to ${networkFields.chainId} as another network for that chain already exists ('${existingNetworkConfigurationViaChainId.name}')`);
|
|
1104
1299
|
}
|
|
1105
1300
|
}
|
|
1106
|
-
if (isPlainObject(responseBody) &&
|
|
1107
|
-
responseBody.error === INFURA_BLOCKED_KEY) {
|
|
1108
|
-
networkStatus = NetworkStatus.Blocked;
|
|
1109
|
-
}
|
|
1110
|
-
else if (error.code === errorCodes.rpc.internal) {
|
|
1111
|
-
networkStatus = NetworkStatus.Unknown;
|
|
1112
|
-
__classPrivateFieldGet(this, _NetworkController_log, "f")?.warn('NetworkController: lookupNetwork: rpc internal error: ', error);
|
|
1113
|
-
}
|
|
1114
|
-
else {
|
|
1115
|
-
networkStatus = NetworkStatus.Unavailable;
|
|
1116
|
-
__classPrivateFieldGet(this, _NetworkController_log, "f")?.warn('NetworkController: lookupNetwork: ', error);
|
|
1117
|
-
}
|
|
1118
1301
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1302
|
+
const isInvalidDefaultBlockExplorerUrlIndex = networkFields.blockExplorerUrls.length > 0
|
|
1303
|
+
? networkFields.defaultBlockExplorerUrlIndex === undefined ||
|
|
1304
|
+
networkFields.blockExplorerUrls[networkFields.defaultBlockExplorerUrlIndex] === undefined
|
|
1305
|
+
: networkFields.defaultBlockExplorerUrlIndex !== undefined;
|
|
1306
|
+
if (isInvalidDefaultBlockExplorerUrlIndex) {
|
|
1307
|
+
throw new Error(`${errorMessagePrefix}: \`defaultBlockExplorerUrlIndex\` must refer to an entry in \`blockExplorerUrls\``);
|
|
1123
1308
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
}, _NetworkController_lookupGivenNetwork =
|
|
1127
|
-
/**
|
|
1128
|
-
* Uses a request for the latest block to gather the following information on
|
|
1129
|
-
* the given network, persisting it to state:
|
|
1130
|
-
*
|
|
1131
|
-
* - The connectivity status: whether the network is available, geo-blocked
|
|
1132
|
-
* (Infura only), unavailable, or unknown
|
|
1133
|
-
* - The feature compatibility status: whether the network supports EIP-1559,
|
|
1134
|
-
* whether it does not, or whether it is unknown
|
|
1135
|
-
*
|
|
1136
|
-
* @param networkClientId - The ID of the network client to inspect.
|
|
1137
|
-
*/
|
|
1138
|
-
async function _NetworkController_lookupGivenNetwork(networkClientId) {
|
|
1139
|
-
const { networkStatus, isEIP1559Compatible } = await __classPrivateFieldGet(this, _NetworkController_instances, "m", _NetworkController_determineNetworkMetadata).call(this, networkClientId);
|
|
1140
|
-
__classPrivateFieldGet(this, _NetworkController_instances, "m", _NetworkController_updateMetadataForNetwork).call(this, networkClientId, {
|
|
1141
|
-
networkStatus,
|
|
1142
|
-
isEIP1559Compatible,
|
|
1143
|
-
});
|
|
1144
|
-
}, _NetworkController_lookupSelectedNetwork =
|
|
1145
|
-
/**
|
|
1146
|
-
* Uses a request for the latest block to gather the following information on
|
|
1147
|
-
* the currently selected network, persisting it to state:
|
|
1148
|
-
*
|
|
1149
|
-
* - The connectivity status: whether the network is available, geo-blocked
|
|
1150
|
-
* (Infura only), unavailable, or unknown
|
|
1151
|
-
* - The feature compatibility status: whether the network supports EIP-1559,
|
|
1152
|
-
* whether it does not, or whether it is unknown
|
|
1153
|
-
*
|
|
1154
|
-
* Note that it is possible for the current network to be switched while this
|
|
1155
|
-
* method is running. If that is the case, it will exit early (as this method
|
|
1156
|
-
* will also run for the new network).
|
|
1157
|
-
*/
|
|
1158
|
-
async function _NetworkController_lookupSelectedNetwork() {
|
|
1159
|
-
if (!__classPrivateFieldGet(this, _NetworkController_ethQuery, "f")) {
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
let networkChanged = false;
|
|
1163
|
-
const listener = () => {
|
|
1164
|
-
networkChanged = true;
|
|
1165
|
-
try {
|
|
1166
|
-
this.messenger.unsubscribe('NetworkController:networkDidChange', listener);
|
|
1309
|
+
if (networkFields.rpcEndpoints.length === 0) {
|
|
1310
|
+
throw new Error(`${errorMessagePrefix}: \`rpcEndpoints\` must be a non-empty array`);
|
|
1167
1311
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1312
|
+
for (const rpcEndpointFields of networkFields.rpcEndpoints) {
|
|
1313
|
+
if (!isValidUrl(rpcEndpointFields.url)) {
|
|
1314
|
+
throw new Error(`${errorMessagePrefix}: An entry in \`rpcEndpoints\` has invalid URL '${rpcEndpointFields.url}'`);
|
|
1315
|
+
}
|
|
1316
|
+
const networkClientId = 'networkClientId' in rpcEndpointFields
|
|
1317
|
+
? rpcEndpointFields.networkClientId
|
|
1318
|
+
: undefined;
|
|
1319
|
+
if (mode === 'update' &&
|
|
1320
|
+
networkClientId !== undefined &&
|
|
1321
|
+
rpcEndpointFields.type === RpcEndpointType.Custom &&
|
|
1322
|
+
!Object.values(autoManagedNetworkClientRegistry).some((networkClientsById) => networkClientId in networkClientsById)) {
|
|
1323
|
+
throw new Error(`${errorMessagePrefix}: RPC endpoint '${rpcEndpointFields.url}' refers to network client '${networkClientId}' that does not exist`);
|
|
1324
|
+
}
|
|
1325
|
+
if (networkFields.rpcEndpoints.some((otherRpcEndpointFields) => otherRpcEndpointFields !== rpcEndpointFields &&
|
|
1326
|
+
URI.equal(otherRpcEndpointFields.url, rpcEndpointFields.url))) {
|
|
1327
|
+
throw new Error(`${errorMessagePrefix}: Each entry in rpcEndpoints must have a unique URL`);
|
|
1328
|
+
}
|
|
1329
|
+
const networkConfigurationsForOtherChains = Object.values(this.state.networkConfigurationsByChainId).filter((networkConfiguration) => existingNetworkConfiguration
|
|
1330
|
+
? networkConfiguration.chainId !==
|
|
1331
|
+
existingNetworkConfiguration.chainId
|
|
1332
|
+
: true);
|
|
1333
|
+
for (const networkConfiguration of networkConfigurationsForOtherChains) {
|
|
1334
|
+
const rpcEndpoint = networkConfiguration.rpcEndpoints.find((existingRpcEndpoint) => URI.equal(rpcEndpointFields.url, existingRpcEndpoint.url));
|
|
1335
|
+
if (rpcEndpoint) {
|
|
1336
|
+
if (mode === 'update') {
|
|
1337
|
+
throw new Error(`Could not update network to point to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`);
|
|
1338
|
+
}
|
|
1339
|
+
else {
|
|
1340
|
+
throw new Error(`Could not add network that points to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1183
1343
|
}
|
|
1184
1344
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
if (networkChanged) {
|
|
1189
|
-
// If the network has changed, then `lookupNetwork` either has been or is
|
|
1190
|
-
// in the process of being called, so we don't need to go further.
|
|
1191
|
-
return;
|
|
1192
|
-
}
|
|
1193
|
-
try {
|
|
1194
|
-
this.messenger.unsubscribe('NetworkController:networkDidChange', listener);
|
|
1195
|
-
}
|
|
1196
|
-
catch (error) {
|
|
1197
|
-
if (!(error instanceof Error) ||
|
|
1198
|
-
error.message !==
|
|
1199
|
-
'Subscription not found for event: NetworkController:networkDidChange') {
|
|
1200
|
-
throw error;
|
|
1345
|
+
if ([...new Set(networkFields.rpcEndpoints)].length <
|
|
1346
|
+
networkFields.rpcEndpoints.length) {
|
|
1347
|
+
throw new Error(`${errorMessagePrefix}: Each entry in rpcEndpoints must be unique`);
|
|
1201
1348
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
this.messenger.publish('NetworkController:infuraIsUnblocked');
|
|
1349
|
+
const networkClientIds = networkFields.rpcEndpoints
|
|
1350
|
+
.map((rpcEndpoint) => 'networkClientId' in rpcEndpoint
|
|
1351
|
+
? rpcEndpoint.networkClientId
|
|
1352
|
+
: undefined)
|
|
1353
|
+
.filter((networkClientId) => networkClientId !== undefined);
|
|
1354
|
+
if ([...new Set(networkClientIds)].length < networkClientIds.length) {
|
|
1355
|
+
throw new Error(`${errorMessagePrefix}: Each entry in rpcEndpoints must have a unique networkClientId`);
|
|
1210
1356
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1357
|
+
const infuraRpcEndpoints = networkFields.rpcEndpoints.filter((rpcEndpointFields) => rpcEndpointFields.type === RpcEndpointType.Infura);
|
|
1358
|
+
if (infuraRpcEndpoints.length > 1) {
|
|
1359
|
+
throw new Error(`${errorMessagePrefix}: There cannot be more than one Infura RPC endpoint`);
|
|
1213
1360
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
// prevent consumers from being stuck in a blocked state if they were
|
|
1218
|
-
// previously connected to an Infura network that was blocked
|
|
1219
|
-
this.messenger.publish('NetworkController:infuraIsUnblocked');
|
|
1220
|
-
}
|
|
1221
|
-
}, _NetworkController_updateMetadataForNetwork = function _NetworkController_updateMetadataForNetwork(networkClientId, metadata) {
|
|
1222
|
-
this.update((state) => {
|
|
1223
|
-
var _a;
|
|
1224
|
-
(_a = state.networksMetadata)[networkClientId] ?? (_a[networkClientId] = {
|
|
1225
|
-
status: NetworkStatus.Unknown,
|
|
1226
|
-
EIPS: {},
|
|
1227
|
-
});
|
|
1228
|
-
const newMetadata = state.networksMetadata[networkClientId];
|
|
1229
|
-
newMetadata.status = metadata.networkStatus;
|
|
1230
|
-
if ('isEIP1559Compatible' in metadata) {
|
|
1231
|
-
if (metadata.isEIP1559Compatible === undefined) {
|
|
1232
|
-
delete newMetadata.EIPS[1559];
|
|
1233
|
-
}
|
|
1234
|
-
else {
|
|
1235
|
-
newMetadata.EIPS[1559] = metadata.isEIP1559Compatible;
|
|
1236
|
-
}
|
|
1361
|
+
if (networkFields.rpcEndpoints[networkFields.defaultRpcEndpointIndex] ===
|
|
1362
|
+
undefined) {
|
|
1363
|
+
throw new Error(`${errorMessagePrefix}: \`defaultRpcEndpointIndex\` must refer to an entry in \`rpcEndpoints\``);
|
|
1237
1364
|
}
|
|
1238
|
-
});
|
|
1239
|
-
}, _NetworkController_getLatestBlock = function _NetworkController_getLatestBlock(networkClientId = this.state.selectedNetworkClientId) {
|
|
1240
|
-
const networkClient = this.getNetworkClientById(networkClientId);
|
|
1241
|
-
const ethQuery = new EthQuery(networkClient.provider);
|
|
1242
|
-
return new Promise((resolve, reject) => {
|
|
1243
|
-
ethQuery.sendAsync({ method: 'eth_getBlockByNumber', params: ['latest', false] }, (error, block) => {
|
|
1244
|
-
if (error) {
|
|
1245
|
-
// This error comes from JsonRpcEngine, we don't control it.
|
|
1246
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
1247
|
-
reject(error);
|
|
1248
|
-
}
|
|
1249
|
-
else {
|
|
1250
|
-
// TODO: Validate this type
|
|
1251
|
-
resolve(block);
|
|
1252
|
-
}
|
|
1253
|
-
});
|
|
1254
|
-
});
|
|
1255
|
-
}, _NetworkController_determineEIP1559Compatibility =
|
|
1256
|
-
/**
|
|
1257
|
-
* Retrieves and checks the latest block from the currently selected
|
|
1258
|
-
* network; if the block has a `baseFeePerGas` property, then we know
|
|
1259
|
-
* that the network supports EIP-1559; otherwise it doesn't.
|
|
1260
|
-
*
|
|
1261
|
-
* @param networkClientId - The networkClientId to fetch the correct provider against which to check 1559 compatibility
|
|
1262
|
-
* @returns A promise that resolves to `true` if the network supports EIP-1559,
|
|
1263
|
-
* `false` otherwise, or `undefined` if unable to retrieve the last block.
|
|
1264
|
-
*/
|
|
1265
|
-
async function _NetworkController_determineEIP1559Compatibility(networkClientId) {
|
|
1266
|
-
const latestBlock = await __classPrivateFieldGet(this, _NetworkController_instances, "m", _NetworkController_getLatestBlock).call(this, networkClientId);
|
|
1267
|
-
if (!latestBlock) {
|
|
1268
|
-
return undefined;
|
|
1269
1365
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1366
|
+
/**
|
|
1367
|
+
* Constructs a network configuration that will be persisted to state when
|
|
1368
|
+
* adding or updating a network.
|
|
1369
|
+
*
|
|
1370
|
+
* @param args - The arguments to this function.
|
|
1371
|
+
* @param args.networkFields - The fields used to add or update a network.
|
|
1372
|
+
* @param args.networkClientOperations - Operations which were calculated for
|
|
1373
|
+
* updating the network client registry but which also map back to RPC
|
|
1374
|
+
* endpoints (and so can be used to save those RPC endpoints).
|
|
1375
|
+
* @returns The network configuration to persist.
|
|
1376
|
+
*/
|
|
1377
|
+
#determineNetworkConfigurationToPersist({ networkFields, networkClientOperations, }) {
|
|
1378
|
+
const rpcEndpointsToPersist = networkClientOperations
|
|
1379
|
+
.filter((networkClientOperation) => {
|
|
1380
|
+
return (networkClientOperation.type === 'add' ||
|
|
1381
|
+
networkClientOperation.type === 'noop');
|
|
1382
|
+
})
|
|
1383
|
+
.map((networkClientOperation) => networkClientOperation.rpcEndpoint)
|
|
1384
|
+
.concat(networkClientOperations
|
|
1385
|
+
.filter((networkClientOperation) => {
|
|
1386
|
+
return networkClientOperation.type === 'replace';
|
|
1387
|
+
})
|
|
1388
|
+
.map((networkClientOperation) => networkClientOperation.newRpcEndpoint));
|
|
1389
|
+
return { ...networkFields, rpcEndpoints: rpcEndpointsToPersist };
|
|
1280
1390
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1391
|
+
/**
|
|
1392
|
+
* Creates and registers network clients using the given operations calculated
|
|
1393
|
+
* as a part of adding or updating a network.
|
|
1394
|
+
*
|
|
1395
|
+
* @param args - The arguments to this function.
|
|
1396
|
+
* @param args.networkFields - The fields used to add or update a network.
|
|
1397
|
+
* @param args.networkClientOperations - Dictate which network clients need to
|
|
1398
|
+
* be created.
|
|
1399
|
+
* @param args.autoManagedNetworkClientRegistry - The network client registry
|
|
1400
|
+
* to update.
|
|
1401
|
+
*/
|
|
1402
|
+
#registerNetworkClientsAsNeeded({ networkFields, networkClientOperations, autoManagedNetworkClientRegistry, }) {
|
|
1403
|
+
const addedRpcEndpoints = networkClientOperations
|
|
1404
|
+
.filter((networkClientOperation) => {
|
|
1405
|
+
return networkClientOperation.type === 'add';
|
|
1406
|
+
})
|
|
1407
|
+
.map((networkClientOperation) => networkClientOperation.rpcEndpoint)
|
|
1408
|
+
.concat(networkClientOperations
|
|
1409
|
+
.filter((networkClientOperation) => {
|
|
1410
|
+
return networkClientOperation.type === 'replace';
|
|
1411
|
+
})
|
|
1412
|
+
.map((networkClientOperation) => networkClientOperation.newRpcEndpoint));
|
|
1413
|
+
const defaultFailoverUrls = this.#failoverUrls?.[networkFields.chainId];
|
|
1414
|
+
for (const addedRpcEndpoint of addedRpcEndpoints) {
|
|
1415
|
+
if (addedRpcEndpoint.type === RpcEndpointType.Infura) {
|
|
1416
|
+
autoManagedNetworkClientRegistry[NetworkClientType.Infura][addedRpcEndpoint.networkClientId] = createAutoManagedNetworkClient({
|
|
1417
|
+
networkClientId: addedRpcEndpoint.networkClientId,
|
|
1418
|
+
networkClientConfiguration: {
|
|
1419
|
+
type: NetworkClientType.Infura,
|
|
1420
|
+
chainId: networkFields.chainId,
|
|
1421
|
+
network: addedRpcEndpoint.networkClientId,
|
|
1422
|
+
failoverRpcUrls: defaultFailoverUrls ?? addedRpcEndpoint.failoverUrls,
|
|
1423
|
+
infuraProjectId: this.#infuraProjectId,
|
|
1424
|
+
ticker: networkFields.nativeCurrency,
|
|
1425
|
+
},
|
|
1426
|
+
getRpcServiceOptions: this.#getRpcServiceOptions,
|
|
1427
|
+
getBlockTrackerOptions: this.#getBlockTrackerOptions,
|
|
1428
|
+
messenger: this.messenger,
|
|
1429
|
+
rpcFailoverMode: this.#rpcFailoverMode,
|
|
1430
|
+
logger: this.#log,
|
|
1431
|
+
});
|
|
1286
1432
|
}
|
|
1287
1433
|
else {
|
|
1288
|
-
|
|
1434
|
+
autoManagedNetworkClientRegistry[NetworkClientType.Custom][addedRpcEndpoint.networkClientId] = createAutoManagedNetworkClient({
|
|
1435
|
+
networkClientId: addedRpcEndpoint.networkClientId,
|
|
1436
|
+
networkClientConfiguration: {
|
|
1437
|
+
type: NetworkClientType.Custom,
|
|
1438
|
+
chainId: networkFields.chainId,
|
|
1439
|
+
failoverRpcUrls: defaultFailoverUrls ?? addedRpcEndpoint.failoverUrls,
|
|
1440
|
+
rpcUrl: addedRpcEndpoint.url,
|
|
1441
|
+
ticker: networkFields.nativeCurrency,
|
|
1442
|
+
},
|
|
1443
|
+
getRpcServiceOptions: this.#getRpcServiceOptions,
|
|
1444
|
+
getBlockTrackerOptions: this.#getBlockTrackerOptions,
|
|
1445
|
+
messenger: this.messenger,
|
|
1446
|
+
rpcFailoverMode: this.#rpcFailoverMode,
|
|
1447
|
+
logger: this.#log,
|
|
1448
|
+
});
|
|
1289
1449
|
}
|
|
1290
1450
|
}
|
|
1291
1451
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
throw new Error(`${errorMessagePrefix}: Each entry in rpcEndpoints must have a unique URL`);
|
|
1318
|
-
}
|
|
1319
|
-
const networkConfigurationsForOtherChains = Object.values(this.state.networkConfigurationsByChainId).filter((networkConfiguration) => existingNetworkConfiguration
|
|
1320
|
-
? networkConfiguration.chainId !==
|
|
1321
|
-
existingNetworkConfiguration.chainId
|
|
1322
|
-
: true);
|
|
1323
|
-
for (const networkConfiguration of networkConfigurationsForOtherChains) {
|
|
1324
|
-
const rpcEndpoint = networkConfiguration.rpcEndpoints.find((existingRpcEndpoint) => URI.equal(rpcEndpointFields.url, existingRpcEndpoint.url));
|
|
1325
|
-
if (rpcEndpoint) {
|
|
1326
|
-
if (mode === 'update') {
|
|
1327
|
-
throw new Error(`Could not update network to point to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`);
|
|
1328
|
-
}
|
|
1329
|
-
else {
|
|
1330
|
-
throw new Error(`Could not add network that points to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1452
|
+
/**
|
|
1453
|
+
* Destroys and removes network clients using the given operations calculated
|
|
1454
|
+
* as a part of updating or removing a network.
|
|
1455
|
+
*
|
|
1456
|
+
* @param args - The arguments to this function.
|
|
1457
|
+
* @param args.networkClientOperations - Dictate which network clients to
|
|
1458
|
+
* remove.
|
|
1459
|
+
* @param args.autoManagedNetworkClientRegistry - The network client registry
|
|
1460
|
+
* to update.
|
|
1461
|
+
*/
|
|
1462
|
+
#unregisterNetworkClientsAsNeeded({ networkClientOperations, autoManagedNetworkClientRegistry, }) {
|
|
1463
|
+
const removedRpcEndpoints = networkClientOperations
|
|
1464
|
+
.filter((networkClientOperation) => {
|
|
1465
|
+
return networkClientOperation.type === 'remove';
|
|
1466
|
+
})
|
|
1467
|
+
.map((networkClientOperation) => networkClientOperation.rpcEndpoint)
|
|
1468
|
+
.concat(networkClientOperations
|
|
1469
|
+
.filter((networkClientOperation) => {
|
|
1470
|
+
return networkClientOperation.type === 'replace';
|
|
1471
|
+
})
|
|
1472
|
+
.map((networkClientOperation) => networkClientOperation.oldRpcEndpoint));
|
|
1473
|
+
for (const rpcEndpoint of removedRpcEndpoints) {
|
|
1474
|
+
const networkClient = this.getNetworkClientById(rpcEndpoint.networkClientId);
|
|
1475
|
+
networkClient.destroy();
|
|
1476
|
+
delete autoManagedNetworkClientRegistry[networkClient.configuration.type][rpcEndpoint.networkClientId];
|
|
1333
1477
|
}
|
|
1334
1478
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
throw new Error(`${errorMessagePrefix}: \`defaultRpcEndpointIndex\` must refer to an entry in \`rpcEndpoints\``);
|
|
1354
|
-
}
|
|
1355
|
-
}, _NetworkController_determineNetworkConfigurationToPersist = function _NetworkController_determineNetworkConfigurationToPersist({ networkFields, networkClientOperations, }) {
|
|
1356
|
-
const rpcEndpointsToPersist = networkClientOperations
|
|
1357
|
-
.filter((networkClientOperation) => {
|
|
1358
|
-
return (networkClientOperation.type === 'add' ||
|
|
1359
|
-
networkClientOperation.type === 'noop');
|
|
1360
|
-
})
|
|
1361
|
-
.map((networkClientOperation) => networkClientOperation.rpcEndpoint)
|
|
1362
|
-
.concat(networkClientOperations
|
|
1363
|
-
.filter((networkClientOperation) => {
|
|
1364
|
-
return networkClientOperation.type === 'replace';
|
|
1365
|
-
})
|
|
1366
|
-
.map((networkClientOperation) => networkClientOperation.newRpcEndpoint));
|
|
1367
|
-
return { ...networkFields, rpcEndpoints: rpcEndpointsToPersist };
|
|
1368
|
-
}, _NetworkController_registerNetworkClientsAsNeeded = function _NetworkController_registerNetworkClientsAsNeeded({ networkFields, networkClientOperations, autoManagedNetworkClientRegistry, }) {
|
|
1369
|
-
const addedRpcEndpoints = networkClientOperations
|
|
1370
|
-
.filter((networkClientOperation) => {
|
|
1371
|
-
return networkClientOperation.type === 'add';
|
|
1372
|
-
})
|
|
1373
|
-
.map((networkClientOperation) => networkClientOperation.rpcEndpoint)
|
|
1374
|
-
.concat(networkClientOperations
|
|
1375
|
-
.filter((networkClientOperation) => {
|
|
1376
|
-
return networkClientOperation.type === 'replace';
|
|
1377
|
-
})
|
|
1378
|
-
.map((networkClientOperation) => networkClientOperation.newRpcEndpoint));
|
|
1379
|
-
const defaultFailoverUrls = __classPrivateFieldGet(this, _NetworkController_failoverUrls, "f")?.[networkFields.chainId];
|
|
1380
|
-
for (const addedRpcEndpoint of addedRpcEndpoints) {
|
|
1381
|
-
if (addedRpcEndpoint.type === RpcEndpointType.Infura) {
|
|
1382
|
-
autoManagedNetworkClientRegistry[NetworkClientType.Infura][addedRpcEndpoint.networkClientId] = createAutoManagedNetworkClient({
|
|
1383
|
-
networkClientId: addedRpcEndpoint.networkClientId,
|
|
1384
|
-
networkClientConfiguration: {
|
|
1385
|
-
type: NetworkClientType.Infura,
|
|
1386
|
-
chainId: networkFields.chainId,
|
|
1387
|
-
network: addedRpcEndpoint.networkClientId,
|
|
1388
|
-
failoverRpcUrls: defaultFailoverUrls ?? addedRpcEndpoint.failoverUrls,
|
|
1389
|
-
infuraProjectId: __classPrivateFieldGet(this, _NetworkController_infuraProjectId, "f"),
|
|
1390
|
-
ticker: networkFields.nativeCurrency,
|
|
1391
|
-
},
|
|
1392
|
-
getRpcServiceOptions: __classPrivateFieldGet(this, _NetworkController_getRpcServiceOptions, "f"),
|
|
1393
|
-
getBlockTrackerOptions: __classPrivateFieldGet(this, _NetworkController_getBlockTrackerOptions, "f"),
|
|
1394
|
-
messenger: this.messenger,
|
|
1395
|
-
rpcFailoverMode: __classPrivateFieldGet(this, _NetworkController_rpcFailoverMode, "f"),
|
|
1396
|
-
logger: __classPrivateFieldGet(this, _NetworkController_log, "f"),
|
|
1397
|
-
});
|
|
1479
|
+
/**
|
|
1480
|
+
* Updates `networkConfigurationsByChainId` in state depending on whether a
|
|
1481
|
+
* network is being added, updated, or removed.
|
|
1482
|
+
*
|
|
1483
|
+
* - The existing network configuration will be removed when a network is
|
|
1484
|
+
* being filed under a different chain or removed.
|
|
1485
|
+
* - A network configuration will be stored when a network is being added or
|
|
1486
|
+
* when a network is being updated.
|
|
1487
|
+
*
|
|
1488
|
+
* @param args - The arguments to this function.
|
|
1489
|
+
*/
|
|
1490
|
+
#updateNetworkConfigurations(args) {
|
|
1491
|
+
const { state, mode } = args;
|
|
1492
|
+
if (mode === 'remove' ||
|
|
1493
|
+
(mode === 'update' &&
|
|
1494
|
+
args.networkFields.chainId !==
|
|
1495
|
+
args.existingNetworkConfiguration.chainId)) {
|
|
1496
|
+
delete state.networkConfigurationsByChainId[args.existingNetworkConfiguration.chainId];
|
|
1398
1497
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
failoverRpcUrls: defaultFailoverUrls ?? addedRpcEndpoint.failoverUrls,
|
|
1406
|
-
rpcUrl: addedRpcEndpoint.url,
|
|
1407
|
-
ticker: networkFields.nativeCurrency,
|
|
1408
|
-
},
|
|
1409
|
-
getRpcServiceOptions: __classPrivateFieldGet(this, _NetworkController_getRpcServiceOptions, "f"),
|
|
1410
|
-
getBlockTrackerOptions: __classPrivateFieldGet(this, _NetworkController_getBlockTrackerOptions, "f"),
|
|
1411
|
-
messenger: this.messenger,
|
|
1412
|
-
rpcFailoverMode: __classPrivateFieldGet(this, _NetworkController_rpcFailoverMode, "f"),
|
|
1413
|
-
logger: __classPrivateFieldGet(this, _NetworkController_log, "f"),
|
|
1414
|
-
});
|
|
1498
|
+
if (mode === 'add' || mode === 'update') {
|
|
1499
|
+
if (!deepEqual(state.networkConfigurationsByChainId[args.networkFields.chainId], args.networkConfigurationToPersist)) {
|
|
1500
|
+
args.networkConfigurationToPersist.lastUpdatedAt = Date.now();
|
|
1501
|
+
}
|
|
1502
|
+
state.networkConfigurationsByChainId[args.networkFields.chainId] =
|
|
1503
|
+
args.networkConfigurationToPersist;
|
|
1415
1504
|
}
|
|
1505
|
+
this.#networkConfigurationsByNetworkClientId =
|
|
1506
|
+
buildNetworkConfigurationsByNetworkClientId(cloneDeep(state.networkConfigurationsByChainId));
|
|
1416
1507
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
for (const rpcEndpoint of removedRpcEndpoints) {
|
|
1429
|
-
const networkClient = this.getNetworkClientById(rpcEndpoint.networkClientId);
|
|
1430
|
-
networkClient.destroy();
|
|
1431
|
-
delete autoManagedNetworkClientRegistry[networkClient.configuration.type][rpcEndpoint.networkClientId];
|
|
1432
|
-
}
|
|
1433
|
-
}, _NetworkController_updateNetworkConfigurations = function _NetworkController_updateNetworkConfigurations(args) {
|
|
1434
|
-
const { state, mode } = args;
|
|
1435
|
-
if (mode === 'remove' ||
|
|
1436
|
-
(mode === 'update' &&
|
|
1437
|
-
args.networkFields.chainId !==
|
|
1438
|
-
args.existingNetworkConfiguration.chainId)) {
|
|
1439
|
-
delete state.networkConfigurationsByChainId[args.existingNetworkConfiguration.chainId];
|
|
1440
|
-
}
|
|
1441
|
-
if (mode === 'add' || mode === 'update') {
|
|
1442
|
-
if (!deepEqual(state.networkConfigurationsByChainId[args.networkFields.chainId], args.networkConfigurationToPersist)) {
|
|
1443
|
-
args.networkConfigurationToPersist.lastUpdatedAt = Date.now();
|
|
1444
|
-
}
|
|
1445
|
-
state.networkConfigurationsByChainId[args.networkFields.chainId] =
|
|
1446
|
-
args.networkConfigurationToPersist;
|
|
1508
|
+
/**
|
|
1509
|
+
* Before accessing or switching the network, the registry of network clients
|
|
1510
|
+
* needs to be populated. Otherwise, `#applyNetworkSelection` and
|
|
1511
|
+
* `getNetworkClientRegistry` will throw an error. This method checks to see if the
|
|
1512
|
+
* population step has happened yet, and if not, makes it happen.
|
|
1513
|
+
*
|
|
1514
|
+
* @returns The populated network client registry.
|
|
1515
|
+
*/
|
|
1516
|
+
#ensureAutoManagedNetworkClientRegistryPopulated() {
|
|
1517
|
+
return (this.#autoManagedNetworkClientRegistry ??=
|
|
1518
|
+
this.#createAutoManagedNetworkClientRegistry());
|
|
1447
1519
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
const
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1520
|
+
/**
|
|
1521
|
+
* Constructs the registry of network clients based on the set of default
|
|
1522
|
+
* and custom networks in state.
|
|
1523
|
+
*
|
|
1524
|
+
* @returns The network clients keyed by ID.
|
|
1525
|
+
*/
|
|
1526
|
+
#createAutoManagedNetworkClientRegistry() {
|
|
1527
|
+
const chainIds = knownKeysOf(this.state.networkConfigurationsByChainId);
|
|
1528
|
+
const networkClientsWithIds = chainIds.flatMap((chainId) => {
|
|
1529
|
+
const networkConfiguration = this.state.networkConfigurationsByChainId[chainId];
|
|
1530
|
+
const defaultFailoverUrls = this.#failoverUrls?.[chainId];
|
|
1531
|
+
return networkConfiguration.rpcEndpoints.map((rpcEndpoint) => {
|
|
1532
|
+
if (rpcEndpoint.type === RpcEndpointType.Infura) {
|
|
1533
|
+
const infuraNetworkName = deriveInfuraNetworkNameFromRpcEndpointUrl(rpcEndpoint.url);
|
|
1534
|
+
return [
|
|
1535
|
+
rpcEndpoint.networkClientId,
|
|
1536
|
+
createAutoManagedNetworkClient({
|
|
1537
|
+
networkClientId: rpcEndpoint.networkClientId,
|
|
1538
|
+
networkClientConfiguration: {
|
|
1539
|
+
type: NetworkClientType.Infura,
|
|
1540
|
+
network: infuraNetworkName,
|
|
1541
|
+
failoverRpcUrls: defaultFailoverUrls ?? rpcEndpoint.failoverUrls,
|
|
1542
|
+
infuraProjectId: this.#infuraProjectId,
|
|
1543
|
+
chainId: networkConfiguration.chainId,
|
|
1544
|
+
ticker: networkConfiguration.nativeCurrency,
|
|
1545
|
+
},
|
|
1546
|
+
getRpcServiceOptions: this.#getRpcServiceOptions,
|
|
1547
|
+
getBlockTrackerOptions: this.#getBlockTrackerOptions,
|
|
1548
|
+
messenger: this.messenger,
|
|
1549
|
+
rpcFailoverMode: this.#rpcFailoverMode,
|
|
1550
|
+
logger: this.#log,
|
|
1551
|
+
}),
|
|
1552
|
+
];
|
|
1553
|
+
}
|
|
1459
1554
|
return [
|
|
1460
1555
|
rpcEndpoint.networkClientId,
|
|
1461
1556
|
createAutoManagedNetworkClient({
|
|
1462
1557
|
networkClientId: rpcEndpoint.networkClientId,
|
|
1463
1558
|
networkClientConfiguration: {
|
|
1464
|
-
type: NetworkClientType.
|
|
1465
|
-
network: infuraNetworkName,
|
|
1466
|
-
failoverRpcUrls: defaultFailoverUrls ?? rpcEndpoint.failoverUrls,
|
|
1467
|
-
infuraProjectId: __classPrivateFieldGet(this, _NetworkController_infuraProjectId, "f"),
|
|
1559
|
+
type: NetworkClientType.Custom,
|
|
1468
1560
|
chainId: networkConfiguration.chainId,
|
|
1561
|
+
failoverRpcUrls: defaultFailoverUrls ?? rpcEndpoint.failoverUrls,
|
|
1562
|
+
rpcUrl: rpcEndpoint.url,
|
|
1469
1563
|
ticker: networkConfiguration.nativeCurrency,
|
|
1470
1564
|
},
|
|
1471
|
-
getRpcServiceOptions:
|
|
1472
|
-
getBlockTrackerOptions:
|
|
1565
|
+
getRpcServiceOptions: this.#getRpcServiceOptions,
|
|
1566
|
+
getBlockTrackerOptions: this.#getBlockTrackerOptions,
|
|
1473
1567
|
messenger: this.messenger,
|
|
1474
|
-
rpcFailoverMode:
|
|
1475
|
-
logger:
|
|
1568
|
+
rpcFailoverMode: this.#rpcFailoverMode,
|
|
1569
|
+
logger: this.#log,
|
|
1476
1570
|
}),
|
|
1477
1571
|
];
|
|
1478
|
-
}
|
|
1479
|
-
return [
|
|
1480
|
-
rpcEndpoint.networkClientId,
|
|
1481
|
-
createAutoManagedNetworkClient({
|
|
1482
|
-
networkClientId: rpcEndpoint.networkClientId,
|
|
1483
|
-
networkClientConfiguration: {
|
|
1484
|
-
type: NetworkClientType.Custom,
|
|
1485
|
-
chainId: networkConfiguration.chainId,
|
|
1486
|
-
failoverRpcUrls: defaultFailoverUrls ?? rpcEndpoint.failoverUrls,
|
|
1487
|
-
rpcUrl: rpcEndpoint.url,
|
|
1488
|
-
ticker: networkConfiguration.nativeCurrency,
|
|
1489
|
-
},
|
|
1490
|
-
getRpcServiceOptions: __classPrivateFieldGet(this, _NetworkController_getRpcServiceOptions, "f"),
|
|
1491
|
-
getBlockTrackerOptions: __classPrivateFieldGet(this, _NetworkController_getBlockTrackerOptions, "f"),
|
|
1492
|
-
messenger: this.messenger,
|
|
1493
|
-
rpcFailoverMode: __classPrivateFieldGet(this, _NetworkController_rpcFailoverMode, "f"),
|
|
1494
|
-
logger: __classPrivateFieldGet(this, _NetworkController_log, "f"),
|
|
1495
|
-
}),
|
|
1496
|
-
];
|
|
1572
|
+
});
|
|
1497
1573
|
});
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
[NetworkClientType.Infura]: {},
|
|
1510
|
-
});
|
|
1511
|
-
}, _NetworkController_applyNetworkSelection = function _NetworkController_applyNetworkSelection(networkClientId, { updateState, } = {}) {
|
|
1512
|
-
__classPrivateFieldSet(this, _NetworkController_autoManagedNetworkClient, this.getNetworkClientById(networkClientId), "f");
|
|
1513
|
-
this.update((state) => {
|
|
1514
|
-
var _a;
|
|
1515
|
-
state.selectedNetworkClientId = networkClientId;
|
|
1516
|
-
(_a = state.networksMetadata)[networkClientId] ?? (_a[networkClientId] = {
|
|
1517
|
-
status: NetworkStatus.Unknown,
|
|
1518
|
-
EIPS: {},
|
|
1574
|
+
return networkClientsWithIds.reduce((obj, [networkClientId, networkClient]) => {
|
|
1575
|
+
return {
|
|
1576
|
+
...obj,
|
|
1577
|
+
[networkClient.configuration.type]: {
|
|
1578
|
+
...obj[networkClient.configuration.type],
|
|
1579
|
+
[networkClientId]: networkClient,
|
|
1580
|
+
},
|
|
1581
|
+
};
|
|
1582
|
+
}, {
|
|
1583
|
+
[NetworkClientType.Custom]: {},
|
|
1584
|
+
[NetworkClientType.Infura]: {},
|
|
1519
1585
|
});
|
|
1520
|
-
updateState?.(state);
|
|
1521
|
-
});
|
|
1522
|
-
if (__classPrivateFieldGet(this, _NetworkController_providerProxy, "f")) {
|
|
1523
|
-
__classPrivateFieldGet(this, _NetworkController_providerProxy, "f").setTarget(__classPrivateFieldGet(this, _NetworkController_autoManagedNetworkClient, "f").provider);
|
|
1524
|
-
}
|
|
1525
|
-
else {
|
|
1526
|
-
__classPrivateFieldSet(this, _NetworkController_providerProxy, createSwappableProxy(__classPrivateFieldGet(this, _NetworkController_autoManagedNetworkClient, "f").provider), "f");
|
|
1527
|
-
}
|
|
1528
|
-
if (__classPrivateFieldGet(this, _NetworkController_blockTrackerProxy, "f")) {
|
|
1529
|
-
__classPrivateFieldGet(this, _NetworkController_blockTrackerProxy, "f").setTarget(__classPrivateFieldGet(this, _NetworkController_autoManagedNetworkClient, "f").blockTracker);
|
|
1530
|
-
}
|
|
1531
|
-
else {
|
|
1532
|
-
__classPrivateFieldSet(this, _NetworkController_blockTrackerProxy, createEventEmitterProxy(__classPrivateFieldGet(this, _NetworkController_autoManagedNetworkClient, "f").blockTracker, {
|
|
1533
|
-
eventFilter: 'skipInternal',
|
|
1534
|
-
}), "f");
|
|
1535
1586
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1587
|
+
/**
|
|
1588
|
+
* Updates the global provider and block tracker proxies (accessible via
|
|
1589
|
+
* {@link getSelectedNetworkClient}) to point to the same ones within the
|
|
1590
|
+
* given network client, thereby magically switching any consumers using these
|
|
1591
|
+
* proxies to use the new network.
|
|
1592
|
+
*
|
|
1593
|
+
* Also refreshes the EthQuery instance accessible via the `getEthQuery`
|
|
1594
|
+
* action to wrap the provider from the new network client. Note that this is
|
|
1595
|
+
* not a proxy, so consumers will need to call `getEthQuery` again after the
|
|
1596
|
+
* network switch.
|
|
1597
|
+
*
|
|
1598
|
+
* @param networkClientId - The ID of a network client that requests will be
|
|
1599
|
+
* routed through (either the name of an Infura network or the ID of a custom
|
|
1600
|
+
* network configuration).
|
|
1601
|
+
* @param options - Options for this method.
|
|
1602
|
+
* @param options.updateState - Allows for updating state.
|
|
1603
|
+
* @throws if no network client could be found matching the given ID.
|
|
1604
|
+
*/
|
|
1605
|
+
#applyNetworkSelection(networkClientId, { updateState, } = {}) {
|
|
1606
|
+
this.#autoManagedNetworkClient = this.getNetworkClientById(networkClientId);
|
|
1607
|
+
this.update((state) => {
|
|
1608
|
+
state.selectedNetworkClientId = networkClientId;
|
|
1609
|
+
state.networksMetadata[networkClientId] ??= {
|
|
1610
|
+
status: NetworkStatus.Unknown,
|
|
1611
|
+
EIPS: {},
|
|
1612
|
+
};
|
|
1613
|
+
updateState?.(state);
|
|
1614
|
+
});
|
|
1615
|
+
if (this.#providerProxy) {
|
|
1616
|
+
this.#providerProxy.setTarget(this.#autoManagedNetworkClient.provider);
|
|
1617
|
+
}
|
|
1618
|
+
else {
|
|
1619
|
+
this.#providerProxy = createSwappableProxy(this.#autoManagedNetworkClient.provider);
|
|
1620
|
+
}
|
|
1621
|
+
if (this.#blockTrackerProxy) {
|
|
1622
|
+
this.#blockTrackerProxy.setTarget(this.#autoManagedNetworkClient.blockTracker);
|
|
1623
|
+
}
|
|
1624
|
+
else {
|
|
1625
|
+
this.#blockTrackerProxy = createEventEmitterProxy(this.#autoManagedNetworkClient.blockTracker, {
|
|
1626
|
+
eventFilter: 'skipInternal',
|
|
1565
1627
|
});
|
|
1566
1628
|
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1629
|
+
this.#ethQuery = new EthQuery(this.#providerProxy);
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Adds networks to state and registers network clients for the given CAIP-2
|
|
1633
|
+
* chain IDs if they are not already present. Configurations for these
|
|
1634
|
+
* networks are retrieved from ConfigRegistryController.
|
|
1635
|
+
*
|
|
1636
|
+
* @param caipChainIds - The CAIP-2 chain IDs of the networks to enable.
|
|
1637
|
+
*/
|
|
1638
|
+
#autoAddNetworksFromConfigRegistry(caipChainIds) {
|
|
1639
|
+
for (const caipChainId of caipChainIds) {
|
|
1640
|
+
try {
|
|
1641
|
+
const registryNetworkConfig = this.messenger.call('ConfigRegistryController:getNetworkConfigByCaip2ChainId', caipChainId);
|
|
1642
|
+
const hexChainId = numberToHex(Number(parseCaipChainId(caipChainId).reference));
|
|
1643
|
+
if (!registryNetworkConfig ||
|
|
1644
|
+
this.state.networkConfigurationsByChainId[hexChainId]) {
|
|
1645
|
+
continue;
|
|
1646
|
+
}
|
|
1647
|
+
const rpcEndpoint = registryNetworkConfig.rpcProviders.default.type === 'infura'
|
|
1648
|
+
? {
|
|
1649
|
+
type: RpcEndpointType.Infura,
|
|
1650
|
+
networkClientId: registryNetworkConfig.rpcProviders.default.networkClientId,
|
|
1651
|
+
url: registryNetworkConfig.rpcProviders.default
|
|
1652
|
+
.url,
|
|
1653
|
+
}
|
|
1654
|
+
: {
|
|
1655
|
+
type: RpcEndpointType.Custom,
|
|
1656
|
+
url: registryNetworkConfig.rpcProviders.default.url,
|
|
1657
|
+
};
|
|
1658
|
+
this.addNetwork({
|
|
1659
|
+
chainId: hexChainId,
|
|
1660
|
+
name: registryNetworkConfig.name,
|
|
1661
|
+
nativeCurrency: registryNetworkConfig.assets.native.symbol,
|
|
1662
|
+
rpcEndpoints: [rpcEndpoint],
|
|
1663
|
+
defaultRpcEndpointIndex: 0,
|
|
1664
|
+
blockExplorerUrls: [registryNetworkConfig.blockExplorerUrls.default],
|
|
1665
|
+
defaultBlockExplorerUrlIndex: 0,
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
catch (error) {
|
|
1669
|
+
const capturedError = error instanceof Error ? error : new Error(String(error));
|
|
1670
|
+
this.#log?.error(`Failed to auto-enable network for chain ID ${caipChainId}: ${capturedError}`);
|
|
1671
|
+
this.messenger.captureException?.(capturedError);
|
|
1672
|
+
}
|
|
1571
1673
|
}
|
|
1572
1674
|
}
|
|
1573
|
-
}
|
|
1574
|
-
//# sourceMappingURL=NetworkController.
|
|
1675
|
+
}
|
|
1676
|
+
//# sourceMappingURL=NetworkController.js.map
|