diff options
Merge pull request #5216 from MetaMask/tx-cancel
Add createCancelTransaction method
Diffstat (limited to 'app/scripts/controllers')
-rw-r--r-- | app/scripts/controllers/transactions/enums.js | 12 | ||||
-rw-r--r-- | app/scripts/controllers/transactions/index.js | 49 |
2 files changed, 59 insertions, 2 deletions
diff --git a/app/scripts/controllers/transactions/enums.js b/app/scripts/controllers/transactions/enums.js new file mode 100644 index 000000000..be6f16e0d --- /dev/null +++ b/app/scripts/controllers/transactions/enums.js @@ -0,0 +1,12 @@ +const TRANSACTION_TYPE_CANCEL = 'cancel' +const TRANSACTION_TYPE_RETRY = 'retry' +const TRANSACTION_TYPE_STANDARD = 'standard' + +const TRANSACTION_STATUS_APPROVED = 'approved' + +module.exports = { + TRANSACTION_TYPE_CANCEL, + TRANSACTION_TYPE_RETRY, + TRANSACTION_TYPE_STANDARD, + TRANSACTION_STATUS_APPROVED, +} diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 5d7d6d6da..59e30cdde 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -11,6 +11,14 @@ const txUtils = require('./lib/util') const cleanErrorStack = require('../../lib/cleanErrorStack') const log = require('loglevel') const recipientBlacklistChecker = require('./lib/recipient-blacklist-checker') +const { + TRANSACTION_TYPE_CANCEL, + TRANSACTION_TYPE_RETRY, + TRANSACTION_TYPE_STANDARD, + TRANSACTION_STATUS_APPROVED, +} = require('./enums') + +const { hexToBn, bnToHex } = require('../../lib/util') /** Transaction Controller is an aggregate of sub-controllers and trackers @@ -160,7 +168,10 @@ class TransactionController extends EventEmitter { const normalizedTxParams = txUtils.normalizeTxParams(txParams) txUtils.validateTxParams(normalizedTxParams) // construct txMeta - let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams }) + let txMeta = this.txStateManager.generateTxMeta({ + txParams: normalizedTxParams, + type: TRANSACTION_TYPE_STANDARD, + }) this.addTx(txMeta) this.emit('newUnapprovedTx', txMeta) @@ -214,6 +225,7 @@ class TransactionController extends EventEmitter { txParams: originalTxMeta.txParams, lastGasPrice, loadingDefaults: false, + type: TRANSACTION_TYPE_RETRY, }) this.addTx(txMeta) this.emit('newUnapprovedTx', txMeta) @@ -221,6 +233,39 @@ class TransactionController extends EventEmitter { } /** + * Creates a new approved transaction to attempt to cancel a previously submitted transaction. The + * new transaction contains the same nonce as the previous, is a basic ETH transfer of 0x value to + * the sender's address, and has a higher gasPrice than that of the previous transaction. + * @param {number} originalTxId - the id of the txMeta that you want to attempt to cancel + * @param {string=} customGasPrice - the hex value to use for the cancel transaction + * @returns {txMeta} + */ + async createCancelTransaction (originalTxId, customGasPrice) { + const originalTxMeta = this.txStateManager.getTx(originalTxId) + const { txParams } = originalTxMeta + const { gasPrice: lastGasPrice, from, nonce } = txParams + const newGasPrice = customGasPrice || bnToHex(hexToBn(lastGasPrice).mul(1.1)) + const newTxMeta = this.txStateManager.generateTxMeta({ + txParams: { + from, + to: from, + nonce, + gas: '0x5208', + value: '0x0', + gasPrice: newGasPrice, + }, + lastGasPrice, + loadingDefaults: false, + status: TRANSACTION_STATUS_APPROVED, + type: TRANSACTION_TYPE_CANCEL, + }) + + this.addTx(newTxMeta) + await this.approveTransaction(newTxMeta.id) + return newTxMeta + } + + /** updates the txMeta in the txStateManager @param txMeta {Object} - the updated txMeta */ @@ -393,7 +438,7 @@ class TransactionController extends EventEmitter { }) this.txStateManager.getFilteredTxList({ - status: 'approved', + status: TRANSACTION_STATUS_APPROVED, }).forEach((txMeta) => { const txSignError = new Error('Transaction found as "approved" during boot - possibly stuck during signing') this.txStateManager.setTxStatusFailed(txMeta.id, txSignError) |