@metamask/transaction-controller 18.2.0 → 18.3.1

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 (72) hide show
  1. package/CHANGELOG.md +372 -0
  2. package/dist/TransactionController.d.ts +10 -10
  3. package/dist/TransactionController.d.ts.map +1 -1
  4. package/dist/TransactionController.js +50 -38
  5. package/dist/TransactionController.js.map +1 -1
  6. package/dist/constants.js +1 -1
  7. package/dist/constants.js.map +1 -1
  8. package/dist/helpers/IncomingTransactionHelper.d.ts.map +1 -1
  9. package/dist/helpers/IncomingTransactionHelper.js +4 -0
  10. package/dist/helpers/IncomingTransactionHelper.js.map +1 -1
  11. package/dist/helpers/PendingTransactionTracker.d.ts +1 -2
  12. package/dist/helpers/PendingTransactionTracker.d.ts.map +1 -1
  13. package/dist/helpers/PendingTransactionTracker.js +24 -12
  14. package/dist/helpers/PendingTransactionTracker.js.map +1 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/types.d.ts +4 -0
  20. package/dist/types.d.ts.map +1 -1
  21. package/dist/types.js.map +1 -1
  22. package/dist/utils/gas.d.ts.map +1 -1
  23. package/dist/utils/gas.js +2 -0
  24. package/dist/utils/gas.js.map +1 -1
  25. package/dist/utils/history.js +8 -2
  26. package/dist/utils/history.js.map +1 -1
  27. package/dist/utils/nonce.d.ts.map +1 -1
  28. package/dist/utils/nonce.js +2 -1
  29. package/dist/utils/nonce.js.map +1 -1
  30. package/dist/utils/swaps.js +4 -0
  31. package/dist/utils/swaps.js.map +1 -1
  32. package/dist/utils/transaction-type.d.ts.map +1 -1
  33. package/dist/utils/transaction-type.js +19 -12
  34. package/dist/utils/transaction-type.js.map +1 -1
  35. package/dist/utils/utils.d.ts.map +1 -1
  36. package/dist/utils/utils.js +6 -0
  37. package/dist/utils/utils.js.map +1 -1
  38. package/dist/utils/validation.js +2 -0
  39. package/dist/utils/validation.js.map +1 -1
  40. package/package.json +5 -5
  41. package/dist/EtherscanRemoteTransactionSource.d.ts +0 -15
  42. package/dist/EtherscanRemoteTransactionSource.d.ts.map +0 -1
  43. package/dist/EtherscanRemoteTransactionSource.js +0 -122
  44. package/dist/EtherscanRemoteTransactionSource.js.map +0 -1
  45. package/dist/IncomingTransactionHelper.d.ts +0 -25
  46. package/dist/IncomingTransactionHelper.d.ts.map +0 -1
  47. package/dist/IncomingTransactionHelper.js +0 -198
  48. package/dist/IncomingTransactionHelper.js.map +0 -1
  49. package/dist/etherscan.d.ts +0 -64
  50. package/dist/etherscan.d.ts.map +0 -1
  51. package/dist/etherscan.js +0 -109
  52. package/dist/etherscan.js.map +0 -1
  53. package/dist/external-transactions.d.ts +0 -10
  54. package/dist/external-transactions.d.ts.map +0 -1
  55. package/dist/external-transactions.js +0 -36
  56. package/dist/external-transactions.js.map +0 -1
  57. package/dist/history.d.ts +0 -15
  58. package/dist/history.d.ts.map +0 -1
  59. package/dist/history.js +0 -75
  60. package/dist/history.js.map +0 -1
  61. package/dist/mocks/txsMock.d.ts +0 -64
  62. package/dist/mocks/txsMock.d.ts.map +0 -1
  63. package/dist/mocks/txsMock.js +0 -515
  64. package/dist/mocks/txsMock.js.map +0 -1
  65. package/dist/transaction-type.d.ts +0 -14
  66. package/dist/transaction-type.d.ts.map +0 -1
  67. package/dist/transaction-type.js +0 -114
  68. package/dist/transaction-type.js.map +0 -1
  69. package/dist/utils.d.ts +0 -72
  70. package/dist/utils.d.ts.map +0 -1
  71. package/dist/utils.js +0 -235
  72. package/dist/utils.js.map +0 -1
@@ -66,12 +66,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
66
66
  * @param options.disableHistory - Whether to disable storing history in transaction metadata.
67
67
  * @param options.disableSendFlowHistory - Explicitly disable transaction metadata history.
68
68
  * @param options.disableSwaps - Whether to disable additional processing on swaps transactions.
69
- * @param options.getSavedGasFees - Gets the saved gas fee config.
70
69
  * @param options.getCurrentAccountEIP1559Compatibility - Whether or not the account supports EIP-1559.
71
70
  * @param options.getCurrentNetworkEIP1559Compatibility - Whether or not the network supports EIP-1559.
71
+ * @param options.getExternalPendingTransactions - Callback to retrieve pending transactions from external sources.
72
72
  * @param options.getGasFeeEstimates - Callback to retrieve gas fee estimates.
73
73
  * @param options.getNetworkState - Gets the state of the network controller.
74
74
  * @param options.getPermittedAccounts - Get accounts that a given origin has permissions for.
75
+ * @param options.getSavedGasFees - Gets the saved gas fee config.
75
76
  * @param options.getSelectedAddress - Gets the address of the currently selected account.
76
77
  * @param options.incomingTransactions - Configuration options for incoming transaction support.
77
78
  * @param options.incomingTransactions.includeTokenTransfers - Whether or not to include ERC20 token transfers.
@@ -94,7 +95,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
94
95
  * @param config - Initial options used to configure this controller.
95
96
  * @param state - Initial state to set on this controller.
96
97
  */
97
- constructor({ blockTracker, cancelMultiplier, disableHistory, disableSendFlowHistory, disableSwaps, getSavedGasFees, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, speedUpMultiplier, hooks = {}, }, config, state) {
98
+ constructor({ blockTracker, cancelMultiplier, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSavedGasFees, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, speedUpMultiplier, hooks = {}, }, config, state) {
98
99
  var _a, _b, _c, _d, _e;
99
100
  super(config, state);
100
101
  this.inProcessOfSigning = new Set();
@@ -133,6 +134,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
133
134
  getGasFeeEstimates || (() => Promise.resolve({}));
134
135
  this.getPermittedAccounts = getPermittedAccounts;
135
136
  this.getSelectedAddress = getSelectedAddress;
137
+ this.getExternalPendingTransactions =
138
+ getExternalPendingTransactions !== null && getExternalPendingTransactions !== void 0 ? getExternalPendingTransactions : (() => []);
136
139
  this.securityProviderRequest = securityProviderRequest;
137
140
  this.cancelMultiplier = cancelMultiplier !== null && cancelMultiplier !== void 0 ? cancelMultiplier : exports.CANCEL_RATE;
138
141
  this.speedUpMultiplier = speedUpMultiplier !== null && speedUpMultiplier !== void 0 ? speedUpMultiplier : exports.SPEED_UP_RATE;
@@ -149,7 +152,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
149
152
  // @ts-expect-error provider types misaligned: SafeEventEmitterProvider vs Record<string,string>
150
153
  provider,
151
154
  blockTracker,
152
- getPendingTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.submitted),
155
+ getPendingTransactions: this.getNonceTrackerPendingTransactions.bind(this),
153
156
  getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
154
157
  });
155
158
  this.incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
@@ -175,7 +178,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
175
178
  getTransactions: () => this.state.transactions,
176
179
  isResubmitEnabled: pendingTransactions.isResubmitEnabled,
177
180
  nonceTracker: this.nonceTracker,
178
- onStateChange: this.subscribe.bind(this),
181
+ onStateChange: (listener) => {
182
+ this.subscribe(listener);
183
+ onNetworkStateChange(listener);
184
+ listener();
185
+ },
179
186
  publishTransaction: this.publishTransaction.bind(this),
180
187
  hooks: {
181
188
  beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
@@ -184,8 +191,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
184
191
  });
185
192
  this.addPendingTransactionTrackerListeners();
186
193
  onNetworkStateChange(() => {
187
- this.ethQuery = new eth_query_1.default(this.provider);
188
- this.registry = new eth_method_registry_1.default({ provider: this.provider });
194
+ (0, logger_1.projectLogger)('Detected network change', this.getChainId());
189
195
  this.onBootCleanup();
190
196
  });
191
197
  this.onBootCleanup();
@@ -302,6 +308,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
302
308
  yield (0, swaps_1.updateSwapsTransaction)(transactionMeta, transactionType, swaps, {
303
309
  isSwapsDisabled: this.isSwapsDisabled,
304
310
  cancelTransaction: this.cancelTransaction.bind(this),
311
+ // TODO: Replace `any` with type
312
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
305
313
  controllerHubEmitter: this.hub.emit.bind(this.hub),
306
314
  });
307
315
  this.addMetadata(transactionMeta);
@@ -713,6 +721,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
713
721
  originalGasEstimate,
714
722
  userEditedGasLimit,
715
723
  userFeeLevel,
724
+ // TODO: Replace `any` with type
725
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
716
726
  };
717
727
  // only update what is defined
718
728
  transactionGasFees.txParams = (0, lodash_1.pickBy)(transactionGasFees.txParams);
@@ -744,6 +754,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
744
754
  maxFeePerGas,
745
755
  maxPriorityFeePerGas,
746
756
  },
757
+ // TODO: Replace `any` with type
758
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
747
759
  };
748
760
  // only update what is defined
749
761
  transactionPreviousGas.previousGas = (0, lodash_1.pickBy)(transactionPreviousGas.previousGas);
@@ -810,6 +822,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
810
822
  */
811
823
  approveTransactionsWithSameNonce(listOfTxParams = []) {
812
824
  return __awaiter(this, void 0, void 0, function* () {
825
+ (0, logger_1.projectLogger)('Approving transactions with same nonce', {
826
+ transactions: listOfTxParams,
827
+ });
813
828
  if (listOfTxParams.length === 0) {
814
829
  return '';
815
830
  }
@@ -829,6 +844,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
829
844
  const fromAddress = initialTx.from;
830
845
  nonceLock = yield this.nonceTracker.getNonceLock(fromAddress);
831
846
  const nonce = nonceLock.nextNonce;
847
+ (0, logger_1.projectLogger)('Using nonce from nonce tracker', nonce, nonceLock.nonceDetails);
832
848
  rawTransactions = yield Promise.all(listOfTxParams.map((txParams) => {
833
849
  txParams.nonce = (0, ethereumjs_util_1.addHexPrefix)(nonce.toString(16));
834
850
  return this.signExternalTransaction(txParams);
@@ -889,7 +905,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
889
905
  initApprovals() {
890
906
  const chainId = this.getChainId();
891
907
  const unapprovedTxs = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.unapproved &&
892
- transaction.chainId === chainId);
908
+ transaction.chainId === chainId &&
909
+ !transaction.isUserOperation);
893
910
  for (const txMeta of unapprovedTxs) {
894
911
  this.processApproval(txMeta, {
895
912
  shouldShowRequest: false,
@@ -922,7 +939,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
922
939
  const predicateMethods = (0, lodash_1.mapValues)(searchCriteria, (predicate) => {
923
940
  return typeof predicate === 'function'
924
941
  ? predicate
925
- : (v) => v === predicate;
942
+ : // TODO: Replace `any` with type
943
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
944
+ (v) => v === predicate;
926
945
  });
927
946
  const transactionsToFilter = initialList !== null && initialList !== void 0 ? initialList : this.state.transactions;
928
947
  // Combine sortBy and pickBy to transform our state object into an array of
@@ -940,9 +959,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
940
959
  // are not fully satisfied. We check both txParams and the base
941
960
  // object as predicate keys can be either.
942
961
  if (key in transaction.txParams) {
962
+ // TODO: Replace `any` with type
963
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
943
964
  if (predicate(transaction.txParams[key]) === false) {
944
965
  return false;
945
966
  }
967
+ // TODO: Replace `any` with type
968
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
946
969
  }
947
970
  else if (predicate(transaction[key]) === false) {
948
971
  return false;
@@ -1038,23 +1061,6 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
1038
1061
  onBootCleanup() {
1039
1062
  this.submitApprovedTransactions();
1040
1063
  }
1041
- /**
1042
- * Create approvals for all unapproved transactions on current chain.
1043
- */
1044
- createApprovalsForUnapprovedTransactions() {
1045
- const unapprovedTransactions = this.getCurrentChainTransactionsByStatus(types_1.TransactionStatus.unapproved);
1046
- for (const transactionMeta of unapprovedTransactions) {
1047
- this.processApproval(transactionMeta, {
1048
- shouldShowRequest: false,
1049
- }).catch((error) => {
1050
- if ((error === null || error === void 0 ? void 0 : error.code) === rpc_errors_1.errorCodes.provider.userRejectedRequest) {
1051
- return;
1052
- }
1053
- /* istanbul ignore next */
1054
- console.error('Error during persisted transaction approval', error);
1055
- });
1056
- }
1057
- }
1058
1064
  /**
1059
1065
  * Force to submit approved transactions on current chain.
1060
1066
  */
@@ -1110,6 +1116,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
1110
1116
  actionId,
1111
1117
  });
1112
1118
  }
1119
+ // TODO: Replace `any` with type
1120
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1113
1121
  }
1114
1122
  catch (error) {
1115
1123
  const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
@@ -1209,6 +1217,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
1209
1217
  });
1210
1218
  this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
1211
1219
  this.onTransactionStatusChange(transactionMeta);
1220
+ // TODO: Replace `any` with type
1221
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1212
1222
  }
1213
1223
  catch (error) {
1214
1224
  this.failTransaction(transactionMeta, error);
@@ -1452,17 +1462,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
1452
1462
  const transactionMeta = this.getTransaction(transactionId);
1453
1463
  const nonce = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.nonce;
1454
1464
  const from = (_b = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.from;
1455
- const sameNonceTxs = this.state.transactions.filter((transaction) => transaction.txParams.from === from &&
1465
+ const sameNonceTxs = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
1466
+ transaction.txParams.from === from &&
1456
1467
  transaction.txParams.nonce === nonce &&
1457
- transaction.chainId === chainId);
1468
+ transaction.chainId === chainId &&
1469
+ transaction.type !== types_1.TransactionType.incoming);
1458
1470
  if (!sameNonceTxs.length) {
1459
1471
  return;
1460
1472
  }
1461
1473
  // Mark all same nonce transactions as dropped and give it a replacedBy hash
1462
1474
  for (const transaction of sameNonceTxs) {
1463
- if (transaction.id === transactionId) {
1464
- continue;
1465
- }
1466
1475
  transaction.replacedBy = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.hash;
1467
1476
  transaction.replacedById = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.id;
1468
1477
  // Drop any transaction that wasn't previously failed (off chain failure)
@@ -1511,14 +1520,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
1511
1520
  */
1512
1521
  updateTransactionMetaRSV(transactionMeta, signedTx) {
1513
1522
  return __awaiter(this, void 0, void 0, function* () {
1514
- if (signedTx.r) {
1515
- transactionMeta.r = (0, ethereumjs_util_1.addHexPrefix)(signedTx.r.toString(16));
1516
- }
1517
- if (signedTx.s) {
1518
- transactionMeta.s = (0, ethereumjs_util_1.addHexPrefix)(signedTx.s.toString(16));
1519
- }
1520
- if (signedTx.v) {
1521
- transactionMeta.v = (0, ethereumjs_util_1.addHexPrefix)(signedTx.v.toString(16));
1523
+ for (const key of ['r', 's', 'v']) {
1524
+ const value = signedTx[key];
1525
+ if (value === undefined || value === null) {
1526
+ continue;
1527
+ }
1528
+ transactionMeta[key] = (0, ethereumjs_util_1.addHexPrefix)(value.toString(16));
1522
1529
  }
1523
1530
  });
1524
1531
  }
@@ -1564,6 +1571,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
1564
1571
  onTransactionStatusChange(transactionMeta) {
1565
1572
  this.hub.emit('transaction-status-update', { transactionMeta });
1566
1573
  }
1574
+ getNonceTrackerPendingTransactions(address) {
1575
+ const standardPendingTransactions = this.getNonceTrackerTransactions(types_1.TransactionStatus.submitted, address);
1576
+ const externalPendingTransactions = this.getExternalPendingTransactions(address);
1577
+ return [...standardPendingTransactions, ...externalPendingTransactions];
1578
+ }
1567
1579
  getNonceTrackerTransactions(status, address) {
1568
1580
  const currentChainId = this.getChainId();
1569
1581
  return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(currentChainId, address, status, this.state.transactions);