{"version":3,"file":"NetworkController.mjs","sourceRoot":"","sources":["../src/NetworkController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n  ControllerGetStateAction,\n  ControllerStateChangeEvent,\n  RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Partialize } from '@metamask/controller-utils';\nimport {\n  InfuraNetworkType,\n  NetworkType,\n  isSafeChainId,\n  isInfuraNetworkType,\n  ChainId,\n  NetworksTicker,\n  NetworkNickname,\n  BUILT_IN_CUSTOM_NETWORKS_RPC,\n  BUILT_IN_NETWORKS,\n  BuiltInNetworkName,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport { errorCodes } from '@metamask/rpc-errors';\nimport { createEventEmitterProxy } from '@metamask/swappable-obj-proxy';\nimport type { SwappableProxy } from '@metamask/swappable-obj-proxy';\nimport type { Hex } from '@metamask/utils';\nimport { hasProperty, isPlainObject, isStrictHexString } from '@metamask/utils';\nimport deepEqual from 'fast-deep-equal';\nimport type { Draft } from 'immer';\nimport { cloneDeep } from 'lodash';\nimport type { Logger } from 'loglevel';\nimport { createSelector } from 'reselect';\nimport * as URI from 'uri-js';\nimport { v4 as uuidV4 } from 'uuid';\n\nimport {\n  DEPRECATED_NETWORKS,\n  INFURA_BLOCKED_KEY,\n  NetworkStatus,\n} from './constants';\nimport type {\n  AutoManagedNetworkClient,\n  ProxyWithAccessibleTarget,\n} from './create-auto-managed-network-client';\nimport { createAutoManagedNetworkClient } from './create-auto-managed-network-client';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { RpcServiceOptions } from './rpc-service/rpc-service';\nimport { NetworkClientType } from './types';\nimport type {\n  BlockTracker,\n  Provider,\n  CustomNetworkClientConfiguration,\n  InfuraNetworkClientConfiguration,\n  NetworkClientConfiguration,\n  AdditionalDefaultNetwork,\n} from './types';\n\nconst debugLog = createModuleLogger(projectLogger, 'NetworkController');\n\nconst INFURA_URL_REGEX =\n  /^https:\\/\\/(?<networkName>[^.]+)\\.infura\\.io\\/v\\d+\\/(?<apiKey>.+)$/u;\n\nexport type Block = {\n  baseFeePerGas?: string;\n};\n\n/**\n * Information about a network not held by any other part of state.\n */\nexport type NetworkMetadata = {\n  /**\n   * EIPs supported by the network.\n   */\n  // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  EIPS: {\n    [eipNumber: number]: boolean;\n  };\n  /**\n   * Indicates the availability of the network\n   */\n  status: NetworkStatus;\n};\n\n/**\n * The type of an RPC endpoint.\n *\n * @see {@link CustomRpcEndpoint}\n * @see {@link InfuraRpcEndpoint}\n */\nexport enum RpcEndpointType {\n  Custom = 'custom',\n  Infura = 'infura',\n}\n\n/**\n * An Infura RPC endpoint is a reference to a specific network that Infura\n * supports as well as an Infura account we own that we allow users to make use\n * of for free. We need to disambiguate these endpoints from custom RPC\n * endpoints, because while the types for these kinds of object both have the\n * same interface, the URL for an Infura endpoint contains the Infura project\n * ID, and we don't want this to be present in state. We therefore hide it by\n * representing it in the URL as `{infuraProjectId}`, which we replace this when\n * create network clients. But we need to know somehow that we only need to do\n * this replacement for Infura endpoints and not custom endpoints — hence the\n * separate type.\n */\nexport type InfuraRpcEndpoint = {\n  /**\n   * Alternate RPC endpoints to use when this endpoint is down.\n   */\n  failoverUrls?: string[];\n  /**\n   * The optional user-facing nickname of the endpoint.\n   */\n  name?: string;\n  /**\n   * The identifier for the network client that has been created for this RPC\n   * endpoint. This is also used to uniquely identify the RPC endpoint in a\n   * set of RPC endpoints as well: once assigned, it is used to determine\n   * whether the `name`, `type`, or `url` of the RPC endpoint has changed.\n   */\n  networkClientId: BuiltInNetworkClientId;\n  /**\n   * The type of this endpoint, always \"default\".\n   */\n  type: RpcEndpointType.Infura;\n  /**\n   * The URL of the endpoint. Expected to be a template with the string\n   * `{infuraProjectId}`, which will get replaced with the Infura project ID\n   * when the network client is created.\n   */\n  url: `https://${InfuraNetworkType}.infura.io/v3/{infuraProjectId}`;\n};\n\n/**\n * A custom RPC endpoint is a reference to a user-defined server which fronts an\n * EVM chain. It may refer to an Infura network, but only by coincidence.\n */\nexport type CustomRpcEndpoint = {\n  /**\n   * Alternate RPC endpoints to use when this endpoint is down.\n   */\n  failoverUrls?: string[];\n  /**\n   * The optional user-facing nickname of the endpoint.\n   */\n  name?: string;\n  /**\n   * The identifier for the network client that has been created for this RPC\n   * endpoint. This is also used to uniquely identify the RPC endpoint in a\n   * set of RPC endpoints as well: once assigned, it is used to determine\n   * whether the `name`, `type`, or `url` of the RPC endpoint has changed.\n   */\n  networkClientId: CustomNetworkClientId;\n  /**\n   * The type of this endpoint, always \"custom\".\n   */\n  type: RpcEndpointType.Custom;\n  /**\n   * The URL of the endpoint.\n   */\n  url: string;\n};\n\n/**\n * An RPC endpoint is a reference to a server which fronts an EVM chain. There\n * are two varieties of RPC endpoints: Infura and custom.\n *\n * @see {@link CustomRpcEndpoint}\n * @see {@link InfuraRpcEndpoint}\n */\nexport type RpcEndpoint = InfuraRpcEndpoint | CustomRpcEndpoint;\n\n/**\n * From a user perspective, a network configuration holds information about a\n * network that a user can select through the client. A \"network\" in this sense\n * can explicitly refer to an EVM chain that the user explicitly adds or doesn't\n * need to add (because it comes shipped with the client). The properties here\n * therefore directly map to fields that a user sees and can edit for a network\n * within the client.\n *\n * Internally, a network configuration represents a single conceptual EVM chain,\n * which is represented tangibly via multiple RPC endpoints. A \"network\" is then\n * something for which a network client object is created automatically or\n * created on demand when it is added to the client.\n */\nexport type NetworkConfiguration = {\n  /**\n   * A set of URLs that allows the user to view activity that has occurred on\n   * the chain.\n   */\n  blockExplorerUrls: string[];\n  /**\n   * The ID of the chain. Represented in hexadecimal format with a leading \"0x\"\n   * instead of decimal format so that when viewed out of context it can be\n   * unambiguously interpreted.\n   */\n  chainId: Hex;\n  /**\n   * A reference to a URL that the client will use by default to allow the user\n   * to view activity that has occurred on the chain. This index must refer to\n   * an item in `blockExplorerUrls`.\n   */\n  defaultBlockExplorerUrlIndex?: number;\n  /**\n   * A reference to an RPC endpoint that all requests will use by default in order to\n   * interact with the chain. This index must refer to an item in\n   * `rpcEndpoints`.\n   */\n  defaultRpcEndpointIndex: number;\n  /**\n   * The user-facing nickname assigned to the chain.\n   */\n  name: string;\n  /**\n   * The name of the currency to use for the chain.\n   */\n  nativeCurrency: string;\n  /**\n   * The collection of possible RPC endpoints that the client can use to\n   * interact with the chain.\n   */\n  rpcEndpoints: RpcEndpoint[];\n  /**\n   * Profile Sync - Network Sync field.\n   * Allows comparison of local network state with state to sync.\n   */\n  lastUpdatedAt?: number;\n};\n\n/**\n * A custom RPC endpoint in a new network configuration, meant to be used in\n * conjunction with `AddNetworkFields`.\n *\n * Custom RPC endpoints do not need a `networkClientId` property because it is\n * assumed that they have not already been added and therefore network clients\n * do not exist for them yet (and hence IDs need to be generated).\n */\nexport type AddNetworkCustomRpcEndpointFields = Omit<\n  CustomRpcEndpoint,\n  'networkClientId'\n>;\n\n/**\n * A new network configuration that `addNetwork` takes.\n *\n * Custom RPC endpoints do not need a `networkClientId` property because it is\n * assumed that they have not already been added and are not represented by\n * network clients yet.\n */\nexport type AddNetworkFields = Omit<NetworkConfiguration, 'rpcEndpoints'> & {\n  rpcEndpoints: (InfuraRpcEndpoint | AddNetworkCustomRpcEndpointFields)[];\n};\n\n/**\n * A custom RPC endpoint in an updated representation of a network\n * configuration, meant to be used in conjunction with `UpdateNetworkFields`.\n *\n * Custom RPC endpoints do not need a `networkClientId` property because it is\n * assumed that they have not already been added and therefore network clients\n * do not exist for them yet (and hence IDs need to be generated).\n */\nexport type UpdateNetworkCustomRpcEndpointFields = Partialize<\n  CustomRpcEndpoint,\n  'networkClientId'\n>;\n\n/**\n * An updated representation of an existing network configuration that\n * `updateNetwork` takes.\n *\n * Custom RPC endpoints may or may not have a `networkClientId` property; if\n * they do, then it is assumed that they already exist, and if not, then it is\n * assumed that they are new and are not represented by network clients yet.\n */\nexport type UpdateNetworkFields = Omit<NetworkConfiguration, 'rpcEndpoints'> & {\n  rpcEndpoints: (InfuraRpcEndpoint | UpdateNetworkCustomRpcEndpointFields)[];\n};\n\n/**\n * `Object.keys()` is intentionally generic: it returns the keys of an object,\n * but it cannot make guarantees about the contents of that object, so the type\n * of the keys is merely `string[]`. While this is technically accurate, it is\n * also unnecessary if we have an object that we own and whose contents are\n * known exactly.\n *\n * TODO: Move to @metamask/utils.\n *\n * @param object - The object.\n * @returns The keys of an object, typed according to the type of the object\n * itself.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function knownKeysOf<K extends PropertyKey>(\n  // TODO: Replace `any` with type\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  object: Partial<Record<K, any>>,\n) {\n  return Object.keys(object) as K[];\n}\n\n/**\n * Type guard for determining whether the given value is an error object with a\n * `code` property, such as an instance of Error.\n *\n * TODO: Move this to @metamask/utils.\n *\n * @param error - The object to check.\n * @returns True if `error` has a `code`, false otherwise.\n */\nfunction isErrorWithCode(error: unknown): error is { code: string | number } {\n  return typeof error === 'object' && error !== null && 'code' in error;\n}\n\n/**\n * The string that uniquely identifies an Infura network client.\n */\nexport type BuiltInNetworkClientId = InfuraNetworkType;\n\n/**\n * The string that uniquely identifies a custom network client.\n */\nexport type CustomNetworkClientId = string;\n\n/**\n * The string that uniquely identifies a network client.\n */\nexport type NetworkClientId = BuiltInNetworkClientId | CustomNetworkClientId;\n\n/**\n * Extra information about each network, such as whether it is accessible or\n * blocked and whether it supports EIP-1559, keyed by network client ID.\n */\nexport type NetworksMetadata = Record<NetworkClientId, NetworkMetadata>;\n\n/**\n * The state that NetworkController stores.\n */\nexport type NetworkState = {\n  /**\n   * The ID of the network client that the proxies returned by\n   * `getSelectedNetworkClient` currently point to.\n   */\n  selectedNetworkClientId: NetworkClientId;\n  /**\n   * The registry of networks and corresponding RPC endpoints that the\n   * controller can use to make requests for various chains.\n   *\n   * @see {@link NetworkConfiguration}\n   */\n  networkConfigurationsByChainId: Record<Hex, NetworkConfiguration>;\n  /**\n   * Extra information about each network, such as whether it is accessible or\n   * blocked and whether it supports EIP-1559, keyed by network client ID.\n   */\n  networksMetadata: NetworksMetadata;\n};\n\nconst controllerName = 'NetworkController';\n\n/**\n * Represents the block tracker for the currently selected network. (Note that\n * this is a proxy around a proxy: the inner one exists so that the block\n * tracker doesn't have to exist until it's used, and the outer one exists so\n * that the currently selected network can change without consumers needing to\n * refresh the object reference to that network.)\n */\nexport type BlockTrackerProxy = SwappableProxy<\n  ProxyWithAccessibleTarget<BlockTracker>\n>;\n\n/**\n * Represents the provider for the currently selected network. (Note that this\n * is a proxy around a proxy: the inner one exists so that the provider doesn't\n * have to exist until it's used, and the outer one exists so that the currently\n * selected network can change without consumers needing to refresh the object\n * reference to that network.)\n */\nexport type ProviderProxy = SwappableProxy<ProxyWithAccessibleTarget<Provider>>;\n\nexport type NetworkControllerStateChangeEvent = ControllerStateChangeEvent<\n  typeof controllerName,\n  NetworkState\n>;\n\n/**\n * `networkWillChange` is published when the current network is about to be\n * switched, but the new provider has not been created and no state changes have\n * occurred yet.\n */\nexport type NetworkControllerNetworkWillChangeEvent = {\n  type: 'NetworkController:networkWillChange';\n  payload: [NetworkState];\n};\n\n/**\n * `networkDidChange` is published after a provider has been created for a newly\n * switched network (but before the network has been confirmed to be available).\n */\nexport type NetworkControllerNetworkDidChangeEvent = {\n  type: 'NetworkController:networkDidChange';\n  payload: [NetworkState];\n};\n\n/**\n * `infuraIsBlocked` is published after the network is switched to an Infura\n * network, but when Infura returns an error blocking the user based on their\n * location.\n */\nexport type NetworkControllerInfuraIsBlockedEvent = {\n  type: 'NetworkController:infuraIsBlocked';\n  payload: [];\n};\n\n/**\n * `infuraIsBlocked` is published either after the network is switched to an\n * Infura network and Infura does not return an error blocking the user based on\n * their location, or the network is switched to a non-Infura network.\n */\nexport type NetworkControllerInfuraIsUnblockedEvent = {\n  type: 'NetworkController:infuraIsUnblocked';\n  payload: [];\n};\n\n/**\n * `networkAdded` is published after a network configuration is added to the\n * network configuration registry and network clients are created for it.\n */\nexport type NetworkControllerNetworkAddedEvent = {\n  type: 'NetworkController:networkAdded';\n  payload: [networkConfiguration: NetworkConfiguration];\n};\n\n/**\n * `networkRemoved` is published after a network configuration is removed from the\n * network configuration registry and once the network clients have been removed.\n */\nexport type NetworkControllerNetworkRemovedEvent = {\n  type: 'NetworkController:networkRemoved';\n  payload: [networkConfiguration: NetworkConfiguration];\n};\n\n/**\n * `rpcEndpointUnavailable` is published after an attempt to make a request to\n * an RPC endpoint fails too many times in a row (because of a connection error\n * or an unusable response).\n */\nexport type NetworkControllerRpcEndpointUnavailableEvent = {\n  type: 'NetworkController:rpcEndpointUnavailable';\n  payload: [\n    {\n      chainId: Hex;\n      endpointUrl: string;\n      failoverEndpointUrl?: string;\n      error: unknown;\n    },\n  ];\n};\n\n/**\n * `rpcEndpointDegraded` is published after a request to an RPC endpoint\n * responds successfully but takes too long.\n */\nexport type NetworkControllerRpcEndpointDegradedEvent = {\n  type: 'NetworkController:rpcEndpointDegraded';\n  payload: [\n    {\n      chainId: Hex;\n      endpointUrl: string;\n    },\n  ];\n};\n\n/**\n * `rpcEndpointRequestRetried` is published after a request to an RPC endpoint\n * is retried following a connection error or an unusable response.\n */\nexport type NetworkControllerRpcEndpointRequestRetriedEvent = {\n  type: 'NetworkController:rpcEndpointRequestRetried';\n  payload: [\n    {\n      endpointUrl: string;\n      attempt: number;\n    },\n  ];\n};\n\nexport type NetworkControllerEvents =\n  | NetworkControllerStateChangeEvent\n  | NetworkControllerNetworkWillChangeEvent\n  | NetworkControllerNetworkDidChangeEvent\n  | NetworkControllerInfuraIsBlockedEvent\n  | NetworkControllerInfuraIsUnblockedEvent\n  | NetworkControllerNetworkAddedEvent\n  | NetworkControllerNetworkRemovedEvent\n  | NetworkControllerRpcEndpointUnavailableEvent\n  | NetworkControllerRpcEndpointDegradedEvent\n  | NetworkControllerRpcEndpointRequestRetriedEvent;\n\nexport type NetworkControllerGetStateAction = ControllerGetStateAction<\n  typeof controllerName,\n  NetworkState\n>;\n\nexport type NetworkControllerGetEthQueryAction = {\n  type: `NetworkController:getEthQuery`;\n  handler: () => EthQuery | undefined;\n};\n\nexport type NetworkControllerGetNetworkClientByIdAction = {\n  type: `NetworkController:getNetworkClientById`;\n  handler: NetworkController['getNetworkClientById'];\n};\n\nexport type NetworkControllerGetSelectedNetworkClientAction = {\n  type: `NetworkController:getSelectedNetworkClient`;\n  handler: NetworkController['getSelectedNetworkClient'];\n};\n\nexport type NetworkControllerGetSelectedChainIdAction = {\n  type: 'NetworkController:getSelectedChainId';\n  handler: NetworkController['getSelectedChainId'];\n};\n\nexport type NetworkControllerGetEIP1559CompatibilityAction = {\n  type: `NetworkController:getEIP1559Compatibility`;\n  handler: NetworkController['getEIP1559Compatibility'];\n};\n\nexport type NetworkControllerFindNetworkClientIdByChainIdAction = {\n  type: `NetworkController:findNetworkClientIdByChainId`;\n  handler: NetworkController['findNetworkClientIdByChainId'];\n};\n\n/**\n * Change the currently selected network to the given built-in network type.\n *\n * @deprecated This action has been replaced by `setActiveNetwork`, and will be\n * removed in a future release.\n */\nexport type NetworkControllerSetProviderTypeAction = {\n  type: `NetworkController:setProviderType`;\n  handler: NetworkController['setProviderType'];\n};\n\nexport type NetworkControllerSetActiveNetworkAction = {\n  type: `NetworkController:setActiveNetwork`;\n  handler: NetworkController['setActiveNetwork'];\n};\n\nexport type NetworkControllerGetNetworkConfigurationByChainId = {\n  type: `NetworkController:getNetworkConfigurationByChainId`;\n  handler: NetworkController['getNetworkConfigurationByChainId'];\n};\n\nexport type NetworkControllerGetNetworkConfigurationByNetworkClientId = {\n  type: `NetworkController:getNetworkConfigurationByNetworkClientId`;\n  handler: NetworkController['getNetworkConfigurationByNetworkClientId'];\n};\n\nexport type NetworkControllerAddNetworkAction = {\n  type: 'NetworkController:addNetwork';\n  handler: NetworkController['addNetwork'];\n};\n\nexport type NetworkControllerRemoveNetworkAction = {\n  type: 'NetworkController:removeNetwork';\n  handler: NetworkController['removeNetwork'];\n};\n\nexport type NetworkControllerUpdateNetworkAction = {\n  type: 'NetworkController:updateNetwork';\n  handler: NetworkController['updateNetwork'];\n};\n\nexport type NetworkControllerActions =\n  | NetworkControllerGetStateAction\n  | NetworkControllerGetEthQueryAction\n  | NetworkControllerGetNetworkClientByIdAction\n  | NetworkControllerGetSelectedNetworkClientAction\n  | NetworkControllerGetSelectedChainIdAction\n  | NetworkControllerGetEIP1559CompatibilityAction\n  | NetworkControllerFindNetworkClientIdByChainIdAction\n  | NetworkControllerSetActiveNetworkAction\n  | NetworkControllerSetProviderTypeAction\n  | NetworkControllerGetNetworkConfigurationByChainId\n  | NetworkControllerGetNetworkConfigurationByNetworkClientId\n  | NetworkControllerAddNetworkAction\n  | NetworkControllerRemoveNetworkAction\n  | NetworkControllerUpdateNetworkAction;\n\nexport type NetworkControllerMessenger = RestrictedMessenger<\n  typeof controllerName,\n  NetworkControllerActions,\n  NetworkControllerEvents,\n  never,\n  never\n>;\n\n/**\n * Options for the NetworkController constructor.\n */\nexport type NetworkControllerOptions = {\n  /**\n   * The messenger suited for this controller.\n   */\n  messenger: NetworkControllerMessenger;\n  /**\n   * The API key for Infura, used to make requests to Infura.\n   */\n  infuraProjectId: string;\n  /**\n   * The desired state with which to initialize this controller.\n   * Missing properties will be filled in with defaults. For instance, if not\n   * specified, `networkConfigurationsByChainId` will default to a basic set of\n   * network configurations (see {@link InfuraNetworkType} for the list).\n   */\n  state?: Partial<NetworkState>;\n  /**\n   * A `loglevel` logger object.\n   */\n  log?: Logger;\n  /**\n   * A function that can be used to customize the options passed to a\n   * RPC service constructed for an RPC endpoint. The object that the function\n   * should return is the same as {@link RpcServiceOptions}, except that\n   * `failoverService` and `endpointUrl` are not accepted (as they are filled in\n   * automatically).\n   */\n  getRpcServiceOptions: (\n    rpcEndpointUrl: string,\n  ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n\n  /**\n   * An array of Hex Chain IDs representing the additional networks to be included as default.\n   */\n  additionalDefaultNetworks?: AdditionalDefaultNetwork[];\n};\n\n/**\n * Constructs a value for the state property `networkConfigurationsByChainId`\n * which will be used if it has not been provided to the constructor.\n *\n * @param [additionalDefaultNetworks] - An array of Hex Chain IDs representing the additional networks to be included as default.\n * @returns The default value for `networkConfigurationsByChainId`.\n */\nfunction getDefaultNetworkConfigurationsByChainId(\n  additionalDefaultNetworks: AdditionalDefaultNetwork[] = [],\n): Record<Hex, NetworkConfiguration> {\n  const infuraNetworks = getDefaultInfuraNetworkConfigurationsByChainId();\n  const customNetworks = getDefaultCustomNetworkConfigurationsByChainId();\n\n  return additionalDefaultNetworks.reduce<Record<Hex, NetworkConfiguration>>(\n    (obj, chainId) => {\n      if (hasProperty(customNetworks, chainId)) {\n        obj[chainId] = customNetworks[chainId];\n      }\n      return obj;\n    },\n    // Always include the infura networks in the default networks\n    infuraNetworks,\n  );\n}\n\n/**\n * Constructs a `networkConfigurationsByChainId` object for all default Infura networks.\n *\n * @returns The `networkConfigurationsByChainId` object of all Infura networks.\n */\nfunction getDefaultInfuraNetworkConfigurationsByChainId(): Record<\n  Hex,\n  NetworkConfiguration\n> {\n  return Object.values(InfuraNetworkType).reduce<\n    Record<Hex, NetworkConfiguration>\n  >((obj, infuraNetworkType) => {\n    const chainId = ChainId[infuraNetworkType];\n\n    // Skip deprecated network as default network.\n    if (DEPRECATED_NETWORKS.has(chainId)) {\n      return obj;\n    }\n\n    const rpcEndpointUrl =\n      // This ESLint rule mistakenly produces an error.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}` as const;\n\n    const networkConfiguration: NetworkConfiguration = {\n      blockExplorerUrls: [],\n      chainId,\n      defaultRpcEndpointIndex: 0,\n      name: NetworkNickname[infuraNetworkType],\n      nativeCurrency: NetworksTicker[infuraNetworkType],\n      rpcEndpoints: [\n        {\n          failoverUrls: [],\n          networkClientId: infuraNetworkType,\n          type: RpcEndpointType.Infura,\n          url: rpcEndpointUrl,\n        },\n      ],\n    };\n\n    return { ...obj, [chainId]: networkConfiguration };\n  }, {});\n}\n\n/**\n * Constructs a `networkConfigurationsByChainId` object for all default custom networks.\n *\n * @returns The `networkConfigurationsByChainId` object of all custom networks.\n */\nfunction getDefaultCustomNetworkConfigurationsByChainId(): Record<\n  Hex,\n  NetworkConfiguration\n> {\n  const { ticker, rpcPrefs } =\n    BUILT_IN_NETWORKS[BuiltInNetworkName.MegaETHTestnet];\n  return {\n    [ChainId[BuiltInNetworkName.MegaETHTestnet]]: {\n      blockExplorerUrls: [rpcPrefs.blockExplorerUrl],\n      chainId: ChainId[BuiltInNetworkName.MegaETHTestnet],\n      defaultRpcEndpointIndex: 0,\n      defaultBlockExplorerUrlIndex: 0,\n      name: NetworkNickname[BuiltInNetworkName.MegaETHTestnet],\n      nativeCurrency: ticker,\n      rpcEndpoints: [\n        {\n          failoverUrls: [],\n          networkClientId: BuiltInNetworkName.MegaETHTestnet,\n          type: RpcEndpointType.Custom,\n          url: BUILT_IN_CUSTOM_NETWORKS_RPC.MEGAETH_TESTNET,\n        },\n      ],\n    },\n  };\n}\n\n/**\n * Constructs properties for the NetworkController state whose values will be\n * used if not provided to the constructor.\n *\n * @param [additionalDefaultNetworks] - An array of Hex Chain IDs representing the additional networks to be included as default.\n * @returns The default NetworkController state.\n */\nexport function getDefaultNetworkControllerState(\n  additionalDefaultNetworks?: AdditionalDefaultNetwork[],\n): NetworkState {\n  const networksMetadata = {};\n  const networkConfigurationsByChainId =\n    getDefaultNetworkConfigurationsByChainId(additionalDefaultNetworks);\n\n  return {\n    selectedNetworkClientId: InfuraNetworkType.mainnet,\n    networksMetadata,\n    networkConfigurationsByChainId,\n  };\n}\n\n/**\n * Redux selector for getting all network configurations from NetworkController\n * state, keyed by chain ID.\n *\n * @param state - NetworkController state\n * @returns All registered network configurations, keyed by chain ID.\n */\nconst selectNetworkConfigurationsByChainId = (state: NetworkState) =>\n  state.networkConfigurationsByChainId;\n\n/**\n * Get a list of all network configurations.\n *\n * @param state - NetworkController state\n * @returns A list of all available network configurations\n */\nexport function getNetworkConfigurations(\n  state: NetworkState,\n): NetworkConfiguration[] {\n  return Object.values(state.networkConfigurationsByChainId);\n}\n\n/**\n * Redux selector for getting a list of all network configurations from\n * NetworkController state.\n *\n * @param state - NetworkController state\n * @returns A list of all available network configurations\n */\nexport const selectNetworkConfigurations = createSelector(\n  selectNetworkConfigurationsByChainId,\n  (networkConfigurationsByChainId) =>\n    Object.values(networkConfigurationsByChainId),\n);\n\n/**\n * Get a list of all available network client IDs from a list of network\n * configurations.\n *\n * @param networkConfigurations - The array of network configurations\n * @returns A list of all available client IDs\n */\nexport function getAvailableNetworkClientIds(\n  networkConfigurations: NetworkConfiguration[],\n): string[] {\n  return networkConfigurations.flatMap((networkConfiguration) =>\n    networkConfiguration.rpcEndpoints.map(\n      (rpcEndpoint) => rpcEndpoint.networkClientId,\n    ),\n  );\n}\n\n/**\n * Redux selector for getting a list of all available network client IDs\n * from NetworkController state.\n *\n * @param state - NetworkController state\n * @returns A list of all available network client IDs.\n */\nexport const selectAvailableNetworkClientIds = createSelector(\n  selectNetworkConfigurations,\n  getAvailableNetworkClientIds,\n);\n\n/**\n * The collection of auto-managed network clients that map to Infura networks.\n */\nexport type AutoManagedBuiltInNetworkClientRegistry = Record<\n  BuiltInNetworkClientId,\n  AutoManagedNetworkClient<InfuraNetworkClientConfiguration>\n>;\n\n/**\n * The collection of auto-managed network clients that map to Infura networks.\n */\nexport type AutoManagedCustomNetworkClientRegistry = Record<\n  CustomNetworkClientId,\n  AutoManagedNetworkClient<CustomNetworkClientConfiguration>\n>;\n\n/**\n * The collection of auto-managed network clients that map to Infura networks\n * as well as custom networks that users have added.\n */\nexport type AutoManagedNetworkClientRegistry = {\n  [NetworkClientType.Infura]: AutoManagedBuiltInNetworkClientRegistry;\n  [NetworkClientType.Custom]: AutoManagedCustomNetworkClientRegistry;\n};\n\n/**\n * Instructs `addNetwork` and `updateNetwork` to create a network client for an\n * RPC endpoint.\n *\n * @see {@link NetworkClientOperation}\n */\ntype AddNetworkClientOperation = {\n  type: 'add';\n  rpcEndpoint: RpcEndpoint;\n};\n\n/**\n * Instructs `updateNetwork` and `removeNetwork` to remove a network client for\n * an RPC endpoint.\n *\n * @see {@link NetworkClientOperation}\n */\ntype RemoveNetworkClientOperation = {\n  type: 'remove';\n  rpcEndpoint: RpcEndpoint;\n};\n\n/**\n * Instructs `addNetwork` and `updateNetwork` to replace the network client for\n * an RPC endpoint.\n *\n * @see {@link NetworkClientOperation}\n */\ntype ReplaceNetworkClientOperation = {\n  type: 'replace';\n  oldRpcEndpoint: RpcEndpoint;\n  newRpcEndpoint: RpcEndpoint;\n};\n\n/**\n * Instructs `addNetwork` and `updateNetwork` not to do anything with an RPC\n * endpoint, as far as the network client registry is concerned.\n *\n * @see {@link NetworkClientOperation}\n */\ntype NoopNetworkClientOperation = {\n  type: 'noop';\n  rpcEndpoint: RpcEndpoint;\n};\n\n/* eslint-disable jsdoc/check-indentation */\n/**\n * Instructs `addNetwork`, `updateNetwork`, and `removeNetwork` how to\n * update the network client registry.\n *\n * - When `addNetwork` is called, represents a network client that should be\n * created for a new RPC endpoint.\n * - When `removeNetwork` is called, represents a network client that should be\n * destroyed for a previously existing RPC endpoint.\n * - When `updateNetwork` is called, represents either:\n *   - a network client that should be added for a new RPC endpoint\n *   - a network client that should be removed for a previously existing RPC\n *   endpoint\n *   - a network client that should be replaced for an RPC endpoint that was\n *   changed in a non-major way, or\n *   - a network client that should be unchanged for an RPC endpoint that was\n *   also unchanged.\n */\n/* eslint-enable jsdoc/check-indentation */\ntype NetworkClientOperation =\n  | AddNetworkClientOperation\n  | RemoveNetworkClientOperation\n  | ReplaceNetworkClientOperation\n  | NoopNetworkClientOperation;\n\n/**\n * Determines whether the given URL is valid by attempting to parse it.\n *\n * @param url - The URL to test.\n * @returns True if the URL is valid, false otherwise.\n */\nfunction isValidUrl(url: string) {\n  const uri = URI.parse(url);\n  return (\n    uri.error === undefined && (uri.scheme === 'http' || uri.scheme === 'https')\n  );\n}\n\n/**\n * Given an Infura API URL, extracts the subdomain that identifies the Infura\n * network.\n *\n * @param rpcEndpointUrl - The URL to operate on.\n * @returns The Infura network name that the URL references.\n * @throws if the URL is not an Infura API URL, or if an Infura network is not\n * present in the URL.\n */\nfunction deriveInfuraNetworkNameFromRpcEndpointUrl(\n  rpcEndpointUrl: string,\n): InfuraNetworkType {\n  const match = INFURA_URL_REGEX.exec(rpcEndpointUrl);\n\n  if (match?.groups) {\n    if (isInfuraNetworkType(match.groups.networkName)) {\n      return match.groups.networkName;\n    }\n\n    throw new Error(`Unknown Infura network '${match.groups.networkName}'`);\n  }\n\n  throw new Error('Could not derive Infura network from RPC endpoint URL');\n}\n\n/**\n * Performs a series of checks that the given NetworkController state is\n * internally consistent — that all parts of state that are supposed to match in\n * fact do — so that working with the state later on doesn't cause unexpected\n * errors.\n *\n * In the case of NetworkController, there are several parts of state that need\n * to match. For instance, `defaultRpcEndpointIndex` needs to match an entry\n * within `rpcEndpoints`, and `selectedNetworkClientId` needs to point to an RPC\n * endpoint within a network configuration.\n *\n * @param state - The NetworkController state to verify.\n * @throws if the state is invalid in some way.\n */\nfunction validateNetworkControllerState(state: NetworkState) {\n  const networkConfigurationEntries = Object.entries(\n    state.networkConfigurationsByChainId,\n  );\n  const networkClientIds = getAvailableNetworkClientIds(\n    getNetworkConfigurations(state),\n  );\n\n  if (networkConfigurationEntries.length === 0) {\n    throw new Error(\n      'NetworkController state is invalid: `networkConfigurationsByChainId` cannot be empty',\n    );\n  }\n\n  for (const [chainId, networkConfiguration] of networkConfigurationEntries) {\n    if (chainId !== networkConfiguration.chainId) {\n      throw new Error(\n        `NetworkController state has invalid \\`networkConfigurationsByChainId\\`: Network configuration '${networkConfiguration.name}' is filed under '${chainId}' which does not match its \\`chainId\\` of '${networkConfiguration.chainId}'`,\n      );\n    }\n\n    const isInvalidDefaultBlockExplorerUrlIndex =\n      networkConfiguration.blockExplorerUrls.length > 0\n        ? networkConfiguration.defaultBlockExplorerUrlIndex === undefined ||\n          networkConfiguration.blockExplorerUrls[\n            networkConfiguration.defaultBlockExplorerUrlIndex\n          ] === undefined\n        : networkConfiguration.defaultBlockExplorerUrlIndex !== undefined;\n\n    if (isInvalidDefaultBlockExplorerUrlIndex) {\n      throw new Error(\n        `NetworkController state has invalid \\`networkConfigurationsByChainId\\`: Network configuration '${networkConfiguration.name}' has a \\`defaultBlockExplorerUrlIndex\\` that does not refer to an entry in \\`blockExplorerUrls\\``,\n      );\n    }\n\n    if (\n      networkConfiguration.rpcEndpoints[\n        networkConfiguration.defaultRpcEndpointIndex\n      ] === undefined\n    ) {\n      throw new Error(\n        `NetworkController state has invalid \\`networkConfigurationsByChainId\\`: Network configuration '${networkConfiguration.name}' has a \\`defaultRpcEndpointIndex\\` that does not refer to an entry in \\`rpcEndpoints\\``,\n      );\n    }\n  }\n\n  if ([...new Set(networkClientIds)].length < networkClientIds.length) {\n    throw new Error(\n      'NetworkController state has invalid `networkConfigurationsByChainId`: Every RPC endpoint across all network configurations must have a unique `networkClientId`',\n    );\n  }\n\n  if (!networkClientIds.includes(state.selectedNetworkClientId)) {\n    throw new Error(\n      // This ESLint rule mistakenly produces an error.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `NetworkController state is invalid: \\`selectedNetworkClientId\\` '${state.selectedNetworkClientId}' does not refer to an RPC endpoint within a network configuration`,\n    );\n  }\n}\n\n/**\n * Transforms a map of chain ID to network configuration to a map of network\n * client ID to network configuration.\n *\n * @param networkConfigurationsByChainId - The network configurations, keyed by\n * chain ID.\n * @returns The network configurations, keyed by network client ID.\n */\nfunction buildNetworkConfigurationsByNetworkClientId(\n  networkConfigurationsByChainId: Record<Hex, NetworkConfiguration>,\n): Map<NetworkClientId, NetworkConfiguration> {\n  return new Map(\n    Object.values(networkConfigurationsByChainId).flatMap(\n      (networkConfiguration) => {\n        return networkConfiguration.rpcEndpoints.map((rpcEndpoint) => {\n          return [rpcEndpoint.networkClientId, networkConfiguration];\n        });\n      },\n    ),\n  );\n}\n\n/**\n * Controller that creates and manages an Ethereum network provider.\n */\nexport class NetworkController extends BaseController<\n  typeof controllerName,\n  NetworkState,\n  NetworkControllerMessenger\n> {\n  #ethQuery?: EthQuery;\n\n  #infuraProjectId: string;\n\n  #previouslySelectedNetworkClientId: string;\n\n  #providerProxy: ProviderProxy | undefined;\n\n  #blockTrackerProxy: BlockTrackerProxy | undefined;\n\n  #autoManagedNetworkClientRegistry?: AutoManagedNetworkClientRegistry;\n\n  #autoManagedNetworkClient?:\n    | AutoManagedNetworkClient<CustomNetworkClientConfiguration>\n    | AutoManagedNetworkClient<InfuraNetworkClientConfiguration>;\n\n  #log: Logger | undefined;\n\n  readonly #getRpcServiceOptions: NetworkControllerOptions['getRpcServiceOptions'];\n\n  #networkConfigurationsByNetworkClientId: Map<\n    NetworkClientId,\n    NetworkConfiguration\n  >;\n\n  /**\n   * Constructs a NetworkController.\n   *\n   * @param options - The options; see {@link NetworkControllerOptions}.\n   */\n  constructor(options: NetworkControllerOptions) {\n    const {\n      messenger,\n      state,\n      infuraProjectId,\n      log,\n      getRpcServiceOptions,\n      additionalDefaultNetworks,\n    } = options;\n    const initialState = {\n      ...getDefaultNetworkControllerState(additionalDefaultNetworks),\n      ...state,\n    };\n    validateNetworkControllerState(initialState);\n    if (!infuraProjectId || typeof infuraProjectId !== 'string') {\n      throw new Error('Invalid Infura project ID');\n    }\n\n    super({\n      name: controllerName,\n      metadata: {\n        selectedNetworkClientId: {\n          persist: true,\n          anonymous: false,\n        },\n        networksMetadata: {\n          persist: true,\n          anonymous: false,\n        },\n        networkConfigurationsByChainId: {\n          persist: true,\n          anonymous: false,\n        },\n      },\n      messenger,\n      state: initialState,\n    });\n\n    this.#infuraProjectId = infuraProjectId;\n    this.#log = log;\n    this.#getRpcServiceOptions = getRpcServiceOptions;\n\n    this.#previouslySelectedNetworkClientId =\n      this.state.selectedNetworkClientId;\n    this.#networkConfigurationsByNetworkClientId =\n      buildNetworkConfigurationsByNetworkClientId(\n        this.state.networkConfigurationsByChainId,\n      );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:getEthQuery`,\n      () => {\n        return this.#ethQuery;\n      },\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:getNetworkClientById`,\n      this.getNetworkClientById.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:getEIP1559Compatibility`,\n      this.getEIP1559Compatibility.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:setActiveNetwork`,\n      this.setActiveNetwork.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:setProviderType`,\n      this.setProviderType.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:findNetworkClientIdByChainId`,\n      this.findNetworkClientIdByChainId.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:getNetworkConfigurationByChainId`,\n      this.getNetworkConfigurationByChainId.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // ESLint is mistaken here; `name` is a string.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:getNetworkConfigurationByNetworkClientId`,\n      this.getNetworkConfigurationByNetworkClientId.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      `${this.name}:getSelectedNetworkClient`,\n      this.getSelectedNetworkClient.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      `${this.name}:getSelectedChainId`,\n      this.getSelectedChainId.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // ESLint is mistaken here; `name` is a string.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:addNetwork`,\n      this.addNetwork.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // ESLint is mistaken here; `name` is a string.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:removeNetwork`,\n      this.removeNetwork.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      // ESLint is mistaken here; `name` is a string.\n      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n      `${this.name}:updateNetwork`,\n      this.updateNetwork.bind(this),\n    );\n  }\n\n  /**\n   * Accesses the provider and block tracker for the currently selected network.\n   * @returns The proxy and block tracker proxies.\n   * @deprecated This method has been replaced by `getSelectedNetworkClient` (which has a more easily used return type) and will be removed in a future release.\n   */\n  getProviderAndBlockTracker(): {\n    provider: SwappableProxy<ProxyWithAccessibleTarget<Provider>> | undefined;\n    blockTracker:\n      | SwappableProxy<ProxyWithAccessibleTarget<BlockTracker>>\n      | undefined;\n  } {\n    return {\n      provider: this.#providerProxy,\n      blockTracker: this.#blockTrackerProxy,\n    };\n  }\n\n  /**\n   * Accesses the provider and block tracker for the currently selected network.\n   *\n   * @returns an object with the provider and block tracker proxies for the currently selected network.\n   */\n  getSelectedNetworkClient():\n    | {\n        provider: SwappableProxy<ProxyWithAccessibleTarget<Provider>>;\n        blockTracker: SwappableProxy<ProxyWithAccessibleTarget<BlockTracker>>;\n      }\n    | undefined {\n    if (this.#providerProxy && this.#blockTrackerProxy) {\n      return {\n        provider: this.#providerProxy,\n        blockTracker: this.#blockTrackerProxy,\n      };\n    }\n    return undefined;\n  }\n\n  /**\n   * Accesses the chain ID from the selected network client.\n   *\n   * @returns The chain ID of the selected network client in hex format or undefined if there is no network client.\n   */\n  getSelectedChainId(): Hex | undefined {\n    const networkConfiguration = this.getNetworkConfigurationByNetworkClientId(\n      this.state.selectedNetworkClientId,\n    );\n    return networkConfiguration?.chainId;\n  }\n\n  /**\n   * Internally, the Infura and custom network clients are categorized by type\n   * so that when accessing either kind of network client, TypeScript knows\n   * which type to assign to the network client. For some cases it's more useful\n   * to be able to access network clients by ID instead of by type and then ID,\n   * so this function makes that possible.\n   *\n   * @returns The network clients registered so far, keyed by ID.\n   */\n  getNetworkClientRegistry(): AutoManagedBuiltInNetworkClientRegistry &\n    AutoManagedCustomNetworkClientRegistry {\n    const autoManagedNetworkClientRegistry =\n      this.#ensureAutoManagedNetworkClientRegistryPopulated();\n\n    return Object.assign(\n      {},\n      autoManagedNetworkClientRegistry[NetworkClientType.Infura],\n      autoManagedNetworkClientRegistry[NetworkClientType.Custom],\n    );\n  }\n\n  /**\n   * Returns the Infura network client with the given ID.\n   *\n   * @param infuraNetworkClientId - An Infura network client ID.\n   * @returns The Infura network client.\n   * @throws If an Infura network client does not exist with the given ID.\n   */\n  getNetworkClientById(\n    infuraNetworkClientId: BuiltInNetworkClientId,\n  ): AutoManagedNetworkClient<InfuraNetworkClientConfiguration>;\n\n  /**\n   * Returns the custom network client with the given ID.\n   *\n   * @param customNetworkClientId - A custom network client ID.\n   * @returns The custom network client.\n   * @throws If a custom network client does not exist with the given ID.\n   */\n  getNetworkClientById(\n    customNetworkClientId: CustomNetworkClientId,\n  ): AutoManagedNetworkClient<CustomNetworkClientConfiguration>;\n\n  getNetworkClientById(\n    networkClientId: NetworkClientId,\n  ): AutoManagedNetworkClient<NetworkClientConfiguration> {\n    if (!networkClientId) {\n      throw new Error('No network client ID was provided.');\n    }\n\n    const autoManagedNetworkClientRegistry =\n      this.#ensureAutoManagedNetworkClientRegistryPopulated();\n\n    if (isInfuraNetworkType(networkClientId)) {\n      const infuraNetworkClient =\n        autoManagedNetworkClientRegistry[NetworkClientType.Infura][\n          networkClientId\n        ];\n      // This is impossible to reach\n      /* istanbul ignore if */\n      if (!infuraNetworkClient) {\n        throw new Error(\n          // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n          `No Infura network client was found with the ID \"${networkClientId}\".`,\n        );\n      }\n      return infuraNetworkClient;\n    }\n\n    const customNetworkClient =\n      autoManagedNetworkClientRegistry[NetworkClientType.Custom][\n        networkClientId\n      ];\n    if (!customNetworkClient) {\n      throw new Error(\n        // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n        `No custom network client was found with the ID \"${networkClientId}\".`,\n      );\n    }\n    return customNetworkClient;\n  }\n\n  /**\n   * Executes a series of steps to switch the network:\n   *\n   * 1. Notifies subscribers via the messenger that the network is about to be\n   * switched (and, really, that the global provider and block tracker proxies\n   * will be re-pointed to a new network).\n   * 2. Looks up a known and preinitialized network client matching the given\n   * ID and uses it to re-point the aforementioned provider and block tracker\n   * proxies.\n   * 3. Notifies subscribers via the messenger that the network has switched.\n   * 4. Captures metadata for the newly switched network in state.\n   *\n   * @param networkClientId - The ID of a network client that requests will be\n   * routed through (either the name of an Infura network or the ID of a custom\n   * network configuration).\n   * @param options - Options for this method.\n   * @param options.updateState - Allows for updating state.\n   */\n  async #refreshNetwork(\n    networkClientId: string,\n    options: {\n      updateState?: (state: Draft<NetworkState>) => void;\n    } = {},\n  ) {\n    this.messagingSystem.publish(\n      'NetworkController:networkWillChange',\n      this.state,\n    );\n    this.#applyNetworkSelection(networkClientId, options);\n    this.messagingSystem.publish(\n      'NetworkController:networkDidChange',\n      this.state,\n    );\n    await this.lookupNetwork();\n  }\n\n  /**\n   * Ensures that network clients for Infura and custom RPC endpoints have been\n   * created. Then, consulting state, initializes and establishes the currently\n   * selected network client.\n   */\n  async initializeProvider() {\n    this.#applyNetworkSelection(this.state.selectedNetworkClientId);\n    await this.lookupNetwork();\n  }\n\n  /**\n   * Refreshes the network meta with EIP-1559 support and the network status\n   * based on the given network client ID.\n   *\n   * @param networkClientId - The ID of the network client to update.\n   */\n  async lookupNetworkByClientId(networkClientId: NetworkClientId) {\n    const isInfura = isInfuraNetworkType(networkClientId);\n    let updatedNetworkStatus: NetworkStatus;\n    let updatedIsEIP1559Compatible: boolean | undefined;\n\n    try {\n      updatedIsEIP1559Compatible =\n        await this.#determineEIP1559Compatibility(networkClientId);\n      updatedNetworkStatus = NetworkStatus.Available;\n    } catch (error) {\n      debugLog('NetworkController: lookupNetworkByClientId: ', error);\n\n      // TODO: mock ethQuery.sendAsync to throw error without error code\n      /* istanbul ignore else */\n      if (isErrorWithCode(error)) {\n        let responseBody;\n        if (\n          isInfura &&\n          hasProperty(error, 'message') &&\n          typeof error.message === 'string'\n        ) {\n          try {\n            responseBody = JSON.parse(error.message);\n          } catch {\n            // error.message must not be JSON\n            this.#log?.warn(\n              'NetworkController: lookupNetworkByClientId: json parse error: ',\n              error,\n            );\n          }\n        }\n\n        if (\n          isPlainObject(responseBody) &&\n          responseBody.error === INFURA_BLOCKED_KEY\n        ) {\n          updatedNetworkStatus = NetworkStatus.Blocked;\n        } else if (error.code === errorCodes.rpc.internal) {\n          updatedNetworkStatus = NetworkStatus.Unknown;\n          this.#log?.warn(\n            'NetworkController: lookupNetworkByClientId: rpc internal error: ',\n            error,\n          );\n        } else {\n          updatedNetworkStatus = NetworkStatus.Unavailable;\n          this.#log?.warn(\n            'NetworkController: lookupNetworkByClientId: ',\n            error,\n          );\n        }\n      } else if (\n        typeof Error !== 'undefined' &&\n        hasProperty(error as unknown as Error, 'message') &&\n        typeof (error as unknown as Error).message === 'string' &&\n        (error as unknown as Error).message.includes(\n          'No custom network client was found with the ID',\n        )\n      ) {\n        throw error;\n      } else {\n        debugLog(\n          'NetworkController - could not determine network status',\n          error,\n        );\n        updatedNetworkStatus = NetworkStatus.Unknown;\n        this.#log?.warn('NetworkController: lookupNetworkByClientId: ', error);\n      }\n    }\n    this.update((state) => {\n      if (state.networksMetadata[networkClientId] === undefined) {\n        state.networksMetadata[networkClientId] = {\n          status: NetworkStatus.Unknown,\n          EIPS: {},\n        };\n      }\n      const meta = state.networksMetadata[networkClientId];\n      meta.status = updatedNetworkStatus;\n      if (updatedIsEIP1559Compatible === undefined) {\n        delete meta.EIPS[1559];\n      } else {\n        meta.EIPS[1559] = updatedIsEIP1559Compatible;\n      }\n    });\n  }\n\n  /**\n   * Persists the following metadata about the given or selected network to\n   * state:\n   *\n   * - The status of the network, namely, whether it is available, geo-blocked\n   * (Infura only), or unavailable, or whether the status is unknown\n   * - Whether the network supports EIP-1559, or whether it is unknown\n   *\n   * Note that it is possible for the network to be switched while this data is\n   * being collected. If that is the case, no metadata for the (now previously)\n   * selected network will be updated.\n   *\n   * @param networkClientId - The ID of the network client to update.\n   * If no ID is provided, uses the currently selected network.\n   */\n  async lookupNetwork(networkClientId?: NetworkClientId) {\n    if (networkClientId) {\n      await this.lookupNetworkByClientId(networkClientId);\n      return;\n    }\n\n    if (!this.#ethQuery) {\n      return;\n    }\n\n    const isInfura =\n      this.#autoManagedNetworkClient?.configuration.type ===\n      NetworkClientType.Infura;\n\n    let networkChanged = false;\n    const listener = () => {\n      networkChanged = true;\n      try {\n        this.messagingSystem.unsubscribe(\n          'NetworkController:networkDidChange',\n          listener,\n        );\n      } catch (error) {\n        // In theory, this `catch` should not be necessary given that this error\n        // would occur \"inside\" of the call to `#determineEIP1559Compatibility`\n        // below and so it should be caught by the `try`/`catch` below (it is\n        // impossible to reproduce in tests for that reason). However, somehow\n        // it occurs within Mobile and so we have to add our own `try`/`catch`\n        // here.\n        /* istanbul ignore next */\n        if (\n          !(error instanceof Error) ||\n          error.message !==\n            'Subscription not found for event: NetworkController:networkDidChange'\n        ) {\n          // Again, this error should not happen and is impossible to reproduce\n          // in tests.\n          /* istanbul ignore next */\n          throw error;\n        }\n      }\n    };\n    this.messagingSystem.subscribe(\n      'NetworkController:networkDidChange',\n      listener,\n    );\n\n    let updatedNetworkStatus: NetworkStatus;\n    let updatedIsEIP1559Compatible: boolean | undefined;\n\n    try {\n      const isEIP1559Compatible = await this.#determineEIP1559Compatibility(\n        this.state.selectedNetworkClientId,\n      );\n      updatedNetworkStatus = NetworkStatus.Available;\n      updatedIsEIP1559Compatible = isEIP1559Compatible;\n    } catch (error) {\n      // TODO: mock ethQuery.sendAsync to throw error without error code\n      /* istanbul ignore else */\n      if (isErrorWithCode(error)) {\n        let responseBody;\n        if (\n          isInfura &&\n          hasProperty(error, 'message') &&\n          typeof error.message === 'string'\n        ) {\n          try {\n            responseBody = JSON.parse(error.message);\n          } catch (parseError) {\n            // error.message must not be JSON\n            this.#log?.warn(\n              'NetworkController: lookupNetwork: json parse error',\n              parseError,\n            );\n          }\n        }\n\n        if (\n          isPlainObject(responseBody) &&\n          responseBody.error === INFURA_BLOCKED_KEY\n        ) {\n          updatedNetworkStatus = NetworkStatus.Blocked;\n        } else if (error.code === errorCodes.rpc.internal) {\n          updatedNetworkStatus = NetworkStatus.Unknown;\n          this.#log?.warn(\n            'NetworkController: lookupNetwork: rpc internal error',\n            error,\n          );\n        } else {\n          updatedNetworkStatus = NetworkStatus.Unavailable;\n          this.#log?.warn('NetworkController: lookupNetwork: ', error);\n        }\n      } else {\n        debugLog(\n          'NetworkController - could not determine network status',\n          error,\n        );\n        updatedNetworkStatus = NetworkStatus.Unknown;\n        this.#log?.warn('NetworkController: lookupNetwork: ', error);\n      }\n    }\n\n    if (networkChanged) {\n      // If the network has changed, then `lookupNetwork` either has been or is\n      // in the process of being called, so we don't need to go further.\n      return;\n    }\n\n    try {\n      this.messagingSystem.unsubscribe(\n        'NetworkController:networkDidChange',\n        listener,\n      );\n    } catch (error) {\n      if (\n        !(error instanceof Error) ||\n        error.message !==\n          'Subscription not found for event: NetworkController:networkDidChange'\n      ) {\n        throw error;\n      }\n    }\n\n    this.update((state) => {\n      const meta = state.networksMetadata[state.selectedNetworkClientId];\n      meta.status = updatedNetworkStatus;\n      if (updatedIsEIP1559Compatible === undefined) {\n        delete meta.EIPS[1559];\n      } else {\n        meta.EIPS[1559] = updatedIsEIP1559Compatible;\n      }\n    });\n\n    if (isInfura) {\n      if (updatedNetworkStatus === NetworkStatus.Available) {\n        this.messagingSystem.publish('NetworkController:infuraIsUnblocked');\n      } else if (updatedNetworkStatus === NetworkStatus.Blocked) {\n        this.messagingSystem.publish('NetworkController:infuraIsBlocked');\n      }\n    } else {\n      // Always publish infuraIsUnblocked regardless of network status to\n      // prevent consumers from being stuck in a blocked state if they were\n      // previously connected to an Infura network that was blocked\n      this.messagingSystem.publish('NetworkController:infuraIsUnblocked');\n    }\n  }\n\n  /**\n   * Convenience method to update provider network type settings.\n   *\n   * @param type - Human readable network name.\n   * @deprecated This has been replaced by `setActiveNetwork`, and will be\n   * removed in a future release\n   */\n  async setProviderType(type: InfuraNetworkType) {\n    if ((type as unknown) === NetworkType.rpc) {\n      throw new Error(\n        // This ESLint rule mistakenly produces an error.\n        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n        `NetworkController - cannot call \"setProviderType\" with type \"${NetworkType.rpc}\". Use \"setActiveNetwork\"`,\n      );\n    }\n    if (!isInfuraNetworkType(type)) {\n      throw new Error(`Unknown Infura provider type \"${String(type)}\".`);\n    }\n\n    await this.setActiveNetwork(type);\n  }\n\n  /**\n   * Changes the selected network.\n   *\n   * @param networkClientId - The ID of a network client that will be used to\n   * make requests.\n   * @param options - Options for this method.\n   * @param options.updateState - Allows for updating state.\n   * @throws if no network client is associated with the given\n   * network client ID.\n   */\n  async setActiveNetwork(\n    networkClientId: string,\n    options: {\n      updateState?: (state: Draft<NetworkState>) => void;\n    } = {},\n  ) {\n    this.#previouslySelectedNetworkClientId =\n      this.state.selectedNetworkClientId;\n\n    await this.#refreshNetwork(networkClientId, options);\n  }\n\n  /**\n   * Fetches the latest block for the network.\n   *\n   * @param networkClientId - The networkClientId to fetch the correct provider against which to check the latest block. Defaults to the selectedNetworkClientId.\n   * @returns A promise that either resolves to the block header or null if\n   * there is no latest block, or rejects with an error.\n   */\n  #getLatestBlock(networkClientId: NetworkClientId): Promise<Block> {\n    if (networkClientId === undefined) {\n      networkClientId = this.state.selectedNetworkClientId;\n    }\n\n    const networkClient = this.getNetworkClientById(networkClientId);\n    const ethQuery = new EthQuery(networkClient.provider);\n\n    return new Promise((resolve, reject) => {\n      ethQuery.sendAsync(\n        { method: 'eth_getBlockByNumber', params: ['latest', false] },\n        (error: unknown, block?: unknown) => {\n          if (error) {\n            reject(error);\n          } else {\n            // TODO: Validate this type\n            resolve(block as Block);\n          }\n        },\n      );\n    });\n  }\n\n  /**\n   * Determines whether the network supports EIP-1559 by checking whether the\n   * latest block has a `baseFeePerGas` property, then updates state\n   * appropriately.\n   *\n   * @param networkClientId - The networkClientId to fetch the correct provider against which to check 1559 compatibility.\n   * @returns A promise that resolves to true if the network supports EIP-1559\n   * , false otherwise, or `undefined` if unable to determine the compatibility.\n   */\n  async getEIP1559Compatibility(networkClientId?: NetworkClientId) {\n    if (networkClientId) {\n      return this.get1559CompatibilityWithNetworkClientId(networkClientId);\n    }\n    if (!this.#ethQuery) {\n      return false;\n    }\n\n    const { EIPS } =\n      this.state.networksMetadata[this.state.selectedNetworkClientId];\n\n    if (EIPS[1559] !== undefined) {\n      return EIPS[1559];\n    }\n\n    const isEIP1559Compatible = await this.#determineEIP1559Compatibility(\n      this.state.selectedNetworkClientId,\n    );\n    this.update((state) => {\n      if (isEIP1559Compatible !== undefined) {\n        state.networksMetadata[state.selectedNetworkClientId].EIPS[1559] =\n          isEIP1559Compatible;\n      }\n    });\n    return isEIP1559Compatible;\n  }\n\n  async get1559CompatibilityWithNetworkClientId(\n    networkClientId: NetworkClientId,\n  ) {\n    let metadata = this.state.networksMetadata[networkClientId];\n    if (metadata === undefined) {\n      await this.lookupNetwork(networkClientId);\n      metadata = this.state.networksMetadata[networkClientId];\n    }\n    const { EIPS } = metadata;\n\n    // may want to include some 'freshness' value - something to make sure we refetch this from time to time\n    return EIPS[1559];\n  }\n\n  /**\n   * Retrieves and checks the latest block from the currently selected\n   * network; if the block has a `baseFeePerGas` property, then we know\n   * that the network supports EIP-1559; otherwise it doesn't.\n   *\n   * @param networkClientId - The networkClientId to fetch the correct provider against which to check 1559 compatibility\n   * @returns A promise that resolves to `true` if the network supports EIP-1559,\n   * `false` otherwise, or `undefined` if unable to retrieve the last block.\n   */\n  async #determineEIP1559Compatibility(\n    networkClientId: NetworkClientId,\n  ): Promise<boolean | undefined> {\n    const latestBlock = await this.#getLatestBlock(networkClientId);\n\n    if (!latestBlock) {\n      return undefined;\n    }\n\n    return latestBlock.baseFeePerGas !== undefined;\n  }\n\n  /**\n   * Ensures that the provider and block tracker proxies are pointed to the\n   * currently selected network and refreshes the metadata for the\n   */\n  async resetConnection() {\n    await this.#refreshNetwork(this.state.selectedNetworkClientId);\n  }\n\n  /**\n   * Returns the network configuration that has been filed under the given chain\n   * ID.\n   *\n   * @param chainId - The chain ID to use as a key.\n   * @returns The network configuration if one exists, or undefined.\n   */\n  getNetworkConfigurationByChainId(\n    chainId: Hex,\n  ): NetworkConfiguration | undefined {\n    return this.state.networkConfigurationsByChainId[chainId];\n  }\n\n  /**\n   * Returns the network configuration that contains an RPC endpoint with the\n   * given network client ID.\n   *\n   * @param networkClientId - The network client ID to use as a key.\n   * @returns The network configuration if one exists, or undefined.\n   */\n  getNetworkConfigurationByNetworkClientId(\n    networkClientId: NetworkClientId,\n  ): NetworkConfiguration | undefined {\n    return this.#networkConfigurationsByNetworkClientId.get(networkClientId);\n  }\n\n  /**\n   * Creates and registers network clients for the collection of Infura and\n   * custom RPC endpoints that can be used to make requests for a particular\n   * chain, storing the given configuration object in state for later reference.\n   *\n   * @param fields - The object that describes the new network/chain and lists\n   * the RPC endpoints which front that chain.\n   * @returns The newly added network configuration.\n   * @throws if any part of `fields` would produce invalid state.\n   * @see {@link NetworkConfiguration}\n   */\n  addNetwork(fields: AddNetworkFields): NetworkConfiguration {\n    const { rpcEndpoints: setOfRpcEndpointFields } = fields;\n\n    const autoManagedNetworkClientRegistry =\n      this.#ensureAutoManagedNetworkClientRegistryPopulated();\n\n    this.#validateNetworkFields({\n      mode: 'add',\n      networkFields: fields,\n      autoManagedNetworkClientRegistry,\n    });\n\n    const networkClientOperations = setOfRpcEndpointFields.map(\n      (defaultOrCustomRpcEndpointFields) => {\n        const rpcEndpoint =\n          defaultOrCustomRpcEndpointFields.type === RpcEndpointType.Custom\n            ? {\n                ...defaultOrCustomRpcEndpointFields,\n                networkClientId: uuidV4(),\n              }\n            : defaultOrCustomRpcEndpointFields;\n        return {\n          type: 'add' as const,\n          rpcEndpoint,\n        };\n      },\n    );\n\n    const newNetworkConfiguration =\n      this.#determineNetworkConfigurationToPersist({\n        networkFields: fields,\n        networkClientOperations,\n      });\n    this.#registerNetworkClientsAsNeeded({\n      networkFields: fields,\n      networkClientOperations,\n      autoManagedNetworkClientRegistry,\n    });\n    this.update((state) => {\n      this.#updateNetworkConfigurations({\n        state,\n        mode: 'add',\n        networkFields: fields,\n        networkConfigurationToPersist: newNetworkConfiguration,\n      });\n    });\n\n    this.messagingSystem.publish(\n      `${controllerName}:networkAdded`,\n      newNetworkConfiguration,\n    );\n\n    return newNetworkConfiguration;\n  }\n\n  /**\n   * Updates the configuration for a previously stored network filed under the\n   * given chain ID, creating + registering new network clients to represent RPC\n   * endpoints that have been added and destroying + unregistering existing\n   * network clients for RPC endpoints that have been removed.\n   *\n   * Note that if `chainId` is changed, then all network clients associated with\n   * that chain will be removed and re-added, even if none of the RPC endpoints\n   * have changed.\n   *\n   * @param chainId - The chain ID associated with an existing network.\n   * @param fields - The object that describes the updates to the network/chain,\n   * including the new set of RPC endpoints which should front that chain.\n   * @param options - Options to provide.\n   * @param options.replacementSelectedRpcEndpointIndex - Usually you cannot\n   * remove an RPC endpoint that is being represented by the currently selected\n   * network client. This option allows you to specify another RPC endpoint\n   * (either an existing one or a new one) that should be used to select a new\n   * network instead.\n   * @returns The updated network configuration.\n   * @throws if `chainId` does not refer to an existing network configuration,\n   * if any part of `fields` would produce invalid state, etc.\n   * @see {@link NetworkConfiguration}\n   */\n  async updateNetwork(\n    chainId: Hex,\n    fields: UpdateNetworkFields,\n    {\n      replacementSelectedRpcEndpointIndex,\n    }: { replacementSelectedRpcEndpointIndex?: number } = {},\n  ): Promise<NetworkConfiguration> {\n    const existingNetworkConfiguration =\n      this.state.networkConfigurationsByChainId[chainId];\n\n    if (existingNetworkConfiguration === undefined) {\n      throw new Error(\n        `Could not update network: Cannot find network configuration for chain '${chainId}'`,\n      );\n    }\n\n    const existingChainId = chainId;\n    const { chainId: newChainId, rpcEndpoints: setOfNewRpcEndpointFields } =\n      fields;\n\n    const autoManagedNetworkClientRegistry =\n      this.#ensureAutoManagedNetworkClientRegistryPopulated();\n\n    this.#validateNetworkFields({\n      mode: 'update',\n      networkFields: fields,\n      existingNetworkConfiguration,\n      autoManagedNetworkClientRegistry,\n    });\n\n    const networkClientOperations: NetworkClientOperation[] = [];\n\n    for (const newRpcEndpointFields of setOfNewRpcEndpointFields) {\n      const existingRpcEndpointForNoop =\n        existingNetworkConfiguration.rpcEndpoints.find((rpcEndpoint) => {\n          return (\n            rpcEndpoint.type === newRpcEndpointFields.type &&\n            rpcEndpoint.url === newRpcEndpointFields.url &&\n            (rpcEndpoint.networkClientId ===\n              newRpcEndpointFields.networkClientId ||\n              newRpcEndpointFields.networkClientId === undefined)\n          );\n        });\n      const existingRpcEndpointForReplaceWhenChainChanged =\n        existingNetworkConfiguration.rpcEndpoints.find((rpcEndpoint) => {\n          return (\n            (rpcEndpoint.type === RpcEndpointType.Infura &&\n              newRpcEndpointFields.type === RpcEndpointType.Infura) ||\n            (rpcEndpoint.type === newRpcEndpointFields.type &&\n              rpcEndpoint.networkClientId ===\n                newRpcEndpointFields.networkClientId &&\n              rpcEndpoint.url === newRpcEndpointFields.url)\n          );\n        });\n      const existingRpcEndpointForReplaceWhenChainNotChanged =\n        existingNetworkConfiguration.rpcEndpoints.find((rpcEndpoint) => {\n          return (\n            rpcEndpoint.type === newRpcEndpointFields.type &&\n            (rpcEndpoint.url === newRpcEndpointFields.url ||\n              rpcEndpoint.networkClientId ===\n                newRpcEndpointFields.networkClientId)\n          );\n        });\n\n      if (\n        newChainId !== existingChainId &&\n        existingRpcEndpointForReplaceWhenChainChanged !== undefined\n      ) {\n        const newRpcEndpoint =\n          newRpcEndpointFields.type === RpcEndpointType.Infura\n            ? newRpcEndpointFields\n            : { ...newRpcEndpointFields, networkClientId: uuidV4() };\n\n        networkClientOperations.push({\n          type: 'replace' as const,\n          oldRpcEndpoint: existingRpcEndpointForReplaceWhenChainChanged,\n          newRpcEndpoint,\n        });\n      } else if (existingRpcEndpointForNoop !== undefined) {\n        let newRpcEndpoint;\n        if (existingRpcEndpointForNoop.type === RpcEndpointType.Infura) {\n          newRpcEndpoint = existingRpcEndpointForNoop;\n        } else {\n          // `networkClientId` shouldn't be missing at this point; if it is,\n          // that's a mistake, so fill it back in\n          newRpcEndpoint = Object.assign({}, newRpcEndpointFields, {\n            networkClientId: existingRpcEndpointForNoop.networkClientId,\n          });\n        }\n        networkClientOperations.push({\n          type: 'noop' as const,\n          rpcEndpoint: newRpcEndpoint,\n        });\n      } else if (\n        existingRpcEndpointForReplaceWhenChainNotChanged !== undefined\n      ) {\n        let newRpcEndpoint;\n        /* istanbul ignore if */\n        if (newRpcEndpointFields.type === RpcEndpointType.Infura) {\n          // This case can't actually happen. If we're here, it means that some\n          // part of the RPC endpoint changed. But there is no part of an Infura\n          // RPC endpoint that can be changed (as it would immediately make that\n          // RPC endpoint self-inconsistent). This is just here to appease\n          // TypeScript.\n          newRpcEndpoint = newRpcEndpointFields;\n        } else {\n          newRpcEndpoint = {\n            ...newRpcEndpointFields,\n            networkClientId: uuidV4(),\n          };\n        }\n\n        networkClientOperations.push({\n          type: 'replace' as const,\n          oldRpcEndpoint: existingRpcEndpointForReplaceWhenChainNotChanged,\n          newRpcEndpoint,\n        });\n      } else {\n        const newRpcEndpoint =\n          newRpcEndpointFields.type === RpcEndpointType.Infura\n            ? newRpcEndpointFields\n            : { ...newRpcEndpointFields, networkClientId: uuidV4() };\n        const networkClientOperation = {\n          type: 'add' as const,\n          rpcEndpoint: newRpcEndpoint,\n        };\n        networkClientOperations.push(networkClientOperation);\n      }\n    }\n\n    for (const existingRpcEndpoint of existingNetworkConfiguration.rpcEndpoints) {\n      if (\n        !networkClientOperations.some((networkClientOperation) => {\n          const otherRpcEndpoint =\n            networkClientOperation.type === 'replace'\n              ? networkClientOperation.oldRpcEndpoint\n              : networkClientOperation.rpcEndpoint;\n          return (\n            otherRpcEndpoint.type === existingRpcEndpoint.type &&\n            otherRpcEndpoint.networkClientId ===\n              existingRpcEndpoint.networkClientId &&\n            otherRpcEndpoint.url === existingRpcEndpoint.url\n          );\n        })\n      ) {\n        const networkClientOperation = {\n          type: 'remove' as const,\n          rpcEndpoint: existingRpcEndpoint,\n        };\n        networkClientOperations.push(networkClientOperation);\n      }\n    }\n\n    const updatedNetworkConfiguration =\n      this.#determineNetworkConfigurationToPersist({\n        networkFields: fields,\n        networkClientOperations,\n      });\n\n    if (\n      replacementSelectedRpcEndpointIndex === undefined &&\n      networkClientOperations.some((networkClientOperation) => {\n        return (\n          networkClientOperation.type === 'remove' &&\n          networkClientOperation.rpcEndpoint.networkClientId ===\n            this.state.selectedNetworkClientId\n        );\n      }) &&\n      !networkClientOperations.some((networkClientOperation) => {\n        return (\n          networkClientOperation.type === 'replace' &&\n          networkClientOperation.oldRpcEndpoint.networkClientId ===\n            this.state.selectedNetworkClientId\n        );\n      })\n    ) {\n      throw new Error(\n        // This ESLint rule mistakenly produces an error.\n        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n        `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.`,\n      );\n    }\n\n    this.#registerNetworkClientsAsNeeded({\n      networkFields: fields,\n      networkClientOperations,\n      autoManagedNetworkClientRegistry,\n    });\n\n    const replacementSelectedRpcEndpointWithIndex = networkClientOperations\n      .map(\n        (networkClientOperation, index) =>\n          [networkClientOperation, index] as const,\n      )\n      .find(([networkClientOperation, _index]) => {\n        return (\n          networkClientOperation.type === 'replace' &&\n          networkClientOperation.oldRpcEndpoint.networkClientId ===\n            this.state.selectedNetworkClientId\n        );\n      });\n    const correctedReplacementSelectedRpcEndpointIndex =\n      replacementSelectedRpcEndpointIndex ??\n      replacementSelectedRpcEndpointWithIndex?.[1];\n\n    let rpcEndpointToSelect: RpcEndpoint | undefined;\n    if (correctedReplacementSelectedRpcEndpointIndex !== undefined) {\n      rpcEndpointToSelect =\n        updatedNetworkConfiguration.rpcEndpoints[\n          correctedReplacementSelectedRpcEndpointIndex\n        ];\n\n      if (rpcEndpointToSelect === undefined) {\n        throw new Error(\n          `Could not update network: \\`replacementSelectedRpcEndpointIndex\\` ${correctedReplacementSelectedRpcEndpointIndex} does not refer to an entry in \\`rpcEndpoints\\``,\n        );\n      }\n    }\n\n    if (\n      rpcEndpointToSelect &&\n      rpcEndpointToSelect.networkClientId !== this.state.selectedNetworkClientId\n    ) {\n      await this.setActiveNetwork(rpcEndpointToSelect.networkClientId, {\n        updateState: (state) => {\n          this.#updateNetworkConfigurations({\n            state,\n            mode: 'update',\n            networkFields: fields,\n            networkConfigurationToPersist: updatedNetworkConfiguration,\n            existingNetworkConfiguration,\n          });\n        },\n      });\n    } else {\n      this.update((state) => {\n        this.#updateNetworkConfigurations({\n          state,\n          mode: 'update',\n          networkFields: fields,\n          networkConfigurationToPersist: updatedNetworkConfiguration,\n          existingNetworkConfiguration,\n        });\n      });\n    }\n\n    this.#unregisterNetworkClientsAsNeeded({\n      networkClientOperations,\n      autoManagedNetworkClientRegistry,\n    });\n\n    return updatedNetworkConfiguration;\n  }\n\n  /**\n   * Destroys and unregisters the network identified by the given chain ID, also\n   * removing the associated network configuration from state.\n   *\n   * @param chainId - The chain ID associated with an existing network.\n   * @throws if `chainId` does not refer to an existing network configuration,\n   * or if the currently selected network is being removed.\n   * @see {@link NetworkConfiguration}\n   */\n  removeNetwork(chainId: Hex) {\n    const existingNetworkConfiguration =\n      this.state.networkConfigurationsByChainId[chainId];\n\n    if (existingNetworkConfiguration === undefined) {\n      throw new Error(\n        `Cannot find network configuration for chain '${chainId}'`,\n      );\n    }\n\n    if (\n      existingNetworkConfiguration.rpcEndpoints.some(\n        (rpcEndpoint) =>\n          rpcEndpoint.networkClientId === this.state.selectedNetworkClientId,\n      )\n    ) {\n      throw new Error(`Cannot remove the currently selected network`);\n    }\n\n    const autoManagedNetworkClientRegistry =\n      this.#ensureAutoManagedNetworkClientRegistryPopulated();\n\n    const networkClientOperations =\n      existingNetworkConfiguration.rpcEndpoints.map((rpcEndpoint) => {\n        return {\n          type: 'remove' as const,\n          rpcEndpoint,\n        };\n      });\n\n    this.#unregisterNetworkClientsAsNeeded({\n      networkClientOperations,\n      autoManagedNetworkClientRegistry,\n    });\n    this.update((state) => {\n      this.#updateNetworkConfigurations({\n        state,\n        mode: 'remove',\n        existingNetworkConfiguration,\n      });\n    });\n\n    this.messagingSystem.publish(\n      'NetworkController:networkRemoved',\n      existingNetworkConfiguration,\n    );\n  }\n\n  /**\n   * Assuming that the network has been previously switched, switches to this\n   * new network.\n   *\n   * If the network has not been previously switched, this method is equivalent\n   * to {@link resetConnection}.\n   */\n  async rollbackToPreviousProvider() {\n    await this.#refreshNetwork(this.#previouslySelectedNetworkClientId);\n  }\n\n  /**\n   * Deactivates the controller, stopping any ongoing polling.\n   *\n   * In-progress requests will not be aborted.\n   */\n  async destroy() {\n    await this.#blockTrackerProxy?.destroy();\n  }\n\n  /**\n   * Merges the given backup data into controller state.\n   *\n   * @param backup - The data that has been backed up.\n   * @param backup.networkConfigurationsByChainId - Network configurations,\n   * keyed by chain ID.\n   */\n  loadBackup({\n    networkConfigurationsByChainId,\n  }: Pick<NetworkState, 'networkConfigurationsByChainId'>): void {\n    this.update((state) => {\n      state.networkConfigurationsByChainId = {\n        ...state.networkConfigurationsByChainId,\n        ...networkConfigurationsByChainId,\n      };\n    });\n  }\n\n  /**\n   * Searches for the default RPC endpoint configured for the given chain and\n   * returns its network client ID. This can then be passed to\n   * {@link getNetworkClientById} to retrieve the network client.\n   *\n   * @param chainId - Chain ID to search for.\n   * @returns The ID of the network client created for the chain's default RPC\n   * endpoint.\n   */\n  findNetworkClientIdByChainId(chainId: Hex): NetworkClientId {\n    const networkConfiguration =\n      this.state.networkConfigurationsByChainId[chainId];\n\n    if (!networkConfiguration) {\n      throw new Error(`Invalid chain ID \"${chainId}\"`);\n    }\n\n    const { networkClientId } =\n      networkConfiguration.rpcEndpoints[\n        networkConfiguration.defaultRpcEndpointIndex\n      ];\n    return networkClientId;\n  }\n\n  /**\n   * Ensure that the given fields which will be used to either add or update a\n   * network are valid.\n   *\n   * @param args - The arguments.\n   */\n  #validateNetworkFields(\n    args: {\n      autoManagedNetworkClientRegistry: AutoManagedNetworkClientRegistry;\n    } & (\n      | {\n          mode: 'add';\n          networkFields: AddNetworkFields;\n        }\n      | {\n          mode: 'update';\n          existingNetworkConfiguration: NetworkConfiguration;\n          networkFields: UpdateNetworkFields;\n        }\n    ),\n  ) {\n    const { mode, networkFields, autoManagedNetworkClientRegistry } = args;\n    const existingNetworkConfiguration =\n      'existingNetworkConfiguration' in args\n        ? args.existingNetworkConfiguration\n        : null;\n\n    const errorMessagePrefix =\n      mode === 'update' ? 'Could not update network' : 'Could not add network';\n\n    if (\n      !isStrictHexString(networkFields.chainId) ||\n      !isSafeChainId(networkFields.chainId)\n    ) {\n      throw new Error(\n        `${errorMessagePrefix}: Invalid \\`chainId\\` '${networkFields.chainId}' (must start with \"0x\" and not exceed the maximum)`,\n      );\n    }\n\n    if (\n      existingNetworkConfiguration === null ||\n      networkFields.chainId !== existingNetworkConfiguration.chainId\n    ) {\n      const existingNetworkConfigurationViaChainId =\n        this.state.networkConfigurationsByChainId[networkFields.chainId];\n      if (existingNetworkConfigurationViaChainId !== undefined) {\n        if (existingNetworkConfiguration === null) {\n          throw new Error(\n            // This ESLint rule mistakenly produces an error.\n            // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n            `Could not add network for chain ${args.networkFields.chainId} as another network for that chain already exists ('${existingNetworkConfigurationViaChainId.name}')`,\n          );\n        } else {\n          throw new Error(\n            // This ESLint rule mistakenly produces an error.\n            // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n            `Cannot move network from chain ${existingNetworkConfiguration.chainId} to ${networkFields.chainId} as another network for that chain already exists ('${existingNetworkConfigurationViaChainId.name}')`,\n          );\n        }\n      }\n    }\n\n    const isInvalidDefaultBlockExplorerUrlIndex =\n      networkFields.blockExplorerUrls.length > 0\n        ? networkFields.defaultBlockExplorerUrlIndex === undefined ||\n          networkFields.blockExplorerUrls[\n            networkFields.defaultBlockExplorerUrlIndex\n          ] === undefined\n        : networkFields.defaultBlockExplorerUrlIndex !== undefined;\n\n    if (isInvalidDefaultBlockExplorerUrlIndex) {\n      throw new Error(\n        `${errorMessagePrefix}: \\`defaultBlockExplorerUrlIndex\\` must refer to an entry in \\`blockExplorerUrls\\``,\n      );\n    }\n\n    if (networkFields.rpcEndpoints.length === 0) {\n      throw new Error(\n        `${errorMessagePrefix}: \\`rpcEndpoints\\` must be a non-empty array`,\n      );\n    }\n    for (const rpcEndpointFields of networkFields.rpcEndpoints) {\n      if (!isValidUrl(rpcEndpointFields.url)) {\n        throw new Error(\n          // This ESLint rule mistakenly produces an error.\n          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n          `${errorMessagePrefix}: An entry in \\`rpcEndpoints\\` has invalid URL '${rpcEndpointFields.url}'`,\n        );\n      }\n      const networkClientId =\n        'networkClientId' in rpcEndpointFields\n          ? rpcEndpointFields.networkClientId\n          : undefined;\n\n      if (\n        rpcEndpointFields.type === RpcEndpointType.Custom &&\n        networkClientId !== undefined &&\n        isInfuraNetworkType(networkClientId)\n      ) {\n        throw new Error(\n          // This is a string.\n          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n          `${errorMessagePrefix}: Custom RPC endpoint '${rpcEndpointFields.url}' has invalid network client ID '${networkClientId}'`,\n        );\n      }\n\n      if (\n        mode === 'update' &&\n        networkClientId !== undefined &&\n        rpcEndpointFields.type === RpcEndpointType.Custom &&\n        !Object.values(autoManagedNetworkClientRegistry).some(\n          (networkClientsById) => networkClientId in networkClientsById,\n        )\n      ) {\n        throw new Error(\n          // This is a string.\n          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n          `${errorMessagePrefix}: RPC endpoint '${rpcEndpointFields.url}' refers to network client '${networkClientId}' that does not exist`,\n        );\n      }\n\n      if (\n        networkFields.rpcEndpoints.some(\n          (otherRpcEndpointFields) =>\n            otherRpcEndpointFields !== rpcEndpointFields &&\n            URI.equal(otherRpcEndpointFields.url, rpcEndpointFields.url),\n        )\n      ) {\n        throw new Error(\n          `${errorMessagePrefix}: Each entry in rpcEndpoints must have a unique URL`,\n        );\n      }\n\n      const networkConfigurationsForOtherChains = Object.values(\n        this.state.networkConfigurationsByChainId,\n      ).filter((networkConfiguration) =>\n        existingNetworkConfiguration\n          ? networkConfiguration.chainId !==\n            existingNetworkConfiguration.chainId\n          : true,\n      );\n      for (const networkConfiguration of networkConfigurationsForOtherChains) {\n        const rpcEndpoint = networkConfiguration.rpcEndpoints.find(\n          (existingRpcEndpoint) =>\n            URI.equal(rpcEndpointFields.url, existingRpcEndpoint.url),\n        );\n        if (rpcEndpoint) {\n          if (mode === 'update') {\n            throw new Error(\n              // This ESLint rule mistakenly produces an error.\n              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n              `Could not update network to point to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`,\n            );\n          } else {\n            throw new Error(\n              // This ESLint rule mistakenly produces an error.\n              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n              `Could not add network that points to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`,\n            );\n          }\n        }\n      }\n    }\n\n    if (\n      [...new Set(networkFields.rpcEndpoints)].length <\n      networkFields.rpcEndpoints.length\n    ) {\n      throw new Error(\n        `${errorMessagePrefix}: Each entry in rpcEndpoints must be unique`,\n      );\n    }\n\n    const networkClientIds = networkFields.rpcEndpoints\n      .map((rpcEndpoint) =>\n        'networkClientId' in rpcEndpoint\n          ? rpcEndpoint.networkClientId\n          : undefined,\n      )\n      .filter(\n        (networkClientId): networkClientId is NetworkClientId =>\n          networkClientId !== undefined,\n      );\n    if ([...new Set(networkClientIds)].length < networkClientIds.length) {\n      throw new Error(\n        `${errorMessagePrefix}: Each entry in rpcEndpoints must have a unique networkClientId`,\n      );\n    }\n\n    const infuraRpcEndpoints = networkFields.rpcEndpoints.filter(\n      (rpcEndpointFields): rpcEndpointFields is InfuraRpcEndpoint =>\n        rpcEndpointFields.type === RpcEndpointType.Infura,\n    );\n    if (infuraRpcEndpoints.length > 1) {\n      throw new Error(\n        `${errorMessagePrefix}: There cannot be more than one Infura RPC endpoint`,\n      );\n    }\n\n    const soleInfuraRpcEndpoint = infuraRpcEndpoints[0];\n    if (soleInfuraRpcEndpoint) {\n      const infuraNetworkName = deriveInfuraNetworkNameFromRpcEndpointUrl(\n        soleInfuraRpcEndpoint.url,\n      );\n      const infuraNetworkNickname = NetworkNickname[infuraNetworkName];\n      const infuraChainId = ChainId[infuraNetworkName];\n      if (networkFields.chainId !== infuraChainId) {\n        throw new Error(\n          mode === 'add'\n            ? // This is a string.\n              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n              `Could not add network with chain ID ${networkFields.chainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict`\n            : // This is a string.\n              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n              `Could not update network with chain ID ${networkFields.chainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict`,\n        );\n      }\n    }\n\n    if (\n      networkFields.rpcEndpoints[networkFields.defaultRpcEndpointIndex] ===\n      undefined\n    ) {\n      throw new Error(\n        `${errorMessagePrefix}: \\`defaultRpcEndpointIndex\\` must refer to an entry in \\`rpcEndpoints\\``,\n      );\n    }\n  }\n\n  /**\n   * Constructs a network configuration that will be persisted to state when\n   * adding or updating a network.\n   *\n   * @param args - The arguments to this function.\n   * @param args.networkFields - The fields used to add or update a network.\n   * @param args.networkClientOperations - Operations which were calculated for\n   * updating the network client registry but which also map back to RPC\n   * endpoints (and so can be used to save those RPC endpoints).\n   * @returns The network configuration to persist.\n   */\n  #determineNetworkConfigurationToPersist({\n    networkFields,\n    networkClientOperations,\n  }: {\n    networkFields: AddNetworkFields | UpdateNetworkFields;\n    networkClientOperations: NetworkClientOperation[];\n  }): NetworkConfiguration {\n    const rpcEndpointsToPersist = networkClientOperations\n      .filter(\n        (\n          networkClientOperation,\n        ): networkClientOperation is\n          | AddNetworkClientOperation\n          | NoopNetworkClientOperation => {\n          return (\n            networkClientOperation.type === 'add' ||\n            networkClientOperation.type === 'noop'\n          );\n        },\n      )\n      .map((networkClientOperation) => networkClientOperation.rpcEndpoint)\n      .concat(\n        networkClientOperations\n          .filter(\n            (\n              networkClientOperation,\n            ): networkClientOperation is ReplaceNetworkClientOperation => {\n              return networkClientOperation.type === 'replace';\n            },\n          )\n          .map(\n            (networkClientOperation) => networkClientOperation.newRpcEndpoint,\n          ),\n      );\n\n    return { ...networkFields, rpcEndpoints: rpcEndpointsToPersist };\n  }\n\n  /**\n   * Creates and registers network clients using the given operations calculated\n   * as a part of adding or updating a network.\n   *\n   * @param args - The arguments to this function.\n   * @param args.networkFields - The fields used to add or update a network.\n   * @param args.networkClientOperations - Dictate which network clients need to\n   * be created.\n   * @param args.autoManagedNetworkClientRegistry - The network client registry\n   * to update.\n   */\n  #registerNetworkClientsAsNeeded({\n    networkFields,\n    networkClientOperations,\n    autoManagedNetworkClientRegistry,\n  }: {\n    networkFields: AddNetworkFields | UpdateNetworkFields;\n    networkClientOperations: NetworkClientOperation[];\n    autoManagedNetworkClientRegistry: AutoManagedNetworkClientRegistry;\n  }) {\n    const addedRpcEndpoints = networkClientOperations\n      .filter(\n        (\n          networkClientOperation,\n        ): networkClientOperation is AddNetworkClientOperation => {\n          return networkClientOperation.type === 'add';\n        },\n      )\n      .map((networkClientOperation) => networkClientOperation.rpcEndpoint)\n      .concat(\n        networkClientOperations\n          .filter(\n            (\n              networkClientOperation,\n            ): networkClientOperation is ReplaceNetworkClientOperation => {\n              return networkClientOperation.type === 'replace';\n            },\n          )\n          .map(\n            (networkClientOperation) => networkClientOperation.newRpcEndpoint,\n          ),\n      );\n\n    for (const addedRpcEndpoint of addedRpcEndpoints) {\n      if (addedRpcEndpoint.type === RpcEndpointType.Infura) {\n        autoManagedNetworkClientRegistry[NetworkClientType.Infura][\n          addedRpcEndpoint.networkClientId\n        ] = createAutoManagedNetworkClient({\n          networkClientConfiguration: {\n            type: NetworkClientType.Infura,\n            chainId: networkFields.chainId,\n            network: addedRpcEndpoint.networkClientId,\n            failoverRpcUrls: addedRpcEndpoint.failoverUrls,\n            infuraProjectId: this.#infuraProjectId,\n            ticker: networkFields.nativeCurrency,\n          },\n          getRpcServiceOptions: this.#getRpcServiceOptions,\n          messenger: this.messagingSystem,\n        });\n      } else {\n        autoManagedNetworkClientRegistry[NetworkClientType.Custom][\n          addedRpcEndpoint.networkClientId\n        ] = createAutoManagedNetworkClient({\n          networkClientConfiguration: {\n            type: NetworkClientType.Custom,\n            chainId: networkFields.chainId,\n            failoverRpcUrls: addedRpcEndpoint.failoverUrls,\n            rpcUrl: addedRpcEndpoint.url,\n            ticker: networkFields.nativeCurrency,\n          },\n          getRpcServiceOptions: this.#getRpcServiceOptions,\n          messenger: this.messagingSystem,\n        });\n      }\n    }\n  }\n\n  /**\n   * Destroys and removes network clients using the given operations calculated\n   * as a part of updating or removing a network.\n   *\n   * @param args - The arguments to this function.\n   * @param args.networkClientOperations - Dictate which network clients to\n   * remove.\n   * @param args.autoManagedNetworkClientRegistry - The network client registry\n   * to update.\n   */\n  #unregisterNetworkClientsAsNeeded({\n    networkClientOperations,\n    autoManagedNetworkClientRegistry,\n  }: {\n    networkClientOperations: NetworkClientOperation[];\n    autoManagedNetworkClientRegistry: AutoManagedNetworkClientRegistry;\n  }) {\n    const removedRpcEndpoints = networkClientOperations\n      .filter(\n        (\n          networkClientOperation,\n        ): networkClientOperation is RemoveNetworkClientOperation => {\n          return networkClientOperation.type === 'remove';\n        },\n      )\n      .map((networkClientOperation) => networkClientOperation.rpcEndpoint)\n      .concat(\n        networkClientOperations\n          .filter(\n            (\n              networkClientOperation,\n            ): networkClientOperation is ReplaceNetworkClientOperation => {\n              return networkClientOperation.type === 'replace';\n            },\n          )\n          .map(\n            (networkClientOperation) => networkClientOperation.oldRpcEndpoint,\n          ),\n      );\n\n    for (const rpcEndpoint of removedRpcEndpoints) {\n      const networkClient = this.getNetworkClientById(\n        rpcEndpoint.networkClientId,\n      );\n      networkClient.destroy();\n      delete autoManagedNetworkClientRegistry[networkClient.configuration.type][\n        rpcEndpoint.networkClientId\n      ];\n    }\n  }\n\n  /**\n   * Updates `networkConfigurationsByChainId` in state depending on whether a\n   * network is being added, updated, or removed.\n   *\n   * - The existing network configuration will be removed when a network is\n   * being filed under a different chain or removed.\n   * - A network configuration will be stored when a network is being added or\n   * when a network is being updated.\n   *\n   * @param args - The arguments to this function.\n   */\n  #updateNetworkConfigurations(\n    args: { state: Draft<NetworkState> } & (\n      | {\n          mode: 'add';\n          networkFields: AddNetworkFields;\n          networkConfigurationToPersist: NetworkConfiguration;\n        }\n      | {\n          mode: 'update';\n          networkFields: UpdateNetworkFields;\n          networkConfigurationToPersist: NetworkConfiguration;\n          existingNetworkConfiguration: NetworkConfiguration;\n        }\n      | {\n          mode: 'remove';\n          existingNetworkConfiguration: NetworkConfiguration;\n        }\n    ),\n  ) {\n    const { state, mode } = args;\n\n    if (\n      mode === 'remove' ||\n      (mode === 'update' &&\n        args.networkFields.chainId !==\n          args.existingNetworkConfiguration.chainId)\n    ) {\n      delete state.networkConfigurationsByChainId[\n        args.existingNetworkConfiguration.chainId\n      ];\n    }\n\n    if (mode === 'add' || mode === 'update') {\n      if (\n        !deepEqual(\n          state.networkConfigurationsByChainId[args.networkFields.chainId],\n          args.networkConfigurationToPersist,\n        )\n      ) {\n        args.networkConfigurationToPersist.lastUpdatedAt = Date.now();\n      }\n      state.networkConfigurationsByChainId[args.networkFields.chainId] =\n        args.networkConfigurationToPersist;\n    }\n\n    this.#networkConfigurationsByNetworkClientId =\n      buildNetworkConfigurationsByNetworkClientId(\n        cloneDeep(state.networkConfigurationsByChainId),\n      );\n  }\n\n  /**\n   * Before accessing or switching the network, the registry of network clients\n   * needs to be populated. Otherwise, `#applyNetworkSelection` and\n   * `getNetworkClientRegistry` will throw an error. This method checks to see if the\n   * population step has happened yet, and if not, makes it happen.\n   *\n   * @returns The populated network client registry.\n   */\n  #ensureAutoManagedNetworkClientRegistryPopulated(): AutoManagedNetworkClientRegistry {\n    return (this.#autoManagedNetworkClientRegistry ??=\n      this.#createAutoManagedNetworkClientRegistry());\n  }\n\n  /**\n   * Constructs the registry of network clients based on the set of default\n   * and custom networks in state.\n   *\n   * @returns The network clients keyed by ID.\n   */\n  #createAutoManagedNetworkClientRegistry(): AutoManagedNetworkClientRegistry {\n    const chainIds = knownKeysOf(this.state.networkConfigurationsByChainId);\n    const networkClientsWithIds = chainIds.flatMap((chainId) => {\n      const networkConfiguration =\n        this.state.networkConfigurationsByChainId[chainId];\n      return networkConfiguration.rpcEndpoints.map((rpcEndpoint) => {\n        if (rpcEndpoint.type === RpcEndpointType.Infura) {\n          const infuraNetworkName = deriveInfuraNetworkNameFromRpcEndpointUrl(\n            rpcEndpoint.url,\n          );\n          return [\n            rpcEndpoint.networkClientId,\n            createAutoManagedNetworkClient({\n              networkClientConfiguration: {\n                type: NetworkClientType.Infura,\n                network: infuraNetworkName,\n                failoverRpcUrls: rpcEndpoint.failoverUrls,\n                infuraProjectId: this.#infuraProjectId,\n                chainId: networkConfiguration.chainId,\n                ticker: networkConfiguration.nativeCurrency,\n              },\n              getRpcServiceOptions: this.#getRpcServiceOptions,\n              messenger: this.messagingSystem,\n            }),\n          ] as const;\n        }\n        return [\n          rpcEndpoint.networkClientId,\n          createAutoManagedNetworkClient({\n            networkClientConfiguration: {\n              type: NetworkClientType.Custom,\n              chainId: networkConfiguration.chainId,\n              failoverRpcUrls: rpcEndpoint.failoverUrls,\n              rpcUrl: rpcEndpoint.url,\n              ticker: networkConfiguration.nativeCurrency,\n            },\n            getRpcServiceOptions: this.#getRpcServiceOptions,\n            messenger: this.messagingSystem,\n          }),\n        ] as const;\n      });\n    });\n\n    return networkClientsWithIds.reduce(\n      (\n        obj: {\n          [NetworkClientType.Custom]: Partial<AutoManagedCustomNetworkClientRegistry>;\n          [NetworkClientType.Infura]: Partial<AutoManagedBuiltInNetworkClientRegistry>;\n        },\n        [networkClientId, networkClient],\n      ) => {\n        return {\n          ...obj,\n          [networkClient.configuration.type]: {\n            ...obj[networkClient.configuration.type],\n            [networkClientId]: networkClient,\n          },\n        };\n      },\n      {\n        [NetworkClientType.Custom]: {},\n        [NetworkClientType.Infura]: {},\n      },\n    ) as AutoManagedNetworkClientRegistry;\n  }\n\n  /**\n   * Updates the global provider and block tracker proxies (accessible via\n   * {@link getSelectedNetworkClient}) to point to the same ones within the\n   * given network client, thereby magically switching any consumers using these\n   * proxies to use the new network.\n   *\n   * Also refreshes the EthQuery instance accessible via the `getEthQuery`\n   * action to wrap the provider from the new network client. Note that this is\n   * not a proxy, so consumers will need to call `getEthQuery` again after the\n   * network switch.\n   *\n   * @param networkClientId - The ID of a network client that requests will be\n   * routed through (either the name of an Infura network or the ID of a custom\n   * network configuration).\n   * @param options - Options for this method.\n   * @param options.updateState - Allows for updating state.\n   * @throws if no network client could be found matching the given ID.\n   */\n  #applyNetworkSelection(\n    networkClientId: string,\n    {\n      updateState,\n    }: {\n      updateState?: (state: Draft<NetworkState>) => void;\n    } = {},\n  ) {\n    const autoManagedNetworkClientRegistry =\n      this.#ensureAutoManagedNetworkClientRegistryPopulated();\n\n    let autoManagedNetworkClient:\n      | AutoManagedNetworkClient<CustomNetworkClientConfiguration>\n      | AutoManagedNetworkClient<InfuraNetworkClientConfiguration>;\n\n    if (isInfuraNetworkType(networkClientId)) {\n      const possibleAutoManagedNetworkClient =\n        autoManagedNetworkClientRegistry[NetworkClientType.Infura][\n          networkClientId\n        ];\n\n      // This is impossible to reach\n      /* istanbul ignore if */\n      if (!possibleAutoManagedNetworkClient) {\n        throw new Error(\n          `No Infura network client found with ID '${networkClientId}'`,\n        );\n      }\n\n      autoManagedNetworkClient = possibleAutoManagedNetworkClient;\n    } else {\n      const possibleAutoManagedNetworkClient =\n        autoManagedNetworkClientRegistry[NetworkClientType.Custom][\n          networkClientId\n        ];\n\n      if (!possibleAutoManagedNetworkClient) {\n        throw new Error(`No network client found with ID '${networkClientId}'`);\n      }\n\n      autoManagedNetworkClient = possibleAutoManagedNetworkClient;\n    }\n\n    this.#autoManagedNetworkClient = autoManagedNetworkClient;\n\n    this.update((state) => {\n      state.selectedNetworkClientId = networkClientId;\n      if (state.networksMetadata[networkClientId] === undefined) {\n        state.networksMetadata[networkClientId] = {\n          status: NetworkStatus.Unknown,\n          EIPS: {},\n        };\n      }\n      updateState?.(state);\n    });\n\n    if (this.#providerProxy) {\n      this.#providerProxy.setTarget(this.#autoManagedNetworkClient.provider);\n    } else {\n      this.#providerProxy = createEventEmitterProxy(\n        this.#autoManagedNetworkClient.provider,\n      );\n    }\n\n    if (this.#blockTrackerProxy) {\n      this.#blockTrackerProxy.setTarget(\n        this.#autoManagedNetworkClient.blockTracker,\n      );\n    } else {\n      this.#blockTrackerProxy = createEventEmitterProxy(\n        this.#autoManagedNetworkClient.blockTracker,\n        { eventFilter: 'skipInternal' },\n      );\n    }\n\n    this.#ethQuery = new EthQuery(this.#providerProxy);\n  }\n}\n"]}