import BigNumber from 'bignumber.js' export function newBigSigDig (n) { return new BigNumber((new BigNumber(String(n))).toPrecision(15)) } const createOp = (a, b, op) => (newBigSigDig(a))[op](newBigSigDig(b)) export function bigNumMinus (a = 0, b = 0) { return createOp(a, b, 'minus') } export function bigNumDiv (a = 0, b = 1) { return createOp(a, b, 'div') } 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.toNumber() } export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) { const closestLowerValueIndex = gasPrices.findIndex((e, i, a) => e <= priceToPosition && a[i + 1] >= priceToPosition) const closestHigherValueIndex = gasPrices.findIndex((e) => e > priceToPosition) return { closestLowerValueIndex, closestHigherValueIndex, closestHigherValue: gasPrices[closestHigherValueIndex], closestLowerValue: gasPrices[closestLowerValueIndex], } } export 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 ? `${symbol}${formattedMin} ${formattedSec}` : symbol + (formattedMin || formattedSec) return formattedCombined } export function getRawTimeEstimateData (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: priceForEstimation }) const newTimeEstimate = extrapolateY({ higherY: estimatedTimes[closestHigherValueIndex], lowerY: estimatedTimes[closestLowerValueIndex], higherX: closestHigherValue, lowerX: closestLowerValue, xForExtrapolation: priceForEstimation, }) return { newTimeEstimate, minGasPrice, maxGasPrice, } } export function getRenderableTimeEstimate (currentGasPrice, gasPrices, estimatedTimes) { const { newTimeEstimate, minGasPrice, maxGasPrice, } = getRawTimeEstimateData(currentGasPrice, gasPrices, estimatedTimes) return formatTimeEstimate(newTimeEstimate, currentGasPrice > maxGasPrice, currentGasPrice < minGasPrice) }