@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.
- package/CHANGELOG.md +0 -1
- package/dist/block-cache.cjs +174 -0
- package/dist/block-cache.cjs.map +1 -0
- package/dist/{block-cache.d.ts → block-cache.d.cts} +4 -4
- package/dist/block-cache.d.cts.map +1 -0
- package/dist/block-cache.d.mts +18 -0
- package/dist/block-cache.d.mts.map +1 -0
- package/dist/{block-cache.js → block-cache.mjs} +3 -3
- package/dist/block-cache.mjs.map +1 -0
- package/dist/block-ref-rewrite.cjs +43 -0
- package/dist/block-ref-rewrite.cjs.map +1 -0
- package/dist/{block-ref-rewrite.d.ts → block-ref-rewrite.d.cts} +4 -4
- package/dist/block-ref-rewrite.d.cts.map +1 -0
- package/dist/block-ref-rewrite.d.mts +17 -0
- package/dist/block-ref-rewrite.d.mts.map +1 -0
- package/dist/{block-ref-rewrite.js → block-ref-rewrite.mjs} +2 -2
- package/dist/block-ref-rewrite.mjs.map +1 -0
- package/dist/block-ref.cjs +53 -0
- package/dist/block-ref.cjs.map +1 -0
- package/dist/{block-ref.d.ts → block-ref.d.cts} +5 -5
- package/dist/block-ref.d.cts.map +1 -0
- package/dist/block-ref.d.mts +20 -0
- package/dist/block-ref.d.mts.map +1 -0
- package/dist/{block-ref.js → block-ref.mjs} +4 -4
- package/dist/block-ref.mjs.map +1 -0
- package/dist/block-tracker-inspector.cjs +59 -0
- package/dist/block-tracker-inspector.cjs.map +1 -0
- package/dist/{block-tracker-inspector.d.ts → block-tracker-inspector.d.cts} +4 -4
- package/dist/block-tracker-inspector.d.cts.map +1 -0
- package/dist/block-tracker-inspector.d.mts +15 -0
- package/dist/block-tracker-inspector.d.mts.map +1 -0
- package/dist/{block-tracker-inspector.js → block-tracker-inspector.mjs} +3 -3
- package/dist/block-tracker-inspector.mjs.map +1 -0
- package/dist/fetch.cjs +39 -0
- package/dist/fetch.cjs.map +1 -0
- package/dist/{fetch.d.ts → fetch.d.cts} +4 -4
- package/dist/fetch.d.cts.map +1 -0
- package/dist/fetch.d.mts +24 -0
- package/dist/fetch.d.mts.map +1 -0
- package/dist/{fetch.js → fetch.mjs} +2 -2
- package/dist/fetch.mjs.map +1 -0
- package/dist/index.cjs +36 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +17 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -0
- package/dist/inflight-cache.cjs +90 -0
- package/dist/inflight-cache.cjs.map +1 -0
- package/dist/{inflight-cache.d.ts → inflight-cache.d.cts} +3 -3
- package/dist/inflight-cache.d.cts.map +1 -0
- package/dist/inflight-cache.d.mts +13 -0
- package/dist/inflight-cache.d.mts.map +1 -0
- package/dist/{inflight-cache.js → inflight-cache.mjs} +4 -4
- package/dist/inflight-cache.mjs.map +1 -0
- package/dist/logging-utils.cjs +7 -0
- package/dist/logging-utils.cjs.map +1 -0
- package/dist/logging-utils.d.cts +5 -0
- package/dist/logging-utils.d.cts.map +1 -0
- package/dist/logging-utils.d.mts +5 -0
- package/dist/logging-utils.d.mts.map +1 -0
- package/dist/logging-utils.mjs +4 -0
- package/dist/logging-utils.mjs.map +1 -0
- package/dist/methods/wallet-get-granted-execution-permissions.cjs +61 -0
- package/dist/methods/wallet-get-granted-execution-permissions.cjs.map +1 -0
- package/dist/methods/{wallet-get-granted-execution-permissions.d.ts → wallet-get-granted-execution-permissions.d.cts} +14 -14
- package/dist/methods/wallet-get-granted-execution-permissions.d.cts.map +1 -0
- package/dist/methods/wallet-get-granted-execution-permissions.d.mts +140 -0
- package/dist/methods/wallet-get-granted-execution-permissions.d.mts.map +1 -0
- package/dist/methods/{wallet-get-granted-execution-permissions.js → wallet-get-granted-execution-permissions.mjs} +6 -6
- package/dist/methods/wallet-get-granted-execution-permissions.mjs.map +1 -0
- package/dist/methods/wallet-get-supported-execution-permissions.cjs +47 -0
- package/dist/methods/wallet-get-supported-execution-permissions.cjs.map +1 -0
- package/dist/methods/{wallet-get-supported-execution-permissions.d.ts → wallet-get-supported-execution-permissions.d.cts} +6 -6
- package/dist/methods/wallet-get-supported-execution-permissions.d.cts.map +1 -0
- package/dist/methods/wallet-get-supported-execution-permissions.d.mts +54 -0
- package/dist/methods/wallet-get-supported-execution-permissions.d.mts.map +1 -0
- package/dist/methods/{wallet-get-supported-execution-permissions.js → wallet-get-supported-execution-permissions.mjs} +6 -6
- package/dist/methods/wallet-get-supported-execution-permissions.mjs.map +1 -0
- package/dist/methods/wallet-request-execution-permissions.cjs +45 -0
- package/dist/methods/wallet-request-execution-permissions.cjs.map +1 -0
- package/dist/methods/{wallet-request-execution-permissions.d.ts → wallet-request-execution-permissions.d.cts} +18 -18
- package/dist/methods/wallet-request-execution-permissions.d.cts.map +1 -0
- package/dist/methods/wallet-request-execution-permissions.d.mts +104 -0
- package/dist/methods/wallet-request-execution-permissions.d.mts.map +1 -0
- package/dist/methods/{wallet-request-execution-permissions.js → wallet-request-execution-permissions.mjs} +5 -5
- package/dist/methods/wallet-request-execution-permissions.mjs.map +1 -0
- package/dist/methods/wallet-revoke-execution-permission.cjs +32 -0
- package/dist/methods/wallet-revoke-execution-permission.cjs.map +1 -0
- package/dist/methods/{wallet-revoke-execution-permission.d.ts → wallet-revoke-execution-permission.d.cts} +5 -5
- package/dist/methods/wallet-revoke-execution-permission.d.cts.map +1 -0
- package/dist/methods/wallet-revoke-execution-permission.d.mts +26 -0
- package/dist/methods/wallet-revoke-execution-permission.d.mts.map +1 -0
- package/dist/methods/{wallet-revoke-execution-permission.js → wallet-revoke-execution-permission.mjs} +5 -5
- package/dist/methods/wallet-revoke-execution-permission.mjs.map +1 -0
- package/dist/providerAsMiddleware.cjs +28 -0
- package/dist/providerAsMiddleware.cjs.map +1 -0
- package/dist/{providerAsMiddleware.d.ts → providerAsMiddleware.d.cts} +5 -5
- package/dist/providerAsMiddleware.d.cts.map +1 -0
- package/dist/providerAsMiddleware.d.mts +20 -0
- package/dist/providerAsMiddleware.d.mts.map +1 -0
- package/dist/{providerAsMiddleware.js → providerAsMiddleware.mjs} +2 -2
- package/dist/providerAsMiddleware.mjs.map +1 -0
- package/dist/retryOnEmpty.cjs +106 -0
- package/dist/retryOnEmpty.cjs.map +1 -0
- package/dist/{retryOnEmpty.d.ts → retryOnEmpty.d.cts} +5 -5
- package/dist/retryOnEmpty.d.cts.map +1 -0
- package/dist/retryOnEmpty.d.mts +17 -0
- package/dist/retryOnEmpty.d.mts.map +1 -0
- package/dist/{retryOnEmpty.js → retryOnEmpty.mjs} +6 -6
- package/dist/retryOnEmpty.mjs.map +1 -0
- package/dist/types.cjs +3 -0
- package/dist/types.cjs.map +1 -0
- package/dist/{types.d.ts → types.d.cts} +2 -2
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +20 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils/cache.cjs +186 -0
- package/dist/utils/cache.cjs.map +1 -0
- package/dist/utils/{cache.d.ts → cache.d.cts} +2 -2
- package/dist/utils/cache.d.cts.map +1 -0
- package/dist/utils/cache.d.mts +68 -0
- package/dist/utils/cache.d.mts.map +1 -0
- package/dist/utils/{cache.js → cache.mjs} +2 -2
- package/dist/utils/cache.mjs.map +1 -0
- package/dist/utils/common.cjs +17 -0
- package/dist/utils/common.cjs.map +1 -0
- package/dist/utils/{common.d.ts → common.d.cts} +1 -1
- package/dist/utils/common.d.cts.map +1 -0
- package/dist/utils/common.d.mts +8 -0
- package/dist/utils/common.d.mts.map +1 -0
- package/dist/utils/{common.js → common.mjs} +1 -1
- package/dist/utils/common.mjs.map +1 -0
- package/dist/utils/error.cjs +19 -0
- package/dist/utils/error.cjs.map +1 -0
- package/dist/utils/{error.d.ts → error.d.cts} +2 -2
- package/dist/utils/error.d.cts.map +1 -0
- package/dist/utils/error.d.mts +10 -0
- package/dist/utils/error.d.mts.map +1 -0
- package/dist/utils/{error.js → error.mjs} +3 -3
- package/dist/utils/error.mjs.map +1 -0
- package/dist/utils/normalize.cjs +57 -0
- package/dist/utils/normalize.cjs.map +1 -0
- package/dist/utils/{normalize.d.ts → normalize.d.cts} +2 -2
- package/dist/utils/normalize.d.cts.map +1 -0
- package/dist/utils/normalize.d.mts +26 -0
- package/dist/utils/normalize.d.mts.map +1 -0
- package/dist/utils/{normalize.js → normalize.mjs} +1 -1
- package/dist/utils/normalize.mjs.map +1 -0
- package/dist/utils/structs.cjs +21 -0
- package/dist/utils/structs.cjs.map +1 -0
- package/dist/utils/{structs.d.ts → structs.d.cts} +2 -2
- package/dist/utils/structs.d.cts.map +1 -0
- package/dist/utils/structs.d.mts +17 -0
- package/dist/utils/structs.d.mts.map +1 -0
- package/dist/utils/{structs.js → structs.mjs} +2 -2
- package/dist/utils/structs.mjs.map +1 -0
- package/dist/utils/timeout.cjs +14 -0
- package/dist/utils/timeout.cjs.map +1 -0
- package/dist/utils/{timeout.d.ts → timeout.d.cts} +1 -1
- package/dist/utils/timeout.d.cts.map +1 -0
- package/dist/utils/timeout.d.mts +8 -0
- package/dist/utils/timeout.d.mts.map +1 -0
- package/dist/utils/{timeout.js → timeout.mjs} +1 -1
- package/dist/utils/timeout.mjs.map +1 -0
- package/dist/utils/validation.cjs +255 -0
- package/dist/utils/validation.cjs.map +1 -0
- package/dist/utils/{validation.d.ts → validation.d.cts} +12 -12
- package/dist/utils/validation.d.cts.map +1 -0
- package/dist/utils/validation.d.mts +156 -0
- package/dist/utils/validation.d.mts.map +1 -0
- package/dist/utils/{validation.js → validation.mjs} +5 -5
- package/dist/utils/validation.mjs.map +1 -0
- package/dist/wallet.cjs +460 -0
- package/dist/wallet.cjs.map +1 -0
- package/dist/{wallet.d.ts → wallet.d.cts} +8 -8
- package/dist/wallet.d.cts.map +1 -0
- package/dist/wallet.d.mts +66 -0
- package/dist/wallet.d.mts.map +1 -0
- package/dist/{wallet.js → wallet.mjs} +12 -12
- package/dist/wallet.mjs.map +1 -0
- package/package.json +17 -13
- package/dist/block-cache.d.ts.map +0 -1
- package/dist/block-cache.js.map +0 -1
- package/dist/block-ref-rewrite.d.ts.map +0 -1
- package/dist/block-ref-rewrite.js.map +0 -1
- package/dist/block-ref.d.ts.map +0 -1
- package/dist/block-ref.js.map +0 -1
- package/dist/block-tracker-inspector.d.ts.map +0 -1
- package/dist/block-tracker-inspector.js.map +0 -1
- package/dist/fetch.d.ts.map +0 -1
- package/dist/fetch.js.map +0 -1
- package/dist/index.d.ts +0 -17
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -13
- package/dist/index.js.map +0 -1
- package/dist/inflight-cache.d.ts.map +0 -1
- package/dist/inflight-cache.js.map +0 -1
- package/dist/logging-utils.d.ts +0 -4
- package/dist/logging-utils.d.ts.map +0 -1
- package/dist/logging-utils.js +0 -4
- package/dist/logging-utils.js.map +0 -1
- package/dist/methods/wallet-get-granted-execution-permissions.d.ts.map +0 -1
- package/dist/methods/wallet-get-granted-execution-permissions.js.map +0 -1
- package/dist/methods/wallet-get-supported-execution-permissions.d.ts.map +0 -1
- package/dist/methods/wallet-get-supported-execution-permissions.js.map +0 -1
- package/dist/methods/wallet-request-execution-permissions.d.ts.map +0 -1
- package/dist/methods/wallet-request-execution-permissions.js.map +0 -1
- package/dist/methods/wallet-revoke-execution-permission.d.ts.map +0 -1
- package/dist/methods/wallet-revoke-execution-permission.js.map +0 -1
- package/dist/providerAsMiddleware.d.ts.map +0 -1
- package/dist/providerAsMiddleware.js.map +0 -1
- package/dist/retryOnEmpty.d.ts.map +0 -1
- package/dist/retryOnEmpty.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/cache.d.ts.map +0 -1
- package/dist/utils/cache.js.map +0 -1
- package/dist/utils/common.d.ts.map +0 -1
- package/dist/utils/common.js.map +0 -1
- package/dist/utils/error.d.ts.map +0 -1
- package/dist/utils/error.js.map +0 -1
- package/dist/utils/normalize.d.ts.map +0 -1
- package/dist/utils/normalize.js.map +0 -1
- package/dist/utils/structs.d.ts.map +0 -1
- package/dist/utils/structs.js.map +0 -1
- package/dist/utils/timeout.d.ts.map +0 -1
- package/dist/utils/timeout.js.map +0 -1
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/validation.js.map +0 -1
- package/dist/wallet.d.ts.map +0 -1
- 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
|
|
2
|
-
import type { JsonRpcMiddleware, MiddlewareContext } from
|
|
3
|
-
import type { Json, JsonRpcRequest } from
|
|
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.
|
|
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
|
|
14
|
-
import { cacheIdentifierForRequest, blockTagForRequest, cacheTypeForMethod, canCache, CacheStrategy
|
|
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.
|
|
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
|
|
2
|
-
import type { JsonRpcMiddleware } from
|
|
3
|
-
import type { Json, JsonRpcRequest } from
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
2
|
-
import type { InternalProvider } from
|
|
3
|
-
import type { JsonRpcMiddleware } from
|
|
4
|
-
import type { Json, JsonRpcRequest } from
|
|
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.
|
|
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
|
|
2
|
-
import { projectLogger, createModuleLogger } from
|
|
3
|
-
import { blockTagParamIndex } from
|
|
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.
|
|
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
|