@metamask/transaction-controller 52.3.0 → 54.0.0

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 (80) hide show
  1. package/CHANGELOG.md +52 -1
  2. package/dist/TransactionController.cjs +133 -119
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +25 -30
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +25 -30
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +133 -119
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/helpers/GasFeePoller.cjs +2 -1
  11. package/dist/helpers/GasFeePoller.cjs.map +1 -1
  12. package/dist/helpers/GasFeePoller.d.cts +1 -1
  13. package/dist/helpers/GasFeePoller.d.cts.map +1 -1
  14. package/dist/helpers/GasFeePoller.d.mts +1 -1
  15. package/dist/helpers/GasFeePoller.d.mts.map +1 -1
  16. package/dist/helpers/GasFeePoller.mjs +2 -1
  17. package/dist/helpers/GasFeePoller.mjs.map +1 -1
  18. package/dist/helpers/PendingTransactionTracker.cjs +8 -7
  19. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  20. package/dist/helpers/PendingTransactionTracker.d.cts +1 -2
  21. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  22. package/dist/helpers/PendingTransactionTracker.d.mts +1 -2
  23. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  24. package/dist/helpers/PendingTransactionTracker.mjs +8 -7
  25. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +2 -2
  28. package/dist/index.d.cts.map +1 -1
  29. package/dist/index.d.mts +2 -2
  30. package/dist/index.d.mts.map +1 -1
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/types.cjs +4 -0
  33. package/dist/types.cjs.map +1 -1
  34. package/dist/types.d.cts +60 -8
  35. package/dist/types.d.cts.map +1 -1
  36. package/dist/types.d.mts +60 -8
  37. package/dist/types.d.mts.map +1 -1
  38. package/dist/types.mjs +4 -0
  39. package/dist/types.mjs.map +1 -1
  40. package/dist/utils/batch.cjs +16 -8
  41. package/dist/utils/batch.cjs.map +1 -1
  42. package/dist/utils/batch.d.cts +4 -3
  43. package/dist/utils/batch.d.cts.map +1 -1
  44. package/dist/utils/batch.d.mts +4 -3
  45. package/dist/utils/batch.d.mts.map +1 -1
  46. package/dist/utils/batch.mjs +16 -8
  47. package/dist/utils/batch.mjs.map +1 -1
  48. package/dist/utils/feature-flags.cjs +21 -1
  49. package/dist/utils/feature-flags.cjs.map +1 -1
  50. package/dist/utils/feature-flags.d.cts +35 -0
  51. package/dist/utils/feature-flags.d.cts.map +1 -1
  52. package/dist/utils/feature-flags.d.mts +35 -0
  53. package/dist/utils/feature-flags.d.mts.map +1 -1
  54. package/dist/utils/feature-flags.mjs +19 -0
  55. package/dist/utils/feature-flags.mjs.map +1 -1
  56. package/dist/utils/gas.cjs +10 -4
  57. package/dist/utils/gas.cjs.map +1 -1
  58. package/dist/utils/gas.d.cts +5 -2
  59. package/dist/utils/gas.d.cts.map +1 -1
  60. package/dist/utils/gas.d.mts +5 -2
  61. package/dist/utils/gas.d.mts.map +1 -1
  62. package/dist/utils/gas.mjs +10 -4
  63. package/dist/utils/gas.mjs.map +1 -1
  64. package/dist/utils/nonce.cjs +4 -1
  65. package/dist/utils/nonce.cjs.map +1 -1
  66. package/dist/utils/nonce.d.cts +1 -1
  67. package/dist/utils/nonce.d.cts.map +1 -1
  68. package/dist/utils/nonce.d.mts +1 -1
  69. package/dist/utils/nonce.d.mts.map +1 -1
  70. package/dist/utils/nonce.mjs +4 -1
  71. package/dist/utils/nonce.mjs.map +1 -1
  72. package/dist/utils/validation.cjs +14 -13
  73. package/dist/utils/validation.cjs.map +1 -1
  74. package/dist/utils/validation.d.cts +3 -1
  75. package/dist/utils/validation.d.cts.map +1 -1
  76. package/dist/utils/validation.d.mts +3 -1
  77. package/dist/utils/validation.d.mts.map +1 -1
  78. package/dist/utils/validation.mjs +14 -13
  79. package/dist/utils/validation.mjs.map +1 -1
  80. package/package.json +3 -3
@@ -9,7 +9,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
11
  };
12
- var _TransactionController_instances, _TransactionController_internalEvents, _TransactionController_methodDataHelper, _TransactionController_incomingTransactionHelper, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_publishBatchHook, _TransactionController_publicKeyEIP7702, _TransactionController_trace, _TransactionController_transactionHistoryLimit, _TransactionController_isFirstTimeInteractionEnabled, _TransactionController_isSimulationEnabled, _TransactionController_testGasFeeFlows, _TransactionController_multichainTrackingHelper, _TransactionController_retryTransaction, _TransactionController_rejectTransaction, _TransactionController_getChainId, _TransactionController_getNetworkClientId, _TransactionController_getEthQuery, _TransactionController_getProvider, _TransactionController_createNonceTracker, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_getLayer1GasFeeFlows, _TransactionController_updateTransactionInternal, _TransactionController_updateFirstTimeInteraction, _TransactionController_updateSimulationData, _TransactionController_onGasFeePollerTransactionUpdate, _TransactionController_getSelectedAccount, _TransactionController_getInternalAccounts, _TransactionController_updateSubmitHistory, _TransactionController_updateGasEstimate, _TransactionController_deleteTransaction, _TransactionController_isRejectError, _TransactionController_rejectTransactionAndThrow;
12
+ var _TransactionController_instances, _TransactionController_internalEvents, _TransactionController_methodDataHelper, _TransactionController_incomingTransactionHelper, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_publishBatchHook, _TransactionController_publicKeyEIP7702, _TransactionController_trace, _TransactionController_transactionHistoryLimit, _TransactionController_isFirstTimeInteractionEnabled, _TransactionController_isSimulationEnabled, _TransactionController_testGasFeeFlows, _TransactionController_multichainTrackingHelper, _TransactionController_retryTransaction, _TransactionController_rejectTransaction, _TransactionController_getChainId, _TransactionController_getNetworkClientId, _TransactionController_getEthQuery, _TransactionController_getProvider, _TransactionController_markNonceDuplicatesDropped, _TransactionController_signTransaction, _TransactionController_onConfirmedTransaction, _TransactionController_createNonceTracker, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_getLayer1GasFeeFlows, _TransactionController_updateTransactionInternal, _TransactionController_updateFirstTimeInteraction, _TransactionController_updateSimulationData, _TransactionController_onGasFeePollerTransactionUpdate, _TransactionController_getSelectedAccount, _TransactionController_getInternalAccounts, _TransactionController_updateSubmitHistory, _TransactionController_updateGasEstimate, _TransactionController_registerActionHandlers, _TransactionController_deleteTransaction, _TransactionController_isRejectError, _TransactionController_rejectTransactionAndThrow;
13
13
  function $importDefault(module) {
14
14
  if (module?.__esModule) {
15
15
  return module.default;
@@ -159,7 +159,7 @@ export class TransactionController extends BaseController {
159
159
  * @param options - The controller options.
160
160
  */
161
161
  constructor(options) {
162
- const { disableHistory, disableSendFlowHistory, disableSwaps, enableTxParamsGasFeeUpdates, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, incomingTransactions = {}, isFirstTimeInteractionEnabled, isSimulationEnabled, messenger, pendingTransactions = {}, publicKeyEIP7702, securityProviderRequest, sign, state, testGasFeeFlows, trace, transactionHistoryLimit = 40, hooks, } = options;
162
+ const { disableHistory, disableSendFlowHistory, disableSwaps, isAutomaticGasFeeUpdateEnabled, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, incomingTransactions = {}, isFirstTimeInteractionEnabled, isSimulationEnabled, messenger, pendingTransactions = {}, publicKeyEIP7702, securityProviderRequest, sign, state, testGasFeeFlows, trace, transactionHistoryLimit = 40, hooks, } = options;
163
163
  super({
164
164
  name: controllerName,
165
165
  metadata,
@@ -189,7 +189,8 @@ export class TransactionController extends BaseController {
189
189
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
190
190
  });
191
191
  this.messagingSystem = messenger;
192
- this.isTxParamsGasFeeUpdatesEnabled = enableTxParamsGasFeeUpdates ?? false;
192
+ this.isTxParamsGasFeeUpdatesEnabled =
193
+ isAutomaticGasFeeUpdateEnabled ?? ((_txMeta) => false);
193
194
  this.getNetworkState = getNetworkState;
194
195
  this.isSendFlowHistoryDisabled = disableSendFlowHistory ?? false;
195
196
  this.isHistoryDisabled = disableHistory ?? false;
@@ -217,10 +218,9 @@ export class TransactionController extends BaseController {
217
218
  __classPrivateFieldSet(this, _TransactionController_trace, trace ?? ((_request, fn) => fn?.()), "f");
218
219
  this.afterSign = hooks?.afterSign ?? (() => true);
219
220
  this.beforeCheckPendingTransaction =
220
- hooks?.beforeCheckPendingTransaction ??
221
- /* istanbul ignore next */
222
- (() => true);
223
- this.beforePublish = hooks?.beforePublish ?? (() => true);
221
+ /* istanbul ignore next */
222
+ hooks?.beforeCheckPendingTransaction ?? (() => Promise.resolve(true));
223
+ this.beforePublish = hooks?.beforePublish ?? (() => Promise.resolve(true));
224
224
  this.getAdditionalSignArguments =
225
225
  hooks?.getAdditionalSignArguments ?? (() => []);
226
226
  this.publish =
@@ -296,6 +296,7 @@ export class TransactionController extends BaseController {
296
296
  });
297
297
  this.onBootCleanup();
298
298
  __classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f").call(this);
299
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_registerActionHandlers).call(this);
299
300
  }
300
301
  /**
301
302
  * Stops polling and removes listeners to prepare the controller for garbage collection.
@@ -336,12 +337,12 @@ export class TransactionController extends BaseController {
336
337
  /**
337
338
  * Determine which chains support atomic batch transactions with the given account address.
338
339
  *
339
- * @param address - The address of the account to check.
340
- * @returns The supported chain IDs.
340
+ * @param request - Request object containing the account address and other parameters.
341
+ * @returns Result object containing the supported chains and related information.
341
342
  */
342
- async isAtomicBatchSupported(address) {
343
+ async isAtomicBatchSupported(request) {
343
344
  return isAtomicBatchSupported({
344
- address,
345
+ ...request,
345
346
  getEthQuery: (chainId) => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, { chainId }),
346
347
  messenger: this.messagingSystem,
347
348
  publicKeyEIP7702: __classPrivateFieldGet(this, _TransactionController_publicKeyEIP7702, "f"),
@@ -401,7 +402,7 @@ export class TransactionController extends BaseController {
401
402
  });
402
403
  const delegationAddressPromise = getDelegationAddress(txParams.from, ethQuery).catch(() => undefined);
403
404
  const isEIP1559Compatible = await this.getEIP1559Compatibility(networkClientId);
404
- validateTxParams(txParams, isEIP1559Compatible);
405
+ validateTxParams(txParams, isEIP1559Compatible, chainId);
405
406
  if (!txParams.type) {
406
407
  // Determine transaction type based on transaction parameters and network compatibility
407
408
  setEnvelopeType(txParams, isEIP1559Compatible);
@@ -570,6 +571,7 @@ export class TransactionController extends BaseController {
570
571
  chainId: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getChainId).call(this, networkClientId),
571
572
  ethQuery,
572
573
  isSimulationEnabled: __classPrivateFieldGet(this, _TransactionController_isSimulationEnabled, "f").call(this),
574
+ messenger: this.messagingSystem,
573
575
  txParams: transaction,
574
576
  });
575
577
  return { gas: estimatedGas, simulationFails };
@@ -590,6 +592,7 @@ export class TransactionController extends BaseController {
590
592
  chainId: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getChainId).call(this, networkClientId),
591
593
  ethQuery,
592
594
  isSimulationEnabled: __classPrivateFieldGet(this, _TransactionController_isSimulationEnabled, "f").call(this),
595
+ messenger: this.messagingSystem,
593
596
  txParams: transaction,
594
597
  });
595
598
  const gas = addGasBuffer(estimatedGas, blockGasLimit, multiplier);
@@ -678,12 +681,13 @@ export class TransactionController extends BaseController {
678
681
  updatedTransactionMeta.baseFeePerGas = baseFeePerGas;
679
682
  }
680
683
  // Update same nonce local transactions as dropped and define replacedBy properties.
681
- this.markNonceDuplicatesDropped(transactionId);
684
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_markNonceDuplicatesDropped).call(this, transactionId);
682
685
  // Update external provided transaction with updated gas values and confirmed status.
683
686
  this.updateTransaction(updatedTransactionMeta, `${controllerName}:confirmExternalTransaction - Add external transaction`);
684
687
  this.onTransactionStatusChange(updatedTransactionMeta);
685
688
  // Intentional given potential duration of process.
686
689
  this.updatePostBalance(updatedTransactionMeta).catch((error) => {
690
+ /* istanbul ignore next */
687
691
  log('Error while updating post balance', error);
688
692
  throw error;
689
693
  });
@@ -932,20 +936,16 @@ export class TransactionController extends BaseController {
932
936
  /**
933
937
  * Update a custodial transaction.
934
938
  *
935
- * @param transactionId - The ID of the transaction to update.
936
- * @param options - The custodial transaction options to update.
937
- * @param options.errorMessage - The error message to be assigned in case transaction status update to failed.
938
- * @param options.hash - The new hash value to be assigned.
939
- * @param options.status - The new status value to be assigned.
939
+ * @param request - The custodial transaction update request.
940
+ *
941
+ * @returns The updated transaction metadata.
940
942
  */
941
- updateCustodialTransaction(transactionId, { errorMessage, hash, status, }) {
943
+ updateCustodialTransaction(request) {
944
+ const { transactionId, errorMessage, hash, status, gasLimit, gasPrice, maxFeePerGas, maxPriorityFeePerGas, nonce, type, } = request;
942
945
  const transactionMeta = this.getTransaction(transactionId);
943
946
  if (!transactionMeta) {
944
947
  throw new Error(`Cannot update custodial transaction as no transaction metadata found`);
945
948
  }
946
- if (!transactionMeta.custodyId) {
947
- throw new Error('Transaction must be a custodian transaction');
948
- }
949
949
  if (status &&
950
950
  ![
951
951
  TransactionStatus.submitted,
@@ -961,11 +961,27 @@ export class TransactionController extends BaseController {
961
961
  if (updatedTransactionMeta.status === TransactionStatus.failed) {
962
962
  updatedTransactionMeta.error = normalizeTxError(new Error(errorMessage));
963
963
  }
964
+ // Update txParams properties with a single pickBy operation
965
+ updatedTransactionMeta.txParams = merge({}, updatedTransactionMeta.txParams, pickBy({
966
+ gasLimit,
967
+ gasPrice,
968
+ maxFeePerGas,
969
+ maxPriorityFeePerGas,
970
+ nonce,
971
+ type,
972
+ }));
973
+ // Special case for type change to legacy
974
+ if (type === TransactionEnvelopeType.legacy) {
975
+ delete updatedTransactionMeta.txParams.maxFeePerGas;
976
+ delete updatedTransactionMeta.txParams.maxPriorityFeePerGas;
977
+ }
964
978
  this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateCustodialTransaction - Custodial transaction updated`);
965
- if ([TransactionStatus.submitted, TransactionStatus.failed].includes(status)) {
979
+ if (status &&
980
+ [TransactionStatus.submitted, TransactionStatus.failed].includes(status)) {
966
981
  this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
967
982
  __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${updatedTransactionMeta.id}:finished`, updatedTransactionMeta);
968
983
  }
984
+ return updatedTransactionMeta;
969
985
  }
970
986
  /**
971
987
  * Search transaction metadata for matching entries.
@@ -1381,13 +1397,13 @@ export class TransactionController extends BaseController {
1381
1397
  }
1382
1398
  });
1383
1399
  this.onTransactionStatusChange(transactionMeta);
1384
- const rawTx = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Sign', parentContext: traceContext }, () => this.signTransaction(transactionMeta));
1385
- if (!this.beforePublish(transactionMeta)) {
1400
+ const rawTx = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Sign', parentContext: traceContext }, () => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_signTransaction).call(this, transactionMeta));
1401
+ if (!(await this.beforePublish(transactionMeta))) {
1386
1402
  log('Skipping publishing transaction based on hook');
1387
1403
  this.messagingSystem.publish(`${controllerName}:transactionPublishingSkipped`, transactionMeta);
1388
1404
  return ApprovalState.SkippedViaBeforePublishHook;
1389
1405
  }
1390
- if (!rawTx) {
1406
+ if (!rawTx && !transactionMeta.isExternalSign) {
1391
1407
  return ApprovalState.NotApproved;
1392
1408
  }
1393
1409
  const { networkClientId } = transactionMeta;
@@ -1414,7 +1430,7 @@ export class TransactionController extends BaseController {
1414
1430
  }
1415
1431
  await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Publish', parentContext: traceContext }, async () => {
1416
1432
  const publishHook = publishHookOverride ?? this.publish;
1417
- ({ transactionHash: hash } = await publishHook(transactionMeta, rawTx));
1433
+ ({ transactionHash: hash } = await publishHook(transactionMeta, rawTx ?? '0x'));
1418
1434
  if (hash === undefined) {
1419
1435
  hash = await this.publishTransaction(ethQuery, {
1420
1436
  ...transactionMeta,
@@ -1638,44 +1654,6 @@ export class TransactionController extends BaseController {
1638
1654
  });
1639
1655
  return newTransactionMeta;
1640
1656
  }
1641
- /**
1642
- * Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
1643
- * in the transactions have the same nonce.
1644
- *
1645
- * @param transactionId - Used to identify original transaction.
1646
- */
1647
- markNonceDuplicatesDropped(transactionId) {
1648
- const transactionMeta = this.getTransaction(transactionId);
1649
- if (!transactionMeta) {
1650
- return;
1651
- }
1652
- const nonce = transactionMeta.txParams?.nonce;
1653
- const from = transactionMeta.txParams?.from;
1654
- const { chainId } = transactionMeta;
1655
- const sameNonceTransactions = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
1656
- transaction.txParams.from === from &&
1657
- transaction.txParams.nonce === nonce &&
1658
- transaction.chainId === chainId &&
1659
- transaction.type !== TransactionType.incoming);
1660
- const sameNonceTransactionIds = sameNonceTransactions.map((transaction) => transaction.id);
1661
- if (sameNonceTransactions.length === 0) {
1662
- return;
1663
- }
1664
- this.update((state) => {
1665
- for (const transaction of state.transactions) {
1666
- if (sameNonceTransactionIds.includes(transaction.id)) {
1667
- transaction.replacedBy = transactionMeta?.hash;
1668
- transaction.replacedById = transactionMeta?.id;
1669
- }
1670
- }
1671
- });
1672
- for (const transaction of this.state.transactions) {
1673
- if (sameNonceTransactionIds.includes(transaction.id) &&
1674
- transaction.status !== TransactionStatus.failed) {
1675
- this.setTransactionStatusDropped(transaction);
1676
- }
1677
- }
1678
- }
1679
1657
  /**
1680
1658
  * Method to set transaction status to dropped.
1681
1659
  *
@@ -1732,47 +1710,6 @@ export class TransactionController extends BaseController {
1732
1710
  const currentAccountIsEIP1559Compatible = await this.getCurrentAccountEIP1559Compatibility();
1733
1711
  return (currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible);
1734
1712
  }
1735
- async signTransaction(transactionMeta) {
1736
- const { txParams } = transactionMeta;
1737
- log('Signing transaction', txParams);
1738
- const { authorizationList, from } = txParams;
1739
- const finalTxParams = { ...txParams };
1740
- finalTxParams.authorizationList = await signAuthorizationList({
1741
- authorizationList,
1742
- messenger: this.messagingSystem,
1743
- transactionMeta,
1744
- });
1745
- const unsignedEthTx = prepareTransaction(transactionMeta.chainId, finalTxParams);
1746
- this.approvingTransactionIds.add(transactionMeta.id);
1747
- const signedTx = await new Promise((resolve, reject) => {
1748
- this.sign?.(unsignedEthTx, from, ...this.getAdditionalSignArguments(transactionMeta)).then(resolve, reject);
1749
- this.signAbortCallbacks.set(transactionMeta.id, () => reject(new Error('Signing aborted by user')));
1750
- });
1751
- this.signAbortCallbacks.delete(transactionMeta.id);
1752
- if (!signedTx) {
1753
- log('Skipping signed status as no signed transaction');
1754
- return undefined;
1755
- }
1756
- const transactionMetaFromHook = cloneDeep(transactionMeta);
1757
- if (!this.afterSign(transactionMetaFromHook, signedTx)) {
1758
- this.updateTransaction(transactionMetaFromHook, 'TransactionController#signTransaction - Update after sign');
1759
- log('Skipping signed status based on hook');
1760
- return undefined;
1761
- }
1762
- const transactionMetaWithRsv = {
1763
- ...this.updateTransactionMetaRSV(transactionMetaFromHook, signedTx),
1764
- status: TransactionStatus.signed,
1765
- txParams: finalTxParams,
1766
- };
1767
- this.updateTransaction(transactionMetaWithRsv, 'TransactionController#approveTransaction - Transaction signed');
1768
- this.onTransactionStatusChange(transactionMetaWithRsv);
1769
- const rawTx = serializeTransaction(signedTx);
1770
- const transactionMetaWithRawTx = merge({}, transactionMetaWithRsv, {
1771
- rawTx,
1772
- });
1773
- this.updateTransaction(transactionMetaWithRawTx, 'TransactionController#approveTransaction - RawTransaction added');
1774
- return rawTx;
1775
- }
1776
1713
  onTransactionStatusChange(transactionMeta) {
1777
1714
  this.messagingSystem.publish(`${controllerName}:transactionStatusUpdated`, {
1778
1715
  transactionMeta,
@@ -1781,17 +1718,6 @@ export class TransactionController extends BaseController {
1781
1718
  getNonceTrackerTransactions(statuses, address, chainId) {
1782
1719
  return getAndFormatTransactionsForNonceTracker(chainId, address, statuses, this.state.transactions);
1783
1720
  }
1784
- onConfirmedTransaction(transactionMeta) {
1785
- log('Processing confirmed transaction', transactionMeta.id);
1786
- this.markNonceDuplicatesDropped(transactionMeta.id);
1787
- this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, transactionMeta);
1788
- this.onTransactionStatusChange(transactionMeta);
1789
- // Intentional given potential duration of process.
1790
- this.updatePostBalance(transactionMeta).catch((error) => {
1791
- log('Error while updating post balance', error);
1792
- throw error;
1793
- });
1794
- }
1795
1721
  async updatePostBalance(transactionMeta) {
1796
1722
  try {
1797
1723
  const { networkClientId, type } = transactionMeta;
@@ -1939,6 +1865,92 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_me
1939
1865
  chainId,
1940
1866
  networkClientId,
1941
1867
  }).provider;
1868
+ }, _TransactionController_markNonceDuplicatesDropped = function _TransactionController_markNonceDuplicatesDropped(transactionId) {
1869
+ const transactionMeta = this.getTransaction(transactionId);
1870
+ if (!transactionMeta) {
1871
+ return;
1872
+ }
1873
+ const nonce = transactionMeta.txParams?.nonce;
1874
+ const from = transactionMeta.txParams?.from;
1875
+ const { chainId } = transactionMeta;
1876
+ const sameNonceTransactions = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
1877
+ transaction.txParams.from === from &&
1878
+ nonce &&
1879
+ transaction.txParams.nonce === nonce &&
1880
+ transaction.chainId === chainId &&
1881
+ transaction.type !== TransactionType.incoming);
1882
+ const sameNonceTransactionIds = sameNonceTransactions.map((transaction) => transaction.id);
1883
+ if (sameNonceTransactions.length === 0) {
1884
+ return;
1885
+ }
1886
+ this.update((state) => {
1887
+ for (const transaction of state.transactions) {
1888
+ if (sameNonceTransactionIds.includes(transaction.id)) {
1889
+ transaction.replacedBy = transactionMeta?.hash;
1890
+ transaction.replacedById = transactionMeta?.id;
1891
+ }
1892
+ }
1893
+ });
1894
+ for (const transaction of this.state.transactions) {
1895
+ if (sameNonceTransactionIds.includes(transaction.id) &&
1896
+ transaction.status !== TransactionStatus.failed) {
1897
+ this.setTransactionStatusDropped(transaction);
1898
+ }
1899
+ }
1900
+ }, _TransactionController_signTransaction = async function _TransactionController_signTransaction(transactionMeta) {
1901
+ const { isExternalSign, txParams } = transactionMeta;
1902
+ if (isExternalSign) {
1903
+ log('Skipping sign as signed externally');
1904
+ return undefined;
1905
+ }
1906
+ log('Signing transaction', txParams);
1907
+ const { authorizationList, from } = txParams;
1908
+ const finalTxParams = { ...txParams };
1909
+ finalTxParams.authorizationList = await signAuthorizationList({
1910
+ authorizationList,
1911
+ messenger: this.messagingSystem,
1912
+ transactionMeta,
1913
+ });
1914
+ const unsignedEthTx = prepareTransaction(transactionMeta.chainId, finalTxParams);
1915
+ this.approvingTransactionIds.add(transactionMeta.id);
1916
+ const signedTx = await new Promise((resolve, reject) => {
1917
+ this.sign?.(unsignedEthTx, from, ...this.getAdditionalSignArguments(transactionMeta)).then(resolve, reject);
1918
+ this.signAbortCallbacks.set(transactionMeta.id, () => reject(new Error('Signing aborted by user')));
1919
+ });
1920
+ this.signAbortCallbacks.delete(transactionMeta.id);
1921
+ if (!signedTx) {
1922
+ log('Skipping signed status as no signed transaction');
1923
+ return undefined;
1924
+ }
1925
+ const transactionMetaFromHook = cloneDeep(transactionMeta);
1926
+ if (!this.afterSign(transactionMetaFromHook, signedTx)) {
1927
+ this.updateTransaction(transactionMetaFromHook, 'TransactionController#signTransaction - Update after sign');
1928
+ log('Skipping signed status based on hook');
1929
+ return undefined;
1930
+ }
1931
+ const transactionMetaWithRsv = {
1932
+ ...this.updateTransactionMetaRSV(transactionMetaFromHook, signedTx),
1933
+ status: TransactionStatus.signed,
1934
+ txParams: finalTxParams,
1935
+ };
1936
+ this.updateTransaction(transactionMetaWithRsv, 'TransactionController#approveTransaction - Transaction signed');
1937
+ this.onTransactionStatusChange(transactionMetaWithRsv);
1938
+ const rawTx = serializeTransaction(signedTx);
1939
+ const transactionMetaWithRawTx = merge({}, transactionMetaWithRsv, {
1940
+ rawTx,
1941
+ });
1942
+ this.updateTransaction(transactionMetaWithRawTx, 'TransactionController#approveTransaction - RawTransaction added');
1943
+ return rawTx;
1944
+ }, _TransactionController_onConfirmedTransaction = function _TransactionController_onConfirmedTransaction(transactionMeta) {
1945
+ log('Processing confirmed transaction', transactionMeta.id);
1946
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_markNonceDuplicatesDropped).call(this, transactionMeta.id);
1947
+ this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, transactionMeta);
1948
+ this.onTransactionStatusChange(transactionMeta);
1949
+ // Intentional given potential duration of process.
1950
+ this.updatePostBalance(transactionMeta).catch((error) => {
1951
+ log('Error while updating post balance', error);
1952
+ throw error;
1953
+ });
1942
1954
  }, _TransactionController_createNonceTracker = function _TransactionController_createNonceTracker({ provider, blockTracker, chainId, }) {
1943
1955
  return new NonceTracker({
1944
1956
  // TODO: Fix types
@@ -1967,7 +1979,6 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_me
1967
1979
  }),
1968
1980
  hooks: {
1969
1981
  beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
1970
- beforePublish: this.beforePublish.bind(this),
1971
1982
  },
1972
1983
  });
1973
1984
  __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addPendingTransactionTrackerListeners).call(this, pendingTransactionTracker);
@@ -1982,7 +1993,7 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_me
1982
1993
  pendingTransactionTracker.hub.removeAllListeners('transaction-failed');
1983
1994
  pendingTransactionTracker.hub.removeAllListeners('transaction-updated');
1984
1995
  }, _TransactionController_addPendingTransactionTrackerListeners = function _TransactionController_addPendingTransactionTrackerListeners(pendingTransactionTracker) {
1985
- pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
1996
+ pendingTransactionTracker.hub.on('transaction-confirmed', __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_onConfirmedTransaction).bind(this));
1986
1997
  pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
1987
1998
  pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
1988
1999
  pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
@@ -2183,8 +2194,11 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_me
2183
2194
  ethQuery,
2184
2195
  isCustomNetwork,
2185
2196
  isSimulationEnabled: __classPrivateFieldGet(this, _TransactionController_isSimulationEnabled, "f").call(this),
2197
+ messenger: this.messagingSystem,
2186
2198
  txMeta: transactionMeta,
2187
2199
  });
2200
+ }, _TransactionController_registerActionHandlers = function _TransactionController_registerActionHandlers() {
2201
+ this.messagingSystem.registerActionHandler(`${controllerName}:updateCustodialTransaction`, this.updateCustodialTransaction.bind(this));
2188
2202
  }, _TransactionController_deleteTransaction = function _TransactionController_deleteTransaction(transactionId) {
2189
2203
  this.update((state) => {
2190
2204
  const transactions = state.transactions.filter(({ id }) => id !== transactionId);