on df0c310 help sign in
bridge/src/lib/getSuggestedGasPrice.js
113 lines 3.7 kB history raw
1import { NETWORK_TYPES } from './network';
2import { DEFAULT_GAS_PRICE_GWEI, MAX_GAS_PRICE_GWEI } from './constants';
3import Web3 from 'web3';
5// ethgasstation returns values in floating point, one order of magitude
6// more than gwei. see: https://docs.ethgasstation.info
7// we don't want to charge users more than the gas tank funds
8const minGas = gas => Math.min(Math.ceil(gas), MAX_GAS_PRICE_GWEI);
10const feeToInt = (f) => f < 1 ? 1 : Math.round(f);
12const feeToWei = (fee) => Web3.utils.toHex(Web3.utils.toWei(String(fee), 'gwei' ))
14const calculateMaxFee = (baseFee, maxPriorityFee) => feeToWei(Math.round((2 * baseFee) + maxPriorityFee))
16// Convert seconds to minutes prettily
17const formatWait = (wait) => Math.round((wait * 100) / 60) / 100;
19export const defaultGasValues = value => ({
20 fast: {
21 price: value,
22 wait: '1',
23 maxFeePerGas: value,
24 maxPriorityFeePerGas: 1,
25 suggestedBaseFeePerGas: value > 2 ? value -1 : 1,
26 },
27 average: {
28 price: value,
29 wait: '1',
30 maxFeePerGas: value,
31 maxPriorityFeePerGas: 1,
32 suggestedBaseFeePerGas: value > 2 ? value -1 : 1,
33 },
34 low: {
35 price: value,
36 wait: '1',
37 maxFeePerGas: value,
38 maxPriorityFeePerGas: 1,
39 suggestedBaseFeePerGas: value > 2 ? value -1 : 1,
40 },
41});
43const getGasForNetwork = async (providerUrl) => {
44 try {
45 const [feeResponse, waitResponse] = await Promise.all([
46 fetch(
47 `${providerUrl}/api` +
48 '?module=gastracker' +
49 '&action=gasoracle' +
50 '&apikey=CG52E4R96W56GIKUI4IJ8CH9EZIXPUW1W8',
51 {
52 method: 'GET',
53 cache: 'no-cache',
54 }
55 ),
56 fetch(
57 'https://ethereum-api.xyz/gas-prices',
58 {
59 method: 'GET',
60 cache: 'no-cache',
61 }
62 )
63 ]);
65 const [feeJson, waitJson] = await Promise.all([
66 feeResponse.json(),
67 waitResponse.json()
68 ])
70 const suggestedBaseFeePerGas = Number(feeJson.result.suggestBaseFee);
72 // Calculations derived from:
73 // https://www.blocknative.com/blog/eip-1559-fees
74 return {
75 fast: {
76 price: minGas(feeJson.result.FastGasPrice),
77 wait: formatWait(waitJson.result.fast.time),
78 maxFeePerGas: calculateMaxFee(suggestedBaseFeePerGas, feeJson.result.FastGasPrice - suggestedBaseFeePerGas),
79 maxPriorityFeePerGas: feeToInt((feeJson.result.FastGasPrice - suggestedBaseFeePerGas)),
80 suggestedBaseFeePerGas
81 },
82 average: {
83 price: minGas(feeJson.result.ProposeGasPrice),
84 wait: formatWait(waitJson.result.average.time),
85 maxFeePerGas: calculateMaxFee(suggestedBaseFeePerGas, feeJson.result.ProposeGasPrice - suggestedBaseFeePerGas),
86 maxPriorityFeePerGas: feeToInt((feeJson.result.ProposeGasPrice - suggestedBaseFeePerGas)),
87 suggestedBaseFeePerGas
88 },
89 low: {
90 price: minGas(feeJson.result.SafeGasPrice),
91 wait: formatWait(waitJson.result.slow.time),
92 maxFeePerGas: calculateMaxFee(suggestedBaseFeePerGas, feeJson.result.SafeGasPrice - suggestedBaseFeePerGas),
93 maxPriorityFeePerGas: feeToInt((feeJson.result.SafeGasPrice - suggestedBaseFeePerGas)),
94 suggestedBaseFeePerGas
95 },
96 };
97 } catch (e) {
98 console.warn(e);
99 return defaultGasValues(DEFAULT_GAS_PRICE_GWEI);
100 }
103export default async function getSuggestedGasPrice(networkType) {
104 switch (networkType) {
105 case NETWORK_TYPES.GOERLI:
106 return getGasForNetwork('https://api-goerli.etherscan.io')
107 case NETWORK_TYPES.OFFLINE:
108 return defaultGasValues(DEFAULT_GAS_PRICE_GWEI);
109 case NETWORK_TYPES.LOCAL:
110 default:
111 return getGasForNetwork('https://api.etherscan.io/');
112 }