aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/ducks/gas.duck.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/ducks/gas.duck.js')
-rw-r--r--ui/app/ducks/gas.duck.js517
1 files changed, 0 insertions, 517 deletions
diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js
deleted file mode 100644
index 957b00163..000000000
--- a/ui/app/ducks/gas.duck.js
+++ /dev/null
@@ -1,517 +0,0 @@
-import { clone, uniqBy, flatten } from 'ramda'
-import BigNumber from 'bignumber.js'
-import {
- loadLocalStorageData,
- saveLocalStorageData,
-} from '../../lib/local-storage-helpers'
-import {
- decGWEIToHexWEI,
-} from '../helpers/conversions.util'
-
-// Actions
-const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'
-const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'
-const GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED'
-const GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED'
-const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'
-const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA'
-const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'
-const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS'
-const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'
-const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'
-const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL'
-const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES'
-const SET_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED'
-const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED'
-const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED'
-
-// TODO: determine if this approach to initState is consistent with conventional ducks pattern
-const initState = {
- customData: {
- price: null,
- limit: null,
- },
- basicEstimates: {
- average: null,
- fastestWait: null,
- fastWait: null,
- fast: null,
- safeLowWait: null,
- blockNum: null,
- avgWait: null,
- blockTime: null,
- speed: null,
- fastest: null,
- safeLow: null,
- },
- basicEstimateIsLoading: true,
- gasEstimatesLoading: true,
- priceAndTimeEstimates: [],
- basicPriceAndTimeEstimates: [],
- priceAndTimeEstimatesLastRetrieved: 0,
- basicPriceAndTimeEstimatesLastRetrieved: 0,
- basicPriceEstimatesLastRetrieved: 0,
- errors: {},
-}
-
-// Reducer
-export default function reducer ({ gas: gasState = initState }, action = {}) {
- const newState = clone(gasState)
-
- switch (action.type) {
- case BASIC_GAS_ESTIMATE_LOADING_STARTED:
- return {
- ...newState,
- basicEstimateIsLoading: true,
- }
- case BASIC_GAS_ESTIMATE_LOADING_FINISHED:
- return {
- ...newState,
- basicEstimateIsLoading: false,
- }
- case GAS_ESTIMATE_LOADING_STARTED:
- return {
- ...newState,
- gasEstimatesLoading: true,
- }
- case GAS_ESTIMATE_LOADING_FINISHED:
- return {
- ...newState,
- gasEstimatesLoading: false,
- }
- case SET_BASIC_GAS_ESTIMATE_DATA:
- return {
- ...newState,
- basicEstimates: action.value,
- }
- case SET_CUSTOM_GAS_PRICE:
- return {
- ...newState,
- customData: {
- ...newState.customData,
- price: action.value,
- },
- }
- case SET_CUSTOM_GAS_LIMIT:
- return {
- ...newState,
- customData: {
- ...newState.customData,
- limit: action.value,
- },
- }
- case SET_CUSTOM_GAS_TOTAL:
- return {
- ...newState,
- customData: {
- ...newState.customData,
- total: action.value,
- },
- }
- case SET_PRICE_AND_TIME_ESTIMATES:
- return {
- ...newState,
- priceAndTimeEstimates: action.value,
- }
- case SET_CUSTOM_GAS_ERRORS:
- return {
- ...newState,
- errors: {
- ...newState.errors,
- ...action.value,
- },
- }
- case SET_API_ESTIMATES_LAST_RETRIEVED:
- return {
- ...newState,
- priceAndTimeEstimatesLastRetrieved: action.value,
- }
- case SET_BASIC_API_ESTIMATES_LAST_RETRIEVED:
- return {
- ...newState,
- basicPriceAndTimeEstimatesLastRetrieved: action.value,
- }
- case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED:
- return {
- ...newState,
- basicPriceEstimatesLastRetrieved: action.value,
- }
- case RESET_CUSTOM_DATA:
- return {
- ...newState,
- customData: clone(initState.customData),
- }
- case RESET_CUSTOM_GAS_STATE:
- return clone(initState)
- default:
- return newState
- }
-}
-
-// Action Creators
-export function basicGasEstimatesLoadingStarted () {
- return {
- type: BASIC_GAS_ESTIMATE_LOADING_STARTED,
- }
-}
-
-export function basicGasEstimatesLoadingFinished () {
- return {
- type: BASIC_GAS_ESTIMATE_LOADING_FINISHED,
- }
-}
-
-export function gasEstimatesLoadingStarted () {
- return {
- type: GAS_ESTIMATE_LOADING_STARTED,
- }
-}
-
-export function gasEstimatesLoadingFinished () {
- return {
- type: GAS_ESTIMATE_LOADING_FINISHED,
- }
-}
-
-export function fetchBasicGasEstimates () {
- return (dispatch, getState) => {
- const {
- basicPriceEstimatesLastRetrieved,
- basicPriceAndTimeEstimates,
- } = getState().gas
- const timeLastRetrieved = basicPriceEstimatesLastRetrieved || loadLocalStorageData('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') || 0
-
- dispatch(basicGasEstimatesLoadingStarted())
-
- const promiseToFetch = Date.now() - timeLastRetrieved > 75000
- ? fetch('https://dev.blockscale.net/api/gasexpress.json', {
- 'headers': {},
- 'referrer': 'https://dev.blockscale.net/api/',
- 'referrerPolicy': 'no-referrer-when-downgrade',
- 'body': null,
- 'method': 'GET',
- 'mode': 'cors'}
- )
- .then(r => r.json())
- .then(({
- safeLow,
- standard: average,
- fast,
- fastest,
- block_time: blockTime,
- blockNum,
- }) => {
- const basicEstimates = {
- safeLow,
- average,
- fast,
- fastest,
- blockTime,
- blockNum,
- }
-
- const timeRetrieved = Date.now()
- dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved))
- saveLocalStorageData(timeRetrieved, 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')
- saveLocalStorageData(basicEstimates, 'BASIC_PRICE_ESTIMATES')
-
- return basicEstimates
- })
- : Promise.resolve(basicPriceAndTimeEstimates.length
- ? basicPriceAndTimeEstimates
- : loadLocalStorageData('BASIC_PRICE_ESTIMATES')
- )
-
- return promiseToFetch.then(basicEstimates => {
- dispatch(setBasicGasEstimateData(basicEstimates))
- dispatch(basicGasEstimatesLoadingFinished())
- return basicEstimates
- })
- }
-}
-
-export function fetchBasicGasAndTimeEstimates () {
- return (dispatch, getState) => {
- const {
- basicPriceAndTimeEstimatesLastRetrieved,
- basicPriceAndTimeEstimates,
- } = getState().gas
- const timeLastRetrieved = basicPriceAndTimeEstimatesLastRetrieved || loadLocalStorageData('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') || 0
-
- dispatch(basicGasEstimatesLoadingStarted())
-
- const promiseToFetch = Date.now() - timeLastRetrieved > 75000
- ? fetch('https://ethgasstation.info/json/ethgasAPI.json', {
- 'headers': {},
- 'referrer': 'http://ethgasstation.info/json/',
- 'referrerPolicy': 'no-referrer-when-downgrade',
- 'body': null,
- 'method': 'GET',
- 'mode': 'cors'}
- )
- .then(r => r.json())
- .then(({
- average: averageTimes10,
- avgWait,
- block_time: blockTime,
- blockNum,
- fast: fastTimes10,
- fastest: fastestTimes10,
- fastestWait,
- fastWait,
- 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,
- blockTime,
- blockNum,
- fast,
- fastest,
- fastestWait,
- fastWait,
- safeLow,
- safeLowWait,
- speed,
- }
-
- const timeRetrieved = Date.now()
- dispatch(setBasicApiEstimatesLastRetrieved(timeRetrieved))
- saveLocalStorageData(timeRetrieved, 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED')
- saveLocalStorageData(basicEstimates, 'BASIC_GAS_AND_TIME_API_ESTIMATES')
-
- return basicEstimates
- })
- : Promise.resolve(basicPriceAndTimeEstimates.length
- ? basicPriceAndTimeEstimates
- : loadLocalStorageData('BASIC_GAS_AND_TIME_API_ESTIMATES')
- )
-
- return promiseToFetch.then(basicEstimates => {
- dispatch(setBasicGasEstimateData(basicEstimates))
- dispatch(basicGasEstimatesLoadingFinished())
- return basicEstimates
- })
- }
-}
-
-function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) {
- higherY = new BigNumber(higherY, 10)
- lowerY = new BigNumber(lowerY, 10)
- higherX = new BigNumber(higherX, 10)
- lowerX = new BigNumber(lowerX, 10)
- xForExtrapolation = new BigNumber(xForExtrapolation, 10)
- const slope = (higherY.minus(lowerY)).div(higherX.minus(lowerX))
- const newTimeEstimate = slope.times(higherX.minus(xForExtrapolation)).minus(higherY).negated()
-
- return Number(newTimeEstimate.toPrecision(10))
-}
-
-function getRandomArbitrary (min, max) {
- min = new BigNumber(min, 10)
- max = new BigNumber(max, 10)
- const random = new BigNumber(String(Math.random()), 10)
- return new BigNumber(random.times(max.minus(min)).plus(min)).toPrecision(10)
-}
-
-function calcMedian (list) {
- const medianPos = (Math.floor(list.length / 2) + Math.ceil(list.length / 2)) / 2
- return medianPos === Math.floor(medianPos)
- ? (list[medianPos - 1] + list[medianPos]) / 2
- : list[Math.floor(medianPos)]
-}
-
-function quartiles (data) {
- const lowerHalf = data.slice(0, Math.floor(data.length / 2))
- const upperHalf = data.slice(Math.floor(data.length / 2) + (data.length % 2 === 0 ? 0 : 1))
- const median = calcMedian(data)
- const lowerQuartile = calcMedian(lowerHalf)
- const upperQuartile = calcMedian(upperHalf)
- return {
- median,
- lowerQuartile,
- upperQuartile,
- }
-}
-
-function inliersByIQR (data, prop) {
- const { lowerQuartile, upperQuartile } = quartiles(data.map(d => prop ? d[prop] : d))
- const IQR = upperQuartile - lowerQuartile
- const lowerBound = lowerQuartile - 1.5 * IQR
- const upperBound = upperQuartile + 1.5 * IQR
- return data.filter(d => {
- const value = prop ? d[prop] : d
- return value >= lowerBound && value <= upperBound
- })
-}
-
-export function fetchGasEstimates (blockTime) {
- return (dispatch, getState) => {
- const {
- priceAndTimeEstimatesLastRetrieved,
- priceAndTimeEstimates,
- } = getState().gas
- const timeLastRetrieved = priceAndTimeEstimatesLastRetrieved || loadLocalStorageData('GAS_API_ESTIMATES_LAST_RETRIEVED') || 0
-
- dispatch(gasEstimatesLoadingStarted())
-
- const promiseToFetch = Date.now() - timeLastRetrieved > 75000
- ? fetch('https://ethgasstation.info/json/predictTable.json', {
- 'headers': {},
- 'referrer': 'http://ethgasstation.info/json/',
- 'referrerPolicy': 'no-referrer-when-downgrade',
- 'body': null,
- 'method': 'GET',
- 'mode': 'cors'}
- )
- .then(r => r.json())
- .then(r => {
- const estimatedPricesAndTimes = r.map(({ expectedTime, expectedWait, gasprice }) => ({ expectedTime, expectedWait, gasprice }))
- const estimatedTimeWithUniquePrices = uniqBy(({ expectedTime }) => expectedTime, estimatedPricesAndTimes)
-
- const withSupplementalTimeEstimates = flatten(estimatedTimeWithUniquePrices.map(({ expectedWait, gasprice }, i, arr) => {
- const next = arr[i + 1]
- if (!next) {
- return [{ expectedWait, gasprice }]
- } else {
- const supplementalPrice = getRandomArbitrary(gasprice, next.gasprice)
- const supplementalTime = extrapolateY({
- higherY: next.expectedWait,
- lowerY: expectedWait,
- higherX: next.gasprice,
- lowerX: gasprice,
- xForExtrapolation: supplementalPrice,
- })
- const supplementalPrice2 = getRandomArbitrary(supplementalPrice, next.gasprice)
- const supplementalTime2 = extrapolateY({
- higherY: next.expectedWait,
- lowerY: supplementalTime,
- higherX: next.gasprice,
- lowerX: supplementalPrice,
- xForExtrapolation: supplementalPrice2,
- })
- return [
- { expectedWait, gasprice },
- { expectedWait: supplementalTime, gasprice: supplementalPrice },
- { expectedWait: supplementalTime2, gasprice: supplementalPrice2 },
- ]
- }
- }))
- const withOutliersRemoved = inliersByIQR(withSupplementalTimeEstimates.slice(0).reverse(), 'expectedWait').reverse()
- const timeMappedToSeconds = withOutliersRemoved.map(({ expectedWait, gasprice }) => {
- const expectedTime = (new BigNumber(expectedWait)).times(Number(blockTime), 10).toNumber()
- return {
- expectedTime,
- gasprice: (new BigNumber(gasprice, 10).toNumber()),
- }
- })
-
- const timeRetrieved = Date.now()
- dispatch(setApiEstimatesLastRetrieved(timeRetrieved))
- saveLocalStorageData(timeRetrieved, 'GAS_API_ESTIMATES_LAST_RETRIEVED')
- saveLocalStorageData(timeMappedToSeconds, 'GAS_API_ESTIMATES')
-
- return timeMappedToSeconds
- })
- : Promise.resolve(priceAndTimeEstimates.length
- ? priceAndTimeEstimates
- : loadLocalStorageData('GAS_API_ESTIMATES')
- )
-
- return promiseToFetch.then(estimates => {
- dispatch(setPricesAndTimeEstimates(estimates))
- dispatch(gasEstimatesLoadingFinished())
- })
- }
-}
-
-export function setCustomGasPriceForRetry (newPrice) {
- return (dispatch) => {
- if (newPrice !== '0x0') {
- dispatch(setCustomGasPrice(newPrice))
- } else {
- const { fast } = loadLocalStorageData('BASIC_PRICE_ESTIMATES')
- dispatch(setCustomGasPrice(decGWEIToHexWEI(fast)))
- }
- }
-}
-
-export function setBasicGasEstimateData (basicGasEstimateData) {
- return {
- type: SET_BASIC_GAS_ESTIMATE_DATA,
- value: basicGasEstimateData,
- }
-}
-
-export function setPricesAndTimeEstimates (estimatedPricesAndTimes) {
- return {
- type: SET_PRICE_AND_TIME_ESTIMATES,
- value: estimatedPricesAndTimes,
- }
-}
-
-export function setCustomGasPrice (newPrice) {
- return {
- type: SET_CUSTOM_GAS_PRICE,
- value: newPrice,
- }
-}
-
-export function setCustomGasLimit (newLimit) {
- return {
- type: SET_CUSTOM_GAS_LIMIT,
- value: newLimit,
- }
-}
-
-export function setCustomGasTotal (newTotal) {
- return {
- type: SET_CUSTOM_GAS_TOTAL,
- value: newTotal,
- }
-}
-
-export function setCustomGasErrors (newErrors) {
- return {
- type: SET_CUSTOM_GAS_ERRORS,
- value: newErrors,
- }
-}
-
-export function setApiEstimatesLastRetrieved (retrievalTime) {
- return {
- type: SET_API_ESTIMATES_LAST_RETRIEVED,
- value: retrievalTime,
- }
-}
-
-export function setBasicApiEstimatesLastRetrieved (retrievalTime) {
- return {
- type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED,
- value: retrievalTime,
- }
-}
-
-export function setBasicPriceEstimatesLastRetrieved (retrievalTime) {
- return {
- type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED,
- value: retrievalTime,
- }
-}
-
-export function resetCustomGasState () {
- return { type: RESET_CUSTOM_GAS_STATE }
-}
-
-export function resetCustomData () {
- return { type: RESET_CUSTOM_DATA }
-}