diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index f1eb394d7..94ba141bc 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -1,6 +1,7 @@ const EventEmitter = require('events').EventEmitter const async = require('async') const Dnode = require('dnode') +const Eth = require('ethjs') const EthQuery = require('eth-query') const launchMetamaskUi = require('../../ui') const StreamProvider = require('web3-stream-provider') @@ -34,6 +35,7 @@ function setupWeb3Connection (connectionStream) { providerStream.on('error', console.error.bind(console)) global.ethereumProvider = providerStream global.ethQuery = new EthQuery(providerStream) + global.eth = new Eth(providerStream) } function setupControllerConnection (connectionStream, cb) { @@ -47,6 +49,7 @@ function setupControllerConnection (connectionStream, cb) { }) connectionStream.pipe(accountManagerDnode).pipe(connectionStream) accountManagerDnode.once('remote', function (accountManager) { + console.log({ accountManager }) // setup push events accountManager.on = eventEmitter.on.bind(eventEmitter) cb(null, accountManager) diff --git a/package.json b/package.json index de6e46833..82f464986 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "ethereumjs-tx": "^1.3.0", "ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", "ethereumjs-wallet": "^0.6.0", + "ethjs": "^0.2.8", "ethjs-ens": "^2.0.0", "ethjs-query": "^0.2.9", "express": "^4.14.0", 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 () { diff --git a/yarn.lock b/yarn.lock index ff4cac1e0..cf8613d99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3382,7 +3382,7 @@ ethjs-util@^0.1.3: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -ethjs@^0.2.7: +ethjs@^0.2.7, ethjs@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/ethjs/-/ethjs-0.2.8.tgz#65ed276c5e58e89d51d4573585b7a16142ccf8f0" dependencies: