diff options
Diffstat (limited to 'ui/app')
19 files changed, 428 insertions, 532 deletions
diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js index d6c259033..d942fd150 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -8,6 +8,17 @@ export default class AdvancedTabContent extends Component { t: PropTypes.func, } + constructor (props) { + super(props) + this.state = { + gasPrice: this.props.customGasPrice, + gasLimit: this.props.customGasLimit, + } + this.changeGasPrice = debounce(this.changeGasPrice, 500) + this.changeGasLimit = debounce(this.changeGasLimit, 500) + } + + static propTypes = { updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, @@ -20,15 +31,40 @@ export default class AdvancedTabContent extends Component { showGasLimitInfoModal: PropTypes.func, } - debouncedGasLimitReset = debounce((dVal) => { - if (dVal < 21000) { + componentDidUpdate (prevProps) { + const { customGasPrice: prevCustomGasPrice, customGasLimit: prevCustomGasLimit } = prevProps + const { customGasPrice, customGasLimit } = this.props + const { gasPrice, gasLimit } = this.state + + if (customGasPrice !== prevCustomGasPrice && customGasPrice !== gasPrice) { + this.setState({ gasPrice: customGasPrice }) + } + if (customGasLimit !== prevCustomGasLimit && customGasLimit !== gasLimit) { + this.setState({ gasLimit: customGasLimit }) + } + } + + onChangeGasLimit = (e) => { + this.setState({ gasLimit: e.target.value }) + this.changeGasLimit({ target: { value: e.target.value } }) + } + + changeGasLimit = (e) => { + if (e.target.value < 21000) { + this.setState({ gasLimit: 21000 }) this.props.updateCustomGasLimit(21000) + } else { + this.props.updateCustomGasLimit(Number(e.target.value)) } - }, 1000, { trailing: true }) + } + + onChangeGasPrice = (e) => { + this.setState({ gasPrice: e.target.value }) + this.changeGasPrice({ target: { value: e.target.value } }) + } - onChangeGasLimit = (val) => { - this.props.updateCustomGasLimit(val) - this.debouncedGasLimitReset(val) + changeGasPrice = (e) => { + this.props.updateCustomGasPrice(Number(e.target.value)) } gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) { @@ -74,7 +110,7 @@ export default class AdvancedTabContent extends Component { })} type="number" value={value} - onChange={event => onChange(Number(event.target.value))} + onChange={onChange} /> <div className={classnames('advanced-gas-inputs__gas-edit-row__input-arrows', { 'advanced-gas-inputs__gas-edit-row__input--error': isInError && errorType === 'error', @@ -82,13 +118,13 @@ export default class AdvancedTabContent extends Component { })}> <div className="advanced-gas-inputs__gas-edit-row__input-arrows__i-wrap" - onClick={() => onChange(value + 1)} + onClick={() => onChange({ target: { value: value + 1 } })} > <i className="fa fa-sm fa-angle-up" /> </div> <div className="advanced-gas-inputs__gas-edit-row__input-arrows__i-wrap" - onClick={() => onChange(Math.max(value - 1, 0))} + onClick={() => onChange({ target: { value: Math.max(value - 1, 0) } })} > <i className="fa fa-sm fa-angle-down" /> </div> @@ -120,9 +156,6 @@ export default class AdvancedTabContent extends Component { render () { const { - customGasPrice, - updateCustomGasPrice, - customGasLimit, insufficientBalance, customPriceIsSafe, isSpeedUp, @@ -134,8 +167,8 @@ export default class AdvancedTabContent extends Component { <div className="advanced-gas-inputs__gas-edit-rows"> { this.renderGasEditRow({ labelKey: 'gasPrice', - value: customGasPrice, - onChange: updateCustomGasPrice, + value: this.state.gasPrice, + onChange: this.onChangeGasPrice, insufficientBalance, customPriceIsSafe, showGWEI: true, @@ -144,7 +177,7 @@ export default class AdvancedTabContent extends Component { }) } { this.renderGasEditRow({ labelKey: 'gasLimit', - value: customGasLimit, + value: this.state.gasLimit, onChange: this.onChangeGasLimit, insufficientBalance, customPriceIsSafe, diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 9da9a2ef6..c260d6798 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -9,6 +9,7 @@ import { hideSidebar, updateSendAmount, setGasTotal, + updateTransaction, } from '../../../../store/actions' import { setCustomGasPrice, @@ -23,9 +24,6 @@ import { updateSendErrors, } from '../../../../ducks/send/send.duck' import { - updateGasAndCalculate, -} from '../../../../ducks/confirm-transaction/confirm-transaction.duck' -import { conversionRateSelector as getConversionRate, getCurrentCurrency, getCurrentEthBalance, @@ -52,9 +50,6 @@ import { getTokenBalance, } from '../../../../pages/send/send.selectors' import { - submittedPendingTransactionsSelector, -} from '../../../../selectors/transactions' -import { formatCurrency, } from '../../../../helpers/utils/confirm-tx.util' import { @@ -77,11 +72,16 @@ import { getMaxModeOn } from '../../../../pages/send/send-content/send-amount-ro import { calcMaxAmount } from '../../../../pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils' const mapStateToProps = (state, ownProps) => { + const { selectedAddressTxList } = state.metamask + const { modalState: { props: modalProps } = {} } = state.appState.modal || {} + const { txData = {} } = modalProps || {} const { transaction = {} } = ownProps + const selectedTransaction = selectedAddressTxList.find(({ id }) => id === (transaction.id || txData.id)) + const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) const gasEstimatesLoading = getGasEstimatesLoadingStatus(state) - const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id) + const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, selectedTransaction) const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit const customGasTotal = calcGasTotal(customModalGasLimitInHex, customModalGasPriceInHex) @@ -118,6 +118,7 @@ const mapStateToProps = (state, ownProps) => { conversionRate, }) + return { hideBasic, isConfirm: isConfirm(state), @@ -151,6 +152,7 @@ const mapStateToProps = (state, ownProps) => { transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal), sendAmount, }, + transaction: txData || transaction, isSpeedUp: transaction.status === 'submitted', txId: transaction.id, insufficientBalance, @@ -179,10 +181,10 @@ const mapDispatchToProps = dispatch => { dispatch(setGasLimit(newLimit)) dispatch(setGasPrice(newPrice)) }, - updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { + updateConfirmTxGasAndCalculate: (gasLimit, gasPrice, updatedTx) => { updateCustomGasPrice(gasPrice) dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16)))) - return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) + return dispatch(updateTransaction(updatedTx)) }, createSpeedUpTransaction: (txId, gasPrice) => { return dispatch(createSpeedUpTransaction(txId, gasPrice)) @@ -214,6 +216,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { selectedToken, tokenBalance, customGasLimit, + transaction, } = stateProps const { updateCustomGasPrice: dispatchUpdateCustomGasPrice, @@ -234,7 +237,15 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...ownProps, onSubmit: (gasLimit, gasPrice) => { if (isConfirm) { - dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice) + const updatedTx = { + ...transaction, + txParams: { + ...transaction.txParams, + gas: gasLimit, + gasPrice, + }, + } + dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice, updatedTx) dispatchHideModal() } else if (isSpeedUp) { dispatchCreateSpeedUpTransaction(txId, gasPrice) @@ -282,12 +293,10 @@ function calcCustomGasLimit (customGasLimitInHex) { return parseInt(customGasLimitInHex, 16) } -function getTxParams (state, transactionId) { - const { confirmTransaction: { txData }, metamask: { send } } = state - const pendingTransactions = submittedPendingTransactionsSelector(state) - const pendingTransaction = pendingTransactions.find(({ id }) => id === transactionId) - const { txParams: pendingTxParams } = pendingTransaction || {} - return txData.txParams || pendingTxParams || { +function getTxParams (state, selectedTransaction = {}) { + const { metamask: { send } } = state + const { txParams } = selectedTransaction + return txParams || { from: send.from, gas: send.gasLimit || '0x5208', gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true), diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index dbe61d5cf..03d254eee 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -63,6 +63,9 @@ describe('gas-modal-page-container container', () => { modalState: { props: { hideBasic: true, + txData: { + id: 34, + }, }, }, }, @@ -82,6 +85,14 @@ describe('gas-modal-page-container container', () => { provider: { type: 'mainnet', }, + selectedAddressTxList: [{ + id: 34, + txParams: { + gas: '0x1600000', + gasPrice: '0x3200000', + value: '0x640000000000000', + }, + }], }, gas: { basicEstimates: { @@ -152,6 +163,9 @@ describe('gas-modal-page-container container', () => { maxModeOn: false, selectedToken: null, tokenBalance: '0x0', + transaction: { + id: 34, + }, } const baseMockOwnProps = { transaction: { id: 34 } } const tests = [ @@ -168,7 +182,7 @@ describe('gas-modal-page-container container', () => { mockOwnProps: Object.assign({}, baseMockOwnProps, { transaction: { id: 34, status: 'submitted' }, }), - expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true }), + expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true, transaction: { id: 34 } }), }, { mockState: Object.assign({}, baseMockState, { @@ -317,8 +331,10 @@ describe('gas-modal-page-container container', () => { it('should dispatch a updateGasAndCalculate action with the correct props', () => { mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') assert.equal(dispatchSpy.callCount, 3) - assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce) - assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' }) + assert(actionSpies.setGasPrice.calledOnce) + assert(actionSpies.setGasLimit.calledOnce) + assert.equal(actionSpies.setGasLimit.getCall(0).args[0], 'ffff') + assert.equal(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa') }) }) @@ -337,6 +353,7 @@ describe('gas-modal-page-container container', () => { }, isConfirm: true, someOtherStateProp: 'baz', + transaction: {}, } dispatchProps = { updateCustomGasPrice: sinon.spy(), diff --git a/ui/app/components/app/modals/account-details-modal.js b/ui/app/components/app/modals/account-details-modal.js deleted file mode 100644 index 6cffc918b..000000000 --- a/ui/app/components/app/modals/account-details-modal.js +++ /dev/null @@ -1,107 +0,0 @@ -const Component = require('react').Component -const PropTypes = require('prop-types') -const h = require('react-hyperscript') -const inherits = require('util').inherits -const connect = require('react-redux').connect -const actions = require('../../../store/actions') -const AccountModalContainer = require('./account-modal-container') -const { getSelectedIdentity, getRpcPrefsForCurrentProvider } = require('../../../selectors/selectors') -const genAccountLink = require('../../../../lib/account-link.js') -const QrView = require('../../ui/qr-code') -const EditableLabel = require('../../ui/editable-label') - -import Button from '../../ui/button' - -function mapStateToProps (state) { - return { - network: state.metamask.network, - selectedIdentity: getSelectedIdentity(state), - keyrings: state.metamask.keyrings, - rpcPrefs: getRpcPrefsForCurrentProvider(state), - } -} - -function mapDispatchToProps (dispatch) { - return { - // Is this supposed to be used somewhere? - showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), - showExportPrivateKeyModal: () => { - dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' })) - }, - hideModal: () => dispatch(actions.hideModal()), - setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)), - } -} - -inherits(AccountDetailsModal, Component) -function AccountDetailsModal () { - Component.call(this) -} - -AccountDetailsModal.contextTypes = { - t: PropTypes.func, -} - -module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) - - -// Not yet pixel perfect todos: - // fonts of qr-header - -AccountDetailsModal.prototype.render = function () { - const { - selectedIdentity, - network, - showExportPrivateKeyModal, - setAccountLabel, - keyrings, - rpcPrefs, - } = this.props - const { name, address } = selectedIdentity - - const keyring = keyrings.find((kr) => { - return kr.accounts.includes(address) - }) - - let exportPrivateKeyFeatureEnabled = true - // This feature is disabled for hardware wallets - if (keyring && keyring.type.search('Hardware') !== -1) { - exportPrivateKeyFeatureEnabled = false - } - - return h(AccountModalContainer, {}, [ - h(EditableLabel, { - className: 'account-modal__name', - defaultValue: name, - onSubmit: label => setAccountLabel(address, label), - }), - - h(QrView, { - Qr: { - data: address, - network: network, - }, - }), - - h('div.account-modal-divider'), - - h(Button, { - type: 'secondary', - className: 'account-modal__button', - onClick: () => { - global.platform.openWindow({ url: genAccountLink(address, network, rpcPrefs) }) - }, - }, (rpcPrefs.blockExplorerUrl - ? this.context.t('blockExplorerView', [rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]]) - : this.context.t('viewOnEtherscan'))), - - // Holding on redesign for Export Private Key functionality - - exportPrivateKeyFeatureEnabled ? h(Button, { - type: 'secondary', - className: 'account-modal__button', - onClick: () => showExportPrivateKeyModal(), - }, this.context.t('exportPrivateKey')) : null, - - ]) -} diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js new file mode 100644 index 000000000..e3919edcf --- /dev/null +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js @@ -0,0 +1,87 @@ +import React, { Component} from 'react' +import PropTypes from 'prop-types' +import AccountModalContainer from '../account-modal-container' +import genAccountLink from '../../../../../lib/account-link.js' +import QrView from '../../../ui/qr-code' +import EditableLabel from '../../../ui/editable-label' +import Button from '../../../ui/button' + +export default class AccountDetailsModal extends Component { + static propTypes = { + selectedIdentity: PropTypes.object, + network: PropTypes.string, + showExportPrivateKeyModal: PropTypes.func, + setAccountLabel: PropTypes.func, + keyrings: PropTypes.array, + rpcPrefs: PropTypes.object, + } + + static contextTypes = { + t: PropTypes.func, + } + + render () { + const { + selectedIdentity, + network, + showExportPrivateKeyModal, + setAccountLabel, + keyrings, + rpcPrefs, + } = this.props + const { name, address } = selectedIdentity + + const keyring = keyrings.find((kr) => { + return kr.accounts.includes(address) + }) + + let exportPrivateKeyFeatureEnabled = true + // This feature is disabled for hardware wallets + if (keyring && keyring.type.search('Hardware') !== -1) { + exportPrivateKeyFeatureEnabled = false + } + + return ( + <AccountModalContainer> + <EditableLabel + className="account-modal__name" + defaultValue={name} + onSubmit={label => setAccountLabel(address, label)} + /> + + <QrView + Qr={{ + data: address, + network: network, + }} + /> + + <div className="account-modal-divider"/> + + <Button + type="secondary" + className="account-modal__button" + onClick={() => { + global.platform.openWindow({ url: genAccountLink(address, network, rpcPrefs) }) + }} + > + {rpcPrefs.blockExplorerUrl + ? this.context.t('blockExplorerView', [rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]]) + : this.context.t('viewOnEtherscan') + } + </Button> + + {exportPrivateKeyFeatureEnabled + ? <Button + type="secondary" + className="account-modal__button" + onClick={() => showExportPrivateKeyModal()} + > + {this.context.t('exportPrivateKey')} + </Button> + : null + } + </AccountModalContainer> + ) + } +} diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js new file mode 100644 index 000000000..4b2283ced --- /dev/null +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js @@ -0,0 +1,27 @@ +import { connect } from 'react-redux' +import actions from '../../../../store/actions' +import { getSelectedIdentity, getRpcPrefsForCurrentProvider } from '../../../../selectors/selectors' +import AccountDetailsModal from './account-details-modal.component' + +const mapStateToProps = (state) => { + return { + network: state.metamask.network, + selectedIdentity: getSelectedIdentity(state), + keyrings: state.metamask.keyrings, + rpcPrefs: getRpcPrefsForCurrentProvider(state), + } +} + +const mapDispatchToProps = (dispatch) => { + return { + // Is this supposed to be used somewhere? + showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), + showExportPrivateKeyModal: () => { + dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' })) + }, + hideModal: () => dispatch(actions.hideModal()), + setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)), + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) diff --git a/ui/app/components/app/modals/account-details-modal/index.js b/ui/app/components/app/modals/account-details-modal/index.js new file mode 100644 index 000000000..433f4d170 --- /dev/null +++ b/ui/app/components/app/modals/account-details-modal/index.js @@ -0,0 +1 @@ +export { default } from './account-details-modal.container' diff --git a/ui/app/components/app/modals/deposit-ether-modal.js b/ui/app/components/app/modals/deposit-ether-modal.js index f56069d65..20c4d018c 100644 --- a/ui/app/components/app/modals/deposit-ether-modal.js +++ b/ui/app/components/app/modals/deposit-ether-modal.js @@ -5,7 +5,6 @@ const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../../store/actions') const { getNetworkDisplayName } = require('../../../../../app/scripts/controllers/network/util') -const ShapeshiftForm = require('../shapeshift-form') import Button from '../../ui/button' @@ -13,8 +12,6 @@ let DIRECT_DEPOSIT_ROW_TITLE let DIRECT_DEPOSIT_ROW_TEXT let WYRE_ROW_TITLE let WYRE_ROW_TEXT -let SHAPESHIFT_ROW_TITLE -let SHAPESHIFT_ROW_TEXT let FAUCET_ROW_TITLE let COINSWITCH_ROW_TITLE let COINSWITCH_ROW_TEXT @@ -56,15 +53,9 @@ function DepositEtherModal (_, context) { DIRECT_DEPOSIT_ROW_TEXT = context.t('directDepositEtherExplainer') WYRE_ROW_TITLE = context.t('buyWithWyre') WYRE_ROW_TEXT = context.t('buyWithWyreDescription') - SHAPESHIFT_ROW_TITLE = context.t('depositShapeShift') - SHAPESHIFT_ROW_TEXT = context.t('depositShapeShiftExplainer') FAUCET_ROW_TITLE = context.t('testFaucet') COINSWITCH_ROW_TITLE = context.t('buyCoinSwitch') COINSWITCH_ROW_TEXT = context.t('buyCoinSwitchExplainer') - - this.state = { - buyingWithShapeshift: false, - } } DepositEtherModal.contextTypes = { @@ -131,7 +122,6 @@ DepositEtherModal.prototype.renderRow = function ({ DepositEtherModal.prototype.render = function () { const { network, toWyre, toCoinSwitch, address, toFaucet } = this.props - const { buyingWithShapeshift } = this.state const isTestNetwork = ['3', '4', '5', '42'].find(n => n === network) const networkName = getNetworkDisplayName(network) @@ -148,7 +138,6 @@ DepositEtherModal.prototype.render = function () { h('div.page-container__header-close', { onClick: () => { - this.setState({ buyingWithShapeshift: false }) this.props.hideWarning() this.props.hideModal() }, @@ -168,7 +157,6 @@ DepositEtherModal.prototype.render = function () { text: DIRECT_DEPOSIT_ROW_TEXT, buttonLabel: this.context.t('viewAccount'), onButtonClick: () => this.goToAccountDetailsModal(), - hide: buyingWithShapeshift, }), this.renderRow({ @@ -177,7 +165,7 @@ DepositEtherModal.prototype.render = function () { text: this.facuetRowText(networkName), buttonLabel: this.context.t('getEther'), onButtonClick: () => toFaucet(network), - hide: !isTestNetwork || buyingWithShapeshift, + hide: !isTestNetwork, }), this.renderRow({ @@ -191,7 +179,7 @@ DepositEtherModal.prototype.render = function () { text: WYRE_ROW_TEXT, buttonLabel: this.context.t('continueToWyre'), onButtonClick: () => toWyre(address), - hide: isTestNetwork || buyingWithShapeshift, + hide: isTestNetwork, }), this.renderRow({ @@ -205,29 +193,9 @@ DepositEtherModal.prototype.render = function () { text: COINSWITCH_ROW_TEXT, buttonLabel: this.context.t('continueToCoinSwitch'), onButtonClick: () => toCoinSwitch(address), - hide: isTestNetwork || buyingWithShapeshift, - }), - - this.renderRow({ - logo: h('div.deposit-ether-modal__logo', { - style: { - backgroundImage: 'url(\'./images/shapeshift logo.png\')', - }, - }), - title: SHAPESHIFT_ROW_TITLE, - text: SHAPESHIFT_ROW_TEXT, - buttonLabel: this.context.t('shapeshiftBuy'), - onButtonClick: () => this.setState({ buyingWithShapeshift: true }), hide: isTestNetwork, - hideButton: buyingWithShapeshift, - hideTitle: buyingWithShapeshift, - onBackClick: () => this.setState({ buyingWithShapeshift: false }), - showBackButton: this.state.buyingWithShapeshift, - className: buyingWithShapeshift && 'deposit-ether-modal__buy-row__shapeshift-buy', }), - buyingWithShapeshift && h(ShapeshiftForm), - ]), ]), diff --git a/ui/app/components/app/modals/modal.js b/ui/app/components/app/modals/modal.js index 717f623af..394367c46 100644 --- a/ui/app/components/app/modals/modal.js +++ b/ui/app/components/app/modals/modal.js @@ -12,11 +12,10 @@ const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums // Modal Components const BuyOptions = require('./buy-options-modal') const DepositEtherModal = require('./deposit-ether-modal') -const AccountDetailsModal = require('./account-details-modal') +import AccountDetailsModal from './account-details-modal' const EditAccountNameModal = require('./edit-account-name-modal') const ExportPrivateKeyModal = require('./export-private-key-modal') const NewAccountModal = require('./new-account-modal') -const ShapeshiftDepositTxModal = require('./shapeshift-deposit-tx-modal.js') const HideTokenConfirmationModal = require('./hide-token-confirmation-modal') const NotifcationModal = require('./notification-modal') const QRScanner = require('./qr-scanner') @@ -181,13 +180,6 @@ const MODALS = { ...accountModalStyle, }, - SHAPESHIFT_DEPOSIT_TX: { - contents: [ - h(ShapeshiftDepositTxModal), - ], - ...accountModalStyle, - }, - HIDE_TOKEN_CONFIRMATION: { contents: [ h(HideTokenConfirmationModal, {}, []), diff --git a/ui/app/components/app/modals/shapeshift-deposit-tx-modal.js b/ui/app/components/app/modals/shapeshift-deposit-tx-modal.js deleted file mode 100644 index ada9430f7..000000000 --- a/ui/app/components/app/modals/shapeshift-deposit-tx-modal.js +++ /dev/null @@ -1,40 +0,0 @@ -const Component = require('react').Component -const h = require('react-hyperscript') -const inherits = require('util').inherits -const connect = require('react-redux').connect -const actions = require('../../../store/actions') -const QrView = require('../../ui/qr-code') -const AccountModalContainer = require('./account-modal-container') - -function mapStateToProps (state) { - return { - Qr: state.appState.modal.modalState.props.Qr, - } -} - -function mapDispatchToProps (dispatch) { - return { - hideModal: () => { - dispatch(actions.hideModal()) - }, - } -} - -inherits(ShapeshiftDepositTxModal, Component) -function ShapeshiftDepositTxModal () { - Component.call(this) - -} - -module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftDepositTxModal) - -ShapeshiftDepositTxModal.prototype.render = function () { - const { Qr } = this.props - - return h(AccountModalContainer, { - }, [ - h('div', {}, [ - h(QrView, {key: 'qr', Qr}), - ]), - ]) -} diff --git a/ui/app/components/app/shapeshift-form.js b/ui/app/components/app/shapeshift-form.js deleted file mode 100644 index 34a6f3acd..000000000 --- a/ui/app/components/app/shapeshift-form.js +++ /dev/null @@ -1,256 +0,0 @@ -const h = require('react-hyperscript') -const inherits = require('util').inherits -const PropTypes = require('prop-types') -const Component = require('react').Component -const connect = require('react-redux').connect -const classnames = require('classnames') -const qrcode = require('qrcode-generator') -const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../../store/actions') -const { isValidAddress } = require('../../helpers/utils/util') -const SimpleDropdown = require('./dropdowns/simple-dropdown') - -import Button from '../ui/button' - -function mapStateToProps (state) { - const { - coinOptions, - tokenExchangeRates, - selectedAddress, - } = state.metamask - const { warning } = state.appState - - return { - coinOptions, - tokenExchangeRates, - selectedAddress, - warning, - } -} - -function mapDispatchToProps (dispatch) { - return { - shapeShiftSubview: () => dispatch(shapeShiftSubview()), - pairUpdate: coin => dispatch(pairUpdate(coin)), - buyWithShapeShift: data => dispatch(buyWithShapeShift(data)), - } -} - -ShapeshiftForm.contextTypes = { - t: PropTypes.func, -} - -module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm) - - -inherits(ShapeshiftForm, Component) -function ShapeshiftForm () { - Component.call(this) - - this.state = { - depositCoin: 'btc', - refundAddress: '', - showQrCode: false, - depositAddress: '', - errorMessage: '', - isLoading: false, - bought: false, - } -} - -ShapeshiftForm.prototype.getCoinPair = function () { - return `${this.state.depositCoin.toUpperCase()}_ETH` -} - -ShapeshiftForm.prototype.componentWillMount = function () { - this.props.shapeShiftSubview() -} - -ShapeshiftForm.prototype.onCoinChange = function (coin) { - this.setState({ - depositCoin: coin, - errorMessage: '', - }) - this.props.pairUpdate(coin) -} - -ShapeshiftForm.prototype.onBuyWithShapeShift = function () { - this.setState({ - isLoading: true, - showQrCode: true, - }) - - const { - buyWithShapeShift, - selectedAddress: withdrawal, - } = this.props - const { - refundAddress: returnAddress, - depositCoin, - } = this.state - const pair = `${depositCoin}_eth` - const data = { - withdrawal, - pair, - returnAddress, - // Public api key - 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6', - } - - if (isValidAddress(withdrawal)) { - buyWithShapeShift(data) - .then(d => this.setState({ - showQrCode: true, - depositAddress: d.deposit, - isLoading: false, - })) - .catch(() => this.setState({ - showQrCode: false, - errorMessage: this.context.t('invalidRequest'), - isLoading: false, - })) - } -} - -ShapeshiftForm.prototype.renderMetadata = function (label, value) { - return h('div', {className: 'shapeshift-form__metadata-wrapper'}, [ - - h('div.shapeshift-form__metadata-label', {}, [ - h('span', `${label}:`), - ]), - - h('div.shapeshift-form__metadata-value', {}, [ - h('span', value), - ]), - - ]) -} - -ShapeshiftForm.prototype.renderMarketInfo = function () { - const { tokenExchangeRates } = this.props - const { - limit, - rate, - minimum, - } = tokenExchangeRates[this.getCoinPair()] || {} - - return h('div.shapeshift-form__metadata', {}, [ - - this.renderMetadata(this.context.t('status'), limit ? this.context.t('available') : this.context.t('unavailable')), - this.renderMetadata(this.context.t('limit'), limit), - this.renderMetadata(this.context.t('exchangeRate'), rate), - this.renderMetadata(this.context.t('min'), minimum), - - ]) -} - -ShapeshiftForm.prototype.renderQrCode = function () { - const { depositAddress, isLoading, depositCoin } = this.state - const qrImage = qrcode(4, 'M') - qrImage.addData(depositAddress) - qrImage.make() - - return h('div.shapeshift-form', {}, [ - - h('div.shapeshift-form__deposit-instruction', [ - this.context.t('depositCoin', [depositCoin.toUpperCase()]), - ]), - - h('div', depositAddress), - - h('div.shapeshift-form__qr-code', [ - isLoading - ? h('img', { - src: 'images/loading.svg', - style: { width: '60px'}, - }) - : h('div', { - dangerouslySetInnerHTML: { __html: qrImage.createTableTag(4) }, - }), - ]), - - this.renderMarketInfo(), - - ]) -} - - -ShapeshiftForm.prototype.render = function () { - const { coinOptions, btnClass, warning } = this.props - const { errorMessage, showQrCode, depositAddress } = this.state - const { tokenExchangeRates } = this.props - const token = tokenExchangeRates[this.getCoinPair()] - - return h('div.shapeshift-form-wrapper', [ - showQrCode - ? this.renderQrCode() - : h('div.modal-shapeshift-form', [ - h('div.shapeshift-form__selectors', [ - - h('div.shapeshift-form__selector', [ - - h('div.shapeshift-form__selector-label', this.context.t('deposit')), - - h(SimpleDropdown, { - selectedOption: this.state.depositCoin, - onSelect: (coin) => this.onCoinChange(coin), - options: Object.entries(coinOptions).map(([coin]) => ({ - value: coin.toLowerCase(), - displayValue: coin, - })), - }), - - ]), - - h('div.icon.shapeshift-form__caret', { - style: { backgroundImage: 'url(images/caret-right.svg)'}, - }), - - h('div.shapeshift-form__selector', [ - - h('div.shapeshift-form__selector-label', [ - this.context.t('receive'), - ]), - - h('div.shapeshift-form__selector-input', ['ETH']), - - ]), - - ]), - - warning && h('div.shapeshift-form__address-input-label', warning), - - !warning && h('div', { - className: classnames('shapeshift-form__address-input-wrapper', { - 'shapeshift-form__address-input-wrapper--error': errorMessage, - }), - }, [ - - h('div.shapeshift-form__address-input-label', [ - this.context.t('refundAddress'), - ]), - - h('input.shapeshift-form__address-input', { - type: 'text', - onChange: e => this.setState({ - refundAddress: e.target.value, - errorMessage: '', - }), - }), - - h('divshapeshift-form__address-input-error-message', [errorMessage]), - ]), - - !warning && this.renderMarketInfo(), - - ]), - - !depositAddress && h(Button, { - type: 'secondary', - large: true, - className: `${btnClass} shapeshift-form__shapeshift-buy-btn`, - disabled: !token, - onClick: () => this.onBuyWithShapeShift(), - }, [this.context.t('buy')]), - - ]) -} diff --git a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js index fc5e2f90d..5d2ccb083 100644 --- a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js +++ b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js @@ -1,7 +1,10 @@ import { connect } from 'react-redux' +import { compose } from 'recompose' +import { withRouter } from 'react-router-dom' import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component' import { contractExchangeRateSelector, + transactionFeeSelector, } from '../../selectors/confirm-transaction' import { tokenSelector } from '../../selectors/tokens' import { @@ -14,15 +17,21 @@ import { } from '../../helpers/utils/token-util' -const mapStateToProps = (state) => { - const { confirmTransaction, metamask: { currentCurrency, conversionRate } } = state +const mapStateToProps = (state, ownProps) => { + const { match: { params = {} } } = ownProps + const { id: paramsTransactionId } = params + const { confirmTransaction, metamask: { currentCurrency, conversionRate, selectedAddressTxList } } = state + const { - txData: { txParams: { to: tokenAddress, data } = {} } = {}, - fiatTransactionTotal, - ethTransactionTotal, + txData: { id: transactionId, txParams: { to: tokenAddress, data } = {} } = {}, } = confirmTransaction + const transaction = selectedAddressTxList.find(({ id }) => id === (Number(paramsTransactionId) || transactionId)) || {} + const { + ethTransactionTotal, + fiatTransactionTotal, + } = transactionFeeSelector(state, transaction) const tokens = tokenSelector(state) const currentToken = tokens && tokens.find(({ address }) => tokenAddress === address) const { decimals, symbol: tokenSymbol } = currentToken || {} @@ -46,4 +55,7 @@ const mapStateToProps = (state) => { } } -export default connect(mapStateToProps)(ConfirmTokenTransactionBase) +export default compose( + withRouter, + connect(mapStateToProps) +)(ConfirmTokenTransactionBase) diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js index e769d8974..2a1b78a8e 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -6,9 +6,9 @@ import contractMap from 'eth-contract-metadata' import ConfirmTransactionBase from './confirm-transaction-base.component' import { clearConfirmTransaction, - updateGasAndCalculate, } from '../../ducks/confirm-transaction/confirm-transaction.duck' -import { clearSend, cancelTx, cancelTxs, updateAndApproveTx, showModal, setMetaMetricsSendCount } from '../../store/actions' + +import { clearSend, cancelTx, cancelTxs, updateAndApproveTx, showModal, setMetaMetricsSendCount, updateTransaction } from '../../store/actions' import { INSUFFICIENT_FUNDS_ERROR_KEY, GAS_LIMIT_TOO_LOW_ERROR_KEY, @@ -19,6 +19,7 @@ import { conversionGreaterThan } from '../../helpers/utils/conversion-util' import { MIN_GAS_LIMIT_DEC } from '../send/send.constants' import { checksumAddress, addressSlicer, valuesFor } from '../../helpers/utils/util' import { getMetaMaskAccounts, getAdvancedInlineGasShown, preferencesSelector, getIsMainnet, getKnownMethodData } from '../../selectors/selectors' +import { transactionFeeSelector } from '../../selectors/confirm-transaction' const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { return { @@ -32,23 +33,26 @@ const mapStateToProps = (state, ownProps) => { const { id: paramsTransactionId } = params const { showFiatInTestnets } = preferencesSelector(state) const isMainnet = getIsMainnet(state) - const { confirmTransaction, metamask, gas } = state + const { confirmTransaction, metamask } = state + const { + conversionRate, + identities, + currentCurrency, + selectedAddress, + selectedAddressTxList, + assetImages, + network, + unapprovedTxs, + metaMetricsSendCount, + } = metamask const { - ethTransactionAmount, - ethTransactionFee, - ethTransactionTotal, - fiatTransactionAmount, - fiatTransactionFee, - fiatTransactionTotal, - hexTransactionAmount, - hexTransactionFee, - hexTransactionTotal, tokenData, txData, tokenProps, nonce, } = confirmTransaction const { txParams = {}, lastGasPrice, id: transactionId, transactionCategory } = txData + const transaction = R.find(({ id }) => id === (transactionId || Number(paramsTransactionId)))(selectedAddressTxList) || {} const { from: fromAddress, to: txParamsToAddress, @@ -56,26 +60,10 @@ const mapStateToProps = (state, ownProps) => { gas: gasLimit, value: amount, data, - } = txParams + } = transaction && transaction.txParams || txParams const accounts = getMetaMaskAccounts(state) - const { - conversionRate, - identities, - currentCurrency, - selectedAddress, - selectedAddressTxList, - assetImages, - network, - unapprovedTxs, - metaMetricsSendCount, - } = metamask const assetImage = assetImages[txParamsToAddress] - const { - customGasLimit, - customGasPrice, - } = gas - const { balance } = accounts[selectedAddress] const { name: fromName } = identities[selectedAddress] const toAddress = propsToAddress || txParamsToAddress @@ -88,9 +76,20 @@ const mapStateToProps = (state, ownProps) => { ) const isTxReprice = Boolean(lastGasPrice) - const transaction = R.find(({ id }) => id === (transactionId || Number(paramsTransactionId)))(selectedAddressTxList) const transactionStatus = transaction ? transaction.status : '' + const { + ethTransactionAmount, + ethTransactionFee, + ethTransactionTotal, + fiatTransactionAmount, + fiatTransactionFee, + fiatTransactionTotal, + hexTransactionAmount, + hexTransactionFee, + hexTransactionTotal, + } = transactionFeeSelector(state, transaction) + if (transaction && transaction.simulationFails) { txData.simulationFails = transaction.simulationFails } @@ -125,7 +124,7 @@ const mapStateToProps = (state, ownProps) => { hexTransactionAmount, hexTransactionFee, hexTransactionTotal, - txData: Object.keys(txData).length ? txData : transaction || {}, + txData: { ...txData, ...transaction }, tokenData, methodData, tokenProps, @@ -139,8 +138,8 @@ const mapStateToProps = (state, ownProps) => { unapprovedTxCount, currentNetworkUnapprovedTxs, customGas: { - gasLimit: customGasLimit || gasLimit, - gasPrice: customGasPrice || gasPrice, + gasLimit, + gasPrice, }, advancedInlineGasShown: getAdvancedInlineGasShown(state), insufficientBalance, @@ -161,8 +160,8 @@ const mapDispatchToProps = dispatch => { showCustomizeGasModal: ({ txData, onSubmit, validate }) => { return dispatch(showModal({ name: 'CUSTOMIZE_GAS', txData, onSubmit, validate })) }, - updateGasAndCalculate: ({ gasLimit, gasPrice }) => { - return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) + updateGasAndCalculate: (updatedTx) => { + return dispatch(updateTransaction(updatedTx)) }, showRejectTransactionsConfirmationModal: ({ onSubmit, unapprovedTxCount }) => { return dispatch(showModal({ name: 'REJECT_TRANSACTIONS', onSubmit, unapprovedTxCount })) @@ -239,7 +238,17 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { validate: validateEditGas, }), cancelAllTransactions: () => dispatchCancelAllTransactions(valuesFor(unapprovedTxs)), - updateGasAndCalculate: dispatchUpdateGasAndCalculate, + updateGasAndCalculate: ({ gasLimit, gasPrice }) => { + const updatedTx = { + ...txData, + txParams: { + ...txData.txParams, + gas: gasLimit, + gasPrice, + }, + } + dispatchUpdateGasAndCalculate(updatedTx) + }, } } diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js index 5092d277e..a2fb5a3bf 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js @@ -30,10 +30,21 @@ export default class ImportWithSeedPhrase extends PureComponent { } parseSeedPhrase = (seedPhrase) => { - return seedPhrase - .trim() - .match(/\w+/g) - .join(' ') + if (!seedPhrase) { + return '' + } + + const trimmed = seedPhrase.trim() + if (!trimmed) { + return '' + } + + const words = trimmed.match(/\w+/g) + if (!words) { + return '' + } + + return words.join(' ') } componentWillMount () { diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js new file mode 100644 index 000000000..7960d17b2 --- /dev/null +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js @@ -0,0 +1,78 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import sinon from 'sinon' +import ImportWithSeedPhrase from '../import-with-seed-phrase.component' + +function shallowRender (props = {}, context = {}) { + return shallow(<ImportWithSeedPhrase {...props} />, { + context: { + t: str => str + '_t', + metricsEvent: sinon.spy(), + ...context, + }, + }) +} + +describe('ImportWithSeedPhrase Component', () => { + it('should render without error', () => { + const root = shallowRender({ + onSubmit: sinon.spy(), + }) + const textareaCount = root.find('.first-time-flow__textarea').length + assert.equal(textareaCount, 1, 'should render 12 seed phrases') + }) + + describe('parseSeedPhrase', () => { + it('should handle a regular seed phrase', () => { + const root = shallowRender({ + onSubmit: sinon.spy(), + }) + + const {parseSeedPhrase} = root.instance() + + assert.deepEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz') + }) + + it('should trim extraneous whitespace from the given seed phrase', () => { + const root = shallowRender({ + onSubmit: sinon.spy(), + }) + + const {parseSeedPhrase} = root.instance() + + assert.deepEqual(parseSeedPhrase(' foo bar baz '), 'foo bar baz') + }) + + it('should return an empty string when given a whitespace-only string', () => { + const root = shallowRender({ + onSubmit: sinon.spy(), + }) + + const {parseSeedPhrase} = root.instance() + + assert.deepEqual(parseSeedPhrase(' '), '') + }) + + it('should return an empty string when given a string with only symbols', () => { + const root = shallowRender({ + onSubmit: sinon.spy(), + }) + + const {parseSeedPhrase} = root.instance() + + assert.deepEqual(parseSeedPhrase('$'), '') + }) + + it('should return an empty string for both null and undefined', () => { + const root = shallowRender({ + onSubmit: sinon.spy(), + }) + + const {parseSeedPhrase} = root.instance() + + assert.deepEqual(parseSeedPhrase(undefined), '') + assert.deepEqual(parseSeedPhrase(null), '') + }) + }) +}) diff --git a/ui/app/pages/first-time-flow/first-time-flow.component.js b/ui/app/pages/first-time-flow/first-time-flow.component.js index bf6e80ca9..0d206bf42 100644 --- a/ui/app/pages/first-time-flow/first-time-flow.component.js +++ b/ui/app/pages/first-time-flow/first-time-flow.component.js @@ -29,7 +29,7 @@ export default class FirstTimeFlow extends PureComponent { isInitialized: PropTypes.bool, isUnlocked: PropTypes.bool, unlockAccount: PropTypes.func, - nextRoute: PropTypes.func, + nextRoute: PropTypes.string, } state = { diff --git a/ui/app/pages/keychains/restore-vault.js b/ui/app/pages/keychains/restore-vault.js index 574949258..08164fd9f 100644 --- a/ui/app/pages/keychains/restore-vault.js +++ b/ui/app/pages/keychains/restore-vault.js @@ -123,6 +123,7 @@ class RestoreVaultPage extends Component { className="import-account__back-button" onClick={e => { e.preventDefault() + this.props.leaveImportSeedScreenState() this.props.history.goBack() }} href="#" diff --git a/ui/app/selectors/confirm-transaction.js b/ui/app/selectors/confirm-transaction.js index 9b5eda82f..82df4e776 100644 --- a/ui/app/selectors/confirm-transaction.js +++ b/ui/app/selectors/confirm-transaction.js @@ -1,7 +1,17 @@ import { createSelector } from 'reselect' import txHelper from '../../lib/tx-helper' import { calcTokenAmount } from '../helpers/utils/token-util' -import { roundExponential } from '../helpers/utils/confirm-tx.util' +import { + roundExponential, + getValueFromWeiHex, + getHexGasTotal, + getTransactionFee, + addFiat, + addEth, +} from '../helpers/utils/confirm-tx.util' +import { + sumHexes, +} from '../helpers/utils/transactions.util' const unapprovedTxsSelector = state => state.metamask.unapprovedTxs const unapprovedMsgsSelector = state => state.metamask.unapprovedMsgs @@ -207,3 +217,51 @@ export const contractExchangeRateSelector = createSelector( tokenAddressSelector, (contractExchangeRates, tokenAddress) => contractExchangeRates[tokenAddress] ) + +export const transactionFeeSelector = function (state, txData) { + const currentCurrency = currentCurrencySelector(state) + const conversionRate = conversionRateSelector(state) + const nativeCurrency = getNativeCurrency(state) + + const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData + + const fiatTransactionAmount = getValueFromWeiHex({ + value, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, + }) + const ethTransactionAmount = getValueFromWeiHex({ + value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6, + }) + + const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice }) + + const fiatTransactionFee = getTransactionFee({ + value: hexTransactionFee, + fromCurrency: nativeCurrency, + toCurrency: currentCurrency, + numberOfDecimals: 2, + conversionRate, + }) + const ethTransactionFee = getTransactionFee({ + value: hexTransactionFee, + fromCurrency: nativeCurrency, + toCurrency: nativeCurrency, + numberOfDecimals: 6, + conversionRate, + }) + + const fiatTransactionTotal = addFiat(fiatTransactionFee, fiatTransactionAmount) + const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount) + const hexTransactionTotal = sumHexes(value, hexTransactionFee) + + return { + hexTransactionAmount: value, + fiatTransactionAmount, + ethTransactionAmount, + hexTransactionFee, + fiatTransactionFee, + ethTransactionFee, + fiatTransactionTotal, + ethTransactionTotal, + hexTransactionTotal, + } +} diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index d3cc7efca..3ed82044d 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -2391,10 +2391,6 @@ function reshowQrCode (data, coin) { dispatch(actions.hideLoadingIndication()) return dispatch(actions.showQrView(data, message)) - // return dispatch(actions.showModal({ - // name: 'SHAPESHIFT_DEPOSIT_TX', - // Qr: { data, message }, - // })) }) } } |