aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/scripts/background.js2
-rw-r--r--app/scripts/controllers/transactions.js63
-rw-r--r--app/scripts/lib/tx-utils.js12
-rw-r--r--app/scripts/metamask-controller.js23
-rw-r--r--test/unit/tx-controller-test.js69
5 files changed, 115 insertions, 54 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index bc0fbdc37..f995c390e 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -126,7 +126,7 @@ function setupController (initState) {
// plugin badge text
function updateBadge () {
var label = ''
- var unapprovedTxCount = controller.txController.unapprovedTxCount
+ var unapprovedTxCount = controller.txController.getUnapprovedTxCount()
var unapprovedMsgCount = controller.messageManager.unapprovedMsgCount
var unapprovedPersonalMsgs = controller.personalMessageManager.unapprovedPersonalMsgCount
var count = unapprovedTxCount + unapprovedMsgCount + unapprovedPersonalMsgs
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 0c63a5647..720323e41 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -70,11 +70,11 @@ module.exports = class TransactionController extends EventEmitter {
return this.store.getState().transactions
}
- get unapprovedTxCount () {
+ getUnapprovedTxCount () {
return Object.keys(this.getUnapprovedTxList()).length
}
- get pendingTxCount () {
+ getPendingTxCount () {
return this.getTxsByMetaData('status', 'signed').length
}
@@ -92,7 +92,7 @@ module.exports = class TransactionController extends EventEmitter {
return txMeta
}
getUnapprovedTxList () {
- let txList = this.getTxList()
+ const txList = this.getTxList()
return txList.filter((txMeta) => txMeta.status === 'unapproved')
.reduce((result, tx) => {
result[tx.id] = tx
@@ -135,7 +135,7 @@ module.exports = class TransactionController extends EventEmitter {
// or rejected tx's.
// not tx's that are pending or unapproved
if (txCount > txHistoryLimit - 1) {
- let index = fullTxList.findIndex((metaTx) => ((metaTx.status === 'confirmed' || metaTx.status === 'rejected') && network === txMeta.metamaskNetworkId))
+ const index = fullTxList.findIndex((metaTx) => ((metaTx.status === 'confirmed' || metaTx.status === 'rejected') && network === txMeta.metamaskNetworkId))
fullTxList.splice(index, 1)
}
fullTxList.push(txMeta)
@@ -153,6 +153,25 @@ module.exports = class TransactionController extends EventEmitter {
this.emit(`${txMeta.id}:unapproved`, txMeta)
}
+ async newUnapprovedTransaction (txParams) {
+ log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`)
+ const txMeta = await this.addUnapprovedTransaction(txParams)
+ this.emit('newUnaprovedTx', txMeta)
+ // listen for tx completion (success, fail)
+ return new Promise((resolve, reject) => {
+ this.once(`${txMeta.id}:finished`, (completedTx) => {
+ switch (completedTx.status) {
+ case 'submitted':
+ return resolve(completedTx.hash)
+ case 'rejected':
+ return reject(new Error('MetaMask Tx Signature: User denied transaction signature.'))
+ default:
+ return reject(new Error(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(completedTx.txParams)}`))
+ }
+ })
+ })
+ }
+
async addUnapprovedTransaction (txParams) {
// validate
await this.txProviderUtils.validateTxParams(txParams)
@@ -229,10 +248,9 @@ module.exports = class TransactionController extends EventEmitter {
// add network/chain id
txParams.chainId = this.getChainId()
const ethTx = this.txProviderUtils.buildEthTxFromParams(txParams)
- const rawTx = await this.signEthTx(ethTx, fromAddress).then(() => {
- this.setTxStatusSigned(txMeta.id)
- return ethUtil.bufferToHex(ethTx.serialize())
- })
+ await this.signEthTx(ethTx, fromAddress)
+ this.setTxStatusSigned(txMeta.id)
+ const rawTx = ethUtil.bufferToHex(ethTx.serialize())
return rawTx
}
@@ -240,15 +258,13 @@ module.exports = class TransactionController extends EventEmitter {
const txMeta = this.getTx(txId)
txMeta.rawTx = rawTx
this.updateTx(txMeta)
- await this.txProviderUtils.publishTransaction(rawTx).then((txHash) => {
- this.setTxHash(txId, txHash)
- this.setTxStatusSubmitted(txId)
- })
+ const txHash = await this.txProviderUtils.publishTransaction(rawTx)
+ this.setTxHash(txId, txHash)
+ this.setTxStatusSubmitted(txId)
}
- cancelTransaction (txId) {
+ async cancelTransaction (txId) {
this.setTxStatusRejected(txId)
- return Promise.resolve()
}
@@ -371,9 +387,9 @@ module.exports = class TransactionController extends EventEmitter {
const txId = txMeta.id
if (!txHash) {
- const noTxHash = new Error('We had an error while submitting this transaction, please try again.')
- noTxHash.name = 'NoTxHashError'
- this.setTxStatusFailed(noTxHash)
+ const noTxHashErr = new Error('We had an error while submitting this transaction, please try again.')
+ noTxHashErr.name = 'NoTxHashError'
+ this.setTxStatusFailed(txId, noTxHashErr)
}
@@ -427,7 +443,12 @@ module.exports = class TransactionController extends EventEmitter {
}))
}
- // PRIVATE METHODS
+
+/* _____________________________________
+| |
+| PRIVATE METHODS |
+|______________________________________*/
+
// Should find the tx in the tx list and
// update it.
@@ -511,9 +532,9 @@ module.exports = class TransactionController extends EventEmitter {
// extra check in case there was an uncaught error during the
// signature and submission process
if (!txHash) {
- const noTxHash = new Error('We had an error while submitting this transaction, please try again.')
- noTxHash.name = 'NoTxHashError'
- this.setTxStatusFailed(noTxHash)
+ const noTxHashErr = new Error('We had an error while submitting this transaction, please try again.')
+ noTxHashErr.name = 'NoTxHashError'
+ this.setTxStatusFailed(txId, noTxHashErr)
}
// get latest transaction status
let txParams
diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js
index 24ea2d763..0e5b6a999 100644
--- a/app/scripts/lib/tx-utils.js
+++ b/app/scripts/lib/tx-utils.js
@@ -86,14 +86,10 @@ module.exports = class txProvideUtils {
return this.query.sendRawTransaction(rawTx)
}
- validateTxParams (txParams) {
- return new Promise((resolve, reject) => {
- if (('value' in txParams) && txParams.value.indexOf('-') === 0) {
- reject(new Error(`Invalid transaction value of ${txParams.value} not a positive number.`))
- } else {
- resolve()
- }
- })
+ async validateTxParams (txParams) {
+ if (('value' in txParams) && txParams.value.indexOf('-') === 0) {
+ throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
+ }
}
sufficientBalance (txParams, hexBalance) {
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 46a01c900..794ca1a9b 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -108,6 +108,7 @@ module.exports = class MetamaskController extends EventEmitter {
ethQuery: this.ethQuery,
ethStore: this.ethStore,
})
+ this.txController.on('newUnaprovedTx', opts.showUnapprovedTx.bind(opts))
// notices
this.noticeController = new NoticeController({
@@ -195,7 +196,7 @@ module.exports = class MetamaskController extends EventEmitter {
cb(null, result)
},
// tx signing
- processTransaction: nodeify(this.newUnapprovedTransaction, this),
+ processTransaction: nodeify(async (txParams) => await this.txController.newUnapprovedTransaction(txParams), this),
// old style msg signing
processMessage: this.newUnsignedMessage.bind(this),
@@ -440,26 +441,6 @@ module.exports = class MetamaskController extends EventEmitter {
// Identity Management
//
- async newUnapprovedTransaction (txParams) {
- log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`)
- const txMeta = await this.txController.addUnapprovedTransaction(txParams)
- this.sendUpdate()
- this.opts.showUnapprovedTx(txMeta)
- // listen for tx completion (success, fail)
- return new Promise((resolve, reject) => {
- this.txController.once(`${txMeta.id}:finished`, (completedTx) => {
- switch (completedTx.status) {
- case 'submitted':
- return resolve(completedTx.hash)
- case 'rejected':
- return reject(new Error('MetaMask Tx Signature: User denied transaction signature.'))
- default:
- return reject(new Error(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(completedTx.txParams)}`))
- }
- })
- })
- }
-
newUnsignedMessage (msgParams, cb) {
const msgId = this.messageManager.addUnapprovedMessage(msgParams)
this.sendUpdate()
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index fc70da9a2..c7743a7c6 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -42,6 +42,70 @@ describe('Transaction Controller', function () {
txController.txProviderUtils = new TxProvideUtils(txController.query)
})
+ describe('#newUnapprovedTransaction', function () {
+ let stub, txMeta, txParams
+ beforeEach(function () {
+ txParams = {
+ 'from':'0xc684832530fcbddae4b4230a47e991ddcec2831d',
+ 'to':'0xc684832530fcbddae4b4230a47e991ddcec2831d',
+ },
+ txMeta = {
+ status: 'unapproved',
+ id: 1,
+ metamaskNetworkId: currentNetworkId,
+ txParams,
+ }
+ txController._saveTxList([txMeta])
+ stub = sinon.stub(txController, 'addUnapprovedTransaction').returns(Promise.resolve(txMeta))
+ })
+
+ afterEach(function () {
+ stub.restore()
+ })
+
+ it('should emit newUnaprovedTx event and pass txMeta as the first argument', function (done) {
+ txController.once('newUnaprovedTx', (txMetaFromEmit) => {
+ assert(txMetaFromEmit, 'txMeta is falsey')
+ assert.equal(txMetaFromEmit.id, 1, 'the right txMeta was passed')
+ done()
+ })
+ txController.newUnapprovedTransaction(txParams)
+ .catch(done)
+ })
+
+ it('should resolve when finished and status is submitted and resolve with the hash', function (done) {
+ txController.once('newUnaprovedTx', (txMetaFromEmit) => {
+ setTimeout(() => {
+ console.log('HELLLO')
+ txController.setTxHash(txMetaFromEmit.id, '0x0')
+ txController.setTxStatusSubmitted(txMetaFromEmit.id)
+ }, 10)
+ })
+
+ txController.newUnapprovedTransaction(txParams)
+ .then((hash) => {
+ assert(hash, 'newUnapprovedTransaction needs to return the hash')
+ done()
+ })
+ .catch(done)
+ })
+
+ it('should reject when finished and status is rejected', function (done) {
+ txController.once('newUnaprovedTx', (txMetaFromEmit) => {
+ setTimeout(() => {
+ console.log('HELLLO')
+ txController.setTxStatusRejected(txMetaFromEmit.id)
+ }, 10)
+ })
+
+ txController.newUnapprovedTransaction(txParams)
+ .catch((err) => {
+ if (err.message === 'MetaMask Tx Signature: User denied transaction signature.') done()
+ else done(err)
+ })
+ })
+ })
+
describe('#addUnapprovedTransaction', function () {
it('should add an unapproved transaction and return a valid txMeta', function (done) {
const addTxDefaultsStub = sinon.stub(txController, 'addTxDefaults').callsFake(() => Promise.resolve)
@@ -92,7 +156,7 @@ describe('Transaction Controller', function () {
}
txController.txProviderUtils.validateTxParams(sample).then(() => {
done()
- })
+ }).catch(done)
})
it('returns error for negative values', function (done) {
@@ -407,5 +471,4 @@ describe('Transaction Controller', function () {
})
})
})
-})
-
+}) \ No newline at end of file