You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
5.4 KiB
210 lines
5.4 KiB
import { cloneDeep } from 'lodash'
|
|
import BigNumber from 'bignumber.js'
|
|
import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'
|
|
import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util'
|
|
import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
|
|
|
|
const fetchWithTimeout = getFetchWithTimeout(30000)
|
|
|
|
// 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 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_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'
|
|
const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'
|
|
const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED =
|
|
'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED'
|
|
|
|
const initState = {
|
|
customData: {
|
|
price: null,
|
|
limit: null,
|
|
},
|
|
basicEstimates: {
|
|
safeLow: null,
|
|
average: null,
|
|
fast: null,
|
|
},
|
|
basicEstimateIsLoading: true,
|
|
basicPriceEstimatesLastRetrieved: 0,
|
|
}
|
|
|
|
// Reducer
|
|
export default function reducer(state = initState, action) {
|
|
switch (action.type) {
|
|
case BASIC_GAS_ESTIMATE_LOADING_STARTED:
|
|
return {
|
|
...state,
|
|
basicEstimateIsLoading: true,
|
|
}
|
|
case BASIC_GAS_ESTIMATE_LOADING_FINISHED:
|
|
return {
|
|
...state,
|
|
basicEstimateIsLoading: false,
|
|
}
|
|
case SET_BASIC_GAS_ESTIMATE_DATA:
|
|
return {
|
|
...state,
|
|
basicEstimates: action.value,
|
|
}
|
|
case SET_CUSTOM_GAS_PRICE:
|
|
return {
|
|
...state,
|
|
customData: {
|
|
...state.customData,
|
|
price: action.value,
|
|
},
|
|
}
|
|
case SET_CUSTOM_GAS_LIMIT:
|
|
return {
|
|
...state,
|
|
customData: {
|
|
...state.customData,
|
|
limit: action.value,
|
|
},
|
|
}
|
|
case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED:
|
|
return {
|
|
...state,
|
|
basicPriceEstimatesLastRetrieved: action.value,
|
|
}
|
|
case RESET_CUSTOM_DATA:
|
|
return {
|
|
...state,
|
|
customData: cloneDeep(initState.customData),
|
|
}
|
|
case RESET_CUSTOM_GAS_STATE:
|
|
return cloneDeep(initState)
|
|
default:
|
|
return state
|
|
}
|
|
}
|
|
|
|
// Action Creators
|
|
export function basicGasEstimatesLoadingStarted() {
|
|
return {
|
|
type: BASIC_GAS_ESTIMATE_LOADING_STARTED,
|
|
}
|
|
}
|
|
|
|
export function basicGasEstimatesLoadingFinished() {
|
|
return {
|
|
type: BASIC_GAS_ESTIMATE_LOADING_FINISHED,
|
|
}
|
|
}
|
|
|
|
async function basicGasPriceQuery() {
|
|
const url = `https://api.metaswap.codefi.network/gasPrices`
|
|
return await fetchWithTimeout(url, {
|
|
headers: {},
|
|
referrer: 'https://api.metaswap.codefi.network/gasPrices',
|
|
referrerPolicy: 'no-referrer-when-downgrade',
|
|
body: null,
|
|
method: 'GET',
|
|
mode: 'cors',
|
|
})
|
|
}
|
|
|
|
export function fetchBasicGasEstimates() {
|
|
return async (dispatch, getState) => {
|
|
const { basicPriceEstimatesLastRetrieved } = getState().gas
|
|
const timeLastRetrieved =
|
|
basicPriceEstimatesLastRetrieved ||
|
|
(await getStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')) ||
|
|
0
|
|
|
|
dispatch(basicGasEstimatesLoadingStarted())
|
|
|
|
let basicEstimates
|
|
if (Date.now() - timeLastRetrieved > 75000) {
|
|
basicEstimates = await fetchExternalBasicGasEstimates(dispatch)
|
|
} else {
|
|
const cachedBasicEstimates = await getStorageItem('BASIC_PRICE_ESTIMATES')
|
|
basicEstimates =
|
|
cachedBasicEstimates || (await fetchExternalBasicGasEstimates(dispatch))
|
|
}
|
|
|
|
dispatch(setBasicGasEstimateData(basicEstimates))
|
|
dispatch(basicGasEstimatesLoadingFinished())
|
|
|
|
return basicEstimates
|
|
}
|
|
}
|
|
|
|
async function fetchExternalBasicGasEstimates(dispatch) {
|
|
const response = await basicGasPriceQuery()
|
|
|
|
const { SafeGasPrice, ProposeGasPrice, FastGasPrice } = await response.json()
|
|
|
|
const [safeLow, average, fast] = [
|
|
SafeGasPrice,
|
|
ProposeGasPrice,
|
|
FastGasPrice,
|
|
].map((price) => new BigNumber(price, 10).toNumber())
|
|
|
|
const basicEstimates = {
|
|
safeLow,
|
|
average,
|
|
fast,
|
|
}
|
|
|
|
const timeRetrieved = Date.now()
|
|
await Promise.all([
|
|
setStorageItem('BASIC_PRICE_ESTIMATES', basicEstimates),
|
|
setStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved),
|
|
])
|
|
dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved))
|
|
|
|
return basicEstimates
|
|
}
|
|
|
|
export function setCustomGasPriceForRetry(newPrice) {
|
|
return async (dispatch) => {
|
|
if (newPrice === '0x0') {
|
|
const { fast } = await getStorageItem('BASIC_PRICE_ESTIMATES')
|
|
dispatch(setCustomGasPrice(decGWEIToHexWEI(fast)))
|
|
} else {
|
|
dispatch(setCustomGasPrice(newPrice))
|
|
}
|
|
}
|
|
}
|
|
|
|
export function setBasicGasEstimateData(basicGasEstimateData) {
|
|
return {
|
|
type: SET_BASIC_GAS_ESTIMATE_DATA,
|
|
value: basicGasEstimateData,
|
|
}
|
|
}
|
|
|
|
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 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 }
|
|
}
|
|
|