1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Integrate gas buttons with the send screen.

This commit is contained in:
Dan Miller 2018-09-13 10:05:17 -02:30
parent 7de3f22d63
commit b567c78bca
14 changed files with 301 additions and 41 deletions

View File

@ -121,6 +121,9 @@
"available": { "available": {
"message": "Available" "message": "Available"
}, },
"average": {
"message": "Average"
},
"back": { "back": {
"message": "Back" "message": "Back"
}, },
@ -439,6 +442,9 @@
"failed": { "failed": {
"message": "Failed" "message": "Failed"
}, },
"fast": {
"message": "Fast"
},
"feeChartTitle": { "feeChartTitle": {
"message": "Live Transaction Fee Predictions" "message": "Live Transaction Fee Predictions"
}, },
@ -1023,6 +1029,9 @@
"save": { "save": {
"message": "Save" "message": "Save"
}, },
"slow": {
"message": "Slow"
},
"saveAsCsvFile": { "saveAsCsvFile": {
"message": "Save as CSV File" "message": "Save as CSV File"
}, },
@ -1277,6 +1286,9 @@
"transactionErrorNoContract": { "transactionErrorNoContract": {
"message": "Trying to call a function on a non-contract address." "message": "Trying to call a function on a non-contract address."
}, },
"transactionFee": {
"message": "Transaction Fee"
},
"transactionMemo": { "transactionMemo": {
"message": "Transaction memo (optional)" "message": "Transaction memo (optional)"
}, },

View File

@ -23,6 +23,12 @@ export default class ButtonGroup extends PureComponent {
: this.props.defaultActiveButtonIndex, : this.props.defaultActiveButtonIndex,
} }
componentDidUpdate (prevProps, prevState) {
if (typeof this.props.newActiveButtonIndex === 'number' && prevState.activeButtonIndex !== this.props.newActiveButtonIndex) {
this.setState({ activeButtonIndex: prevProps.newActiveButtonIndex })
}
}
handleButtonClick (activeButtonIndex) { handleButtonClick (activeButtonIndex) {
this.setState({ activeButtonIndex }) this.setState({ activeButtonIndex })
} }

View File

@ -89,16 +89,20 @@ export default class GasModalPageContainer extends Component {
}, },
{ {
gasPriceButtonGroupProps, gasPriceButtonGroupProps,
hideBasic,
...advancedTabProps ...advancedTabProps
}) { }) {
return ( return (
<Tabs> <Tabs>
<Tab name={this.context.t('basic')}> {hideBasic
<div className="gas-modal-content"> ? null
{ this.renderBasicTabContent(gasPriceButtonGroupProps) } : <Tab name={this.context.t('basic')}>
{ this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } <div className="gas-modal-content">
</div> { this.renderBasicTabContent(gasPriceButtonGroupProps) }
</Tab> { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
</div>
</Tab>
}
<Tab name={this.context.t('advanced')}> <Tab name={this.context.t('advanced')}>
<div className="gas-modal-content"> <div className="gas-modal-content">
{ this.renderAdvancedTabContent(advancedTabProps) } { this.renderAdvancedTabContent(advancedTabProps) }

View File

@ -10,6 +10,9 @@ import {
setCustomGasPrice, setCustomGasPrice,
setCustomGasLimit, setCustomGasLimit,
} from '../../../ducks/gas.duck' } from '../../../ducks/gas.duck'
import {
hideGasButtonGroup,
} from '../../../ducks/send.duck'
import { import {
updateGasAndCalculate, updateGasAndCalculate,
} from '../../../ducks/confirm-transaction.duck' } from '../../../ducks/confirm-transaction.duck'
@ -59,7 +62,10 @@ const mapStateToProps = state => {
const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate) const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate)
const hideBasic = state.appState.modal.modalState.props.hideBasic
return { return {
hideBasic,
isConfirm: isConfirm(state), isConfirm: isConfirm(state),
customGasPriceInHex, customGasPriceInHex,
customGasLimitInHex, customGasLimitInHex,
@ -95,6 +101,7 @@ const mapDispatchToProps = dispatch => {
updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
}, },
hideGasButtonGroup: () => dispatch(hideGasButtonGroup()),
} }
} }
@ -102,6 +109,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
const { gasPriceButtonGroupProps, isConfirm } = stateProps const { gasPriceButtonGroupProps, isConfirm } = stateProps
const { const {
updateCustomGasPrice: dispatchUpdateCustomGasPrice, updateCustomGasPrice: dispatchUpdateCustomGasPrice,
hideGasButtonGroup: dispatchHideGasButtonGroup,
setGasData: dispatchSetGasData, setGasData: dispatchSetGasData,
updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate,
...otherDispatchProps ...otherDispatchProps
@ -111,7 +119,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
...stateProps, ...stateProps,
...otherDispatchProps, ...otherDispatchProps,
...ownProps, ...ownProps,
onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData, onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => {
dispatchSetGasData(newLimit, newPrice)
dispatchHideGasButtonGroup()
},
gasPriceButtonGroupProps: { gasPriceButtonGroupProps: {
...gasPriceButtonGroupProps, ...gasPriceButtonGroupProps,
handleGasPriceSelection: dispatchUpdateCustomGasPrice, handleGasPriceSelection: dispatchUpdateCustomGasPrice,

View File

@ -27,7 +27,7 @@ export default class GasPriceButtonGroup extends Component {
} }
renderButtonContent ({ renderButtonContent ({
label, labelKey,
feeInPrimaryCurrency, feeInPrimaryCurrency,
feeInSecondaryCurrency, feeInSecondaryCurrency,
timeEstimate, timeEstimate,
@ -36,7 +36,7 @@ export default class GasPriceButtonGroup extends Component {
showCheck, showCheck,
}) { }) {
return (<div> return (<div>
{ label && <div className={`${className}__label`}>{ label }</div> } { labelKey && <div className={`${className}__label`}>{ this.context.t(labelKey) }</div> }
{ feeInPrimaryCurrency && <div className={`${className}__primary-currency`}>{ feeInPrimaryCurrency }</div> } { feeInPrimaryCurrency && <div className={`${className}__primary-currency`}>{ feeInPrimaryCurrency }</div> }
{ feeInSecondaryCurrency && <div className={`${className}__secondary-currency`}>{ feeInSecondaryCurrency }</div> } { feeInSecondaryCurrency && <div className={`${className}__secondary-currency`}>{ feeInSecondaryCurrency }</div> }
{ timeEstimate && <div className={`${className}__time-estimate`}>{ timeEstimate }</div> } { timeEstimate && <div className={`${className}__time-estimate`}>{ timeEstimate }</div> }
@ -57,9 +57,7 @@ export default class GasPriceButtonGroup extends Component {
onClick={() => handleGasPriceSelection(priceInHexWei)} onClick={() => handleGasPriceSelection(priceInHexWei)}
key={`gas-price-button-${index}`} key={`gas-price-button-${index}`}
> >
{buttonDataLoading {this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)}
? 'Loading...'
: this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)}
</Button> </Button>
) )
} }
@ -68,18 +66,23 @@ export default class GasPriceButtonGroup extends Component {
const { const {
gasButtonInfo, gasButtonInfo,
defaultActiveButtonIndex = 1, defaultActiveButtonIndex = 1,
newActiveButtonIndex,
noButtonActiveByDefault = false, noButtonActiveByDefault = false,
buttonDataLoading,
...buttonPropsAndFlags ...buttonPropsAndFlags
} = this.props } = this.props
return ( return (
<ButtonGroup !buttonDataLoading
className={buttonPropsAndFlags.className} ? <ButtonGroup
defaultActiveButtonIndex={defaultActiveButtonIndex} className={buttonPropsAndFlags.className}
noButtonActiveByDefault={noButtonActiveByDefault} defaultActiveButtonIndex={defaultActiveButtonIndex}
> newActiveButtonIndex={newActiveButtonIndex}
{ gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } noButtonActiveByDefault={noButtonActiveByDefault}
</ButtonGroup> >
{ gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) }
</ButtonGroup>
: <div className={`${buttonPropsAndFlags.className}__loading-container`}>Loading...</div>
) )
} }
} }

View File

@ -18,6 +18,9 @@
height: 15.4px; height: 15.4px;
} }
&__loading-container {
height: 130px;
}
.button-group__button, .button-group__button--active { .button-group__button, .button-group__button--active {
height: 130px; height: 130px;
@ -58,3 +61,67 @@
} }
} }
} }
.gas-price-button-group--small {
display: flex;
justify-content: stretch;
max-width: 260px;
&__button-fiat-price {
font-size: 13px;
}
&__button-label {
font-size: 16px;
}
&__label {
font-weight: 500;
}
&__primary-currency {
font-size: 12px;
}
&__secondary-currency {
font-size: 12px;
}
&__loading-container {
height: 78px;
}
.button-group__button, .button-group__button--active {
height: 78px;
background: white;
color: $scorpion;
padding-top: 9px;
padding-left: 8.5px;
div {
display: flex;
flex-flow: column;
align-items: flex-start;
justify-content: flex-start;
}
i {
&:last-child {
display: none;
}
}
}
.button-group__button--active {
color: $white;
background: $dodger-blue;
i {
&:last-child {
display: flex;
color: $curious-blue;
margin-top: 10px
}
}
}
}

View File

@ -58,7 +58,8 @@ export default class PageContainer extends PureComponent {
renderActiveTabContent () { renderActiveTabContent () {
const { tabsComponent } = this.props const { tabsComponent } = this.props
const { children } = tabsComponent.props let { children } = tabsComponent.props
children = children.filter(child => child)
const { activeTabIndex } = this.state const { activeTabIndex } = this.state
return children[activeTabIndex] return children[activeTabIndex]

View File

@ -46,11 +46,10 @@ export default class GasFeeDisplay extends Component {
</div> </div>
} }
<button <button
className="sliders-icon-container" className="gas-fee-reset"
onClick={onClick} onClick={showGasButtonGroup}
disabled={!gasTotal && !gasLoadingError}
> >
<i className="fa fa-sliders sliders-icon" /> Reset
</button> </button>
</div> </div>
) )

View File

@ -2,6 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import SendRowWrapper from '../send-row-wrapper/' import SendRowWrapper from '../send-row-wrapper/'
import GasFeeDisplay from './gas-fee-display/gas-fee-display.component' import GasFeeDisplay from './gas-fee-display/gas-fee-display.component'
import GasPriceButtonGroup from '../../../gas-customization/gas-price-button-group'
export default class SendGasRow extends Component { export default class SendGasRow extends Component {
@ -26,21 +27,37 @@ export default class SendGasRow extends Component {
gasTotal, gasTotal,
gasFeeError, gasFeeError,
showCustomizeGasModal, showCustomizeGasModal,
gasPriceButtonGroupProps,
gasButtonGroupShown,
showGasButtonGroup
} = this.props } = this.props
return ( return (
<SendRowWrapper <SendRowWrapper
label={`${this.context.t('gasFee')}:`} label={`${this.context.t('transactionFee')}:`}
showError={gasFeeError} showError={gasFeeError}
errorType={'gasFee'} errorType={'gasFee'}
> >
<GasFeeDisplay {gasButtonGroupShown
conversionRate={conversionRate} ? <div>
convertedCurrency={convertedCurrency} <GasPriceButtonGroup
gasLoadingError={gasLoadingError} className="gas-price-button-group--small"
gasTotal={gasTotal} showCheck={false}
onClick={() => showCustomizeGasModal()} {...this.props.gasPriceButtonGroupProps}
/> />
<div className="advanced-gas-options-btn" onClick={() => showCustomizeGasModal()}>
Advanced Options
</div>
</div>
: <GasFeeDisplay
conversionRate={conversionRate}
convertedCurrency={convertedCurrency}
gasLoadingError={gasLoadingError}
gasTotal={gasTotal}
showGasButtonGroup={showGasButtonGroup}
onClick={() => showCustomizeGasModal()}
/>}
</SendRowWrapper> </SendRowWrapper>
) )
} }

View File

@ -3,25 +3,64 @@ import {
getConversionRate, getConversionRate,
getCurrentCurrency, getCurrentCurrency,
getGasTotal, getGasTotal,
getGasPrice,
} from '../../send.selectors.js' } from '../../send.selectors.js'
import { getGasLoadingError, gasFeeIsInError } from './send-gas-row.selectors.js' import{
import { showModal } from '../../../../actions' getBasicGasEstimateLoadingStatus,
getRenderableEstimateDataForSmallButtons,
getDefaultActiveButtonIndex
} from '../../../../selectors/custom-gas'
import{
showGasButtonGroup
} from '../../../../ducks/send.duck'
import { getGasLoadingError, gasFeeIsInError, getGasButtonGroupShown } from './send-gas-row.selectors.js'
import { showModal, setGasPrice } from '../../../../actions'
import SendGasRow from './send-gas-row.component' import SendGasRow from './send-gas-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendGasRow) export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(SendGasRow)
function mapStateToProps (state) { function mapStateToProps (state) {
const gasButtonInfo = getRenderableEstimateDataForSmallButtons(state)
const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, getGasPrice(state))
return { return {
conversionRate: getConversionRate(state), conversionRate: getConversionRate(state),
convertedCurrency: getCurrentCurrency(state), convertedCurrency: getCurrentCurrency(state),
gasTotal: getGasTotal(state), gasTotal: getGasTotal(state),
gasFeeError: gasFeeIsInError(state), gasFeeError: gasFeeIsInError(state),
gasLoadingError: getGasLoadingError(state), gasLoadingError: getGasLoadingError(state),
gasPriceButtonGroupProps: {
buttonDataLoading: getBasicGasEstimateLoadingStatus(state),
defaultActiveButtonIndex: 1,
newActiveButtonIndex: activeButtonIndex > -1 ? activeButtonIndex : null,
gasButtonInfo,
},
gasButtonGroupShown: getGasButtonGroupShown(state),
} }
} }
function mapDispatchToProps (dispatch) { function mapDispatchToProps (dispatch) {
return { return {
showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS' })), showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })),
setGasPrice: newPrice => dispatch(setGasPrice(newPrice)),
showGasButtonGroup: () => dispatch(showGasButtonGroup())
} }
} }
function mergeProps (stateProps, dispatchProps, ownProps) {
const { gasPriceButtonGroupProps } = stateProps
const {
setGasPrice: dispatchSetGasPrice,
...otherDispatchProps
} = dispatchProps
return {
...stateProps,
...otherDispatchProps,
...ownProps,
gasPriceButtonGroupProps: {
...gasPriceButtonGroupProps,
handleGasPriceSelection: dispatchSetGasPrice,
},
}
}

View File

@ -1,6 +1,7 @@
const selectors = { const selectors = {
gasFeeIsInError, gasFeeIsInError,
getGasLoadingError, getGasLoadingError,
getGasButtonGroupShown,
} }
module.exports = selectors module.exports = selectors
@ -12,3 +13,7 @@ function getGasLoadingError (state) {
function gasFeeIsInError (state) { function gasFeeIsInError (state) {
return Boolean(state.send.errors.gasFee) return Boolean(state.send.errors.gasFee)
} }
function getGasButtonGroupShown (state) {
return state.send.gasButtonGroupShown
}

View File

@ -579,7 +579,7 @@
font-family: Roboto; font-family: Roboto;
font-size: 16px; font-size: 16px;
line-height: 22px; line-height: 22px;
width: 88px; width: 112px;
font-weight: 400; font-weight: 400;
flex: 0 0 auto; flex: 0 0 auto;
} }
@ -622,6 +622,7 @@
&__to-autocomplete { &__to-autocomplete {
position: relative; position: relative;
max-width: 260px;
&__down-caret { &__down-caret {
z-index: 1026; z-index: 1026;
@ -684,6 +685,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
} }
} }
&__sliders-icon-container { &__sliders-icon-container {
@ -917,6 +919,15 @@
display: none; display: none;
} }
} }
}
.advanced-gas-options-btn {
display: flex;
justify-content: flex-end;
font-size: 14px;
color: #2f9ae0;
cursor: pointer;
} }
.sliders-icon-container { .sliders-icon-container {
@ -935,6 +946,23 @@
font-size: 1em; font-size: 1em;
} }
.gas-fee-reset {
display: flex;
align-items: center;
justify-content: center;
height: 24px;
border-radius: 4px;
background-color: #fff;
position: absolute;
right: 12px;
top: 14px;
cursor: pointer;
font-size: 1em;
font-size: 14px;
color: #2f9ae0;
font-family: Roboto;
}
.sliders-icon { .sliders-icon {
color: $curious-blue; color: $curious-blue;
} }

View File

@ -7,11 +7,14 @@ const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN'
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN' const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN'
const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS' const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS'
const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE' const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE'
const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP'
const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP'
// 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 = {
fromDropdownOpen: false, fromDropdownOpen: false,
toDropdownOpen: false, toDropdownOpen: false,
gasButtonGroupShown: true,
errors: {}, errors: {},
} }
@ -43,6 +46,14 @@ export default function reducer ({ send: sendState = initState }, action = {}) {
...action.value, ...action.value,
}, },
}) })
case SHOW_GAS_BUTTON_GROUP:
return extend(newState, {
gasButtonGroupShown: true,
})
case HIDE_GAS_BUTTON_GROUP:
return extend(newState, {
gasButtonGroupShown: false,
})
case RESET_SEND_STATE: case RESET_SEND_STATE:
return extend({}, initState) return extend({}, initState)
default: default:
@ -67,6 +78,14 @@ export function closeToDropdown () {
return { type: CLOSE_TO_DROPDOWN } return { type: CLOSE_TO_DROPDOWN }
} }
export function showGasButtonGroup () {
return { type: SHOW_GAS_BUTTON_GROUP }
}
export function hideGasButtonGroup () {
return { type: HIDE_GAS_BUTTON_GROUP }
}
export function updateSendErrors (errorObject) { export function updateSendErrors (errorObject) {
return { return {
type: UPDATE_SEND_ERRORS, type: UPDATE_SEND_ERRORS,

View File

@ -25,6 +25,7 @@ const selectors = {
getCustomGasLimit, getCustomGasLimit,
getCustomGasPrice, getCustomGasPrice,
getCustomGasTotal, getCustomGasTotal,
getRenderableEstimateDataForSmallButtons,
getRenderableBasicEstimateData, getRenderableBasicEstimateData,
getBasicGasEstimateLoadingStatus, getBasicGasEstimateLoadingStatus,
getAveragePriceEstimateInHexWEI, getAveragePriceEstimateInHexWEI,
@ -34,6 +35,8 @@ const selectors = {
module.exports = selectors module.exports = selectors
const NUMBER_OF_DECIMALS_SM_BTNS = 5
function getCustomGasErrors (state) { function getCustomGasErrors (state) {
return state.gas.errors return state.gas.errors
} }
@ -60,7 +63,9 @@ function getAveragePriceEstimateInHexWEI (state) {
} }
function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) {
console.log('gasButtonInfo', gasButtonInfo)
return gasButtonInfo.findIndex(({ priceInHexWei }) => { return gasButtonInfo.findIndex(({ priceInHexWei }) => {
console.log('priceInHexWei', priceInHexWei, '|', customGasPriceInHex)
return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice)
}) })
} }
@ -74,23 +79,24 @@ function apiEstimateModifiedToGWEI (estimate) {
}) })
} }
function basicPriceEstimateToETHTotal (estimate, gasLimit) { function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) {
return conversionUtil(calcGasTotal(gasLimit, estimate), { return conversionUtil(calcGasTotal(gasLimit, estimate), {
fromNumericBase: 'hex', fromNumericBase: 'hex',
toNumericBase: 'dec', toNumericBase: 'dec',
fromDenomination: 'GWEI', fromDenomination: 'GWEI',
numberOfDecimals: 9, numberOfDecimals,
}) })
} }
function getRenderableEthFee (estimate, gasLimit) { function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) {
return pipe( return pipe(
apiEstimateModifiedToGWEI, apiEstimateModifiedToGWEI,
partialRight(basicPriceEstimateToETHTotal, [gasLimit]), partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]),
formatETHFee formatETHFee
)(estimate, gasLimit) )(estimate, gasLimit)
} }
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) { function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) {
return pipe( return pipe(
apiEstimateModifiedToGWEI, apiEstimateModifiedToGWEI,
@ -188,3 +194,46 @@ function getRenderableBasicEstimateData (state) {
}, },
] ]
} }
function getRenderableEstimateDataForSmallButtons (state) {
if (getBasicGasEstimateLoadingStatus(state)) {
return []
}
const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state)
const conversionRate = state.metamask.conversionRate
const currentCurrency = getCurrentCurrency(state)
const {
gas: {
basicEstimates: {
safeLow,
average,
fast,
blockTime,
safeLowWait,
avgWait,
fastWait,
},
},
} = state
return [
{
labelKey: 'fast',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate),
feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS),
priceInHexWei: getGasPriceInHexWei(fast),
},
{
labelKey: 'average',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate),
feeInPrimaryCurrency: getRenderableEthFee(average, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS),
priceInHexWei: getGasPriceInHexWei(average),
},
{
labelKey: 'slow',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate),
feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS),
priceInHexWei: getGasPriceInHexWei(safeLow),
},
]
}