@metamask/transaction-controller 17.0.0 → 18.1.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.
@@ -24,7 +24,7 @@ const eth_method_registry_1 = __importDefault(require("eth-method-registry"));
24
24
  const ethereumjs_util_1 = require("ethereumjs-util");
25
25
  const events_1 = require("events");
26
26
  const lodash_1 = require("lodash");
27
- const nonce_tracker_1 = __importDefault(require("nonce-tracker"));
27
+ const nonce_tracker_1 = require("nonce-tracker");
28
28
  const uuid_1 = require("uuid");
29
29
  const EtherscanRemoteTransactionSource_1 = require("./helpers/EtherscanRemoteTransactionSource");
30
30
  const IncomingTransactionHelper_1 = require("./helpers/IncomingTransactionHelper");
@@ -55,12 +55,13 @@ const controllerName = 'TransactionController';
55
55
  /**
56
56
  * Controller responsible for submitting and managing transactions.
57
57
  */
58
- class TransactionController extends base_controller_1.BaseController {
58
+ class TransactionController extends base_controller_1.BaseControllerV1 {
59
59
  /**
60
60
  * Creates a TransactionController instance.
61
61
  *
62
62
  * @param options - The controller options.
63
63
  * @param options.blockTracker - The block tracker used to poll for new blocks data.
64
+ * @param options.cancelMultiplier - Multiplier used to determine a transaction's increased gas fee during cancellation.
64
65
  * @param options.disableHistory - Whether to disable storing history in transaction metadata.
65
66
  * @param options.disableSendFlowHistory - Explicitly disable transaction metadata history.
66
67
  * @param options.disableSwaps - Whether to disable additional processing on swaps transactions.
@@ -82,6 +83,7 @@ class TransactionController extends base_controller_1.BaseController {
82
83
  * @param options.pendingTransactions.isResubmitEnabled - Whether transaction publishing is automatically retried.
83
84
  * @param options.provider - The provider used to create the underlying EthQuery instance.
84
85
  * @param options.securityProviderRequest - A function for verifying a transaction, whether it is malicious or not.
86
+ * @param options.speedUpMultiplier - Multiplier used to determine a transaction's increased gas fee during speed up.
85
87
  * @param options.hooks - The controller hooks.
86
88
  * @param options.hooks.afterSign - Additional logic to execute after signing a transaction. Return false to not change the status to signed.
87
89
  * @param options.hooks.beforeApproveOnInit - Additional logic to execute before starting an approval flow for a transaction during initialization. Return false to skip the transaction.
@@ -91,7 +93,7 @@ class TransactionController extends base_controller_1.BaseController {
91
93
  * @param config - Initial options used to configure this controller.
92
94
  * @param state - Initial state to set on this controller.
93
95
  */
94
- constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getSavedGasFees, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, hooks = {}, }, config, state) {
96
+ constructor({ blockTracker, cancelMultiplier, disableHistory, disableSendFlowHistory, disableSwaps, getSavedGasFees, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, speedUpMultiplier, hooks = {}, }, config, state) {
95
97
  var _a, _b, _c, _d, _e;
96
98
  super(config, state);
97
99
  this.inProcessOfSigning = new Set();
@@ -123,7 +125,7 @@ class TransactionController extends base_controller_1.BaseController {
123
125
  this.registry = new eth_method_registry_1.default({ provider });
124
126
  this.getSavedGasFees = getSavedGasFees !== null && getSavedGasFees !== void 0 ? getSavedGasFees : ((_chainId) => undefined);
125
127
  this.getCurrentAccountEIP1559Compatibility =
126
- getCurrentAccountEIP1559Compatibility;
128
+ getCurrentAccountEIP1559Compatibility !== null && getCurrentAccountEIP1559Compatibility !== void 0 ? getCurrentAccountEIP1559Compatibility : (() => Promise.resolve(true));
127
129
  this.getCurrentNetworkEIP1559Compatibility =
128
130
  getCurrentNetworkEIP1559Compatibility;
129
131
  this.getGasFeeEstimates =
@@ -131,6 +133,8 @@ class TransactionController extends base_controller_1.BaseController {
131
133
  this.getPermittedAccounts = getPermittedAccounts;
132
134
  this.getSelectedAddress = getSelectedAddress;
133
135
  this.securityProviderRequest = securityProviderRequest;
136
+ this.cancelMultiplier = cancelMultiplier !== null && cancelMultiplier !== void 0 ? cancelMultiplier : exports.CANCEL_RATE;
137
+ this.speedUpMultiplier = speedUpMultiplier !== null && speedUpMultiplier !== void 0 ? speedUpMultiplier : exports.SPEED_UP_RATE;
134
138
  this.afterSign = (_a = hooks === null || hooks === void 0 ? void 0 : hooks.afterSign) !== null && _a !== void 0 ? _a : (() => true);
135
139
  this.beforeApproveOnInit = (_b = hooks === null || hooks === void 0 ? void 0 : hooks.beforeApproveOnInit) !== null && _b !== void 0 ? _b : (() => true);
136
140
  this.beforeCheckPendingTransaction =
@@ -140,11 +144,12 @@ class TransactionController extends base_controller_1.BaseController {
140
144
  this.beforePublish = (_d = hooks === null || hooks === void 0 ? void 0 : hooks.beforePublish) !== null && _d !== void 0 ? _d : (() => true);
141
145
  this.getAdditionalSignArguments =
142
146
  (_e = hooks === null || hooks === void 0 ? void 0 : hooks.getAdditionalSignArguments) !== null && _e !== void 0 ? _e : (() => []);
143
- this.nonceTracker = new nonce_tracker_1.default({
147
+ this.nonceTracker = new nonce_tracker_1.NonceTracker({
148
+ // @ts-expect-error provider types misaligned: SafeEventEmitterProvider vs Record<string,string>
144
149
  provider,
145
150
  blockTracker,
146
- getPendingTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, types_1.TransactionStatus.submitted, this.state.transactions),
147
- getConfirmedTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, types_1.TransactionStatus.confirmed, this.state.transactions),
151
+ getPendingTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.submitted),
152
+ getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
148
153
  });
149
154
  this.incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
150
155
  blockTracker,
@@ -192,6 +197,7 @@ class TransactionController extends base_controller_1.BaseController {
192
197
  transactionMeta: newTransactionMeta,
193
198
  });
194
199
  this.updateTransaction(newTransactionMeta, 'TransactionController#failTransaction - Add error message and set status to failed');
200
+ this.onTransactionStatusChange(newTransactionMeta);
195
201
  this.hub.emit(`${transactionMeta.id}:finished`, newTransactionMeta);
196
202
  }
197
203
  registryLookup(fourBytePrefix) {
@@ -249,7 +255,7 @@ class TransactionController extends base_controller_1.BaseController {
249
255
  */
250
256
  addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, } = {}) {
251
257
  return __awaiter(this, void 0, void 0, function* () {
252
- const chainId = this.getChainId();
258
+ (0, logger_1.projectLogger)('Adding transaction', txParams);
253
259
  txParams = (0, utils_1.normalizeTxParams)(txParams);
254
260
  const isEIP1559Compatible = yield this.getEIP1559Compatibility();
255
261
  (0, validation_1.validateTxParams)(txParams, isEIP1559Compatible);
@@ -259,6 +265,7 @@ class TransactionController extends base_controller_1.BaseController {
259
265
  const dappSuggestedGasFees = this.generateDappSuggestedGasFees(txParams, origin);
260
266
  const transactionType = type !== null && type !== void 0 ? type : (yield (0, transaction_type_1.determineTransactionType)(txParams, this.ethQuery)).type;
261
267
  const existingTransactionMeta = this.getTransactionWithActionId(actionId);
268
+ const chainId = this.getChainId();
262
269
  // If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
263
270
  const transactionMeta = existingTransactionMeta || {
264
271
  // Add actionId to txMeta to check if same actionId is seen again
@@ -331,15 +338,18 @@ class TransactionController extends base_controller_1.BaseController {
331
338
  * @param options.estimatedBaseFee - The estimated base fee of the transaction.
332
339
  */
333
340
  stopTransaction(transactionId, gasValues, { estimatedBaseFee, actionId, } = {}) {
334
- var _a, _b;
341
+ var _a, _b, _c;
335
342
  return __awaiter(this, void 0, void 0, function* () {
336
343
  // If transaction is found for same action id, do not create a cancel transaction.
337
344
  if (this.getTransactionWithActionId(actionId)) {
338
345
  return;
339
346
  }
340
347
  if (gasValues) {
348
+ // Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
349
+ gasValues = (0, utils_1.normalizeGasFeeValues)(gasValues);
341
350
  (0, utils_1.validateGasValues)(gasValues);
342
351
  }
352
+ (0, logger_1.projectLogger)('Creating cancel transaction', transactionId, gasValues);
343
353
  const transactionMeta = this.getTransaction(transactionId);
344
354
  if (!transactionMeta) {
345
355
  return;
@@ -348,21 +358,21 @@ class TransactionController extends base_controller_1.BaseController {
348
358
  throw new Error('No sign method defined.');
349
359
  }
350
360
  // gasPrice (legacy non EIP1559)
351
- const minGasPrice = (0, utils_1.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, exports.CANCEL_RATE);
361
+ const minGasPrice = (0, utils_1.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, this.cancelMultiplier);
352
362
  const gasPriceFromValues = (0, utils_1.isGasPriceValue)(gasValues) && gasValues.gasPrice;
353
363
  const newGasPrice = (gasPriceFromValues &&
354
364
  (0, utils_1.validateMinimumIncrease)(gasPriceFromValues, minGasPrice)) ||
355
365
  minGasPrice;
356
366
  // maxFeePerGas (EIP1559)
357
367
  const existingMaxFeePerGas = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.maxFeePerGas;
358
- const minMaxFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxFeePerGas, exports.CANCEL_RATE);
368
+ const minMaxFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxFeePerGas, this.cancelMultiplier);
359
369
  const maxFeePerGasValues = (0, utils_1.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxFeePerGas;
360
370
  const newMaxFeePerGas = (maxFeePerGasValues &&
361
371
  (0, utils_1.validateMinimumIncrease)(maxFeePerGasValues, minMaxFeePerGas)) ||
362
372
  (existingMaxFeePerGas && minMaxFeePerGas);
363
373
  // maxPriorityFeePerGas (EIP1559)
364
374
  const existingMaxPriorityFeePerGas = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.maxPriorityFeePerGas;
365
- const minMaxPriorityFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, exports.CANCEL_RATE);
375
+ const minMaxPriorityFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, this.cancelMultiplier);
366
376
  const maxPriorityFeePerGasValues = (0, utils_1.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxPriorityFeePerGas;
367
377
  const newMaxPriorityFeePerGas = (maxPriorityFeePerGasValues &&
368
378
  (0, utils_1.validateMinimumIncrease)(maxPriorityFeePerGasValues, minMaxPriorityFeePerGas)) ||
@@ -373,7 +383,7 @@ class TransactionController extends base_controller_1.BaseController {
373
383
  gasLimit: transactionMeta.txParams.gas,
374
384
  maxFeePerGas: newMaxFeePerGas,
375
385
  maxPriorityFeePerGas: newMaxPriorityFeePerGas,
376
- type: '2',
386
+ type: types_1.TransactionEnvelopeType.feeMarket,
377
387
  nonce: transactionMeta.txParams.nonce,
378
388
  to: transactionMeta.txParams.from,
379
389
  value: '0x0',
@@ -389,6 +399,15 @@ class TransactionController extends base_controller_1.BaseController {
389
399
  const unsignedEthTx = this.prepareUnsignedEthTx(newTxParams);
390
400
  const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
391
401
  const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
402
+ const newFee = (_c = newTxParams.maxFeePerGas) !== null && _c !== void 0 ? _c : newTxParams.gasPrice;
403
+ const oldFee = newTxParams.maxFeePerGas
404
+ ? transactionMeta.txParams.maxFeePerGas
405
+ : transactionMeta.txParams.gasPrice;
406
+ (0, logger_1.projectLogger)('Submitting cancel transaction', {
407
+ oldFee,
408
+ newFee,
409
+ txParams: newTxParams,
410
+ });
392
411
  const hash = yield this.publishTransaction(rawTx);
393
412
  const cancelTransactionMeta = {
394
413
  actionId,
@@ -425,15 +444,18 @@ class TransactionController extends base_controller_1.BaseController {
425
444
  * @param options.estimatedBaseFee - The estimated base fee of the transaction.
426
445
  */
427
446
  speedUpTransaction(transactionId, gasValues, { actionId, estimatedBaseFee, } = {}) {
428
- var _a, _b;
447
+ var _a, _b, _c;
429
448
  return __awaiter(this, void 0, void 0, function* () {
430
449
  // If transaction is found for same action id, do not create a new speed up transaction.
431
450
  if (this.getTransactionWithActionId(actionId)) {
432
451
  return;
433
452
  }
434
453
  if (gasValues) {
454
+ // Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
455
+ gasValues = (0, utils_1.normalizeGasFeeValues)(gasValues);
435
456
  (0, utils_1.validateGasValues)(gasValues);
436
457
  }
458
+ (0, logger_1.projectLogger)('Creating speed up transaction', transactionId, gasValues);
437
459
  const transactionMeta = this.state.transactions.find(({ id }) => id === transactionId);
438
460
  /* istanbul ignore next */
439
461
  if (!transactionMeta) {
@@ -444,31 +466,36 @@ class TransactionController extends base_controller_1.BaseController {
444
466
  throw new Error('No sign method defined.');
445
467
  }
446
468
  // gasPrice (legacy non EIP1559)
447
- const minGasPrice = (0, utils_1.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, exports.SPEED_UP_RATE);
469
+ const minGasPrice = (0, utils_1.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, this.speedUpMultiplier);
448
470
  const gasPriceFromValues = (0, utils_1.isGasPriceValue)(gasValues) && gasValues.gasPrice;
449
471
  const newGasPrice = (gasPriceFromValues &&
450
472
  (0, utils_1.validateMinimumIncrease)(gasPriceFromValues, minGasPrice)) ||
451
473
  minGasPrice;
452
474
  // maxFeePerGas (EIP1559)
453
475
  const existingMaxFeePerGas = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.maxFeePerGas;
454
- const minMaxFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxFeePerGas, exports.SPEED_UP_RATE);
476
+ const minMaxFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxFeePerGas, this.speedUpMultiplier);
455
477
  const maxFeePerGasValues = (0, utils_1.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxFeePerGas;
456
478
  const newMaxFeePerGas = (maxFeePerGasValues &&
457
479
  (0, utils_1.validateMinimumIncrease)(maxFeePerGasValues, minMaxFeePerGas)) ||
458
480
  (existingMaxFeePerGas && minMaxFeePerGas);
459
481
  // maxPriorityFeePerGas (EIP1559)
460
482
  const existingMaxPriorityFeePerGas = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.maxPriorityFeePerGas;
461
- const minMaxPriorityFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, exports.SPEED_UP_RATE);
483
+ const minMaxPriorityFeePerGas = (0, utils_1.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, this.speedUpMultiplier);
462
484
  const maxPriorityFeePerGasValues = (0, utils_1.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxPriorityFeePerGas;
463
485
  const newMaxPriorityFeePerGas = (maxPriorityFeePerGasValues &&
464
486
  (0, utils_1.validateMinimumIncrease)(maxPriorityFeePerGasValues, minMaxPriorityFeePerGas)) ||
465
487
  (existingMaxPriorityFeePerGas && minMaxPriorityFeePerGas);
466
488
  const txParams = newMaxFeePerGas && newMaxPriorityFeePerGas
467
- ? Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas, type: '2' }) : Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, gasPrice: newGasPrice });
489
+ ? Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas, type: types_1.TransactionEnvelopeType.feeMarket }) : Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, gasPrice: newGasPrice });
468
490
  const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
469
491
  const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
470
492
  yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
471
493
  const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
494
+ const newFee = (_c = txParams.maxFeePerGas) !== null && _c !== void 0 ? _c : txParams.gasPrice;
495
+ const oldFee = txParams.maxFeePerGas
496
+ ? transactionMeta.txParams.maxFeePerGas
497
+ : transactionMeta.txParams.gasPrice;
498
+ (0, logger_1.projectLogger)('Submitting speed up transaction', { oldFee, newFee, txParams });
472
499
  const hash = yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [rawTx]);
473
500
  const baseTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), hash,
474
501
  actionId, originalGasEstimate: transactionMeta.txParams.gas, type: types_1.TransactionType.retry, originalType: transactionMeta.type });
@@ -606,29 +633,16 @@ class TransactionController extends base_controller_1.BaseController {
606
633
  this.markNonceDuplicatesDropped(transactionId);
607
634
  // Update external provided transaction with updated gas values and confirmed status.
608
635
  this.updateTransaction(transactionMeta, 'TransactionController:confirmExternalTransaction - Add external transaction');
609
- if (transactionMeta.type === types_1.TransactionType.swap) {
610
- (0, swaps_1.updatePostTransactionBalance)(transactionMeta, {
611
- ethQuery: this.ethQuery,
612
- getTransaction: this.getTransaction.bind(this),
613
- updateTransaction: this.updateTransaction.bind(this),
614
- })
615
- .then(({ updatedTransactionMeta, approvalTransactionMeta }) => {
616
- this.hub.emit('post-transaction-balance-updated', {
617
- transactionMeta: updatedTransactionMeta,
618
- approvalTransactionMeta,
619
- });
620
- })
621
- .catch((error) => {
622
- /* istanbul ignore next */
623
- (0, logger_1.projectLogger)('Error while updating post transaction balance', error);
624
- });
625
- }
636
+ this.onTransactionStatusChange(transactionMeta);
637
+ // Intentional given potential duration of process.
638
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
639
+ this.updatePostBalance(transactionMeta);
626
640
  this.hub.emit('transaction-confirmed', {
627
641
  transactionMeta,
628
642
  });
629
643
  }
630
644
  catch (error) {
631
- console.error(error);
645
+ console.error('Failed to confirm external transaction', error);
632
646
  }
633
647
  });
634
648
  }
@@ -749,6 +763,44 @@ class TransactionController extends base_controller_1.BaseController {
749
763
  return this.nonceTracker.getNonceLock(address);
750
764
  });
751
765
  }
766
+ /**
767
+ * Updates the editable parameters of a transaction.
768
+ *
769
+ * @param txId - The ID of the transaction to update.
770
+ * @param params - The editable parameters to update.
771
+ * @param params.data - Data to pass with the transaction.
772
+ * @param params.gas - Maximum number of units of gas to use for the transaction.
773
+ * @param params.gasPrice - Price per gas for legacy transactions.
774
+ * @param params.from - Address to send the transaction from.
775
+ * @param params.to - Address to send the transaction to.
776
+ * @param params.value - Value associated with the transaction.
777
+ * @returns The updated transaction metadata.
778
+ */
779
+ updateEditableParams(txId, { data, gas, gasPrice, from, to, value, }) {
780
+ return __awaiter(this, void 0, void 0, function* () {
781
+ const transactionMeta = this.getTransaction(txId);
782
+ if (!transactionMeta) {
783
+ throw new Error(`Cannot update editable params as no transaction metadata found`);
784
+ }
785
+ (0, utils_1.validateIfTransactionUnapproved)(transactionMeta, 'updateEditableParams');
786
+ const editableParams = {
787
+ txParams: {
788
+ data,
789
+ from,
790
+ to,
791
+ value,
792
+ gas,
793
+ gasPrice,
794
+ },
795
+ };
796
+ editableParams.txParams = (0, lodash_1.pickBy)(editableParams.txParams);
797
+ const updatedTransaction = (0, lodash_1.merge)(transactionMeta, editableParams);
798
+ const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, this.ethQuery);
799
+ updatedTransaction.type = type;
800
+ this.updateTransaction(updatedTransaction, `Update Editable Params for ${txId}`);
801
+ return this.getTransaction(txId);
802
+ });
803
+ }
752
804
  /**
753
805
  * Signs and returns the raw transaction data for provided transaction params list.
754
806
  *
@@ -801,14 +853,12 @@ class TransactionController extends base_controller_1.BaseController {
801
853
  *
802
854
  * @param transactionId - The ID of the transaction to update.
803
855
  * @param options - The custodial transaction options to update.
804
- * @param options.custodyStatus - The new custody status value to be assigned.
805
856
  * @param options.errorMessage - The error message to be assigned in case transaction status update to failed.
806
857
  * @param options.hash - The new hash value to be assigned.
807
858
  * @param options.status - The new status value to be assigned.
808
859
  */
809
- updateCustodialTransaction(transactionId, { custodyStatus, errorMessage, hash, status, }) {
810
- let transactionMeta;
811
- transactionMeta = this.getTransaction(transactionId);
860
+ updateCustodialTransaction(transactionId, { errorMessage, hash, status, }) {
861
+ const transactionMeta = this.getTransaction(transactionId);
812
862
  if (!transactionMeta) {
813
863
  throw new Error(`Cannot update custodial transaction as no transaction metadata found`);
814
864
  }
@@ -823,23 +873,112 @@ class TransactionController extends base_controller_1.BaseController {
823
873
  ].includes(status)) {
824
874
  throw new Error(`Cannot update custodial transaction with status: ${status}`);
825
875
  }
826
- if (status === types_1.TransactionStatus.signed) {
827
- transactionMeta.status = status;
828
- }
876
+ const updatedTransactionMeta = (0, lodash_1.merge)(transactionMeta, (0, lodash_1.pickBy)({ hash, status }));
829
877
  if (status === types_1.TransactionStatus.submitted) {
830
- transactionMeta.submittedTime = new Date().getTime();
831
- transactionMeta.status = status;
878
+ updatedTransactionMeta.submittedTime = new Date().getTime();
832
879
  }
833
880
  if (status === types_1.TransactionStatus.failed) {
834
- transactionMeta = Object.assign(Object.assign({}, transactionMeta), { error: (0, utils_1.normalizeTxError)(new Error(errorMessage)), status: types_1.TransactionStatus.failed });
881
+ updatedTransactionMeta.error = (0, utils_1.normalizeTxError)(new Error(errorMessage));
835
882
  }
836
- if (custodyStatus) {
837
- transactionMeta.custodyStatus = custodyStatus;
883
+ this.updateTransaction(updatedTransactionMeta, `TransactionController:updateCustodialTransaction - Custodial transaction updated`);
884
+ }
885
+ /**
886
+ * Creates approvals for all unapproved transactions persisted.
887
+ */
888
+ initApprovals() {
889
+ const chainId = this.getChainId();
890
+ const unapprovedTxs = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.unapproved &&
891
+ transaction.chainId === chainId);
892
+ for (const txMeta of unapprovedTxs) {
893
+ this.processApproval(txMeta, {
894
+ shouldShowRequest: false,
895
+ }).catch((error) => {
896
+ if ((error === null || error === void 0 ? void 0 : error.code) === rpc_errors_1.errorCodes.provider.userRejectedRequest) {
897
+ return;
898
+ }
899
+ console.error('Error during persisted transaction approval', error);
900
+ });
838
901
  }
839
- if (hash) {
840
- transactionMeta.hash = hash;
902
+ }
903
+ /**
904
+ * Search transaction metadata for matching entries.
905
+ *
906
+ * @param opts - Options bag.
907
+ * @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
908
+ * @param opts.initialList - The transactions to search. Defaults to the current state.
909
+ * @param opts.filterToCurrentNetwork - Whether to filter the results to the current network. Defaults to true.
910
+ * @param opts.limit - The maximum number of transactions to return. No limit by default.
911
+ * @returns An array of transactions matching the provided options.
912
+ */
913
+ getTransactions({ searchCriteria = {}, initialList, filterToCurrentNetwork = true, limit, } = {}) {
914
+ const chainId = this.getChainId();
915
+ // searchCriteria is an object that might have values that aren't predicate
916
+ // methods. When providing any other value type (string, number, etc), we
917
+ // consider this shorthand for "check the value at key for strict equality
918
+ // with the provided value". To conform this object to be only methods, we
919
+ // mapValues (lodash) such that every value on the object is a method that
920
+ // returns a boolean.
921
+ const predicateMethods = (0, lodash_1.mapValues)(searchCriteria, (predicate) => {
922
+ return typeof predicate === 'function'
923
+ ? predicate
924
+ : (v) => v === predicate;
925
+ });
926
+ const transactionsToFilter = initialList !== null && initialList !== void 0 ? initialList : this.state.transactions;
927
+ // Combine sortBy and pickBy to transform our state object into an array of
928
+ // matching transactions that are sorted by time.
929
+ const filteredTransactions = (0, lodash_1.sortBy)((0, lodash_1.pickBy)(transactionsToFilter, (transaction) => {
930
+ if (filterToCurrentNetwork && transaction.chainId !== chainId) {
931
+ return false;
932
+ }
933
+ // iterate over the predicateMethods keys to check if the transaction
934
+ // matches the searchCriteria
935
+ for (const [key, predicate] of Object.entries(predicateMethods)) {
936
+ // We return false early as soon as we know that one of the specified
937
+ // search criteria do not match the transaction. This prevents
938
+ // needlessly checking all criteria when we already know the criteria
939
+ // are not fully satisfied. We check both txParams and the base
940
+ // object as predicate keys can be either.
941
+ if (key in transaction.txParams) {
942
+ if (predicate(transaction.txParams[key]) === false) {
943
+ return false;
944
+ }
945
+ }
946
+ else if (predicate(transaction[key]) === false) {
947
+ return false;
948
+ }
949
+ }
950
+ return true;
951
+ }), 'time');
952
+ if (limit !== undefined) {
953
+ // We need to have all transactions of a given nonce in order to display
954
+ // necessary details in the UI. We use the size of this set to determine
955
+ // whether we have reached the limit provided, thus ensuring that all
956
+ // transactions of nonces we include will be sent to the UI.
957
+ const nonces = new Set();
958
+ const txs = [];
959
+ // By default, the transaction list we filter from is sorted by time ASC.
960
+ // To ensure that filtered results prefers the newest transactions we
961
+ // iterate from right to left, inserting transactions into front of a new
962
+ // array. The original order is preserved, but we ensure that newest txs
963
+ // are preferred.
964
+ for (let i = filteredTransactions.length - 1; i > -1; i--) {
965
+ const txMeta = filteredTransactions[i];
966
+ const { nonce } = txMeta.txParams;
967
+ if (!nonces.has(nonce)) {
968
+ if (nonces.size < limit) {
969
+ nonces.add(nonce);
970
+ }
971
+ else {
972
+ continue;
973
+ }
974
+ }
975
+ // Push transaction into the beginning of our array to ensure the
976
+ // original order is preserved.
977
+ txs.unshift(txMeta);
978
+ }
979
+ return txs;
841
980
  }
842
- this.updateTransaction(transactionMeta, `TransactionController:updateCustodialTransaction - Custodial transaction updated`);
981
+ return filteredTransactions;
843
982
  }
844
983
  signExternalTransaction(transactionParams) {
845
984
  return __awaiter(this, void 0, void 0, function* () {
@@ -874,7 +1013,8 @@ class TransactionController extends base_controller_1.BaseController {
874
1013
  }
875
1014
  updateGasProperties(transactionMeta) {
876
1015
  return __awaiter(this, void 0, void 0, function* () {
877
- const isEIP1559Compatible = yield this.getEIP1559Compatibility();
1016
+ const isEIP1559Compatible = (yield this.getEIP1559Compatibility()) &&
1017
+ transactionMeta.txParams.type !== types_1.TransactionEnvelopeType.legacy;
878
1018
  const chainId = this.getChainId();
879
1019
  yield (0, gas_1.updateGas)({
880
1020
  ethQuery: this.ethQuery,
@@ -895,8 +1035,6 @@ class TransactionController extends base_controller_1.BaseController {
895
1035
  return this.state.transactions.filter((transaction) => transaction.status === status && transaction.chainId === chainId);
896
1036
  }
897
1037
  onBootCleanup() {
898
- this.createApprovalsForUnapprovedTransactions();
899
- this.loadGasValuesForUnapprovedTransactions();
900
1038
  this.submitApprovedTransactions();
901
1039
  }
902
1040
  /**
@@ -916,26 +1054,6 @@ class TransactionController extends base_controller_1.BaseController {
916
1054
  });
917
1055
  }
918
1056
  }
919
- /**
920
- * Update the gas values of all unapproved transactions on current chain.
921
- */
922
- loadGasValuesForUnapprovedTransactions() {
923
- return __awaiter(this, void 0, void 0, function* () {
924
- const unapprovedTransactions = this.getCurrentChainTransactionsByStatus(types_1.TransactionStatus.unapproved);
925
- const results = yield Promise.allSettled(unapprovedTransactions.map((transactionMeta) => __awaiter(this, void 0, void 0, function* () {
926
- yield this.updateGasProperties(transactionMeta);
927
- this.updateTransaction(transactionMeta, 'TransactionController:loadGasValuesForUnapprovedTransactions - Gas values updated');
928
- })));
929
- for (const [index, result] of results.entries()) {
930
- if (result.status === 'rejected') {
931
- const transactionMeta = unapprovedTransactions[index];
932
- this.failTransaction(transactionMeta, result.reason);
933
- /* istanbul ignore next */
934
- console.error('Error while loading gas values for persisted transaction id: ', transactionMeta.id, result.reason);
935
- }
936
- }
937
- });
938
- }
939
1057
  /**
940
1058
  * Force to submit approved transactions on current chain.
941
1059
  */
@@ -965,6 +1083,13 @@ class TransactionController extends base_controller_1.BaseController {
965
1083
  shouldShowRequest,
966
1084
  });
967
1085
  resultCallbacks = acceptResult.resultCallbacks;
1086
+ if (resultCallbacks) {
1087
+ this.hub.once(`${transactionId}:publish-skip`, () => {
1088
+ resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.success();
1089
+ // Remove the reference to prevent additional reports once submitted.
1090
+ resultCallbacks = undefined;
1091
+ });
1092
+ }
968
1093
  }
969
1094
  const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
970
1095
  if (!isTxCompleted) {
@@ -1036,7 +1161,6 @@ class TransactionController extends base_controller_1.BaseController {
1036
1161
  (0, logger_1.projectLogger)('Skipping approval as signing in progress', transactionId);
1037
1162
  return;
1038
1163
  }
1039
- const { approved: status } = types_1.TransactionStatus;
1040
1164
  let nonceToUse = nonce;
1041
1165
  // if a nonce already exists on the transactionMeta it means this is a speedup or cancel transaction
1042
1166
  // so we want to reuse that nonce and hope that it beats the previous attempt to chain. Otherwise use a new locked nonce
@@ -1044,37 +1168,42 @@ class TransactionController extends base_controller_1.BaseController {
1044
1168
  nonceLock = yield this.nonceTracker.getNonceLock(from);
1045
1169
  nonceToUse = (0, ethereumjs_util_1.addHexPrefix)(nonceLock.nextNonce.toString(16));
1046
1170
  }
1047
- transactionMeta.status = status;
1171
+ transactionMeta.status = types_1.TransactionStatus.approved;
1048
1172
  transactionMeta.txParams.nonce = nonceToUse;
1049
1173
  transactionMeta.txParams.chainId = chainId;
1050
1174
  const baseTxParams = Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas });
1051
1175
  this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction approved');
1176
+ this.onTransactionStatusChange(transactionMeta);
1052
1177
  const isEIP1559 = (0, utils_1.isEIP1559Transaction)(transactionMeta.txParams);
1053
1178
  const txParams = isEIP1559
1054
- ? Object.assign(Object.assign({}, baseTxParams), { maxFeePerGas: transactionMeta.txParams.maxFeePerGas, maxPriorityFeePerGas: transactionMeta.txParams.maxPriorityFeePerGas, estimatedBaseFee: transactionMeta.txParams.estimatedBaseFee,
1055
- // specify type 2 if maxFeePerGas and maxPriorityFeePerGas are set
1056
- type: '2' }) : baseTxParams;
1057
- // delete gasPrice if maxFeePerGas and maxPriorityFeePerGas are set
1058
- if (isEIP1559) {
1059
- delete txParams.gasPrice;
1060
- }
1061
- const rawTx = yield this.signTransaction(transactionMeta);
1179
+ ? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee: transactionMeta.txParams.estimatedBaseFee, type: types_1.TransactionEnvelopeType.feeMarket }) : baseTxParams;
1180
+ const rawTx = yield this.signTransaction(transactionMeta, txParams);
1062
1181
  if (!this.beforePublish(transactionMeta)) {
1063
1182
  (0, logger_1.projectLogger)('Skipping publishing transaction based on hook');
1183
+ this.hub.emit(`${transactionMeta.id}:publish-skip`, transactionMeta);
1064
1184
  return;
1065
1185
  }
1066
1186
  if (!rawTx) {
1067
1187
  return;
1068
1188
  }
1189
+ if (transactionMeta.type === types_1.TransactionType.swap) {
1190
+ (0, logger_1.projectLogger)('Determining pre-transaction balance');
1191
+ const preTxBalance = yield (0, controller_utils_1.query)(this.ethQuery, 'getBalance', [from]);
1192
+ transactionMeta.preTxBalance = preTxBalance;
1193
+ (0, logger_1.projectLogger)('Updated pre-transaction balance', transactionMeta.preTxBalance);
1194
+ }
1195
+ (0, logger_1.projectLogger)('Publishing transaction', txParams);
1069
1196
  const hash = yield this.publishTransaction(rawTx);
1197
+ (0, logger_1.projectLogger)('Publish successful', hash);
1070
1198
  transactionMeta.hash = hash;
1071
1199
  transactionMeta.status = types_1.TransactionStatus.submitted;
1072
1200
  transactionMeta.submittedTime = new Date().getTime();
1201
+ this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction submitted');
1073
1202
  this.hub.emit('transaction-submitted', {
1074
1203
  transactionMeta,
1075
1204
  });
1076
- this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction submitted');
1077
1205
  this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
1206
+ this.onTransactionStatusChange(transactionMeta);
1078
1207
  }
1079
1208
  catch (error) {
1080
1209
  this.failTransaction(transactionMeta, error);
@@ -1107,13 +1236,14 @@ class TransactionController extends base_controller_1.BaseController {
1107
1236
  return;
1108
1237
  }
1109
1238
  transactionMeta.status = types_1.TransactionStatus.rejected;
1239
+ const transactions = this.state.transactions.filter(({ id }) => id !== transactionId);
1240
+ this.update({ transactions: this.trimTransactionsForState(transactions) });
1110
1241
  this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
1111
1242
  this.hub.emit('transaction-rejected', {
1112
1243
  transactionMeta,
1113
1244
  actionId,
1114
1245
  });
1115
- const transactions = this.state.transactions.filter(({ id }) => id !== transactionId);
1116
- this.update({ transactions: this.trimTransactionsForState(transactions) });
1246
+ this.onTransactionStatusChange(transactionMeta);
1117
1247
  }
1118
1248
  /**
1119
1249
  * Trim the amount of transactions that are set on the state. Checks
@@ -1124,7 +1254,7 @@ class TransactionController extends base_controller_1.BaseController {
1124
1254
  * representation, this function will not break apart transactions with the
1125
1255
  * same nonce, created on the same day, per network. Not accounting for transactions of the same
1126
1256
  * nonce, same day and network combo can result in confusing or broken experiences
1127
- * in the UI. The transactions are then updated using the BaseController update.
1257
+ * in the UI. The transactions are then updated using the BaseControllerV1 update.
1128
1258
  *
1129
1259
  * @param transactions - The transactions to be applied to the state.
1130
1260
  * @returns The trimmed list of transactions.
@@ -1288,25 +1418,23 @@ class TransactionController extends base_controller_1.BaseController {
1288
1418
  */
1289
1419
  addExternalTransaction(transactionMeta) {
1290
1420
  var _a, _b;
1291
- return __awaiter(this, void 0, void 0, function* () {
1292
- const chainId = this.getChainId();
1293
- const { transactions } = this.state;
1294
- const fromAddress = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.from;
1295
- const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.txParams.from === fromAddress &&
1296
- transaction.chainId === chainId);
1297
- const confirmedTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.confirmed);
1298
- const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.submitted);
1299
- (0, external_transactions_1.validateConfirmedExternalTransaction)(transactionMeta, confirmedTxs, pendingTxs);
1300
- // Make sure provided external transaction has non empty history array
1301
- if (!((_b = transactionMeta.history) !== null && _b !== void 0 ? _b : []).length) {
1302
- if (!this.isHistoryDisabled) {
1303
- (0, history_1.addInitialHistorySnapshot)(transactionMeta);
1304
- }
1421
+ const chainId = this.getChainId();
1422
+ const { transactions } = this.state;
1423
+ const fromAddress = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.from;
1424
+ const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.txParams.from === fromAddress &&
1425
+ transaction.chainId === chainId);
1426
+ const confirmedTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.confirmed);
1427
+ const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.submitted);
1428
+ (0, external_transactions_1.validateConfirmedExternalTransaction)(transactionMeta, confirmedTxs, pendingTxs);
1429
+ // Make sure provided external transaction has non empty history array
1430
+ if (!((_b = transactionMeta.history) !== null && _b !== void 0 ? _b : []).length) {
1431
+ if (!this.isHistoryDisabled) {
1432
+ (0, history_1.addInitialHistorySnapshot)(transactionMeta);
1305
1433
  }
1306
- const updatedTransactions = [...transactions, transactionMeta];
1307
- this.update({
1308
- transactions: this.trimTransactionsForState(updatedTransactions),
1309
- });
1434
+ }
1435
+ const updatedTransactions = [...transactions, transactionMeta];
1436
+ this.update({
1437
+ transactions: this.trimTransactionsForState(updatedTransactions),
1310
1438
  });
1311
1439
  }
1312
1440
  /**
@@ -1351,6 +1479,7 @@ class TransactionController extends base_controller_1.BaseController {
1351
1479
  transactionMeta,
1352
1480
  });
1353
1481
  this.updateTransaction(transactionMeta, 'TransactionController#setTransactionStatusDropped - Transaction dropped');
1482
+ this.onTransactionStatusChange(transactionMeta);
1354
1483
  }
1355
1484
  /**
1356
1485
  * Get transaction with provided actionId.
@@ -1391,26 +1520,22 @@ class TransactionController extends base_controller_1.BaseController {
1391
1520
  });
1392
1521
  }
1393
1522
  getEIP1559Compatibility() {
1394
- var _a, _b;
1395
1523
  return __awaiter(this, void 0, void 0, function* () {
1396
1524
  const currentNetworkIsEIP1559Compatible = yield this.getCurrentNetworkEIP1559Compatibility();
1397
- const currentAccountIsEIP1559Compatible = (_b = (_a = this.getCurrentAccountEIP1559Compatibility) === null || _a === void 0 ? void 0 : _a.call(this)) !== null && _b !== void 0 ? _b : true;
1525
+ const currentAccountIsEIP1559Compatible = yield this.getCurrentAccountEIP1559Compatibility();
1398
1526
  return (currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible);
1399
1527
  });
1400
1528
  }
1401
1529
  addPendingTransactionTrackerListeners() {
1402
- this.pendingTransactionTracker.hub.on('transaction-confirmed', (transactionMeta) => {
1403
- this.hub.emit('transaction-confirmed', { transactionMeta });
1404
- this.hub.emit(`${transactionMeta.id}:confirmed`, transactionMeta);
1405
- });
1530
+ this.pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
1406
1531
  this.pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
1407
1532
  this.pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
1408
1533
  this.pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
1409
1534
  }
1410
- signTransaction(transactionMeta) {
1535
+ signTransaction(transactionMeta, txParams) {
1411
1536
  var _a;
1412
1537
  return __awaiter(this, void 0, void 0, function* () {
1413
- const { txParams } = transactionMeta;
1538
+ (0, logger_1.projectLogger)('Signing transaction', txParams);
1414
1539
  const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
1415
1540
  this.inProcessOfSigning.add(transactionMeta.id);
1416
1541
  const signedTx = yield ((_a = this.sign) === null || _a === void 0 ? void 0 : _a.call(this, unsignedEthTx, txParams.from, ...this.getAdditionalSignArguments(transactionMeta)));
@@ -1419,19 +1544,59 @@ class TransactionController extends base_controller_1.BaseController {
1419
1544
  return undefined;
1420
1545
  }
1421
1546
  if (!this.afterSign(transactionMeta, signedTx)) {
1547
+ this.updateTransaction(transactionMeta, 'TransactionController#signTransaction - Update after sign');
1422
1548
  (0, logger_1.projectLogger)('Skipping signed status based on hook');
1423
1549
  return undefined;
1424
1550
  }
1425
1551
  yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
1426
1552
  transactionMeta.status = types_1.TransactionStatus.signed;
1427
1553
  this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction signed');
1554
+ this.onTransactionStatusChange(transactionMeta);
1428
1555
  const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
1429
1556
  transactionMeta.rawTx = rawTx;
1430
1557
  this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - RawTransaction added');
1431
1558
  return rawTx;
1432
1559
  });
1433
1560
  }
1561
+ onTransactionStatusChange(transactionMeta) {
1562
+ this.hub.emit('transaction-status-update', { transactionMeta });
1563
+ }
1564
+ getNonceTrackerTransactions(status, address) {
1565
+ const currentChainId = this.getChainId();
1566
+ return (0, utils_1.getAndFormatTransactionsForNonceTracker)(currentChainId, address, status, this.state.transactions);
1567
+ }
1568
+ onConfirmedTransaction(transactionMeta) {
1569
+ (0, logger_1.projectLogger)('Processing confirmed transaction', transactionMeta.id);
1570
+ this.markNonceDuplicatesDropped(transactionMeta.id);
1571
+ this.hub.emit('transaction-confirmed', { transactionMeta });
1572
+ this.hub.emit(`${transactionMeta.id}:confirmed`, transactionMeta);
1573
+ this.onTransactionStatusChange(transactionMeta);
1574
+ // Intentional given potential duration of process.
1575
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1576
+ this.updatePostBalance(transactionMeta);
1577
+ }
1578
+ updatePostBalance(transactionMeta) {
1579
+ return __awaiter(this, void 0, void 0, function* () {
1580
+ try {
1581
+ if (transactionMeta.type !== types_1.TransactionType.swap) {
1582
+ return;
1583
+ }
1584
+ const { updatedTransactionMeta, approvalTransactionMeta } = yield (0, swaps_1.updatePostTransactionBalance)(transactionMeta, {
1585
+ ethQuery: this.ethQuery,
1586
+ getTransaction: this.getTransaction.bind(this),
1587
+ updateTransaction: this.updateTransaction.bind(this),
1588
+ });
1589
+ this.hub.emit('post-transaction-balance-updated', {
1590
+ transactionMeta: updatedTransactionMeta,
1591
+ approvalTransactionMeta,
1592
+ });
1593
+ }
1594
+ catch (error) {
1595
+ /* istanbul ignore next */
1596
+ (0, logger_1.projectLogger)('Error while updating post transaction balance', error);
1597
+ }
1598
+ });
1599
+ }
1434
1600
  }
1435
1601
  exports.TransactionController = TransactionController;
1436
- exports.default = TransactionController;
1437
1602
  //# sourceMappingURL=TransactionController.js.map