@metamask-previews/transaction-controller 62.7.0-preview-42084fe4 → 62.7.0-preview-7bc2d97e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/TransactionController.cjs +23 -72
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +12 -13
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +12 -13
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +23 -72
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/helpers/PendingTransactionTracker.cjs +37 -25
  11. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  12. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  13. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  14. package/dist/helpers/PendingTransactionTracker.mjs +38 -26
  15. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  16. package/dist/index.cjs +1 -4
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +0 -1
  19. package/dist/index.d.cts.map +1 -1
  20. package/dist/index.d.mts +0 -1
  21. package/dist/index.d.mts.map +1 -1
  22. package/dist/index.mjs +0 -1
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/types.cjs.map +1 -1
  25. package/dist/types.d.cts +5 -4
  26. package/dist/types.d.cts.map +1 -1
  27. package/dist/types.d.mts +5 -4
  28. package/dist/types.d.mts.map +1 -1
  29. package/dist/types.mjs.map +1 -1
  30. package/dist/utils/feature-flags.cjs +4 -1
  31. package/dist/utils/feature-flags.cjs.map +1 -1
  32. package/dist/utils/feature-flags.d.cts +5 -0
  33. package/dist/utils/feature-flags.d.cts.map +1 -1
  34. package/dist/utils/feature-flags.d.mts +5 -0
  35. package/dist/utils/feature-flags.d.mts.map +1 -1
  36. package/dist/utils/feature-flags.mjs +4 -1
  37. package/dist/utils/feature-flags.mjs.map +1 -1
  38. package/package.json +3 -3
  39. package/dist/utils/history.cjs +0 -164
  40. package/dist/utils/history.cjs.map +0 -1
  41. package/dist/utils/history.d.cts +0 -29
  42. package/dist/utils/history.d.cts.map +0 -1
  43. package/dist/utils/history.d.mts +0 -29
  44. package/dist/utils/history.d.mts.map +0 -1
  45. package/dist/utils/history.mjs +0 -164
  46. package/dist/utils/history.mjs.map +0 -1
@@ -13,7 +13,7 @@ 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 _PendingTransactionTracker_instances, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_isTimeoutEnabled, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_getNetworkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_messenger, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_timeoutCountByHash, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_transactionToForcePoll, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_cleanTransactionToForcePoll, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionTimeout, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getTransactionByHash, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
16
+ var _PendingTransactionTracker_instances, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_isTimeoutEnabled, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_getNetworkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_lastSeenTimestampByHash, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_messenger, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_transactionToForcePoll, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_cleanTransaction, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionTimeout, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getTransactionByHash, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.PendingTransactionTracker = void 0;
19
19
  const controller_utils_1 = require("@metamask/controller-utils");
@@ -54,6 +54,7 @@ class PendingTransactionTracker {
54
54
  _PendingTransactionTracker_getNetworkClientId.set(this, void 0);
55
55
  _PendingTransactionTracker_getTransactions.set(this, void 0);
56
56
  _PendingTransactionTracker_isResubmitEnabled.set(this, void 0);
57
+ _PendingTransactionTracker_lastSeenTimestampByHash.set(this, void 0);
57
58
  // TODO: Replace `any` with type
58
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
60
  _PendingTransactionTracker_listener.set(this, void 0);
@@ -61,7 +62,6 @@ class PendingTransactionTracker {
61
62
  _PendingTransactionTracker_messenger.set(this, void 0);
62
63
  _PendingTransactionTracker_publishTransaction.set(this, void 0);
63
64
  _PendingTransactionTracker_running.set(this, void 0);
64
- _PendingTransactionTracker_timeoutCountByHash.set(this, void 0);
65
65
  _PendingTransactionTracker_transactionPoller.set(this, void 0);
66
66
  _PendingTransactionTracker_transactionToForcePoll.set(this, void 0);
67
67
  this.startIfPendingTransactions = () => {
@@ -81,11 +81,11 @@ class PendingTransactionTracker {
81
81
  __classPrivateFieldSet(this, _PendingTransactionTracker_getNetworkClientId, getNetworkClientId, "f");
82
82
  __classPrivateFieldSet(this, _PendingTransactionTracker_getTransactions, getTransactions, "f");
83
83
  __classPrivateFieldSet(this, _PendingTransactionTracker_isResubmitEnabled, isResubmitEnabled ?? (() => true), "f");
84
+ __classPrivateFieldSet(this, _PendingTransactionTracker_lastSeenTimestampByHash, new Map(), "f");
84
85
  __classPrivateFieldSet(this, _PendingTransactionTracker_listener, __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_onLatestBlock).bind(this), "f");
85
86
  __classPrivateFieldSet(this, _PendingTransactionTracker_messenger, messenger, "f");
86
87
  __classPrivateFieldSet(this, _PendingTransactionTracker_publishTransaction, publishTransaction, "f");
87
88
  __classPrivateFieldSet(this, _PendingTransactionTracker_running, false, "f");
88
- __classPrivateFieldSet(this, _PendingTransactionTracker_timeoutCountByHash, new Map(), "f");
89
89
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionToForcePoll, undefined, "f");
90
90
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionPoller, new TransactionPoller_1.TransactionPoller({
91
91
  blockTracker,
@@ -141,7 +141,7 @@ class PendingTransactionTracker {
141
141
  }
142
142
  }
143
143
  exports.PendingTransactionTracker = PendingTransactionTracker;
144
- _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_isTimeoutEnabled = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_getNetworkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_messenger = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_timeoutCountByHash = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_transactionToForcePoll = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
144
+ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_isTimeoutEnabled = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_getNetworkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_lastSeenTimestampByHash = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_messenger = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_transactionToForcePoll = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
145
145
  __classPrivateFieldGet(this, _PendingTransactionTracker_transactionPoller, "f").setPendingTransactions(pendingTransactions);
146
146
  if (__classPrivateFieldGet(this, _PendingTransactionTracker_running, "f")) {
147
147
  return;
@@ -242,10 +242,14 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
242
242
  // Capped at ~15 minutes between retries
243
243
  const requiredBlocksSinceFirstRetry = Math.min(MAX_RETRY_BLOCK_DISTANCE, Math.pow(2, retryCount));
244
244
  return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;
245
- }, _PendingTransactionTracker_cleanTransactionToForcePoll = function _PendingTransactionTracker_cleanTransactionToForcePoll(transactionId) {
246
- if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === transactionId) {
245
+ }, _PendingTransactionTracker_cleanTransaction = function _PendingTransactionTracker_cleanTransaction(txMeta) {
246
+ const { hash, id } = txMeta;
247
+ if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === id) {
247
248
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionToForcePoll, undefined, "f");
248
249
  }
250
+ if (hash) {
251
+ __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").delete(hash);
252
+ }
249
253
  }, _PendingTransactionTracker_checkTransaction = async function _PendingTransactionTracker_checkTransaction(txMeta) {
250
254
  const { hash, id, isIntentComplete, txParams: { from }, } = txMeta;
251
255
  if (isIntentComplete) {
@@ -269,7 +273,7 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
269
273
  const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;
270
274
  if (isFailure) {
271
275
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction receipt has failed status');
272
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_failTransaction).call(this, txMeta, new Error('Transaction dropped or replaced'));
276
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_failTransaction).call(this, txMeta, new Error('Transaction failed on-chain'));
273
277
  return;
274
278
  }
275
279
  const { blockNumber, blockHash } = receipt ?? {};
@@ -300,8 +304,9 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
300
304
  const { id } = txMeta;
301
305
  const { blockHash } = receipt ?? {};
302
306
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction confirmed', id);
303
- if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")) {
304
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransactionToForcePoll).call(this, txMeta.id);
307
+ const isForcePollTransaction = __classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === id;
308
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransaction).call(this, txMeta);
309
+ if (isForcePollTransaction) {
305
310
  this.hub.emit('transaction-confirmed', txMeta);
306
311
  return;
307
312
  }
@@ -321,7 +326,7 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
321
326
  __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_updateTransaction).call(this, updatedTxMeta, 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed');
322
327
  this.hub.emit('transaction-confirmed', updatedTxMeta);
323
328
  }, _PendingTransactionTracker_isTransactionTimeout = async function _PendingTransactionTracker_isTransactionTimeout(txMeta, nextNonce) {
324
- const { chainId, hash, id: transactionId, txParams: { nonce }, } = txMeta;
329
+ const { chainId, hash, id: transactionId, submittedTime, txParams: { nonce }, } = txMeta;
325
330
  if (!hash || !nonce) {
326
331
  return false;
327
332
  }
@@ -347,27 +352,34 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
347
352
  try {
348
353
  // Check if transaction exists on the network
349
354
  const transaction = await __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getTransactionByHash).call(this, hash);
350
- // If transaction exists, reset the counter
355
+ // If transaction exists, record the timestamp
351
356
  if (transaction !== null) {
352
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction found on network, resetting timeout counter', transactionId);
353
- __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").delete(hash);
357
+ const currentTimestamp = Date.now();
358
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction found on network, recording timestamp', transactionId);
359
+ __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").set(hash, currentTimestamp);
360
+ return false;
361
+ }
362
+ const lastSeenTimestamp = __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").get(hash) ?? submittedTime;
363
+ if (lastSeenTimestamp === undefined) {
364
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction not yet seen on network and has no submitted time, skipping timeout check', transactionId);
354
365
  return false;
355
366
  }
356
- // Transaction doesn't exist, increment counter
357
- let attempts = __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").get(hash);
358
- attempts ?? (attempts = 0);
359
- attempts += 1;
360
- __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").set(hash, attempts);
361
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Incrementing timeout counter', {
367
+ const { blockTime } = (0, feature_flags_1.getAcceleratedPollingParams)(chainId, __classPrivateFieldGet(this, _PendingTransactionTracker_messenger, "f"));
368
+ const currentTimestamp = Date.now();
369
+ const durationSinceLastSeen = currentTimestamp - lastSeenTimestamp;
370
+ const timeoutDuration = blockTime * threshold;
371
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Checking timeout duration', {
362
372
  transactionId,
363
- attempts,
373
+ durationSinceLastSeen,
374
+ timeoutDuration,
364
375
  threshold,
376
+ blockTime,
365
377
  });
366
- if (attempts < threshold) {
378
+ if (durationSinceLastSeen < timeoutDuration) {
367
379
  return false;
368
380
  }
369
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Hit timeout threshold', transactionId);
370
- __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").delete(hash);
381
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Hit timeout duration threshold', transactionId);
382
+ __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").delete(hash);
371
383
  __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_failTransaction).call(this, txMeta, new Error('Transaction not found on network after timeout'));
372
384
  return true;
373
385
  }
@@ -418,11 +430,11 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
418
430
  }, 'PendingTransactionTracker:#warnTransaction - Warning added');
419
431
  }, _PendingTransactionTracker_failTransaction = function _PendingTransactionTracker_failTransaction(txMeta, error) {
420
432
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction failed', txMeta.id, error);
421
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransactionToForcePoll).call(this, txMeta.id);
433
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransaction).call(this, txMeta);
422
434
  this.hub.emit('transaction-failed', txMeta, error);
423
435
  }, _PendingTransactionTracker_dropTransaction = function _PendingTransactionTracker_dropTransaction(txMeta) {
424
436
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction dropped', txMeta.id);
425
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransactionToForcePoll).call(this, txMeta.id);
437
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransaction).call(this, txMeta);
426
438
  this.hub.emit('transaction-dropped', txMeta);
427
439
  }, _PendingTransactionTracker_updateTransaction = function _PendingTransactionTracker_updateTransaction(txMeta, note) {
428
440
  this.hub.emit('transaction-updated', txMeta, note);
@@ -1 +1 @@
1
- {"version":3,"file":"PendingTransactionTracker.cjs","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n BlockTracker,\n NetworkClientId,\n} from '@metamask/network-controller';\nimport type { Hex, Json } from '@metamask/utils';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\nimport { cloneDeep, merge } from 'lodash';\n\nimport { TransactionPoller } from './TransactionPoller';\nimport { createModuleLogger, projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { TransactionMeta, TransactionReceipt } from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\nimport { getTimeoutAttempts } from '../utils/feature-flags';\n\n/**\n * We wait this many blocks before emitting a 'transaction-dropped' event\n * This is because we could be talking to a node that is out of sync\n */\nconst DROPPED_BLOCK_COUNT = 3;\n\nconst RECEIPT_STATUS_SUCCESS = '0x1';\nconst RECEIPT_STATUS_FAILURE = '0x0';\nconst MAX_RETRY_BLOCK_DISTANCE = 50;\n\nconst KNOWN_TRANSACTION_ERRORS = [\n 'replacement transaction underpriced',\n 'known transaction',\n 'gas price too low to replace',\n 'transaction with the same hash was already imported',\n 'gateway timeout',\n 'nonce too low',\n];\n\nconst log = createModuleLogger(projectLogger, 'pending-transactions');\n\ntype SuccessfulTransactionReceipt = TransactionReceipt & {\n blockNumber: string;\n blockHash: string;\n};\n\ntype Events = {\n 'transaction-confirmed': [txMeta: TransactionMeta];\n 'transaction-dropped': [txMeta: TransactionMeta];\n 'transaction-failed': [txMeta: TransactionMeta, error: Error];\n 'transaction-updated': [txMeta: TransactionMeta, note: string];\n};\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface PendingTransactionTrackerEventEmitter extends EventEmitter {\n on<EventName extends keyof Events>(\n eventName: EventName,\n listener: (...args: Events[EventName]) => void,\n ): this;\n\n emit<EventName extends keyof Events>(\n eventName: EventName,\n ...args: Events[EventName]\n ): boolean;\n}\n\nexport class PendingTransactionTracker {\n hub: PendingTransactionTrackerEventEmitter;\n\n readonly #beforeCheckPendingTransaction: (\n transactionMeta: TransactionMeta,\n ) => Promise<boolean>;\n\n readonly #droppedBlockCountByHash: Map<string, number>;\n\n readonly #isTimeoutEnabled: (transactionMeta: TransactionMeta) => boolean;\n\n readonly #getChainId: () => string;\n\n readonly #getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n\n readonly #getGlobalLock: () => Promise<() => void>;\n\n readonly #getNetworkClientId: () => NetworkClientId;\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #isResubmitEnabled: () => boolean;\n\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly #listener: any;\n\n readonly #log: debug.Debugger;\n\n readonly #messenger: TransactionControllerMessenger;\n\n readonly #publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n\n #running: boolean;\n\n readonly #timeoutCountByHash: Map<string, number>;\n\n readonly #transactionPoller: TransactionPoller;\n\n #transactionToForcePoll: TransactionMeta | undefined;\n\n constructor({\n blockTracker,\n getChainId,\n getEthQuery,\n getGlobalLock,\n getNetworkClientId,\n getTransactions,\n isTimeoutEnabled,\n hooks,\n isResubmitEnabled,\n messenger,\n publishTransaction,\n }: {\n blockTracker: BlockTracker;\n getChainId: () => Hex;\n getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n getGlobalLock: () => Promise<() => void>;\n getNetworkClientId: () => string;\n getTransactions: () => TransactionMeta[];\n hooks?: {\n beforeCheckPendingTransaction?: (\n transactionMeta: TransactionMeta,\n ) => Promise<boolean>;\n };\n isResubmitEnabled?: () => boolean;\n isTimeoutEnabled: (transactionMeta: TransactionMeta) => boolean;\n messenger: TransactionControllerMessenger;\n publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n }) {\n this.hub = new EventEmitter() as PendingTransactionTrackerEventEmitter;\n\n this.#droppedBlockCountByHash = new Map();\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getGlobalLock = getGlobalLock;\n this.#getNetworkClientId = getNetworkClientId;\n this.#getTransactions = getTransactions;\n this.#isResubmitEnabled = isResubmitEnabled ?? ((): boolean => true);\n this.#listener = this.#onLatestBlock.bind(this);\n this.#messenger = messenger;\n this.#publishTransaction = publishTransaction;\n this.#running = false;\n this.#timeoutCountByHash = new Map();\n this.#transactionToForcePoll = undefined;\n\n this.#transactionPoller = new TransactionPoller({\n blockTracker,\n chainId: getChainId(),\n messenger,\n });\n\n this.#beforeCheckPendingTransaction =\n hooks?.beforeCheckPendingTransaction ??\n /* istanbul ignore next */\n ((): Promise<boolean> => Promise.resolve(true));\n\n this.#isTimeoutEnabled = isTimeoutEnabled;\n\n this.#log = createModuleLogger(\n log,\n `${getChainId()}:${getNetworkClientId()}`,\n );\n }\n\n startIfPendingTransactions = (): void => {\n const pendingTransactions = this.#getPendingTransactions();\n\n if (pendingTransactions.length) {\n this.#start(pendingTransactions);\n } else {\n this.stop();\n }\n };\n\n /**\n * Adds a transaction to the polling mechanism for monitoring its status.\n *\n * This method forcefully adds a single transaction to the list of transactions\n * being polled, ensuring that its status is checked, event emitted but no update is performed.\n * It overrides the default behavior by prioritizing the given transaction for polling.\n *\n * @param transactionMeta - The transaction metadata to be added for polling.\n *\n * The transaction will now be monitored for updates, such as confirmation or failure.\n */\n addTransactionToPoll(transactionMeta: TransactionMeta): void {\n this.#start([transactionMeta]);\n this.#transactionToForcePoll = transactionMeta;\n }\n\n /**\n * Force checks the network if the given transaction is confirmed and updates it's status.\n *\n * @param txMeta - The transaction to check\n */\n async forceCheckTransaction(txMeta: TransactionMeta): Promise<void> {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransaction(txMeta);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transaction', error);\n } finally {\n releaseLock();\n }\n }\n\n #start(pendingTransactions: TransactionMeta[]): void {\n this.#transactionPoller.setPendingTransactions(pendingTransactions);\n\n if (this.#running) {\n return;\n }\n\n this.#transactionPoller.start(this.#listener);\n this.#running = true;\n\n this.#log('Started polling');\n }\n\n stop(): void {\n if (!this.#running) {\n return;\n }\n\n this.#transactionPoller.stop();\n this.#running = false;\n\n this.#log('Stopped polling');\n }\n\n async #onLatestBlock(latestBlockNumber: string): Promise<void> {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransactions();\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transactions', error);\n } finally {\n releaseLock();\n }\n\n try {\n await this.#resubmitTransactions(latestBlockNumber);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to resubmit transactions', error);\n }\n }\n\n async #checkTransactions(): Promise<void> {\n this.#log('Checking transactions');\n\n const pendingTransactions: TransactionMeta[] = [\n ...this.#getPendingTransactions(),\n ...(this.#transactionToForcePoll ? [this.#transactionToForcePoll] : []),\n ];\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to check');\n return;\n }\n\n this.#log('Found pending transactions to check', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n await Promise.all(\n pendingTransactions.map((tx) => this.#checkTransaction(tx)),\n );\n }\n\n async #resubmitTransactions(latestBlockNumber: string): Promise<void> {\n if (!this.#isResubmitEnabled() || !this.#running) {\n return;\n }\n\n this.#log('Resubmitting transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to resubmit');\n return;\n }\n\n this.#log('Found pending transactions to resubmit', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n for (const txMeta of pendingTransactions) {\n try {\n await this.#resubmitTransaction(txMeta, latestBlockNumber);\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n /* istanbul ignore next */\n const errorMessage =\n error.value?.message?.toLowerCase() ??\n error.message?.toLowerCase() ??\n String(error);\n\n if (this.#isKnownTransactionError(errorMessage)) {\n this.#log('Ignoring known transaction error', errorMessage);\n continue;\n }\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was an error when resubmitting this transaction.',\n );\n }\n }\n }\n\n #isKnownTransactionError(errorMessage: string): boolean {\n return KNOWN_TRANSACTION_ERRORS.some((knownError) =>\n errorMessage.includes(knownError),\n );\n }\n\n async #resubmitTransaction(\n txMeta: TransactionMeta,\n latestBlockNumber: string,\n ): Promise<void> {\n if (!this.#isResubmitDue(txMeta, latestBlockNumber)) {\n return;\n }\n\n if (!(await this.#beforeCheckPendingTransaction(txMeta))) {\n return;\n }\n\n const ethQuery = this.#getEthQuery(txMeta.networkClientId);\n await this.#publishTransaction(ethQuery, txMeta);\n\n const retryCount = (txMeta.retryCount ?? 0) + 1;\n\n this.#updateTransaction(\n merge({}, txMeta, { retryCount }),\n 'PendingTransactionTracker:transaction-retry - Retry count increased',\n );\n }\n\n #isResubmitDue(txMeta: TransactionMeta, latestBlockNumber: string): boolean {\n const txMetaWithFirstRetryBlockNumber = cloneDeep(txMeta);\n\n if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {\n txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;\n\n this.#updateTransaction(\n txMetaWithFirstRetryBlockNumber,\n 'PendingTransactionTracker:#isResubmitDue - First retry block number set',\n );\n }\n\n const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;\n\n const blocksSinceFirstRetry =\n Number.parseInt(latestBlockNumber, 16) -\n Number.parseInt(firstRetryBlockNumber, 16);\n\n const retryCount = txMeta.retryCount ?? 0;\n\n // Exponential backoff to limit retries at publishing\n // Capped at ~15 minutes between retries\n const requiredBlocksSinceFirstRetry = Math.min(\n MAX_RETRY_BLOCK_DISTANCE,\n Math.pow(2, retryCount),\n );\n\n return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;\n }\n\n #cleanTransactionToForcePoll(transactionId: string): void {\n if (this.#transactionToForcePoll?.id === transactionId) {\n this.#transactionToForcePoll = undefined;\n }\n }\n\n async #checkTransaction(txMeta: TransactionMeta): Promise<void> {\n const {\n hash,\n id,\n isIntentComplete,\n txParams: { from },\n } = txMeta;\n\n if (isIntentComplete) {\n await this.#onTransactionConfirmed(txMeta);\n return;\n }\n\n if (!hash && (await this.#beforeCheckPendingTransaction(txMeta))) {\n const error = new Error(\n 'We had an error while submitting this transaction, please try again.',\n );\n\n error.name = 'NoTxHashError';\n\n this.#failTransaction(txMeta, error);\n\n return;\n }\n\n if (this.#isNonceTaken(txMeta)) {\n this.#log('Nonce already taken', id);\n this.#dropTransaction(txMeta);\n return;\n }\n\n try {\n const receipt = await this.#getTransactionReceipt(hash);\n const isSuccess = receipt?.status === RECEIPT_STATUS_SUCCESS;\n const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;\n\n if (isFailure) {\n this.#log('Transaction receipt has failed status');\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction dropped or replaced'),\n );\n\n return;\n }\n\n const { blockNumber, blockHash } = receipt ?? {};\n\n if (isSuccess && blockNumber && blockHash) {\n await this.#onTransactionConfirmed(txMeta, {\n ...receipt,\n blockNumber,\n blockHash,\n });\n\n return;\n }\n\n this.#log('No receipt status', { hash, receipt });\n\n const nextNonceHex = await this.#getNetworkTransactionCount(from);\n const nextNonce = parseInt(nextNonceHex, 16);\n\n // Check if transaction should be failed due to no receipt\n if (!receipt && (await this.#isTransactionTimeout(txMeta, nextNonce))) {\n return;\n }\n\n if (await this.#isTransactionDropped(txMeta, nextNonce)) {\n this.#dropTransaction(txMeta);\n }\n } catch (error) {\n this.#log('Failed to check transaction', id, error);\n\n this.#warnTransaction(\n txMeta,\n (error as { message: string }).message,\n 'There was a problem loading this transaction.',\n );\n }\n }\n\n async #onTransactionConfirmed(\n txMeta: TransactionMeta,\n receipt?: SuccessfulTransactionReceipt,\n ): Promise<void> {\n const { id } = txMeta;\n const { blockHash } = receipt ?? {};\n\n this.#log('Transaction confirmed', id);\n\n if (this.#transactionToForcePoll) {\n this.#cleanTransactionToForcePoll(txMeta.id);\n this.hub.emit('transaction-confirmed', txMeta);\n return;\n }\n\n const updatedTxMeta = cloneDeep(txMeta);\n\n if (receipt && blockHash) {\n const { baseFeePerGas, timestamp: blockTimestamp } =\n await this.#getBlockByHash(blockHash, false);\n\n updatedTxMeta.baseFeePerGas = baseFeePerGas;\n updatedTxMeta.blockTimestamp = blockTimestamp;\n updatedTxMeta.txParams = {\n ...updatedTxMeta.txParams,\n gasUsed: receipt.gasUsed,\n };\n updatedTxMeta.txReceipt = receipt;\n updatedTxMeta.verifiedOnBlockchain = true;\n }\n\n updatedTxMeta.status = TransactionStatus.confirmed;\n\n this.#updateTransaction(\n updatedTxMeta,\n 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed',\n );\n\n this.hub.emit('transaction-confirmed', updatedTxMeta);\n }\n\n async #isTransactionTimeout(\n txMeta: TransactionMeta,\n nextNonce: number,\n ): Promise<boolean> {\n const {\n chainId,\n hash,\n id: transactionId,\n txParams: { nonce },\n } = txMeta;\n\n if (!hash || !nonce) {\n return false;\n }\n\n if (!this.#isTimeoutEnabled(txMeta)) {\n this.#log('Timeout disabled for transaction', txMeta);\n return false;\n }\n\n const threshold = getTimeoutAttempts(chainId, this.#messenger);\n\n // Feature is disabled if threshold is undefined or zero\n if (threshold === undefined || threshold === 0) {\n this.#log('Timeout disabled due to threshold', { chainId, threshold });\n return false;\n }\n\n // Skip timeout if this transaction's nonce is a queued transaction with a future nonce\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber > nextNonce) {\n this.#log('Skipping timeout as queued transaction', {\n transactionNonce: nonceNumber,\n nextNonce,\n });\n return false;\n }\n\n try {\n // Check if transaction exists on the network\n const transaction = await this.#getTransactionByHash(hash);\n\n // If transaction exists, reset the counter\n if (transaction !== null) {\n this.#log(\n 'Transaction found on network, resetting timeout counter',\n transactionId,\n );\n\n this.#timeoutCountByHash.delete(hash);\n return false;\n }\n\n // Transaction doesn't exist, increment counter\n let attempts = this.#timeoutCountByHash.get(hash);\n\n attempts ??= 0;\n attempts += 1;\n this.#timeoutCountByHash.set(hash, attempts);\n\n this.#log('Incrementing timeout counter', {\n transactionId,\n attempts,\n threshold,\n });\n\n if (attempts < threshold) {\n return false;\n }\n\n this.#log('Hit timeout threshold', transactionId);\n this.#timeoutCountByHash.delete(hash);\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction not found on network after timeout'),\n );\n\n return true;\n } catch (error) {\n this.#log('Failed to check transaction by hash', transactionId, error);\n return false;\n }\n }\n\n async #isTransactionDropped(\n txMeta: TransactionMeta,\n nextNonce: number,\n ): Promise<boolean> {\n const {\n hash,\n id,\n txParams: { nonce },\n } = txMeta;\n\n /* istanbul ignore next */\n if (!nonce || !hash) {\n return false;\n }\n\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber >= nextNonce) {\n return false;\n }\n\n let droppedBlockCount = this.#droppedBlockCountByHash.get(hash);\n\n if (droppedBlockCount === undefined) {\n droppedBlockCount = 0;\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount);\n }\n\n if (droppedBlockCount < DROPPED_BLOCK_COUNT) {\n this.#log('Incrementing dropped block count', { id, droppedBlockCount });\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount + 1);\n return false;\n }\n\n this.#log('Hit dropped block count', id);\n\n this.#droppedBlockCountByHash.delete(hash);\n return true;\n }\n\n #isNonceTaken(txMeta: TransactionMeta): boolean {\n const { id, txParams } = txMeta;\n\n return this.#getChainTransactions().some(\n (tx) =>\n tx.id !== id &&\n tx.txParams.from === txParams.from &&\n tx.status === TransactionStatus.confirmed &&\n tx.txParams.nonce &&\n tx.txParams.nonce === txParams.nonce &&\n tx.type !== TransactionType.incoming &&\n tx.isTransfer === undefined,\n );\n }\n\n #getPendingTransactions(): TransactionMeta[] {\n return this.#getNetworkClientTransactions().filter(\n (tx) =>\n tx.status === TransactionStatus.submitted &&\n !tx.verifiedOnBlockchain &&\n !tx.isUserOperation,\n );\n }\n\n #warnTransaction(\n txMeta: TransactionMeta,\n error: string,\n message: string,\n ): void {\n this.#updateTransaction(\n {\n ...txMeta,\n warning: { error, message },\n },\n 'PendingTransactionTracker:#warnTransaction - Warning added',\n );\n }\n\n #failTransaction(txMeta: TransactionMeta, error: Error): void {\n this.#log('Transaction failed', txMeta.id, error);\n this.#cleanTransactionToForcePoll(txMeta.id);\n this.hub.emit('transaction-failed', txMeta, error);\n }\n\n #dropTransaction(txMeta: TransactionMeta): void {\n this.#log('Transaction dropped', txMeta.id);\n this.#cleanTransactionToForcePoll(txMeta.id);\n this.hub.emit('transaction-dropped', txMeta);\n }\n\n #updateTransaction(txMeta: TransactionMeta, note: string): void {\n this.hub.emit('transaction-updated', txMeta, note);\n }\n\n async #getTransactionReceipt(\n txHash?: string,\n ): Promise<TransactionReceipt | undefined> {\n return await query(this.#getEthQuery(), 'getTransactionReceipt', [txHash]);\n }\n\n async #getTransactionByHash(txHash?: string): Promise<Json> {\n return await query(this.#getEthQuery(), 'getTransactionByHash', [txHash]);\n }\n\n async #getBlockByHash(\n blockHash: string,\n includeTransactionDetails: boolean,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n return await query(this.#getEthQuery(), 'getBlockByHash', [\n blockHash,\n includeTransactionDetails,\n ]);\n }\n\n async #getNetworkTransactionCount(address: string): Promise<string> {\n return await query(this.#getEthQuery(), 'getTransactionCount', [address]);\n }\n\n #getChainTransactions(): TransactionMeta[] {\n const chainId = this.#getChainId();\n return this.#getTransactions().filter((tx) => tx.chainId === chainId);\n }\n\n #getNetworkClientTransactions(): TransactionMeta[] {\n const networkClientId = this.#getNetworkClientId();\n return this.#getTransactions().filter(\n (tx) => tx.networkClientId === networkClientId,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"PendingTransactionTracker.cjs","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n BlockTracker,\n NetworkClientId,\n} from '@metamask/network-controller';\nimport type { Hex, Json } from '@metamask/utils';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\nimport { cloneDeep, merge } from 'lodash';\n\nimport { TransactionPoller } from './TransactionPoller';\nimport { createModuleLogger, projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { TransactionMeta, TransactionReceipt } from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\nimport {\n getAcceleratedPollingParams,\n getTimeoutAttempts,\n} from '../utils/feature-flags';\n\n/**\n * We wait this many blocks before emitting a 'transaction-dropped' event\n * This is because we could be talking to a node that is out of sync\n */\nconst DROPPED_BLOCK_COUNT = 3;\n\nconst RECEIPT_STATUS_SUCCESS = '0x1';\nconst RECEIPT_STATUS_FAILURE = '0x0';\nconst MAX_RETRY_BLOCK_DISTANCE = 50;\n\nconst KNOWN_TRANSACTION_ERRORS = [\n 'replacement transaction underpriced',\n 'known transaction',\n 'gas price too low to replace',\n 'transaction with the same hash was already imported',\n 'gateway timeout',\n 'nonce too low',\n];\n\nconst log = createModuleLogger(projectLogger, 'pending-transactions');\n\ntype SuccessfulTransactionReceipt = TransactionReceipt & {\n blockNumber: string;\n blockHash: string;\n};\n\ntype Events = {\n 'transaction-confirmed': [txMeta: TransactionMeta];\n 'transaction-dropped': [txMeta: TransactionMeta];\n 'transaction-failed': [txMeta: TransactionMeta, error: Error];\n 'transaction-updated': [txMeta: TransactionMeta, note: string];\n};\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface PendingTransactionTrackerEventEmitter extends EventEmitter {\n on<EventName extends keyof Events>(\n eventName: EventName,\n listener: (...args: Events[EventName]) => void,\n ): this;\n\n emit<EventName extends keyof Events>(\n eventName: EventName,\n ...args: Events[EventName]\n ): boolean;\n}\n\nexport class PendingTransactionTracker {\n hub: PendingTransactionTrackerEventEmitter;\n\n readonly #beforeCheckPendingTransaction: (\n transactionMeta: TransactionMeta,\n ) => Promise<boolean>;\n\n readonly #droppedBlockCountByHash: Map<string, number>;\n\n readonly #isTimeoutEnabled: (transactionMeta: TransactionMeta) => boolean;\n\n readonly #getChainId: () => string;\n\n readonly #getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n\n readonly #getGlobalLock: () => Promise<() => void>;\n\n readonly #getNetworkClientId: () => NetworkClientId;\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #isResubmitEnabled: () => boolean;\n\n readonly #lastSeenTimestampByHash: Map<string, number>;\n\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly #listener: any;\n\n readonly #log: debug.Debugger;\n\n readonly #messenger: TransactionControllerMessenger;\n\n readonly #publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n\n #running: boolean;\n\n readonly #transactionPoller: TransactionPoller;\n\n #transactionToForcePoll: TransactionMeta | undefined;\n\n constructor({\n blockTracker,\n getChainId,\n getEthQuery,\n getGlobalLock,\n getNetworkClientId,\n getTransactions,\n isTimeoutEnabled,\n hooks,\n isResubmitEnabled,\n messenger,\n publishTransaction,\n }: {\n blockTracker: BlockTracker;\n getChainId: () => Hex;\n getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n getGlobalLock: () => Promise<() => void>;\n getNetworkClientId: () => string;\n getTransactions: () => TransactionMeta[];\n hooks?: {\n beforeCheckPendingTransaction?: (\n transactionMeta: TransactionMeta,\n ) => Promise<boolean>;\n };\n isResubmitEnabled?: () => boolean;\n isTimeoutEnabled: (transactionMeta: TransactionMeta) => boolean;\n messenger: TransactionControllerMessenger;\n publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n }) {\n this.hub = new EventEmitter() as PendingTransactionTrackerEventEmitter;\n\n this.#droppedBlockCountByHash = new Map();\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getGlobalLock = getGlobalLock;\n this.#getNetworkClientId = getNetworkClientId;\n this.#getTransactions = getTransactions;\n this.#isResubmitEnabled = isResubmitEnabled ?? ((): boolean => true);\n this.#lastSeenTimestampByHash = new Map();\n this.#listener = this.#onLatestBlock.bind(this);\n this.#messenger = messenger;\n this.#publishTransaction = publishTransaction;\n this.#running = false;\n this.#transactionToForcePoll = undefined;\n\n this.#transactionPoller = new TransactionPoller({\n blockTracker,\n chainId: getChainId(),\n messenger,\n });\n\n this.#beforeCheckPendingTransaction =\n hooks?.beforeCheckPendingTransaction ??\n /* istanbul ignore next */\n ((): Promise<boolean> => Promise.resolve(true));\n\n this.#isTimeoutEnabled = isTimeoutEnabled;\n\n this.#log = createModuleLogger(\n log,\n `${getChainId()}:${getNetworkClientId()}`,\n );\n }\n\n startIfPendingTransactions = (): void => {\n const pendingTransactions = this.#getPendingTransactions();\n\n if (pendingTransactions.length) {\n this.#start(pendingTransactions);\n } else {\n this.stop();\n }\n };\n\n /**\n * Adds a transaction to the polling mechanism for monitoring its status.\n *\n * This method forcefully adds a single transaction to the list of transactions\n * being polled, ensuring that its status is checked, event emitted but no update is performed.\n * It overrides the default behavior by prioritizing the given transaction for polling.\n *\n * @param transactionMeta - The transaction metadata to be added for polling.\n *\n * The transaction will now be monitored for updates, such as confirmation or failure.\n */\n addTransactionToPoll(transactionMeta: TransactionMeta): void {\n this.#start([transactionMeta]);\n this.#transactionToForcePoll = transactionMeta;\n }\n\n /**\n * Force checks the network if the given transaction is confirmed and updates it's status.\n *\n * @param txMeta - The transaction to check\n */\n async forceCheckTransaction(txMeta: TransactionMeta): Promise<void> {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransaction(txMeta);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transaction', error);\n } finally {\n releaseLock();\n }\n }\n\n #start(pendingTransactions: TransactionMeta[]): void {\n this.#transactionPoller.setPendingTransactions(pendingTransactions);\n\n if (this.#running) {\n return;\n }\n\n this.#transactionPoller.start(this.#listener);\n this.#running = true;\n\n this.#log('Started polling');\n }\n\n stop(): void {\n if (!this.#running) {\n return;\n }\n\n this.#transactionPoller.stop();\n this.#running = false;\n\n this.#log('Stopped polling');\n }\n\n async #onLatestBlock(latestBlockNumber: string): Promise<void> {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransactions();\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transactions', error);\n } finally {\n releaseLock();\n }\n\n try {\n await this.#resubmitTransactions(latestBlockNumber);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to resubmit transactions', error);\n }\n }\n\n async #checkTransactions(): Promise<void> {\n this.#log('Checking transactions');\n\n const pendingTransactions: TransactionMeta[] = [\n ...this.#getPendingTransactions(),\n ...(this.#transactionToForcePoll ? [this.#transactionToForcePoll] : []),\n ];\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to check');\n return;\n }\n\n this.#log('Found pending transactions to check', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n await Promise.all(\n pendingTransactions.map((tx) => this.#checkTransaction(tx)),\n );\n }\n\n async #resubmitTransactions(latestBlockNumber: string): Promise<void> {\n if (!this.#isResubmitEnabled() || !this.#running) {\n return;\n }\n\n this.#log('Resubmitting transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to resubmit');\n return;\n }\n\n this.#log('Found pending transactions to resubmit', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n for (const txMeta of pendingTransactions) {\n try {\n await this.#resubmitTransaction(txMeta, latestBlockNumber);\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n /* istanbul ignore next */\n const errorMessage =\n error.value?.message?.toLowerCase() ??\n error.message?.toLowerCase() ??\n String(error);\n\n if (this.#isKnownTransactionError(errorMessage)) {\n this.#log('Ignoring known transaction error', errorMessage);\n continue;\n }\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was an error when resubmitting this transaction.',\n );\n }\n }\n }\n\n #isKnownTransactionError(errorMessage: string): boolean {\n return KNOWN_TRANSACTION_ERRORS.some((knownError) =>\n errorMessage.includes(knownError),\n );\n }\n\n async #resubmitTransaction(\n txMeta: TransactionMeta,\n latestBlockNumber: string,\n ): Promise<void> {\n if (!this.#isResubmitDue(txMeta, latestBlockNumber)) {\n return;\n }\n\n if (!(await this.#beforeCheckPendingTransaction(txMeta))) {\n return;\n }\n\n const ethQuery = this.#getEthQuery(txMeta.networkClientId);\n await this.#publishTransaction(ethQuery, txMeta);\n\n const retryCount = (txMeta.retryCount ?? 0) + 1;\n\n this.#updateTransaction(\n merge({}, txMeta, { retryCount }),\n 'PendingTransactionTracker:transaction-retry - Retry count increased',\n );\n }\n\n #isResubmitDue(txMeta: TransactionMeta, latestBlockNumber: string): boolean {\n const txMetaWithFirstRetryBlockNumber = cloneDeep(txMeta);\n\n if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {\n txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;\n\n this.#updateTransaction(\n txMetaWithFirstRetryBlockNumber,\n 'PendingTransactionTracker:#isResubmitDue - First retry block number set',\n );\n }\n\n const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;\n\n const blocksSinceFirstRetry =\n Number.parseInt(latestBlockNumber, 16) -\n Number.parseInt(firstRetryBlockNumber, 16);\n\n const retryCount = txMeta.retryCount ?? 0;\n\n // Exponential backoff to limit retries at publishing\n // Capped at ~15 minutes between retries\n const requiredBlocksSinceFirstRetry = Math.min(\n MAX_RETRY_BLOCK_DISTANCE,\n Math.pow(2, retryCount),\n );\n\n return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;\n }\n\n #cleanTransaction(txMeta: TransactionMeta): void {\n const { hash, id } = txMeta;\n\n if (this.#transactionToForcePoll?.id === id) {\n this.#transactionToForcePoll = undefined;\n }\n\n if (hash) {\n this.#lastSeenTimestampByHash.delete(hash);\n }\n }\n\n async #checkTransaction(txMeta: TransactionMeta): Promise<void> {\n const {\n hash,\n id,\n isIntentComplete,\n txParams: { from },\n } = txMeta;\n\n if (isIntentComplete) {\n await this.#onTransactionConfirmed(txMeta);\n return;\n }\n\n if (!hash && (await this.#beforeCheckPendingTransaction(txMeta))) {\n const error = new Error(\n 'We had an error while submitting this transaction, please try again.',\n );\n\n error.name = 'NoTxHashError';\n\n this.#failTransaction(txMeta, error);\n\n return;\n }\n\n if (this.#isNonceTaken(txMeta)) {\n this.#log('Nonce already taken', id);\n this.#dropTransaction(txMeta);\n return;\n }\n\n try {\n const receipt = await this.#getTransactionReceipt(hash);\n const isSuccess = receipt?.status === RECEIPT_STATUS_SUCCESS;\n const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;\n\n if (isFailure) {\n this.#log('Transaction receipt has failed status');\n\n this.#failTransaction(txMeta, new Error('Transaction failed on-chain'));\n\n return;\n }\n\n const { blockNumber, blockHash } = receipt ?? {};\n\n if (isSuccess && blockNumber && blockHash) {\n await this.#onTransactionConfirmed(txMeta, {\n ...receipt,\n blockNumber,\n blockHash,\n });\n\n return;\n }\n\n this.#log('No receipt status', { hash, receipt });\n\n const nextNonceHex = await this.#getNetworkTransactionCount(from);\n const nextNonce = parseInt(nextNonceHex, 16);\n\n // Check if transaction should be failed due to no receipt\n if (!receipt && (await this.#isTransactionTimeout(txMeta, nextNonce))) {\n return;\n }\n\n if (await this.#isTransactionDropped(txMeta, nextNonce)) {\n this.#dropTransaction(txMeta);\n }\n } catch (error) {\n this.#log('Failed to check transaction', id, error);\n\n this.#warnTransaction(\n txMeta,\n (error as { message: string }).message,\n 'There was a problem loading this transaction.',\n );\n }\n }\n\n async #onTransactionConfirmed(\n txMeta: TransactionMeta,\n receipt?: SuccessfulTransactionReceipt,\n ): Promise<void> {\n const { id } = txMeta;\n const { blockHash } = receipt ?? {};\n\n this.#log('Transaction confirmed', id);\n\n const isForcePollTransaction = this.#transactionToForcePoll?.id === id;\n\n this.#cleanTransaction(txMeta);\n\n if (isForcePollTransaction) {\n this.hub.emit('transaction-confirmed', txMeta);\n return;\n }\n\n const updatedTxMeta = cloneDeep(txMeta);\n\n if (receipt && blockHash) {\n const { baseFeePerGas, timestamp: blockTimestamp } =\n await this.#getBlockByHash(blockHash, false);\n\n updatedTxMeta.baseFeePerGas = baseFeePerGas;\n updatedTxMeta.blockTimestamp = blockTimestamp;\n updatedTxMeta.txParams = {\n ...updatedTxMeta.txParams,\n gasUsed: receipt.gasUsed,\n };\n updatedTxMeta.txReceipt = receipt;\n updatedTxMeta.verifiedOnBlockchain = true;\n }\n\n updatedTxMeta.status = TransactionStatus.confirmed;\n\n this.#updateTransaction(\n updatedTxMeta,\n 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed',\n );\n\n this.hub.emit('transaction-confirmed', updatedTxMeta);\n }\n\n async #isTransactionTimeout(\n txMeta: TransactionMeta,\n nextNonce: number,\n ): Promise<boolean> {\n const {\n chainId,\n hash,\n id: transactionId,\n submittedTime,\n txParams: { nonce },\n } = txMeta;\n\n if (!hash || !nonce) {\n return false;\n }\n\n if (!this.#isTimeoutEnabled(txMeta)) {\n this.#log('Timeout disabled for transaction', txMeta);\n return false;\n }\n\n const threshold = getTimeoutAttempts(chainId, this.#messenger);\n\n // Feature is disabled if threshold is undefined or zero\n if (threshold === undefined || threshold === 0) {\n this.#log('Timeout disabled due to threshold', { chainId, threshold });\n return false;\n }\n\n // Skip timeout if this transaction's nonce is a queued transaction with a future nonce\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber > nextNonce) {\n this.#log('Skipping timeout as queued transaction', {\n transactionNonce: nonceNumber,\n nextNonce,\n });\n return false;\n }\n\n try {\n // Check if transaction exists on the network\n const transaction = await this.#getTransactionByHash(hash);\n\n // If transaction exists, record the timestamp\n if (transaction !== null) {\n const currentTimestamp = Date.now();\n\n this.#log(\n 'Transaction found on network, recording timestamp',\n transactionId,\n );\n\n this.#lastSeenTimestampByHash.set(hash, currentTimestamp);\n return false;\n }\n\n const lastSeenTimestamp =\n this.#lastSeenTimestampByHash.get(hash) ?? submittedTime;\n\n if (lastSeenTimestamp === undefined) {\n this.#log(\n 'Transaction not yet seen on network and has no submitted time, skipping timeout check',\n transactionId,\n );\n\n return false;\n }\n\n const { blockTime } = getAcceleratedPollingParams(\n chainId,\n this.#messenger,\n );\n\n const currentTimestamp = Date.now();\n const durationSinceLastSeen = currentTimestamp - lastSeenTimestamp;\n const timeoutDuration = blockTime * threshold;\n\n this.#log('Checking timeout duration', {\n transactionId,\n durationSinceLastSeen,\n timeoutDuration,\n threshold,\n blockTime,\n });\n\n if (durationSinceLastSeen < timeoutDuration) {\n return false;\n }\n\n this.#log('Hit timeout duration threshold', transactionId);\n this.#lastSeenTimestampByHash.delete(hash);\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction not found on network after timeout'),\n );\n\n return true;\n } catch (error) {\n this.#log('Failed to check transaction by hash', transactionId, error);\n return false;\n }\n }\n\n async #isTransactionDropped(\n txMeta: TransactionMeta,\n nextNonce: number,\n ): Promise<boolean> {\n const {\n hash,\n id,\n txParams: { nonce },\n } = txMeta;\n\n /* istanbul ignore next */\n if (!nonce || !hash) {\n return false;\n }\n\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber >= nextNonce) {\n return false;\n }\n\n let droppedBlockCount = this.#droppedBlockCountByHash.get(hash);\n\n if (droppedBlockCount === undefined) {\n droppedBlockCount = 0;\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount);\n }\n\n if (droppedBlockCount < DROPPED_BLOCK_COUNT) {\n this.#log('Incrementing dropped block count', { id, droppedBlockCount });\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount + 1);\n return false;\n }\n\n this.#log('Hit dropped block count', id);\n\n this.#droppedBlockCountByHash.delete(hash);\n return true;\n }\n\n #isNonceTaken(txMeta: TransactionMeta): boolean {\n const { id, txParams } = txMeta;\n\n return this.#getChainTransactions().some(\n (tx) =>\n tx.id !== id &&\n tx.txParams.from === txParams.from &&\n tx.status === TransactionStatus.confirmed &&\n tx.txParams.nonce &&\n tx.txParams.nonce === txParams.nonce &&\n tx.type !== TransactionType.incoming &&\n tx.isTransfer === undefined,\n );\n }\n\n #getPendingTransactions(): TransactionMeta[] {\n return this.#getNetworkClientTransactions().filter(\n (tx) =>\n tx.status === TransactionStatus.submitted &&\n !tx.verifiedOnBlockchain &&\n !tx.isUserOperation,\n );\n }\n\n #warnTransaction(\n txMeta: TransactionMeta,\n error: string,\n message: string,\n ): void {\n this.#updateTransaction(\n {\n ...txMeta,\n warning: { error, message },\n },\n 'PendingTransactionTracker:#warnTransaction - Warning added',\n );\n }\n\n #failTransaction(txMeta: TransactionMeta, error: Error): void {\n this.#log('Transaction failed', txMeta.id, error);\n this.#cleanTransaction(txMeta);\n this.hub.emit('transaction-failed', txMeta, error);\n }\n\n #dropTransaction(txMeta: TransactionMeta): void {\n this.#log('Transaction dropped', txMeta.id);\n this.#cleanTransaction(txMeta);\n this.hub.emit('transaction-dropped', txMeta);\n }\n\n #updateTransaction(txMeta: TransactionMeta, note: string): void {\n this.hub.emit('transaction-updated', txMeta, note);\n }\n\n async #getTransactionReceipt(\n txHash?: string,\n ): Promise<TransactionReceipt | undefined> {\n return await query(this.#getEthQuery(), 'getTransactionReceipt', [txHash]);\n }\n\n async #getTransactionByHash(txHash?: string): Promise<Json> {\n return await query(this.#getEthQuery(), 'getTransactionByHash', [txHash]);\n }\n\n async #getBlockByHash(\n blockHash: string,\n includeTransactionDetails: boolean,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n return await query(this.#getEthQuery(), 'getBlockByHash', [\n blockHash,\n includeTransactionDetails,\n ]);\n }\n\n async #getNetworkTransactionCount(address: string): Promise<string> {\n return await query(this.#getEthQuery(), 'getTransactionCount', [address]);\n }\n\n #getChainTransactions(): TransactionMeta[] {\n const chainId = this.#getChainId();\n return this.#getTransactions().filter((tx) => tx.chainId === chainId);\n }\n\n #getNetworkClientTransactions(): TransactionMeta[] {\n const networkClientId = this.#getNetworkClientId();\n return this.#getTransactions().filter(\n (tx) => tx.networkClientId === networkClientId,\n );\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PendingTransactionTracker.d.cts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAQ,wBAAwB;AAGjD,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA8BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,SAAS,SAAS,MAAM,MAAM,EAC/B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAC7C,IAAI,CAAC;IAER,IAAI,CAAC,SAAS,SAAS,MAAM,MAAM,EACjC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GACzB,OAAO,CAAC;CACZ;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBA2C/B,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,iBAAiB,EACjB,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,WAAW,EAAE,CAAC,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC7D,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,kBAAkB,EAAE,MAAM,MAAM,CAAC;QACjC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;SACvB,CAAC;QACF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;QAClC,gBAAgB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;QAChE,SAAS,EAAE,8BAA8B,CAAC;QAC1C,kBAAkB,EAAE,CAClB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC;KACtB;IAoCD,0BAA0B,QAAO,IAAI,CAQnC;IAEF;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAK5D;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,IAAI,IAAI,IAAI;CAyfb"}
1
+ {"version":3,"file":"PendingTransactionTracker.d.cts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAQ,wBAAwB;AAGjD,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AAiCpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,SAAS,SAAS,MAAM,MAAM,EAC/B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAC7C,IAAI,CAAC;IAER,IAAI,CAAC,SAAS,SAAS,MAAM,MAAM,EACjC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GACzB,OAAO,CAAC;CACZ;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBA2C/B,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,iBAAiB,EACjB,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,WAAW,EAAE,CAAC,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC7D,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,kBAAkB,EAAE,MAAM,MAAM,CAAC;QACjC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;SACvB,CAAC;QACF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;QAClC,gBAAgB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;QAChE,SAAS,EAAE,8BAA8B,CAAC;QAC1C,kBAAkB,EAAE,CAClB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC;KACtB;IAoCD,0BAA0B,QAAO,IAAI,CAQnC;IAEF;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAK5D;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,IAAI,IAAI,IAAI;CAkhBb"}
@@ -1 +1 @@
1
- {"version":3,"file":"PendingTransactionTracker.d.mts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAQ,wBAAwB;AAGjD,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA8BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,SAAS,SAAS,MAAM,MAAM,EAC/B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAC7C,IAAI,CAAC;IAER,IAAI,CAAC,SAAS,SAAS,MAAM,MAAM,EACjC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GACzB,OAAO,CAAC;CACZ;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBA2C/B,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,iBAAiB,EACjB,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,WAAW,EAAE,CAAC,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC7D,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,kBAAkB,EAAE,MAAM,MAAM,CAAC;QACjC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;SACvB,CAAC;QACF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;QAClC,gBAAgB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;QAChE,SAAS,EAAE,8BAA8B,CAAC;QAC1C,kBAAkB,EAAE,CAClB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC;KACtB;IAoCD,0BAA0B,QAAO,IAAI,CAQnC;IAEF;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAK5D;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,IAAI,IAAI,IAAI;CAyfb"}
1
+ {"version":3,"file":"PendingTransactionTracker.d.mts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAQ,wBAAwB;AAGjD,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AAiCpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,SAAS,SAAS,MAAM,MAAM,EAC/B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAC7C,IAAI,CAAC;IAER,IAAI,CAAC,SAAS,SAAS,MAAM,MAAM,EACjC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GACzB,OAAO,CAAC;CACZ;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBA2C/B,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,iBAAiB,EACjB,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,WAAW,EAAE,CAAC,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC7D,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,kBAAkB,EAAE,MAAM,MAAM,CAAC;QACjC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;SACvB,CAAC;QACF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;QAClC,gBAAgB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;QAChE,SAAS,EAAE,8BAA8B,CAAC;QAC1C,kBAAkB,EAAE,CAClB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC;KACtB;IAoCD,0BAA0B,QAAO,IAAI,CAQnC;IAEF;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAK5D;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,IAAI,IAAI,IAAI;CAkhBb"}
@@ -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 _PendingTransactionTracker_instances, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_isTimeoutEnabled, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_getNetworkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_messenger, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_timeoutCountByHash, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_transactionToForcePoll, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_cleanTransactionToForcePoll, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionTimeout, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getTransactionByHash, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
12
+ var _PendingTransactionTracker_instances, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_isTimeoutEnabled, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_getNetworkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_lastSeenTimestampByHash, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_messenger, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_transactionToForcePoll, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_cleanTransaction, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionTimeout, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getTransactionByHash, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
13
13
  import { query } from "@metamask/controller-utils";
14
14
  // This package purposefully relies on Node's EventEmitter module.
15
15
  // eslint-disable-next-line import-x/no-nodejs-modules
@@ -19,7 +19,7 @@ const { cloneDeep, merge } = $lodash;
19
19
  import { TransactionPoller } from "./TransactionPoller.mjs";
20
20
  import { createModuleLogger, projectLogger } from "../logger.mjs";
21
21
  import { TransactionStatus, TransactionType } from "../types.mjs";
22
- import { getTimeoutAttempts } from "../utils/feature-flags.mjs";
22
+ import { getAcceleratedPollingParams, getTimeoutAttempts } from "../utils/feature-flags.mjs";
23
23
  /**
24
24
  * We wait this many blocks before emitting a 'transaction-dropped' event
25
25
  * This is because we could be talking to a node that is out of sync
@@ -49,6 +49,7 @@ export class PendingTransactionTracker {
49
49
  _PendingTransactionTracker_getNetworkClientId.set(this, void 0);
50
50
  _PendingTransactionTracker_getTransactions.set(this, void 0);
51
51
  _PendingTransactionTracker_isResubmitEnabled.set(this, void 0);
52
+ _PendingTransactionTracker_lastSeenTimestampByHash.set(this, void 0);
52
53
  // TODO: Replace `any` with type
53
54
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
55
  _PendingTransactionTracker_listener.set(this, void 0);
@@ -56,7 +57,6 @@ export class PendingTransactionTracker {
56
57
  _PendingTransactionTracker_messenger.set(this, void 0);
57
58
  _PendingTransactionTracker_publishTransaction.set(this, void 0);
58
59
  _PendingTransactionTracker_running.set(this, void 0);
59
- _PendingTransactionTracker_timeoutCountByHash.set(this, void 0);
60
60
  _PendingTransactionTracker_transactionPoller.set(this, void 0);
61
61
  _PendingTransactionTracker_transactionToForcePoll.set(this, void 0);
62
62
  this.startIfPendingTransactions = () => {
@@ -76,11 +76,11 @@ export class PendingTransactionTracker {
76
76
  __classPrivateFieldSet(this, _PendingTransactionTracker_getNetworkClientId, getNetworkClientId, "f");
77
77
  __classPrivateFieldSet(this, _PendingTransactionTracker_getTransactions, getTransactions, "f");
78
78
  __classPrivateFieldSet(this, _PendingTransactionTracker_isResubmitEnabled, isResubmitEnabled ?? (() => true), "f");
79
+ __classPrivateFieldSet(this, _PendingTransactionTracker_lastSeenTimestampByHash, new Map(), "f");
79
80
  __classPrivateFieldSet(this, _PendingTransactionTracker_listener, __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_onLatestBlock).bind(this), "f");
80
81
  __classPrivateFieldSet(this, _PendingTransactionTracker_messenger, messenger, "f");
81
82
  __classPrivateFieldSet(this, _PendingTransactionTracker_publishTransaction, publishTransaction, "f");
82
83
  __classPrivateFieldSet(this, _PendingTransactionTracker_running, false, "f");
83
- __classPrivateFieldSet(this, _PendingTransactionTracker_timeoutCountByHash, new Map(), "f");
84
84
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionToForcePoll, undefined, "f");
85
85
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionPoller, new TransactionPoller({
86
86
  blockTracker,
@@ -135,7 +135,7 @@ export class PendingTransactionTracker {
135
135
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Stopped polling');
136
136
  }
137
137
  }
138
- _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_isTimeoutEnabled = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_getNetworkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_messenger = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_timeoutCountByHash = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_transactionToForcePoll = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
138
+ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_isTimeoutEnabled = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_getNetworkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_lastSeenTimestampByHash = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_messenger = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_transactionToForcePoll = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
139
139
  __classPrivateFieldGet(this, _PendingTransactionTracker_transactionPoller, "f").setPendingTransactions(pendingTransactions);
140
140
  if (__classPrivateFieldGet(this, _PendingTransactionTracker_running, "f")) {
141
141
  return;
@@ -236,10 +236,14 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
236
236
  // Capped at ~15 minutes between retries
237
237
  const requiredBlocksSinceFirstRetry = Math.min(MAX_RETRY_BLOCK_DISTANCE, Math.pow(2, retryCount));
238
238
  return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;
239
- }, _PendingTransactionTracker_cleanTransactionToForcePoll = function _PendingTransactionTracker_cleanTransactionToForcePoll(transactionId) {
240
- if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === transactionId) {
239
+ }, _PendingTransactionTracker_cleanTransaction = function _PendingTransactionTracker_cleanTransaction(txMeta) {
240
+ const { hash, id } = txMeta;
241
+ if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === id) {
241
242
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionToForcePoll, undefined, "f");
242
243
  }
244
+ if (hash) {
245
+ __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").delete(hash);
246
+ }
243
247
  }, _PendingTransactionTracker_checkTransaction = async function _PendingTransactionTracker_checkTransaction(txMeta) {
244
248
  const { hash, id, isIntentComplete, txParams: { from }, } = txMeta;
245
249
  if (isIntentComplete) {
@@ -263,7 +267,7 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
263
267
  const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;
264
268
  if (isFailure) {
265
269
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction receipt has failed status');
266
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_failTransaction).call(this, txMeta, new Error('Transaction dropped or replaced'));
270
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_failTransaction).call(this, txMeta, new Error('Transaction failed on-chain'));
267
271
  return;
268
272
  }
269
273
  const { blockNumber, blockHash } = receipt ?? {};
@@ -294,8 +298,9 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
294
298
  const { id } = txMeta;
295
299
  const { blockHash } = receipt ?? {};
296
300
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction confirmed', id);
297
- if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")) {
298
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransactionToForcePoll).call(this, txMeta.id);
301
+ const isForcePollTransaction = __classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === id;
302
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransaction).call(this, txMeta);
303
+ if (isForcePollTransaction) {
299
304
  this.hub.emit('transaction-confirmed', txMeta);
300
305
  return;
301
306
  }
@@ -315,7 +320,7 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
315
320
  __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_updateTransaction).call(this, updatedTxMeta, 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed');
316
321
  this.hub.emit('transaction-confirmed', updatedTxMeta);
317
322
  }, _PendingTransactionTracker_isTransactionTimeout = async function _PendingTransactionTracker_isTransactionTimeout(txMeta, nextNonce) {
318
- const { chainId, hash, id: transactionId, txParams: { nonce }, } = txMeta;
323
+ const { chainId, hash, id: transactionId, submittedTime, txParams: { nonce }, } = txMeta;
319
324
  if (!hash || !nonce) {
320
325
  return false;
321
326
  }
@@ -341,27 +346,34 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
341
346
  try {
342
347
  // Check if transaction exists on the network
343
348
  const transaction = await __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getTransactionByHash).call(this, hash);
344
- // If transaction exists, reset the counter
349
+ // If transaction exists, record the timestamp
345
350
  if (transaction !== null) {
346
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction found on network, resetting timeout counter', transactionId);
347
- __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").delete(hash);
351
+ const currentTimestamp = Date.now();
352
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction found on network, recording timestamp', transactionId);
353
+ __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").set(hash, currentTimestamp);
354
+ return false;
355
+ }
356
+ const lastSeenTimestamp = __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").get(hash) ?? submittedTime;
357
+ if (lastSeenTimestamp === undefined) {
358
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction not yet seen on network and has no submitted time, skipping timeout check', transactionId);
348
359
  return false;
349
360
  }
350
- // Transaction doesn't exist, increment counter
351
- let attempts = __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").get(hash);
352
- attempts ?? (attempts = 0);
353
- attempts += 1;
354
- __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").set(hash, attempts);
355
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Incrementing timeout counter', {
361
+ const { blockTime } = getAcceleratedPollingParams(chainId, __classPrivateFieldGet(this, _PendingTransactionTracker_messenger, "f"));
362
+ const currentTimestamp = Date.now();
363
+ const durationSinceLastSeen = currentTimestamp - lastSeenTimestamp;
364
+ const timeoutDuration = blockTime * threshold;
365
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Checking timeout duration', {
356
366
  transactionId,
357
- attempts,
367
+ durationSinceLastSeen,
368
+ timeoutDuration,
358
369
  threshold,
370
+ blockTime,
359
371
  });
360
- if (attempts < threshold) {
372
+ if (durationSinceLastSeen < timeoutDuration) {
361
373
  return false;
362
374
  }
363
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Hit timeout threshold', transactionId);
364
- __classPrivateFieldGet(this, _PendingTransactionTracker_timeoutCountByHash, "f").delete(hash);
375
+ __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Hit timeout duration threshold', transactionId);
376
+ __classPrivateFieldGet(this, _PendingTransactionTracker_lastSeenTimestampByHash, "f").delete(hash);
365
377
  __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_failTransaction).call(this, txMeta, new Error('Transaction not found on network after timeout'));
366
378
  return true;
367
379
  }
@@ -412,11 +424,11 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
412
424
  }, 'PendingTransactionTracker:#warnTransaction - Warning added');
413
425
  }, _PendingTransactionTracker_failTransaction = function _PendingTransactionTracker_failTransaction(txMeta, error) {
414
426
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction failed', txMeta.id, error);
415
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransactionToForcePoll).call(this, txMeta.id);
427
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransaction).call(this, txMeta);
416
428
  this.hub.emit('transaction-failed', txMeta, error);
417
429
  }, _PendingTransactionTracker_dropTransaction = function _PendingTransactionTracker_dropTransaction(txMeta) {
418
430
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Transaction dropped', txMeta.id);
419
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransactionToForcePoll).call(this, txMeta.id);
431
+ __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_cleanTransaction).call(this, txMeta);
420
432
  this.hub.emit('transaction-dropped', txMeta);
421
433
  }, _PendingTransactionTracker_updateTransaction = function _PendingTransactionTracker_updateTransaction(txMeta, note) {
422
434
  this.hub.emit('transaction-updated', txMeta, note);