aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Miller <danjm.com@gmail.com>2018-09-13 16:47:05 +0800
committerDan Miller <danjm.com@gmail.com>2018-12-04 11:36:04 +0800
commit7de3f22d63748ed5a81e947755db056d4cdef3db (patch)
tree748482505ce65c3de4e71787d27b69d71156b522
parent6ada9b4a3c02014f8d00b1f45a149afbf47f700d (diff)
downloadtangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.tar
tangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.tar.gz
tangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.tar.bz2
tangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.tar.lz
tangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.tar.xz
tangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.tar.zst
tangerine-wallet-browser-7de3f22d63748ed5a81e947755db056d4cdef3db.zip
Connects remained of the gas customization component to redux.
-rw-r--r--ui/app/actions.js42
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js8
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js4
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js2
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js80
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js141
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js97
-rw-r--r--ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js122
-rw-r--r--ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js14
-rw-r--r--ui/app/components/pages/confirm-transaction/confirm-transaction.component.js3
-rw-r--r--ui/app/components/pages/confirm-transaction/confirm-transaction.container.js4
-rw-r--r--ui/app/components/send/send.component.js9
-rw-r--r--ui/app/components/send/send.container.js4
-rw-r--r--ui/app/components/send/send.selectors.js10
-rw-r--r--ui/app/components/send/tests/send-component.test.js46
-rw-r--r--ui/app/components/send/tests/send-container.test.js10
-rw-r--r--ui/app/components/send/tests/send-selectors.test.js2
-rw-r--r--ui/app/ducks/gas.duck.js4
-rw-r--r--ui/app/ducks/tests/gas-duck.test.js4
-rw-r--r--ui/app/helpers/conversions.util.js39
-rw-r--r--ui/app/helpers/formatters.js3
-rw-r--r--ui/app/selectors/custom-gas.js43
22 files changed, 497 insertions, 194 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index e3cf57c9e..b747a97fb 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -3,7 +3,6 @@ const pify = require('pify')
const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url')
const { getTokenAddressFromTokenObject } = require('./util')
const {
- calcGasTotal,
calcTokenBalance,
estimateGas,
} = require('./components/send/send.utils')
@@ -12,6 +11,7 @@ const { fetchLocale } = require('../i18n-helper')
const log = require('loglevel')
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../app/scripts/lib/enums')
const { hasUnconfirmedTransactions } = require('./helpers/confirm-transaction/util')
+const gasDuck = require('./ducks/gas.duck')
const WebcamUtils = require('../lib/webcam-utils')
var actions = {
@@ -921,6 +921,7 @@ function setGasTotal (gasTotal) {
}
function updateGasData ({
+ gasPrice,
blockGasLimit,
recentBlocks,
selectedAddress,
@@ -931,34 +932,19 @@ function updateGasData ({
}) {
return (dispatch) => {
dispatch(actions.gasLoadingStarted())
- return new Promise((resolve, reject) => {
- background.getGasPrice((err, data) => {
- if (err) return reject(err)
- return resolve(data)
- })
- })
- .then(estimateGasPrice => {
- return Promise.all([
- Promise.resolve(estimateGasPrice),
- estimateGas({
- estimateGasMethod: background.estimateGas,
- blockGasLimit,
- selectedAddress,
- selectedToken,
- to,
- value,
- estimateGasPrice,
- data,
- }),
- ])
- })
- .then(([gasPrice, gas]) => {
- dispatch(actions.setGasPrice(gasPrice))
+ return estimateGas({
+ estimateGasMethod: background.estimateGas,
+ blockGasLimit,
+ selectedAddress,
+ selectedToken,
+ to,
+ value,
+ estimateGasPrice: gasPrice,
+ data,
+ })
+ .then(gas => {
dispatch(actions.setGasLimit(gas))
- return calcGasTotal(gas, gasPrice)
- })
- .then((gasEstimate) => {
- dispatch(actions.setGasTotal(gasEstimate))
+ dispatch(gasDuck.setCustomGasLimit(gas))
dispatch(updateSendErrors({ gasLoadingError: null }))
dispatch(actions.gasLoadingFinished())
})
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js
index 38fa117f9..56d10cc2b 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js
@@ -1,9 +1,5 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import {
- MIN_GAS_PRICE_DEC,
- MIN_GAS_LIMIT_DEC,
-} from '../../../send/send.constants'
import TimeRemaining from './time-remaining'
export default class AdvancedTabContent extends Component {
@@ -76,8 +72,8 @@ export default class AdvancedTabContent extends Component {
renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) {
return (
<div className="advanced-tab__gas-edit-rows">
- { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) }
- { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) }
+ { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) }
+ { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) }
</div>
)
}
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js
index 5cdcf687e..0ef286b8a 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js
@@ -138,10 +138,10 @@ describe('AdvancedTabContent Component', function () {
const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args
assert.equal(renderGasEditRowSpyArgs.length, 2)
assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [
- 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', '0', 9, true,
+ 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true,
].map(String))
assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [
- 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 21000, '0',
+ 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0,
].map(String))
})
})
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js
index 164da4a32..0e5f15519 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js
@@ -17,9 +17,7 @@ export default class BasicTabContent extends Component {
<div className="basic-tab-content__title">Suggest gas fee increases</div>
<GasPriceButtonGroup
className="gas-price-button-group"
- noButtonActiveByDefault={true}
showCheck={true}
- handleGasPriceSelection={(newPrice) => console.log('New Price:', newPrice)}
{...this.props.gasPriceButtonGroupProps}
/>
</div>
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
index 399520baf..89065472d 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
@@ -17,34 +17,42 @@ export default class GasModalPageContainer extends Component {
customGasPrice: PropTypes.number,
customGasLimit: PropTypes.number,
gasPriceButtonGroupProps: PropTypes.object,
+ infoRowProps: PropTypes.shape({
+ originalTotalFiat: PropTypes.string,
+ originalTotalEth: PropTypes.string,
+ newTotalFiat: PropTypes.string,
+ newTotalEth: PropTypes.string,
+ }),
+ onSubmit: PropTypes.func,
+ customGasPriceInHex: PropTypes.string,
+ customGasLimitInHex: PropTypes.string,
}
state = {}
- renderBasicTabContent () {
+ renderBasicTabContent (gasPriceButtonGroupProps) {
return (
<BasicTabContent
- gasPriceButtonGroupProps={this.props.gasPriceButtonGroupProps}
+ gasPriceButtonGroupProps={gasPriceButtonGroupProps}
/>
)
}
- renderAdvancedTabContent = () => {
- const {
- updateCustomGasPrice,
- updateCustomGasLimit,
- customGasPrice,
- customGasLimit,
- } = this.props
-
+ renderAdvancedTabContent ({
+ convertThenUpdateCustomGasPrice,
+ convertThenUpdateCustomGasLimit,
+ customGasPrice,
+ customGasLimit,
+ newTotalFiat,
+ }) {
return (
<AdvancedTabContent
- updateCustomGasPrice={updateCustomGasPrice}
- updateCustomGasLimit={updateCustomGasLimit}
+ updateCustomGasPrice={convertThenUpdateCustomGasPrice}
+ updateCustomGasLimit={convertThenUpdateCustomGasLimit}
customGasPrice={customGasPrice}
customGasLimit={customGasLimit}
millisecondsRemaining={91000}
- totalFee={'$0.30'}
+ totalFee={newTotalFiat}
/>
)
}
@@ -64,41 +72,67 @@ export default class GasModalPageContainer extends Component {
)
}
- renderTabContent (mainTabContent) {
+ renderInfoRows (originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) {
return (
- <div className="gas-modal-content">
- { mainTabContent }
- { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') }
- { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
+ <div>
+ { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', originalTotalFiat, originalTotalEth) }
+ { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', newTotalFiat, newTotalEth) }
</div>
)
}
- renderTabs () {
+ renderTabs ({
+ originalTotalFiat,
+ originalTotalEth,
+ newTotalFiat,
+ newTotalEth,
+ },
+ {
+ gasPriceButtonGroupProps,
+ ...advancedTabProps
+ }) {
return (
<Tabs>
<Tab name={this.context.t('basic')}>
- { this.renderTabContent(this.renderBasicTabContent()) }
+ <div className="gas-modal-content">
+ { this.renderBasicTabContent(gasPriceButtonGroupProps) }
+ { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
+ </div>
</Tab>
<Tab name={this.context.t('advanced')}>
- { this.renderTabContent(this.renderAdvancedTabContent()) }
+ <div className="gas-modal-content">
+ { this.renderAdvancedTabContent(advancedTabProps) }
+ { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
+ </div>
</Tab>
</Tabs>
)
}
render () {
- const { hideModal } = this.props
+ const {
+ hideModal,
+ infoRowProps,
+ onSubmit,
+ customGasPriceInHex,
+ customGasLimitInHex,
+ ...tabProps
+ } = this.props
return (
<div className="gas-modal-page-container">
<PageContainer
title={this.context.t('customGas')}
subtitle={this.context.t('customGasSubTitle')}
- tabsComponent={this.renderTabs()}
+ tabsComponent={this.renderTabs(infoRowProps, tabProps)}
disabled={false}
onCancel={() => hideModal()}
onClose={() => hideModal()}
+ onSubmit={() => {
+ onSubmit(customGasLimitInHex, customGasPriceInHex)
+ hideModal()
+ }}
+ submitText={this.context.t('save')}
/>
</div>
)
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
index ebdd035ea..7e2a7e144 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
@@ -1,36 +1,161 @@
import { connect } from 'react-redux'
+import { pipe, partialRight } from 'ramda'
import GasModalPageContainer from './gas-modal-page-container.component'
-import { hideModal } from '../../../actions'
+import {
+ hideModal,
+ setGasLimit,
+ setGasPrice,
+} from '../../../actions'
import {
setCustomGasPrice,
setCustomGasLimit,
} from '../../../ducks/gas.duck'
import {
+ updateGasAndCalculate,
+} from '../../../ducks/confirm-transaction.duck'
+import {
+ getCurrentCurrency,
+ conversionRateSelector as getConversionRate,
+ getSelectedToken,
+} from '../../../selectors.js'
+import {
getCustomGasPrice,
getCustomGasLimit,
getRenderableBasicEstimateData,
getBasicGasEstimateLoadingStatus,
+ getAveragePriceEstimateInHexWEI,
+ getDefaultActiveButtonIndex,
} from '../../../selectors/custom-gas'
+import {
+ formatCurrency,
+} from '../../../helpers/confirm-transaction/util'
+import {
+ addHexWEIsToDec,
+ decEthToConvertedCurrency as ethTotalToConvertedCurrency,
+ decGWEIToHexWEI,
+ hexWEIToDecGWEI,
+} from '../../../helpers/conversions.util'
+import {
+ formatETHFee,
+} from '../../../helpers/formatters'
+import {
+ calcGasTotal,
+} from '../../send/send.utils'
+import { addHexPrefix } from 'ethereumjs-util'
const mapStateToProps = state => {
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state)
+ const { gasPrice, gas: gasLimit, value } = getTxParams(state)
+ const gasTotal = calcGasTotal(gasLimit, gasPrice)
+
+ const customGasPriceInHex = getCustomGasPrice(state)
+ const customGasLimitInHex = getCustomGasLimit(state)
+ const customGasTotal = calcGasTotal(customGasLimitInHex || gasLimit, customGasPriceInHex || gasPrice)
+
+ const gasButtonInfo = getRenderableBasicEstimateData(state)
+
+ const currentCurrency = getCurrentCurrency(state)
+ const conversionRate = getConversionRate(state)
+
+ const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate)
+
return {
- customGasPrice: getCustomGasPrice(state),
- customGasLimit: getCustomGasLimit(state),
+ isConfirm: isConfirm(state),
+ customGasPriceInHex,
+ customGasLimitInHex,
+ customGasPrice: calcCustomGasPrice(customGasPriceInHex, gasPrice),
+ customGasLimit: calcCustomGasLimit(customGasLimitInHex, gasLimit),
+ newTotalFiat,
gasPriceButtonGroupProps: {
buttonDataLoading,
- gasButtonInfo: getRenderableBasicEstimateData(state),
+ defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customGasPriceInHex, gasPrice),
+ gasButtonInfo,
+ },
+ infoRowProps: {
+ originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate),
+ originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal),
+ newTotalFiat,
+ newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal),
},
}
}
const mapDispatchToProps = dispatch => {
+ const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice)))
+
return {
hideModal: () => dispatch(hideModal()),
- updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)),
- updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)),
- handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice),
+ updateCustomGasPrice,
+ convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)),
+ convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))),
+ setGasData: (newLimit, newPrice) => {
+ dispatch(setGasLimit(newLimit))
+ dispatch(setGasPrice(newPrice))
+ },
+ updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
+ return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
+ },
}
}
-export default connect(mapStateToProps, mapDispatchToProps)(GasModalPageContainer)
+const mergeProps = (stateProps, dispatchProps, ownProps) => {
+ const { gasPriceButtonGroupProps, isConfirm } = stateProps
+ const {
+ updateCustomGasPrice: dispatchUpdateCustomGasPrice,
+ setGasData: dispatchSetGasData,
+ updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate,
+ ...otherDispatchProps
+ } = dispatchProps
+
+ return {
+ ...stateProps,
+ ...otherDispatchProps,
+ ...ownProps,
+ onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData,
+ gasPriceButtonGroupProps: {
+ ...gasPriceButtonGroupProps,
+ handleGasPriceSelection: dispatchUpdateCustomGasPrice,
+ },
+ }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(GasModalPageContainer)
+
+function isConfirm (state) {
+ return Boolean(Object.keys(state.confirmTransaction.txData).length)
+}
+
+function calcCustomGasPrice (customGasPriceInHex, gasPrice) {
+ return Number(hexWEIToDecGWEI(customGasPriceInHex || gasPrice))
+}
+
+function calcCustomGasLimit (customGasLimitInHex, gasLimit) {
+ return parseInt(customGasLimitInHex || gasLimit, 16)
+}
+
+function getTxParams (state) {
+ const { confirmTransaction: { txData }, metamask: { send } } = state
+
+ return txData.txParams || {
+ from: send.from,
+ gas: send.gasLimit,
+ gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state),
+ to: send.to,
+ value: getSelectedToken(state) ? '0x0' : send.amount,
+ }
+}
+
+function addHexWEIsToRenderableEth (aHexWEI, bHexWEI) {
+ return pipe(
+ addHexWEIsToDec,
+ formatETHFee
+ )(aHexWEI, bHexWEI)
+}
+
+function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conversionRate) {
+ return pipe(
+ addHexWEIsToDec,
+ partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]),
+ partialRight(formatCurrency, [convertedCurrency]),
+ )(aHexWEI, bHexWEI)
+}
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js
index 86286b615..c41adca83 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js
@@ -5,13 +5,12 @@ import sinon from 'sinon'
import GasModalPageContainer from '../gas-modal-page-container.component.js'
import PageContainer from '../../../page-container'
-import BasicTabContent from '../basic-tab-content'
-import AdvancedTabContent from '../advanced-tab-content'
import { Tab } from '../../../tabs'
const propsMethodSpies = {
hideModal: sinon.spy(),
+ onSubmit: sinon.spy(),
}
const mockGasPriceButtonGroupProps = {
@@ -41,18 +40,29 @@ const mockGasPriceButtonGroupProps = {
noButtonActiveByDefault: true,
showCheck: true,
}
+const mockInfoRowProps = {
+ originalTotalFiat: 'mockOriginalTotalFiat',
+ originalTotalEth: 'mockOriginalTotalEth',
+ newTotalFiat: 'mockNewTotalFiat',
+ newTotalEth: 'mockNewTotalEth',
+}
+const GP = GasModalPageContainer.prototype
describe('GasModalPageContainer Component', function () {
let wrapper
beforeEach(() => {
wrapper = shallow(<GasModalPageContainer
hideModal={propsMethodSpies.hideModal}
+ onSubmit={propsMethodSpies.onSubmit}
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'}
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'}
customGasPrice={21}
customGasLimit={54321}
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
+ infoRowProps={mockInfoRowProps}
+ customGasPriceInHex={'mockCustomGasPriceInHex'}
+ customGasLimitInHex={'mockCustomGasLimitInHex'}
/>, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
})
@@ -89,7 +99,7 @@ describe('GasModalPageContainer Component', function () {
})
it('should pass the correct renderTabs property to PageContainer', () => {
- sinon.stub(GasModalPageContainer.prototype, 'renderTabs').returns('mockTabs')
+ sinon.stub(GP, 'renderTabs').returns('mockTabs')
const renderTabsWrapperTester = shallow(<GasModalPageContainer />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props()
assert.equal(tabsComponent, 'mockTabs')
@@ -98,8 +108,23 @@ describe('GasModalPageContainer Component', function () {
})
describe('renderTabs', () => {
+ beforeEach(() => {
+ sinon.spy(GP, 'renderBasicTabContent')
+ sinon.spy(GP, 'renderAdvancedTabContent')
+ sinon.spy(GP, 'renderInfoRows')
+ })
+
+ afterEach(() => {
+ GP.renderBasicTabContent.restore()
+ GP.renderAdvancedTabContent.restore()
+ GP.renderInfoRows.restore()
+ })
+
it('should render a Tabs component with "Basic" and "Advanced" tabs', () => {
- const renderTabsResult = wrapper.instance().renderTabs()
+ const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, {
+ gasPriceButtonGroupProps: mockGasPriceButtonGroupProps,
+ otherProps: 'mockAdvancedTabProps',
+ })
const renderedTabs = shallow(renderTabsResult)
assert.equal(renderedTabs.props().className, 'tabs')
@@ -113,45 +138,28 @@ describe('GasModalPageContainer Component', function () {
assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content')
})
- it('should render the expected children of each tab', () => {
- const GP = GasModalPageContainer.prototype
- sinon.spy(GP, 'renderTabContent')
- assert.equal(GP.renderTabContent.callCount, 0)
+ it('should call renderBasicTabContent and renderAdvancedTabContent with the expected props', () => {
+ assert.equal(GP.renderBasicTabContent.callCount, 0)
+ assert.equal(GP.renderAdvancedTabContent.callCount, 0)
- wrapper.instance().renderTabs()
+ wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' })
- assert.equal(GP.renderTabContent.callCount, 2)
+ assert.equal(GP.renderBasicTabContent.callCount, 1)
+ assert.equal(GP.renderAdvancedTabContent.callCount, 1)
- assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type)
- assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type)
-
- GP.renderTabContent.restore()
+ assert.deepEqual(GP.renderBasicTabContent.getCall(0).args[0], mockGasPriceButtonGroupProps)
+ assert.deepEqual(GP.renderAdvancedTabContent.getCall(0).args[0], { otherProps: 'mockAdvancedTabProps' })
})
- })
- describe('renderTabContent', () => {
- it('should render a root gas-modal-content div', () => {
- const renderTabContentResult = wrapper.instance().renderTabContent(() => {})
- const renderedTabContent = shallow(renderTabContentResult)
- assert.equal(renderedTabContent.props().className, 'gas-modal-content')
- })
-
- it('should render the passed element as its first child', () => {
- const renderTabContentResult = wrapper.instance().renderTabContent(<span>Mock content</span>)
- const renderedTabContent = shallow(renderTabContentResult)
- assert(renderedTabContent.childAt(0).equals(<span>Mock content</span>))
- })
+ it('should call renderInfoRows with the expected props', () => {
+ assert.equal(GP.renderInfoRows.callCount, 0)
- it('should render the element results of renderInfoRow calls as second and third childs', () => {
- const GP = GasModalPageContainer.prototype
- sinon.stub(GP, 'renderInfoRow').callsFake((...args) => args.join(','))
+ wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' })
- const renderTabContentResult = wrapper.instance().renderTabContent(() => <span>Mock content</span>)
- const renderedTabContent = shallow(renderTabContentResult)
- assert.equal(renderedTabContent.childAt(1).text(), 'gas-modal-content__info-row--fade,originalTotal,$20.02 USD,0.06685 ETH')
- assert.equal(renderedTabContent.childAt(2).text(), 'gas-modal-content__info-row,newTotal,$20.02 USD,0.06685 ETH')
+ assert.equal(GP.renderInfoRows.callCount, 2)
- GP.renderInfoRow.restore()
+ assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth'])
+ assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth'])
})
})
@@ -176,7 +184,7 @@ describe('GasModalPageContainer Component', function () {
describe('renderBasicTabContent', () => {
it('should render', () => {
- const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent()
+ const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps)
assert.deepEqual(
renderBasicTabContentResult.props.gasPriceButtonGroupProps,
@@ -187,15 +195,20 @@ describe('GasModalPageContainer Component', function () {
describe('renderAdvancedTabContent', () => {
it('should render with the correct props', () => {
- const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent()
+ const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent({
+ convertThenUpdateCustomGasPrice: () => 'mockConvertThenUpdateCustomGasPrice',
+ convertThenUpdateCustomGasLimit: () => 'mockConvertThenUpdateCustomGasLimit',
+ customGasPrice: 123,
+ customGasLimit: 456,
+ newTotalFiat: '$0.30',
+ })
const advancedTabContentProps = renderAdvancedTabContentResult.props
- assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockupdateCustomGasPrice')
- assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockupdateCustomGasLimit')
- assert.equal(advancedTabContentProps.customGasPrice, 21)
- assert.equal(advancedTabContentProps.customGasLimit, 54321)
+ assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice')
+ assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit')
+ assert.equal(advancedTabContentProps.customGasPrice, 123)
+ assert.equal(advancedTabContentProps.customGasLimit, 456)
assert.equal(advancedTabContentProps.millisecondsRemaining, 91000)
assert.equal(advancedTabContentProps.totalFee, '$0.30')
- assert(shallow(renderAdvancedTabContentResult).hasClass('advanced-tab'))
})
})
})
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
index 4067265b5..e01fd3898 100644
--- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
+++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
@@ -7,13 +7,19 @@ let mapDispatchToProps
const actionSpies = {
hideModal: sinon.spy(),
+ setGasLimit: sinon.spy(),
+ setGasPrice: sinon.spy(),
}
-const customGasActionSpies = {
+const gasActionSpies = {
setCustomGasPrice: sinon.spy(),
setCustomGasLimit: sinon.spy(),
}
+const confirmTransactionActionSpies = {
+ updateGasAndCalculate: sinon.spy(),
+}
+
proxyquire('../gas-modal-page-container.container.js', {
'react-redux': {
connect: (ms, md) => {
@@ -23,13 +29,13 @@ proxyquire('../gas-modal-page-container.container.js', {
},
},
'../../../selectors/custom-gas': {
- getCustomGasPrice: (s) => `mockGasPrice:${s}`,
- getCustomGasLimit: (s) => `mockGasLimit:${s}`,
- getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`,
- getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${s}`,
+ getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`,
+ getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`,
+ getDefaultActiveButtonIndex: (a, b, c) => a + b + c,
},
'../../../actions': actionSpies,
- '../../../ducks/gas.duck': customGasActionSpies,
+ '../../../ducks/gas.duck': gasActionSpies,
+ '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies,
})
describe('gas-modal-page-container container', () => {
@@ -37,10 +43,54 @@ describe('gas-modal-page-container container', () => {
describe('mapStateToProps()', () => {
it('should map the correct properties to props', () => {
- assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState')
- assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState')
- assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.buttonDataLoading, 'mockBasicGasEstimateLoadingStatus:mockState')
- assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.gasButtonInfo, 'mockRenderableBasicEstimateData:mockState')
+ const mockState2 = {
+ metamask: {
+ send: {
+ gasLimit: '16',
+ gasPrice: '32',
+ amount: '64',
+ },
+ currentCurrency: 'abc',
+ conversionRate: 50,
+ },
+ gas: {
+ customData: {
+ limit: 'aaaaaaaa',
+ price: 'ffffffff',
+ },
+ },
+ confirmTransaction: {
+ txData: {
+ txParams: {
+ gas: '0x1600000',
+ gasPrice: '0x3200000',
+ value: '0x640000000000000',
+ },
+ },
+ },
+ }
+ const result2 = mapStateToProps(mockState2)
+
+ assert.deepEqual(result2, {
+ isConfirm: true,
+ customGasPriceInHex: 'ffffffff',
+ customGasLimitInHex: 'aaaaaaaa',
+ customGasPrice: 4.294967295,
+ customGasLimit: 2863311530,
+ newTotalFiat: '637.41',
+ gasPriceButtonGroupProps:
+ {
+ buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:3',
+ defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:3ffffffff0x3200000',
+ gasButtonInfo: 'mockRenderableBasicEstimateData:3',
+ },
+ infoRowProps: {
+ originalTotalFiat: '22.58',
+ originalTotalEth: '0.451569 ETH',
+ newTotalFiat: '637.41',
+ newTotalEth: '12.748189 ETH',
+ },
+ })
})
})
@@ -54,6 +104,12 @@ describe('gas-modal-page-container container', () => {
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy)
})
+ afterEach(() => {
+ actionSpies.hideModal.resetHistory()
+ gasActionSpies.setCustomGasPrice.resetHistory()
+ gasActionSpies.setCustomGasLimit.resetHistory()
+ })
+
describe('hideModal()', () => {
it('should dispatch a hideModal action', () => {
mapDispatchToPropsObject.hideModal()
@@ -63,18 +119,50 @@ describe('gas-modal-page-container container', () => {
})
describe('updateCustomGasPrice()', () => {
- it('should dispatch a setCustomGasPrice action', () => {
- mapDispatchToPropsObject.updateCustomGasPrice()
+ it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', () => {
+ mapDispatchToPropsObject.updateCustomGasPrice('ffff')
+ assert(dispatchSpy.calledOnce)
+ assert(gasActionSpies.setCustomGasPrice.calledOnce)
+ assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff')
+ })
+ })
+
+ describe('convertThenUpdateCustomGasPrice()', () => {
+ it('should dispatch a setCustomGasPrice action with the arg passed to convertThenUpdateCustomGasPrice converted to WEI', () => {
+ mapDispatchToPropsObject.convertThenUpdateCustomGasPrice('0xffff')
assert(dispatchSpy.calledOnce)
- assert(customGasActionSpies.setCustomGasPrice.calledOnce)
+ assert(gasActionSpies.setCustomGasPrice.calledOnce)
+ assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0x3b9a8e653600')
+ })
+ })
+
+
+ describe('convertThenUpdateCustomGasLimit()', () => {
+ it('should dispatch a setCustomGasLimit action with the arg passed to convertThenUpdateCustomGasLimit converted to hex', () => {
+ mapDispatchToPropsObject.convertThenUpdateCustomGasLimit(16)
+ assert(dispatchSpy.calledOnce)
+ assert(gasActionSpies.setCustomGasLimit.calledOnce)
+ assert.equal(gasActionSpies.setCustomGasLimit.getCall(0).args[0], '0x10')
+ })
+ })
+
+ describe('setGasData()', () => {
+ it('should dispatch a setGasPrice and setGasLimit action with the correct props', () => {
+ mapDispatchToPropsObject.setGasData('ffff', 'aaaa')
+ assert(dispatchSpy.calledTwice)
+ 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')
})
})
- describe('updateCustomGasLimit()', () => {
- it('should dispatch a setCustomGasLimit action', () => {
- mapDispatchToPropsObject.updateCustomGasLimit()
+ describe('updateConfirmTxGasAndCalculate()', () => {
+ it('should dispatch a updateGasAndCalculate action with the correct props', () => {
+ mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa')
assert(dispatchSpy.calledOnce)
- assert(customGasActionSpies.setCustomGasLimit.calledOnce)
+ assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce)
+ assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' })
})
})
diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
index a3ec82863..1e2270432 100644
--- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
+++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
@@ -29,7 +29,7 @@ const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
const mapStateToProps = (state, props) => {
const { toAddress: propsToAddress } = props
- const { confirmTransaction, metamask } = state
+ const { confirmTransaction, metamask, gas } = state
const {
ethTransactionAmount,
ethTransactionFee,
@@ -60,6 +60,12 @@ const mapStateToProps = (state, props) => {
unapprovedTxs,
} = metamask
const assetImage = assetImages[txParamsToAddress]
+
+ const {
+ customGasLimit,
+ customGasPrice,
+ } = gas
+
const { balance } = accounts[selectedAddress]
const { name: fromName } = identities[selectedAddress]
const toAddress = propsToAddress || txParamsToAddress
@@ -106,6 +112,10 @@ const mapStateToProps = (state, props) => {
unapprovedTxs,
unapprovedTxCount,
currentNetworkUnapprovedTxs,
+ customGas: {
+ gasLimit: customGasLimit || txData.gasPrice,
+ gasPrice: customGasPrice || txData.gasLimit,
+ },
}
}
@@ -192,7 +202,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
...ownProps,
showCustomizeGasModal: () => dispatchShowCustomizeGasModal({
txData,
- onSubmit: txData => dispatchUpdateGasAndCalculate(txData),
+ onSubmit: customGas => dispatchUpdateGasAndCalculate(customGas),
validate: validateEditGas,
}),
cancelAllTransactions: () => dispatchCancelAllTransactions(valuesFor(unapprovedTxs)),
diff --git a/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js b/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js
index 3ac656d73..614b3e584 100644
--- a/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js
+++ b/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js
@@ -32,6 +32,7 @@ export default class ConfirmTransaction extends Component {
setTransactionToConfirm: PropTypes.func,
confirmTransaction: PropTypes.object,
clearConfirmTransaction: PropTypes.func,
+ fetchGasEstimates: PropTypes.func,
}
getParamsTransactionId () {
@@ -45,6 +46,7 @@ export default class ConfirmTransaction extends Component {
send = {},
history,
confirmTransaction: { txData: { id: transactionId } = {} },
+ fetchGasEstimates,
} = this.props
if (!totalUnapprovedCount && !send.to) {
@@ -53,6 +55,7 @@ export default class ConfirmTransaction extends Component {
}
if (!transactionId) {
+ fetchGasEstimates()
this.setTransactionToConfirm()
}
}
diff --git a/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js
index 1bc2f1efb..cb1a737f9 100644
--- a/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js
+++ b/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js
@@ -5,6 +5,9 @@ import {
setTransactionToConfirm,
clearConfirmTransaction,
} from '../../../ducks/confirm-transaction.duck'
+import {
+ fetchGasEstimates,
+} from '../../../ducks/gas.duck'
import ConfirmTransaction from './confirm-transaction.component'
import { getTotalUnapprovedCount } from '../../../selectors'
import { unconfirmedTransactionsListSelector } from '../../../selectors/confirm-transaction'
@@ -24,6 +27,7 @@ const mapDispatchToProps = dispatch => {
return {
setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)),
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
+ fetchGasEstimates: () => dispatch(fetchGasEstimates()),
}
}
diff --git a/ui/app/components/send/send.component.js b/ui/app/components/send/send.component.js
index a639c24b0..5c12826ea 100644
--- a/ui/app/components/send/send.component.js
+++ b/ui/app/components/send/send.component.js
@@ -73,10 +73,10 @@ export default class SendTransactionScreen extends PersistentForm {
selectedAddress,
selectedToken = {},
to: currentToAddress,
- updateAndSetGasTotal,
+ updateAndSetGasLimit,
} = this.props
- updateAndSetGasTotal({
+ updateAndSetGasLimit({
blockGasLimit,
editingTransactionId,
gasLimit,
@@ -164,6 +164,9 @@ export default class SendTransactionScreen extends PersistentForm {
componentDidMount () {
this.props.fetchGasEstimates()
+ .then(() => {
+ this.updateGas()
+ })
}
componentWillMount () {
@@ -173,12 +176,12 @@ export default class SendTransactionScreen extends PersistentForm {
tokenContract,
updateSendTokenBalance,
} = this.props
+
updateSendTokenBalance({
selectedToken,
tokenContract,
address,
})
- this.updateGas()
// Show QR Scanner modal if ?scan=true
if (window.location.search === '?scan=true') {
diff --git a/ui/app/components/send/send.container.js b/ui/app/components/send/send.container.js
index a00fb3545..f240774d4 100644
--- a/ui/app/components/send/send.container.js
+++ b/ui/app/components/send/send.container.js
@@ -79,7 +79,7 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- updateAndSetGasTotal: ({
+ updateAndSetGasLimit: ({
blockGasLimit,
editingTransactionId,
gasLimit,
@@ -92,7 +92,7 @@ function mapDispatchToProps (dispatch) {
data,
}) => {
!editingTransactionId
- ? dispatch(updateGasData({ recentBlocks, selectedAddress, selectedToken, blockGasLimit, to, value, data }))
+ ? dispatch(updateGasData({ gasPrice, recentBlocks, selectedAddress, selectedToken, blockGasLimit, to, value, data }))
: dispatch(setGasTotal(calcGasTotal(gasLimit, gasPrice)))
},
updateSendTokenBalance: ({ selectedToken, tokenContract, address }) => {
diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js
index c217d848e..71eb93d61 100644
--- a/ui/app/components/send/send.selectors.js
+++ b/ui/app/components/send/send.selectors.js
@@ -8,7 +8,11 @@ const {
} = require('../../selectors')
const {
estimateGasPriceFromRecentBlocks,
+ calcGasTotal,
} = require('./send.utils')
+import {
+ getAveragePriceEstimateInHexWEI,
+} from '../../selectors/custom-gas'
const selectors = {
accountsWithSendEtherInfoSelector,
@@ -131,11 +135,11 @@ function getForceGasMin (state) {
}
function getGasLimit (state) {
- return state.metamask.send.gasLimit
+ return state.metamask.send.gasLimit || '0'
}
function getGasPrice (state) {
- return state.metamask.send.gasPrice
+ return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state)
}
function getGasPriceFromRecentBlocks (state) {
@@ -143,7 +147,7 @@ function getGasPriceFromRecentBlocks (state) {
}
function getGasTotal (state) {
- return state.metamask.send.gasTotal
+ return calcGasTotal(getGasLimit(state), getGasPrice(state))
}
function getPrimaryCurrency (state) {
diff --git a/ui/app/components/send/tests/send-component.test.js b/ui/app/components/send/tests/send-component.test.js
index 0f3902c07..82e84de30 100644
--- a/ui/app/components/send/tests/send-component.test.js
+++ b/ui/app/components/send/tests/send-component.test.js
@@ -9,11 +9,11 @@ import SendContent from '../send-content/send-content.component'
import SendFooter from '../send-footer/send-footer.container'
const propsMethodSpies = {
- updateAndSetGasTotal: sinon.spy(),
+ updateAndSetGasLimit: sinon.spy(),
updateSendErrors: sinon.spy(),
updateSendTokenBalance: sinon.spy(),
resetSendState: sinon.spy(),
- fetchGasEstimates: sinon.spy(),
+ fetchGasEstimates: sinon.stub().returns(Promise.resolve()),
}
const utilsMethodStubs = {
getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }),
@@ -52,7 +52,7 @@ describe('Send Component', function () {
showHexData={true}
tokenBalance={'mockTokenBalance'}
tokenContract={'mockTokenContract'}
- updateAndSetGasTotal={propsMethodSpies.updateAndSetGasTotal}
+ updateAndSetGasLimit={propsMethodSpies.updateAndSetGasLimit}
updateSendErrors={propsMethodSpies.updateSendErrors}
updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance}
resetSendState={propsMethodSpies.resetSendState}
@@ -66,7 +66,7 @@ describe('Send Component', function () {
utilsMethodStubs.getAmountErrorObject.resetHistory()
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
propsMethodSpies.fetchGasEstimates.resetHistory()
- propsMethodSpies.updateAndSetGasTotal.resetHistory()
+ propsMethodSpies.updateAndSetGasLimit.resetHistory()
propsMethodSpies.updateSendErrors.resetHistory()
propsMethodSpies.updateSendTokenBalance.resetHistory()
})
@@ -75,16 +75,6 @@ describe('Send Component', function () {
assert(SendTransactionScreen.prototype.componentDidMount.calledOnce)
})
- describe('componentWillMount', () => {
- it('should call this.updateGas', () => {
- SendTransactionScreen.prototype.updateGas.resetHistory()
- propsMethodSpies.updateSendErrors.resetHistory()
- assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
- wrapper.instance().componentWillMount()
- assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1)
- })
- })
-
describe('componentDidMount', () => {
it('should call props.fetchGasEstimates', () => {
propsMethodSpies.fetchGasEstimates.resetHistory()
@@ -92,6 +82,14 @@ describe('Send Component', function () {
wrapper.instance().componentDidMount()
assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1)
})
+
+ it('should call this.updateGas', () => {
+ SendTransactionScreen.prototype.updateGas.resetHistory()
+ propsMethodSpies.updateSendErrors.resetHistory()
+ assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
+ wrapper.instance().componentDidMount()
+ setTimeout(() => assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1), 250)
+ })
})
describe('componentWillUnmount', () => {
@@ -283,12 +281,12 @@ describe('Send Component', function () {
})
describe('updateGas', () => {
- it('should call updateAndSetGasTotal with the correct params if no to prop is passed', () => {
- propsMethodSpies.updateAndSetGasTotal.resetHistory()
+ it('should call updateAndSetGasLimit with the correct params if no to prop is passed', () => {
+ propsMethodSpies.updateAndSetGasLimit.resetHistory()
wrapper.instance().updateGas()
- assert.equal(propsMethodSpies.updateAndSetGasTotal.callCount, 1)
+ assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1)
assert.deepEqual(
- propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0],
+ propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0],
{
blockGasLimit: 'mockBlockGasLimit',
editingTransactionId: 'mockEditingTransactionId',
@@ -304,20 +302,20 @@ describe('Send Component', function () {
)
})
- it('should call updateAndSetGasTotal with the correct params if a to prop is passed', () => {
- propsMethodSpies.updateAndSetGasTotal.resetHistory()
+ it('should call updateAndSetGasLimit with the correct params if a to prop is passed', () => {
+ propsMethodSpies.updateAndSetGasLimit.resetHistory()
wrapper.setProps({ to: 'someAddress' })
wrapper.instance().updateGas()
assert.equal(
- propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0].to,
+ propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to,
'someaddress',
)
})
- it('should call updateAndSetGasTotal with to set to lowercase if passed', () => {
- propsMethodSpies.updateAndSetGasTotal.resetHistory()
+ it('should call updateAndSetGasLimit with to set to lowercase if passed', () => {
+ propsMethodSpies.updateAndSetGasLimit.resetHistory()
wrapper.instance().updateGas({ to: '0xABC' })
- assert.equal(propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0].to, '0xabc')
+ assert.equal(propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, '0xabc')
})
})
diff --git a/ui/app/components/send/tests/send-container.test.js b/ui/app/components/send/tests/send-container.test.js
index 6aa4bf826..d8fe85d22 100644
--- a/ui/app/components/send/tests/send-container.test.js
+++ b/ui/app/components/send/tests/send-container.test.js
@@ -94,7 +94,7 @@ describe('send container', () => {
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy)
})
- describe('updateAndSetGasTotal()', () => {
+ describe('updateAndSetGasLimit()', () => {
const mockProps = {
blockGasLimit: 'mockBlockGasLimit',
editingTransactionId: '0x2',
@@ -109,7 +109,7 @@ describe('send container', () => {
}
it('should dispatch a setGasTotal action when editingTransactionId is truthy', () => {
- mapDispatchToPropsObject.updateAndSetGasTotal(mockProps)
+ mapDispatchToPropsObject.updateAndSetGasLimit(mockProps)
assert(dispatchSpy.calledOnce)
assert.equal(
actionSpies.setGasTotal.getCall(0).args[0],
@@ -118,14 +118,14 @@ describe('send container', () => {
})
it('should dispatch an updateGasData action when editingTransactionId is falsy', () => {
- const { selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } = mockProps
- mapDispatchToPropsObject.updateAndSetGasTotal(
+ const { gasPrice, selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } = mockProps
+ mapDispatchToPropsObject.updateAndSetGasLimit(
Object.assign({}, mockProps, {editingTransactionId: false})
)
assert(dispatchSpy.calledOnce)
assert.deepEqual(
actionSpies.updateGasData.getCall(0).args[0],
- { selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data }
+ { gasPrice, selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, }
)
})
})
diff --git a/ui/app/components/send/tests/send-selectors.test.js b/ui/app/components/send/tests/send-selectors.test.js
index e7e901f0d..cdc86fe59 100644
--- a/ui/app/components/send/tests/send-selectors.test.js
+++ b/ui/app/components/send/tests/send-selectors.test.js
@@ -237,7 +237,7 @@ describe('send selectors', () => {
it('should return the send.gasTotal', () => {
assert.equal(
getGasTotal(mockState),
- '0xb451dc41b578'
+ 'a9ff56'
)
})
})
diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js
index 8b2fbcfdb..7f18b2272 100644
--- a/ui/app/ducks/gas.duck.js
+++ b/ui/app/ducks/gas.duck.js
@@ -13,8 +13,8 @@ const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL'
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
const initState = {
customData: {
- price: 0,
- limit: 21000,
+ price: null,
+ limit: '0x5208',
},
basicEstimates: {
average: null,
diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js
index 7fd74f815..66cf376a7 100644
--- a/ui/app/ducks/tests/gas-duck.test.js
+++ b/ui/app/ducks/tests/gas-duck.test.js
@@ -47,8 +47,8 @@ describe('Gas Duck', () => {
}
const initState = {
customData: {
- price: 0,
- limit: 21000,
+ price: null,
+ limit: '0x5208',
},
basicEstimates: {
average: null,
diff --git a/ui/app/helpers/conversions.util.js b/ui/app/helpers/conversions.util.js
index cb5e1b90b..d8e0d87fe 100644
--- a/ui/app/helpers/conversions.util.js
+++ b/ui/app/helpers/conversions.util.js
@@ -1,6 +1,7 @@
import ethUtil from 'ethereumjs-util'
import { conversionUtil } from '../conversion-util'
import { ETH, GWEI, WEI } from '../constants/common'
+import { conversionUtil, addCurrencies } from '../conversion-util'
export function bnToHex (inputBn) {
return ethUtil.addHexPrefix(inputBn.toString(16))
@@ -82,3 +83,41 @@ export function getWeiHexFromDecimalValue ({
toDenomination: WEI,
})
}
+
+export function addHexWEIsToDec (aHexWEI, bHexWEI) {
+ return addCurrencies(aHexWEI, bHexWEI, {
+ aBase: 16,
+ bBase: 16,
+ fromDenomination: 'WEI',
+ numberOfDecimals: 6,
+ })
+}
+
+export function decEthToConvertedCurrency (ethTotal, convertedCurrency, conversionRate) {
+ return conversionUtil(ethTotal, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: convertedCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+}
+
+export function decGWEIToHexWEI (decGWEI) {
+ return conversionUtil(decGWEI, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ fromDenomination: 'GWEI',
+ toDenomination: 'WEI',
+ })
+}
+
+export function hexWEIToDecGWEI (decGWEI) {
+ return conversionUtil(decGWEI, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ toDenomination: 'GWEI',
+ })
+}
diff --git a/ui/app/helpers/formatters.js b/ui/app/helpers/formatters.js
new file mode 100644
index 000000000..106a2520d
--- /dev/null
+++ b/ui/app/helpers/formatters.js
@@ -0,0 +1,3 @@
+export function formatETHFee (ethFee) {
+ return ethFee + ' ETH'
+}
diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js
index ff2fd0e05..61c0525df 100644
--- a/ui/app/selectors/custom-gas.js
+++ b/ui/app/selectors/custom-gas.js
@@ -1,9 +1,5 @@
import { pipe, partialRight } from 'ramda'
import {
- getConversionRate,
- getGasLimit,
-} from '../components/send/send.selectors'
-import {
conversionUtil,
multiplyCurrencies,
} from '../conversion-util'
@@ -14,6 +10,12 @@ import {
formatCurrency,
} from '../helpers/confirm-transaction/util'
import {
+ decEthToConvertedCurrency as ethTotalToConvertedCurrency,
+} from '../helpers/conversions.util'
+import {
+ formatETHFee,
+} from '../helpers/formatters'
+import {
calcGasTotal,
} from '../components/send/send.utils'
import { addHexPrefix } from 'ethereumjs-util'
@@ -25,6 +27,9 @@ const selectors = {
getCustomGasTotal,
getRenderableBasicEstimateData,
getBasicGasEstimateLoadingStatus,
+ getAveragePriceEstimateInHexWEI,
+ getDefaultActiveButtonIndex,
+ priceEstimateToWei,
}
module.exports = selectors
@@ -49,6 +54,16 @@ function getBasicGasEstimateLoadingStatus (state) {
return state.gas.basicEstimateIsLoading
}
+function getAveragePriceEstimateInHexWEI (state) {
+ const averagePriceEstimate = state.gas.basicEstimates.average
+ return getGasPriceInHexWei(averagePriceEstimate || '0x0')
+}
+
+function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) {
+ return gasButtonInfo.findIndex(({ priceInHexWei }) => {
+ return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice)
+ })
+}
function apiEstimateModifiedToGWEI (estimate) {
return multiplyCurrencies(estimate, 0.10, {
@@ -68,21 +83,6 @@ function basicPriceEstimateToETHTotal (estimate, gasLimit) {
})
}
-function ethTotalToConvertedCurrency (ethTotal, convertedCurrency, conversionRate) {
- return conversionUtil(ethTotal, {
- fromNumericBase: 'dec',
- toNumericBase: 'dec',
- fromCurrency: 'ETH',
- toCurrency: convertedCurrency,
- numberOfDecimals: 2,
- conversionRate,
- })
-}
-
-function formatETHFee (ethFee) {
- return ethFee + ' ETH'
-}
-
function getRenderableEthFee (estimate, gasLimit) {
return pipe(
apiEstimateModifiedToGWEI,
@@ -150,9 +150,8 @@ function getRenderableBasicEstimateData (state) {
if (getBasicGasEstimateLoadingStatus(state)) {
return []
}
-
- const gasLimit = getGasLimit(state)
- const conversionRate = getConversionRate(state)
+ const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state)
+ const conversionRate = state.metamask.conversionRate
const currentCurrency = getCurrentCurrency(state)
const {
gas: {