{"version":3,"file":"cache.mjs","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Json, JsonRpcRequest } from '@metamask/utils';\nimport { configure } from 'safe-stable-stringify';\n\nconst stringify = configure({ bigint: false, circularValue: Error });\n\n/**\n * The cache strategy to use for a given method.\n */\nexport enum CacheStrategy {\n  /**\n   * Cache per-block.\n   */\n  Block = 'block',\n  /**\n   * Cache until a chain reorganization occurs.\n   */\n  Fork = 'fork',\n  /**\n   * Never cache.\n   */\n  Never = 'never',\n  /**\n   * Permanently cache.\n   */\n  Permanent = 'perma',\n}\n\n/**\n * Return a cache identifier for the given request.\n *\n * This identifier should include any request details that might impact the\n * response, with the exception of the block parameter if the `skipBlockRef`\n * option is set,\n *\n * If the request cannot be cached, this will return `null`.\n *\n * @param request - The JSON-RPC request.\n * @param skipBlockRef - Skip the block parameter when generating the cache\n * identifier.\n * @returns The cache identifier for this request, or `null` if it can't be\n * cached.\n */\nexport function cacheIdentifierForRequest(\n  request: JsonRpcRequest,\n  skipBlockRef?: boolean,\n): string | null {\n  const simpleParams = skipBlockRef\n    ? paramsWithoutBlockTag(request)\n    : (request.params ?? []);\n  if (canCache(request.method)) {\n    return `${request.method}:${stringify(simpleParams)}`;\n  }\n  return null;\n}\n\n/**\n * Return whether a method can be cached or not.\n *\n * @param method - The method to check.\n * @returns Whether the method can be cached.\n */\nexport function canCache(method: string): boolean {\n  return cacheTypeForMethod(method) !== CacheStrategy.Never;\n}\n\n/**\n * Return the block parameter for the given request, if it has one.\n *\n * @param request - The JSON-RPC request.\n * @returns The block parameter in the given request, or `undefined` if none was found.\n */\nexport function blockTagForRequest(request: JsonRpcRequest): Json | undefined {\n  if (!request.params) {\n    return undefined;\n  }\n  const index: number | undefined = blockTagParamIndex(request.method);\n\n  // Block tag param not passed.\n  if (\n    index === undefined ||\n    !Array.isArray(request.params) ||\n    index >= request.params.length\n  ) {\n    return undefined;\n  }\n\n  return request.params[index];\n}\n\n/**\n * Return the request parameters without the block parameter.\n *\n * @param request - The JSON-RPC request.\n * @returns The request parameters with the block parameter removed, if one was found.\n */\nfunction paramsWithoutBlockTag(request: JsonRpcRequest): Json {\n  if (!request.params) {\n    return [];\n  }\n  const index: number | undefined = blockTagParamIndex(request.method);\n\n  // Block tag param not passed.\n  if (\n    index === undefined ||\n    !Array.isArray(request.params) ||\n    index >= request.params.length\n  ) {\n    return request.params;\n  }\n\n  // eth_getBlockByNumber has the block tag first, then the optional includeTx? param\n  if (request.method === 'eth_getBlockByNumber') {\n    return request.params.slice(1);\n  }\n  return request.params.slice(0, index);\n}\n\n/**\n * Returns the index of the block parameter for the given method.\n *\n * @param method - A JSON-RPC method.\n * @returns The index of the block parameter for that method, or `undefined` if\n * there is no known block parameter.\n */\nexport function blockTagParamIndex(method: string): number | undefined {\n  switch (method) {\n    // blockTag is at index 2\n    case 'eth_getStorageAt':\n      return 2;\n    // blockTag is at index 1\n    case 'eth_getBalance':\n    case 'eth_getCode':\n    case 'eth_getTransactionCount':\n    case 'eth_call':\n      return 1;\n    // blockTag is at index 0\n    case 'eth_getBlockByNumber':\n      return 0;\n    // there is no blockTag\n    default:\n      return undefined;\n  }\n}\n\n/**\n * Return the cache type used for the given method.\n *\n * @param method - A JSON-RPC method.\n * @returns The cache type to use for that method.\n */\nexport function cacheTypeForMethod(method: string): CacheStrategy {\n  switch (method) {\n    // cache permanently\n    case 'web3_clientVersion':\n    case 'web3_sha3':\n    case 'eth_protocolVersion':\n    case 'eth_getBlockTransactionCountByHash':\n    case 'eth_getUncleCountByBlockHash':\n    case 'eth_getCode':\n    case 'eth_getBlockByHash':\n    case 'eth_getTransactionByHash':\n    case 'eth_getTransactionByBlockHashAndIndex':\n    case 'eth_getTransactionReceipt':\n    case 'eth_getUncleByBlockHashAndIndex':\n    case 'eth_getCompilers':\n    case 'eth_compileLLL':\n    case 'eth_compileSolidity':\n    case 'eth_compileSerpent':\n    case 'shh_version':\n    case 'test_permaCache':\n      return CacheStrategy.Permanent;\n\n    // cache until fork\n    case 'eth_getBlockByNumber':\n    case 'eth_getBlockTransactionCountByNumber':\n    case 'eth_getUncleCountByBlockNumber':\n    case 'eth_getTransactionByBlockNumberAndIndex':\n    case 'eth_getUncleByBlockNumberAndIndex':\n    case 'test_forkCache':\n      return CacheStrategy.Fork;\n\n    // cache for block\n    case 'eth_gasPrice':\n    case 'eth_blockNumber':\n    case 'eth_getBalance':\n    case 'eth_getStorageAt':\n    case 'eth_getTransactionCount':\n    case 'eth_call':\n    case 'eth_estimateGas':\n    case 'eth_getFilterLogs':\n    case 'eth_getLogs':\n    case 'test_blockCache':\n      return CacheStrategy.Block;\n\n    // never cache\n    default:\n      return CacheStrategy.Never;\n  }\n}\n"]}