From 564f920ae0a1be1aa08905f1b4cf6d081e9a5a0b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 22 Feb 2017 16:23:13 -0800 Subject: [PATCH] Add personal sign actions and template --- app/scripts/metamask-controller.js | 5 ++ ui/app/actions.js | 22 +++++++++ ui/app/components/pending-personal-msg.js | 56 +++++++++++++++++++++++ ui/app/conf-tx.js | 41 ++++++++--------- ui/lib/tx-helper.js | 13 ++++-- 5 files changed, 111 insertions(+), 26 deletions(-) create mode 100644 ui/app/components/pending-personal-msg.js diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d58d1c22d..b109918cf 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -241,6 +241,7 @@ module.exports = class MetamaskController extends EventEmitter { const preferencesController = this.preferencesController const txManager = this.txManager const messageManager = this.messageManager + const personalMessageManager = this.personalMessageManager const noticeController = this.noticeController return { @@ -285,6 +286,10 @@ module.exports = class MetamaskController extends EventEmitter { signMessage: this.signMessage.bind(this), cancelMessage: messageManager.rejectMsg.bind(messageManager), + // personalMessageManager + signPersonalMessage: this.signPersonalMessage.bind(this), + cancelPersonalMessage: personalMessageManager.rejectMsg.bind(personalMessageManager), + // notices checkNotices: noticeController.updateNoticesList.bind(noticeController), markNoticeRead: noticeController.markNoticeRead.bind(noticeController), diff --git a/ui/app/actions.js b/ui/app/actions.js index 6552e7f5c..6060d4299 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -90,6 +90,8 @@ var actions = { PREVIOUS_TX: 'PREV_TX', signMsg: signMsg, cancelMsg: cancelMsg, + signPersonalMsg, + cancelPersonalMsg, sendTx: sendTx, signTx: signTx, cancelTx: cancelTx, @@ -359,6 +361,20 @@ function signMsg (msgData) { } } +function signPersonalMsg (msgData) { + return (dispatch) => { + dispatch(actions.showLoadingIndication()) + + if (global.METAMASK_DEBUG) console.log(`background.signMessage`) + background.signPersonalMessage(msgData, (err) => { + dispatch(actions.hideLoadingIndication()) + + if (err) return dispatch(actions.displayWarning(err.message)) + dispatch(actions.completedTx(msgData.metamaskId)) + }) + } +} + function signTx (txData) { return (dispatch) => { if (global.METAMASK_DEBUG) console.log(`background.setGasMultiplier`) @@ -408,6 +424,12 @@ function cancelMsg (msgData) { return actions.completedTx(msgData.id) } +function cancelPersonalMsg (msgData) { + if (global.METAMASK_DEBUG) console.log(`background.cancelMessage`) + background.cancelPersonalMessage(msgData.id) + return actions.completedTx(msgData.id) +} + function cancelTx (txData) { if (global.METAMASK_DEBUG) console.log(`background.cancelTransaction`) background.cancelTransaction(txData.id) diff --git a/ui/app/components/pending-personal-msg.js b/ui/app/components/pending-personal-msg.js new file mode 100644 index 000000000..b2cac164a --- /dev/null +++ b/ui/app/components/pending-personal-msg.js @@ -0,0 +1,56 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const PendingTxDetails = require('./pending-msg-details') + +module.exports = PendingMsg + +inherits(PendingMsg, Component) +function PendingMsg () { + Component.call(this) +} + +PendingMsg.prototype.render = function () { + var state = this.props + var msgData = state.txData + + return ( + + h('div', { + key: msgData.id, + }, [ + + // header + h('h3', { + style: { + fontWeight: 'bold', + textAlign: 'center', + }, + }, 'Sign Message'), + + h('.error', { + style: { + margin: '10px', + }, + }, `Signing this message can have + dangerous side effects. Only sign messages from + sites you fully trust with your entire account. + This will be fixed in a future version.`), + + // message details + h(PendingTxDetails, state), + + // sign + cancel + h('.flex-row.flex-space-around', [ + h('button', { + onClick: state.cancelMessage, + }, 'Cancel'), + h('button', { + onClick: state.signMessage, + }, 'Sign'), + ]), + ]) + + ) +} + diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 646dbb602..672ea54ae 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -12,6 +12,7 @@ const BN = ethUtil.BN const PendingTx = require('./components/pending-tx') const PendingMsg = require('./components/pending-msg') +const PendingPersonalMsg = require('./components/pending-personal-msg') module.exports = connect(mapStateToProps)(ConfirmTxScreen) @@ -22,6 +23,7 @@ function mapStateToProps (state) { selectedAddress: state.metamask.selectedAddress, unapprovedTxs: state.metamask.unapprovedTxs, unapprovedMsgs: state.metamask.unapprovedMsgs, + unapprovedPersonalMsgs: state.metamask.unapprovedPersonalMsgs, index: state.appState.currentView.context, warning: state.appState.warning, network: state.metamask.network, @@ -35,15 +37,12 @@ function ConfirmTxScreen () { } ConfirmTxScreen.prototype.render = function () { - var state = this.props + const props = this.props + const { network, provider, unapprovedTxs, + unapprovedMsgs, unapprovedPersonalMsgs } = props - var network = state.network - var provider = state.provider - var unapprovedTxs = state.unapprovedTxs - var unapprovedMsgs = state.unapprovedMsgs - - var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network) - var index = state.index !== undefined && unconfTxList[index] ? state.index : 0 + var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network) + var index = props.index !== undefined && unconfTxList[index] ? props.index : 0 var txData = unconfTxList[index] || {} var txParams = txData.params || {} var isNotification = isPopupOrNotification() === 'notification' @@ -75,20 +74,20 @@ ConfirmTxScreen.prototype.render = function () { }, [ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { style: { - display: state.index === 0 ? 'none' : 'inline-block', + display: props.index === 0 ? 'none' : 'inline-block', }, - onClick: () => state.dispatch(actions.previousTx()), + onClick: () => props.dispatch(actions.previousTx()), }), - ` ${state.index + 1} of ${unconfTxList.length} `, + ` ${props.index + 1} of ${unconfTxList.length} `, h('i.fa.fa-arrow-right.fa-lg.cursor-pointer', { style: { - display: state.index + 1 === unconfTxList.length ? 'none' : 'inline-block', + display: props.index + 1 === unconfTxList.length ? 'none' : 'inline-block', }, - onClick: () => state.dispatch(actions.nextTx()), + onClick: () => props.dispatch(actions.nextTx()), }), ]), - warningIfExists(state.warning), + warningIfExists(props.warning), h(ReactCSSTransitionGroup, { className: 'css-transition-group', @@ -101,12 +100,12 @@ ConfirmTxScreen.prototype.render = function () { // Properties txData: txData, key: txData.id, - selectedAddress: state.selectedAddress, - accounts: state.accounts, - identities: state.identities, + selectedAddress: props.selectedAddress, + accounts: props.accounts, + identities: props.identities, insufficientBalance: this.checkBalanceAgainstTx(txData), // Actions - buyEth: this.buyEth.bind(this, txParams.from || state.selectedAddress), + buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress), sendTransaction: this.sendTransaction.bind(this, txData), cancelTransaction: this.cancelTransaction.bind(this, txData), signMessage: this.signMessage.bind(this, txData), @@ -135,9 +134,9 @@ function currentTxView (opts) { } ConfirmTxScreen.prototype.checkBalanceAgainstTx = function (txData) { if (!txData.txParams) return false - var state = this.props - var address = txData.txParams.from || state.selectedAddress - var account = state.accounts[address] + var props = this.props + var address = txData.txParams.from || props.selectedAddress + var account = props.accounts[address] var balance = account ? account.balance : '0x0' var maxCost = new BN(txData.maxCost, 16) diff --git a/ui/lib/tx-helper.js b/ui/lib/tx-helper.js index 7f64f9fbe..c8dc46c9d 100644 --- a/ui/lib/tx-helper.js +++ b/ui/lib/tx-helper.js @@ -1,13 +1,16 @@ const valuesFor = require('../app/util').valuesFor -module.exports = function (unapprovedTxs, unapprovedMsgs, network) { +module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, network) { log.debug('tx-helper called with params:') - log.debug({ unapprovedTxs, unapprovedMsgs, network }) + log.debug({ unapprovedTxs, unapprovedMsgs, personalMsgs, network }) - var txValues = network ? valuesFor(unapprovedTxs).filter(tx => tx.txParams.metamaskNetworkId === network) : valuesFor(unapprovedTxs) + const txValues = network ? valuesFor(unapprovedTxs).filter(tx => tx.txParams.metamaskNetworkId === network) : valuesFor(unapprovedTxs) log.debug(`tx helper found ${txValues.length} unapproved txs`) - var msgValues = valuesFor(unapprovedMsgs) + const msgValues = valuesFor(unapprovedMsgs) log.debug(`tx helper found ${msgValues.length} unsigned messages`) - var allValues = txValues.concat(msgValues) + let allValues = txValues.concat(msgValues) + const personalValues = valuesFor(personalMsgs) + allValues = allValues.concat(personalValues) + return allValues.sort(tx => tx.time) }