A Metamask fork with Infura removed and default networks editable
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.
 
 
 
 
 
ciphermask/ui/app/ducks/gas.duck.js

276 lines
7.0 KiB

import { mockGasEstimateData } from './mock-gas-estimate-data'
import { clone, uniqBy } from 'ramda'
import BigNumber from 'bignumber.js'
// 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'
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
const initState = {
customData: {
price: null,
limit: '0x5208',
},
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: [],
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 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) => {
dispatch(basicGasEstimatesLoadingStarted())
return 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,
avgWait,
block_time: blockTime,
blockNum,
fast,
fastest,
fastestWait,
fastWait,
safeLow,
safeLowWait,
speed,
}) => {
const basicEstimates = {
average,
avgWait,
blockTime,
blockNum,
fast,
fastest,
fastestWait,
fastWait,
safeLow,
safeLowWait,
speed,
}
dispatch(setBasicGasEstimateData(basicEstimates))
dispatch(basicGasEstimatesLoadingFinished())
return basicEstimates
})
}
}
export function fetchGasEstimates (blockTime) {
return (dispatch) => {
dispatch(gasEstimatesLoadingStarted())
// TODO: uncomment code when live api is ready
// return fetch('https://ethgasstation.info/json/predictTable.json', {
// 'headers': {},
// 'referrer': 'http://ethgasstation.info/json/',
// 'referrerPolicy': 'no-referrer-when-downgrade',
// 'body': null,
// 'method': 'GET',
// 'mode': 'cors'}
// )
return new Promise(resolve => {
resolve(mockGasEstimateData)
})
// .then(r => r.json())
.then(r => {
const estimatedPricesAndTimes = r.map(({ expectedTime, expectedWait, gasprice }) => ({ expectedTime, expectedWait, gasprice }))
const estimatedTimeWithUniquePrices = uniqBy(({ expectedTime }) => expectedTime, estimatedPricesAndTimes)
const timeMappedToSeconds = estimatedTimeWithUniquePrices.map(({ expectedWait, gasprice }) => {
const expectedTime = (new BigNumber(expectedWait)).times(Number(blockTime), 10).div(60, 10).toString(10)
return {
expectedTime,
expectedWait,
gasprice,
}
})
dispatch(setPricesAndTimeEstimates(timeMappedToSeconds.slice(1)))
dispatch(gasEstimatesLoadingFinished())
})
}
}
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 resetCustomGasState () {
return { type: RESET_CUSTOM_GAS_STATE }
}
export function resetCustomData () {
return { type: RESET_CUSTOM_DATA }
}