@metamask-previews/eth-json-rpc-middleware 24.0.1-preview-4f4c98e → 24.0.1-preview-eb263b0ee

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 (237) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/dist/block-cache.cjs +174 -0
  3. package/dist/block-cache.cjs.map +1 -0
  4. package/dist/{block-cache.d.ts → block-cache.d.cts} +4 -4
  5. package/dist/block-cache.d.cts.map +1 -0
  6. package/dist/block-cache.d.mts +18 -0
  7. package/dist/block-cache.d.mts.map +1 -0
  8. package/dist/{block-cache.js → block-cache.mjs} +3 -3
  9. package/dist/block-cache.mjs.map +1 -0
  10. package/dist/block-ref-rewrite.cjs +43 -0
  11. package/dist/block-ref-rewrite.cjs.map +1 -0
  12. package/dist/{block-ref-rewrite.d.ts → block-ref-rewrite.d.cts} +4 -4
  13. package/dist/block-ref-rewrite.d.cts.map +1 -0
  14. package/dist/block-ref-rewrite.d.mts +17 -0
  15. package/dist/block-ref-rewrite.d.mts.map +1 -0
  16. package/dist/{block-ref-rewrite.js → block-ref-rewrite.mjs} +2 -2
  17. package/dist/block-ref-rewrite.mjs.map +1 -0
  18. package/dist/block-ref.cjs +53 -0
  19. package/dist/block-ref.cjs.map +1 -0
  20. package/dist/{block-ref.d.ts → block-ref.d.cts} +5 -5
  21. package/dist/block-ref.d.cts.map +1 -0
  22. package/dist/block-ref.d.mts +20 -0
  23. package/dist/block-ref.d.mts.map +1 -0
  24. package/dist/{block-ref.js → block-ref.mjs} +4 -4
  25. package/dist/block-ref.mjs.map +1 -0
  26. package/dist/block-tracker-inspector.cjs +59 -0
  27. package/dist/block-tracker-inspector.cjs.map +1 -0
  28. package/dist/{block-tracker-inspector.d.ts → block-tracker-inspector.d.cts} +4 -4
  29. package/dist/block-tracker-inspector.d.cts.map +1 -0
  30. package/dist/block-tracker-inspector.d.mts +15 -0
  31. package/dist/block-tracker-inspector.d.mts.map +1 -0
  32. package/dist/{block-tracker-inspector.js → block-tracker-inspector.mjs} +3 -3
  33. package/dist/block-tracker-inspector.mjs.map +1 -0
  34. package/dist/fetch.cjs +39 -0
  35. package/dist/fetch.cjs.map +1 -0
  36. package/dist/{fetch.d.ts → fetch.d.cts} +4 -4
  37. package/dist/fetch.d.cts.map +1 -0
  38. package/dist/fetch.d.mts +24 -0
  39. package/dist/fetch.d.mts.map +1 -0
  40. package/dist/{fetch.js → fetch.mjs} +2 -2
  41. package/dist/fetch.mjs.map +1 -0
  42. package/dist/index.cjs +36 -0
  43. package/dist/index.cjs.map +1 -0
  44. package/dist/index.d.cts +17 -0
  45. package/dist/index.d.cts.map +1 -0
  46. package/dist/index.d.mts +17 -0
  47. package/dist/index.d.mts.map +1 -0
  48. package/dist/index.mjs +13 -0
  49. package/dist/index.mjs.map +1 -0
  50. package/dist/inflight-cache.cjs +90 -0
  51. package/dist/inflight-cache.cjs.map +1 -0
  52. package/dist/{inflight-cache.d.ts → inflight-cache.d.cts} +3 -3
  53. package/dist/inflight-cache.d.cts.map +1 -0
  54. package/dist/inflight-cache.d.mts +13 -0
  55. package/dist/inflight-cache.d.mts.map +1 -0
  56. package/dist/{inflight-cache.js → inflight-cache.mjs} +4 -4
  57. package/dist/inflight-cache.mjs.map +1 -0
  58. package/dist/logging-utils.cjs +7 -0
  59. package/dist/logging-utils.cjs.map +1 -0
  60. package/dist/logging-utils.d.cts +5 -0
  61. package/dist/logging-utils.d.cts.map +1 -0
  62. package/dist/logging-utils.d.mts +5 -0
  63. package/dist/logging-utils.d.mts.map +1 -0
  64. package/dist/logging-utils.mjs +4 -0
  65. package/dist/logging-utils.mjs.map +1 -0
  66. package/dist/methods/wallet-get-granted-execution-permissions.cjs +61 -0
  67. package/dist/methods/wallet-get-granted-execution-permissions.cjs.map +1 -0
  68. package/dist/methods/{wallet-get-granted-execution-permissions.d.ts → wallet-get-granted-execution-permissions.d.cts} +14 -14
  69. package/dist/methods/wallet-get-granted-execution-permissions.d.cts.map +1 -0
  70. package/dist/methods/wallet-get-granted-execution-permissions.d.mts +140 -0
  71. package/dist/methods/wallet-get-granted-execution-permissions.d.mts.map +1 -0
  72. package/dist/methods/{wallet-get-granted-execution-permissions.js → wallet-get-granted-execution-permissions.mjs} +6 -6
  73. package/dist/methods/wallet-get-granted-execution-permissions.mjs.map +1 -0
  74. package/dist/methods/wallet-get-supported-execution-permissions.cjs +47 -0
  75. package/dist/methods/wallet-get-supported-execution-permissions.cjs.map +1 -0
  76. package/dist/methods/{wallet-get-supported-execution-permissions.d.ts → wallet-get-supported-execution-permissions.d.cts} +6 -6
  77. package/dist/methods/wallet-get-supported-execution-permissions.d.cts.map +1 -0
  78. package/dist/methods/wallet-get-supported-execution-permissions.d.mts +54 -0
  79. package/dist/methods/wallet-get-supported-execution-permissions.d.mts.map +1 -0
  80. package/dist/methods/{wallet-get-supported-execution-permissions.js → wallet-get-supported-execution-permissions.mjs} +6 -6
  81. package/dist/methods/wallet-get-supported-execution-permissions.mjs.map +1 -0
  82. package/dist/methods/wallet-request-execution-permissions.cjs +45 -0
  83. package/dist/methods/wallet-request-execution-permissions.cjs.map +1 -0
  84. package/dist/methods/{wallet-request-execution-permissions.d.ts → wallet-request-execution-permissions.d.cts} +18 -18
  85. package/dist/methods/wallet-request-execution-permissions.d.cts.map +1 -0
  86. package/dist/methods/wallet-request-execution-permissions.d.mts +104 -0
  87. package/dist/methods/wallet-request-execution-permissions.d.mts.map +1 -0
  88. package/dist/methods/{wallet-request-execution-permissions.js → wallet-request-execution-permissions.mjs} +5 -5
  89. package/dist/methods/wallet-request-execution-permissions.mjs.map +1 -0
  90. package/dist/methods/wallet-revoke-execution-permission.cjs +32 -0
  91. package/dist/methods/wallet-revoke-execution-permission.cjs.map +1 -0
  92. package/dist/methods/{wallet-revoke-execution-permission.d.ts → wallet-revoke-execution-permission.d.cts} +5 -5
  93. package/dist/methods/wallet-revoke-execution-permission.d.cts.map +1 -0
  94. package/dist/methods/wallet-revoke-execution-permission.d.mts +26 -0
  95. package/dist/methods/wallet-revoke-execution-permission.d.mts.map +1 -0
  96. package/dist/methods/{wallet-revoke-execution-permission.js → wallet-revoke-execution-permission.mjs} +5 -5
  97. package/dist/methods/wallet-revoke-execution-permission.mjs.map +1 -0
  98. package/dist/providerAsMiddleware.cjs +28 -0
  99. package/dist/providerAsMiddleware.cjs.map +1 -0
  100. package/dist/{providerAsMiddleware.d.ts → providerAsMiddleware.d.cts} +5 -5
  101. package/dist/providerAsMiddleware.d.cts.map +1 -0
  102. package/dist/providerAsMiddleware.d.mts +20 -0
  103. package/dist/providerAsMiddleware.d.mts.map +1 -0
  104. package/dist/{providerAsMiddleware.js → providerAsMiddleware.mjs} +2 -2
  105. package/dist/providerAsMiddleware.mjs.map +1 -0
  106. package/dist/retryOnEmpty.cjs +106 -0
  107. package/dist/retryOnEmpty.cjs.map +1 -0
  108. package/dist/{retryOnEmpty.d.ts → retryOnEmpty.d.cts} +5 -5
  109. package/dist/retryOnEmpty.d.cts.map +1 -0
  110. package/dist/retryOnEmpty.d.mts +17 -0
  111. package/dist/retryOnEmpty.d.mts.map +1 -0
  112. package/dist/{retryOnEmpty.js → retryOnEmpty.mjs} +6 -6
  113. package/dist/retryOnEmpty.mjs.map +1 -0
  114. package/dist/types.cjs +3 -0
  115. package/dist/types.cjs.map +1 -0
  116. package/dist/{types.d.ts → types.d.cts} +2 -2
  117. package/dist/types.d.cts.map +1 -0
  118. package/dist/types.d.mts +20 -0
  119. package/dist/types.d.mts.map +1 -0
  120. package/dist/types.mjs +2 -0
  121. package/dist/types.mjs.map +1 -0
  122. package/dist/utils/cache.cjs +186 -0
  123. package/dist/utils/cache.cjs.map +1 -0
  124. package/dist/utils/{cache.d.ts → cache.d.cts} +2 -2
  125. package/dist/utils/cache.d.cts.map +1 -0
  126. package/dist/utils/cache.d.mts +68 -0
  127. package/dist/utils/cache.d.mts.map +1 -0
  128. package/dist/utils/{cache.js → cache.mjs} +2 -2
  129. package/dist/utils/cache.mjs.map +1 -0
  130. package/dist/utils/common.cjs +17 -0
  131. package/dist/utils/common.cjs.map +1 -0
  132. package/dist/utils/{common.d.ts → common.d.cts} +1 -1
  133. package/dist/utils/common.d.cts.map +1 -0
  134. package/dist/utils/common.d.mts +8 -0
  135. package/dist/utils/common.d.mts.map +1 -0
  136. package/dist/utils/{common.js → common.mjs} +1 -1
  137. package/dist/utils/common.mjs.map +1 -0
  138. package/dist/utils/error.cjs +19 -0
  139. package/dist/utils/error.cjs.map +1 -0
  140. package/dist/utils/{error.d.ts → error.d.cts} +2 -2
  141. package/dist/utils/error.d.cts.map +1 -0
  142. package/dist/utils/error.d.mts +10 -0
  143. package/dist/utils/error.d.mts.map +1 -0
  144. package/dist/utils/{error.js → error.mjs} +3 -3
  145. package/dist/utils/error.mjs.map +1 -0
  146. package/dist/utils/normalize.cjs +57 -0
  147. package/dist/utils/normalize.cjs.map +1 -0
  148. package/dist/utils/{normalize.d.ts → normalize.d.cts} +2 -2
  149. package/dist/utils/normalize.d.cts.map +1 -0
  150. package/dist/utils/normalize.d.mts +26 -0
  151. package/dist/utils/normalize.d.mts.map +1 -0
  152. package/dist/utils/{normalize.js → normalize.mjs} +1 -1
  153. package/dist/utils/normalize.mjs.map +1 -0
  154. package/dist/utils/structs.cjs +21 -0
  155. package/dist/utils/structs.cjs.map +1 -0
  156. package/dist/utils/{structs.d.ts → structs.d.cts} +2 -2
  157. package/dist/utils/structs.d.cts.map +1 -0
  158. package/dist/utils/structs.d.mts +17 -0
  159. package/dist/utils/structs.d.mts.map +1 -0
  160. package/dist/utils/{structs.js → structs.mjs} +2 -2
  161. package/dist/utils/structs.mjs.map +1 -0
  162. package/dist/utils/timeout.cjs +14 -0
  163. package/dist/utils/timeout.cjs.map +1 -0
  164. package/dist/utils/{timeout.d.ts → timeout.d.cts} +1 -1
  165. package/dist/utils/timeout.d.cts.map +1 -0
  166. package/dist/utils/timeout.d.mts +8 -0
  167. package/dist/utils/timeout.d.mts.map +1 -0
  168. package/dist/utils/{timeout.js → timeout.mjs} +1 -1
  169. package/dist/utils/timeout.mjs.map +1 -0
  170. package/dist/utils/validation.cjs +255 -0
  171. package/dist/utils/validation.cjs.map +1 -0
  172. package/dist/utils/{validation.d.ts → validation.d.cts} +12 -12
  173. package/dist/utils/validation.d.cts.map +1 -0
  174. package/dist/utils/validation.d.mts +156 -0
  175. package/dist/utils/validation.d.mts.map +1 -0
  176. package/dist/utils/{validation.js → validation.mjs} +5 -5
  177. package/dist/utils/validation.mjs.map +1 -0
  178. package/dist/wallet.cjs +460 -0
  179. package/dist/wallet.cjs.map +1 -0
  180. package/dist/{wallet.d.ts → wallet.d.cts} +8 -8
  181. package/dist/wallet.d.cts.map +1 -0
  182. package/dist/wallet.d.mts +66 -0
  183. package/dist/wallet.d.mts.map +1 -0
  184. package/dist/{wallet.js → wallet.mjs} +12 -12
  185. package/dist/wallet.mjs.map +1 -0
  186. package/package.json +17 -13
  187. package/dist/block-cache.d.ts.map +0 -1
  188. package/dist/block-cache.js.map +0 -1
  189. package/dist/block-ref-rewrite.d.ts.map +0 -1
  190. package/dist/block-ref-rewrite.js.map +0 -1
  191. package/dist/block-ref.d.ts.map +0 -1
  192. package/dist/block-ref.js.map +0 -1
  193. package/dist/block-tracker-inspector.d.ts.map +0 -1
  194. package/dist/block-tracker-inspector.js.map +0 -1
  195. package/dist/fetch.d.ts.map +0 -1
  196. package/dist/fetch.js.map +0 -1
  197. package/dist/index.d.ts +0 -17
  198. package/dist/index.d.ts.map +0 -1
  199. package/dist/index.js +0 -13
  200. package/dist/index.js.map +0 -1
  201. package/dist/inflight-cache.d.ts.map +0 -1
  202. package/dist/inflight-cache.js.map +0 -1
  203. package/dist/logging-utils.d.ts +0 -4
  204. package/dist/logging-utils.d.ts.map +0 -1
  205. package/dist/logging-utils.js +0 -4
  206. package/dist/logging-utils.js.map +0 -1
  207. package/dist/methods/wallet-get-granted-execution-permissions.d.ts.map +0 -1
  208. package/dist/methods/wallet-get-granted-execution-permissions.js.map +0 -1
  209. package/dist/methods/wallet-get-supported-execution-permissions.d.ts.map +0 -1
  210. package/dist/methods/wallet-get-supported-execution-permissions.js.map +0 -1
  211. package/dist/methods/wallet-request-execution-permissions.d.ts.map +0 -1
  212. package/dist/methods/wallet-request-execution-permissions.js.map +0 -1
  213. package/dist/methods/wallet-revoke-execution-permission.d.ts.map +0 -1
  214. package/dist/methods/wallet-revoke-execution-permission.js.map +0 -1
  215. package/dist/providerAsMiddleware.d.ts.map +0 -1
  216. package/dist/providerAsMiddleware.js.map +0 -1
  217. package/dist/retryOnEmpty.d.ts.map +0 -1
  218. package/dist/retryOnEmpty.js.map +0 -1
  219. package/dist/types.d.ts.map +0 -1
  220. package/dist/types.js +0 -2
  221. package/dist/types.js.map +0 -1
  222. package/dist/utils/cache.d.ts.map +0 -1
  223. package/dist/utils/cache.js.map +0 -1
  224. package/dist/utils/common.d.ts.map +0 -1
  225. package/dist/utils/common.js.map +0 -1
  226. package/dist/utils/error.d.ts.map +0 -1
  227. package/dist/utils/error.js.map +0 -1
  228. package/dist/utils/normalize.d.ts.map +0 -1
  229. package/dist/utils/normalize.js.map +0 -1
  230. package/dist/utils/structs.d.ts.map +0 -1
  231. package/dist/utils/structs.js.map +0 -1
  232. package/dist/utils/timeout.d.ts.map +0 -1
  233. package/dist/utils/timeout.js.map +0 -1
  234. package/dist/utils/validation.d.ts.map +0 -1
  235. package/dist/utils/validation.js.map +0 -1
  236. package/dist/wallet.d.ts.map +0 -1
  237. package/dist/wallet.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -11,7 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ### Changed
13
13
 
14
- - **BREAKING:** Bump minimum Node.js version to 22 ([#9168](https://github.com/MetaMask/core/pull/9168))
15
14
  - Bump `@metamask/superstruct` from `^3.1.0` to `^3.4.1` ([#9754](https://github.com/MetaMask/core/pull/9754))
16
15
 
17
16
  ### Fixed
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _BlockCacheStrategy_cache;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createBlockCacheMiddleware = void 0;
16
+ const logging_utils_js_1 = require("./logging-utils.cjs");
17
+ const cache_js_1 = require("./utils/cache.cjs");
18
+ const log = (0, logging_utils_js_1.createModuleLogger)(logging_utils_js_1.projectLogger, 'block-cache');
19
+ // `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925
20
+ const emptyValues = [undefined, null, '\u003cnil\u003e'];
21
+ //
22
+ // Cache Strategies
23
+ //
24
+ class BlockCacheStrategy {
25
+ constructor() {
26
+ _BlockCacheStrategy_cache.set(this, void 0);
27
+ __classPrivateFieldSet(this, _BlockCacheStrategy_cache, {}, "f");
28
+ }
29
+ getBlockCache(blockNumberHex) {
30
+ const blockNumber = Number.parseInt(blockNumberHex, 16);
31
+ let blockCache = __classPrivateFieldGet(this, _BlockCacheStrategy_cache, "f")[blockNumber];
32
+ // create new cache if necesary
33
+ if (!blockCache) {
34
+ const newCache = {};
35
+ __classPrivateFieldGet(this, _BlockCacheStrategy_cache, "f")[blockNumber] = newCache;
36
+ blockCache = newCache;
37
+ }
38
+ return blockCache;
39
+ }
40
+ async get(request, requestedBlockNumber) {
41
+ // lookup block cache
42
+ const blockCache = this.getBlockCache(requestedBlockNumber);
43
+ // lookup payload in block cache
44
+ const identifier = (0, cache_js_1.cacheIdentifierForRequest)(request, true);
45
+ return identifier ? blockCache[identifier] : undefined;
46
+ }
47
+ async set(request, requestedBlockNumber, result) {
48
+ // check if we can cached this result
49
+ const canCacheResult = this.canCacheResult(request, result);
50
+ if (!canCacheResult) {
51
+ return;
52
+ }
53
+ // set the value in the cache
54
+ const identifier = (0, cache_js_1.cacheIdentifierForRequest)(request, true);
55
+ if (!identifier) {
56
+ return;
57
+ }
58
+ const blockCache = this.getBlockCache(requestedBlockNumber);
59
+ blockCache[identifier] = result;
60
+ }
61
+ canCacheRequest(request) {
62
+ // check request method
63
+ if (!(0, cache_js_1.canCache)(request.method)) {
64
+ return false;
65
+ }
66
+ // check blockTag
67
+ const blockTag = (0, cache_js_1.blockTagForRequest)(request);
68
+ if (blockTag === 'pending') {
69
+ return false;
70
+ }
71
+ // can be cached
72
+ return true;
73
+ }
74
+ canCacheResult(request, result) {
75
+ // never cache empty values (e.g. undefined)
76
+ if (emptyValues.includes(result)) {
77
+ return false;
78
+ }
79
+ // check if transactions have block reference before caching
80
+ if (request.method &&
81
+ ['eth_getTransactionByHash', 'eth_getTransactionReceipt'].includes(request.method)) {
82
+ if (!result?.blockHash ||
83
+ result.blockHash ===
84
+ '0x0000000000000000000000000000000000000000000000000000000000000000') {
85
+ return false;
86
+ }
87
+ }
88
+ // otherwise true
89
+ return true;
90
+ }
91
+ // removes all block caches with block number lower than `oldBlockHex`
92
+ clearBefore(oldBlockHex) {
93
+ const oldBlockNumber = Number.parseInt(oldBlockHex, 16);
94
+ // clear old caches
95
+ Object.keys(__classPrivateFieldGet(this, _BlockCacheStrategy_cache, "f"))
96
+ .map(Number)
97
+ .filter((value) => value < oldBlockNumber)
98
+ .forEach((value) => delete __classPrivateFieldGet(this, _BlockCacheStrategy_cache, "f")[value]);
99
+ }
100
+ }
101
+ _BlockCacheStrategy_cache = new WeakMap();
102
+ /**
103
+ * Creates a middleware that caches block-related requests.
104
+ *
105
+ * @param options - The options for the middleware.
106
+ * @param options.blockTracker - The block tracker to use.
107
+ * @returns The block cache middleware.
108
+ */
109
+ function createBlockCacheMiddleware({ blockTracker, } = {}) {
110
+ if (!blockTracker) {
111
+ throw new Error('createBlockCacheMiddleware - No PollingBlockTracker specified');
112
+ }
113
+ const blockCache = new BlockCacheStrategy();
114
+ const strategies = {
115
+ [cache_js_1.CacheStrategy.Permanent]: blockCache,
116
+ [cache_js_1.CacheStrategy.Block]: blockCache,
117
+ [cache_js_1.CacheStrategy.Fork]: blockCache,
118
+ [cache_js_1.CacheStrategy.Never]: undefined,
119
+ };
120
+ return async ({ request, next, context }) => {
121
+ if (context.get('skipCache')) {
122
+ return next();
123
+ }
124
+ const type = (0, cache_js_1.cacheTypeForMethod)(request.method);
125
+ const strategy = strategies[type];
126
+ if (!strategy) {
127
+ return next();
128
+ }
129
+ if (!strategy.canCacheRequest(request)) {
130
+ return next();
131
+ }
132
+ const requestBlockTag = (0, cache_js_1.blockTagForRequest)(request);
133
+ const blockTag = requestBlockTag && typeof requestBlockTag === 'string'
134
+ ? requestBlockTag
135
+ : 'latest';
136
+ log('blockTag = %o, req = %o', blockTag, request);
137
+ // get exact block number
138
+ let requestedBlockNumber;
139
+ if (blockTag === 'earliest') {
140
+ // this just exists for symmetry with "latest"
141
+ requestedBlockNumber = '0x00';
142
+ }
143
+ else if (blockTag === 'latest') {
144
+ log('Fetching latest block number to determine cache key');
145
+ const latestBlockNumber = await blockTracker.getLatestBlock();
146
+ // clear all cache before latest block
147
+ log('Clearing values stored under block numbers before %o', latestBlockNumber);
148
+ blockCache.clearBefore(latestBlockNumber);
149
+ requestedBlockNumber = latestBlockNumber;
150
+ }
151
+ else {
152
+ // we have a hex number
153
+ requestedBlockNumber = blockTag;
154
+ }
155
+ // end on a hit, continue on a miss
156
+ const cacheResult = await strategy.get(request, requestedBlockNumber);
157
+ if (cacheResult === undefined) {
158
+ // cache miss
159
+ // wait for other middleware to handle request
160
+ log('No cache stored under block number %o, carrying request forward', requestedBlockNumber);
161
+ const result = await next();
162
+ // add result to cache
163
+ // it's safe to cast res.result as Block, due to runtime type checks
164
+ // performed when strategy.set is called
165
+ log('Populating cache with', result);
166
+ await strategy.set(request, requestedBlockNumber, result);
167
+ return result;
168
+ }
169
+ log('Cache hit, reusing cache result stored under block number %o', requestedBlockNumber);
170
+ return cacheResult;
171
+ };
172
+ }
173
+ exports.createBlockCacheMiddleware = createBlockCacheMiddleware;
174
+ //# sourceMappingURL=block-cache.cjs.map
@@ -0,0 +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 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.js';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n} from './types.js';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache.js';\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 #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((value) => value < oldBlockNumber)\n .forEach((value) => delete this.#cache[value]);\n }\n}\n\n/**\n * Creates a middleware that caches block-related requests.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The block cache middleware.\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,6 +1,6 @@
1
- import type { PollingBlockTracker } from '@metamask/eth-block-tracker';
2
- import type { JsonRpcMiddleware, MiddlewareContext } from '@metamask/json-rpc-engine/v2';
3
- import type { Json, JsonRpcRequest } from '@metamask/utils';
1
+ import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
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
  };
@@ -15,4 +15,4 @@ export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCach
15
15
  skipCache?: boolean;
16
16
  }>>;
17
17
  export {};
18
- //# sourceMappingURL=block-cache.d.ts.map
18
+ //# sourceMappingURL=block-cache.d.cts.map
@@ -0,0 +1 @@
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;;;;;;GAMG;AACH,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"}
@@ -0,0 +1,18 @@
1
+ import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
+ import type { JsonRpcMiddleware, MiddlewareContext } from "@metamask/json-rpc-engine/v2";
3
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
4
+ type BlockCacheMiddlewareOptions = {
5
+ blockTracker?: PollingBlockTracker;
6
+ };
7
+ /**
8
+ * Creates a middleware that caches block-related requests.
9
+ *
10
+ * @param options - The options for the middleware.
11
+ * @param options.blockTracker - The block tracker to use.
12
+ * @returns The block cache middleware.
13
+ */
14
+ export declare function createBlockCacheMiddleware({ blockTracker, }?: BlockCacheMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json, MiddlewareContext<{
15
+ skipCache?: boolean;
16
+ }>>;
17
+ export {};
18
+ //# sourceMappingURL=block-cache.d.mts.map
@@ -0,0 +1 @@
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;;;;;;GAMG;AACH,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"}
@@ -10,8 +10,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _BlockCacheStrategy_cache;
13
- import { projectLogger, createModuleLogger } from './logging-utils.js';
14
- import { cacheIdentifierForRequest, blockTagForRequest, cacheTypeForMethod, canCache, CacheStrategy, } from './utils/cache.js';
13
+ import { projectLogger, createModuleLogger } from "./logging-utils.mjs";
14
+ import { cacheIdentifierForRequest, blockTagForRequest, cacheTypeForMethod, canCache, CacheStrategy } from "./utils/cache.mjs";
15
15
  const log = createModuleLogger(projectLogger, 'block-cache');
16
16
  // `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925
17
17
  const emptyValues = [undefined, null, '\u003cnil\u003e'];
@@ -167,4 +167,4 @@ export function createBlockCacheMiddleware({ blockTracker, } = {}) {
167
167
  return cacheResult;
168
168
  };
169
169
  }
170
- //# sourceMappingURL=block-cache.js.map
170
+ //# sourceMappingURL=block-cache.mjs.map
@@ -0,0 +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 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.js';\nimport type {\n Block,\n BlockCache,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Cache,\n} from './types.js';\nimport {\n cacheIdentifierForRequest,\n blockTagForRequest,\n cacheTypeForMethod,\n canCache,\n CacheStrategy,\n} from './utils/cache.js';\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 #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((value) => value < oldBlockNumber)\n .forEach((value) => delete this.#cache[value]);\n }\n}\n\n/**\n * Creates a middleware that caches block-related requests.\n *\n * @param options - The options for the middleware.\n * @param options.blockTracker - The block tracker to use.\n * @returns The block cache middleware.\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"]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBlockRefRewriteMiddleware = void 0;
4
+ const cache_js_1 = require("./utils/cache.cjs");
5
+ /**
6
+ * Creates a middleware that rewrites "latest" block references to the known
7
+ * latest block number from a block tracker.
8
+ *
9
+ * @param options - The options for the middleware.
10
+ * @param options.blockTracker - The block tracker to use.
11
+ * @returns The middleware.
12
+ */
13
+ function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
14
+ if (!blockTracker) {
15
+ throw Error('BlockRefRewriteMiddleware - mandatory "blockTracker" option is missing.');
16
+ }
17
+ return async ({ request, next }) => {
18
+ const blockRefIndex = (0, cache_js_1.blockTagParamIndex)(request.method);
19
+ if (blockRefIndex === undefined) {
20
+ return next();
21
+ }
22
+ const blockRef = Array.isArray(request.params) && request.params[blockRefIndex]
23
+ ? request.params[blockRefIndex]
24
+ : // omitted blockRef implies "latest"
25
+ 'latest';
26
+ if (blockRef !== 'latest') {
27
+ return next();
28
+ }
29
+ // rewrite blockRef to block-tracker's block number
30
+ const latestBlockNumber = await blockTracker.getLatestBlock();
31
+ if (Array.isArray(request.params)) {
32
+ const params = request.params.slice();
33
+ params[blockRefIndex] = latestBlockNumber;
34
+ return next({
35
+ ...request,
36
+ params,
37
+ });
38
+ }
39
+ return next();
40
+ };
41
+ }
42
+ exports.createBlockRefRewriteMiddleware = createBlockRefRewriteMiddleware;
43
+ //# sourceMappingURL=block-ref-rewrite.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-ref-rewrite.cjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":";;;AAIA,gDAAsD;AAMtD;;;;;;;GAOG;AACH,SAAgB,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,MAAM,aAAa,GAAuB,IAAA,6BAAkB,EAC1D,OAAO,CAAC,MAAM,CACf,CAAC;QACF,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;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,CAAC;YAC1B,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,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;QACL,CAAC;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.js';\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
- import type { PollingBlockTracker } from '@metamask/eth-block-tracker';
2
- import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';
3
- import type { Json, JsonRpcRequest } from '@metamask/utils';
1
+ import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
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
  };
@@ -14,4 +14,4 @@ type BlockRefRewriteMiddlewareOptions = {
14
14
  */
15
15
  export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json>;
16
16
  export {};
17
- //# sourceMappingURL=block-ref-rewrite.d.ts.map
17
+ //# sourceMappingURL=block-ref-rewrite.d.cts.map
@@ -0,0 +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,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"}
@@ -0,0 +1,17 @@
1
+ import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine/v2";
3
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
4
+ type BlockRefRewriteMiddlewareOptions = {
5
+ blockTracker?: PollingBlockTracker;
6
+ };
7
+ /**
8
+ * Creates a middleware that rewrites "latest" block references to the known
9
+ * latest block number from a block tracker.
10
+ *
11
+ * @param options - The options for the middleware.
12
+ * @param options.blockTracker - The block tracker to use.
13
+ * @returns The middleware.
14
+ */
15
+ export declare function createBlockRefRewriteMiddleware({ blockTracker, }?: BlockRefRewriteMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json>;
16
+ export {};
17
+ //# sourceMappingURL=block-ref-rewrite.d.mts.map
@@ -0,0 +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,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,4 @@
1
- import { blockTagParamIndex } from './utils/cache.js';
1
+ import { blockTagParamIndex } from "./utils/cache.mjs";
2
2
  /**
3
3
  * Creates a middleware that rewrites "latest" block references to the known
4
4
  * latest block number from a block tracker.
@@ -36,4 +36,4 @@ export function createBlockRefRewriteMiddleware({ blockTracker, } = {}) {
36
36
  return next();
37
37
  };
38
38
  }
39
- //# sourceMappingURL=block-ref-rewrite.js.map
39
+ //# sourceMappingURL=block-ref-rewrite.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-ref-rewrite.mjs","sourceRoot":"","sources":["../src/block-ref-rewrite.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,0BAAyB;AAMtD;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAAC,EAC9C,YAAY,MACwB,EAAE;IAItC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,KAAK,CACT,yEAAyE,CAC1E,CAAC;IACJ,CAAC;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,CAAC;YAChC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;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,CAAC;YAC1B,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,mDAAmD;QACnD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,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;QACL,CAAC;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.js';\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"]}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBlockRefMiddleware = void 0;
4
+ const klona_1 = require("klona");
5
+ const logging_utils_js_1 = require("./logging-utils.cjs");
6
+ const cache_js_1 = require("./utils/cache.cjs");
7
+ const log = (0, logging_utils_js_1.createModuleLogger)(logging_utils_js_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
+ */
17
+ function createBlockRefMiddleware({ provider, blockTracker, } = {}) {
18
+ if (!provider) {
19
+ throw Error('BlockRefMiddleware - mandatory "provider" option is missing.');
20
+ }
21
+ if (!blockTracker) {
22
+ throw Error('BlockRefMiddleware - mandatory "blockTracker" option is missing.');
23
+ }
24
+ return async ({ request, next }) => {
25
+ const blockRefIndex = (0, cache_js_1.blockTagParamIndex)(request.method);
26
+ // skip if method does not include blockRef
27
+ if (blockRefIndex === undefined) {
28
+ return next();
29
+ }
30
+ const blockRef = Array.isArray(request.params)
31
+ ? (request.params[blockRefIndex] ?? 'latest')
32
+ : 'latest';
33
+ // skip if not "latest"
34
+ if (blockRef !== 'latest') {
35
+ log('blockRef is not "latest", carrying request forward');
36
+ return next();
37
+ }
38
+ // lookup latest block
39
+ const latestBlockNumber = await blockTracker.getLatestBlock();
40
+ log(`blockRef is "latest", setting param ${blockRefIndex} to latest block ${latestBlockNumber}`);
41
+ // create child request with specific block-ref
42
+ const childRequest = (0, klona_1.klona)(request);
43
+ if (Array.isArray(childRequest.params)) {
44
+ childRequest.params[blockRefIndex] = latestBlockNumber;
45
+ }
46
+ // perform child request
47
+ log('Performing another request %o', childRequest);
48
+ // copy child result onto original response
49
+ return await provider.request(childRequest);
50
+ };
51
+ }
52
+ exports.createBlockRefMiddleware = createBlockRefMiddleware;
53
+ //# sourceMappingURL=block-ref.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-ref.cjs","sourceRoot":"","sources":["../src/block-ref.ts"],"names":[],"mappings":";;;AAIA,iCAA8B;AAE9B,0DAAuE;AAEvE,gDAAsD;AAOtD,MAAM,GAAG,GAAG,IAAA,qCAAkB,EAAC,gCAAa,EAAE,WAAW,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,SAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,YAAY,MACiB,EAAE;IAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,KAAK,CACT,kEAAkE,CACnE,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,MAAM,aAAa,GAAG,IAAA,6BAAkB,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEzD,2CAA2C;QAC3C,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5C,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,QAAQ,CAAC;YAC7C,CAAC,CAAC,QAAQ,CAAC;QAEb,uBAAuB;QACvB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAC1D,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,sBAAsB;QACtB,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,GAAG,CACD,uCAAuC,aAAa,oBAAoB,iBAAiB,EAAE,CAC5F,CAAC;QAEF,+CAA+C;QAC/C,MAAM,YAAY,GAAG,IAAA,aAAK,EAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;QACzD,CAAC;QAED,wBAAwB;QACxB,GAAG,CAAC,+BAA+B,EAAE,YAAY,CAAC,CAAC;QACnD,2CAA2C;QAC3C,OAAO,MAAM,QAAQ,CAAC,OAAO,CAAuB,YAAY,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC;AAlDD,4DAkDC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\nimport { klona } from 'klona';\n\nimport { projectLogger, createModuleLogger } from './logging-utils.js';\nimport type { Block } from './types.js';\nimport { blockTagParamIndex } from './utils/cache.js';\n\ntype BlockRefMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n provider?: InternalProvider;\n};\n\nconst log = createModuleLogger(projectLogger, 'block-ref');\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.provider - The provider to use.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefMiddleware({\n provider,\n blockTracker,\n}: BlockRefMiddlewareOptions = {}): JsonRpcMiddleware<JsonRpcRequest, Json> {\n if (!provider) {\n throw Error('BlockRefMiddleware - mandatory \"provider\" option is missing.');\n }\n\n if (!blockTracker) {\n throw Error(\n 'BlockRefMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return async ({ request, next }) => {\n const blockRefIndex = blockTagParamIndex(request.method);\n\n // skip if method does not include blockRef\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef = Array.isArray(request.params)\n ? (request.params[blockRefIndex] ?? 'latest')\n : 'latest';\n\n // skip if not \"latest\"\n if (blockRef !== 'latest') {\n log('blockRef is not \"latest\", carrying request forward');\n return next();\n }\n\n // lookup latest block\n const latestBlockNumber = await blockTracker.getLatestBlock();\n log(\n `blockRef is \"latest\", setting param ${blockRefIndex} to latest block ${latestBlockNumber}`,\n );\n\n // create child request with specific block-ref\n const childRequest = klona(request);\n\n if (Array.isArray(childRequest.params)) {\n childRequest.params[blockRefIndex] = latestBlockNumber;\n }\n\n // perform child request\n log('Performing another request %o', childRequest);\n // copy child result onto original response\n return await provider.request<JsonRpcParams, Block>(childRequest);\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
- import type { PollingBlockTracker } from '@metamask/eth-block-tracker';
2
- import type { InternalProvider } from '@metamask/eth-json-rpc-provider';
3
- import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';
4
- import type { Json, JsonRpcRequest } from '@metamask/utils';
1
+ import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
+ import type { InternalProvider } from "@metamask/eth-json-rpc-provider";
3
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine/v2";
4
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
5
5
  type BlockRefMiddlewareOptions = {
6
6
  blockTracker?: PollingBlockTracker;
7
7
  provider?: InternalProvider;
@@ -17,4 +17,4 @@ type BlockRefMiddlewareOptions = {
17
17
  */
18
18
  export declare function createBlockRefMiddleware({ provider, blockTracker, }?: BlockRefMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json>;
19
19
  export {};
20
- //# sourceMappingURL=block-ref.d.ts.map
20
+ //# sourceMappingURL=block-ref.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-ref.d.cts","sourceRoot":"","sources":["../src/block-ref.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,wCAAwC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,qCAAqC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAiB,cAAc,EAAE,wBAAwB;AAO3E,KAAK,yBAAyB,GAAG;IAC/B,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAIF;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,YAAY,GACb,GAAE,yBAA8B,GAAG,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CA+C1E"}
@@ -0,0 +1,20 @@
1
+ import type { PollingBlockTracker } from "@metamask/eth-block-tracker";
2
+ import type { InternalProvider } from "@metamask/eth-json-rpc-provider";
3
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine/v2";
4
+ import type { Json, JsonRpcRequest } from "@metamask/utils";
5
+ type BlockRefMiddlewareOptions = {
6
+ blockTracker?: PollingBlockTracker;
7
+ provider?: InternalProvider;
8
+ };
9
+ /**
10
+ * Creates a middleware that rewrites "latest" block references to the known
11
+ * latest block number from a block tracker.
12
+ *
13
+ * @param options - The options for the middleware.
14
+ * @param options.provider - The provider to use.
15
+ * @param options.blockTracker - The block tracker to use.
16
+ * @returns The middleware.
17
+ */
18
+ export declare function createBlockRefMiddleware({ provider, blockTracker, }?: BlockRefMiddlewareOptions): JsonRpcMiddleware<JsonRpcRequest, Json>;
19
+ export {};
20
+ //# sourceMappingURL=block-ref.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-ref.d.mts","sourceRoot":"","sources":["../src/block-ref.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oCAAoC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,wCAAwC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,qCAAqC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAiB,cAAc,EAAE,wBAAwB;AAO3E,KAAK,yBAAyB,GAAG;IAC/B,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAIF;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,YAAY,GACb,GAAE,yBAA8B,GAAG,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CA+C1E"}
@@ -1,6 +1,6 @@
1
- import { klona } from 'klona';
2
- import { projectLogger, createModuleLogger } from './logging-utils.js';
3
- import { blockTagParamIndex } from './utils/cache.js';
1
+ import { klona } from "klona";
2
+ import { projectLogger, createModuleLogger } from "./logging-utils.mjs";
3
+ import { blockTagParamIndex } from "./utils/cache.mjs";
4
4
  const log = createModuleLogger(projectLogger, 'block-ref');
5
5
  /**
6
6
  * Creates a middleware that rewrites "latest" block references to the known
@@ -46,4 +46,4 @@ export function createBlockRefMiddleware({ provider, blockTracker, } = {}) {
46
46
  return await provider.request(childRequest);
47
47
  };
48
48
  }
49
- //# sourceMappingURL=block-ref.js.map
49
+ //# sourceMappingURL=block-ref.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-ref.mjs","sourceRoot":"","sources":["../src/block-ref.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,cAAc;AAE9B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,4BAA2B;AAEvE,OAAO,EAAE,kBAAkB,EAAE,0BAAyB;AAOtD,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,EACvC,QAAQ,EACR,YAAY,MACiB,EAAE;IAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,KAAK,CACT,kEAAkE,CACnE,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEzD,2CAA2C;QAC3C,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5C,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,QAAQ,CAAC;YAC7C,CAAC,CAAC,QAAQ,CAAC;QAEb,uBAAuB;QACvB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAC1D,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,sBAAsB;QACtB,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;QAC9D,GAAG,CACD,uCAAuC,aAAa,oBAAoB,iBAAiB,EAAE,CAC5F,CAAC;QAEF,+CAA+C;QAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;QACzD,CAAC;QAED,wBAAwB;QACxB,GAAG,CAAC,+BAA+B,EAAE,YAAY,CAAC,CAAC;QACnD,2CAA2C;QAC3C,OAAO,MAAM,QAAQ,CAAC,OAAO,CAAuB,YAAY,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\nimport { klona } from 'klona';\n\nimport { projectLogger, createModuleLogger } from './logging-utils.js';\nimport type { Block } from './types.js';\nimport { blockTagParamIndex } from './utils/cache.js';\n\ntype BlockRefMiddlewareOptions = {\n blockTracker?: PollingBlockTracker;\n provider?: InternalProvider;\n};\n\nconst log = createModuleLogger(projectLogger, 'block-ref');\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.provider - The provider to use.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createBlockRefMiddleware({\n provider,\n blockTracker,\n}: BlockRefMiddlewareOptions = {}): JsonRpcMiddleware<JsonRpcRequest, Json> {\n if (!provider) {\n throw Error('BlockRefMiddleware - mandatory \"provider\" option is missing.');\n }\n\n if (!blockTracker) {\n throw Error(\n 'BlockRefMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return async ({ request, next }) => {\n const blockRefIndex = blockTagParamIndex(request.method);\n\n // skip if method does not include blockRef\n if (blockRefIndex === undefined) {\n return next();\n }\n\n const blockRef = Array.isArray(request.params)\n ? (request.params[blockRefIndex] ?? 'latest')\n : 'latest';\n\n // skip if not \"latest\"\n if (blockRef !== 'latest') {\n log('blockRef is not \"latest\", carrying request forward');\n return next();\n }\n\n // lookup latest block\n const latestBlockNumber = await blockTracker.getLatestBlock();\n log(\n `blockRef is \"latest\", setting param ${blockRefIndex} to latest block ${latestBlockNumber}`,\n );\n\n // create child request with specific block-ref\n const childRequest = klona(request);\n\n if (Array.isArray(childRequest.params)) {\n childRequest.params[blockRefIndex] = latestBlockNumber;\n }\n\n // perform child request\n log('Performing another request %o', childRequest);\n // copy child result onto original response\n return await provider.request<JsonRpcParams, Block>(childRequest);\n };\n}\n"]}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBlockTrackerInspectorMiddleware = void 0;
4
+ const utils_1 = require("@metamask/utils");
5
+ const logging_utils_js_1 = require("./logging-utils.cjs");
6
+ const log = (0, logging_utils_js_1.createModuleLogger)(logging_utils_js_1.projectLogger, 'block-tracker-inspector');
7
+ const futureBlockRefRequests = [
8
+ 'eth_getTransactionByHash',
9
+ 'eth_getTransactionReceipt',
10
+ ];
11
+ /**
12
+ * Creates a middleware that checks whether response block references are higher than the current block.
13
+ * If the block reference is higher, the middleware will make the block tracker check for a new block.
14
+ *
15
+ * @param options - The options for the middleware.
16
+ * @param options.blockTracker - The block tracker to use.
17
+ * @returns The middleware.
18
+ */
19
+ function createBlockTrackerInspectorMiddleware({ blockTracker, }) {
20
+ return async ({ request, next }) => {
21
+ if (!futureBlockRefRequests.includes(request.method)) {
22
+ return next();
23
+ }
24
+ const result = await next();
25
+ const responseBlockNumber = getResultBlockNumber(result);
26
+ if (responseBlockNumber) {
27
+ log('res.result.blockNumber exists, proceeding. res = %o', result);
28
+ // If number is higher, suggest block-tracker check for a new block
29
+ const blockNumber = Number.parseInt(responseBlockNumber, 16);
30
+ const currentBlockNumber = Number.parseInt(
31
+ // Typecast: If getCurrentBlock returns null, currentBlockNumber will be NaN, which is fine.
32
+ blockTracker.getCurrentBlock(), 16);
33
+ if (blockNumber > currentBlockNumber) {
34
+ log('blockNumber from response is greater than current block number, refreshing current block number');
35
+ await blockTracker.checkForLatestBlock();
36
+ }
37
+ }
38
+ return result;
39
+ };
40
+ }
41
+ exports.createBlockTrackerInspectorMiddleware = createBlockTrackerInspectorMiddleware;
42
+ /**
43
+ * Extracts the block number from the result.
44
+ *
45
+ * @param result - The result to extract the block number from.
46
+ * @returns The block number, or undefined if the result is not an object with a
47
+ * `blockNumber` property.
48
+ */
49
+ function getResultBlockNumber(result) {
50
+ if (!result ||
51
+ typeof result !== 'object' ||
52
+ !(0, utils_1.hasProperty)(result, 'blockNumber')) {
53
+ return undefined;
54
+ }
55
+ return typeof result.blockNumber === 'string'
56
+ ? result.blockNumber
57
+ : undefined;
58
+ }
59
+ //# sourceMappingURL=block-tracker-inspector.cjs.map