mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Connects remained of the gas customization component to redux.
This commit is contained in:
parent
6ada9b4a3c
commit
7de3f22d63
@ -3,7 +3,6 @@ const pify = require('pify')
|
|||||||
const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url')
|
const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url')
|
||||||
const { getTokenAddressFromTokenObject } = require('./util')
|
const { getTokenAddressFromTokenObject } = require('./util')
|
||||||
const {
|
const {
|
||||||
calcGasTotal,
|
|
||||||
calcTokenBalance,
|
calcTokenBalance,
|
||||||
estimateGas,
|
estimateGas,
|
||||||
} = require('./components/send/send.utils')
|
} = require('./components/send/send.utils')
|
||||||
@ -12,6 +11,7 @@ const { fetchLocale } = require('../i18n-helper')
|
|||||||
const log = require('loglevel')
|
const log = require('loglevel')
|
||||||
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../app/scripts/lib/enums')
|
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../app/scripts/lib/enums')
|
||||||
const { hasUnconfirmedTransactions } = require('./helpers/confirm-transaction/util')
|
const { hasUnconfirmedTransactions } = require('./helpers/confirm-transaction/util')
|
||||||
|
const gasDuck = require('./ducks/gas.duck')
|
||||||
const WebcamUtils = require('../lib/webcam-utils')
|
const WebcamUtils = require('../lib/webcam-utils')
|
||||||
|
|
||||||
var actions = {
|
var actions = {
|
||||||
@ -921,6 +921,7 @@ function setGasTotal (gasTotal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateGasData ({
|
function updateGasData ({
|
||||||
|
gasPrice,
|
||||||
blockGasLimit,
|
blockGasLimit,
|
||||||
recentBlocks,
|
recentBlocks,
|
||||||
selectedAddress,
|
selectedAddress,
|
||||||
@ -931,34 +932,19 @@ function updateGasData ({
|
|||||||
}) {
|
}) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch(actions.gasLoadingStarted())
|
dispatch(actions.gasLoadingStarted())
|
||||||
return new Promise((resolve, reject) => {
|
return estimateGas({
|
||||||
background.getGasPrice((err, data) => {
|
|
||||||
if (err) return reject(err)
|
|
||||||
return resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(estimateGasPrice => {
|
|
||||||
return Promise.all([
|
|
||||||
Promise.resolve(estimateGasPrice),
|
|
||||||
estimateGas({
|
|
||||||
estimateGasMethod: background.estimateGas,
|
estimateGasMethod: background.estimateGas,
|
||||||
blockGasLimit,
|
blockGasLimit,
|
||||||
selectedAddress,
|
selectedAddress,
|
||||||
selectedToken,
|
selectedToken,
|
||||||
to,
|
to,
|
||||||
value,
|
value,
|
||||||
estimateGasPrice,
|
estimateGasPrice: gasPrice,
|
||||||
data,
|
data,
|
||||||
}),
|
|
||||||
])
|
|
||||||
})
|
})
|
||||||
.then(([gasPrice, gas]) => {
|
.then(gas => {
|
||||||
dispatch(actions.setGasPrice(gasPrice))
|
|
||||||
dispatch(actions.setGasLimit(gas))
|
dispatch(actions.setGasLimit(gas))
|
||||||
return calcGasTotal(gas, gasPrice)
|
dispatch(gasDuck.setCustomGasLimit(gas))
|
||||||
})
|
|
||||||
.then((gasEstimate) => {
|
|
||||||
dispatch(actions.setGasTotal(gasEstimate))
|
|
||||||
dispatch(updateSendErrors({ gasLoadingError: null }))
|
dispatch(updateSendErrors({ gasLoadingError: null }))
|
||||||
dispatch(actions.gasLoadingFinished())
|
dispatch(actions.gasLoadingFinished())
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {
|
|
||||||
MIN_GAS_PRICE_DEC,
|
|
||||||
MIN_GAS_LIMIT_DEC,
|
|
||||||
} from '../../../send/send.constants'
|
|
||||||
import TimeRemaining from './time-remaining'
|
import TimeRemaining from './time-remaining'
|
||||||
|
|
||||||
export default class AdvancedTabContent extends Component {
|
export default class AdvancedTabContent extends Component {
|
||||||
@ -76,8 +72,8 @@ export default class AdvancedTabContent extends Component {
|
|||||||
renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) {
|
renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) {
|
||||||
return (
|
return (
|
||||||
<div className="advanced-tab__gas-edit-rows">
|
<div className="advanced-tab__gas-edit-rows">
|
||||||
{ this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) }
|
{ this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) }
|
||||||
{ this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) }
|
{ this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) }
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -138,10 +138,10 @@ describe('AdvancedTabContent Component', function () {
|
|||||||
const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args
|
const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args
|
||||||
assert.equal(renderGasEditRowSpyArgs.length, 2)
|
assert.equal(renderGasEditRowSpyArgs.length, 2)
|
||||||
assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [
|
assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [
|
||||||
'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', '0', 9, true,
|
'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true,
|
||||||
].map(String))
|
].map(String))
|
||||||
assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [
|
assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [
|
||||||
'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 21000, '0',
|
'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0,
|
||||||
].map(String))
|
].map(String))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -17,9 +17,7 @@ export default class BasicTabContent extends Component {
|
|||||||
<div className="basic-tab-content__title">Suggest gas fee increases</div>
|
<div className="basic-tab-content__title">Suggest gas fee increases</div>
|
||||||
<GasPriceButtonGroup
|
<GasPriceButtonGroup
|
||||||
className="gas-price-button-group"
|
className="gas-price-button-group"
|
||||||
noButtonActiveByDefault={true}
|
|
||||||
showCheck={true}
|
showCheck={true}
|
||||||
handleGasPriceSelection={(newPrice) => console.log('New Price:', newPrice)}
|
|
||||||
{...this.props.gasPriceButtonGroupProps}
|
{...this.props.gasPriceButtonGroupProps}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,34 +17,42 @@ export default class GasModalPageContainer extends Component {
|
|||||||
customGasPrice: PropTypes.number,
|
customGasPrice: PropTypes.number,
|
||||||
customGasLimit: PropTypes.number,
|
customGasLimit: PropTypes.number,
|
||||||
gasPriceButtonGroupProps: PropTypes.object,
|
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 = {}
|
state = {}
|
||||||
|
|
||||||
renderBasicTabContent () {
|
renderBasicTabContent (gasPriceButtonGroupProps) {
|
||||||
return (
|
return (
|
||||||
<BasicTabContent
|
<BasicTabContent
|
||||||
gasPriceButtonGroupProps={this.props.gasPriceButtonGroupProps}
|
gasPriceButtonGroupProps={gasPriceButtonGroupProps}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderAdvancedTabContent = () => {
|
renderAdvancedTabContent ({
|
||||||
const {
|
convertThenUpdateCustomGasPrice,
|
||||||
updateCustomGasPrice,
|
convertThenUpdateCustomGasLimit,
|
||||||
updateCustomGasLimit,
|
|
||||||
customGasPrice,
|
customGasPrice,
|
||||||
customGasLimit,
|
customGasLimit,
|
||||||
} = this.props
|
newTotalFiat,
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<AdvancedTabContent
|
<AdvancedTabContent
|
||||||
updateCustomGasPrice={updateCustomGasPrice}
|
updateCustomGasPrice={convertThenUpdateCustomGasPrice}
|
||||||
updateCustomGasLimit={updateCustomGasLimit}
|
updateCustomGasLimit={convertThenUpdateCustomGasLimit}
|
||||||
customGasPrice={customGasPrice}
|
customGasPrice={customGasPrice}
|
||||||
customGasLimit={customGasLimit}
|
customGasLimit={customGasLimit}
|
||||||
millisecondsRemaining={91000}
|
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 (
|
return (
|
||||||
<div className="gas-modal-content">
|
<div>
|
||||||
{ mainTabContent }
|
{ this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', originalTotalFiat, originalTotalEth) }
|
||||||
{ this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') }
|
{ this.renderInfoRow('gas-modal-content__info-row', 'newTotal', newTotalFiat, newTotalEth) }
|
||||||
{ this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTabs () {
|
renderTabs ({
|
||||||
|
originalTotalFiat,
|
||||||
|
originalTotalEth,
|
||||||
|
newTotalFiat,
|
||||||
|
newTotalEth,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
gasPriceButtonGroupProps,
|
||||||
|
...advancedTabProps
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab name={this.context.t('basic')}>
|
<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>
|
||||||
<Tab name={this.context.t('advanced')}>
|
<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>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { hideModal } = this.props
|
const {
|
||||||
|
hideModal,
|
||||||
|
infoRowProps,
|
||||||
|
onSubmit,
|
||||||
|
customGasPriceInHex,
|
||||||
|
customGasLimitInHex,
|
||||||
|
...tabProps
|
||||||
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gas-modal-page-container">
|
<div className="gas-modal-page-container">
|
||||||
<PageContainer
|
<PageContainer
|
||||||
title={this.context.t('customGas')}
|
title={this.context.t('customGas')}
|
||||||
subtitle={this.context.t('customGasSubTitle')}
|
subtitle={this.context.t('customGasSubTitle')}
|
||||||
tabsComponent={this.renderTabs()}
|
tabsComponent={this.renderTabs(infoRowProps, tabProps)}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
onCancel={() => hideModal()}
|
onCancel={() => hideModal()}
|
||||||
onClose={() => hideModal()}
|
onClose={() => hideModal()}
|
||||||
|
onSubmit={() => {
|
||||||
|
onSubmit(customGasLimitInHex, customGasPriceInHex)
|
||||||
|
hideModal()
|
||||||
|
}}
|
||||||
|
submitText={this.context.t('save')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,36 +1,161 @@
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
import { pipe, partialRight } from 'ramda'
|
||||||
import GasModalPageContainer from './gas-modal-page-container.component'
|
import GasModalPageContainer from './gas-modal-page-container.component'
|
||||||
import { hideModal } from '../../../actions'
|
import {
|
||||||
|
hideModal,
|
||||||
|
setGasLimit,
|
||||||
|
setGasPrice,
|
||||||
|
} from '../../../actions'
|
||||||
import {
|
import {
|
||||||
setCustomGasPrice,
|
setCustomGasPrice,
|
||||||
setCustomGasLimit,
|
setCustomGasLimit,
|
||||||
} from '../../../ducks/gas.duck'
|
} from '../../../ducks/gas.duck'
|
||||||
|
import {
|
||||||
|
updateGasAndCalculate,
|
||||||
|
} from '../../../ducks/confirm-transaction.duck'
|
||||||
|
import {
|
||||||
|
getCurrentCurrency,
|
||||||
|
conversionRateSelector as getConversionRate,
|
||||||
|
getSelectedToken,
|
||||||
|
} from '../../../selectors.js'
|
||||||
import {
|
import {
|
||||||
getCustomGasPrice,
|
getCustomGasPrice,
|
||||||
getCustomGasLimit,
|
getCustomGasLimit,
|
||||||
getRenderableBasicEstimateData,
|
getRenderableBasicEstimateData,
|
||||||
getBasicGasEstimateLoadingStatus,
|
getBasicGasEstimateLoadingStatus,
|
||||||
|
getAveragePriceEstimateInHexWEI,
|
||||||
|
getDefaultActiveButtonIndex,
|
||||||
} from '../../../selectors/custom-gas'
|
} 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 mapStateToProps = state => {
|
||||||
const buttonDataLoading = getBasicGasEstimateLoadingStatus(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 {
|
return {
|
||||||
customGasPrice: getCustomGasPrice(state),
|
isConfirm: isConfirm(state),
|
||||||
customGasLimit: getCustomGasLimit(state),
|
customGasPriceInHex,
|
||||||
|
customGasLimitInHex,
|
||||||
|
customGasPrice: calcCustomGasPrice(customGasPriceInHex, gasPrice),
|
||||||
|
customGasLimit: calcCustomGasLimit(customGasLimitInHex, gasLimit),
|
||||||
|
newTotalFiat,
|
||||||
gasPriceButtonGroupProps: {
|
gasPriceButtonGroupProps: {
|
||||||
buttonDataLoading,
|
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 mapDispatchToProps = dispatch => {
|
||||||
|
const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice)))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hideModal: () => dispatch(hideModal()),
|
hideModal: () => dispatch(hideModal()),
|
||||||
updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)),
|
updateCustomGasPrice,
|
||||||
updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)),
|
convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)),
|
||||||
handleGasPriceSelection: newPrice => console.log('NewPrice: ', 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)
|
||||||
|
}
|
||||||
|
@ -5,13 +5,12 @@ import sinon from 'sinon'
|
|||||||
import GasModalPageContainer from '../gas-modal-page-container.component.js'
|
import GasModalPageContainer from '../gas-modal-page-container.component.js'
|
||||||
|
|
||||||
import PageContainer from '../../../page-container'
|
import PageContainer from '../../../page-container'
|
||||||
import BasicTabContent from '../basic-tab-content'
|
|
||||||
import AdvancedTabContent from '../advanced-tab-content'
|
|
||||||
|
|
||||||
import { Tab } from '../../../tabs'
|
import { Tab } from '../../../tabs'
|
||||||
|
|
||||||
const propsMethodSpies = {
|
const propsMethodSpies = {
|
||||||
hideModal: sinon.spy(),
|
hideModal: sinon.spy(),
|
||||||
|
onSubmit: sinon.spy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const mockGasPriceButtonGroupProps = {
|
const mockGasPriceButtonGroupProps = {
|
||||||
@ -41,18 +40,29 @@ const mockGasPriceButtonGroupProps = {
|
|||||||
noButtonActiveByDefault: true,
|
noButtonActiveByDefault: true,
|
||||||
showCheck: true,
|
showCheck: true,
|
||||||
}
|
}
|
||||||
|
const mockInfoRowProps = {
|
||||||
|
originalTotalFiat: 'mockOriginalTotalFiat',
|
||||||
|
originalTotalEth: 'mockOriginalTotalEth',
|
||||||
|
newTotalFiat: 'mockNewTotalFiat',
|
||||||
|
newTotalEth: 'mockNewTotalEth',
|
||||||
|
}
|
||||||
|
|
||||||
|
const GP = GasModalPageContainer.prototype
|
||||||
describe('GasModalPageContainer Component', function () {
|
describe('GasModalPageContainer Component', function () {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(<GasModalPageContainer
|
wrapper = shallow(<GasModalPageContainer
|
||||||
hideModal={propsMethodSpies.hideModal}
|
hideModal={propsMethodSpies.hideModal}
|
||||||
|
onSubmit={propsMethodSpies.onSubmit}
|
||||||
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'}
|
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'}
|
||||||
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'}
|
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'}
|
||||||
customGasPrice={21}
|
customGasPrice={21}
|
||||||
customGasLimit={54321}
|
customGasLimit={54321}
|
||||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
|
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
|
||||||
|
infoRowProps={mockInfoRowProps}
|
||||||
|
customGasPriceInHex={'mockCustomGasPriceInHex'}
|
||||||
|
customGasLimitInHex={'mockCustomGasLimitInHex'}
|
||||||
/>, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
|
/>, { 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', () => {
|
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 renderTabsWrapperTester = shallow(<GasModalPageContainer />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
|
||||||
const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props()
|
const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props()
|
||||||
assert.equal(tabsComponent, 'mockTabs')
|
assert.equal(tabsComponent, 'mockTabs')
|
||||||
@ -98,8 +108,23 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('renderTabs', () => {
|
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', () => {
|
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)
|
const renderedTabs = shallow(renderTabsResult)
|
||||||
assert.equal(renderedTabs.props().className, 'tabs')
|
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')
|
assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render the expected children of each tab', () => {
|
it('should call renderBasicTabContent and renderAdvancedTabContent with the expected props', () => {
|
||||||
const GP = GasModalPageContainer.prototype
|
assert.equal(GP.renderBasicTabContent.callCount, 0)
|
||||||
sinon.spy(GP, 'renderTabContent')
|
assert.equal(GP.renderAdvancedTabContent.callCount, 0)
|
||||||
assert.equal(GP.renderTabContent.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.deepEqual(GP.renderBasicTabContent.getCall(0).args[0], mockGasPriceButtonGroupProps)
|
||||||
assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type)
|
assert.deepEqual(GP.renderAdvancedTabContent.getCall(0).args[0], { otherProps: 'mockAdvancedTabProps' })
|
||||||
|
|
||||||
GP.renderTabContent.restore()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('renderTabContent', () => {
|
it('should call renderInfoRows with the expected props', () => {
|
||||||
it('should render a root gas-modal-content div', () => {
|
assert.equal(GP.renderInfoRows.callCount, 0)
|
||||||
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', () => {
|
wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' })
|
||||||
const renderTabContentResult = wrapper.instance().renderTabContent(<span>Mock content</span>)
|
|
||||||
const renderedTabContent = shallow(renderTabContentResult)
|
|
||||||
assert(renderedTabContent.childAt(0).equals(<span>Mock content</span>))
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render the element results of renderInfoRow calls as second and third childs', () => {
|
assert.equal(GP.renderInfoRows.callCount, 2)
|
||||||
const GP = GasModalPageContainer.prototype
|
|
||||||
sinon.stub(GP, 'renderInfoRow').callsFake((...args) => args.join(','))
|
|
||||||
|
|
||||||
const renderTabContentResult = wrapper.instance().renderTabContent(() => <span>Mock content</span>)
|
assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth'])
|
||||||
const renderedTabContent = shallow(renderTabContentResult)
|
assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth'])
|
||||||
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')
|
|
||||||
|
|
||||||
GP.renderInfoRow.restore()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -176,7 +184,7 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
|
|
||||||
describe('renderBasicTabContent', () => {
|
describe('renderBasicTabContent', () => {
|
||||||
it('should render', () => {
|
it('should render', () => {
|
||||||
const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent()
|
const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps)
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
renderBasicTabContentResult.props.gasPriceButtonGroupProps,
|
renderBasicTabContentResult.props.gasPriceButtonGroupProps,
|
||||||
@ -187,15 +195,20 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
|
|
||||||
describe('renderAdvancedTabContent', () => {
|
describe('renderAdvancedTabContent', () => {
|
||||||
it('should render with the correct props', () => {
|
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
|
const advancedTabContentProps = renderAdvancedTabContentResult.props
|
||||||
assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockupdateCustomGasPrice')
|
assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice')
|
||||||
assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockupdateCustomGasLimit')
|
assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit')
|
||||||
assert.equal(advancedTabContentProps.customGasPrice, 21)
|
assert.equal(advancedTabContentProps.customGasPrice, 123)
|
||||||
assert.equal(advancedTabContentProps.customGasLimit, 54321)
|
assert.equal(advancedTabContentProps.customGasLimit, 456)
|
||||||
assert.equal(advancedTabContentProps.millisecondsRemaining, 91000)
|
assert.equal(advancedTabContentProps.millisecondsRemaining, 91000)
|
||||||
assert.equal(advancedTabContentProps.totalFee, '$0.30')
|
assert.equal(advancedTabContentProps.totalFee, '$0.30')
|
||||||
assert(shallow(renderAdvancedTabContentResult).hasClass('advanced-tab'))
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -7,13 +7,19 @@ let mapDispatchToProps
|
|||||||
|
|
||||||
const actionSpies = {
|
const actionSpies = {
|
||||||
hideModal: sinon.spy(),
|
hideModal: sinon.spy(),
|
||||||
|
setGasLimit: sinon.spy(),
|
||||||
|
setGasPrice: sinon.spy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const customGasActionSpies = {
|
const gasActionSpies = {
|
||||||
setCustomGasPrice: sinon.spy(),
|
setCustomGasPrice: sinon.spy(),
|
||||||
setCustomGasLimit: sinon.spy(),
|
setCustomGasLimit: sinon.spy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const confirmTransactionActionSpies = {
|
||||||
|
updateGasAndCalculate: sinon.spy(),
|
||||||
|
}
|
||||||
|
|
||||||
proxyquire('../gas-modal-page-container.container.js', {
|
proxyquire('../gas-modal-page-container.container.js', {
|
||||||
'react-redux': {
|
'react-redux': {
|
||||||
connect: (ms, md) => {
|
connect: (ms, md) => {
|
||||||
@ -23,13 +29,13 @@ proxyquire('../gas-modal-page-container.container.js', {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
'../../../selectors/custom-gas': {
|
'../../../selectors/custom-gas': {
|
||||||
getCustomGasPrice: (s) => `mockGasPrice:${s}`,
|
getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`,
|
||||||
getCustomGasLimit: (s) => `mockGasLimit:${s}`,
|
getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`,
|
||||||
getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`,
|
getDefaultActiveButtonIndex: (a, b, c) => a + b + c,
|
||||||
getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${s}`,
|
|
||||||
},
|
},
|
||||||
'../../../actions': actionSpies,
|
'../../../actions': actionSpies,
|
||||||
'../../../ducks/gas.duck': customGasActionSpies,
|
'../../../ducks/gas.duck': gasActionSpies,
|
||||||
|
'../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies,
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('gas-modal-page-container container', () => {
|
describe('gas-modal-page-container container', () => {
|
||||||
@ -37,10 +43,54 @@ describe('gas-modal-page-container container', () => {
|
|||||||
describe('mapStateToProps()', () => {
|
describe('mapStateToProps()', () => {
|
||||||
|
|
||||||
it('should map the correct properties to props', () => {
|
it('should map the correct properties to props', () => {
|
||||||
assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState')
|
const mockState2 = {
|
||||||
assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState')
|
metamask: {
|
||||||
assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.buttonDataLoading, 'mockBasicGasEstimateLoadingStatus:mockState')
|
send: {
|
||||||
assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.gasButtonInfo, 'mockRenderableBasicEstimateData:mockState')
|
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)
|
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
actionSpies.hideModal.resetHistory()
|
||||||
|
gasActionSpies.setCustomGasPrice.resetHistory()
|
||||||
|
gasActionSpies.setCustomGasLimit.resetHistory()
|
||||||
|
})
|
||||||
|
|
||||||
describe('hideModal()', () => {
|
describe('hideModal()', () => {
|
||||||
it('should dispatch a hideModal action', () => {
|
it('should dispatch a hideModal action', () => {
|
||||||
mapDispatchToPropsObject.hideModal()
|
mapDispatchToPropsObject.hideModal()
|
||||||
@ -63,18 +119,50 @@ describe('gas-modal-page-container container', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('updateCustomGasPrice()', () => {
|
describe('updateCustomGasPrice()', () => {
|
||||||
it('should dispatch a setCustomGasPrice action', () => {
|
it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', () => {
|
||||||
mapDispatchToPropsObject.updateCustomGasPrice()
|
mapDispatchToPropsObject.updateCustomGasPrice('ffff')
|
||||||
assert(dispatchSpy.calledOnce)
|
assert(dispatchSpy.calledOnce)
|
||||||
assert(customGasActionSpies.setCustomGasPrice.calledOnce)
|
assert(gasActionSpies.setCustomGasPrice.calledOnce)
|
||||||
|
assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('updateCustomGasLimit()', () => {
|
describe('convertThenUpdateCustomGasPrice()', () => {
|
||||||
it('should dispatch a setCustomGasLimit action', () => {
|
it('should dispatch a setCustomGasPrice action with the arg passed to convertThenUpdateCustomGasPrice converted to WEI', () => {
|
||||||
mapDispatchToPropsObject.updateCustomGasLimit()
|
mapDispatchToPropsObject.convertThenUpdateCustomGasPrice('0xffff')
|
||||||
assert(dispatchSpy.calledOnce)
|
assert(dispatchSpy.calledOnce)
|
||||||
assert(customGasActionSpies.setCustomGasLimit.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('updateConfirmTxGasAndCalculate()', () => {
|
||||||
|
it('should dispatch a updateGasAndCalculate action with the correct props', () => {
|
||||||
|
mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa')
|
||||||
|
assert(dispatchSpy.calledOnce)
|
||||||
|
assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce)
|
||||||
|
assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
|
|||||||
|
|
||||||
const mapStateToProps = (state, props) => {
|
const mapStateToProps = (state, props) => {
|
||||||
const { toAddress: propsToAddress } = props
|
const { toAddress: propsToAddress } = props
|
||||||
const { confirmTransaction, metamask } = state
|
const { confirmTransaction, metamask, gas } = state
|
||||||
const {
|
const {
|
||||||
ethTransactionAmount,
|
ethTransactionAmount,
|
||||||
ethTransactionFee,
|
ethTransactionFee,
|
||||||
@ -60,6 +60,12 @@ const mapStateToProps = (state, props) => {
|
|||||||
unapprovedTxs,
|
unapprovedTxs,
|
||||||
} = metamask
|
} = metamask
|
||||||
const assetImage = assetImages[txParamsToAddress]
|
const assetImage = assetImages[txParamsToAddress]
|
||||||
|
|
||||||
|
const {
|
||||||
|
customGasLimit,
|
||||||
|
customGasPrice,
|
||||||
|
} = gas
|
||||||
|
|
||||||
const { balance } = accounts[selectedAddress]
|
const { balance } = accounts[selectedAddress]
|
||||||
const { name: fromName } = identities[selectedAddress]
|
const { name: fromName } = identities[selectedAddress]
|
||||||
const toAddress = propsToAddress || txParamsToAddress
|
const toAddress = propsToAddress || txParamsToAddress
|
||||||
@ -106,6 +112,10 @@ const mapStateToProps = (state, props) => {
|
|||||||
unapprovedTxs,
|
unapprovedTxs,
|
||||||
unapprovedTxCount,
|
unapprovedTxCount,
|
||||||
currentNetworkUnapprovedTxs,
|
currentNetworkUnapprovedTxs,
|
||||||
|
customGas: {
|
||||||
|
gasLimit: customGasLimit || txData.gasPrice,
|
||||||
|
gasPrice: customGasPrice || txData.gasLimit,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +202,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
...ownProps,
|
...ownProps,
|
||||||
showCustomizeGasModal: () => dispatchShowCustomizeGasModal({
|
showCustomizeGasModal: () => dispatchShowCustomizeGasModal({
|
||||||
txData,
|
txData,
|
||||||
onSubmit: txData => dispatchUpdateGasAndCalculate(txData),
|
onSubmit: customGas => dispatchUpdateGasAndCalculate(customGas),
|
||||||
validate: validateEditGas,
|
validate: validateEditGas,
|
||||||
}),
|
}),
|
||||||
cancelAllTransactions: () => dispatchCancelAllTransactions(valuesFor(unapprovedTxs)),
|
cancelAllTransactions: () => dispatchCancelAllTransactions(valuesFor(unapprovedTxs)),
|
||||||
|
@ -32,6 +32,7 @@ export default class ConfirmTransaction extends Component {
|
|||||||
setTransactionToConfirm: PropTypes.func,
|
setTransactionToConfirm: PropTypes.func,
|
||||||
confirmTransaction: PropTypes.object,
|
confirmTransaction: PropTypes.object,
|
||||||
clearConfirmTransaction: PropTypes.func,
|
clearConfirmTransaction: PropTypes.func,
|
||||||
|
fetchGasEstimates: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
getParamsTransactionId () {
|
getParamsTransactionId () {
|
||||||
@ -45,6 +46,7 @@ export default class ConfirmTransaction extends Component {
|
|||||||
send = {},
|
send = {},
|
||||||
history,
|
history,
|
||||||
confirmTransaction: { txData: { id: transactionId } = {} },
|
confirmTransaction: { txData: { id: transactionId } = {} },
|
||||||
|
fetchGasEstimates,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!totalUnapprovedCount && !send.to) {
|
if (!totalUnapprovedCount && !send.to) {
|
||||||
@ -53,6 +55,7 @@ export default class ConfirmTransaction extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!transactionId) {
|
if (!transactionId) {
|
||||||
|
fetchGasEstimates()
|
||||||
this.setTransactionToConfirm()
|
this.setTransactionToConfirm()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,9 @@ import {
|
|||||||
setTransactionToConfirm,
|
setTransactionToConfirm,
|
||||||
clearConfirmTransaction,
|
clearConfirmTransaction,
|
||||||
} from '../../../ducks/confirm-transaction.duck'
|
} from '../../../ducks/confirm-transaction.duck'
|
||||||
|
import {
|
||||||
|
fetchGasEstimates,
|
||||||
|
} from '../../../ducks/gas.duck'
|
||||||
import ConfirmTransaction from './confirm-transaction.component'
|
import ConfirmTransaction from './confirm-transaction.component'
|
||||||
import { getTotalUnapprovedCount } from '../../../selectors'
|
import { getTotalUnapprovedCount } from '../../../selectors'
|
||||||
import { unconfirmedTransactionsListSelector } from '../../../selectors/confirm-transaction'
|
import { unconfirmedTransactionsListSelector } from '../../../selectors/confirm-transaction'
|
||||||
@ -24,6 +27,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
return {
|
return {
|
||||||
setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)),
|
setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)),
|
||||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||||
|
fetchGasEstimates: () => dispatch(fetchGasEstimates()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +73,10 @@ export default class SendTransactionScreen extends PersistentForm {
|
|||||||
selectedAddress,
|
selectedAddress,
|
||||||
selectedToken = {},
|
selectedToken = {},
|
||||||
to: currentToAddress,
|
to: currentToAddress,
|
||||||
updateAndSetGasTotal,
|
updateAndSetGasLimit,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
updateAndSetGasTotal({
|
updateAndSetGasLimit({
|
||||||
blockGasLimit,
|
blockGasLimit,
|
||||||
editingTransactionId,
|
editingTransactionId,
|
||||||
gasLimit,
|
gasLimit,
|
||||||
@ -164,6 +164,9 @@ export default class SendTransactionScreen extends PersistentForm {
|
|||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.props.fetchGasEstimates()
|
this.props.fetchGasEstimates()
|
||||||
|
.then(() => {
|
||||||
|
this.updateGas()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
@ -173,12 +176,12 @@ export default class SendTransactionScreen extends PersistentForm {
|
|||||||
tokenContract,
|
tokenContract,
|
||||||
updateSendTokenBalance,
|
updateSendTokenBalance,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
updateSendTokenBalance({
|
updateSendTokenBalance({
|
||||||
selectedToken,
|
selectedToken,
|
||||||
tokenContract,
|
tokenContract,
|
||||||
address,
|
address,
|
||||||
})
|
})
|
||||||
this.updateGas()
|
|
||||||
|
|
||||||
// Show QR Scanner modal if ?scan=true
|
// Show QR Scanner modal if ?scan=true
|
||||||
if (window.location.search === '?scan=true') {
|
if (window.location.search === '?scan=true') {
|
||||||
|
@ -79,7 +79,7 @@ function mapStateToProps (state) {
|
|||||||
|
|
||||||
function mapDispatchToProps (dispatch) {
|
function mapDispatchToProps (dispatch) {
|
||||||
return {
|
return {
|
||||||
updateAndSetGasTotal: ({
|
updateAndSetGasLimit: ({
|
||||||
blockGasLimit,
|
blockGasLimit,
|
||||||
editingTransactionId,
|
editingTransactionId,
|
||||||
gasLimit,
|
gasLimit,
|
||||||
@ -92,7 +92,7 @@ function mapDispatchToProps (dispatch) {
|
|||||||
data,
|
data,
|
||||||
}) => {
|
}) => {
|
||||||
!editingTransactionId
|
!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)))
|
: dispatch(setGasTotal(calcGasTotal(gasLimit, gasPrice)))
|
||||||
},
|
},
|
||||||
updateSendTokenBalance: ({ selectedToken, tokenContract, address }) => {
|
updateSendTokenBalance: ({ selectedToken, tokenContract, address }) => {
|
||||||
|
@ -8,7 +8,11 @@ const {
|
|||||||
} = require('../../selectors')
|
} = require('../../selectors')
|
||||||
const {
|
const {
|
||||||
estimateGasPriceFromRecentBlocks,
|
estimateGasPriceFromRecentBlocks,
|
||||||
|
calcGasTotal,
|
||||||
} = require('./send.utils')
|
} = require('./send.utils')
|
||||||
|
import {
|
||||||
|
getAveragePriceEstimateInHexWEI,
|
||||||
|
} from '../../selectors/custom-gas'
|
||||||
|
|
||||||
const selectors = {
|
const selectors = {
|
||||||
accountsWithSendEtherInfoSelector,
|
accountsWithSendEtherInfoSelector,
|
||||||
@ -131,11 +135,11 @@ function getForceGasMin (state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getGasLimit (state) {
|
function getGasLimit (state) {
|
||||||
return state.metamask.send.gasLimit
|
return state.metamask.send.gasLimit || '0'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGasPrice (state) {
|
function getGasPrice (state) {
|
||||||
return state.metamask.send.gasPrice
|
return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGasPriceFromRecentBlocks (state) {
|
function getGasPriceFromRecentBlocks (state) {
|
||||||
@ -143,7 +147,7 @@ function getGasPriceFromRecentBlocks (state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getGasTotal (state) {
|
function getGasTotal (state) {
|
||||||
return state.metamask.send.gasTotal
|
return calcGasTotal(getGasLimit(state), getGasPrice(state))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrimaryCurrency (state) {
|
function getPrimaryCurrency (state) {
|
||||||
|
@ -9,11 +9,11 @@ import SendContent from '../send-content/send-content.component'
|
|||||||
import SendFooter from '../send-footer/send-footer.container'
|
import SendFooter from '../send-footer/send-footer.container'
|
||||||
|
|
||||||
const propsMethodSpies = {
|
const propsMethodSpies = {
|
||||||
updateAndSetGasTotal: sinon.spy(),
|
updateAndSetGasLimit: sinon.spy(),
|
||||||
updateSendErrors: sinon.spy(),
|
updateSendErrors: sinon.spy(),
|
||||||
updateSendTokenBalance: sinon.spy(),
|
updateSendTokenBalance: sinon.spy(),
|
||||||
resetSendState: sinon.spy(),
|
resetSendState: sinon.spy(),
|
||||||
fetchGasEstimates: sinon.spy(),
|
fetchGasEstimates: sinon.stub().returns(Promise.resolve()),
|
||||||
}
|
}
|
||||||
const utilsMethodStubs = {
|
const utilsMethodStubs = {
|
||||||
getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }),
|
getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }),
|
||||||
@ -52,7 +52,7 @@ describe('Send Component', function () {
|
|||||||
showHexData={true}
|
showHexData={true}
|
||||||
tokenBalance={'mockTokenBalance'}
|
tokenBalance={'mockTokenBalance'}
|
||||||
tokenContract={'mockTokenContract'}
|
tokenContract={'mockTokenContract'}
|
||||||
updateAndSetGasTotal={propsMethodSpies.updateAndSetGasTotal}
|
updateAndSetGasLimit={propsMethodSpies.updateAndSetGasLimit}
|
||||||
updateSendErrors={propsMethodSpies.updateSendErrors}
|
updateSendErrors={propsMethodSpies.updateSendErrors}
|
||||||
updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance}
|
updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance}
|
||||||
resetSendState={propsMethodSpies.resetSendState}
|
resetSendState={propsMethodSpies.resetSendState}
|
||||||
@ -66,7 +66,7 @@ describe('Send Component', function () {
|
|||||||
utilsMethodStubs.getAmountErrorObject.resetHistory()
|
utilsMethodStubs.getAmountErrorObject.resetHistory()
|
||||||
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
|
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
|
||||||
propsMethodSpies.fetchGasEstimates.resetHistory()
|
propsMethodSpies.fetchGasEstimates.resetHistory()
|
||||||
propsMethodSpies.updateAndSetGasTotal.resetHistory()
|
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
||||||
propsMethodSpies.updateSendErrors.resetHistory()
|
propsMethodSpies.updateSendErrors.resetHistory()
|
||||||
propsMethodSpies.updateSendTokenBalance.resetHistory()
|
propsMethodSpies.updateSendTokenBalance.resetHistory()
|
||||||
})
|
})
|
||||||
@ -75,16 +75,6 @@ describe('Send Component', function () {
|
|||||||
assert(SendTransactionScreen.prototype.componentDidMount.calledOnce)
|
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', () => {
|
describe('componentDidMount', () => {
|
||||||
it('should call props.fetchGasEstimates', () => {
|
it('should call props.fetchGasEstimates', () => {
|
||||||
propsMethodSpies.fetchGasEstimates.resetHistory()
|
propsMethodSpies.fetchGasEstimates.resetHistory()
|
||||||
@ -92,6 +82,14 @@ describe('Send Component', function () {
|
|||||||
wrapper.instance().componentDidMount()
|
wrapper.instance().componentDidMount()
|
||||||
assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1)
|
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', () => {
|
describe('componentWillUnmount', () => {
|
||||||
@ -283,12 +281,12 @@ describe('Send Component', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('updateGas', () => {
|
describe('updateGas', () => {
|
||||||
it('should call updateAndSetGasTotal with the correct params if no to prop is passed', () => {
|
it('should call updateAndSetGasLimit with the correct params if no to prop is passed', () => {
|
||||||
propsMethodSpies.updateAndSetGasTotal.resetHistory()
|
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
||||||
wrapper.instance().updateGas()
|
wrapper.instance().updateGas()
|
||||||
assert.equal(propsMethodSpies.updateAndSetGasTotal.callCount, 1)
|
assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0],
|
propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0],
|
||||||
{
|
{
|
||||||
blockGasLimit: 'mockBlockGasLimit',
|
blockGasLimit: 'mockBlockGasLimit',
|
||||||
editingTransactionId: 'mockEditingTransactionId',
|
editingTransactionId: 'mockEditingTransactionId',
|
||||||
@ -304,20 +302,20 @@ describe('Send Component', function () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call updateAndSetGasTotal with the correct params if a to prop is passed', () => {
|
it('should call updateAndSetGasLimit with the correct params if a to prop is passed', () => {
|
||||||
propsMethodSpies.updateAndSetGasTotal.resetHistory()
|
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
||||||
wrapper.setProps({ to: 'someAddress' })
|
wrapper.setProps({ to: 'someAddress' })
|
||||||
wrapper.instance().updateGas()
|
wrapper.instance().updateGas()
|
||||||
assert.equal(
|
assert.equal(
|
||||||
propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0].to,
|
propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to,
|
||||||
'someaddress',
|
'someaddress',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call updateAndSetGasTotal with to set to lowercase if passed', () => {
|
it('should call updateAndSetGasLimit with to set to lowercase if passed', () => {
|
||||||
propsMethodSpies.updateAndSetGasTotal.resetHistory()
|
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
||||||
wrapper.instance().updateGas({ to: '0xABC' })
|
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')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ describe('send container', () => {
|
|||||||
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy)
|
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('updateAndSetGasTotal()', () => {
|
describe('updateAndSetGasLimit()', () => {
|
||||||
const mockProps = {
|
const mockProps = {
|
||||||
blockGasLimit: 'mockBlockGasLimit',
|
blockGasLimit: 'mockBlockGasLimit',
|
||||||
editingTransactionId: '0x2',
|
editingTransactionId: '0x2',
|
||||||
@ -109,7 +109,7 @@ describe('send container', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it('should dispatch a setGasTotal action when editingTransactionId is truthy', () => {
|
it('should dispatch a setGasTotal action when editingTransactionId is truthy', () => {
|
||||||
mapDispatchToPropsObject.updateAndSetGasTotal(mockProps)
|
mapDispatchToPropsObject.updateAndSetGasLimit(mockProps)
|
||||||
assert(dispatchSpy.calledOnce)
|
assert(dispatchSpy.calledOnce)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
actionSpies.setGasTotal.getCall(0).args[0],
|
actionSpies.setGasTotal.getCall(0).args[0],
|
||||||
@ -118,14 +118,14 @@ describe('send container', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should dispatch an updateGasData action when editingTransactionId is falsy', () => {
|
it('should dispatch an updateGasData action when editingTransactionId is falsy', () => {
|
||||||
const { selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } = mockProps
|
const { gasPrice, selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } = mockProps
|
||||||
mapDispatchToPropsObject.updateAndSetGasTotal(
|
mapDispatchToPropsObject.updateAndSetGasLimit(
|
||||||
Object.assign({}, mockProps, {editingTransactionId: false})
|
Object.assign({}, mockProps, {editingTransactionId: false})
|
||||||
)
|
)
|
||||||
assert(dispatchSpy.calledOnce)
|
assert(dispatchSpy.calledOnce)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
actionSpies.updateGasData.getCall(0).args[0],
|
actionSpies.updateGasData.getCall(0).args[0],
|
||||||
{ selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data }
|
{ gasPrice, selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -237,7 +237,7 @@ describe('send selectors', () => {
|
|||||||
it('should return the send.gasTotal', () => {
|
it('should return the send.gasTotal', () => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
getGasTotal(mockState),
|
getGasTotal(mockState),
|
||||||
'0xb451dc41b578'
|
'a9ff56'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -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
|
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
|
||||||
const initState = {
|
const initState = {
|
||||||
customData: {
|
customData: {
|
||||||
price: 0,
|
price: null,
|
||||||
limit: 21000,
|
limit: '0x5208',
|
||||||
},
|
},
|
||||||
basicEstimates: {
|
basicEstimates: {
|
||||||
average: null,
|
average: null,
|
||||||
|
@ -47,8 +47,8 @@ describe('Gas Duck', () => {
|
|||||||
}
|
}
|
||||||
const initState = {
|
const initState = {
|
||||||
customData: {
|
customData: {
|
||||||
price: 0,
|
price: null,
|
||||||
limit: 21000,
|
limit: '0x5208',
|
||||||
},
|
},
|
||||||
basicEstimates: {
|
basicEstimates: {
|
||||||
average: null,
|
average: null,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import ethUtil from 'ethereumjs-util'
|
import ethUtil from 'ethereumjs-util'
|
||||||
import { conversionUtil } from '../conversion-util'
|
import { conversionUtil } from '../conversion-util'
|
||||||
import { ETH, GWEI, WEI } from '../constants/common'
|
import { ETH, GWEI, WEI } from '../constants/common'
|
||||||
|
import { conversionUtil, addCurrencies } from '../conversion-util'
|
||||||
|
|
||||||
export function bnToHex (inputBn) {
|
export function bnToHex (inputBn) {
|
||||||
return ethUtil.addHexPrefix(inputBn.toString(16))
|
return ethUtil.addHexPrefix(inputBn.toString(16))
|
||||||
@ -82,3 +83,41 @@ export function getWeiHexFromDecimalValue ({
|
|||||||
toDenomination: WEI,
|
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',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
3
ui/app/helpers/formatters.js
Normal file
3
ui/app/helpers/formatters.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function formatETHFee (ethFee) {
|
||||||
|
return ethFee + ' ETH'
|
||||||
|
}
|
@ -1,8 +1,4 @@
|
|||||||
import { pipe, partialRight } from 'ramda'
|
import { pipe, partialRight } from 'ramda'
|
||||||
import {
|
|
||||||
getConversionRate,
|
|
||||||
getGasLimit,
|
|
||||||
} from '../components/send/send.selectors'
|
|
||||||
import {
|
import {
|
||||||
conversionUtil,
|
conversionUtil,
|
||||||
multiplyCurrencies,
|
multiplyCurrencies,
|
||||||
@ -13,6 +9,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
formatCurrency,
|
formatCurrency,
|
||||||
} from '../helpers/confirm-transaction/util'
|
} from '../helpers/confirm-transaction/util'
|
||||||
|
import {
|
||||||
|
decEthToConvertedCurrency as ethTotalToConvertedCurrency,
|
||||||
|
} from '../helpers/conversions.util'
|
||||||
|
import {
|
||||||
|
formatETHFee,
|
||||||
|
} from '../helpers/formatters'
|
||||||
import {
|
import {
|
||||||
calcGasTotal,
|
calcGasTotal,
|
||||||
} from '../components/send/send.utils'
|
} from '../components/send/send.utils'
|
||||||
@ -25,6 +27,9 @@ const selectors = {
|
|||||||
getCustomGasTotal,
|
getCustomGasTotal,
|
||||||
getRenderableBasicEstimateData,
|
getRenderableBasicEstimateData,
|
||||||
getBasicGasEstimateLoadingStatus,
|
getBasicGasEstimateLoadingStatus,
|
||||||
|
getAveragePriceEstimateInHexWEI,
|
||||||
|
getDefaultActiveButtonIndex,
|
||||||
|
priceEstimateToWei,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = selectors
|
module.exports = selectors
|
||||||
@ -49,6 +54,16 @@ function getBasicGasEstimateLoadingStatus (state) {
|
|||||||
return state.gas.basicEstimateIsLoading
|
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) {
|
function apiEstimateModifiedToGWEI (estimate) {
|
||||||
return multiplyCurrencies(estimate, 0.10, {
|
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) {
|
function getRenderableEthFee (estimate, gasLimit) {
|
||||||
return pipe(
|
return pipe(
|
||||||
apiEstimateModifiedToGWEI,
|
apiEstimateModifiedToGWEI,
|
||||||
@ -150,9 +150,8 @@ function getRenderableBasicEstimateData (state) {
|
|||||||
if (getBasicGasEstimateLoadingStatus(state)) {
|
if (getBasicGasEstimateLoadingStatus(state)) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state)
|
||||||
const gasLimit = getGasLimit(state)
|
const conversionRate = state.metamask.conversionRate
|
||||||
const conversionRate = getConversionRate(state)
|
|
||||||
const currentCurrency = getCurrentCurrency(state)
|
const currentCurrency = getCurrentCurrency(state)
|
||||||
const {
|
const {
|
||||||
gas: {
|
gas: {
|
||||||
|
Loading…
Reference in New Issue
Block a user