From 7eb6dae4185d083ebb967256fdd09203b5092480 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 12 Sep 2017 02:22:23 -0700 Subject: Added signTokenTx; Adding token confirmation screen --- ui/app/actions.js | 16 +++++++++++ ui/app/components/pending-tx.js | 6 ++-- ui/app/components/send-token/index.js | 52 +++++++++++++++++++++++++++-------- 3 files changed, 60 insertions(+), 14 deletions(-) (limited to 'ui/app') diff --git a/ui/app/actions.js b/ui/app/actions.js index 9c0ca794e..3ee11ddb5 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1,3 +1,4 @@ +const abi = require('human-standard-token-abi') const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url') var actions = { @@ -118,6 +119,7 @@ var actions = { cancelPersonalMsg, sendTx: sendTx, signTx: signTx, + signTokenTx: signTokenTx, updateAndApproveTx, cancelTx: cancelTx, completedTx: completedTx, @@ -192,6 +194,7 @@ module.exports = actions var background = null function _setBackgroundConnection (backgroundConnection) { background = backgroundConnection + console.log({ background }) } function goHome () { @@ -439,6 +442,19 @@ function sendTx (txData) { } } +function signTokenTx (tokenAddress, toAddress, amount, txData) { + return dispatch => { + dispatch(actions.showLoadingIndication()) + const token = global.eth.contract(abi).at(tokenAddress) + token.transfer(toAddress, amount, txData) + .catch(err => { + dispatch(actions.hideLoadingIndication()) + dispatch(actions.displayWarning(err.message)) + }) + dispatch(actions.showConfTxPage({})) + } +} + function updateAndApproveTx (txData) { log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData)) return (dispatch) => { diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 31281faf2..ab425abf5 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -91,9 +91,9 @@ PendingTx.prototype.render = function () { // const maxCost = txFeeBn.add(amountBn) // const balanceBn = hexToBn(balance) // const insufficientBalance = balanceBn.lt(maxCost) - - const fromName = identities[txParams.from].name; - const toName = identities[txParams.to].name; + const fromName = identities[txParams.from].name + const to = identities[txParams.to] + const toName = to ? to.name : ' ' const endOfFromAddress = txParams.from.slice(txParams.from.length - 4) const endOfToAddress = txParams.to.slice(txParams.to.length - 4) diff --git a/ui/app/components/send-token/index.js b/ui/app/components/send-token/index.js index 439ea45b7..8c02ec45d 100644 --- a/ui/app/components/send-token/index.js +++ b/ui/app/components/send-token/index.js @@ -1,7 +1,7 @@ const Component = require('react').Component const connect = require('react-redux').connect const h = require('react-hyperscript') -const ethUtil = require('ethereumjs-util') +const { addHexPrefix } = require('ethereumjs-util') const classnames = require('classnames') const inherits = require('util').inherits const actions = require('../../actions') @@ -50,6 +50,14 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)), + hideWarning: () => dispatch(actions.hideWarning()), + addToAddressBook: (recipient, nickname) => dispatch( + actions.addToAddressBook(recipient, nickname) + ), + signTx: txParams => dispatch(actions.signTx(txParams)), + signTokenTx: (tokenAddress, toAddress, amount, txData) => ( + dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData)) + ), // showSidebar: () => { dispatch(actions.showSidebar()) }, // hideSidebar: () => { dispatch(actions.hideSidebar()) }, // showModal: (payload) => { dispatch(actions.showModal(payload)) }, @@ -75,13 +83,14 @@ function SendTokenScreen () { SendTokenScreen.prototype.validate = function () { const { to, - amount, + amount: stringAmount, gasPrice: hexGasPrice, gasLimit: hexGasLimit, } = this.state const gasPrice = parseInt(hexGasPrice, 16) const gasLimit = parseInt(hexGasLimit, 16) / 1000000000 + const amount = Number(stringAmount) if (to && amount && gasPrice && gasLimit) { return { @@ -92,7 +101,7 @@ SendTokenScreen.prototype.validate = function () { const errors = { to: !to ? 'Required' : null, - amount: !Number(amount) ? 'Required' : null, + amount: !amount ? 'Required' : null, gasPrice: !gasPrice ? 'Gas Price Required' : null, gasLimit: !gasLimit ? 'Gas Limit Required' : null, } @@ -104,20 +113,41 @@ SendTokenScreen.prototype.validate = function () { } SendTokenScreen.prototype.submit = function () { - // const { - // to, - // amount, - // selectedCurrency, - // isGasTooltipOpen, - // gasPrice, - // gasLimit, - // } = this.state + const { + to, + amount, + gasPrice, + gasLimit, + } = this.state + + const { + identities, + selectedAddress, + selectedTokenAddress, + hideWarning, + addToAddressBook, + signTokenTx, + } = this.props + + const { nickname = ' ' } = identities[to] || {} const { isValid, errors } = this.validate() if (!isValid) { return this.setState({ errors }) } + + hideWarning() + addToAddressBook(to, nickname) + + const txParams = { + from: selectedAddress, + value: '0', + gas: gasLimit, + gasPrice: gasPrice, + } + + signTokenTx(selectedTokenAddress, to, Number(amount).toString(16), txParams) } SendTokenScreen.prototype.renderToAddressInput = function () { -- cgit