@metamask-previews/eth-json-rpc-middleware 21.0.0-preview-2e88eaea → 21.0.0-preview-c96ff8f

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 (104) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/block-cache.cjs +15 -27
  3. package/dist/block-cache.cjs.map +1 -1
  4. package/dist/block-cache.d.cts +5 -3
  5. package/dist/block-cache.d.cts.map +1 -1
  6. package/dist/block-cache.d.mts +5 -3
  7. package/dist/block-cache.d.mts.map +1 -1
  8. package/dist/block-cache.mjs +15 -27
  9. package/dist/block-cache.mjs.map +1 -1
  10. package/dist/block-ref-rewrite.cjs +12 -8
  11. package/dist/block-ref-rewrite.cjs.map +1 -1
  12. package/dist/block-ref-rewrite.d.cts +3 -3
  13. package/dist/block-ref-rewrite.d.cts.map +1 -1
  14. package/dist/block-ref-rewrite.d.mts +3 -3
  15. package/dist/block-ref-rewrite.d.mts.map +1 -1
  16. package/dist/block-ref-rewrite.mjs +12 -8
  17. package/dist/block-ref-rewrite.mjs.map +1 -1
  18. package/dist/block-ref.cjs +17 -10
  19. package/dist/block-ref.cjs.map +1 -1
  20. package/dist/block-ref.d.cts +12 -3
  21. package/dist/block-ref.d.cts.map +1 -1
  22. package/dist/block-ref.d.mts +12 -3
  23. package/dist/block-ref.d.mts.map +1 -1
  24. package/dist/block-ref.mjs +17 -10
  25. package/dist/block-ref.mjs.map +1 -1
  26. package/dist/block-tracker-inspector.cjs +28 -25
  27. package/dist/block-tracker-inspector.cjs.map +1 -1
  28. package/dist/block-tracker-inspector.d.cts +3 -3
  29. package/dist/block-tracker-inspector.d.cts.map +1 -1
  30. package/dist/block-tracker-inspector.d.mts +3 -3
  31. package/dist/block-tracker-inspector.d.mts.map +1 -1
  32. package/dist/block-tracker-inspector.mjs +28 -25
  33. package/dist/block-tracker-inspector.mjs.map +1 -1
  34. package/dist/fetch.cjs +8 -12
  35. package/dist/fetch.cjs.map +1 -1
  36. package/dist/fetch.d.cts +5 -3
  37. package/dist/fetch.d.cts.map +1 -1
  38. package/dist/fetch.d.mts +5 -3
  39. package/dist/fetch.d.mts.map +1 -1
  40. package/dist/fetch.mjs +8 -12
  41. package/dist/fetch.mjs.map +1 -1
  42. package/dist/inflight-cache.cjs +61 -45
  43. package/dist/inflight-cache.cjs.map +1 -1
  44. package/dist/inflight-cache.d.cts +12 -3
  45. package/dist/inflight-cache.d.cts.map +1 -1
  46. package/dist/inflight-cache.d.mts +12 -3
  47. package/dist/inflight-cache.d.mts.map +1 -1
  48. package/dist/inflight-cache.mjs +61 -45
  49. package/dist/inflight-cache.mjs.map +1 -1
  50. package/dist/methods/wallet-request-execution-permissions.cjs +11 -9
  51. package/dist/methods/wallet-request-execution-permissions.cjs.map +1 -1
  52. package/dist/methods/wallet-request-execution-permissions.d.cts +5 -3
  53. package/dist/methods/wallet-request-execution-permissions.d.cts.map +1 -1
  54. package/dist/methods/wallet-request-execution-permissions.d.mts +5 -3
  55. package/dist/methods/wallet-request-execution-permissions.d.mts.map +1 -1
  56. package/dist/methods/wallet-request-execution-permissions.mjs +9 -7
  57. package/dist/methods/wallet-request-execution-permissions.mjs.map +1 -1
  58. package/dist/methods/wallet-revoke-execution-permission.cjs +14 -11
  59. package/dist/methods/wallet-revoke-execution-permission.cjs.map +1 -1
  60. package/dist/methods/wallet-revoke-execution-permission.d.cts +10 -5
  61. package/dist/methods/wallet-revoke-execution-permission.d.cts.map +1 -1
  62. package/dist/methods/wallet-revoke-execution-permission.d.mts +10 -5
  63. package/dist/methods/wallet-revoke-execution-permission.d.mts.map +1 -1
  64. package/dist/methods/wallet-revoke-execution-permission.mjs +11 -8
  65. package/dist/methods/wallet-revoke-execution-permission.mjs.map +1 -1
  66. package/dist/providerAsMiddleware.cjs +5 -1
  67. package/dist/providerAsMiddleware.cjs.map +1 -1
  68. package/dist/providerAsMiddleware.d.cts +5 -3
  69. package/dist/providerAsMiddleware.d.cts.map +1 -1
  70. package/dist/providerAsMiddleware.d.mts +5 -3
  71. package/dist/providerAsMiddleware.d.mts.map +1 -1
  72. package/dist/providerAsMiddleware.mjs +3 -0
  73. package/dist/providerAsMiddleware.mjs.map +1 -1
  74. package/dist/retryOnEmpty.cjs +9 -16
  75. package/dist/retryOnEmpty.cjs.map +1 -1
  76. package/dist/retryOnEmpty.d.cts +3 -3
  77. package/dist/retryOnEmpty.d.cts.map +1 -1
  78. package/dist/retryOnEmpty.d.mts +3 -3
  79. package/dist/retryOnEmpty.d.mts.map +1 -1
  80. package/dist/retryOnEmpty.mjs +9 -16
  81. package/dist/retryOnEmpty.mjs.map +1 -1
  82. package/dist/types.cjs.map +1 -1
  83. package/dist/types.d.cts +0 -5
  84. package/dist/types.d.cts.map +1 -1
  85. package/dist/types.d.mts +0 -5
  86. package/dist/types.d.mts.map +1 -1
  87. package/dist/types.mjs.map +1 -1
  88. package/dist/utils/validation.cjs +2 -2
  89. package/dist/utils/validation.cjs.map +1 -1
  90. package/dist/utils/validation.d.cts +6 -3
  91. package/dist/utils/validation.d.cts.map +1 -1
  92. package/dist/utils/validation.d.mts +6 -3
  93. package/dist/utils/validation.d.mts.map +1 -1
  94. package/dist/utils/validation.mjs +2 -2
  95. package/dist/utils/validation.mjs.map +1 -1
  96. package/dist/wallet.cjs +87 -92
  97. package/dist/wallet.cjs.map +1 -1
  98. package/dist/wallet.d.cts +8 -5
  99. package/dist/wallet.d.cts.map +1 -1
  100. package/dist/wallet.d.mts +8 -5
  101. package/dist/wallet.d.mts.map +1 -1
  102. package/dist/wallet.mjs +88 -93
  103. package/dist/wallet.mjs.map +1 -1
  104. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -9,8 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
+ - **BREAKING:** Migrate to `JsonRpcEngineV2` ([#7065](https://github.com/MetaMask/core/pull/7065))
13
+ - Migrates all middleware from `JsonRpcEngine` to `JsonRpcEngineV2`.
14
+ - To continue using this package with the legacy `JsonRpcEngine`, use the `asLegacyMiddleware` backwards compatibility function.
12
15
  - **BREAKING:** Use `InternalProvider` instead of `SafeEventEmitterProvider` ([#6796](https://github.com/MetaMask/core/pull/6796))
13
16
  - Wherever a `SafeEventEmitterProvider` was expected, an `InternalProvider` is now expected instead.
17
+ - **BREAKING:** Stop retrying `undefined` results for methods that include a block tag parameter ([#7001](https://github.com/MetaMask/core/pull/7001))
18
+ - The `retryOnEmpty` middleware will now throw an error if it encounters an `undefined` result when dispatching
19
+ a request with a later block number than the originally requested block number.
20
+ - In practice, this should happen rarely if ever.
14
21
  - Migrate all uses of `interface` to `type` ([#6885](https://github.com/MetaMask/core/pull/6885))
15
22
 
16
23
  ## [21.0.0]
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBlockCacheMiddleware = void 0;
4
- const json_rpc_engine_1 = require("@metamask/json-rpc-engine");
5
4
  const logging_utils_1 = require("./logging-utils.cjs");
6
5
  const cache_1 = require("./utils/cache.cjs");
7
6
  const log = (0, logging_utils_1.createModuleLogger)(logging_utils_1.projectLogger, 'block-cache');
@@ -87,11 +86,9 @@ class BlockCacheStrategy {
87
86
  }
88
87
  }
89
88
  function createBlockCacheMiddleware({ blockTracker, } = {}) {
90
- // validate options
91
89
  if (!blockTracker) {
92
90
  throw new Error('createBlockCacheMiddleware - No PollingBlockTracker specified');
93
91
  }
94
- // create caching strategies
95
92
  const blockCache = new BlockCacheStrategy();
96
93
  const strategies = {
97
94
  [cache_1.CacheStrategy.Permanent]: blockCache,
@@ -99,28 +96,23 @@ function createBlockCacheMiddleware({ blockTracker, } = {}) {
99
96
  [cache_1.CacheStrategy.Fork]: blockCache,
100
97
  [cache_1.CacheStrategy.Never]: undefined,
101
98
  };
102
- return (0, json_rpc_engine_1.createAsyncMiddleware)(async (req, res, next) => {
103
- // allow cach to be skipped if so specified
104
- if (req.skipCache) {
99
+ return async ({ request, next, context }) => {
100
+ if (context.get('skipCache')) {
105
101
  return next();
106
102
  }
107
- // check type and matching strategy
108
- const type = (0, cache_1.cacheTypeForMethod)(req.method);
103
+ const type = (0, cache_1.cacheTypeForMethod)(request.method);
109
104
  const strategy = strategies[type];
110
- // If there's no strategy in place, pass it down the chain.
111
105
  if (!strategy) {
112
106
  return next();
113
107
  }
114
- // If the strategy can't cache this request, ignore it.
115
- if (!strategy.canCacheRequest(req)) {
108
+ if (!strategy.canCacheRequest(request)) {
116
109
  return next();
117
110
  }
118
- // get block reference (number or keyword)
119
- const requestBlockTag = (0, cache_1.blockTagForRequest)(req);
111
+ const requestBlockTag = (0, cache_1.blockTagForRequest)(request);
120
112
  const blockTag = requestBlockTag && typeof requestBlockTag === 'string'
121
113
  ? requestBlockTag
122
114
  : 'latest';
123
- log('blockTag = %o, req = %o', blockTag, req);
115
+ log('blockTag = %o, req = %o', blockTag, request);
124
116
  // get exact block number
125
117
  let requestedBlockNumber;
126
118
  if (blockTag === 'earliest') {
@@ -128,7 +120,6 @@ function createBlockCacheMiddleware({ blockTracker, } = {}) {
128
120
  requestedBlockNumber = '0x00';
129
121
  }
130
122
  else if (blockTag === 'latest') {
131
- // fetch latest block number
132
123
  log('Fetching latest block number to determine cache key');
133
124
  const latestBlockNumber = await blockTracker.getLatestBlock();
134
125
  // clear all cache before latest block
@@ -137,29 +128,26 @@ function createBlockCacheMiddleware({ blockTracker, } = {}) {
137
128
  requestedBlockNumber = latestBlockNumber;
138
129
  }
139
130
  else {
140
- // We have a hex number
131
+ // we have a hex number
141
132
  requestedBlockNumber = blockTag;
142
133
  }
143
134
  // end on a hit, continue on a miss
144
- const cacheResult = await strategy.get(req, requestedBlockNumber);
135
+ const cacheResult = await strategy.get(request, requestedBlockNumber);
145
136
  if (cacheResult === undefined) {
146
137
  // cache miss
147
138
  // wait for other middleware to handle request
148
139
  log('No cache stored under block number %o, carrying request forward', requestedBlockNumber);
149
- await next();
140
+ const result = await next();
150
141
  // add result to cache
151
142
  // it's safe to cast res.result as Block, due to runtime type checks
152
143
  // performed when strategy.set is called
153
- log('Populating cache with', res);
154
- await strategy.set(req, requestedBlockNumber, res.result);
144
+ log('Populating cache with', result);
145
+ await strategy.set(request, requestedBlockNumber, result);
146
+ return result;
155
147
  }
156
- else {
157
- // fill in result from cache
158
- log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
159
- res.result = cacheResult;
160
- }
161
- return undefined;
162
- });
148
+ log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
149
+ return cacheResult;
150
+ };
163
151
  }
164
152
  exports.createBlockCacheMiddleware = createBlockCacheMiddleware;
165
153
  //# sourceMappingURL=block-cache.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-cache.cjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n JsonRpcCacheMiddleware,\n JsonRpcRequestToCache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n private cache: Cache;\n\n constructor() {\n this.cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result as any)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.cache[num]);\n }\n}\n\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcCacheMiddleware<\n JsonRpcParams,\n Json\n> {\n // validate options\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n // create caching strategies\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return createAsyncMiddleware(\n async (req: JsonRpcRequestToCache<JsonRpcParams>, res, next) => {\n // allow cach to be skipped if so specified\n if (req.skipCache) {\n return next();\n }\n // check type and matching strategy\n const type = cacheTypeForMethod(req.method);\n const strategy = strategies[type];\n // If there's no strategy in place, pass it down the chain.\n if (!strategy) {\n return next();\n }\n\n // If the strategy can't cache this request, ignore it.\n if (!strategy.canCacheRequest(req)) {\n return next();\n }\n\n // get block reference (number or keyword)\n const requestBlockTag = blockTagForRequest(req);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, req);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n // fetch latest block number\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // We have a hex number\n requestedBlockNumber = blockTag;\n }\n // end on a hit, continue on a miss\n const cacheResult: Block | undefined = await strategy.get(\n req,\n requestedBlockNumber,\n );\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', res);\n await strategy.set(req, requestedBlockNumber, res.result as Block);\n } else {\n // fill in result from cache\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n res.result = cacheResult;\n }\n return undefined;\n },\n );\n}\n"]}
1
+ {"version":3,"file":"block-cache.cjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues: unknown[] = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n private cache: Cache;\n\n constructor() {\n this.cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.cache[num]);\n }\n}\n\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ skipCache?: boolean }>\n> {\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return async ({ request, next, context }) => {\n if (context.get('skipCache')) {\n return next();\n }\n\n const type = cacheTypeForMethod(request.method);\n const strategy = strategies[type];\n if (!strategy) {\n return next();\n }\n\n if (!strategy.canCacheRequest(request)) {\n return next();\n }\n\n const requestBlockTag = blockTagForRequest(request);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, request);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // we have a hex number\n requestedBlockNumber = blockTag;\n }\n\n // end on a hit, continue on a miss\n const cacheResult = await strategy.get(request, requestedBlockNumber);\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n const result = await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', result);\n await strategy.set(request, requestedBlockNumber, result as Block);\n return result;\n }\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n return cacheResult;\n };\n}\n"]}
@@ -1,9 +1,11 @@
1
1
  import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
- import type { Json, JsonRpcParams } from "@metamask/utils";
3
- import type { JsonRpcCacheMiddleware } from "./types.cjs";
2
+ import type { JsonRpcMiddleware, MiddlewareContext } from "@metamask/json-rpc-engine/v2";
3
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
4
4
  type BlockCacheMiddlewareOptions = {
5
5
  blockTracker?: PollingBlockTracker;
6
6
  };
7
- export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcCacheMiddleware<JsonRpcParams, Json>;
7
+ export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json, MiddlewareContext<{
8
+ skipCache?: boolean;
9
+ }>>;
8
10
  export {};
9
11
  //# sourceMappingURL=block-cache.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-cache.d.cts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AAEvE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAkB,wBAAwB;AAG3E,OAAO,KAAK,EAKV,sBAAsB,EAEvB,oBAAgB;AAajB,KAAK,2BAA2B,GAAG;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AA2GF,wBAAgB,0BAA0B,CAAC,EACzC,YAAY,GACb,GAAE,2BAAgC,GAAG,sBAAsB,CAC1D,aAAa,EACb,IAAI,CACL,CA+FA"}
1
+ {"version":3,"file":"block-cache.d.cts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,qCAAqC;AACtC,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,wBAAwB;AAqB5D,KAAK,2BAA2B,GAAG;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AA2GF,wBAAgB,0BAA0B,CAAC,EACzC,YAAY,GACb,GAAE,2BAAgC,GAAG,iBAAiB,CACrD,cAAc,EACd,IAAI,EACJ,iBAAiB,CAAC;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAC3C,CAmFA"}
@@ -1,9 +1,11 @@
1
1
  import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
- import type { Json, JsonRpcParams } from "@metamask/utils";
3
- import type { JsonRpcCacheMiddleware } from "./types.mjs";
2
+ import type { JsonRpcMiddleware, MiddlewareContext } from "@metamask/json-rpc-engine/v2";
3
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
4
4
  type BlockCacheMiddlewareOptions = {
5
5
  blockTracker?: PollingBlockTracker;
6
6
  };
7
- export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcCacheMiddleware<JsonRpcParams, Json>;
7
+ export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json, MiddlewareContext<{
8
+ skipCache?: boolean;
9
+ }>>;
8
10
  export {};
9
11
  //# sourceMappingURL=block-cache.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-cache.d.mts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AAEvE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAkB,wBAAwB;AAG3E,OAAO,KAAK,EAKV,sBAAsB,EAEvB,oBAAgB;AAajB,KAAK,2BAA2B,GAAG;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AA2GF,wBAAgB,0BAA0B,CAAC,EACzC,YAAY,GACb,GAAE,2BAAgC,GAAG,sBAAsB,CAC1D,aAAa,EACb,IAAI,CACL,CA+FA"}
1
+ {"version":3,"file":"block-cache.d.mts","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,qCAAqC;AACtC,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,wBAAwB;AAqB5D,KAAK,2BAA2B,GAAG;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AA2GF,wBAAgB,0BAA0B,CAAC,EACzC,YAAY,GACb,GAAE,2BAAgC,GAAG,iBAAiB,CACrD,cAAc,EACd,IAAI,EACJ,iBAAiB,CAAC;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAC3C,CAmFA"}
@@ -1,4 +1,3 @@
1
- import { createAsyncMiddleware } from "@metamask/json-rpc-engine";
2
1
  import { projectLogger, createModuleLogger } from "./logging-utils.mjs";
3
2
  import { cacheIdentifierForRequest, blockTagForRequest, cacheTypeForMethod, canCache, CacheStrategy } from "./utils/cache.mjs";
4
3
  const log = createModuleLogger(projectLogger, 'block-cache');
@@ -84,11 +83,9 @@ class BlockCacheStrategy {
84
83
  }
85
84
  }
86
85
  export function createBlockCacheMiddleware({ blockTracker, } = {}) {
87
- // validate options
88
86
  if (!blockTracker) {
89
87
  throw new Error('createBlockCacheMiddleware - No PollingBlockTracker specified');
90
88
  }
91
- // create caching strategies
92
89
  const blockCache = new BlockCacheStrategy();
93
90
  const strategies = {
94
91
  [CacheStrategy.Permanent]: blockCache,
@@ -96,28 +93,23 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
96
93
  [CacheStrategy.Fork]: blockCache,
97
94
  [CacheStrategy.Never]: undefined,
98
95
  };
99
- return createAsyncMiddleware(async (req, res, next) => {
100
- // allow cach to be skipped if so specified
101
- if (req.skipCache) {
96
+ return async ({ request, next, context }) => {
97
+ if (context.get('skipCache')) {
102
98
  return next();
103
99
  }
104
- // check type and matching strategy
105
- const type = cacheTypeForMethod(req.method);
100
+ const type = cacheTypeForMethod(request.method);
106
101
  const strategy = strategies[type];
107
- // If there's no strategy in place, pass it down the chain.
108
102
  if (!strategy) {
109
103
  return next();
110
104
  }
111
- // If the strategy can't cache this request, ignore it.
112
- if (!strategy.canCacheRequest(req)) {
105
+ if (!strategy.canCacheRequest(request)) {
113
106
  return next();
114
107
  }
115
- // get block reference (number or keyword)
116
- const requestBlockTag = blockTagForRequest(req);
108
+ const requestBlockTag = blockTagForRequest(request);
117
109
  const blockTag = requestBlockTag && typeof requestBlockTag === 'string'
118
110
  ? requestBlockTag
119
111
  : 'latest';
120
- log('blockTag = %o, req = %o', blockTag, req);
112
+ log('blockTag = %o, req = %o', blockTag, request);
121
113
  // get exact block number
122
114
  let requestedBlockNumber;
123
115
  if (blockTag === 'earliest') {
@@ -125,7 +117,6 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
125
117
  requestedBlockNumber = '0x00';
126
118
  }
127
119
  else if (blockTag === 'latest') {
128
- // fetch latest block number
129
120
  log('Fetching latest block number to determine cache key');
130
121
  const latestBlockNumber = await blockTracker.getLatestBlock();
131
122
  // clear all cache before latest block
@@ -134,28 +125,25 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
134
125
  requestedBlockNumber = latestBlockNumber;
135
126
  }
136
127
  else {
137
- // We have a hex number
128
+ // we have a hex number
138
129
  requestedBlockNumber = blockTag;
139
130
  }
140
131
  // end on a hit, continue on a miss
141
- const cacheResult = await strategy.get(req, requestedBlockNumber);
132
+ const cacheResult = await strategy.get(request, requestedBlockNumber);
142
133
  if (cacheResult === undefined) {
143
134
  // cache miss
144
135
  // wait for other middleware to handle request
145
136
  log('No cache stored under block number %o, carrying request forward', requestedBlockNumber);
146
- await next();
137
+ const result = await next();
147
138
  // add result to cache
148
139
  // it's safe to cast res.result as Block, due to runtime type checks
149
140
  // performed when strategy.set is called
150
- log('Populating cache with', res);
151
- await strategy.set(req, requestedBlockNumber, res.result);
141
+ log('Populating cache with', result);
142
+ await strategy.set(request, requestedBlockNumber, result);
143
+ return result;
152
144
  }
153
- else {
154
- // fill in result from cache
155
- log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
156
- res.result = cacheResult;
157
- }
158
- return undefined;
159
- });
145
+ log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
146
+ return cacheResult;
147
+ };
160
148
  }
161
149
  //# sourceMappingURL=block-cache.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-cache.mjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n JsonRpcCacheMiddleware,\n JsonRpcRequestToCache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n private cache: Cache;\n\n constructor() {\n this.cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result as any)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.cache[num]);\n }\n}\n\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcCacheMiddleware<\n JsonRpcParams,\n Json\n> {\n // validate options\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n // create caching strategies\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return createAsyncMiddleware(\n async (req: JsonRpcRequestToCache<JsonRpcParams>, res, next) => {\n // allow cach to be skipped if so specified\n if (req.skipCache) {\n return next();\n }\n // check type and matching strategy\n const type = cacheTypeForMethod(req.method);\n const strategy = strategies[type];\n // If there's no strategy in place, pass it down the chain.\n if (!strategy) {\n return next();\n }\n\n // If the strategy can't cache this request, ignore it.\n if (!strategy.canCacheRequest(req)) {\n return next();\n }\n\n // get block reference (number or keyword)\n const requestBlockTag = blockTagForRequest(req);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, req);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n // fetch latest block number\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // We have a hex number\n requestedBlockNumber = blockTag;\n }\n // end on a hit, continue on a miss\n const cacheResult: Block | undefined = await strategy.get(\n req,\n requestedBlockNumber,\n );\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', res);\n await strategy.set(req, requestedBlockNumber, res.result as Block);\n } else {\n // fill in result from cache\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n res.result = cacheResult;\n }\n return undefined;\n },\n );\n}\n"]}
1
+ {"version":3,"file":"block-cache.mjs","sourceRoot":"","sources":["../src/block-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type {\n JsonRpcMiddleware,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n} from './types';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache';\n\nconst log = createModuleLogger(projectLogger, 'block-cache');\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues: unknown[] = [undefined, null, '\\u003cnil\\u003e'];\n\ntype BlockCacheMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n//\n// Cache Strategies\n//\n\nclass BlockCacheStrategy {\n private cache: Cache;\n\n constructor() {\n this.cache = {};\n }\n\n getBlockCache(blockNumberHex: string): BlockCache {\n const blockNumber: number = Number.parseInt(blockNumberHex, 16);\n let blockCache: BlockCache = this.cache[blockNumber];\n // create new cache if necesary\n if (!blockCache) {\n const newCache: BlockCache = {};\n this.cache[blockNumber] = newCache;\n blockCache = newCache;\n }\n return blockCache;\n }\n\n async get(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n ): Promise<Block | undefined> {\n // lookup block cache\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n // lookup payload in block cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n return identifier ? blockCache[identifier] : undefined;\n }\n\n async set(\n request: JsonRpcRequest,\n requestedBlockNumber: string,\n result: Block,\n ): Promise<void> {\n // check if we can cached this result\n const canCacheResult: boolean = this.canCacheResult(request, result);\n if (!canCacheResult) {\n return;\n }\n\n // set the value in the cache\n const identifier: string | null = cacheIdentifierForRequest(request, true);\n if (!identifier) {\n return;\n }\n const blockCache: BlockCache = this.getBlockCache(requestedBlockNumber);\n blockCache[identifier] = result;\n }\n\n canCacheRequest(request: JsonRpcRequest): boolean {\n // check request method\n if (!canCache(request.method)) {\n return false;\n }\n // check blockTag\n const blockTag = blockTagForRequest(request);\n\n if (blockTag === 'pending') {\n return false;\n }\n // can be cached\n return true;\n }\n\n canCacheResult(request: JsonRpcRequest, result: Block): boolean {\n // never cache empty values (e.g. undefined)\n if (emptyValues.includes(result)) {\n return false;\n }\n\n // check if transactions have block reference before caching\n if (\n request.method &&\n ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(\n request.method,\n )\n ) {\n if (\n !result?.blockHash ||\n result.blockHash ===\n '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n return false;\n }\n }\n // otherwise true\n return true;\n }\n\n // removes all block caches with block number lower than `oldBlockHex`\n clearBefore(oldBlockHex: string): void {\n const oldBlockNumber: number = Number.parseInt(oldBlockHex, 16);\n // clear old caches\n Object.keys(this.cache)\n .map(Number)\n .filter((num) => num < oldBlockNumber)\n .forEach((num) => delete this.cache[num]);\n }\n}\n\nexport function createBlockCacheMiddleware({\n blockTracker,\n}: BlockCacheMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json,\n MiddlewareContext<{ skipCache?: boolean }>\n> {\n if (!blockTracker) {\n throw new Error(\n 'createBlockCacheMiddleware - No PollingBlockTracker specified',\n );\n }\n\n const blockCache: BlockCacheStrategy = new BlockCacheStrategy();\n const strategies: Record<CacheStrategy, BlockCacheStrategy | undefined> = {\n [CacheStrategy.Permanent]: blockCache,\n [CacheStrategy.Block]: blockCache,\n [CacheStrategy.Fork]: blockCache,\n [CacheStrategy.Never]: undefined,\n };\n\n return async ({ request, next, context }) => {\n if (context.get('skipCache')) {\n return next();\n }\n\n const type = cacheTypeForMethod(request.method);\n const strategy = strategies[type];\n if (!strategy) {\n return next();\n }\n\n if (!strategy.canCacheRequest(request)) {\n return next();\n }\n\n const requestBlockTag = blockTagForRequest(request);\n const blockTag =\n requestBlockTag && typeof requestBlockTag === 'string'\n ? requestBlockTag\n : 'latest';\n\n log('blockTag = %o, req = %o', blockTag, request);\n\n // get exact block number\n let requestedBlockNumber: string;\n if (blockTag === 'earliest') {\n // this just exists for symmetry with \"latest\"\n requestedBlockNumber = '0x00';\n } else if (blockTag === 'latest') {\n log('Fetching latest block number to determine cache key');\n const latestBlockNumber = await blockTracker.getLatestBlock();\n\n // clear all cache before latest block\n log(\n 'Clearing values stored under block numbers before %o',\n latestBlockNumber,\n );\n blockCache.clearBefore(latestBlockNumber);\n requestedBlockNumber = latestBlockNumber;\n } else {\n // we have a hex number\n requestedBlockNumber = blockTag;\n }\n\n // end on a hit, continue on a miss\n const cacheResult = await strategy.get(request, requestedBlockNumber);\n if (cacheResult === undefined) {\n // cache miss\n // wait for other middleware to handle request\n log(\n 'No cache stored under block number %o, carrying request forward',\n requestedBlockNumber,\n );\n const result = await next();\n\n // add result to cache\n // it's safe to cast res.result as Block, due to runtime type checks\n // performed when strategy.set is called\n log('Populating cache with', result);\n await strategy.set(request, requestedBlockNumber, result as Block);\n return result;\n }\n log(\n 'Cache hit, reusing cache result stored under block number %o',\n requestedBlockNumber,\n );\n return cacheResult;\n };\n}\n"]}
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBlockRefRewriteMiddleware = void 0;
4
- const json_rpc_engine_1 = require("@metamask/json-rpc-engine");
5
4
  const cache_1 = require("./utils/cache.cjs");
6
5
  /**
7
6
  * Creates a middleware that rewrites "latest" block references to the known
@@ -15,13 +14,13 @@ function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
15
14
  if (!blockTracker) {
16
15
  throw Error('BlockRefRewriteMiddleware - mandatory "blockTracker" option is missing.');
17
16
  }
18
- return (0, json_rpc_engine_1.createAsyncMiddleware)(async (req, _res, next) => {
19
- const blockRefIndex = (0, cache_1.blockTagParamIndex)(req.method);
17
+ return async ({ request, next }) => {
18
+ const blockRefIndex = (0, cache_1.blockTagParamIndex)(request.method);
20
19
  if (blockRefIndex === undefined) {
21
20
  return next();
22
21
  }
23
- const blockRef = Array.isArray(req.params) && req.params[blockRefIndex]
24
- ? req.params[blockRefIndex]
22
+ const blockRef = Array.isArray(request.params) && request.params[blockRefIndex]
23
+ ? request.params[blockRefIndex]
25
24
  : // omitted blockRef implies "latest"
26
25
  'latest';
27
26
  if (blockRef !== 'latest') {
@@ -29,11 +28,16 @@ function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
29
28
  }
30
29
  // rewrite blockRef to block-tracker's block number
31
30
  const latestBlockNumber = await blockTracker.getLatestBlock();
32
- if (Array.isArray(req.params)) {
33
- req.params[blockRefIndex] = latestBlockNumber;
31
+ if (Array.isArray(request.params)) {
32
+ const params = request.params.slice();
33
+ params[blockRefIndex] = latestBlockNumber;
34
+ return next({
35
+ ...request,
36
+ params,
37
+ });
34
38
  }
35
39
  return next();
36
- });
40
+ };
37
41
  }
38
42
  exports.createBlockRefRewriteMiddleware = createBlockRefRewriteMiddleware;
39
43
  //# sourceMappingURL=block-ref-rewrite.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-ref-rewrite.cjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":";;;AAEA,+DAAkE;AAGlE,6CAAmD;AAMnD;;;;;;;GAOG;AACH,SAAgB,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE;QACjB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;KACH;IAED,OAAO,IAAA,uCAAqB,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,aAAa,GAAuB,IAAA,0BAAkB,EAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzE,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,QAAQ,GACZ,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;YACpD,CAAC,CAAE,GAAG,CAAC,MAAM,CAAC,aAAa,CAAY;YACvC,CAAC,CAAC,oCAAoC;gBACpC,QAAQ,CAAC;QAEf,IAAI,QAAQ,KAAK,QAAQ,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC7B,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;SAC/C;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAnCD,0EAmCC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams } from '@metamask/utils';\n\nimport { blockTagParamIndex } from './utils/cache';\n\ntype BlockRefRewriteMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n/**\n * Creates a middleware that rewrites \"latest\" block references to the known\n * latest block number from a block tracker.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefRewriteMiddleware({\n blockTracker,\n}: BlockRefRewriteMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcParams,\n Json\n> {\n if (!blockTracker) {\n throw Error(\n 'BlockRefRewriteMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return createAsyncMiddleware(async (req, _res, next) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(req.method);\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef: string | undefined =\n Array.isArray(req.params) && req.params[blockRefIndex]\n ? (req.params[blockRefIndex] as string)\n : // omitted blockRef implies \"latest\"\n 'latest';\n\n if (blockRef !== 'latest') {\n return next();\n }\n\n // rewrite blockRef to block-tracker's block number\n const latestBlockNumber = await blockTracker.getLatestBlock();\n if (Array.isArray(req.params)) {\n req.params[blockRefIndex] = latestBlockNumber;\n }\n return next();\n });\n}\n"]}
1
+ {"version":3,"file":"block-ref-rewrite.cjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":";;;AAIA,6CAAmD;AAMnD;;;;;;;GAOG;AACH,SAAgB,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE;QACjB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;KACH;IAED,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,MAAM,aAAa,GAAuB,IAAA,0BAAkB,EAC1D,OAAO,CAAC,MAAM,CACf,CAAC;QACF,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,QAAQ,GACZ,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;YAC5D,CAAC,CAAE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAY;YAC3C,CAAC,CAAC,oCAAoC;gBACpC,QAAQ,CAAC;QAEf,IAAI,QAAQ,KAAK,QAAQ,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACjC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;YAC1C,OAAO,IAAI,CAAC;gBACV,GAAG,OAAO;gBACV,MAAM;aACP,CAAC,CAAC;SACJ;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AA1CD,0EA0CC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { blockTagParamIndex } from './utils/cache';\n\ntype BlockRefRewriteMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n/**\n * Creates a middleware that rewrites \"latest\" block references to the known\n * latest block number from a block tracker.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefRewriteMiddleware({\n blockTracker,\n}: BlockRefRewriteMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json\n> {\n if (!blockTracker) {\n throw Error(\n 'BlockRefRewriteMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return async ({ request, next }) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(\n request.method,\n );\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef: string | undefined =\n Array.isArray(request.params) && request.params[blockRefIndex]\n ? (request.params[blockRefIndex] as string)\n : // omitted blockRef implies \"latest\"\n 'latest';\n\n if (blockRef !== 'latest') {\n return next();\n }\n\n // rewrite blockRef to block-tracker's block number\n const latestBlockNumber = await blockTracker.getLatestBlock();\n if (Array.isArray(request.params)) {\n const params = request.params.slice();\n params[blockRefIndex] = latestBlockNumber;\n return next({\n ...request,\n params,\n });\n }\n return next();\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
- import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine";
3
- import type { Json, JsonRpcParams } from "@metamask/utils";
2
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine/v2";
3
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
4
4
  type BlockRefRewriteMiddlewareOptions = {
5
5
  blockTracker?: PollingBlockTracker;
6
6
  };
@@ -12,6 +12,6 @@ type BlockRefRewriteMiddlewareOptions = {
12
12
  * @param options.blockTracker - The block tracker to use.
13
13
  * @returns The middleware.
14
14
  */
15
- export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcParams, Json>;
15
+ export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json>;
16
16
  export {};
17
17
  //# sourceMappingURL=block-ref-rewrite.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-ref-rewrite.d.cts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,kCAAkC;AAEnE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,wBAAwB;AAI3D,KAAK,gCAAgC,GAAG;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,YAAY,GACb,GAAE,gCAAqC,GAAG,iBAAiB,CAC1D,aAAa,EACb,IAAI,CACL,CA8BA"}
1
+ {"version":3,"file":"block-ref-rewrite.d.cts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,qCAAqC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,wBAAwB;AAI5D,KAAK,gCAAgC,GAAG;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,YAAY,GACb,GAAE,gCAAqC,GAAG,iBAAiB,CAC1D,cAAc,EACd,IAAI,CACL,CAqCA"}
@@ -1,6 +1,6 @@
1
1
  import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
- import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine";
3
- import type { Json, JsonRpcParams } from "@metamask/utils";
2
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine/v2";
3
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
4
4
  type BlockRefRewriteMiddlewareOptions = {
5
5
  blockTracker?: PollingBlockTracker;
6
6
  };
@@ -12,6 +12,6 @@ type BlockRefRewriteMiddlewareOptions = {
12
12
  * @param options.blockTracker - The block tracker to use.
13
13
  * @returns The middleware.
14
14
  */
15
- export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcParams, Json>;
15
+ export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json>;
16
16
  export {};
17
17
  //# sourceMappingURL=block-ref-rewrite.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-ref-rewrite.d.mts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,kCAAkC;AAEnE,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,wBAAwB;AAI3D,KAAK,gCAAgC,GAAG;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,YAAY,GACb,GAAE,gCAAqC,GAAG,iBAAiB,CAC1D,aAAa,EACb,IAAI,CACL,CA8BA"}
1
+ {"version":3,"file":"block-ref-rewrite.d.mts","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,qCAAqC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,wBAAwB;AAI5D,KAAK,gCAAgC,GAAG;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,YAAY,GACb,GAAE,gCAAqC,GAAG,iBAAiB,CAC1D,cAAc,EACd,IAAI,CACL,CAqCA"}
@@ -1,4 +1,3 @@
1
- import { createAsyncMiddleware } from "@metamask/json-rpc-engine";
2
1
  import { blockTagParamIndex } from "./utils/cache.mjs";
3
2
  /**
4
3
  * Creates a middleware that rewrites "latest" block references to the known
@@ -12,13 +11,13 @@ export function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
12
11
  if (!blockTracker) {
13
12
  throw Error('BlockRefRewriteMiddleware - mandatory "blockTracker" option is missing.');
14
13
  }
15
- return createAsyncMiddleware(async (req, _res, next) => {
16
- const blockRefIndex = blockTagParamIndex(req.method);
14
+ return async ({ request, next }) => {
15
+ const blockRefIndex = blockTagParamIndex(request.method);
17
16
  if (blockRefIndex === undefined) {
18
17
  return next();
19
18
  }
20
- const blockRef = Array.isArray(req.params) && req.params[blockRefIndex]
21
- ? req.params[blockRefIndex]
19
+ const blockRef = Array.isArray(request.params) && request.params[blockRefIndex]
20
+ ? request.params[blockRefIndex]
22
21
  : // omitted blockRef implies "latest"
23
22
  'latest';
24
23
  if (blockRef !== 'latest') {
@@ -26,10 +25,15 @@ export function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
26
25
  }
27
26
  // rewrite blockRef to block-tracker's block number
28
27
  const latestBlockNumber = await blockTracker.getLatestBlock();
29
- if (Array.isArray(req.params)) {
30
- req.params[blockRefIndex] = latestBlockNumber;
28
+ if (Array.isArray(request.params)) {
29
+ const params = request.params.slice();
30
+ params[blockRefIndex] = latestBlockNumber;
31
+ return next({
32
+ ...request,
33
+ params,
34
+ });
31
35
  }
32
36
  return next();
33
- });
37
+ };
34
38
  }
35
39
  //# sourceMappingURL=block-ref-rewrite.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-ref-rewrite.mjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,kCAAkC;AAGlE,OAAO,EAAE,kBAAkB,EAAE,0BAAsB;AAMnD;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE;QACjB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;KACH;IAED,OAAO,qBAAqB,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,aAAa,GAAuB,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzE,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,QAAQ,GACZ,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;YACpD,CAAC,CAAE,GAAG,CAAC,MAAM,CAAC,aAAa,CAAY;YACvC,CAAC,CAAC,oCAAoC;gBACpC,QAAQ,CAAC;QAEf,IAAI,QAAQ,KAAK,QAAQ,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC7B,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;SAC/C;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams } from '@metamask/utils';\n\nimport { blockTagParamIndex } from './utils/cache';\n\ntype BlockRefRewriteMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n/**\n * Creates a middleware that rewrites \"latest\" block references to the known\n * latest block number from a block tracker.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefRewriteMiddleware({\n blockTracker,\n}: BlockRefRewriteMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcParams,\n Json\n> {\n if (!blockTracker) {\n throw Error(\n 'BlockRefRewriteMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return createAsyncMiddleware(async (req, _res, next) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(req.method);\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef: string | undefined =\n Array.isArray(req.params) && req.params[blockRefIndex]\n ? (req.params[blockRefIndex] as string)\n : // omitted blockRef implies \"latest\"\n 'latest';\n\n if (blockRef !== 'latest') {\n return next();\n }\n\n // rewrite blockRef to block-tracker's block number\n const latestBlockNumber = await blockTracker.getLatestBlock();\n if (Array.isArray(req.params)) {\n req.params[blockRefIndex] = latestBlockNumber;\n }\n return next();\n });\n}\n"]}
1
+ {"version":3,"file":"block-ref-rewrite.mjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,0BAAsB;AAMnD;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE;QACjB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;KACH;IAED,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,MAAM,aAAa,GAAuB,kBAAkB,CAC1D,OAAO,CAAC,MAAM,CACf,CAAC;QACF,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,QAAQ,GACZ,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;YAC5D,CAAC,CAAE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAY;YAC3C,CAAC,CAAC,oCAAoC;gBACpC,QAAQ,CAAC;QAEf,IAAI,QAAQ,KAAK,QAAQ,EAAE;YACzB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACjC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;YAC1C,OAAO,IAAI,CAAC;gBACV,GAAG,OAAO;gBACV,MAAM;aACP,CAAC,CAAC;SACJ;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { blockTagParamIndex } from './utils/cache';\n\ntype BlockRefRewriteMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n};\n\n/**\n * Creates a middleware that rewrites \"latest\" block references to the known\n * latest block number from a block tracker.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefRewriteMiddleware({\n blockTracker,\n}: BlockRefRewriteMiddlewareOptions = {}): JsonRpcMiddleware<\n JsonRpcRequest,\n Json\n> {\n if (!blockTracker) {\n throw Error(\n 'BlockRefRewriteMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return async ({ request, next }) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(\n request.method,\n );\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef: string | undefined =\n Array.isArray(request.params) && request.params[blockRefIndex]\n ? (request.params[blockRefIndex] as string)\n : // omitted blockRef implies \"latest\"\n 'latest';\n\n if (blockRef !== 'latest') {\n return next();\n }\n\n // rewrite blockRef to block-tracker's block number\n const latestBlockNumber = await blockTracker.getLatestBlock();\n if (Array.isArray(request.params)) {\n const params = request.params.slice();\n params[blockRefIndex] = latestBlockNumber;\n return next({\n ...request,\n params,\n });\n }\n return next();\n };\n}\n"]}
@@ -1,11 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBlockRefMiddleware = void 0;
4
- const json_rpc_engine_1 = require("@metamask/json-rpc-engine");
5
- const full_1 = require("klona/full");
4
+ const klona_1 = require("klona");
6
5
  const logging_utils_1 = require("./logging-utils.cjs");
7
6
  const cache_1 = require("./utils/cache.cjs");
8
7
  const log = (0, logging_utils_1.createModuleLogger)(logging_utils_1.projectLogger, 'block-ref');
8
+ /**
9
+ * Creates a middleware that rewrites "latest" block references to the known
10
+ * latest block number from a block tracker.
11
+ *
12
+ * @param options - The options for the middleware.
13
+ * @param options.provider - The provider to use.
14
+ * @param options.blockTracker - The block tracker to use.
15
+ * @returns The middleware.
16
+ */
9
17
  function createBlockRefMiddleware({ provider, blockTracker, } = {}) {
10
18
  if (!provider) {
11
19
  throw Error('BlockRefMiddleware - mandatory "provider" option is missing.');
@@ -13,14 +21,14 @@ function createBlockRefMiddleware({ provider, blockTracker, } = {}) {
13
21
  if (!blockTracker) {
14
22
  throw Error('BlockRefMiddleware - mandatory "blockTracker" option is missing.');
15
23
  }
16
- return (0, json_rpc_engine_1.createAsyncMiddleware)(async (req, res, next) => {
17
- const blockRefIndex = (0, cache_1.blockTagParamIndex)(req.method);
24
+ return async ({ request, next }) => {
25
+ const blockRefIndex = (0, cache_1.blockTagParamIndex)(request.method);
18
26
  // skip if method does not include blockRef
19
27
  if (blockRefIndex === undefined) {
20
28
  return next();
21
29
  }
22
- const blockRef = Array.isArray(req.params)
23
- ? (req.params[blockRefIndex] ?? 'latest')
30
+ const blockRef = Array.isArray(request.params)
31
+ ? (request.params[blockRefIndex] ?? 'latest')
24
32
  : 'latest';
25
33
  // skip if not "latest"
26
34
  if (blockRef !== 'latest') {
@@ -31,16 +39,15 @@ function createBlockRefMiddleware({ provider, blockTracker, } = {}) {
31
39
  const latestBlockNumber = await blockTracker.getLatestBlock();
32
40
  log(`blockRef is "latest", setting param ${blockRefIndex} to latest block ${latestBlockNumber}`);
33
41
  // create child request with specific block-ref
34
- const childRequest = (0, full_1.klona)(req);
42
+ const childRequest = (0, klona_1.klona)(request);
35
43
  if (Array.isArray(childRequest.params)) {
36
44
  childRequest.params[blockRefIndex] = latestBlockNumber;
37
45
  }
38
46
  // perform child request
39
47
  log('Performing another request %o', childRequest);
40
48
  // copy child result onto original response
41
- res.result = await provider.request(childRequest);
42
- return undefined;
43
- });
49
+ return await provider.request(childRequest);
50
+ };
44
51
  }
45
52
  exports.createBlockRefMiddleware = createBlockRefMiddleware;
46
53
  //# sourceMappingURL=block-ref.cjs.map