@metamask-previews/network-controller 29.0.0-preview-ee8f1b28b → 29.0.0-preview-33dbba4f3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/NetworkController.cjs.map +1 -1
  3. package/dist/NetworkController.d.cts +12 -0
  4. package/dist/NetworkController.d.cts.map +1 -1
  5. package/dist/NetworkController.d.mts +12 -0
  6. package/dist/NetworkController.d.mts.map +1 -1
  7. package/dist/NetworkController.mjs.map +1 -1
  8. package/dist/create-network-client.cjs +12 -8
  9. package/dist/create-network-client.cjs.map +1 -1
  10. package/dist/create-network-client.mjs +12 -8
  11. package/dist/create-network-client.mjs.map +1 -1
  12. package/dist/rpc-service/rpc-service-chain.cjs +1 -0
  13. package/dist/rpc-service/rpc-service-chain.cjs.map +1 -1
  14. package/dist/rpc-service/rpc-service-chain.d.cts.map +1 -1
  15. package/dist/rpc-service/rpc-service-chain.d.mts.map +1 -1
  16. package/dist/rpc-service/rpc-service-chain.mjs +1 -0
  17. package/dist/rpc-service/rpc-service-chain.mjs.map +1 -1
  18. package/dist/rpc-service/rpc-service-requestable.cjs.map +1 -1
  19. package/dist/rpc-service/rpc-service-requestable.d.cts +2 -0
  20. package/dist/rpc-service/rpc-service-requestable.d.cts.map +1 -1
  21. package/dist/rpc-service/rpc-service-requestable.d.mts +2 -0
  22. package/dist/rpc-service/rpc-service-requestable.d.mts.map +1 -1
  23. package/dist/rpc-service/rpc-service-requestable.mjs.map +1 -1
  24. package/dist/rpc-service/rpc-service.cjs +47 -15
  25. package/dist/rpc-service/rpc-service.cjs.map +1 -1
  26. package/dist/rpc-service/rpc-service.d.cts.map +1 -1
  27. package/dist/rpc-service/rpc-service.d.mts.map +1 -1
  28. package/dist/rpc-service/rpc-service.mjs +47 -15
  29. package/dist/rpc-service/rpc-service.mjs.map +1 -1
  30. package/package.json +1 -1
@@ -135,8 +135,8 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
135
135
  * filter policy considers a failure.
136
136
  *
137
137
  * @param value - The event data object from the circuit breaker event
138
- * listener (after destructuring known properties like `endpointUrl`). This
139
- * represents Cockatiel's `FailureReason` type.
138
+ * listener (after destructuring known properties like `endpointUrl` and
139
+ * `rpcMethodName`). This represents Cockatiel's `FailureReason` type.
140
140
  * @returns The error or failure value, or `undefined` if neither property
141
141
  * exists (which shouldn't happen in practice unless the circuit breaker is
142
142
  * manually isolated).
@@ -154,8 +154,8 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
154
154
  rpcServiceConfigurations[0],
155
155
  ...rpcServiceConfigurations.slice(1),
156
156
  ]);
157
- rpcServiceChain.onBreak((data) => {
158
- const error = getError(data);
157
+ rpcServiceChain.onBreak(({ rpcMethodName, ...rest }) => {
158
+ const error = getError(rest);
159
159
  if (error === undefined) {
160
160
  // This error shouldn't happen in practice because we never call `.isolate`
161
161
  // on the circuit breaker policy, but we need to appease TypeScript.
@@ -165,9 +165,10 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
165
165
  chainId: configuration.chainId,
166
166
  networkClientId: id,
167
167
  error,
168
+ rpcMethodName,
168
169
  });
169
170
  });
170
- rpcServiceChain.onServiceBreak(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, ...rest }) => {
171
+ rpcServiceChain.onServiceBreak(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, rpcMethodName, ...rest }) => {
171
172
  const error = getError(rest);
172
173
  if (error === undefined) {
173
174
  // This error shouldn't happen in practice because we never call `.isolate`
@@ -180,17 +181,19 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
180
181
  primaryEndpointUrl: primaryEndpointUrlFromEvent,
181
182
  endpointUrl,
182
183
  error,
184
+ rpcMethodName,
183
185
  });
184
186
  });
185
- rpcServiceChain.onDegraded((data) => {
186
- const error = getError(data);
187
+ rpcServiceChain.onDegraded(({ rpcMethodName, ...rest }) => {
188
+ const error = getError(rest);
187
189
  messenger.publish('NetworkController:rpcEndpointChainDegraded', {
188
190
  chainId: configuration.chainId,
189
191
  networkClientId: id,
190
192
  error,
193
+ rpcMethodName,
191
194
  });
192
195
  });
193
- rpcServiceChain.onServiceDegraded(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, ...rest }) => {
196
+ rpcServiceChain.onServiceDegraded(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, rpcMethodName, ...rest }) => {
194
197
  const error = getError(rest);
195
198
  messenger.publish('NetworkController:rpcEndpointDegraded', {
196
199
  chainId: configuration.chainId,
@@ -198,6 +201,7 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
198
201
  primaryEndpointUrl: primaryEndpointUrlFromEvent,
199
202
  endpointUrl,
200
203
  error,
204
+ rpcMethodName,
201
205
  });
202
206
  });
203
207
  rpcServiceChain.onAvailable(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"create-network-client.cjs","sourceRoot":"","sources":["../src/create-network-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { CONNECTIVITY_STATUSES } from '@metamask/connectivity-controller';\nimport type {\n CockatielFailureReason,\n InfuraNetworkType,\n} from '@metamask/controller-utils';\nimport { ChainId } from '@metamask/controller-utils';\nimport type { PollingBlockTrackerOptions } from '@metamask/eth-block-tracker';\nimport { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createInfuraMiddleware } from '@metamask/eth-json-rpc-infura';\nimport {\n createBlockCacheMiddleware,\n createBlockRefMiddleware,\n createBlockRefRewriteMiddleware,\n createBlockTrackerInspectorMiddleware,\n createInflightCacheMiddleware,\n createFetchMiddleware,\n createRetryOnEmptyMiddleware,\n} from '@metamask/eth-json-rpc-middleware';\nimport { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport { providerFromMiddlewareV2 } from '@metamask/eth-json-rpc-provider';\nimport { asV2Middleware } from '@metamask/json-rpc-engine';\nimport {\n createScaffoldMiddleware,\n JsonRpcEngineV2,\n} from '@metamask/json-rpc-engine/v2';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Hex, Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Logger } from 'loglevel';\n\nimport type {\n NetworkClientId,\n NetworkControllerMessenger,\n} from './NetworkController';\nimport type { RpcServiceOptions } from './rpc-service/rpc-service';\nimport { RpcServiceChain } from './rpc-service/rpc-service-chain';\nimport type {\n BlockTracker,\n NetworkClientConfiguration,\n Provider,\n} from './types';\nimport { NetworkClientType } from './types';\n\nconst SECOND = 1000;\n\n/**\n * The pair of provider / block tracker that can be used to interface with the\n * network and respond to new activity.\n */\nexport type NetworkClient = {\n configuration: NetworkClientConfiguration;\n provider: Provider;\n blockTracker: BlockTracker;\n destroy: () => void;\n};\n\ntype RpcApiMiddleware = JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string }>\n>;\n\n/**\n * Create a JSON RPC network client for a specific network.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.getBlockTrackerOptions - Factory for constructing block tracker\n * options. See {@link NetworkControllerOptions.getBlockTrackerOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The network client.\n */\nexport function createNetworkClient({\n id,\n configuration,\n getRpcServiceOptions,\n getBlockTrackerOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n getBlockTrackerOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): NetworkClient {\n const primaryEndpointUrl =\n configuration.type === NetworkClientType.Infura\n ? `https://${configuration.network}.infura.io/v3/${configuration.infuraProjectId}`\n : configuration.rpcUrl;\n const rpcServiceChain = createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n });\n\n let rpcApiMiddleware: RpcApiMiddleware;\n if (configuration.type === NetworkClientType.Infura) {\n rpcApiMiddleware = asV2Middleware(\n createInfuraMiddleware({\n rpcService: rpcServiceChain,\n options: {\n source: 'metamask',\n },\n }),\n );\n } else {\n rpcApiMiddleware = createFetchMiddleware({ rpcService: rpcServiceChain });\n }\n\n const rpcProvider = providerFromMiddlewareV2(rpcApiMiddleware);\n\n const blockTracker = createBlockTracker({\n networkClientType: configuration.type,\n endpointUrl: primaryEndpointUrl,\n getOptions: getBlockTrackerOptions,\n provider: rpcProvider,\n });\n\n const networkMiddleware =\n configuration.type === NetworkClientType.Infura\n ? createInfuraNetworkMiddleware({\n blockTracker,\n network: configuration.network,\n rpcProvider,\n rpcApiMiddleware,\n })\n : createCustomNetworkMiddleware({\n blockTracker,\n chainId: configuration.chainId,\n rpcApiMiddleware,\n });\n\n const provider: Provider = new InternalProvider({\n engine: JsonRpcEngineV2.create({\n middleware: [networkMiddleware],\n }),\n });\n\n const destroy = (): void => {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n blockTracker.destroy();\n };\n\n return { configuration, provider, blockTracker, destroy };\n}\n\n/**\n * Creates an RPC service chain, which represents the primary endpoint URL for\n * the network as well as its failover URLs.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.primaryEndpointUrl - The primary endpoint URL.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The RPC service chain.\n */\nfunction createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n primaryEndpointUrl: string;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): RpcServiceChain {\n const availableEndpointUrls: [string, ...string[]] = isRpcFailoverEnabled\n ? [primaryEndpointUrl, ...(configuration.failoverRpcUrls ?? [])]\n : [primaryEndpointUrl];\n\n const isOffline = (): boolean => {\n const connectivityState = messenger.call('ConnectivityController:getState');\n return (\n connectivityState.connectivityStatus === CONNECTIVITY_STATUSES.Offline\n );\n };\n\n const rpcServiceConfigurations = availableEndpointUrls.map((endpointUrl) => ({\n ...getRpcServiceOptions(endpointUrl),\n endpointUrl,\n logger,\n isOffline,\n }));\n\n /**\n * Extracts the error from Cockatiel's `FailureReason` type received in\n * circuit breaker event handlers.\n *\n * The `FailureReason` object can have two possible shapes:\n * - `{ error: Error }` - When the RPC service throws an error (the common\n * case for RPC failures).\n * - `{ value: T }` - When the RPC service returns a value that the retry\n * filter policy considers a failure.\n *\n * @param value - The event data object from the circuit breaker event\n * listener (after destructuring known properties like `endpointUrl`). This\n * represents Cockatiel's `FailureReason` type.\n * @returns The error or failure value, or `undefined` if neither property\n * exists (which shouldn't happen in practice unless the circuit breaker is\n * manually isolated).\n */\n const getError = (\n value: CockatielFailureReason<unknown> | Record<never, never>,\n ): Error | unknown | undefined => {\n if ('error' in value) {\n return value.error;\n } else if ('value' in value) {\n return value.value;\n }\n return undefined;\n };\n\n const rpcServiceChain = new RpcServiceChain([\n rpcServiceConfigurations[0],\n ...rpcServiceConfigurations.slice(1),\n ]);\n\n rpcServiceChain.onBreak((data) => {\n const error = getError(data);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointChainUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n });\n });\n\n rpcServiceChain.onServiceBreak(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n ...rest\n }) => {\n const error = getError(rest);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n });\n },\n );\n\n rpcServiceChain.onDegraded((data) => {\n const error = getError(data);\n messenger.publish('NetworkController:rpcEndpointChainDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n });\n });\n\n rpcServiceChain.onServiceDegraded(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n ...rest\n }) => {\n const error = getError(rest);\n\n messenger.publish('NetworkController:rpcEndpointDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n });\n },\n );\n\n rpcServiceChain.onAvailable(() => {\n messenger.publish('NetworkController:rpcEndpointChainAvailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n });\n });\n\n rpcServiceChain.onServiceRetry(\n ({\n attempt,\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n }) => {\n messenger.publish('NetworkController:rpcEndpointRetried', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n attempt,\n });\n },\n );\n\n return rpcServiceChain;\n}\n\n/**\n * Create the block tracker for the network.\n *\n * @param args - The arguments.\n * @param args.networkClientType - The type of the network client (\"infura\" or\n * \"custom\").\n * @param args.endpointUrl - The URL of the endpoint.\n * @param args.getOptions - Factory for the block tracker options.\n * @param args.provider - The EIP-1193 provider for the network's JSON-RPC\n * middleware stack.\n * @returns The created block tracker.\n */\nfunction createBlockTracker({\n networkClientType,\n endpointUrl,\n getOptions,\n provider,\n}: {\n networkClientType: NetworkClientType;\n endpointUrl: string;\n getOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n provider: InternalProvider;\n}): PollingBlockTracker {\n const testOptions =\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n process.env.IN_TEST && networkClientType === NetworkClientType.Custom\n ? { pollingInterval: SECOND }\n : {};\n\n return new PollingBlockTracker({\n ...testOptions,\n ...getOptions(endpointUrl),\n provider,\n });\n}\n\n/**\n * Create middleware for infura.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.network - The Infura network to use.\n * @param args.rpcProvider - The RPC provider to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createInfuraNetworkMiddleware({\n blockTracker,\n network,\n rpcProvider,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n network: InfuraNetworkType;\n rpcProvider: InternalProvider;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n return JsonRpcEngineV2.create({\n middleware: [\n createNetworkAndChainIdMiddleware({ network }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockRefMiddleware({ blockTracker, provider: rpcProvider }),\n createRetryOnEmptyMiddleware({ blockTracker, provider: rpcProvider }),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * Creates static method middleware.\n *\n * @param args - The Arguments.\n * @param args.network - The Infura network to use.\n * @returns The middleware that implements the eth_chainId method.\n */\nfunction createNetworkAndChainIdMiddleware({\n network,\n}: {\n network: InfuraNetworkType;\n}): JsonRpcMiddleware<JsonRpcRequest> {\n return createScaffoldMiddleware({\n eth_chainId: ChainId[network],\n });\n}\n\nconst createChainIdMiddleware = (\n chainId: Hex,\n): JsonRpcMiddleware<JsonRpcRequest, Json> => {\n return ({ request, next }) => {\n if (request.method === 'eth_chainId') {\n return chainId;\n }\n return next();\n };\n};\n\n/**\n * Creates custom middleware.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.chainId - The chain id to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createCustomNetworkMiddleware({\n blockTracker,\n chainId,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n chainId: Hex;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n const testMiddlewares = process.env.IN_TEST\n ? [createEstimateGasDelayTestMiddleware()]\n : [];\n\n return JsonRpcEngineV2.create({\n middleware: [\n ...testMiddlewares,\n createChainIdMiddleware(chainId),\n createBlockRefRewriteMiddleware({ blockTracker }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * For use in tests only.\n * Adds a delay to `eth_estimateGas` calls.\n *\n * @returns The middleware for delaying gas estimation calls by 2 seconds when in test.\n */\nfunction createEstimateGasDelayTestMiddleware(): JsonRpcMiddleware<\n JsonRpcRequest,\n Json\n> {\n return async ({ request, next }) => {\n if (request.method === 'eth_estimateGas') {\n await new Promise((resolve) => setTimeout(resolve, SECOND * 2));\n }\n return next();\n };\n}\n"]}
1
+ {"version":3,"file":"create-network-client.cjs","sourceRoot":"","sources":["../src/create-network-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { CONNECTIVITY_STATUSES } from '@metamask/connectivity-controller';\nimport type {\n CockatielFailureReason,\n InfuraNetworkType,\n} from '@metamask/controller-utils';\nimport { ChainId } from '@metamask/controller-utils';\nimport type { PollingBlockTrackerOptions } from '@metamask/eth-block-tracker';\nimport { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createInfuraMiddleware } from '@metamask/eth-json-rpc-infura';\nimport {\n createBlockCacheMiddleware,\n createBlockRefMiddleware,\n createBlockRefRewriteMiddleware,\n createBlockTrackerInspectorMiddleware,\n createInflightCacheMiddleware,\n createFetchMiddleware,\n createRetryOnEmptyMiddleware,\n} from '@metamask/eth-json-rpc-middleware';\nimport { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport { providerFromMiddlewareV2 } from '@metamask/eth-json-rpc-provider';\nimport { asV2Middleware } from '@metamask/json-rpc-engine';\nimport {\n createScaffoldMiddleware,\n JsonRpcEngineV2,\n} from '@metamask/json-rpc-engine/v2';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Hex, Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Logger } from 'loglevel';\n\nimport type {\n NetworkClientId,\n NetworkControllerMessenger,\n} from './NetworkController';\nimport type { RpcServiceOptions } from './rpc-service/rpc-service';\nimport { RpcServiceChain } from './rpc-service/rpc-service-chain';\nimport type {\n BlockTracker,\n NetworkClientConfiguration,\n Provider,\n} from './types';\nimport { NetworkClientType } from './types';\n\nconst SECOND = 1000;\n\n/**\n * The pair of provider / block tracker that can be used to interface with the\n * network and respond to new activity.\n */\nexport type NetworkClient = {\n configuration: NetworkClientConfiguration;\n provider: Provider;\n blockTracker: BlockTracker;\n destroy: () => void;\n};\n\ntype RpcApiMiddleware = JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string }>\n>;\n\n/**\n * Create a JSON RPC network client for a specific network.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.getBlockTrackerOptions - Factory for constructing block tracker\n * options. See {@link NetworkControllerOptions.getBlockTrackerOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The network client.\n */\nexport function createNetworkClient({\n id,\n configuration,\n getRpcServiceOptions,\n getBlockTrackerOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n getBlockTrackerOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): NetworkClient {\n const primaryEndpointUrl =\n configuration.type === NetworkClientType.Infura\n ? `https://${configuration.network}.infura.io/v3/${configuration.infuraProjectId}`\n : configuration.rpcUrl;\n const rpcServiceChain = createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n });\n\n let rpcApiMiddleware: RpcApiMiddleware;\n if (configuration.type === NetworkClientType.Infura) {\n rpcApiMiddleware = asV2Middleware(\n createInfuraMiddleware({\n rpcService: rpcServiceChain,\n options: {\n source: 'metamask',\n },\n }),\n );\n } else {\n rpcApiMiddleware = createFetchMiddleware({ rpcService: rpcServiceChain });\n }\n\n const rpcProvider = providerFromMiddlewareV2(rpcApiMiddleware);\n\n const blockTracker = createBlockTracker({\n networkClientType: configuration.type,\n endpointUrl: primaryEndpointUrl,\n getOptions: getBlockTrackerOptions,\n provider: rpcProvider,\n });\n\n const networkMiddleware =\n configuration.type === NetworkClientType.Infura\n ? createInfuraNetworkMiddleware({\n blockTracker,\n network: configuration.network,\n rpcProvider,\n rpcApiMiddleware,\n })\n : createCustomNetworkMiddleware({\n blockTracker,\n chainId: configuration.chainId,\n rpcApiMiddleware,\n });\n\n const provider: Provider = new InternalProvider({\n engine: JsonRpcEngineV2.create({\n middleware: [networkMiddleware],\n }),\n });\n\n const destroy = (): void => {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n blockTracker.destroy();\n };\n\n return { configuration, provider, blockTracker, destroy };\n}\n\n/**\n * Creates an RPC service chain, which represents the primary endpoint URL for\n * the network as well as its failover URLs.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.primaryEndpointUrl - The primary endpoint URL.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The RPC service chain.\n */\nfunction createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n primaryEndpointUrl: string;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): RpcServiceChain {\n const availableEndpointUrls: [string, ...string[]] = isRpcFailoverEnabled\n ? [primaryEndpointUrl, ...(configuration.failoverRpcUrls ?? [])]\n : [primaryEndpointUrl];\n\n const isOffline = (): boolean => {\n const connectivityState = messenger.call('ConnectivityController:getState');\n return (\n connectivityState.connectivityStatus === CONNECTIVITY_STATUSES.Offline\n );\n };\n\n const rpcServiceConfigurations = availableEndpointUrls.map((endpointUrl) => ({\n ...getRpcServiceOptions(endpointUrl),\n endpointUrl,\n logger,\n isOffline,\n }));\n\n /**\n * Extracts the error from Cockatiel's `FailureReason` type received in\n * circuit breaker event handlers.\n *\n * The `FailureReason` object can have two possible shapes:\n * - `{ error: Error }` - When the RPC service throws an error (the common\n * case for RPC failures).\n * - `{ value: T }` - When the RPC service returns a value that the retry\n * filter policy considers a failure.\n *\n * @param value - The event data object from the circuit breaker event\n * listener (after destructuring known properties like `endpointUrl` and\n * `rpcMethodName`). This represents Cockatiel's `FailureReason` type.\n * @returns The error or failure value, or `undefined` if neither property\n * exists (which shouldn't happen in practice unless the circuit breaker is\n * manually isolated).\n */\n const getError = (\n value: CockatielFailureReason<unknown> | Record<never, never>,\n ): Error | unknown | undefined => {\n if ('error' in value) {\n return value.error;\n } else if ('value' in value) {\n return value.value;\n }\n return undefined;\n };\n\n const rpcServiceChain = new RpcServiceChain([\n rpcServiceConfigurations[0],\n ...rpcServiceConfigurations.slice(1),\n ]);\n\n rpcServiceChain.onBreak(({ rpcMethodName, ...rest }) => {\n const error = getError(rest);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointChainUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n rpcMethodName,\n });\n });\n\n rpcServiceChain.onServiceBreak(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n rpcMethodName,\n ...rest\n }) => {\n const error = getError(rest);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n rpcMethodName,\n });\n },\n );\n\n rpcServiceChain.onDegraded(({ rpcMethodName, ...rest }) => {\n const error = getError(rest);\n messenger.publish('NetworkController:rpcEndpointChainDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n rpcMethodName,\n });\n });\n\n rpcServiceChain.onServiceDegraded(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n rpcMethodName,\n ...rest\n }) => {\n const error = getError(rest);\n\n messenger.publish('NetworkController:rpcEndpointDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n rpcMethodName,\n });\n },\n );\n\n rpcServiceChain.onAvailable(() => {\n messenger.publish('NetworkController:rpcEndpointChainAvailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n });\n });\n\n rpcServiceChain.onServiceRetry(\n ({\n attempt,\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n }) => {\n messenger.publish('NetworkController:rpcEndpointRetried', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n attempt,\n });\n },\n );\n\n return rpcServiceChain;\n}\n\n/**\n * Create the block tracker for the network.\n *\n * @param args - The arguments.\n * @param args.networkClientType - The type of the network client (\"infura\" or\n * \"custom\").\n * @param args.endpointUrl - The URL of the endpoint.\n * @param args.getOptions - Factory for the block tracker options.\n * @param args.provider - The EIP-1193 provider for the network's JSON-RPC\n * middleware stack.\n * @returns The created block tracker.\n */\nfunction createBlockTracker({\n networkClientType,\n endpointUrl,\n getOptions,\n provider,\n}: {\n networkClientType: NetworkClientType;\n endpointUrl: string;\n getOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n provider: InternalProvider;\n}): PollingBlockTracker {\n const testOptions =\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n process.env.IN_TEST && networkClientType === NetworkClientType.Custom\n ? { pollingInterval: SECOND }\n : {};\n\n return new PollingBlockTracker({\n ...testOptions,\n ...getOptions(endpointUrl),\n provider,\n });\n}\n\n/**\n * Create middleware for infura.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.network - The Infura network to use.\n * @param args.rpcProvider - The RPC provider to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createInfuraNetworkMiddleware({\n blockTracker,\n network,\n rpcProvider,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n network: InfuraNetworkType;\n rpcProvider: InternalProvider;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n return JsonRpcEngineV2.create({\n middleware: [\n createNetworkAndChainIdMiddleware({ network }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockRefMiddleware({ blockTracker, provider: rpcProvider }),\n createRetryOnEmptyMiddleware({ blockTracker, provider: rpcProvider }),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * Creates static method middleware.\n *\n * @param args - The Arguments.\n * @param args.network - The Infura network to use.\n * @returns The middleware that implements the eth_chainId method.\n */\nfunction createNetworkAndChainIdMiddleware({\n network,\n}: {\n network: InfuraNetworkType;\n}): JsonRpcMiddleware<JsonRpcRequest> {\n return createScaffoldMiddleware({\n eth_chainId: ChainId[network],\n });\n}\n\nconst createChainIdMiddleware = (\n chainId: Hex,\n): JsonRpcMiddleware<JsonRpcRequest, Json> => {\n return ({ request, next }) => {\n if (request.method === 'eth_chainId') {\n return chainId;\n }\n return next();\n };\n};\n\n/**\n * Creates custom middleware.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.chainId - The chain id to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createCustomNetworkMiddleware({\n blockTracker,\n chainId,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n chainId: Hex;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n const testMiddlewares = process.env.IN_TEST\n ? [createEstimateGasDelayTestMiddleware()]\n : [];\n\n return JsonRpcEngineV2.create({\n middleware: [\n ...testMiddlewares,\n createChainIdMiddleware(chainId),\n createBlockRefRewriteMiddleware({ blockTracker }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * For use in tests only.\n * Adds a delay to `eth_estimateGas` calls.\n *\n * @returns The middleware for delaying gas estimation calls by 2 seconds when in test.\n */\nfunction createEstimateGasDelayTestMiddleware(): JsonRpcMiddleware<\n JsonRpcRequest,\n Json\n> {\n return async ({ request, next }) => {\n if (request.method === 'eth_estimateGas') {\n await new Promise((resolve) => setTimeout(resolve, SECOND * 2));\n }\n return next();\n };\n}\n"]}
@@ -131,8 +131,8 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
131
131
  * filter policy considers a failure.
132
132
  *
133
133
  * @param value - The event data object from the circuit breaker event
134
- * listener (after destructuring known properties like `endpointUrl`). This
135
- * represents Cockatiel's `FailureReason` type.
134
+ * listener (after destructuring known properties like `endpointUrl` and
135
+ * `rpcMethodName`). This represents Cockatiel's `FailureReason` type.
136
136
  * @returns The error or failure value, or `undefined` if neither property
137
137
  * exists (which shouldn't happen in practice unless the circuit breaker is
138
138
  * manually isolated).
@@ -150,8 +150,8 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
150
150
  rpcServiceConfigurations[0],
151
151
  ...rpcServiceConfigurations.slice(1),
152
152
  ]);
153
- rpcServiceChain.onBreak((data) => {
154
- const error = getError(data);
153
+ rpcServiceChain.onBreak(({ rpcMethodName, ...rest }) => {
154
+ const error = getError(rest);
155
155
  if (error === undefined) {
156
156
  // This error shouldn't happen in practice because we never call `.isolate`
157
157
  // on the circuit breaker policy, but we need to appease TypeScript.
@@ -161,9 +161,10 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
161
161
  chainId: configuration.chainId,
162
162
  networkClientId: id,
163
163
  error,
164
+ rpcMethodName,
164
165
  });
165
166
  });
166
- rpcServiceChain.onServiceBreak(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, ...rest }) => {
167
+ rpcServiceChain.onServiceBreak(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, rpcMethodName, ...rest }) => {
167
168
  const error = getError(rest);
168
169
  if (error === undefined) {
169
170
  // This error shouldn't happen in practice because we never call `.isolate`
@@ -176,17 +177,19 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
176
177
  primaryEndpointUrl: primaryEndpointUrlFromEvent,
177
178
  endpointUrl,
178
179
  error,
180
+ rpcMethodName,
179
181
  });
180
182
  });
181
- rpcServiceChain.onDegraded((data) => {
182
- const error = getError(data);
183
+ rpcServiceChain.onDegraded(({ rpcMethodName, ...rest }) => {
184
+ const error = getError(rest);
183
185
  messenger.publish('NetworkController:rpcEndpointChainDegraded', {
184
186
  chainId: configuration.chainId,
185
187
  networkClientId: id,
186
188
  error,
189
+ rpcMethodName,
187
190
  });
188
191
  });
189
- rpcServiceChain.onServiceDegraded(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, ...rest }) => {
192
+ rpcServiceChain.onServiceDegraded(({ endpointUrl, primaryEndpointUrl: primaryEndpointUrlFromEvent, rpcMethodName, ...rest }) => {
190
193
  const error = getError(rest);
191
194
  messenger.publish('NetworkController:rpcEndpointDegraded', {
192
195
  chainId: configuration.chainId,
@@ -194,6 +197,7 @@ function createRpcServiceChain({ id, primaryEndpointUrl, configuration, getRpcSe
194
197
  primaryEndpointUrl: primaryEndpointUrlFromEvent,
195
198
  endpointUrl,
196
199
  error,
200
+ rpcMethodName,
197
201
  });
198
202
  });
199
203
  rpcServiceChain.onAvailable(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"create-network-client.mjs","sourceRoot":"","sources":["../src/create-network-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,0CAA0C;AAK1E,OAAO,EAAE,OAAO,EAAE,mCAAmC;AAErD,OAAO,EAAE,mBAAmB,EAAE,oCAAoC;AAClE,OAAO,EAAE,sBAAsB,EAAE,sCAAsC;AACvE,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,+BAA+B,EAC/B,qCAAqC,EACrC,6BAA6B,EAC7B,qBAAqB,EACrB,4BAA4B,EAC7B,0CAA0C;AAC3C,OAAO,EAAE,gBAAgB,EAAE,wCAAwC;AACnE,OAAO,EAAE,wBAAwB,EAAE,wCAAwC;AAC3E,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,EACL,wBAAwB,EACxB,eAAe,EAChB,qCAAqC;AAatC,OAAO,EAAE,eAAe,EAAE,4CAAwC;AAMlE,OAAO,EAAE,iBAAiB,EAAE,oBAAgB;AAE5C,MAAM,MAAM,GAAG,IAAI,CAAC;AAmBpB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,EAAE,EACF,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,oBAAoB,EACpB,MAAM,GAaP;IACC,MAAM,kBAAkB,GACtB,aAAa,CAAC,IAAI,KAAK,iBAAiB,CAAC,MAAM;QAC7C,CAAC,CAAC,WAAW,aAAa,CAAC,OAAO,iBAAiB,aAAa,CAAC,eAAe,EAAE;QAClF,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC;IAC3B,MAAM,eAAe,GAAG,qBAAqB,CAAC;QAC5C,EAAE;QACF,kBAAkB;QAClB,aAAa;QACb,oBAAoB;QACpB,SAAS;QACT,oBAAoB;QACpB,MAAM;KACP,CAAC,CAAC;IAEH,IAAI,gBAAkC,CAAC;IACvC,IAAI,aAAa,CAAC,IAAI,KAAK,iBAAiB,CAAC,MAAM,EAAE,CAAC;QACpD,gBAAgB,GAAG,cAAc,CAC/B,sBAAsB,CAAC;YACrB,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE;gBACP,MAAM,EAAE,UAAU;aACnB;SACF,CAAC,CACH,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,WAAW,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,kBAAkB,CAAC;QACtC,iBAAiB,EAAE,aAAa,CAAC,IAAI;QACrC,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,sBAAsB;QAClC,QAAQ,EAAE,WAAW;KACtB,CAAC,CAAC;IAEH,MAAM,iBAAiB,GACrB,aAAa,CAAC,IAAI,KAAK,iBAAiB,CAAC,MAAM;QAC7C,CAAC,CAAC,6BAA6B,CAAC;YAC5B,YAAY;YACZ,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,WAAW;YACX,gBAAgB;SACjB,CAAC;QACJ,CAAC,CAAC,6BAA6B,CAAC;YAC5B,YAAY;YACZ,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,gBAAgB;SACjB,CAAC,CAAC;IAET,MAAM,QAAQ,GAAa,IAAI,gBAAgB,CAAC;QAC9C,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;YAC7B,UAAU,EAAE,CAAC,iBAAiB,CAAC;SAChC,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,gFAAgF;QAChF,mEAAmE;QACnE,YAAY,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC;IAEF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,qBAAqB,CAAC,EAC7B,EAAE,EACF,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,oBAAoB,EACpB,MAAM,GAWP;IACC,MAAM,qBAAqB,GAA0B,oBAAoB;QACvE,CAAC,CAAC,CAAC,kBAAkB,EAAE,GAAG,CAAC,aAAa,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAEzB,MAAM,SAAS,GAAG,GAAY,EAAE;QAC9B,MAAM,iBAAiB,GAAG,SAAS,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC5E,OAAO,CACL,iBAAiB,CAAC,kBAAkB,KAAK,qBAAqB,CAAC,OAAO,CACvE,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,wBAAwB,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC3E,GAAG,oBAAoB,CAAC,WAAW,CAAC;QACpC,WAAW;QACX,MAAM;QACN,SAAS;KACV,CAAC,CAAC,CAAC;IAEJ;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,QAAQ,GAAG,CACf,KAA6D,EAChC,EAAE;QAC/B,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,CAAC;aAAM,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC;QAC1C,wBAAwB,CAAC,CAAC,CAAC;QAC3B,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;KACrC,CAAC,CAAC;IAEH,eAAe,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,2EAA2E;YAC3E,oEAAoE;YACpE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,+CAA+C,EAAE;YACjE,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,eAAe,EAAE,EAAE;YACnB,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,cAAc,CAC5B,CAAC,EACC,WAAW,EACX,kBAAkB,EAAE,2BAA2B,EAC/C,GAAG,IAAI,EACR,EAAE,EAAE;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,2EAA2E;YAC3E,oEAAoE;YACpE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,0CAA0C,EAAE;YAC5D,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,eAAe,EAAE,EAAE;YACnB,kBAAkB,EAAE,2BAA2B;YAC/C,WAAW;YACX,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,SAAS,CAAC,OAAO,CAAC,4CAA4C,EAAE;YAC9D,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,eAAe,EAAE,EAAE;YACnB,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,iBAAiB,CAC/B,CAAC,EACC,WAAW,EACX,kBAAkB,EAAE,2BAA2B,EAC/C,GAAG,IAAI,EACR,EAAE,EAAE;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE7B,SAAS,CAAC,OAAO,CAAC,uCAAuC,EAAE;YACzD,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,eAAe,EAAE,EAAE;YACnB,kBAAkB,EAAE,2BAA2B;YAC/C,WAAW;YACX,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,eAAe,CAAC,WAAW,CAAC,GAAG,EAAE;QAC/B,SAAS,CAAC,OAAO,CAAC,6CAA6C,EAAE;YAC/D,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,eAAe,EAAE,EAAE;SACpB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,cAAc,CAC5B,CAAC,EACC,OAAO,EACP,WAAW,EACX,kBAAkB,EAAE,2BAA2B,GAChD,EAAE,EAAE;QACH,SAAS,CAAC,OAAO,CAAC,sCAAsC,EAAE;YACxD,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,eAAe,EAAE,EAAE;YACnB,kBAAkB,EAAE,2BAA2B;YAC/C,WAAW;YACX,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,kBAAkB,CAAC,EAC1B,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,QAAQ,GAQT;IACC,MAAM,WAAW;IACf,sBAAsB;IACtB,iDAAiD;IACjD,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,iBAAiB,KAAK,iBAAiB,CAAC,MAAM;QACnE,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE;QAC7B,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,IAAI,mBAAmB,CAAC;QAC7B,GAAG,WAAW;QACd,GAAG,UAAU,CAAC,WAAW,CAAC;QAC1B,QAAQ;KACT,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,6BAA6B,CAAC,EACrC,YAAY,EACZ,OAAO,EACP,WAAW,EACX,gBAAgB,GAMjB;IAKC,OAAO,eAAe,CAAC,MAAM,CAAC;QAC5B,UAAU,EAAE;YACV,iCAAiC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC9C,0BAA0B,CAAC,EAAE,YAAY,EAAE,CAAC;YAC5C,6BAA6B,EAAE;YAC/B,wBAAwB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;YACjE,4BAA4B,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;YACrE,qCAAqC,CAAC,EAAE,YAAY,EAAE,CAAC;YACvD,gBAAgB;SACjB;KACF,CAAC,CAAC,YAAY,EAAE,CAAC;AACpB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iCAAiC,CAAC,EACzC,OAAO,GAGR;IACC,OAAO,wBAAwB,CAAC;QAC9B,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,uBAAuB,GAAG,CAC9B,OAAY,EAC6B,EAAE;IAC3C,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;YACrC,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,SAAS,6BAA6B,CAAC,EACrC,YAAY,EACZ,OAAO,EACP,gBAAgB,GAKjB;IAKC,sBAAsB;IACtB,iDAAiD;IACjD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO;QACzC,CAAC,CAAC,CAAC,oCAAoC,EAAE,CAAC;QAC1C,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,eAAe,CAAC,MAAM,CAAC;QAC5B,UAAU,EAAE;YACV,GAAG,eAAe;YAClB,uBAAuB,CAAC,OAAO,CAAC;YAChC,+BAA+B,CAAC,EAAE,YAAY,EAAE,CAAC;YACjD,0BAA0B,CAAC,EAAE,YAAY,EAAE,CAAC;YAC5C,6BAA6B,EAAE;YAC/B,qCAAqC,CAAC,EAAE,YAAY,EAAE,CAAC;YACvD,gBAAgB;SACjB;KACF,CAAC,CAAC,YAAY,EAAE,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAS,oCAAoC;IAI3C,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,IAAI,OAAO,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;YACzC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { CONNECTIVITY_STATUSES } from '@metamask/connectivity-controller';\nimport type {\n CockatielFailureReason,\n InfuraNetworkType,\n} from '@metamask/controller-utils';\nimport { ChainId } from '@metamask/controller-utils';\nimport type { PollingBlockTrackerOptions } from '@metamask/eth-block-tracker';\nimport { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createInfuraMiddleware } from '@metamask/eth-json-rpc-infura';\nimport {\n createBlockCacheMiddleware,\n createBlockRefMiddleware,\n createBlockRefRewriteMiddleware,\n createBlockTrackerInspectorMiddleware,\n createInflightCacheMiddleware,\n createFetchMiddleware,\n createRetryOnEmptyMiddleware,\n} from '@metamask/eth-json-rpc-middleware';\nimport { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport { providerFromMiddlewareV2 } from '@metamask/eth-json-rpc-provider';\nimport { asV2Middleware } from '@metamask/json-rpc-engine';\nimport {\n createScaffoldMiddleware,\n JsonRpcEngineV2,\n} from '@metamask/json-rpc-engine/v2';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Hex, Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Logger } from 'loglevel';\n\nimport type {\n NetworkClientId,\n NetworkControllerMessenger,\n} from './NetworkController';\nimport type { RpcServiceOptions } from './rpc-service/rpc-service';\nimport { RpcServiceChain } from './rpc-service/rpc-service-chain';\nimport type {\n BlockTracker,\n NetworkClientConfiguration,\n Provider,\n} from './types';\nimport { NetworkClientType } from './types';\n\nconst SECOND = 1000;\n\n/**\n * The pair of provider / block tracker that can be used to interface with the\n * network and respond to new activity.\n */\nexport type NetworkClient = {\n configuration: NetworkClientConfiguration;\n provider: Provider;\n blockTracker: BlockTracker;\n destroy: () => void;\n};\n\ntype RpcApiMiddleware = JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string }>\n>;\n\n/**\n * Create a JSON RPC network client for a specific network.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.getBlockTrackerOptions - Factory for constructing block tracker\n * options. See {@link NetworkControllerOptions.getBlockTrackerOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The network client.\n */\nexport function createNetworkClient({\n id,\n configuration,\n getRpcServiceOptions,\n getBlockTrackerOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n getBlockTrackerOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): NetworkClient {\n const primaryEndpointUrl =\n configuration.type === NetworkClientType.Infura\n ? `https://${configuration.network}.infura.io/v3/${configuration.infuraProjectId}`\n : configuration.rpcUrl;\n const rpcServiceChain = createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n });\n\n let rpcApiMiddleware: RpcApiMiddleware;\n if (configuration.type === NetworkClientType.Infura) {\n rpcApiMiddleware = asV2Middleware(\n createInfuraMiddleware({\n rpcService: rpcServiceChain,\n options: {\n source: 'metamask',\n },\n }),\n );\n } else {\n rpcApiMiddleware = createFetchMiddleware({ rpcService: rpcServiceChain });\n }\n\n const rpcProvider = providerFromMiddlewareV2(rpcApiMiddleware);\n\n const blockTracker = createBlockTracker({\n networkClientType: configuration.type,\n endpointUrl: primaryEndpointUrl,\n getOptions: getBlockTrackerOptions,\n provider: rpcProvider,\n });\n\n const networkMiddleware =\n configuration.type === NetworkClientType.Infura\n ? createInfuraNetworkMiddleware({\n blockTracker,\n network: configuration.network,\n rpcProvider,\n rpcApiMiddleware,\n })\n : createCustomNetworkMiddleware({\n blockTracker,\n chainId: configuration.chainId,\n rpcApiMiddleware,\n });\n\n const provider: Provider = new InternalProvider({\n engine: JsonRpcEngineV2.create({\n middleware: [networkMiddleware],\n }),\n });\n\n const destroy = (): void => {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n blockTracker.destroy();\n };\n\n return { configuration, provider, blockTracker, destroy };\n}\n\n/**\n * Creates an RPC service chain, which represents the primary endpoint URL for\n * the network as well as its failover URLs.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.primaryEndpointUrl - The primary endpoint URL.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The RPC service chain.\n */\nfunction createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n primaryEndpointUrl: string;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): RpcServiceChain {\n const availableEndpointUrls: [string, ...string[]] = isRpcFailoverEnabled\n ? [primaryEndpointUrl, ...(configuration.failoverRpcUrls ?? [])]\n : [primaryEndpointUrl];\n\n const isOffline = (): boolean => {\n const connectivityState = messenger.call('ConnectivityController:getState');\n return (\n connectivityState.connectivityStatus === CONNECTIVITY_STATUSES.Offline\n );\n };\n\n const rpcServiceConfigurations = availableEndpointUrls.map((endpointUrl) => ({\n ...getRpcServiceOptions(endpointUrl),\n endpointUrl,\n logger,\n isOffline,\n }));\n\n /**\n * Extracts the error from Cockatiel's `FailureReason` type received in\n * circuit breaker event handlers.\n *\n * The `FailureReason` object can have two possible shapes:\n * - `{ error: Error }` - When the RPC service throws an error (the common\n * case for RPC failures).\n * - `{ value: T }` - When the RPC service returns a value that the retry\n * filter policy considers a failure.\n *\n * @param value - The event data object from the circuit breaker event\n * listener (after destructuring known properties like `endpointUrl`). This\n * represents Cockatiel's `FailureReason` type.\n * @returns The error or failure value, or `undefined` if neither property\n * exists (which shouldn't happen in practice unless the circuit breaker is\n * manually isolated).\n */\n const getError = (\n value: CockatielFailureReason<unknown> | Record<never, never>,\n ): Error | unknown | undefined => {\n if ('error' in value) {\n return value.error;\n } else if ('value' in value) {\n return value.value;\n }\n return undefined;\n };\n\n const rpcServiceChain = new RpcServiceChain([\n rpcServiceConfigurations[0],\n ...rpcServiceConfigurations.slice(1),\n ]);\n\n rpcServiceChain.onBreak((data) => {\n const error = getError(data);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointChainUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n });\n });\n\n rpcServiceChain.onServiceBreak(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n ...rest\n }) => {\n const error = getError(rest);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n });\n },\n );\n\n rpcServiceChain.onDegraded((data) => {\n const error = getError(data);\n messenger.publish('NetworkController:rpcEndpointChainDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n });\n });\n\n rpcServiceChain.onServiceDegraded(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n ...rest\n }) => {\n const error = getError(rest);\n\n messenger.publish('NetworkController:rpcEndpointDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n });\n },\n );\n\n rpcServiceChain.onAvailable(() => {\n messenger.publish('NetworkController:rpcEndpointChainAvailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n });\n });\n\n rpcServiceChain.onServiceRetry(\n ({\n attempt,\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n }) => {\n messenger.publish('NetworkController:rpcEndpointRetried', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n attempt,\n });\n },\n );\n\n return rpcServiceChain;\n}\n\n/**\n * Create the block tracker for the network.\n *\n * @param args - The arguments.\n * @param args.networkClientType - The type of the network client (\"infura\" or\n * \"custom\").\n * @param args.endpointUrl - The URL of the endpoint.\n * @param args.getOptions - Factory for the block tracker options.\n * @param args.provider - The EIP-1193 provider for the network's JSON-RPC\n * middleware stack.\n * @returns The created block tracker.\n */\nfunction createBlockTracker({\n networkClientType,\n endpointUrl,\n getOptions,\n provider,\n}: {\n networkClientType: NetworkClientType;\n endpointUrl: string;\n getOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n provider: InternalProvider;\n}): PollingBlockTracker {\n const testOptions =\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n process.env.IN_TEST && networkClientType === NetworkClientType.Custom\n ? { pollingInterval: SECOND }\n : {};\n\n return new PollingBlockTracker({\n ...testOptions,\n ...getOptions(endpointUrl),\n provider,\n });\n}\n\n/**\n * Create middleware for infura.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.network - The Infura network to use.\n * @param args.rpcProvider - The RPC provider to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createInfuraNetworkMiddleware({\n blockTracker,\n network,\n rpcProvider,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n network: InfuraNetworkType;\n rpcProvider: InternalProvider;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n return JsonRpcEngineV2.create({\n middleware: [\n createNetworkAndChainIdMiddleware({ network }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockRefMiddleware({ blockTracker, provider: rpcProvider }),\n createRetryOnEmptyMiddleware({ blockTracker, provider: rpcProvider }),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * Creates static method middleware.\n *\n * @param args - The Arguments.\n * @param args.network - The Infura network to use.\n * @returns The middleware that implements the eth_chainId method.\n */\nfunction createNetworkAndChainIdMiddleware({\n network,\n}: {\n network: InfuraNetworkType;\n}): JsonRpcMiddleware<JsonRpcRequest> {\n return createScaffoldMiddleware({\n eth_chainId: ChainId[network],\n });\n}\n\nconst createChainIdMiddleware = (\n chainId: Hex,\n): JsonRpcMiddleware<JsonRpcRequest, Json> => {\n return ({ request, next }) => {\n if (request.method === 'eth_chainId') {\n return chainId;\n }\n return next();\n };\n};\n\n/**\n * Creates custom middleware.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.chainId - The chain id to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createCustomNetworkMiddleware({\n blockTracker,\n chainId,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n chainId: Hex;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n const testMiddlewares = process.env.IN_TEST\n ? [createEstimateGasDelayTestMiddleware()]\n : [];\n\n return JsonRpcEngineV2.create({\n middleware: [\n ...testMiddlewares,\n createChainIdMiddleware(chainId),\n createBlockRefRewriteMiddleware({ blockTracker }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * For use in tests only.\n * Adds a delay to `eth_estimateGas` calls.\n *\n * @returns The middleware for delaying gas estimation calls by 2 seconds when in test.\n */\nfunction createEstimateGasDelayTestMiddleware(): JsonRpcMiddleware<\n JsonRpcRequest,\n Json\n> {\n return async ({ request, next }) => {\n if (request.method === 'eth_estimateGas') {\n await new Promise((resolve) => setTimeout(resolve, SECOND * 2));\n }\n return next();\n };\n}\n"]}
1
+ {"version":3,"file":"create-network-client.mjs","sourceRoot":"","sources":["../src/create-network-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { CONNECTIVITY_STATUSES } from '@metamask/connectivity-controller';\nimport type {\n CockatielFailureReason,\n InfuraNetworkType,\n} from '@metamask/controller-utils';\nimport { ChainId } from '@metamask/controller-utils';\nimport type { PollingBlockTrackerOptions } from '@metamask/eth-block-tracker';\nimport { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createInfuraMiddleware } from '@metamask/eth-json-rpc-infura';\nimport {\n createBlockCacheMiddleware,\n createBlockRefMiddleware,\n createBlockRefRewriteMiddleware,\n createBlockTrackerInspectorMiddleware,\n createInflightCacheMiddleware,\n createFetchMiddleware,\n createRetryOnEmptyMiddleware,\n} from '@metamask/eth-json-rpc-middleware';\nimport { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport { providerFromMiddlewareV2 } from '@metamask/eth-json-rpc-provider';\nimport { asV2Middleware } from '@metamask/json-rpc-engine';\nimport {\n createScaffoldMiddleware,\n JsonRpcEngineV2,\n} from '@metamask/json-rpc-engine/v2';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Hex, Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Logger } from 'loglevel';\n\nimport type {\n NetworkClientId,\n NetworkControllerMessenger,\n} from './NetworkController';\nimport type { RpcServiceOptions } from './rpc-service/rpc-service';\nimport { RpcServiceChain } from './rpc-service/rpc-service-chain';\nimport type {\n BlockTracker,\n NetworkClientConfiguration,\n Provider,\n} from './types';\nimport { NetworkClientType } from './types';\n\nconst SECOND = 1000;\n\n/**\n * The pair of provider / block tracker that can be used to interface with the\n * network and respond to new activity.\n */\nexport type NetworkClient = {\n configuration: NetworkClientConfiguration;\n provider: Provider;\n blockTracker: BlockTracker;\n destroy: () => void;\n};\n\ntype RpcApiMiddleware = JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string }>\n>;\n\n/**\n * Create a JSON RPC network client for a specific network.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.getBlockTrackerOptions - Factory for constructing block tracker\n * options. See {@link NetworkControllerOptions.getBlockTrackerOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The network client.\n */\nexport function createNetworkClient({\n id,\n configuration,\n getRpcServiceOptions,\n getBlockTrackerOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n getBlockTrackerOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): NetworkClient {\n const primaryEndpointUrl =\n configuration.type === NetworkClientType.Infura\n ? `https://${configuration.network}.infura.io/v3/${configuration.infuraProjectId}`\n : configuration.rpcUrl;\n const rpcServiceChain = createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n });\n\n let rpcApiMiddleware: RpcApiMiddleware;\n if (configuration.type === NetworkClientType.Infura) {\n rpcApiMiddleware = asV2Middleware(\n createInfuraMiddleware({\n rpcService: rpcServiceChain,\n options: {\n source: 'metamask',\n },\n }),\n );\n } else {\n rpcApiMiddleware = createFetchMiddleware({ rpcService: rpcServiceChain });\n }\n\n const rpcProvider = providerFromMiddlewareV2(rpcApiMiddleware);\n\n const blockTracker = createBlockTracker({\n networkClientType: configuration.type,\n endpointUrl: primaryEndpointUrl,\n getOptions: getBlockTrackerOptions,\n provider: rpcProvider,\n });\n\n const networkMiddleware =\n configuration.type === NetworkClientType.Infura\n ? createInfuraNetworkMiddleware({\n blockTracker,\n network: configuration.network,\n rpcProvider,\n rpcApiMiddleware,\n })\n : createCustomNetworkMiddleware({\n blockTracker,\n chainId: configuration.chainId,\n rpcApiMiddleware,\n });\n\n const provider: Provider = new InternalProvider({\n engine: JsonRpcEngineV2.create({\n middleware: [networkMiddleware],\n }),\n });\n\n const destroy = (): void => {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n blockTracker.destroy();\n };\n\n return { configuration, provider, blockTracker, destroy };\n}\n\n/**\n * Creates an RPC service chain, which represents the primary endpoint URL for\n * the network as well as its failover URLs.\n *\n * @param args - The arguments.\n * @param args.id - The ID that will be assigned to the new network client in\n * the registry.\n * @param args.primaryEndpointUrl - The primary endpoint URL.\n * @param args.configuration - The network configuration.\n * @param args.getRpcServiceOptions - Factory for constructing RPC service\n * options. See {@link NetworkControllerOptions.getRpcServiceOptions}.\n * @param args.messenger - The network controller messenger.\n * @param args.isRpcFailoverEnabled - Whether or not requests sent to the\n * primary RPC endpoint for this network should be automatically diverted to\n * provided failover endpoints if the primary is unavailable. This effectively\n * causes the `failoverRpcUrls` property of the network client configuration\n * to be honored or ignored.\n * @param args.logger - A `loglevel` logger.\n * @returns The RPC service chain.\n */\nfunction createRpcServiceChain({\n id,\n primaryEndpointUrl,\n configuration,\n getRpcServiceOptions,\n messenger,\n isRpcFailoverEnabled,\n logger,\n}: {\n id: NetworkClientId;\n primaryEndpointUrl: string;\n configuration: NetworkClientConfiguration;\n getRpcServiceOptions: (\n rpcEndpointUrl: string,\n ) => Omit<RpcServiceOptions, 'failoverService' | 'endpointUrl'>;\n messenger: NetworkControllerMessenger;\n isRpcFailoverEnabled: boolean;\n logger?: Logger;\n}): RpcServiceChain {\n const availableEndpointUrls: [string, ...string[]] = isRpcFailoverEnabled\n ? [primaryEndpointUrl, ...(configuration.failoverRpcUrls ?? [])]\n : [primaryEndpointUrl];\n\n const isOffline = (): boolean => {\n const connectivityState = messenger.call('ConnectivityController:getState');\n return (\n connectivityState.connectivityStatus === CONNECTIVITY_STATUSES.Offline\n );\n };\n\n const rpcServiceConfigurations = availableEndpointUrls.map((endpointUrl) => ({\n ...getRpcServiceOptions(endpointUrl),\n endpointUrl,\n logger,\n isOffline,\n }));\n\n /**\n * Extracts the error from Cockatiel's `FailureReason` type received in\n * circuit breaker event handlers.\n *\n * The `FailureReason` object can have two possible shapes:\n * - `{ error: Error }` - When the RPC service throws an error (the common\n * case for RPC failures).\n * - `{ value: T }` - When the RPC service returns a value that the retry\n * filter policy considers a failure.\n *\n * @param value - The event data object from the circuit breaker event\n * listener (after destructuring known properties like `endpointUrl` and\n * `rpcMethodName`). This represents Cockatiel's `FailureReason` type.\n * @returns The error or failure value, or `undefined` if neither property\n * exists (which shouldn't happen in practice unless the circuit breaker is\n * manually isolated).\n */\n const getError = (\n value: CockatielFailureReason<unknown> | Record<never, never>,\n ): Error | unknown | undefined => {\n if ('error' in value) {\n return value.error;\n } else if ('value' in value) {\n return value.value;\n }\n return undefined;\n };\n\n const rpcServiceChain = new RpcServiceChain([\n rpcServiceConfigurations[0],\n ...rpcServiceConfigurations.slice(1),\n ]);\n\n rpcServiceChain.onBreak(({ rpcMethodName, ...rest }) => {\n const error = getError(rest);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointChainUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n rpcMethodName,\n });\n });\n\n rpcServiceChain.onServiceBreak(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n rpcMethodName,\n ...rest\n }) => {\n const error = getError(rest);\n\n if (error === undefined) {\n // This error shouldn't happen in practice because we never call `.isolate`\n // on the circuit breaker policy, but we need to appease TypeScript.\n throw new Error('Could not make request to endpoint.');\n }\n\n messenger.publish('NetworkController:rpcEndpointUnavailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n rpcMethodName,\n });\n },\n );\n\n rpcServiceChain.onDegraded(({ rpcMethodName, ...rest }) => {\n const error = getError(rest);\n messenger.publish('NetworkController:rpcEndpointChainDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n error,\n rpcMethodName,\n });\n });\n\n rpcServiceChain.onServiceDegraded(\n ({\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n rpcMethodName,\n ...rest\n }) => {\n const error = getError(rest);\n\n messenger.publish('NetworkController:rpcEndpointDegraded', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n error,\n rpcMethodName,\n });\n },\n );\n\n rpcServiceChain.onAvailable(() => {\n messenger.publish('NetworkController:rpcEndpointChainAvailable', {\n chainId: configuration.chainId,\n networkClientId: id,\n });\n });\n\n rpcServiceChain.onServiceRetry(\n ({\n attempt,\n endpointUrl,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n }) => {\n messenger.publish('NetworkController:rpcEndpointRetried', {\n chainId: configuration.chainId,\n networkClientId: id,\n primaryEndpointUrl: primaryEndpointUrlFromEvent,\n endpointUrl,\n attempt,\n });\n },\n );\n\n return rpcServiceChain;\n}\n\n/**\n * Create the block tracker for the network.\n *\n * @param args - The arguments.\n * @param args.networkClientType - The type of the network client (\"infura\" or\n * \"custom\").\n * @param args.endpointUrl - The URL of the endpoint.\n * @param args.getOptions - Factory for the block tracker options.\n * @param args.provider - The EIP-1193 provider for the network's JSON-RPC\n * middleware stack.\n * @returns The created block tracker.\n */\nfunction createBlockTracker({\n networkClientType,\n endpointUrl,\n getOptions,\n provider,\n}: {\n networkClientType: NetworkClientType;\n endpointUrl: string;\n getOptions: (\n rpcEndpointUrl: string,\n ) => Omit<PollingBlockTrackerOptions, 'provider'>;\n provider: InternalProvider;\n}): PollingBlockTracker {\n const testOptions =\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n process.env.IN_TEST && networkClientType === NetworkClientType.Custom\n ? { pollingInterval: SECOND }\n : {};\n\n return new PollingBlockTracker({\n ...testOptions,\n ...getOptions(endpointUrl),\n provider,\n });\n}\n\n/**\n * Create middleware for infura.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.network - The Infura network to use.\n * @param args.rpcProvider - The RPC provider to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createInfuraNetworkMiddleware({\n blockTracker,\n network,\n rpcProvider,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n network: InfuraNetworkType;\n rpcProvider: InternalProvider;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n return JsonRpcEngineV2.create({\n middleware: [\n createNetworkAndChainIdMiddleware({ network }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockRefMiddleware({ blockTracker, provider: rpcProvider }),\n createRetryOnEmptyMiddleware({ blockTracker, provider: rpcProvider }),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * Creates static method middleware.\n *\n * @param args - The Arguments.\n * @param args.network - The Infura network to use.\n * @returns The middleware that implements the eth_chainId method.\n */\nfunction createNetworkAndChainIdMiddleware({\n network,\n}: {\n network: InfuraNetworkType;\n}): JsonRpcMiddleware<JsonRpcRequest> {\n return createScaffoldMiddleware({\n eth_chainId: ChainId[network],\n });\n}\n\nconst createChainIdMiddleware = (\n chainId: Hex,\n): JsonRpcMiddleware<JsonRpcRequest, Json> => {\n return ({ request, next }) => {\n if (request.method === 'eth_chainId') {\n return chainId;\n }\n return next();\n };\n};\n\n/**\n * Creates custom middleware.\n *\n * @param args - The arguments.\n * @param args.blockTracker - The block tracker to use.\n * @param args.chainId - The chain id to use.\n * @param args.rpcApiMiddleware - Additional middleware.\n * @returns The collection of middleware that makes up the Infura client.\n */\nfunction createCustomNetworkMiddleware({\n blockTracker,\n chainId,\n rpcApiMiddleware,\n}: {\n blockTracker: PollingBlockTracker;\n chainId: Hex;\n rpcApiMiddleware: RpcApiMiddleware;\n}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ origin: string; skipCache: boolean }>\n> {\n // Needed for testing.\n // eslint-disable-next-line no-restricted-globals\n const testMiddlewares = process.env.IN_TEST\n ? [createEstimateGasDelayTestMiddleware()]\n : [];\n\n return JsonRpcEngineV2.create({\n middleware: [\n ...testMiddlewares,\n createChainIdMiddleware(chainId),\n createBlockRefRewriteMiddleware({ blockTracker }),\n createBlockCacheMiddleware({ blockTracker }),\n createInflightCacheMiddleware(),\n createBlockTrackerInspectorMiddleware({ blockTracker }),\n rpcApiMiddleware,\n ],\n }).asMiddleware();\n}\n\n/**\n * For use in tests only.\n * Adds a delay to `eth_estimateGas` calls.\n *\n * @returns The middleware for delaying gas estimation calls by 2 seconds when in test.\n */\nfunction createEstimateGasDelayTestMiddleware(): JsonRpcMiddleware<\n JsonRpcRequest,\n Json\n> {\n return async ({ request, next }) => {\n if (request.method === 'eth_estimateGas') {\n await new Promise((resolve) => setTimeout(resolve, SECOND * 2));\n }\n return next();\n };\n}\n"]}
@@ -269,6 +269,7 @@ class RpcServiceChain {
269
269
  __classPrivateFieldSet(this, _RpcServiceChain_status, STATUSES.Unavailable, "f");
270
270
  __classPrivateFieldGet(this, _RpcServiceChain_onBreakEventEmitter, "f").emit({
271
271
  error: lastError,
272
+ rpcMethodName: jsonRpcRequest.method,
272
273
  });
273
274
  }
274
275
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CircuitState,\n CockatielEventEmitter,\n} from '@metamask/controller-utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\nimport { IDisposable } from 'cockatiel';\n\nimport { RpcService } from './rpc-service';\nimport type { RpcServiceOptions } from './rpc-service';\nimport type {\n CockatielEventToEventListenerWithData,\n ExcludeCockatielEventData,\n ExtractCockatielEventData,\n FetchOptions,\n} from './shared';\nimport { projectLogger, createModuleLogger } from '../logger';\n\nconst log = createModuleLogger(projectLogger, 'RpcServiceChain');\n\n/**\n * Statuses that the RPC service chain can be in.\n */\nconst STATUSES = {\n Available: 'available',\n Degraded: 'degraded',\n Unknown: 'unknown',\n Unavailable: 'unavailable',\n} as const;\n\n/**\n * Statuses that the RPC service chain can be in.\n */\ntype Status = (typeof STATUSES)[keyof typeof STATUSES];\n\n/**\n * This class constructs and manages requests to a chain of RpcService objects\n * which represent RPC endpoints with which to access a particular network. The\n * first service in the chain is intended to be the primary way of hitting the\n * network and the remaining services are used as failovers.\n */\nexport class RpcServiceChain {\n /**\n * The event emitter for the `onAvailable` event.\n */\n readonly #onAvailableEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onBreak` event.\n */\n readonly #onBreakEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onDegraded` event.\n */\n readonly #onDegradedEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The first RPC service that requests will be sent to.\n */\n readonly #primaryService: RpcService;\n\n /**\n * The RPC services in the chain.\n */\n readonly #services: RpcService[];\n\n /**\n * The status of the RPC service chain.\n */\n #status: Status;\n\n /**\n * Constructs a new RpcServiceChain object.\n *\n * @param rpcServiceConfigurations - The options for the RPC services\n * that you want to construct. Each object in this array is the same as\n * {@link RpcServiceOptions}.\n */\n constructor(\n rpcServiceConfigurations: [RpcServiceOptions, ...RpcServiceOptions[]],\n ) {\n this.#services = rpcServiceConfigurations.map(\n (rpcServiceConfiguration) => new RpcService(rpcServiceConfiguration),\n );\n this.#primaryService = this.#services[0];\n\n this.#status = STATUSES.Unknown;\n this.#onBreakEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >();\n\n this.#onDegradedEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onDegraded((data) => {\n if (this.#status !== STATUSES.Degraded) {\n log('Updating status to \"degraded\"', data);\n this.#status = STATUSES.Degraded;\n const { endpointUrl, ...rest } = data;\n this.#onDegradedEventEmitter.emit(rest);\n }\n });\n }\n\n this.#onAvailableEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onAvailable((data) => {\n if (this.#status !== STATUSES.Available) {\n log('Updating status to \"available\"', data);\n this.#status = STATUSES.Available;\n const { endpointUrl, ...rest } = data;\n this.#onAvailableEventEmitter.emit(rest);\n }\n });\n }\n }\n\n /**\n * Calls the provided callback when any of the RPC services is retried.\n *\n * This is mainly useful for tests.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the event listener.\n */\n onServiceRetry(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onRetry'],\n { primaryEndpointUrl: string }\n >,\n ): { dispose(): void } {\n const disposables = this.#services.map((service) =>\n service.onRetry((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback only when the maximum number of failed\n * consecutive attempts to receive a 2xx response has been reached for all\n * RPC services in the chain, and all services' underlying circuits have\n * broken.\n *\n * The callback will not be called if a service's circuit breaks but its\n * failover does not. Use `onServiceBreak` if you'd like a lower level of\n * granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onBreak(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onBreakEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time when, for *any* of the RPC services\n * in this chain, the maximum number of failed consecutive attempts to receive\n * a 2xx response has been reached and the underlying circuit has broken. A\n * more granular version of `onBreak`.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceBreak(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onBreak'],\n { primaryEndpointUrl: string }\n >,\n ): IDisposable {\n const disposables = this.#services.map((service) =>\n service.onBreak((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback if no requests have been initiated yet or\n * all requests to RPC services in this chain have responded successfully in a\n * timely fashion, and then one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * Also note this callback will only be called if the RPC service chain as a\n * whole is in a \"degraded\" state, and will then only be called once (e.g., it\n * will not be called if a failover service falls into a degraded state, then\n * the primary comes back online, but it is slow). Use `onServiceDegraded` if\n * you'd like a lower level of granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onDegraded(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onDegradedEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * This is a more granular version of `onDegraded`. The callback will be\n * called for each slow request to an RPC service. It may also be called again\n * if a failover service falls into a degraded state, then the primary comes\n * back online, but it is slow.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceDegraded(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onDegraded'],\n { primaryEndpointUrl: string }\n >,\n ): IDisposable {\n const disposables = this.#services.map((service) =>\n service.onDegraded((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback in one of the following two conditions:\n *\n * 1. The first time that a 2xx request is made to any of the RPC services in\n * this chain.\n * 2. When requests to any the failover RPC services in this chain were\n * failing such that they were degraded or their underyling circuits broke,\n * but the first request to the primary succeeds again.\n *\n * Note this callback will only be called if the RPC service chain as a whole\n * is in an \"available\" state.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onAvailable(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onAvailableEventEmitter.addListener(listener);\n }\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\n *\n * This overload is specifically designed for `eth_getBlockByNumber`, which\n * can return a `result` of `null` despite an expected `Result` being\n * provided.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>> & {\n method: 'eth_getBlockByNumber';\n },\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>>;\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\n *\n * This overload is designed for all RPC methods except for\n * `eth_getBlockByNumber`, which are expected to return a `result` of the\n * expected `Result`.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result>>;\n\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n // Start with the primary (first) service and switch to failovers as the\n // need arises. This is a bit confusing, so keep reading for more on how\n // this works.\n\n let availableServiceIndex: number | undefined;\n let response: JsonRpcResponse<Result> | undefined;\n\n for (const [i, service] of this.#services.entries()) {\n log(`Trying service #${i + 1}...`);\n const previousCircuitState = service.getCircuitState();\n\n try {\n // Try making the request through the service.\n response = await service.request<Params, Result>(\n jsonRpcRequest,\n fetchOptions,\n );\n log('Service successfully received request.');\n availableServiceIndex = i;\n break;\n } catch (error) {\n // Oops, that didn't work.\n // Capture this error so that we can handle it later.\n\n const { lastError } = service;\n const isCircuitOpen = service.getCircuitState() === CircuitState.Open;\n\n log('Service failed! error =', error, 'lastError = ', lastError);\n\n if (isCircuitOpen) {\n if (i < this.#services.length - 1) {\n log(\n \"This service's circuit is open. Proceeding to next service...\",\n );\n continue;\n }\n\n if (\n previousCircuitState !== CircuitState.Open &&\n this.#status !== STATUSES.Unavailable &&\n lastError !== undefined\n ) {\n // If the service's circuit just broke and it's the last one in the\n // chain, then trigger the onBreak event. (But if for some reason we\n // have already done this, then don't do it.)\n log(\n 'This service\\'s circuit just opened and it is the last service. Updating status to \"unavailable\" and triggering onBreak.',\n );\n this.#status = STATUSES.Unavailable;\n this.#onBreakEventEmitter.emit({\n error: lastError,\n });\n }\n }\n\n // The service failed, and we throw whatever the error is. The calling\n // code can try again if it so desires.\n log(\n `${isCircuitOpen ? '' : \"This service's circuit is closed. \"}Re-throwing error.`,\n );\n throw error;\n }\n }\n\n if (response) {\n // If one of the services is available, reset all of the circuits of the\n // following services. If we didn't do this and the service became\n // unavailable in the future, and any of the failovers' circuits were\n // open (due to previous failures), we would receive a \"circuit broken\"\n // error when we attempted to divert traffic to the failovers again.\n //\n if (availableServiceIndex !== undefined) {\n for (const [i, service] of [...this.#services.entries()].slice(\n availableServiceIndex + 1,\n )) {\n log(`Resetting policy for service #${i + 1}.`);\n service.resetPolicy();\n }\n }\n\n return response;\n }\n\n // The only way we can end up here is if there are no services to loop over.\n // That is not possible due to the types on the constructor, but TypeScript\n // doesn't know this, so we have to appease it.\n throw new Error('Nothing to return');\n }\n}\n"]}
1
+ {"version":3,"file":"rpc-service-chain.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,iEAGoC;AASpC,mDAA2C;AAQ3C,0CAA8D;AAE9D,MAAM,GAAG,GAAG,IAAA,2BAAkB,EAAC,sBAAa,EAAE,iBAAiB,CAAC,CAAC;AAEjE;;GAEG;AACH,MAAM,QAAQ,GAAG;IACf,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;CAClB,CAAC;AAOX;;;;;GAKG;AACH,MAAa,eAAe;IA8C1B;;;;;;OAMG;IACH,YACE,wBAAqE;QArDvE;;WAEG;QACM,2DAKP;QAEF;;WAEG;QACM,uDAKP;QAEF;;WAEG;QACM,0DAKP;QAEF;;WAEG;QACM,kDAA4B;QAErC;;WAEG;QACM,4CAAwB;QAEjC;;WAEG;QACH,0CAAgB;QAYd,uBAAA,IAAI,6BAAa,wBAAwB,CAAC,GAAG,CAC3C,CAAC,uBAAuB,EAAE,EAAE,CAAC,IAAI,wBAAU,CAAC,uBAAuB,CAAC,CACrE,MAAA,CAAC;QACF,uBAAA,IAAI,mCAAmB,uBAAA,IAAI,iCAAU,CAAC,CAAC,CAAC,MAAA,CAAC;QAEzC,uBAAA,IAAI,2BAAW,QAAQ,CAAC,OAAO,MAAA,CAAC;QAChC,uBAAA,IAAI,wCAAwB,IAAI,wCAAqB,EAKlD,MAAA,CAAC;QAEJ,uBAAA,IAAI,2CAA2B,IAAI,wCAAqB,EAKrD,MAAA,CAAC;QACJ,KAAK,MAAM,OAAO,IAAI,uBAAA,IAAI,iCAAU,EAAE,CAAC;YACrC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC1B,IAAI,uBAAA,IAAI,+BAAQ,KAAK,QAAQ,CAAC,QAAQ,EAAE,CAAC;oBACvC,GAAG,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAAC;oBAC3C,uBAAA,IAAI,2BAAW,QAAQ,CAAC,QAAQ,MAAA,CAAC;oBACjC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;oBACtC,uBAAA,IAAI,+CAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,uBAAA,IAAI,4CAA4B,IAAI,wCAAqB,EAKtD,MAAA,CAAC;QACJ,KAAK,MAAM,OAAO,IAAI,uBAAA,IAAI,iCAAU,EAAE,CAAC;YACrC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC3B,IAAI,uBAAA,IAAI,+BAAQ,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC;oBACxC,GAAG,CAAC,gCAAgC,EAAE,IAAI,CAAC,CAAC;oBAC5C,uBAAA,IAAI,2BAAW,QAAQ,CAAC,SAAS,MAAA,CAAC;oBAClC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;oBACtC,uBAAA,IAAI,gDAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc,CACZ,QAGC;QAED,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACvB,QAAQ,CAAC;gBACP,GAAG,IAAI;gBACP,kBAAkB,EAAE,uBAAA,IAAI,uCAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE;aAChE,CAAC,CAAC;QACL,CAAC,CAAC,CACH,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAKS;QAET,OAAO,uBAAA,IAAI,4CAAqB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;;OASG;IACH,cAAc,CACZ,QAGC;QAED,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACvB,QAAQ,CAAC;gBACP,GAAG,IAAI;gBACP,kBAAkB,EAAE,uBAAA,IAAI,uCAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE;aAChE,CAAC,CAAC;QACL,CAAC,CAAC,CACH,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAKS;QAET,OAAO,uBAAA,IAAI,+CAAwB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAGC;QAED,MAAM,WAAW,GAAG,uBAAA,IAAI,iCAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,QAAQ,CAAC;gBACP,GAAG,IAAI;gBACP,kBAAkB,EAAE,uBAAA,IAAI,uCAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE;aAChE,CAAC,CAAC;QACL,CAAC,CAAC,CACH,CAAC;QAEF,OAAO;YACL,OAAO;gBACL,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAKS;QAET,OAAO,uBAAA,IAAI,gDAAyB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC7D,CAAC;IAkDD,KAAK,CAAC,OAAO,CACX,cAAgD,EAChD,eAA6B,EAAE;QAE/B,wEAAwE;QACxE,wEAAwE;QACxE,cAAc;QAEd,IAAI,qBAAyC,CAAC;QAC9C,IAAI,QAA6C,CAAC;QAElD,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,uBAAA,IAAI,iCAAU,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,oBAAoB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;YAEvD,IAAI,CAAC;gBACH,8CAA8C;gBAC9C,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAC9B,cAAc,EACd,YAAY,CACb,CAAC;gBACF,GAAG,CAAC,wCAAwC,CAAC,CAAC;gBAC9C,qBAAqB,GAAG,CAAC,CAAC;gBAC1B,MAAM;YACR,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,0BAA0B;gBAC1B,qDAAqD;gBAErD,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;gBAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,eAAe,EAAE,KAAK,+BAAY,CAAC,IAAI,CAAC;gBAEtE,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;gBAEjE,IAAI,aAAa,EAAE,CAAC;oBAClB,IAAI,CAAC,GAAG,uBAAA,IAAI,iCAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAClC,GAAG,CACD,+DAA+D,CAChE,CAAC;wBACF,SAAS;oBACX,CAAC;oBAED,IACE,oBAAoB,KAAK,+BAAY,CAAC,IAAI;wBAC1C,uBAAA,IAAI,+BAAQ,KAAK,QAAQ,CAAC,WAAW;wBACrC,SAAS,KAAK,SAAS,EACvB,CAAC;wBACD,mEAAmE;wBACnE,oEAAoE;wBACpE,6CAA6C;wBAC7C,GAAG,CACD,0HAA0H,CAC3H,CAAC;wBACF,uBAAA,IAAI,2BAAW,QAAQ,CAAC,WAAW,MAAA,CAAC;wBACpC,uBAAA,IAAI,4CAAqB,CAAC,IAAI,CAAC;4BAC7B,KAAK,EAAE,SAAS;4BAChB,aAAa,EAAE,cAAc,CAAC,MAAM;yBACrC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,sEAAsE;gBACtE,uCAAuC;gBACvC,GAAG,CACD,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oCAAoC,oBAAoB,CACjF,CAAC;gBACF,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,wEAAwE;YACxE,kEAAkE;YAClE,qEAAqE;YACrE,uEAAuE;YACvE,oEAAoE;YACpE,EAAE;YACF,IAAI,qBAAqB,KAAK,SAAS,EAAE,CAAC;gBACxC,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,uBAAA,IAAI,iCAAU,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAC5D,qBAAqB,GAAG,CAAC,CAC1B,EAAE,CAAC;oBACF,GAAG,CAAC,iCAAiC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC/C,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,CAAC;YACH,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,4EAA4E;QAC5E,2EAA2E;QAC3E,+CAA+C;QAC/C,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;CACF;AApbD,0CAobC","sourcesContent":["import {\n CircuitState,\n CockatielEventEmitter,\n} from '@metamask/controller-utils';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\nimport { IDisposable } from 'cockatiel';\n\nimport { RpcService } from './rpc-service';\nimport type { RpcServiceOptions } from './rpc-service';\nimport type {\n CockatielEventToEventListenerWithData,\n ExcludeCockatielEventData,\n ExtractCockatielEventData,\n FetchOptions,\n} from './shared';\nimport { projectLogger, createModuleLogger } from '../logger';\n\nconst log = createModuleLogger(projectLogger, 'RpcServiceChain');\n\n/**\n * Statuses that the RPC service chain can be in.\n */\nconst STATUSES = {\n Available: 'available',\n Degraded: 'degraded',\n Unknown: 'unknown',\n Unavailable: 'unavailable',\n} as const;\n\n/**\n * Statuses that the RPC service chain can be in.\n */\ntype Status = (typeof STATUSES)[keyof typeof STATUSES];\n\n/**\n * This class constructs and manages requests to a chain of RpcService objects\n * which represent RPC endpoints with which to access a particular network. The\n * first service in the chain is intended to be the primary way of hitting the\n * network and the remaining services are used as failovers.\n */\nexport class RpcServiceChain {\n /**\n * The event emitter for the `onAvailable` event.\n */\n readonly #onAvailableEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onBreak` event.\n */\n readonly #onBreakEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The event emitter for the `onDegraded` event.\n */\n readonly #onDegradedEventEmitter: CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >;\n\n /**\n * The first RPC service that requests will be sent to.\n */\n readonly #primaryService: RpcService;\n\n /**\n * The RPC services in the chain.\n */\n readonly #services: RpcService[];\n\n /**\n * The status of the RPC service chain.\n */\n #status: Status;\n\n /**\n * Constructs a new RpcServiceChain object.\n *\n * @param rpcServiceConfigurations - The options for the RPC services\n * that you want to construct. Each object in this array is the same as\n * {@link RpcServiceOptions}.\n */\n constructor(\n rpcServiceConfigurations: [RpcServiceOptions, ...RpcServiceOptions[]],\n ) {\n this.#services = rpcServiceConfigurations.map(\n (rpcServiceConfiguration) => new RpcService(rpcServiceConfiguration),\n );\n this.#primaryService = this.#services[0];\n\n this.#status = STATUSES.Unknown;\n this.#onBreakEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >\n >();\n\n this.#onDegradedEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onDegraded((data) => {\n if (this.#status !== STATUSES.Degraded) {\n log('Updating status to \"degraded\"', data);\n this.#status = STATUSES.Degraded;\n const { endpointUrl, ...rest } = data;\n this.#onDegradedEventEmitter.emit(rest);\n }\n });\n }\n\n this.#onAvailableEventEmitter = new CockatielEventEmitter<\n ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >\n >();\n for (const service of this.#services) {\n service.onAvailable((data) => {\n if (this.#status !== STATUSES.Available) {\n log('Updating status to \"available\"', data);\n this.#status = STATUSES.Available;\n const { endpointUrl, ...rest } = data;\n this.#onAvailableEventEmitter.emit(rest);\n }\n });\n }\n }\n\n /**\n * Calls the provided callback when any of the RPC services is retried.\n *\n * This is mainly useful for tests.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the event listener.\n */\n onServiceRetry(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onRetry'],\n { primaryEndpointUrl: string }\n >,\n ): { dispose(): void } {\n const disposables = this.#services.map((service) =>\n service.onRetry((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback only when the maximum number of failed\n * consecutive attempts to receive a 2xx response has been reached for all\n * RPC services in the chain, and all services' underlying circuits have\n * broken.\n *\n * The callback will not be called if a service's circuit breaks but its\n * failover does not. Use `onServiceBreak` if you'd like a lower level of\n * granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onBreak(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onBreak']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onBreakEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time when, for *any* of the RPC services\n * in this chain, the maximum number of failed consecutive attempts to receive\n * a 2xx response has been reached and the underlying circuit has broken. A\n * more granular version of `onBreak`.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceBreak(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onBreak'],\n { primaryEndpointUrl: string }\n >,\n ): IDisposable {\n const disposables = this.#services.map((service) =>\n service.onBreak((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback if no requests have been initiated yet or\n * all requests to RPC services in this chain have responded successfully in a\n * timely fashion, and then one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * Also note this callback will only be called if the RPC service chain as a\n * whole is in a \"degraded\" state, and will then only be called once (e.g., it\n * will not be called if a failover service falls into a degraded state, then\n * the primary comes back online, but it is slow). Use `onServiceDegraded` if\n * you'd like a lower level of granularity.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onDegraded(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onDegraded']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onDegradedEventEmitter.addListener(listener);\n }\n\n /**\n * Calls the provided callback each time one of the two conditions apply:\n *\n * 1. When a retriable error is encountered making a request to an RPC\n * service, and the request is retried until a set maximum is reached.\n * 2. When a RPC service responds successfully, but the request takes longer\n * than a set number of seconds to complete.\n *\n * Note that the callback will be called even if there are local connectivity\n * issues which prevent requests from being initiated. This is intentional.\n *\n * This is a more granular version of `onDegraded`. The callback will be\n * called for each slow request to an RPC service. It may also be called again\n * if a failover service falls into a degraded state, then the primary comes\n * back online, but it is slow.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onServiceDegraded(\n listener: CockatielEventToEventListenerWithData<\n RpcService['onDegraded'],\n { primaryEndpointUrl: string }\n >,\n ): IDisposable {\n const disposables = this.#services.map((service) =>\n service.onDegraded((data) => {\n listener({\n ...data,\n primaryEndpointUrl: this.#primaryService.endpointUrl.toString(),\n });\n }),\n );\n\n return {\n dispose(): void {\n disposables.forEach((disposable) => disposable.dispose());\n },\n };\n }\n\n /**\n * Calls the provided callback in one of the following two conditions:\n *\n * 1. The first time that a 2xx request is made to any of the RPC services in\n * this chain.\n * 2. When requests to any the failover RPC services in this chain were\n * failing such that they were degraded or their underyling circuits broke,\n * but the first request to the primary succeeds again.\n *\n * Note this callback will only be called if the RPC service chain as a whole\n * is in an \"available\" state.\n *\n * @param listener - The callback to be called.\n * @returns An object with a `dispose` method which can be used to unregister\n * the callback.\n */\n onAvailable(\n listener: (\n data: ExcludeCockatielEventData<\n ExtractCockatielEventData<RpcService['onAvailable']>,\n 'endpointUrl'\n >,\n ) => void,\n ): IDisposable {\n return this.#onAvailableEventEmitter.addListener(listener);\n }\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\n *\n * This overload is specifically designed for `eth_getBlockByNumber`, which\n * can return a `result` of `null` despite an expected `Result` being\n * provided.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>> & {\n method: 'eth_getBlockByNumber';\n },\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result> | JsonRpcResponse<null>>;\n\n /**\n * Uses the RPC services in the chain to make a request, using each service\n * after the first as a fallback to the previous one as necessary.\n *\n * This overload is designed for all RPC methods except for\n * `eth_getBlockByNumber`, which are expected to return a `result` of the\n * expected `Result`.\n *\n * @param jsonRpcRequest - The JSON-RPC request to send to the endpoint.\n * @param fetchOptions - An options bag for {@link fetch} which further\n * specifies the request.\n * @returns The decoded JSON-RPC response from the endpoint.\n * @throws A 401 error if the response status is 401.\n * @throws A \"rate limiting\" error if the response HTTP status is 429.\n * @throws A \"resource unavailable\" error if the response status is 402, 404, or any 5xx.\n * @throws A generic HTTP client error (-32100) for any other 4xx status codes.\n * @throws A \"parse\" error if the response is not valid JSON.\n */\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions?: FetchOptions,\n ): Promise<JsonRpcResponse<Result>>;\n\n async request<Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: Readonly<JsonRpcRequest<Params>>,\n fetchOptions: FetchOptions = {},\n ): Promise<JsonRpcResponse<Result | null>> {\n // Start with the primary (first) service and switch to failovers as the\n // need arises. This is a bit confusing, so keep reading for more on how\n // this works.\n\n let availableServiceIndex: number | undefined;\n let response: JsonRpcResponse<Result> | undefined;\n\n for (const [i, service] of this.#services.entries()) {\n log(`Trying service #${i + 1}...`);\n const previousCircuitState = service.getCircuitState();\n\n try {\n // Try making the request through the service.\n response = await service.request<Params, Result>(\n jsonRpcRequest,\n fetchOptions,\n );\n log('Service successfully received request.');\n availableServiceIndex = i;\n break;\n } catch (error) {\n // Oops, that didn't work.\n // Capture this error so that we can handle it later.\n\n const { lastError } = service;\n const isCircuitOpen = service.getCircuitState() === CircuitState.Open;\n\n log('Service failed! error =', error, 'lastError = ', lastError);\n\n if (isCircuitOpen) {\n if (i < this.#services.length - 1) {\n log(\n \"This service's circuit is open. Proceeding to next service...\",\n );\n continue;\n }\n\n if (\n previousCircuitState !== CircuitState.Open &&\n this.#status !== STATUSES.Unavailable &&\n lastError !== undefined\n ) {\n // If the service's circuit just broke and it's the last one in the\n // chain, then trigger the onBreak event. (But if for some reason we\n // have already done this, then don't do it.)\n log(\n 'This service\\'s circuit just opened and it is the last service. Updating status to \"unavailable\" and triggering onBreak.',\n );\n this.#status = STATUSES.Unavailable;\n this.#onBreakEventEmitter.emit({\n error: lastError,\n rpcMethodName: jsonRpcRequest.method,\n });\n }\n }\n\n // The service failed, and we throw whatever the error is. The calling\n // code can try again if it so desires.\n log(\n `${isCircuitOpen ? '' : \"This service's circuit is closed. \"}Re-throwing error.`,\n );\n throw error;\n }\n }\n\n if (response) {\n // If one of the services is available, reset all of the circuits of the\n // following services. If we didn't do this and the service became\n // unavailable in the future, and any of the failovers' circuits were\n // open (due to previous failures), we would receive a \"circuit broken\"\n // error when we attempted to divert traffic to the failovers again.\n //\n if (availableServiceIndex !== undefined) {\n for (const [i, service] of [...this.#services.entries()].slice(\n availableServiceIndex + 1,\n )) {\n log(`Resetting policy for service #${i + 1}.`);\n service.resetPolicy();\n }\n }\n\n return response;\n }\n\n // The only way we can end up here is if there are no services to loop over.\n // That is not possible due to the types on the constructor, but TypeScript\n // doesn't know this, so we have to appease it.\n throw new Error('Nothing to return');\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,WAAW,EAAE,kBAAkB;AAExC,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE;IAiBtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA8FpC"}
1
+ {"version":3,"file":"rpc-service-chain.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,WAAW,EAAE,kBAAkB;AAExC,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE;IAiBtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA+FpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-service-chain.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,WAAW,EAAE,kBAAkB;AAExC,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE;IAiBtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA8FpC"}
1
+ {"version":3,"file":"rpc-service-chain.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-service-chain.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AACzB,OAAO,EAAE,WAAW,EAAE,kBAAkB;AAExC,OAAO,EAAE,UAAU,EAAE,0BAAsB;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAAsB;AACvD,OAAO,KAAK,EACV,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB,EACzB,YAAY,EACb,qBAAiB;AAoBlB;;;;;GAKG;AACH,qBAAa,eAAe;;IA8C1B;;;;;;OAMG;gBAED,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAkDvE;;;;;;;;OAQG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE;IAiBtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CACL,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAChD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,SAAS,CAAC,EACrB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACR,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACnD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iBAAiB,CACf,QAAQ,EAAE,qCAAqC,CAC7C,UAAU,CAAC,YAAY,CAAC,EACxB;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAC/B,GACA,WAAW;IAiBd;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,QAAQ,EAAE,CACR,IAAI,EAAE,yBAAyB,CAC7B,yBAAyB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EACpD,aAAa,CACd,KACE,IAAI,GACR,WAAW;IAId;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG;QACjD,MAAM,EAAE,sBAAsB,CAAC;KAChC,EACD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EAC7D,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAChD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;CA+FpC"}
@@ -266,6 +266,7 @@ export class RpcServiceChain {
266
266
  __classPrivateFieldSet(this, _RpcServiceChain_status, STATUSES.Unavailable, "f");
267
267
  __classPrivateFieldGet(this, _RpcServiceChain_onBreakEventEmitter, "f").emit({
268
268
  error: lastError,
269
+ rpcMethodName: jsonRpcRequest.method,
269
270
  });
270
271
  }
271
272
  }