import { pipe, partialRight } from 'ramda' import { conversionUtil, multiplyCurrencies, } from '../conversion-util' import { getCurrentCurrency, } from '../selectors' import { formatCurrency, } from '../helpers/confirm-transaction/util' import { decEthToConvertedCurrency as ethTotalToConvertedCurrency, } from '../helpers/conversions.util' import { formatETHFee, } from '../helpers/formatters' import { calcGasTotal, } from '../components/send/send.utils' import { addHexPrefix } from 'ethereumjs-util' const selectors = { getCustomGasErrors, getCustomGasLimit, getCustomGasPrice, getCustomGasTotal, getRenderableEstimateDataForSmallButtons, getRenderableBasicEstimateData, getBasicGasEstimateLoadingStatus, getAveragePriceEstimateInHexWEI, getDefaultActiveButtonIndex, priceEstimateToWei, } module.exports = selectors const NUMBER_OF_DECIMALS_SM_BTNS = 5 function getCustomGasErrors (state) { return state.gas.errors } function getCustomGasLimit (state) { return state.gas.customData.limit } function getCustomGasPrice (state) { return state.gas.customData.price } function getCustomGasTotal (state) { return state.gas.customData.total } function getBasicGasEstimateLoadingStatus (state) { return state.gas.basicEstimateIsLoading } function getAveragePriceEstimateInHexWEI (state) { const averagePriceEstimate = state.gas.basicEstimates.average return getGasPriceInHexWei(averagePriceEstimate || '0x0') } function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { return gasButtonInfo.findIndex(({ priceInHexWei }) => { return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) }) } function apiEstimateModifiedToGWEI (estimate) { return multiplyCurrencies(estimate, 0.10, { toNumericBase: 'hex', multiplicandBase: 10, multiplierBase: 10, numberOfDecimals: 9, }) } function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) { return conversionUtil(calcGasTotal(gasLimit, estimate), { fromNumericBase: 'hex', toNumericBase: 'dec', fromDenomination: 'GWEI', numberOfDecimals, }) } function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) { return pipe( apiEstimateModifiedToGWEI, partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]), formatETHFee )(estimate, gasLimit) } function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) { return pipe( apiEstimateModifiedToGWEI, partialRight(basicPriceEstimateToETHTotal, [gasLimit]), partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]), partialRight(formatCurrency, [convertedCurrency]) )(estimate, gasLimit, convertedCurrency, conversionRate) } function getTimeEstimateInSeconds (blockWaitEstimate, currentBlockTime) { return multiplyCurrencies(blockWaitEstimate, currentBlockTime, { toNumericBase: 'dec', multiplicandBase: 10, multiplierBase: 10, numberOfDecimals: 1, }) } function formatTimeEstimate (totalSeconds) { const minutes = Math.floor(totalSeconds / 60) const seconds = Math.floor(totalSeconds % 60) const formattedMin = `${minutes ? minutes + ' min' : ''}` const formattedSec = `${seconds ? seconds + ' sec' : ''}` const formattedCombined = formattedMin && formattedSec ? `~${formattedMin} ${formattedSec}` : '~' + [formattedMin, formattedSec].find(t => t) return formattedCombined } function getRenderableTimeEstimate (blockWaitEstimate, currentBlockTime) { return pipe( getTimeEstimateInSeconds, formatTimeEstimate )(blockWaitEstimate, currentBlockTime) } function priceEstimateToWei (priceEstimate) { return conversionUtil(priceEstimate, { fromNumericBase: 'hex', toNumericBase: 'hex', fromDenomination: 'GWEI', toDenomination: 'WEI', numberOfDecimals: 9, }) } function getGasPriceInHexWei (price) { return pipe( apiEstimateModifiedToGWEI, priceEstimateToWei, addHexPrefix )(price) } function getRenderableBasicEstimateData (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 [ { feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: getRenderableEthFee(fast, gasLimit), timeEstimate: getRenderableTimeEstimate(fastWait, blockTime), priceInHexWei: getGasPriceInHexWei(fast), }, { feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: getRenderableEthFee(average, gasLimit), timeEstimate: getRenderableTimeEstimate(avgWait, blockTime), priceInHexWei: getGasPriceInHexWei(average), }, { feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: getRenderableEthFee(safeLow, gasLimit), timeEstimate: getRenderableTimeEstimate(safeLowWait, blockTime), priceInHexWei: getGasPriceInHexWei(safeLow), }, ] } 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, }, }, } = 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), }, ] }