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

Final gas customization fixes

This commit is contained in:
Dan Miller 2018-11-27 14:00:41 -03:30
parent 75d7545437
commit d8e41a6aa5
18 changed files with 198 additions and 104 deletions

View File

@ -413,7 +413,7 @@ describe('Transaction Controller', function () {
gasPrice: '0xa',
}
txController.txStateManager._saveTxList([
{ id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [] },
{ id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [{}] },
])
expectedTxParams = Object.assign({}, txParams, { gasPrice: '0xb'})

View File

@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import classnames from 'classnames'
import Loading from '../../../loading-screen'
import GasPriceChart from '../../gas-price-chart'
import debounce from 'lodash.debounce'
export default class AdvancedTabContent extends Component {
static contextTypes = {
@ -22,7 +23,21 @@ export default class AdvancedTabContent extends Component {
insufficientBalance: PropTypes.bool,
}
gasInput (value, onChange, min, insufficientBalance, precision, showGWEI) {
constructor (props) {
super(props)
this.debouncedGasLimitReset = debounce((dVal) => {
if (dVal < 21000) {
props.updateCustomGasLimit(21000)
}
}, 1000, { trailing: true })
this.onChangeGasLimit = (val) => {
props.updateCustomGasLimit(val)
this.debouncedGasLimitReset(val)
}
}
gasInput (value, onChange, min, insufficientBalance, showGWEI) {
return (
<div className="advanced-tab__gas-edit-row__input-wrapper">
<input
@ -32,14 +47,13 @@ export default class AdvancedTabContent extends Component {
type="number"
value={value}
min={min}
precision={precision}
onChange={event => onChange(Number(event.target.value))}
/>
<div className={classnames('advanced-tab__gas-edit-row__input-arrows', {
'advanced-tab__gas-edit-row__input-arrows--error': insufficientBalance,
})}>
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap"><i className="fa fa-sm fa-angle-up" onClick={() => onChange(value + 1)} /></div>
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap"><i className="fa fa-sm fa-angle-down" onClick={() => onChange(value - 1)} /></div>
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap" onClick={() => onChange(value + 1)}><i className="fa fa-sm fa-angle-up" /></div>
<div className="advanced-tab__gas-edit-row__input-arrows__i-wrap" onClick={() => onChange(value - 1)}><i className="fa fa-sm fa-angle-down" /></div>
</div>
{insufficientBalance && <div className="advanced-tab__gas-edit-row__insufficient-balance">
Insufficient Balance
@ -84,8 +98,8 @@ export default class AdvancedTabContent extends Component {
renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit, insufficientBalance) {
return (
<div className="advanced-tab__gas-edit-rows">
{ this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, 9, true) }
{ this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, insufficientBalance, 0) }
{ this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, true) }
{ this.renderGasEditRow('gasLimit', customGasLimit, this.onChangeGasLimit, customGasLimit, insufficientBalance) }
</div>
)
}

View File

@ -148,6 +148,7 @@
height: 100%;
display: flex;
justify-content: center;
cursor: pointer;
}
&__i-wrap:hover {

View File

@ -155,8 +155,11 @@ describe('AdvancedTabContent Component', function () {
describe('renderGasEditRows()', () => {
let gasEditRows
let tempOnChangeGasLimit
beforeEach(() => {
tempOnChangeGasLimit = wrapper.instance().onChangeGasLimit
wrapper.instance().onChangeGasLimit = () => 'mockOnChangeGasLimit'
AdvancedTabContent.prototype.renderGasEditRow.resetHistory()
gasEditRows = shallow(wrapper.instance().renderGasEditRows(
'mockGasPrice',
@ -167,6 +170,10 @@ describe('AdvancedTabContent Component', function () {
))
})
afterEach(() => {
wrapper.instance().onChangeGasLimit = tempOnChangeGasLimit
})
it('should render the gas-edit-rows root node', () => {
assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows'))
})
@ -182,10 +189,10 @@ describe('AdvancedTabContent Component', function () {
const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args
assert.equal(renderGasEditRowSpyArgs.length, 2)
assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [
'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, 9, true,
'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, true,
].map(String))
assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [
'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', false, 0,
'gasLimit', 'mockGasLimit', () => 'mockOnChangeGasLimit', 'mockGasLimit', false,
].map(String))
})
})
@ -234,7 +241,6 @@ describe('AdvancedTabContent Component', function () {
const inputProps = gasInput.find('input').props()
assert.equal(inputProps.min, 0)
assert.equal(inputProps.value, 321)
assert.equal(inputProps.precision, 8)
})
it('should call the passed onChange method with the value of the input onChange event', () => {
@ -257,9 +263,9 @@ describe('AdvancedTabContent Component', function () {
8,
false
))
const upArrow = gasInput.find('.fa-angle-up')
const upArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(0)
assert.equal(upArrow.props().onClick(), 329)
const downArrow = gasInput.find('.fa-angle-down')
const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1)
assert.equal(downArrow.props().onClick(), 327)
})
})

View File

@ -89,7 +89,7 @@ export default class GasModalPageContainer extends Component {
renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) {
return (
<div>
<div className="gas-modal-content__info-row-wrapper">
<div className="gas-modal-content__info-row">
<div className="gas-modal-content__info-row__send-info">
<span className="gas-modal-content__info-row__send-info__label">{this.context.t('sendAmount')}</span>
@ -167,7 +167,6 @@ export default class GasModalPageContainer extends Component {
onClose={() => cancelAndClose()}
onSubmit={() => {
onSubmit(customModalGasLimitInHex, customModalGasPriceInHex)
cancelAndClose()
}}
submitText={this.context.t('save')}
headerCloseText={'Close'}

View File

@ -142,6 +142,7 @@ const mapDispatchToProps = dispatch => {
dispatch(resetCustomData())
dispatch(hideModal())
},
hideModal: () => dispatch(hideModal()),
updateCustomGasPrice,
convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)),
convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))),
@ -150,6 +151,8 @@ const mapDispatchToProps = dispatch => {
dispatch(setGasPrice(newPrice))
},
updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
updateCustomGasPrice(gasPrice)
dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16))))
return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
},
createSpeedUpTransaction: (txId, gasPrice) => {
@ -172,6 +175,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate,
createSpeedUpTransaction: dispatchCreateSpeedUpTransaction,
hideSidebar: dispatchHideSidebar,
cancelAndClose: dispatchCancelAndClose,
hideModal: dispatchHideModal,
...otherDispatchProps
} = dispatchProps
@ -182,18 +187,27 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
onSubmit: (gasLimit, gasPrice) => {
if (isConfirm) {
dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice)
dispatchHideModal()
} else if (isSpeedUp) {
dispatchCreateSpeedUpTransaction(txId, gasPrice)
dispatchHideSidebar()
dispatchCancelAndClose()
} else {
dispatchSetGasData(gasLimit, gasPrice)
dispatchHideGasButtonGroup()
dispatchCancelAndClose()
}
},
gasPriceButtonGroupProps: {
...gasPriceButtonGroupProps,
handleGasPriceSelection: dispatchUpdateCustomGasPrice,
},
cancelAndClose: () => {
dispatchCancelAndClose()
if (isSpeedUp) {
dispatchHideSidebar()
}
},
}
}
@ -241,20 +255,29 @@ function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conver
}
function getRenderableTimeEstimate (currentGasPrice, gasPrices, estimatedTimes) {
const minGasPrice = gasPrices[0]
const maxGasPrice = gasPrices[gasPrices.length - 1]
let priceForEstimation = currentGasPrice
if (currentGasPrice < minGasPrice) {
priceForEstimation = minGasPrice
} else if (currentGasPrice > maxGasPrice) {
priceForEstimation = maxGasPrice
}
const {
closestLowerValueIndex,
closestHigherValueIndex,
closestHigherValue,
closestLowerValue,
} = getAdjacentGasPrices({ gasPrices, priceToPosition: currentGasPrice })
} = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation })
const newTimeEstimate = extrapolateY({
higherY: estimatedTimes[closestHigherValueIndex],
lowerY: estimatedTimes[closestLowerValueIndex],
higherX: closestHigherValue,
lowerX: closestLowerValue,
xForExtrapolation: currentGasPrice,
xForExtrapolation: priceForEstimation,
})
return formatTimeEstimate(newTimeEstimate)
return formatTimeEstimate(newTimeEstimate, currentGasPrice > maxGasPrice, currentGasPrice < minGasPrice)
}

View File

@ -44,6 +44,7 @@
display: flex;
justify-content: center;
align-items: flex-start;
margin-right: 0;
}
&__subtitle {

View File

@ -82,10 +82,10 @@ describe('gas-modal-page-container container', () => {
},
gasEstimatesLoading: false,
priceAndTimeEstimates: [
{ gasprice: 3, expectedTime: '31' },
{ gasprice: 4, expectedTime: '62' },
{ gasprice: 5, expectedTime: '93' },
{ gasprice: 6, expectedTime: '124' },
{ gasprice: 3, expectedTime: 31 },
{ gasprice: 4, expectedTime: 62 },
{ gasprice: 5, expectedTime: 93 },
{ gasprice: 6, expectedTime: 124 },
],
},
confirmTransaction: {
@ -235,7 +235,7 @@ describe('gas-modal-page-container container', () => {
describe('updateConfirmTxGasAndCalculate()', () => {
it('should dispatch a updateGasAndCalculate action with the correct props', () => {
mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa')
assert(dispatchSpy.calledOnce)
assert.equal(dispatchSpy.callCount, 3)
assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce)
assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' })
})
@ -265,6 +265,8 @@ describe('gas-modal-page-container container', () => {
someOtherDispatchProp: sinon.spy(),
createSpeedUpTransaction: sinon.spy(),
hideSidebar: sinon.spy(),
hideModal: sinon.spy(),
cancelAndClose: sinon.spy(),
}
ownProps = { someOwnProp: 123 }
})
@ -277,6 +279,7 @@ describe('gas-modal-page-container container', () => {
dispatchProps.someOtherDispatchProp.resetHistory()
dispatchProps.createSpeedUpTransaction.resetHistory()
dispatchProps.hideSidebar.resetHistory()
dispatchProps.hideModal.resetHistory()
})
it('should return the expected props when isConfirm is true', () => {
const result = mergeProps(stateProps, dispatchProps, ownProps)
@ -290,12 +293,14 @@ describe('gas-modal-page-container container', () => {
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0)
assert.equal(dispatchProps.setGasData.callCount, 0)
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
assert.equal(dispatchProps.hideModal.callCount, 0)
result.onSubmit()
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1)
assert.equal(dispatchProps.setGasData.callCount, 0)
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
assert.equal(dispatchProps.hideModal.callCount, 1)
assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0)
result.gasPriceButtonGroupProps.handleGasPriceSelection()
@ -318,6 +323,7 @@ describe('gas-modal-page-container container', () => {
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0)
assert.equal(dispatchProps.setGasData.callCount, 0)
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
assert.equal(dispatchProps.cancelAndClose.callCount, 0)
result.onSubmit('mockNewLimit', 'mockNewPrice')
@ -325,6 +331,7 @@ describe('gas-modal-page-container container', () => {
assert.equal(dispatchProps.setGasData.callCount, 1)
assert.deepEqual(dispatchProps.setGasData.getCall(0).args, ['mockNewLimit', 'mockNewPrice'])
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 1)
assert.equal(dispatchProps.cancelAndClose.callCount, 1)
assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0)
result.gasPriceButtonGroupProps.handleGasPriceSelection()
@ -343,6 +350,7 @@ describe('gas-modal-page-container container', () => {
assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0)
assert.equal(dispatchProps.setGasData.callCount, 0)
assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0)
assert.equal(dispatchProps.cancelAndClose.callCount, 1)
assert.equal(dispatchProps.createSpeedUpTransaction.callCount, 1)
assert.equal(dispatchProps.hideSidebar.callCount, 1)

View File

@ -137,7 +137,7 @@
.gas-price-button-group--alt {
display: flex;
justify-content: stretch;
max-width: 342px;
width: 95%;
&__button-fiat-price {
font-size: 13px;

View File

@ -19,7 +19,7 @@ export default class GasPriceChart extends Component {
gasPrices: PropTypes.array,
estimatedTimes: PropTypes.array,
gasPricesMax: PropTypes.number,
estimatedTimesMax: PropTypes.string,
estimatedTimesMax: PropTypes.number,
currentPrice: PropTypes.number,
updateCustomGasPrice: PropTypes.func,
}

View File

@ -1,5 +1,11 @@
import * as d3 from 'd3'
import c3 from 'c3'
import BigNumber from 'bignumber.js'
const newBigSigDig = n => (new BigNumber(n.toPrecision(15)))
const createOp = (a, b, op) => (newBigSigDig(a))[op](newBigSigDig(b))
const bigNumMinus = (a = 0, b = 0) => createOp(a, b, 'minus')
const bigNumDiv = (a = 0, b = 1) => createOp(a, b, 'div')
export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes, chart }) {
const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({
@ -24,7 +30,8 @@ export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices
}
export function getCoordinateData (selector) {
return d3.select(selector).node().getBoundingClientRect()
const node = d3.select(selector).node()
return node ? node.getBoundingClientRect() : {}
}
export function generateDataUIObj (x, index, value) {
@ -70,19 +77,22 @@ export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) {
}
}
export function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) {
const slope = (higherY - lowerY) / (higherX - lowerX)
const newTimeEstimate = -1 * (slope * (higherX - xForExtrapolation) - higherY)
export function extrapolateY ({ higherY = 0, lowerY = 0, higherX = 0, lowerX = 0, xForExtrapolation = 0 }) {
const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX))
const newTimeEstimate = slope.times(bigNumMinus(higherX, xForExtrapolation)).minus(newBigSigDig(higherY)).negated()
return newTimeEstimate
return newTimeEstimate.toNumber()
}
export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes }) {
const chartMouseXPos = xMousePos - chartXStart
const posPercentile = chartMouseXPos / chartWidth
const chartMouseXPos = bigNumMinus(xMousePos, chartXStart)
const posPercentile = bigNumDiv(chartMouseXPos, chartWidth)
const currentPosValue = (gasPrices[gasPrices.length - 1] - gasPrices[0]) * posPercentile + gasPrices[0]
const currentPosValue = (bigNumMinus(gasPrices[gasPrices.length - 1], gasPrices[0]))
.times(newBigSigDig(posPercentile))
.plus(newBigSigDig(gasPrices[0]))
.toNumber()
const {
closestLowerValueIndex,
@ -162,20 +172,28 @@ export function setSelectedCircle ({
closestHigherValue,
}) {
const numberOfValues = chart.internal.data.xs.data1.length
const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`)
let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`)
let count = closestHigherValueIndex + 1
if (lowerX === higherX) {
const { x: higherXAdjusted, y: higherYAdjusted } = getCoordinateData(`.c3-circle-${closestHigherValueIndex + 1}`)
higherY = higherYAdjusted
higherX = higherXAdjusted
if (lowerX && higherX) {
while (lowerX === higherX) {
higherX = getCoordinateData(`.c3-circle-${count}`).x
higherY = getCoordinateData(`.c3-circle-${count}`).y
count++
}
}
const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue)
const currentX = bigNumMinus(higherX, lowerX)
.times(bigNumMinus(newPrice, closestLowerValue))
.div(bigNumMinus(closestHigherValue, closestLowerValue))
.plus(newBigSigDig(lowerX))
const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX })
chart.internal.selectPoint(
generateDataUIObj(currentX, numberOfValues, newTimeEstimate),
generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate),
numberOfValues
)
}
@ -282,8 +300,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate
.style('margin-top', flipTooltip ? '-16px' : '4px')
return {
top: circleY - chartYStart - 19 + (flipTooltip ? circleWidth + 38 : 0),
left: circleX - chartXStart + circleWidth - (gasPricesMaxPadded / 50),
top: bigNumMinus(circleY, chartYStart).minus(19).plus(flipTooltip ? circleWidth + 38 : 0).toNumber(),
left: bigNumMinus(circleX, chartXStart).plus(newBigSigDig(circleWidth)).minus(bigNumDiv(gasPricesMaxPadded, 50)).toNumber(),
}
},
show: true,
@ -298,8 +316,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate
appendOrUpdateCircle.bind(this)({
data,
itemIndex,
cx: () => data.x - chartXStart + 11,
cy: () => data.value - chartYStart + 10,
cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(),
cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(),
cssId: 'set-circle',
appendOnly: true,
})

View File

@ -399,7 +399,7 @@ function mapDispatchToProps (dispatch) {
return {
hideModal: (customOnHideOpts) => {
dispatch(actions.hideModal())
if (customOnHideOpts.action) {
if (customOnHideOpts && customOnHideOpts.action) {
dispatch(customOnHideOpts.action(...customOnHideOpts.args))
}
},

View File

@ -12,7 +12,7 @@ export default class PageContainerFooter extends Component {
submitText: PropTypes.string,
disabled: PropTypes.bool,
submitButtonType: PropTypes.string,
hideCancel: PropTypes.func,
hideCancel: PropTypes.bool,
}
static contextTypes = {

View File

@ -1,6 +1,11 @@
.sidebar-left {
display: flex;
.gas-modal-page-container {
display: flex;
.page-container {
flex: 1;
max-width: 100%;
&__content {
@ -12,6 +17,10 @@
max-width: 344px;
min-height: auto;
}
@media screen and (min-width: $break-small) {
max-height: none;
}
}
.gas-price-chart {
@ -34,9 +43,10 @@
}
.basic-tab-content {
height: 318px;
height: auto;
margin-bottom: 0px;
border-bottom: 1px solid #d2d8dd;
flex: 1 1 70%;
@media screen and (max-width: $break-small) {
padding-left: 14px;
@ -55,6 +65,10 @@
}
.advanced-tab {
@media screen and (min-width: $break-small) {
flex: 1 1 70%;
}
&__fee-chart {
height: 320px;
@ -72,14 +86,26 @@
}
}
.gas-modal-content {
display: flex;
flex-direction: column;
width: 100%;
.gas-modal-content__info-row {
height: 170px;
@media screen and (max-width: $break-small) {
height: initial;
&__info-row-wrapper {
display: flex;
justify-content: center;
@media screen and (min-width: $break-small) {
flex: 1 1 30%;
}
}
&__info-row {
height: 170px;
@media screen and (max-width: $break-small) {
height: initial;
display: flex;
justify-content: center;
}
}
}
}

View File

@ -220,18 +220,25 @@ export function fetchBasicGasAndTimeEstimates () {
)
.then(r => r.json())
.then(({
average,
average: averageTimes10,
avgWait,
block_time: blockTime,
blockNum,
fast,
fastest,
fast: fastTimes10,
fastest: fastestTimes10,
fastestWait,
fastWait,
safeLow,
safeLow: safeLowTimes10,
safeLowWait,
speed,
}) => {
const [average, fast, fastest, safeLow] = [
averageTimes10,
fastTimes10,
fastestTimes10,
safeLowTimes10,
].map(price => (new BigNumber(price)).div(10).toNumber())
const basicEstimates = {
average,
avgWait,

View File

@ -32,15 +32,15 @@ describe('Gas Duck', () => {
let tempFetch
let tempDateNow
const mockEthGasApiResponse = {
average: 'mockAverage',
average: 20,
avgWait: 'mockAvgWait',
block_time: 'mockBlock_time',
blockNum: 'mockBlockNum',
fast: 'mockFast',
fastest: 'mockFastest',
fast: 30,
fastest: 40,
fastestWait: 'mockFastestWait',
fastWait: 'mockFastWait',
safeLow: 'mockSafeLow',
safeLow: 10,
safeLowWait: 'mockSafeLowWait',
speed: 'mockSpeed',
}
@ -338,15 +338,15 @@ describe('Gas Duck', () => {
[{
type: SET_BASIC_GAS_ESTIMATE_DATA,
value: {
average: 'mockAverage',
average: 2,
avgWait: 'mockAvgWait',
blockTime: 'mockBlock_time',
blockNum: 'mockBlockNum',
fast: 'mockFast',
fastest: 'mockFastest',
fast: 3,
fastest: 4,
fastestWait: 'mockFastestWait',
fastWait: 'mockFastWait',
safeLow: 'mockSafeLow',
safeLow: 1,
safeLowWait: 'mockSafeLowWait',
speed: 'mockSpeed',
},

View File

@ -85,9 +85,9 @@ function getAveragePriceEstimateInHexWEI (state) {
return getGasPriceInHexWei(averagePriceEstimate || '0x0')
}
function getFastPriceEstimateInHexWEI (state, convertFromDecGWEI) {
function getFastPriceEstimateInHexWEI (state) {
const fastPriceEstimate = state.gas.basicEstimates.fast
return getGasPriceInHexWei(fastPriceEstimate || '0x0', convertFromDecGWEI)
return getGasPriceInHexWei(fastPriceEstimate || '0x0')
}
function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) {
@ -100,15 +100,6 @@ function getBasicGasEstimateBlockTime (state) {
return state.gas.basicEstimates.blockTime
}
function apiEstimateModifiedToGWEI (estimate) {
return multiplyCurrencies(estimate, 0.10, {
toNumericBase: 'hex',
multiplicandBase: 10,
multiplierBase: 10,
numberOfDecimals: 9,
})
}
function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) {
return conversionUtil(calcGasTotal(gasLimit, estimate), {
fromNumericBase: 'hex',
@ -118,26 +109,18 @@ function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9)
})
}
function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9, convertFromDecGWEI) {
const initialConversion = convertFromDecGWEI
? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' })
: apiEstimateModifiedToGWEI
function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) {
return pipe(
initialConversion,
x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }),
partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]),
formatETHFee
)(estimate, gasLimit)
}
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate, convertFromDecGWEI) {
const initialConversion = convertFromDecGWEI
? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' })
: apiEstimateModifiedToGWEI
function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) {
return pipe(
initialConversion,
x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }),
partialRight(basicPriceEstimateToETHTotal, [gasLimit]),
partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]),
partialRight(formatCurrency, [convertedCurrency])
@ -153,14 +136,26 @@ function getTimeEstimateInSeconds (blockWaitEstimate) {
})
}
function formatTimeEstimate (totalSeconds) {
function formatTimeEstimate (totalSeconds, greaterThanMax, lessThanMin) {
const minutes = Math.floor(totalSeconds / 60)
const seconds = Math.floor(totalSeconds % 60)
if (!minutes && !seconds) {
return '...'
}
let symbol = '~'
if (greaterThanMax) {
symbol = '< '
} else if (lessThanMin) {
symbol = '> '
}
const formattedMin = `${minutes ? minutes + ' min' : ''}`
const formattedSec = `${seconds ? seconds + ' sec' : ''}`
const formattedCombined = formattedMin && formattedSec
? `~${formattedMin} ${formattedSec}`
: '~' + [formattedMin, formattedSec].find(t => t)
? `${symbol}${formattedMin} ${formattedSec}`
: symbol + [formattedMin, formattedSec].find(t => t)
return formattedCombined
}
@ -182,13 +177,9 @@ function priceEstimateToWei (priceEstimate) {
})
}
function getGasPriceInHexWei (price, convertFromDecGWEI) {
const initialConversion = convertFromDecGWEI
? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' })
: apiEstimateModifiedToGWEI
function getGasPriceInHexWei (price) {
return pipe(
initialConversion,
x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }),
priceEstimateToWei,
addHexPrefix
)(price)
@ -259,19 +250,19 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) {
return [
{
labelKey: 'fastest',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate, true),
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate),
feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
priceInHexWei: getGasPriceInHexWei(fastest, true),
},
{
labelKey: 'fast',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate, true),
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate),
feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
priceInHexWei: getGasPriceInHexWei(fast, true),
},
{
labelKey: 'slow',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate, true),
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate),
feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
priceInHexWei: getGasPriceInHexWei(safeLow, true),
},

View File

@ -109,11 +109,11 @@ describe('custom-gas selectors', () => {
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 25,
safeLow: 2.5,
safeLowWait: 6.6,
fast: 50,
fast: 5,
fastWait: 3.3,
fastest: 100,
fastest: 10,
fastestWait: 0.5,
},
},
@ -154,11 +154,11 @@ describe('custom-gas selectors', () => {
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 50,
safeLow: 5,
safeLowWait: 13.2,
fast: 100,
fast: 10,
fastWait: 6.6,
fastest: 200,
fastest: 20,
fastestWait: 1.0,
},
},