diff --git a/ui/app/actions.js b/ui/app/actions.js index 2fbd578c5..ed1ff75e5 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -135,8 +135,18 @@ var actions = { getGasPrice, UPDATE_GAS_LIMIT: 'UPDATE_GAS_LIMIT', UPDATE_GAS_PRICE: 'UPDATE_GAS_PRICE', + UPDATE_GAS_TOTAL: 'UPDATE_GAS_TOTAL', + UPDATE_SEND_FROM: 'UPDATE_SEND_FROM', + UPDATE_SEND_TO: 'UPDATE_SEND_TO', + UPDATE_SEND_AMOUNT: 'UPDATE_SEND_AMOUNT', + UPDATE_SEND_MEMO: 'UPDATE_SEND_MEMO', updateGasLimit, updateGasPrice, + updateGasTotal, + updateSendFrom, + updateSendTo, + updateSendAmount, + updateSendMemo, setSelectedAddress, // app messages confirmSeedWords: confirmSeedWords, @@ -508,6 +518,42 @@ function updateGasPrice (gasPrice) { } } +function updateGasTotal (gasTotal) { + return { + type: actions.UPDATE_GAS_TOTAL, + value: gasTotal, + } +} + +function updateSendFrom (from) { + return { + type: actions.UPDATE_SEND_FROM, + value: from, + } +} + +function updateSendTo (to) { + return { + type: actions.UPDATE_SEND_TO, + value: to, + } +} + +function updateSendAmount (amount) { + return { + type: actions.UPDATE_SEND_AMOUNT, + value: amount, + } +} + +function updateSendMemo (memo) { + return { + type: actions.UPDATE_SEND_MEMO, + value: memo, + } +} + + function sendTx (txData) { log.info(`actions - sendTx: ${JSON.stringify(txData.txParams)}`) return (dispatch) => { diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js index 2df24b4e1..0ba768893 100644 --- a/ui/app/components/customize-gas-modal/index.js +++ b/ui/app/components/customize-gas-modal/index.js @@ -5,7 +5,7 @@ const connect = require('react-redux').connect const actions = require('../../actions') const GasModalCard = require('./gas-modal-card') -const { conversionUtil } = require('../../conversion-util') +const { conversionUtil, multiplyCurrencies } = require('../../conversion-util') const { getGasPrice, @@ -26,6 +26,7 @@ function mapDispatchToProps (dispatch) { hideModal: () => dispatch(actions.hideModal()), updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)), updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)), + updateGasTotal: newGasTotal => dispatch(actions.updateGasTotal(newGasTotal)), } } @@ -46,10 +47,18 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit) { updateGasPrice, updateGasLimit, hideModal, + updateGasTotal } = this.props + const newGasTotal = multiplyCurrencies(gasLimit, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) + updateGasPrice(gasPrice) updateGasLimit(gasLimit) + updateGasTotal(newGasTotal) hideModal() } diff --git a/ui/app/components/send/from-dropdown.js b/ui/app/components/send/from-dropdown.js index fd6fb7e64..6f2b9da68 100644 --- a/ui/app/components/send/from-dropdown.js +++ b/ui/app/components/send/from-dropdown.js @@ -38,7 +38,7 @@ FromDropdown.prototype.renderDropdown = function () { ...accounts.map(account => h(AccountListItem, { account, handleClick: () => { - onSelect(account.address) + onSelect(account) closeDropdown() }, icon: this.getListItemIcon(account, selectedAccount), diff --git a/ui/app/components/send/gas-fee-display-v2.js b/ui/app/components/send/gas-fee-display-v2.js index 961d55610..7c3913c7f 100644 --- a/ui/app/components/send/gas-fee-display-v2.js +++ b/ui/app/components/send/gas-fee-display-v2.js @@ -1,9 +1,7 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits -const CurrencyDisplay = require('./currency-display'); - -const { multiplyCurrencies } = require('../../conversion-util') +const CurrencyDisplay = require('./currency-display') module.exports = GasFeeDisplay @@ -15,24 +13,17 @@ function GasFeeDisplay () { GasFeeDisplay.prototype.render = function () { const { conversionRate, - gasLimit, - gasPrice, + gasTotal, onClick, } = this.props - const readyToRender = Boolean(gasLimit && gasPrice) - return h('div', [ - readyToRender + gasTotal ? h(CurrencyDisplay, { primaryCurrency: 'ETH', convertedCurrency: 'USD', - value: multiplyCurrencies(gasLimit, gasPrice, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, - }), + value: gasTotal, conversionRate, convertedPrefix: '$', readOnly: true, diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js index 8ac5cc961..dcf764048 100644 --- a/ui/app/components/send/send-v2-container.js +++ b/ui/app/components/send/send-v2-container.js @@ -15,6 +15,7 @@ const { getGasPrice, getGasLimit, getAddressBook, + getSendFrom, } = require('../../selectors') module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther) @@ -46,16 +47,15 @@ function mapStateToProps (state) { } return { - selectedAccount: getCurrentAccountWithSendEtherInfo(state), + ...state.metamask.send, + from: getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state), fromAccounts, toAccounts: [...fromAccounts, ...getAddressBook(state)], conversionRate, selectedToken, primaryCurrency, data, - tokenToUSDRate, - gasPrice: getGasPrice(state), - gasLimit: getGasLimit(state), + amountConversionRate: selectedToken ? tokenToUSDRate : conversionRate, } } @@ -71,5 +71,10 @@ function mapDispatchToProps (dispatch) { signTx: txParams => dispatch(actions.signTx(txParams)), setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)), addToAddressBook: address => dispatch(actions.addToAddressBook(address)), + updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)), + updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)), + updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)), + updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)), + updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)), } } diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index a9a54e91e..6915dbb0f 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -24,6 +24,11 @@ function reduceMetamask (state, action) { send: { gasLimit: null, gasPrice: null, + gasTotal: null, + from: '', + to: '', + amount: '0x0', + memo: '', }, }, state.metamask) @@ -157,6 +162,7 @@ function reduceMetamask (state, action) { tokens: action.newTokens, }) + // metamask.send case actions.UPDATE_GAS_LIMIT: return extend(metamaskState, { send: { @@ -178,6 +184,46 @@ function reduceMetamask (state, action) { isAccountMenuOpen: !metamaskState.isAccountMenuOpen, }) + case actions.UPDATE_GAS_TOTAL: + return extend(metamaskState, { + send: { + ...metamaskState.send, + gasTotal: action.value, + }, + }) + + case actions.UPDATE_SEND_FROM: + return extend(metamaskState, { + send: { + ...metamaskState.send, + from: action.value, + }, + }) + + case actions.UPDATE_SEND_TO: + return extend(metamaskState, { + send: { + ...metamaskState.send, + to: action.value, + }, + }) + + case actions.UPDATE_SEND_AMOUNT: + return extend(metamaskState, { + send: { + ...metamaskState.send, + amount: action.value, + }, + }) + + case actions.UPDATE_SEND_MEMO: + return extend(metamaskState, { + send: { + ...metamaskState.send, + memo: action.value, + }, + }) + default: return metamaskState diff --git a/ui/app/selectors.js b/ui/app/selectors.js index fffe7dd61..9d4e6eb67 100644 --- a/ui/app/selectors.js +++ b/ui/app/selectors.js @@ -13,6 +13,7 @@ const selectors = { getGasPrice, getGasLimit, getAddressBook, + getSendFrom, } module.exports = selectors @@ -107,3 +108,7 @@ function getGasPrice (state) { function getGasLimit (state) { return state.metamask.send.gasLimit } + +function getSendFrom (state) { + return state.metamask.send.from +} diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index c41ba9758..e3182689d 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -12,6 +12,8 @@ const GasFeeDisplay = require('./components/send/gas-fee-display-v2') const { showModal } = require('./actions') +const { multiplyCurrencies } = require('./conversion-util') + module.exports = SendTransactionScreen inherits(SendTransactionScreen, PersistentForm) @@ -19,13 +21,6 @@ function SendTransactionScreen () { PersistentForm.call(this) this.state = { - from: '', - to: '', - gasPrice: null, - gasLimit: null, - amount: '0x0', - txData: null, - memo: '', dropdownOpen: false, } @@ -41,6 +36,7 @@ SendTransactionScreen.prototype.componentWillMount = function () { estimateGas, selectedAddress, data, + updateGasTotal, } = this.props const { symbol } = selectedToken || {} @@ -58,13 +54,23 @@ SendTransactionScreen.prototype.componentWillMount = function () { Object.assign(estimateGasParams, { data }) } - Promise.all([ - getGasPrice(), - estimateGas({ - from: selectedAddress, - gas: '746a528800', - }), - ]) + Promise + .all([ + getGasPrice(), + estimateGas({ + from: selectedAddress, + gas: '746a528800', + }), + ]) + .then(([gasPrice, gas]) => { + + const newGasTotal = multiplyCurrencies(gas, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) + updateGasTotal(newGasTotal) + }) } SendTransactionScreen.prototype.renderHeaderIcon = function () { @@ -122,10 +128,11 @@ SendTransactionScreen.prototype.renderHeader = function () { SendTransactionScreen.prototype.renderFromRow = function () { const { + from, fromAccounts, conversionRate, - selectedAccount, setSelectedAddress, + updateSendFrom, } = this.props const { dropdownOpen } = this.state @@ -137,8 +144,8 @@ SendTransactionScreen.prototype.renderFromRow = function () { h(FromDropdown, { dropdownOpen, accounts: fromAccounts, - selectedAccount, - onSelect: address => setSelectedAddress(address), + selectedAccount: from, + onSelect: updateSendFrom, openDropdown: () => this.setState({ dropdownOpen: true }), closeDropdown: () => this.setState({ dropdownOpen: false }), conversionRate, @@ -148,12 +155,10 @@ SendTransactionScreen.prototype.renderFromRow = function () { } SendTransactionScreen.prototype.handleToChange = function (event) { + const { updateSendTo } = this.props const to = event.target.value - this.setState({ - ...this.state, - to, - }) + updateSendTo(to) } SendTransactionScreen.prototype.renderToRow = function () { @@ -174,26 +179,21 @@ SendTransactionScreen.prototype.renderToRow = function () { } SendTransactionScreen.prototype.handleAmountChange = function (value) { + const { updateSendAmount } = this.props const amount = value - this.setState({ - ...this.state, - amount, - }) + updateSendAmount(amount) } SendTransactionScreen.prototype.renderAmountRow = function () { const { - conversionRate, - tokenToUSDRate, selectedToken, primaryCurrency = 'ETH', + amountConversionRate, } = this.props const { amount } = this.state - const amountConversionRate = selectedToken ? tokenToUSDRate : conversionRate - return h('div.send-v2__form-row', [ h('div.send-v2__form-label', 'Amount:'), @@ -214,8 +214,7 @@ SendTransactionScreen.prototype.renderGasRow = function () { const { conversionRate, showCustomizeGasModal, - gasLimit, - gasPrice, + gasTotal, } = this.props return h('div.send-v2__form-row', [ @@ -223,8 +222,7 @@ SendTransactionScreen.prototype.renderGasRow = function () { h('div.send-v2__form-label', 'Gas fee:'), h(GasFeeDisplay, { - gasLimit, - gasPrice, + gasTotal, conversionRate, onClick: showCustomizeGasModal, }), @@ -239,6 +237,7 @@ SendTransactionScreen.prototype.renderGasRow = function () { } SendTransactionScreen.prototype.renderMemoRow = function () { + const { updateSendMemo } = this.props const { memo } = this.state return h('div.send-v2__form-row', [ @@ -247,12 +246,7 @@ SendTransactionScreen.prototype.renderMemoRow = function () { h(MemoTextArea, { memo, - onChange: (event) => { - this.setState({ - ...this.state, - memo: event.target.value, - }) - }, + onChange: (event) => updateSendMemo(event.target.value), }), ]) @@ -313,16 +307,14 @@ SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress) { SendTransactionScreen.prototype.onSubmit = function (event) { event.preventDefault() const { + from: {address: from}, to, amount, - } = this.state - const { gasLimit: gas, gasPrice, signTokenTx, signTx, selectedToken, - selectedAccount: { address: from }, toAccounts, } = this.props