aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts
diff options
context:
space:
mode:
authorFrankie <frankie.diamond@gmail.com>2018-09-11 07:29:29 +0800
committerGitHub <noreply@github.com>2018-09-11 07:29:29 +0800
commit1552fe1c3eb8571036f8e32a3b2c5895849d19f1 (patch)
treeccb2b157cbc249e8b750202763299a59fa57a9ff /app/scripts
parenta43e71693f87290ac1610ae9bc3cc2887a86555b (diff)
parent43de189d067f8cf03cdd97380cbe2487319271eb (diff)
downloadtangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.tar
tangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.tar.gz
tangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.tar.bz2
tangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.tar.lz
tangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.tar.xz
tangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.tar.zst
tangerine-wallet-browser-1552fe1c3eb8571036f8e32a3b2c5895849d19f1.zip
Merge pull request #5216 from MetaMask/tx-cancel
Add createCancelTransaction method
Diffstat (limited to 'app/scripts')
-rw-r--r--app/scripts/controllers/transactions/enums.js12
-rw-r--r--app/scripts/controllers/transactions/index.js49
-rw-r--r--app/scripts/metamask-controller.js14
3 files changed, 73 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)
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 1060f508a..3ab256314 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -407,6 +407,7 @@ module.exports = class MetamaskController extends EventEmitter {
updateTransaction: nodeify(txController.updateTransaction, txController),
updateAndApproveTransaction: nodeify(txController.updateAndApproveTransaction, txController),
retryTransaction: nodeify(this.retryTransaction, this),
+ createCancelTransaction: nodeify(this.createCancelTransaction, this),
getFilteredTxList: nodeify(txController.getFilteredTxList, txController),
isNonceTaken: nodeify(txController.isNonceTaken, txController),
estimateGas: nodeify(this.estimateGas, this),
@@ -1109,6 +1110,19 @@ module.exports = class MetamaskController extends EventEmitter {
return state
}
+ /**
+ * Allows a user to attempt to cancel a previously submitted transaction by creating a new
+ * 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 {object} MetaMask state
+ */
+ async createCancelTransaction (originalTxId, customGasPrice, cb) {
+ await this.txController.createCancelTransaction(originalTxId, customGasPrice)
+ const state = await this.getState()
+ return state
+ }
+
estimateGas (estimateGasParams) {
return new Promise((resolve, reject) => {
return this.txController.txGasUtil.query.estimateGas(estimateGasParams, (err, res) => {