@metamask-previews/eth-block-tracker 15.0.1-preview-ec4680201 → 15.0.1-preview-40d5fb1e2
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 -4
- package/dist/PollingBlockTracker.cjs +7 -14
- package/dist/PollingBlockTracker.cjs.map +1 -1
- package/dist/PollingBlockTracker.d.cts.map +1 -1
- package/dist/PollingBlockTracker.d.mts.map +1 -1
- package/dist/PollingBlockTracker.mjs +5 -12
- package/dist/PollingBlockTracker.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -13,10 +13,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
13
|
- Bump `@metamask/json-rpc-engine` from `^10.2.4` to `^10.3.0` ([#8661](https://github.com/MetaMask/core/pull/8661))
|
|
14
14
|
- Bump `@metamask/eth-json-rpc-provider` from `^6.0.0` to `^6.0.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
15
15
|
|
|
16
|
-
### Fixed
|
|
17
|
-
|
|
18
|
-
- Deduplicate concurrent `checkForLatestBlock()` calls so they share a single ongoing request and resolve to the same promise, instead of each issuing its own `eth_blockNumber` request ([#7905](https://github.com/MetaMask/core/pull/7905))
|
|
19
|
-
|
|
20
16
|
## [15.0.1]
|
|
21
17
|
|
|
22
18
|
### Changed
|
|
@@ -13,14 +13,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _PollingBlockTracker_instances, _PollingBlockTracker_isRunning, _PollingBlockTracker_blockResetDuration, _PollingBlockTracker_usePastBlocks, _PollingBlockTracker_currentBlock, _PollingBlockTracker_blockResetTimeout, _PollingBlockTracker_pollingTimeout, _PollingBlockTracker_provider, _PollingBlockTracker_pollingInterval, _PollingBlockTracker_retryTimeout, _PollingBlockTracker_keepEventLoopActive, _PollingBlockTracker_setSkipCacheFlag, _PollingBlockTracker_internalEventListeners, _PollingBlockTracker_pendingLatestBlock, _PollingBlockTracker_pendingFetch,
|
|
16
|
+
var _PollingBlockTracker_instances, _PollingBlockTracker_isRunning, _PollingBlockTracker_blockResetDuration, _PollingBlockTracker_usePastBlocks, _PollingBlockTracker_currentBlock, _PollingBlockTracker_blockResetTimeout, _PollingBlockTracker_pollingTimeout, _PollingBlockTracker_provider, _PollingBlockTracker_pollingInterval, _PollingBlockTracker_retryTimeout, _PollingBlockTracker_keepEventLoopActive, _PollingBlockTracker_setSkipCacheFlag, _PollingBlockTracker_internalEventListeners, _PollingBlockTracker_pendingLatestBlock, _PollingBlockTracker_pendingFetch, _PollingBlockTracker_onNewListener, _PollingBlockTracker_onRemoveListener, _PollingBlockTracker_resetCurrentBlock, _PollingBlockTracker_setupInternalEvents, _PollingBlockTracker_onNewListenerUnbound, _PollingBlockTracker_onRemoveListenerUnbound, _PollingBlockTracker_maybeStart, _PollingBlockTracker_maybeEnd, _PollingBlockTracker_getBlockTrackerEventCount, _PollingBlockTracker_shouldUseNewBlock, _PollingBlockTracker_newPotentialLatest, _PollingBlockTracker_setCurrentBlock, _PollingBlockTracker_setupBlockResetTimeout, _PollingBlockTracker_cancelBlockResetTimeout, _PollingBlockTracker_resetCurrentBlockUnbound, _PollingBlockTracker_start, _PollingBlockTracker_end, _PollingBlockTracker_updateLatestBlock, _PollingBlockTracker_fetchLatestBlock, _PollingBlockTracker_updateAndQueue, _PollingBlockTracker_clearPollingTimeout, _PollingBlockTracker_addInternalListener, _PollingBlockTracker_removeInternalListener, _PollingBlockTracker_rejectPendingLatestBlock;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.PollingBlockTracker = void 0;
|
|
19
19
|
const safe_event_emitter_1 = __importDefault(require("@metamask/safe-event-emitter"));
|
|
20
20
|
const utils_1 = require("@metamask/utils");
|
|
21
21
|
const json_rpc_random_id_1 = __importDefault(require("json-rpc-random-id"));
|
|
22
|
-
const
|
|
23
|
-
const log = (0,
|
|
22
|
+
const logging_utils_1 = require("./logging-utils.cjs");
|
|
23
|
+
const log = (0, logging_utils_1.createModuleLogger)(logging_utils_1.projectLogger, 'polling-block-tracker');
|
|
24
24
|
const createRandomId = (0, json_rpc_random_id_1.default)();
|
|
25
25
|
const sec = 1000;
|
|
26
26
|
const blockTrackerEvents = ['sync', 'latest'];
|
|
@@ -46,7 +46,6 @@ class PollingBlockTracker extends safe_event_emitter_1.default {
|
|
|
46
46
|
_PollingBlockTracker_internalEventListeners.set(this, []);
|
|
47
47
|
_PollingBlockTracker_pendingLatestBlock.set(this, void 0);
|
|
48
48
|
_PollingBlockTracker_pendingFetch.set(this, void 0);
|
|
49
|
-
_PollingBlockTracker_pendingCheckForLatestBlock.set(this, void 0);
|
|
50
49
|
_PollingBlockTracker_onNewListener.set(this, void 0);
|
|
51
50
|
_PollingBlockTracker_onRemoveListener.set(this, void 0);
|
|
52
51
|
_PollingBlockTracker_resetCurrentBlock.set(this, void 0);
|
|
@@ -155,19 +154,13 @@ class PollingBlockTracker extends safe_event_emitter_1.default {
|
|
|
155
154
|
* @deprecated Use {@link getLatestBlock} instead.
|
|
156
155
|
* @returns A promise that resolves to the latest block number.
|
|
157
156
|
*/
|
|
158
|
-
checkForLatestBlock() {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
.then(() => this.getLatestBlock())
|
|
162
|
-
.finally(() => {
|
|
163
|
-
__classPrivateFieldSet(this, _PollingBlockTracker_pendingCheckForLatestBlock, undefined, "f");
|
|
164
|
-
}), "f");
|
|
165
|
-
}
|
|
166
|
-
return __classPrivateFieldGet(this, _PollingBlockTracker_pendingCheckForLatestBlock, "f");
|
|
157
|
+
async checkForLatestBlock() {
|
|
158
|
+
await __classPrivateFieldGet(this, _PollingBlockTracker_instances, "m", _PollingBlockTracker_updateLatestBlock).call(this);
|
|
159
|
+
return await this.getLatestBlock();
|
|
167
160
|
}
|
|
168
161
|
}
|
|
169
162
|
exports.PollingBlockTracker = PollingBlockTracker;
|
|
170
|
-
_PollingBlockTracker_isRunning = new WeakMap(), _PollingBlockTracker_blockResetDuration = new WeakMap(), _PollingBlockTracker_usePastBlocks = new WeakMap(), _PollingBlockTracker_currentBlock = new WeakMap(), _PollingBlockTracker_blockResetTimeout = new WeakMap(), _PollingBlockTracker_pollingTimeout = new WeakMap(), _PollingBlockTracker_provider = new WeakMap(), _PollingBlockTracker_pollingInterval = new WeakMap(), _PollingBlockTracker_retryTimeout = new WeakMap(), _PollingBlockTracker_keepEventLoopActive = new WeakMap(), _PollingBlockTracker_setSkipCacheFlag = new WeakMap(), _PollingBlockTracker_internalEventListeners = new WeakMap(), _PollingBlockTracker_pendingLatestBlock = new WeakMap(), _PollingBlockTracker_pendingFetch = new WeakMap(),
|
|
163
|
+
_PollingBlockTracker_isRunning = new WeakMap(), _PollingBlockTracker_blockResetDuration = new WeakMap(), _PollingBlockTracker_usePastBlocks = new WeakMap(), _PollingBlockTracker_currentBlock = new WeakMap(), _PollingBlockTracker_blockResetTimeout = new WeakMap(), _PollingBlockTracker_pollingTimeout = new WeakMap(), _PollingBlockTracker_provider = new WeakMap(), _PollingBlockTracker_pollingInterval = new WeakMap(), _PollingBlockTracker_retryTimeout = new WeakMap(), _PollingBlockTracker_keepEventLoopActive = new WeakMap(), _PollingBlockTracker_setSkipCacheFlag = new WeakMap(), _PollingBlockTracker_internalEventListeners = new WeakMap(), _PollingBlockTracker_pendingLatestBlock = new WeakMap(), _PollingBlockTracker_pendingFetch = new WeakMap(), _PollingBlockTracker_onNewListener = new WeakMap(), _PollingBlockTracker_onRemoveListener = new WeakMap(), _PollingBlockTracker_resetCurrentBlock = new WeakMap(), _PollingBlockTracker_instances = new WeakSet(), _PollingBlockTracker_setupInternalEvents = function _PollingBlockTracker_setupInternalEvents() {
|
|
171
164
|
// first remove listeners for idempotence
|
|
172
165
|
this.removeListener('newListener', __classPrivateFieldGet(this, _PollingBlockTracker_onNewListener, "f"));
|
|
173
166
|
this.removeListener('removeListener', __classPrivateFieldGet(this, _PollingBlockTracker_onRemoveListener, "f"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PollingBlockTracker.cjs","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type {\n ContextConstraint,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport SafeEventEmitter from '@metamask/safe-event-emitter';\nimport { createDeferredPromise, getErrorMessage } from '@metamask/utils';\nimport type { DeferredPromise, JsonRpcRequest } from '@metamask/utils';\nimport getCreateRandomId from 'json-rpc-random-id';\n\nimport type { BlockTracker } from './BlockTracker.js';\nimport { projectLogger, createModuleLogger } from './logging-utils.js';\n\nconst log = createModuleLogger(projectLogger, 'polling-block-tracker');\nconst createRandomId = getCreateRandomId();\nconst sec = 1000;\n\nconst blockTrackerEvents: (string | symbol)[] = ['sync', 'latest'];\n\nexport type PollingBlockTrackerOptions<\n Context extends ContextConstraint = MiddlewareContext,\n> = {\n provider?: InternalProvider<Context>;\n pollingInterval?: number;\n retryTimeout?: number;\n keepEventLoopActive?: boolean;\n setSkipCacheFlag?: boolean;\n blockResetDuration?: number;\n usePastBlocks?: boolean;\n};\n\ntype ExtendedJsonRpcRequest = {\n skipCache?: boolean;\n} & JsonRpcRequest<[]>;\n\ntype InternalListener = (value: string) => void;\n\nexport class PollingBlockTracker<\n Context extends ContextConstraint = MiddlewareContext,\n>\n extends SafeEventEmitter\n implements BlockTracker\n{\n #isRunning: boolean;\n\n readonly #blockResetDuration: number;\n\n readonly #usePastBlocks: boolean;\n\n #currentBlock: string | null;\n\n #blockResetTimeout?: ReturnType<typeof setTimeout>;\n\n #pollingTimeout?: ReturnType<typeof setTimeout>;\n\n readonly #provider: InternalProvider<Context>;\n\n readonly #pollingInterval: number;\n\n readonly #retryTimeout: number;\n\n readonly #keepEventLoopActive: boolean;\n\n readonly #setSkipCacheFlag: boolean;\n\n readonly #internalEventListeners: InternalListener[] = [];\n\n #pendingLatestBlock?: Omit<DeferredPromise<string>, 'resolve'>;\n\n #pendingFetch?: Omit<DeferredPromise<string>, 'resolve'>;\n\n #pendingCheckForLatestBlock?: Promise<string>;\n\n readonly #onNewListener: (eventName: string | symbol) => void;\n\n readonly #onRemoveListener: () => void;\n\n readonly #resetCurrentBlock: () => void;\n\n constructor(opts: PollingBlockTrackerOptions<Context> = {}) {\n // parse + validate args\n if (!opts.provider) {\n throw new Error('PollingBlockTracker - no provider specified.');\n }\n\n super();\n\n // config\n this.#blockResetDuration = opts.blockResetDuration ?? 20 * sec;\n this.#usePastBlocks = opts.usePastBlocks ?? false;\n // state\n this.#currentBlock = null;\n this.#isRunning = false;\n\n // bind functions for internal use\n this.#onNewListener = this.#onNewListenerUnbound.bind(this);\n this.#onRemoveListener = this.#onRemoveListenerUnbound.bind(this);\n this.#resetCurrentBlock = this.#resetCurrentBlockUnbound.bind(this);\n\n // listen for handler changes\n this.#setupInternalEvents();\n\n // config\n this.#provider = opts.provider;\n this.#pollingInterval = opts.pollingInterval ?? 20 * sec;\n this.#retryTimeout = opts.retryTimeout ?? this.#pollingInterval / 10;\n this.#keepEventLoopActive = opts.keepEventLoopActive ?? true;\n this.#setSkipCacheFlag = opts.setSkipCacheFlag ?? false;\n }\n\n async destroy(): Promise<void> {\n this.#cancelBlockResetTimeout();\n super.removeAllListeners();\n this.#maybeEnd();\n }\n\n isRunning(): boolean {\n return this.#isRunning;\n }\n\n getCurrentBlock(): string | null {\n return this.#currentBlock;\n }\n\n async getLatestBlock({\n useCache = true,\n }: { useCache?: boolean } = {}): Promise<string> {\n // return if available\n if (this.#currentBlock && useCache) {\n return this.#currentBlock;\n }\n\n if (this.#pendingLatestBlock) {\n return await this.#pendingLatestBlock.promise;\n }\n\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingLatestBlock = { reject, promise };\n\n if (this.#isRunning) {\n try {\n // If tracker is running, wait for next block with timeout\n const onLatestBlock = (value: string): void => {\n this.#removeInternalListener(onLatestBlock);\n this.removeListener('latest', onLatestBlock);\n resolve(value);\n };\n\n this.#addInternalListener(onLatestBlock);\n this.once('latest', onLatestBlock);\n\n return await promise;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n this.#pendingLatestBlock = undefined;\n }\n } else {\n // If tracker isn't running, just fetch directly\n try {\n const latestBlock = await this.#updateLatestBlock();\n resolve(latestBlock);\n return latestBlock;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n // We want to rate limit calls to this method if we made a direct fetch\n // for the block number because the BlockTracker was not running. We\n // achieve this by delaying the unsetting of the #pendingLatestBlock promise.\n setTimeout(() => {\n this.#pendingLatestBlock = undefined;\n }, this.#pollingInterval);\n }\n }\n }\n\n // Don't allow module consumer to remove our internal event listeners.\n removeAllListeners(eventName?: string | symbol): this {\n // perform default behavior, preserve fn arity\n if (eventName) {\n super.removeAllListeners(eventName);\n } else {\n super.removeAllListeners();\n }\n\n // re-add internal events\n this.#setupInternalEvents();\n // trigger stop check just in case\n this.#onRemoveListener();\n\n return this;\n }\n\n #setupInternalEvents(): void {\n // first remove listeners for idempotence\n this.removeListener('newListener', this.#onNewListener);\n this.removeListener('removeListener', this.#onRemoveListener);\n // then add them\n this.on('newListener', this.#onNewListener);\n this.on('removeListener', this.#onRemoveListener);\n }\n\n #onNewListenerUnbound(eventName: string | symbol): void {\n // `newListener` is called *before* the listener is added\n if (blockTrackerEvents.includes(eventName)) {\n // TODO: Handle dangling promise\n this.#maybeStart();\n }\n }\n\n #onRemoveListenerUnbound(): void {\n // `removeListener` is called *after* the listener is removed\n if (this.#getBlockTrackerEventCount() > 0) {\n return;\n }\n this.#maybeEnd();\n }\n\n #maybeStart(): void {\n if (this.#isRunning) {\n return;\n }\n\n this.#isRunning = true;\n // cancel setting latest block to stale\n this.#cancelBlockResetTimeout();\n this.#start();\n this.emit('_started');\n }\n\n #maybeEnd(): void {\n if (!this.#isRunning) {\n return;\n }\n\n this.#isRunning = false;\n this.#setupBlockResetTimeout();\n this.#end();\n this.#rejectPendingLatestBlock(new Error('Block tracker destroyed'));\n this.emit('_ended');\n }\n\n #getBlockTrackerEventCount(): number {\n return (\n blockTrackerEvents\n .map((eventName) => this.listeners(eventName))\n .flat()\n // internal listeners are not included in the count\n .filter((listener) =>\n this.#internalEventListeners.every(\n (internalListener) => !Object.is(internalListener, listener),\n ),\n ).length\n );\n }\n\n #shouldUseNewBlock(newBlock: string): boolean {\n const currentBlock = this.#currentBlock;\n if (!currentBlock) {\n return true;\n }\n const newBlockInt = hexToInt(newBlock);\n const currentBlockInt = hexToInt(currentBlock);\n\n return (\n (this.#usePastBlocks && newBlockInt < currentBlockInt) ||\n newBlockInt > currentBlockInt\n );\n }\n\n #newPotentialLatest(newBlock: string): void {\n if (!this.#shouldUseNewBlock(newBlock)) {\n return;\n }\n this.#setCurrentBlock(newBlock);\n }\n\n #setCurrentBlock(newBlock: string): void {\n const oldBlock = this.#currentBlock;\n this.#currentBlock = newBlock;\n this.emit('latest', newBlock);\n this.emit('sync', { oldBlock, newBlock });\n }\n\n #setupBlockResetTimeout(): void {\n // clear any existing timeout\n this.#cancelBlockResetTimeout();\n // clear latest block when stale\n this.#blockResetTimeout = setTimeout(\n this.#resetCurrentBlock,\n this.#blockResetDuration,\n );\n\n // nodejs - dont hold process open\n if (this.#blockResetTimeout.unref) {\n this.#blockResetTimeout.unref();\n }\n }\n\n #cancelBlockResetTimeout(): void {\n if (this.#blockResetTimeout) {\n clearTimeout(this.#blockResetTimeout);\n }\n }\n\n #resetCurrentBlockUnbound(): void {\n this.#currentBlock = null;\n }\n\n /**\n * Checks for the latest block, updates the internal state, and returns the\n * value immediately rather than waiting for the next polling interval.\n *\n * @deprecated Use {@link getLatestBlock} instead.\n * @returns A promise that resolves to the latest block number.\n */\n checkForLatestBlock(): Promise<string> {\n if (!this.#pendingCheckForLatestBlock) {\n this.#pendingCheckForLatestBlock = this.#updateLatestBlock()\n .then(() => this.getLatestBlock())\n .finally(() => {\n this.#pendingCheckForLatestBlock = undefined;\n });\n }\n return this.#pendingCheckForLatestBlock;\n }\n\n #start(): void {\n // Intentionally not awaited as this starts the polling via a timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }\n\n #end(): void {\n this.#clearPollingTimeout();\n }\n\n async #updateLatestBlock(): Promise<string> {\n // fetch + set latest block\n const latestBlock = await this.#fetchLatestBlock();\n this.#newPotentialLatest(latestBlock);\n\n if (!this.#isRunning) {\n // Ensure the one-time update is eventually reset once it's stale\n this.#setupBlockResetTimeout();\n }\n\n // _newPotentialLatest() ensures that this._currentBlock is not null\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#currentBlock!;\n }\n\n async #fetchLatestBlock(): Promise<string> {\n // If there's already a pending fetch, reuse it\n if (this.#pendingFetch) {\n return await this.#pendingFetch.promise;\n }\n\n // Create a new deferred promise for this request\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingFetch = { reject, promise };\n\n try {\n const req: ExtendedJsonRpcRequest = {\n jsonrpc: '2.0',\n id: createRandomId(),\n method: 'eth_blockNumber',\n params: [] as [],\n };\n if (this.#setSkipCacheFlag) {\n req.skipCache = true;\n }\n\n log('Making request', req);\n const result = await this.#provider.request<[], string>(req);\n log('Got result', result);\n resolve(result);\n return result;\n } catch (error) {\n log('Encountered error fetching block', getErrorMessage(error));\n reject(error);\n this.#rejectPendingLatestBlock(error);\n throw error;\n } finally {\n this.#pendingFetch = undefined;\n }\n }\n\n /**\n * The core polling function that runs after each interval.\n * Updates the latest block and then queues the next update.\n */\n async #updateAndQueue(): Promise<void> {\n let interval = this.#pollingInterval;\n\n try {\n await this.#updateLatestBlock();\n } catch (error: unknown) {\n try {\n this.emit('error', error);\n } catch {\n console.error(`Error updating latest block: ${getErrorMessage(error)}`);\n }\n\n interval = this.#retryTimeout;\n }\n\n if (!this.#isRunning) {\n return;\n }\n\n this.#clearPollingTimeout();\n\n const timeoutRef = setTimeout(() => {\n // Intentionally not awaited as this just continues the polling loop.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }, interval);\n\n if (timeoutRef.unref && !this.#keepEventLoopActive) {\n timeoutRef.unref();\n }\n\n this.#pollingTimeout = timeoutRef;\n\n this.emit('_waitingForNextIteration');\n }\n\n #clearPollingTimeout(): void {\n if (this.#pollingTimeout) {\n clearTimeout(this.#pollingTimeout);\n this.#pollingTimeout = undefined;\n }\n }\n\n #addInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.push(listener);\n }\n\n #removeInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.splice(\n this.#internalEventListeners.indexOf(listener),\n 1,\n );\n }\n\n #rejectPendingLatestBlock(error: unknown): void {\n this.#pendingLatestBlock?.reject(error);\n this.#pendingLatestBlock = undefined;\n }\n}\n\n/**\n * Converts a number represented as a string in hexadecimal format into a native\n * number.\n *\n * @param hexInt - The hex string.\n * @returns The number.\n */\nfunction hexToInt(hexInt: string): number {\n return Number.parseInt(hexInt, 16);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PollingBlockTracker.cjs","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type {\n ContextConstraint,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport SafeEventEmitter from '@metamask/safe-event-emitter';\nimport { createDeferredPromise, getErrorMessage } from '@metamask/utils';\nimport type { DeferredPromise, JsonRpcRequest } from '@metamask/utils';\nimport getCreateRandomId from 'json-rpc-random-id';\n\nimport type { BlockTracker } from './BlockTracker';\nimport { projectLogger, createModuleLogger } from './logging-utils';\n\nconst log = createModuleLogger(projectLogger, 'polling-block-tracker');\nconst createRandomId = getCreateRandomId();\nconst sec = 1000;\n\nconst blockTrackerEvents: (string | symbol)[] = ['sync', 'latest'];\n\nexport type PollingBlockTrackerOptions<\n Context extends ContextConstraint = MiddlewareContext,\n> = {\n provider?: InternalProvider<Context>;\n pollingInterval?: number;\n retryTimeout?: number;\n keepEventLoopActive?: boolean;\n setSkipCacheFlag?: boolean;\n blockResetDuration?: number;\n usePastBlocks?: boolean;\n};\n\ntype ExtendedJsonRpcRequest = {\n skipCache?: boolean;\n} & JsonRpcRequest<[]>;\n\ntype InternalListener = (value: string) => void;\n\nexport class PollingBlockTracker<\n Context extends ContextConstraint = MiddlewareContext,\n>\n extends SafeEventEmitter\n implements BlockTracker\n{\n #isRunning: boolean;\n\n readonly #blockResetDuration: number;\n\n readonly #usePastBlocks: boolean;\n\n #currentBlock: string | null;\n\n #blockResetTimeout?: ReturnType<typeof setTimeout>;\n\n #pollingTimeout?: ReturnType<typeof setTimeout>;\n\n readonly #provider: InternalProvider<Context>;\n\n readonly #pollingInterval: number;\n\n readonly #retryTimeout: number;\n\n readonly #keepEventLoopActive: boolean;\n\n readonly #setSkipCacheFlag: boolean;\n\n readonly #internalEventListeners: InternalListener[] = [];\n\n #pendingLatestBlock?: Omit<DeferredPromise<string>, 'resolve'>;\n\n #pendingFetch?: Omit<DeferredPromise<string>, 'resolve'>;\n\n readonly #onNewListener: (eventName: string | symbol) => void;\n\n readonly #onRemoveListener: () => void;\n\n readonly #resetCurrentBlock: () => void;\n\n constructor(opts: PollingBlockTrackerOptions<Context> = {}) {\n // parse + validate args\n if (!opts.provider) {\n throw new Error('PollingBlockTracker - no provider specified.');\n }\n\n super();\n\n // config\n this.#blockResetDuration = opts.blockResetDuration ?? 20 * sec;\n this.#usePastBlocks = opts.usePastBlocks ?? false;\n // state\n this.#currentBlock = null;\n this.#isRunning = false;\n\n // bind functions for internal use\n this.#onNewListener = this.#onNewListenerUnbound.bind(this);\n this.#onRemoveListener = this.#onRemoveListenerUnbound.bind(this);\n this.#resetCurrentBlock = this.#resetCurrentBlockUnbound.bind(this);\n\n // listen for handler changes\n this.#setupInternalEvents();\n\n // config\n this.#provider = opts.provider;\n this.#pollingInterval = opts.pollingInterval ?? 20 * sec;\n this.#retryTimeout = opts.retryTimeout ?? this.#pollingInterval / 10;\n this.#keepEventLoopActive = opts.keepEventLoopActive ?? true;\n this.#setSkipCacheFlag = opts.setSkipCacheFlag ?? false;\n }\n\n async destroy(): Promise<void> {\n this.#cancelBlockResetTimeout();\n super.removeAllListeners();\n this.#maybeEnd();\n }\n\n isRunning(): boolean {\n return this.#isRunning;\n }\n\n getCurrentBlock(): string | null {\n return this.#currentBlock;\n }\n\n async getLatestBlock({\n useCache = true,\n }: { useCache?: boolean } = {}): Promise<string> {\n // return if available\n if (this.#currentBlock && useCache) {\n return this.#currentBlock;\n }\n\n if (this.#pendingLatestBlock) {\n return await this.#pendingLatestBlock.promise;\n }\n\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingLatestBlock = { reject, promise };\n\n if (this.#isRunning) {\n try {\n // If tracker is running, wait for next block with timeout\n const onLatestBlock = (value: string): void => {\n this.#removeInternalListener(onLatestBlock);\n this.removeListener('latest', onLatestBlock);\n resolve(value);\n };\n\n this.#addInternalListener(onLatestBlock);\n this.once('latest', onLatestBlock);\n\n return await promise;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n this.#pendingLatestBlock = undefined;\n }\n } else {\n // If tracker isn't running, just fetch directly\n try {\n const latestBlock = await this.#updateLatestBlock();\n resolve(latestBlock);\n return latestBlock;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n // We want to rate limit calls to this method if we made a direct fetch\n // for the block number because the BlockTracker was not running. We\n // achieve this by delaying the unsetting of the #pendingLatestBlock promise.\n setTimeout(() => {\n this.#pendingLatestBlock = undefined;\n }, this.#pollingInterval);\n }\n }\n }\n\n // Don't allow module consumer to remove our internal event listeners.\n removeAllListeners(eventName?: string | symbol): this {\n // perform default behavior, preserve fn arity\n if (eventName) {\n super.removeAllListeners(eventName);\n } else {\n super.removeAllListeners();\n }\n\n // re-add internal events\n this.#setupInternalEvents();\n // trigger stop check just in case\n this.#onRemoveListener();\n\n return this;\n }\n\n #setupInternalEvents(): void {\n // first remove listeners for idempotence\n this.removeListener('newListener', this.#onNewListener);\n this.removeListener('removeListener', this.#onRemoveListener);\n // then add them\n this.on('newListener', this.#onNewListener);\n this.on('removeListener', this.#onRemoveListener);\n }\n\n #onNewListenerUnbound(eventName: string | symbol): void {\n // `newListener` is called *before* the listener is added\n if (blockTrackerEvents.includes(eventName)) {\n // TODO: Handle dangling promise\n this.#maybeStart();\n }\n }\n\n #onRemoveListenerUnbound(): void {\n // `removeListener` is called *after* the listener is removed\n if (this.#getBlockTrackerEventCount() > 0) {\n return;\n }\n this.#maybeEnd();\n }\n\n #maybeStart(): void {\n if (this.#isRunning) {\n return;\n }\n\n this.#isRunning = true;\n // cancel setting latest block to stale\n this.#cancelBlockResetTimeout();\n this.#start();\n this.emit('_started');\n }\n\n #maybeEnd(): void {\n if (!this.#isRunning) {\n return;\n }\n\n this.#isRunning = false;\n this.#setupBlockResetTimeout();\n this.#end();\n this.#rejectPendingLatestBlock(new Error('Block tracker destroyed'));\n this.emit('_ended');\n }\n\n #getBlockTrackerEventCount(): number {\n return (\n blockTrackerEvents\n .map((eventName) => this.listeners(eventName))\n .flat()\n // internal listeners are not included in the count\n .filter((listener) =>\n this.#internalEventListeners.every(\n (internalListener) => !Object.is(internalListener, listener),\n ),\n ).length\n );\n }\n\n #shouldUseNewBlock(newBlock: string): boolean {\n const currentBlock = this.#currentBlock;\n if (!currentBlock) {\n return true;\n }\n const newBlockInt = hexToInt(newBlock);\n const currentBlockInt = hexToInt(currentBlock);\n\n return (\n (this.#usePastBlocks && newBlockInt < currentBlockInt) ||\n newBlockInt > currentBlockInt\n );\n }\n\n #newPotentialLatest(newBlock: string): void {\n if (!this.#shouldUseNewBlock(newBlock)) {\n return;\n }\n this.#setCurrentBlock(newBlock);\n }\n\n #setCurrentBlock(newBlock: string): void {\n const oldBlock = this.#currentBlock;\n this.#currentBlock = newBlock;\n this.emit('latest', newBlock);\n this.emit('sync', { oldBlock, newBlock });\n }\n\n #setupBlockResetTimeout(): void {\n // clear any existing timeout\n this.#cancelBlockResetTimeout();\n // clear latest block when stale\n this.#blockResetTimeout = setTimeout(\n this.#resetCurrentBlock,\n this.#blockResetDuration,\n );\n\n // nodejs - dont hold process open\n if (this.#blockResetTimeout.unref) {\n this.#blockResetTimeout.unref();\n }\n }\n\n #cancelBlockResetTimeout(): void {\n if (this.#blockResetTimeout) {\n clearTimeout(this.#blockResetTimeout);\n }\n }\n\n #resetCurrentBlockUnbound(): void {\n this.#currentBlock = null;\n }\n\n /**\n * Checks for the latest block, updates the internal state, and returns the\n * value immediately rather than waiting for the next polling interval.\n *\n * @deprecated Use {@link getLatestBlock} instead.\n * @returns A promise that resolves to the latest block number.\n */\n async checkForLatestBlock(): Promise<string> {\n await this.#updateLatestBlock();\n return await this.getLatestBlock();\n }\n\n #start(): void {\n // Intentionally not awaited as this starts the polling via a timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }\n\n #end(): void {\n this.#clearPollingTimeout();\n }\n\n async #updateLatestBlock(): Promise<string> {\n // fetch + set latest block\n const latestBlock = await this.#fetchLatestBlock();\n this.#newPotentialLatest(latestBlock);\n\n if (!this.#isRunning) {\n // Ensure the one-time update is eventually reset once it's stale\n this.#setupBlockResetTimeout();\n }\n\n // _newPotentialLatest() ensures that this._currentBlock is not null\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#currentBlock!;\n }\n\n async #fetchLatestBlock(): Promise<string> {\n // If there's already a pending fetch, reuse it\n if (this.#pendingFetch) {\n return await this.#pendingFetch.promise;\n }\n\n // Create a new deferred promise for this request\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingFetch = { reject, promise };\n\n try {\n const req: ExtendedJsonRpcRequest = {\n jsonrpc: '2.0',\n id: createRandomId(),\n method: 'eth_blockNumber',\n params: [] as [],\n };\n if (this.#setSkipCacheFlag) {\n req.skipCache = true;\n }\n\n log('Making request', req);\n const result = await this.#provider.request<[], string>(req);\n log('Got result', result);\n resolve(result);\n return result;\n } catch (error) {\n log('Encountered error fetching block', getErrorMessage(error));\n reject(error);\n this.#rejectPendingLatestBlock(error);\n throw error;\n } finally {\n this.#pendingFetch = undefined;\n }\n }\n\n /**\n * The core polling function that runs after each interval.\n * Updates the latest block and then queues the next update.\n */\n async #updateAndQueue(): Promise<void> {\n let interval = this.#pollingInterval;\n\n try {\n await this.#updateLatestBlock();\n } catch (error: unknown) {\n try {\n this.emit('error', error);\n } catch {\n console.error(`Error updating latest block: ${getErrorMessage(error)}`);\n }\n\n interval = this.#retryTimeout;\n }\n\n if (!this.#isRunning) {\n return;\n }\n\n this.#clearPollingTimeout();\n\n const timeoutRef = setTimeout(() => {\n // Intentionally not awaited as this just continues the polling loop.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }, interval);\n\n if (timeoutRef.unref && !this.#keepEventLoopActive) {\n timeoutRef.unref();\n }\n\n this.#pollingTimeout = timeoutRef;\n\n this.emit('_waitingForNextIteration');\n }\n\n #clearPollingTimeout(): void {\n if (this.#pollingTimeout) {\n clearTimeout(this.#pollingTimeout);\n this.#pollingTimeout = undefined;\n }\n }\n\n #addInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.push(listener);\n }\n\n #removeInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.splice(\n this.#internalEventListeners.indexOf(listener),\n 1,\n );\n }\n\n #rejectPendingLatestBlock(error: unknown): void {\n this.#pendingLatestBlock?.reject(error);\n this.#pendingLatestBlock = undefined;\n }\n}\n\n/**\n * Converts a number represented as a string in hexadecimal format into a native\n * number.\n *\n * @param hexInt - The hex string.\n * @returns The number.\n */\nfunction hexToInt(hexInt: string): number {\n return Number.parseInt(hexInt, 16);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PollingBlockTracker.d.cts","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wCAAwC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,qCAAqC;AACtC,OAAO,gBAAgB,qCAAqC;AAK5D,OAAO,KAAK,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"PollingBlockTracker.d.cts","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wCAAwC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,qCAAqC;AACtC,OAAO,gBAAgB,qCAAqC;AAK5D,OAAO,KAAK,EAAE,YAAY,EAAE,2BAAuB;AASnD,MAAM,MAAM,0BAA0B,CACpC,OAAO,SAAS,iBAAiB,GAAG,iBAAiB,IACnD;IACF,QAAQ,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAQF,qBAAa,mBAAmB,CAC9B,OAAO,SAAS,iBAAiB,GAAG,iBAAiB,CAErD,SAAQ,gBACR,YAAW,YAAY;;gBAoCX,IAAI,GAAE,0BAA0B,CAAC,OAAO,CAAM;IA+BpD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,SAAS,IAAI,OAAO;IAIpB,eAAe,IAAI,MAAM,GAAG,IAAI;IAI1B,cAAc,CAAC,EACnB,QAAe,GAChB,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAuDhD,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAoIrD;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;CAkI7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PollingBlockTracker.d.mts","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wCAAwC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,qCAAqC;AACtC,OAAO,gBAAgB,qCAAqC;AAK5D,OAAO,KAAK,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"PollingBlockTracker.d.mts","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wCAAwC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,qCAAqC;AACtC,OAAO,gBAAgB,qCAAqC;AAK5D,OAAO,KAAK,EAAE,YAAY,EAAE,2BAAuB;AASnD,MAAM,MAAM,0BAA0B,CACpC,OAAO,SAAS,iBAAiB,GAAG,iBAAiB,IACnD;IACF,QAAQ,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAQF,qBAAa,mBAAmB,CAC9B,OAAO,SAAS,iBAAiB,GAAG,iBAAiB,CAErD,SAAQ,gBACR,YAAW,YAAY;;gBAoCX,IAAI,GAAE,0BAA0B,CAAC,OAAO,CAAM;IA+BpD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,SAAS,IAAI,OAAO;IAIpB,eAAe,IAAI,MAAM,GAAG,IAAI;IAI1B,cAAc,CAAC,EACnB,QAAe,GAChB,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAuDhD,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAoIrD;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;CAkI7C"}
|
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _PollingBlockTracker_instances, _PollingBlockTracker_isRunning, _PollingBlockTracker_blockResetDuration, _PollingBlockTracker_usePastBlocks, _PollingBlockTracker_currentBlock, _PollingBlockTracker_blockResetTimeout, _PollingBlockTracker_pollingTimeout, _PollingBlockTracker_provider, _PollingBlockTracker_pollingInterval, _PollingBlockTracker_retryTimeout, _PollingBlockTracker_keepEventLoopActive, _PollingBlockTracker_setSkipCacheFlag, _PollingBlockTracker_internalEventListeners, _PollingBlockTracker_pendingLatestBlock, _PollingBlockTracker_pendingFetch,
|
|
12
|
+
var _PollingBlockTracker_instances, _PollingBlockTracker_isRunning, _PollingBlockTracker_blockResetDuration, _PollingBlockTracker_usePastBlocks, _PollingBlockTracker_currentBlock, _PollingBlockTracker_blockResetTimeout, _PollingBlockTracker_pollingTimeout, _PollingBlockTracker_provider, _PollingBlockTracker_pollingInterval, _PollingBlockTracker_retryTimeout, _PollingBlockTracker_keepEventLoopActive, _PollingBlockTracker_setSkipCacheFlag, _PollingBlockTracker_internalEventListeners, _PollingBlockTracker_pendingLatestBlock, _PollingBlockTracker_pendingFetch, _PollingBlockTracker_onNewListener, _PollingBlockTracker_onRemoveListener, _PollingBlockTracker_resetCurrentBlock, _PollingBlockTracker_setupInternalEvents, _PollingBlockTracker_onNewListenerUnbound, _PollingBlockTracker_onRemoveListenerUnbound, _PollingBlockTracker_maybeStart, _PollingBlockTracker_maybeEnd, _PollingBlockTracker_getBlockTrackerEventCount, _PollingBlockTracker_shouldUseNewBlock, _PollingBlockTracker_newPotentialLatest, _PollingBlockTracker_setCurrentBlock, _PollingBlockTracker_setupBlockResetTimeout, _PollingBlockTracker_cancelBlockResetTimeout, _PollingBlockTracker_resetCurrentBlockUnbound, _PollingBlockTracker_start, _PollingBlockTracker_end, _PollingBlockTracker_updateLatestBlock, _PollingBlockTracker_fetchLatestBlock, _PollingBlockTracker_updateAndQueue, _PollingBlockTracker_clearPollingTimeout, _PollingBlockTracker_addInternalListener, _PollingBlockTracker_removeInternalListener, _PollingBlockTracker_rejectPendingLatestBlock;
|
|
13
13
|
function $importDefault(module) {
|
|
14
14
|
if (module?.__esModule) {
|
|
15
15
|
return module.default;
|
|
@@ -47,7 +47,6 @@ export class PollingBlockTracker extends SafeEventEmitter {
|
|
|
47
47
|
_PollingBlockTracker_internalEventListeners.set(this, []);
|
|
48
48
|
_PollingBlockTracker_pendingLatestBlock.set(this, void 0);
|
|
49
49
|
_PollingBlockTracker_pendingFetch.set(this, void 0);
|
|
50
|
-
_PollingBlockTracker_pendingCheckForLatestBlock.set(this, void 0);
|
|
51
50
|
_PollingBlockTracker_onNewListener.set(this, void 0);
|
|
52
51
|
_PollingBlockTracker_onRemoveListener.set(this, void 0);
|
|
53
52
|
_PollingBlockTracker_resetCurrentBlock.set(this, void 0);
|
|
@@ -156,18 +155,12 @@ export class PollingBlockTracker extends SafeEventEmitter {
|
|
|
156
155
|
* @deprecated Use {@link getLatestBlock} instead.
|
|
157
156
|
* @returns A promise that resolves to the latest block number.
|
|
158
157
|
*/
|
|
159
|
-
checkForLatestBlock() {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
.then(() => this.getLatestBlock())
|
|
163
|
-
.finally(() => {
|
|
164
|
-
__classPrivateFieldSet(this, _PollingBlockTracker_pendingCheckForLatestBlock, undefined, "f");
|
|
165
|
-
}), "f");
|
|
166
|
-
}
|
|
167
|
-
return __classPrivateFieldGet(this, _PollingBlockTracker_pendingCheckForLatestBlock, "f");
|
|
158
|
+
async checkForLatestBlock() {
|
|
159
|
+
await __classPrivateFieldGet(this, _PollingBlockTracker_instances, "m", _PollingBlockTracker_updateLatestBlock).call(this);
|
|
160
|
+
return await this.getLatestBlock();
|
|
168
161
|
}
|
|
169
162
|
}
|
|
170
|
-
_PollingBlockTracker_isRunning = new WeakMap(), _PollingBlockTracker_blockResetDuration = new WeakMap(), _PollingBlockTracker_usePastBlocks = new WeakMap(), _PollingBlockTracker_currentBlock = new WeakMap(), _PollingBlockTracker_blockResetTimeout = new WeakMap(), _PollingBlockTracker_pollingTimeout = new WeakMap(), _PollingBlockTracker_provider = new WeakMap(), _PollingBlockTracker_pollingInterval = new WeakMap(), _PollingBlockTracker_retryTimeout = new WeakMap(), _PollingBlockTracker_keepEventLoopActive = new WeakMap(), _PollingBlockTracker_setSkipCacheFlag = new WeakMap(), _PollingBlockTracker_internalEventListeners = new WeakMap(), _PollingBlockTracker_pendingLatestBlock = new WeakMap(), _PollingBlockTracker_pendingFetch = new WeakMap(),
|
|
163
|
+
_PollingBlockTracker_isRunning = new WeakMap(), _PollingBlockTracker_blockResetDuration = new WeakMap(), _PollingBlockTracker_usePastBlocks = new WeakMap(), _PollingBlockTracker_currentBlock = new WeakMap(), _PollingBlockTracker_blockResetTimeout = new WeakMap(), _PollingBlockTracker_pollingTimeout = new WeakMap(), _PollingBlockTracker_provider = new WeakMap(), _PollingBlockTracker_pollingInterval = new WeakMap(), _PollingBlockTracker_retryTimeout = new WeakMap(), _PollingBlockTracker_keepEventLoopActive = new WeakMap(), _PollingBlockTracker_setSkipCacheFlag = new WeakMap(), _PollingBlockTracker_internalEventListeners = new WeakMap(), _PollingBlockTracker_pendingLatestBlock = new WeakMap(), _PollingBlockTracker_pendingFetch = new WeakMap(), _PollingBlockTracker_onNewListener = new WeakMap(), _PollingBlockTracker_onRemoveListener = new WeakMap(), _PollingBlockTracker_resetCurrentBlock = new WeakMap(), _PollingBlockTracker_instances = new WeakSet(), _PollingBlockTracker_setupInternalEvents = function _PollingBlockTracker_setupInternalEvents() {
|
|
171
164
|
// first remove listeners for idempotence
|
|
172
165
|
this.removeListener('newListener', __classPrivateFieldGet(this, _PollingBlockTracker_onNewListener, "f"));
|
|
173
166
|
this.removeListener('removeListener', __classPrivateFieldGet(this, _PollingBlockTracker_onRemoveListener, "f"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PollingBlockTracker.mjs","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type {\n ContextConstraint,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport SafeEventEmitter from '@metamask/safe-event-emitter';\nimport { createDeferredPromise, getErrorMessage } from '@metamask/utils';\nimport type { DeferredPromise, JsonRpcRequest } from '@metamask/utils';\nimport getCreateRandomId from 'json-rpc-random-id';\n\nimport type { BlockTracker } from './BlockTracker.js';\nimport { projectLogger, createModuleLogger } from './logging-utils.js';\n\nconst log = createModuleLogger(projectLogger, 'polling-block-tracker');\nconst createRandomId = getCreateRandomId();\nconst sec = 1000;\n\nconst blockTrackerEvents: (string | symbol)[] = ['sync', 'latest'];\n\nexport type PollingBlockTrackerOptions<\n Context extends ContextConstraint = MiddlewareContext,\n> = {\n provider?: InternalProvider<Context>;\n pollingInterval?: number;\n retryTimeout?: number;\n keepEventLoopActive?: boolean;\n setSkipCacheFlag?: boolean;\n blockResetDuration?: number;\n usePastBlocks?: boolean;\n};\n\ntype ExtendedJsonRpcRequest = {\n skipCache?: boolean;\n} & JsonRpcRequest<[]>;\n\ntype InternalListener = (value: string) => void;\n\nexport class PollingBlockTracker<\n Context extends ContextConstraint = MiddlewareContext,\n>\n extends SafeEventEmitter\n implements BlockTracker\n{\n #isRunning: boolean;\n\n readonly #blockResetDuration: number;\n\n readonly #usePastBlocks: boolean;\n\n #currentBlock: string | null;\n\n #blockResetTimeout?: ReturnType<typeof setTimeout>;\n\n #pollingTimeout?: ReturnType<typeof setTimeout>;\n\n readonly #provider: InternalProvider<Context>;\n\n readonly #pollingInterval: number;\n\n readonly #retryTimeout: number;\n\n readonly #keepEventLoopActive: boolean;\n\n readonly #setSkipCacheFlag: boolean;\n\n readonly #internalEventListeners: InternalListener[] = [];\n\n #pendingLatestBlock?: Omit<DeferredPromise<string>, 'resolve'>;\n\n #pendingFetch?: Omit<DeferredPromise<string>, 'resolve'>;\n\n #pendingCheckForLatestBlock?: Promise<string>;\n\n readonly #onNewListener: (eventName: string | symbol) => void;\n\n readonly #onRemoveListener: () => void;\n\n readonly #resetCurrentBlock: () => void;\n\n constructor(opts: PollingBlockTrackerOptions<Context> = {}) {\n // parse + validate args\n if (!opts.provider) {\n throw new Error('PollingBlockTracker - no provider specified.');\n }\n\n super();\n\n // config\n this.#blockResetDuration = opts.blockResetDuration ?? 20 * sec;\n this.#usePastBlocks = opts.usePastBlocks ?? false;\n // state\n this.#currentBlock = null;\n this.#isRunning = false;\n\n // bind functions for internal use\n this.#onNewListener = this.#onNewListenerUnbound.bind(this);\n this.#onRemoveListener = this.#onRemoveListenerUnbound.bind(this);\n this.#resetCurrentBlock = this.#resetCurrentBlockUnbound.bind(this);\n\n // listen for handler changes\n this.#setupInternalEvents();\n\n // config\n this.#provider = opts.provider;\n this.#pollingInterval = opts.pollingInterval ?? 20 * sec;\n this.#retryTimeout = opts.retryTimeout ?? this.#pollingInterval / 10;\n this.#keepEventLoopActive = opts.keepEventLoopActive ?? true;\n this.#setSkipCacheFlag = opts.setSkipCacheFlag ?? false;\n }\n\n async destroy(): Promise<void> {\n this.#cancelBlockResetTimeout();\n super.removeAllListeners();\n this.#maybeEnd();\n }\n\n isRunning(): boolean {\n return this.#isRunning;\n }\n\n getCurrentBlock(): string | null {\n return this.#currentBlock;\n }\n\n async getLatestBlock({\n useCache = true,\n }: { useCache?: boolean } = {}): Promise<string> {\n // return if available\n if (this.#currentBlock && useCache) {\n return this.#currentBlock;\n }\n\n if (this.#pendingLatestBlock) {\n return await this.#pendingLatestBlock.promise;\n }\n\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingLatestBlock = { reject, promise };\n\n if (this.#isRunning) {\n try {\n // If tracker is running, wait for next block with timeout\n const onLatestBlock = (value: string): void => {\n this.#removeInternalListener(onLatestBlock);\n this.removeListener('latest', onLatestBlock);\n resolve(value);\n };\n\n this.#addInternalListener(onLatestBlock);\n this.once('latest', onLatestBlock);\n\n return await promise;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n this.#pendingLatestBlock = undefined;\n }\n } else {\n // If tracker isn't running, just fetch directly\n try {\n const latestBlock = await this.#updateLatestBlock();\n resolve(latestBlock);\n return latestBlock;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n // We want to rate limit calls to this method if we made a direct fetch\n // for the block number because the BlockTracker was not running. We\n // achieve this by delaying the unsetting of the #pendingLatestBlock promise.\n setTimeout(() => {\n this.#pendingLatestBlock = undefined;\n }, this.#pollingInterval);\n }\n }\n }\n\n // Don't allow module consumer to remove our internal event listeners.\n removeAllListeners(eventName?: string | symbol): this {\n // perform default behavior, preserve fn arity\n if (eventName) {\n super.removeAllListeners(eventName);\n } else {\n super.removeAllListeners();\n }\n\n // re-add internal events\n this.#setupInternalEvents();\n // trigger stop check just in case\n this.#onRemoveListener();\n\n return this;\n }\n\n #setupInternalEvents(): void {\n // first remove listeners for idempotence\n this.removeListener('newListener', this.#onNewListener);\n this.removeListener('removeListener', this.#onRemoveListener);\n // then add them\n this.on('newListener', this.#onNewListener);\n this.on('removeListener', this.#onRemoveListener);\n }\n\n #onNewListenerUnbound(eventName: string | symbol): void {\n // `newListener` is called *before* the listener is added\n if (blockTrackerEvents.includes(eventName)) {\n // TODO: Handle dangling promise\n this.#maybeStart();\n }\n }\n\n #onRemoveListenerUnbound(): void {\n // `removeListener` is called *after* the listener is removed\n if (this.#getBlockTrackerEventCount() > 0) {\n return;\n }\n this.#maybeEnd();\n }\n\n #maybeStart(): void {\n if (this.#isRunning) {\n return;\n }\n\n this.#isRunning = true;\n // cancel setting latest block to stale\n this.#cancelBlockResetTimeout();\n this.#start();\n this.emit('_started');\n }\n\n #maybeEnd(): void {\n if (!this.#isRunning) {\n return;\n }\n\n this.#isRunning = false;\n this.#setupBlockResetTimeout();\n this.#end();\n this.#rejectPendingLatestBlock(new Error('Block tracker destroyed'));\n this.emit('_ended');\n }\n\n #getBlockTrackerEventCount(): number {\n return (\n blockTrackerEvents\n .map((eventName) => this.listeners(eventName))\n .flat()\n // internal listeners are not included in the count\n .filter((listener) =>\n this.#internalEventListeners.every(\n (internalListener) => !Object.is(internalListener, listener),\n ),\n ).length\n );\n }\n\n #shouldUseNewBlock(newBlock: string): boolean {\n const currentBlock = this.#currentBlock;\n if (!currentBlock) {\n return true;\n }\n const newBlockInt = hexToInt(newBlock);\n const currentBlockInt = hexToInt(currentBlock);\n\n return (\n (this.#usePastBlocks && newBlockInt < currentBlockInt) ||\n newBlockInt > currentBlockInt\n );\n }\n\n #newPotentialLatest(newBlock: string): void {\n if (!this.#shouldUseNewBlock(newBlock)) {\n return;\n }\n this.#setCurrentBlock(newBlock);\n }\n\n #setCurrentBlock(newBlock: string): void {\n const oldBlock = this.#currentBlock;\n this.#currentBlock = newBlock;\n this.emit('latest', newBlock);\n this.emit('sync', { oldBlock, newBlock });\n }\n\n #setupBlockResetTimeout(): void {\n // clear any existing timeout\n this.#cancelBlockResetTimeout();\n // clear latest block when stale\n this.#blockResetTimeout = setTimeout(\n this.#resetCurrentBlock,\n this.#blockResetDuration,\n );\n\n // nodejs - dont hold process open\n if (this.#blockResetTimeout.unref) {\n this.#blockResetTimeout.unref();\n }\n }\n\n #cancelBlockResetTimeout(): void {\n if (this.#blockResetTimeout) {\n clearTimeout(this.#blockResetTimeout);\n }\n }\n\n #resetCurrentBlockUnbound(): void {\n this.#currentBlock = null;\n }\n\n /**\n * Checks for the latest block, updates the internal state, and returns the\n * value immediately rather than waiting for the next polling interval.\n *\n * @deprecated Use {@link getLatestBlock} instead.\n * @returns A promise that resolves to the latest block number.\n */\n checkForLatestBlock(): Promise<string> {\n if (!this.#pendingCheckForLatestBlock) {\n this.#pendingCheckForLatestBlock = this.#updateLatestBlock()\n .then(() => this.getLatestBlock())\n .finally(() => {\n this.#pendingCheckForLatestBlock = undefined;\n });\n }\n return this.#pendingCheckForLatestBlock;\n }\n\n #start(): void {\n // Intentionally not awaited as this starts the polling via a timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }\n\n #end(): void {\n this.#clearPollingTimeout();\n }\n\n async #updateLatestBlock(): Promise<string> {\n // fetch + set latest block\n const latestBlock = await this.#fetchLatestBlock();\n this.#newPotentialLatest(latestBlock);\n\n if (!this.#isRunning) {\n // Ensure the one-time update is eventually reset once it's stale\n this.#setupBlockResetTimeout();\n }\n\n // _newPotentialLatest() ensures that this._currentBlock is not null\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#currentBlock!;\n }\n\n async #fetchLatestBlock(): Promise<string> {\n // If there's already a pending fetch, reuse it\n if (this.#pendingFetch) {\n return await this.#pendingFetch.promise;\n }\n\n // Create a new deferred promise for this request\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingFetch = { reject, promise };\n\n try {\n const req: ExtendedJsonRpcRequest = {\n jsonrpc: '2.0',\n id: createRandomId(),\n method: 'eth_blockNumber',\n params: [] as [],\n };\n if (this.#setSkipCacheFlag) {\n req.skipCache = true;\n }\n\n log('Making request', req);\n const result = await this.#provider.request<[], string>(req);\n log('Got result', result);\n resolve(result);\n return result;\n } catch (error) {\n log('Encountered error fetching block', getErrorMessage(error));\n reject(error);\n this.#rejectPendingLatestBlock(error);\n throw error;\n } finally {\n this.#pendingFetch = undefined;\n }\n }\n\n /**\n * The core polling function that runs after each interval.\n * Updates the latest block and then queues the next update.\n */\n async #updateAndQueue(): Promise<void> {\n let interval = this.#pollingInterval;\n\n try {\n await this.#updateLatestBlock();\n } catch (error: unknown) {\n try {\n this.emit('error', error);\n } catch {\n console.error(`Error updating latest block: ${getErrorMessage(error)}`);\n }\n\n interval = this.#retryTimeout;\n }\n\n if (!this.#isRunning) {\n return;\n }\n\n this.#clearPollingTimeout();\n\n const timeoutRef = setTimeout(() => {\n // Intentionally not awaited as this just continues the polling loop.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }, interval);\n\n if (timeoutRef.unref && !this.#keepEventLoopActive) {\n timeoutRef.unref();\n }\n\n this.#pollingTimeout = timeoutRef;\n\n this.emit('_waitingForNextIteration');\n }\n\n #clearPollingTimeout(): void {\n if (this.#pollingTimeout) {\n clearTimeout(this.#pollingTimeout);\n this.#pollingTimeout = undefined;\n }\n }\n\n #addInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.push(listener);\n }\n\n #removeInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.splice(\n this.#internalEventListeners.indexOf(listener),\n 1,\n );\n }\n\n #rejectPendingLatestBlock(error: unknown): void {\n this.#pendingLatestBlock?.reject(error);\n this.#pendingLatestBlock = undefined;\n }\n}\n\n/**\n * Converts a number represented as a string in hexadecimal format into a native\n * number.\n *\n * @param hexInt - The hex string.\n * @returns The number.\n */\nfunction hexToInt(hexInt: string): number {\n return Number.parseInt(hexInt, 16);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PollingBlockTracker.mjs","sourceRoot":"","sources":["../src/PollingBlockTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type {\n ContextConstraint,\n MiddlewareContext,\n} from '@metamask/json-rpc-engine/v2';\nimport SafeEventEmitter from '@metamask/safe-event-emitter';\nimport { createDeferredPromise, getErrorMessage } from '@metamask/utils';\nimport type { DeferredPromise, JsonRpcRequest } from '@metamask/utils';\nimport getCreateRandomId from 'json-rpc-random-id';\n\nimport type { BlockTracker } from './BlockTracker';\nimport { projectLogger, createModuleLogger } from './logging-utils';\n\nconst log = createModuleLogger(projectLogger, 'polling-block-tracker');\nconst createRandomId = getCreateRandomId();\nconst sec = 1000;\n\nconst blockTrackerEvents: (string | symbol)[] = ['sync', 'latest'];\n\nexport type PollingBlockTrackerOptions<\n Context extends ContextConstraint = MiddlewareContext,\n> = {\n provider?: InternalProvider<Context>;\n pollingInterval?: number;\n retryTimeout?: number;\n keepEventLoopActive?: boolean;\n setSkipCacheFlag?: boolean;\n blockResetDuration?: number;\n usePastBlocks?: boolean;\n};\n\ntype ExtendedJsonRpcRequest = {\n skipCache?: boolean;\n} & JsonRpcRequest<[]>;\n\ntype InternalListener = (value: string) => void;\n\nexport class PollingBlockTracker<\n Context extends ContextConstraint = MiddlewareContext,\n>\n extends SafeEventEmitter\n implements BlockTracker\n{\n #isRunning: boolean;\n\n readonly #blockResetDuration: number;\n\n readonly #usePastBlocks: boolean;\n\n #currentBlock: string | null;\n\n #blockResetTimeout?: ReturnType<typeof setTimeout>;\n\n #pollingTimeout?: ReturnType<typeof setTimeout>;\n\n readonly #provider: InternalProvider<Context>;\n\n readonly #pollingInterval: number;\n\n readonly #retryTimeout: number;\n\n readonly #keepEventLoopActive: boolean;\n\n readonly #setSkipCacheFlag: boolean;\n\n readonly #internalEventListeners: InternalListener[] = [];\n\n #pendingLatestBlock?: Omit<DeferredPromise<string>, 'resolve'>;\n\n #pendingFetch?: Omit<DeferredPromise<string>, 'resolve'>;\n\n readonly #onNewListener: (eventName: string | symbol) => void;\n\n readonly #onRemoveListener: () => void;\n\n readonly #resetCurrentBlock: () => void;\n\n constructor(opts: PollingBlockTrackerOptions<Context> = {}) {\n // parse + validate args\n if (!opts.provider) {\n throw new Error('PollingBlockTracker - no provider specified.');\n }\n\n super();\n\n // config\n this.#blockResetDuration = opts.blockResetDuration ?? 20 * sec;\n this.#usePastBlocks = opts.usePastBlocks ?? false;\n // state\n this.#currentBlock = null;\n this.#isRunning = false;\n\n // bind functions for internal use\n this.#onNewListener = this.#onNewListenerUnbound.bind(this);\n this.#onRemoveListener = this.#onRemoveListenerUnbound.bind(this);\n this.#resetCurrentBlock = this.#resetCurrentBlockUnbound.bind(this);\n\n // listen for handler changes\n this.#setupInternalEvents();\n\n // config\n this.#provider = opts.provider;\n this.#pollingInterval = opts.pollingInterval ?? 20 * sec;\n this.#retryTimeout = opts.retryTimeout ?? this.#pollingInterval / 10;\n this.#keepEventLoopActive = opts.keepEventLoopActive ?? true;\n this.#setSkipCacheFlag = opts.setSkipCacheFlag ?? false;\n }\n\n async destroy(): Promise<void> {\n this.#cancelBlockResetTimeout();\n super.removeAllListeners();\n this.#maybeEnd();\n }\n\n isRunning(): boolean {\n return this.#isRunning;\n }\n\n getCurrentBlock(): string | null {\n return this.#currentBlock;\n }\n\n async getLatestBlock({\n useCache = true,\n }: { useCache?: boolean } = {}): Promise<string> {\n // return if available\n if (this.#currentBlock && useCache) {\n return this.#currentBlock;\n }\n\n if (this.#pendingLatestBlock) {\n return await this.#pendingLatestBlock.promise;\n }\n\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingLatestBlock = { reject, promise };\n\n if (this.#isRunning) {\n try {\n // If tracker is running, wait for next block with timeout\n const onLatestBlock = (value: string): void => {\n this.#removeInternalListener(onLatestBlock);\n this.removeListener('latest', onLatestBlock);\n resolve(value);\n };\n\n this.#addInternalListener(onLatestBlock);\n this.once('latest', onLatestBlock);\n\n return await promise;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n this.#pendingLatestBlock = undefined;\n }\n } else {\n // If tracker isn't running, just fetch directly\n try {\n const latestBlock = await this.#updateLatestBlock();\n resolve(latestBlock);\n return latestBlock;\n } catch (error) {\n reject(error);\n throw error;\n } finally {\n // We want to rate limit calls to this method if we made a direct fetch\n // for the block number because the BlockTracker was not running. We\n // achieve this by delaying the unsetting of the #pendingLatestBlock promise.\n setTimeout(() => {\n this.#pendingLatestBlock = undefined;\n }, this.#pollingInterval);\n }\n }\n }\n\n // Don't allow module consumer to remove our internal event listeners.\n removeAllListeners(eventName?: string | symbol): this {\n // perform default behavior, preserve fn arity\n if (eventName) {\n super.removeAllListeners(eventName);\n } else {\n super.removeAllListeners();\n }\n\n // re-add internal events\n this.#setupInternalEvents();\n // trigger stop check just in case\n this.#onRemoveListener();\n\n return this;\n }\n\n #setupInternalEvents(): void {\n // first remove listeners for idempotence\n this.removeListener('newListener', this.#onNewListener);\n this.removeListener('removeListener', this.#onRemoveListener);\n // then add them\n this.on('newListener', this.#onNewListener);\n this.on('removeListener', this.#onRemoveListener);\n }\n\n #onNewListenerUnbound(eventName: string | symbol): void {\n // `newListener` is called *before* the listener is added\n if (blockTrackerEvents.includes(eventName)) {\n // TODO: Handle dangling promise\n this.#maybeStart();\n }\n }\n\n #onRemoveListenerUnbound(): void {\n // `removeListener` is called *after* the listener is removed\n if (this.#getBlockTrackerEventCount() > 0) {\n return;\n }\n this.#maybeEnd();\n }\n\n #maybeStart(): void {\n if (this.#isRunning) {\n return;\n }\n\n this.#isRunning = true;\n // cancel setting latest block to stale\n this.#cancelBlockResetTimeout();\n this.#start();\n this.emit('_started');\n }\n\n #maybeEnd(): void {\n if (!this.#isRunning) {\n return;\n }\n\n this.#isRunning = false;\n this.#setupBlockResetTimeout();\n this.#end();\n this.#rejectPendingLatestBlock(new Error('Block tracker destroyed'));\n this.emit('_ended');\n }\n\n #getBlockTrackerEventCount(): number {\n return (\n blockTrackerEvents\n .map((eventName) => this.listeners(eventName))\n .flat()\n // internal listeners are not included in the count\n .filter((listener) =>\n this.#internalEventListeners.every(\n (internalListener) => !Object.is(internalListener, listener),\n ),\n ).length\n );\n }\n\n #shouldUseNewBlock(newBlock: string): boolean {\n const currentBlock = this.#currentBlock;\n if (!currentBlock) {\n return true;\n }\n const newBlockInt = hexToInt(newBlock);\n const currentBlockInt = hexToInt(currentBlock);\n\n return (\n (this.#usePastBlocks && newBlockInt < currentBlockInt) ||\n newBlockInt > currentBlockInt\n );\n }\n\n #newPotentialLatest(newBlock: string): void {\n if (!this.#shouldUseNewBlock(newBlock)) {\n return;\n }\n this.#setCurrentBlock(newBlock);\n }\n\n #setCurrentBlock(newBlock: string): void {\n const oldBlock = this.#currentBlock;\n this.#currentBlock = newBlock;\n this.emit('latest', newBlock);\n this.emit('sync', { oldBlock, newBlock });\n }\n\n #setupBlockResetTimeout(): void {\n // clear any existing timeout\n this.#cancelBlockResetTimeout();\n // clear latest block when stale\n this.#blockResetTimeout = setTimeout(\n this.#resetCurrentBlock,\n this.#blockResetDuration,\n );\n\n // nodejs - dont hold process open\n if (this.#blockResetTimeout.unref) {\n this.#blockResetTimeout.unref();\n }\n }\n\n #cancelBlockResetTimeout(): void {\n if (this.#blockResetTimeout) {\n clearTimeout(this.#blockResetTimeout);\n }\n }\n\n #resetCurrentBlockUnbound(): void {\n this.#currentBlock = null;\n }\n\n /**\n * Checks for the latest block, updates the internal state, and returns the\n * value immediately rather than waiting for the next polling interval.\n *\n * @deprecated Use {@link getLatestBlock} instead.\n * @returns A promise that resolves to the latest block number.\n */\n async checkForLatestBlock(): Promise<string> {\n await this.#updateLatestBlock();\n return await this.getLatestBlock();\n }\n\n #start(): void {\n // Intentionally not awaited as this starts the polling via a timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }\n\n #end(): void {\n this.#clearPollingTimeout();\n }\n\n async #updateLatestBlock(): Promise<string> {\n // fetch + set latest block\n const latestBlock = await this.#fetchLatestBlock();\n this.#newPotentialLatest(latestBlock);\n\n if (!this.#isRunning) {\n // Ensure the one-time update is eventually reset once it's stale\n this.#setupBlockResetTimeout();\n }\n\n // _newPotentialLatest() ensures that this._currentBlock is not null\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#currentBlock!;\n }\n\n async #fetchLatestBlock(): Promise<string> {\n // If there's already a pending fetch, reuse it\n if (this.#pendingFetch) {\n return await this.#pendingFetch.promise;\n }\n\n // Create a new deferred promise for this request\n const { promise, resolve, reject } = createDeferredPromise<string>({\n suppressUnhandledRejection: true,\n });\n this.#pendingFetch = { reject, promise };\n\n try {\n const req: ExtendedJsonRpcRequest = {\n jsonrpc: '2.0',\n id: createRandomId(),\n method: 'eth_blockNumber',\n params: [] as [],\n };\n if (this.#setSkipCacheFlag) {\n req.skipCache = true;\n }\n\n log('Making request', req);\n const result = await this.#provider.request<[], string>(req);\n log('Got result', result);\n resolve(result);\n return result;\n } catch (error) {\n log('Encountered error fetching block', getErrorMessage(error));\n reject(error);\n this.#rejectPendingLatestBlock(error);\n throw error;\n } finally {\n this.#pendingFetch = undefined;\n }\n }\n\n /**\n * The core polling function that runs after each interval.\n * Updates the latest block and then queues the next update.\n */\n async #updateAndQueue(): Promise<void> {\n let interval = this.#pollingInterval;\n\n try {\n await this.#updateLatestBlock();\n } catch (error: unknown) {\n try {\n this.emit('error', error);\n } catch {\n console.error(`Error updating latest block: ${getErrorMessage(error)}`);\n }\n\n interval = this.#retryTimeout;\n }\n\n if (!this.#isRunning) {\n return;\n }\n\n this.#clearPollingTimeout();\n\n const timeoutRef = setTimeout(() => {\n // Intentionally not awaited as this just continues the polling loop.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#updateAndQueue();\n }, interval);\n\n if (timeoutRef.unref && !this.#keepEventLoopActive) {\n timeoutRef.unref();\n }\n\n this.#pollingTimeout = timeoutRef;\n\n this.emit('_waitingForNextIteration');\n }\n\n #clearPollingTimeout(): void {\n if (this.#pollingTimeout) {\n clearTimeout(this.#pollingTimeout);\n this.#pollingTimeout = undefined;\n }\n }\n\n #addInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.push(listener);\n }\n\n #removeInternalListener(listener: InternalListener): void {\n this.#internalEventListeners.splice(\n this.#internalEventListeners.indexOf(listener),\n 1,\n );\n }\n\n #rejectPendingLatestBlock(error: unknown): void {\n this.#pendingLatestBlock?.reject(error);\n this.#pendingLatestBlock = undefined;\n }\n}\n\n/**\n * Converts a number represented as a string in hexadecimal format into a native\n * number.\n *\n * @param hexInt - The hex string.\n * @returns The number.\n */\nfunction hexToInt(hexInt: string): number {\n return Number.parseInt(hexInt, 16);\n}\n"]}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAAsC","sourcesContent":["export * from './PollingBlockTracker';\nexport type * from './BlockTracker';\n"]}
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAAsC;AACtC,wCAAoC"}
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAAsC;AACtC,wCAAoC"}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAAsC","sourcesContent":["export * from './PollingBlockTracker';\nexport type * from './BlockTracker';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/eth-block-tracker",
|
|
3
|
-
"version": "15.0.1-preview-
|
|
3
|
+
"version": "15.0.1-preview-40d5fb1e2",
|
|
4
4
|
"description": "A block tracker for the Ethereum blockchain. Keeps track of the latest block",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"@metamask/auto-changelog": "^6.1.0",
|
|
65
65
|
"@metamask/json-rpc-engine": "^10.5.0",
|
|
66
66
|
"@ts-bridge/cli": "^0.6.4",
|
|
67
|
-
"@types/jest": "^
|
|
67
|
+
"@types/jest": "^29.5.14",
|
|
68
68
|
"@types/json-rpc-random-id": "^1.0.1",
|
|
69
69
|
"deepmerge": "^4.2.2",
|
|
70
|
-
"jest": "^
|
|
71
|
-
"ts-jest": "^29.
|
|
70
|
+
"jest": "^29.7.0",
|
|
71
|
+
"ts-jest": "^29.2.5",
|
|
72
72
|
"tsx": "^4.20.5",
|
|
73
73
|
"typedoc": "^0.25.13",
|
|
74
74
|
"typedoc-plugin-missing-exports": "^2.0.0",
|