{"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 {\n  isConnectionError,\n  isConnectionResetError,\n  isJsonParseError,\n  isHttpServerError,\n  isTimeoutError,\n} 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 * Why the degraded event was emitted.\n */\nexport type DegradedEventType = 'slow_success' | 'retries_exhausted';\n\n/**\n * The category of error that was retried until retries were exhausted.\n */\nexport type RetryReason =\n  | 'connection_failed'\n  | 'response_not_json'\n  | 'non_successful_http_status'\n  | 'timed_out'\n  | 'connection_reset'\n  | 'unknown';\n\n/**\n * Classifies the error that was being retried when retries were exhausted.\n *\n * @param error - The error from the last retry attempt.\n * @returns A classification string.\n */\nexport function classifyRetryReason(error: unknown): RetryReason {\n  if (!(error instanceof Error)) {\n    return 'unknown';\n  }\n  if (isConnectionError(error)) {\n    return 'connection_failed';\n  }\n  if (isJsonParseError(error)) {\n    return 'response_not_json';\n  }\n  if (isHttpServerError(error)) {\n    return 'non_successful_http_status';\n  }\n  if (isTimeoutError(error)) {\n    return 'timed_out';\n  }\n  if (isConnectionResetError(error)) {\n    return 'connection_reset';\n  }\n  return 'unknown';\n}\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(\n    ({ rpcMethodName, duration, traceId, ...rest }) => {\n      const error = getError(rest);\n      const type: DegradedEventType =\n        error === undefined ? 'slow_success' : 'retries_exhausted';\n      messenger.publish('NetworkController:rpcEndpointChainDegraded', {\n        chainId: configuration.chainId,\n        networkClientId: id,\n        error,\n        rpcMethodName,\n        duration,\n        traceId,\n        type,\n        retryReason:\n          error === undefined ? undefined : classifyRetryReason(error),\n      });\n    },\n  );\n\n  rpcServiceChain.onServiceDegraded(\n    ({\n      endpointUrl,\n      primaryEndpointUrl: primaryEndpointUrlFromEvent,\n      rpcMethodName,\n      duration,\n      traceId,\n      ...rest\n    }) => {\n      const error = getError(rest);\n      const type: DegradedEventType =\n        error === undefined ? 'slow_success' : 'retries_exhausted';\n\n      messenger.publish('NetworkController:rpcEndpointDegraded', {\n        chainId: configuration.chainId,\n        networkClientId: id,\n        primaryEndpointUrl: primaryEndpointUrlFromEvent,\n        endpointUrl,\n        error,\n        rpcMethodName,\n        duration,\n        traceId,\n        type,\n        retryReason:\n          error === undefined ? undefined : classifyRetryReason(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"]}