on ea25a45 help sign in
bridge/src/lib/getSuggestedGasPrice.js
120 lines 3.5 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 weiToGwei = wei => Math.ceil(wei / 1_000_000_000);
16const calculateMaxFee = (baseFee, maxPriorityFee) =>
17 feeToWei(Math.round(2 * baseFee + maxPriorityFee));
19// Convert seconds to minutes prettily
20const formatWait = wait => Math.round((wait * 100) / 60) / 100;
22export const defaultGasValues = value => ({
23 fast: {
24 price: value,
25 wait: '1',
26 maxFeePerGas: value,
27 maxPriorityFeePerGas: 1,
28 suggestedBaseFeePerGas: value > 2 ? value - 1 : 1,
29 },
30 average: {
31 price: value,
32 wait: '1',
33 maxFeePerGas: value,
34 maxPriorityFeePerGas: 1,
35 suggestedBaseFeePerGas: value > 2 ? value - 1 : 1,
36 },
37 low: {
38 price: value,
39 wait: '1',
40 maxFeePerGas: value,
41 maxPriorityFeePerGas: 1,
42 suggestedBaseFeePerGas: value > 2 ? value - 1 : 1,
43 },
44});
46const getGasForNetwork = async providerUrl => {
47 try {
48 const [feeResponse, baseFeeResponse] = await Promise.all([
49 fetch(
50 'https://beaconcha.in/api/v1/execution/gasnow',
51 {
52 method: 'get',
53 cache: 'no-cache',
54 }
55 ),
56 fetch(
57 `${providerUrl}/v2/api` +
58 '?module=gastracker' +
59 '&action=gasoracle' +
60 '&apikey=CG52E4R96W56GIKUI4IJ8CH9EZIXPUW1W8' +
61 '&chainid=1',
62 {
63 method: 'GET',
64 cache: 'no-cache',
65 }
66 ),
67 ]);
69 const [feeJson, baseFeeJson] = await Promise.all([
70 feeResponse.json(),
71 baseFeeResponse.json(),
72 ]);
74 const suggestedBaseFeePerGas = Number(baseFeeJson.result.suggestBaseFee);
76 // Calculations derived from:
77 // https://www.blocknative.com/blog/eip-1559-fees
78 return {
79 fast: {
80 price: minGas(weiToGwei(feeJson.data.rapid)),
81 wait: formatWait(15),
82 maxFeePerGas: weiToGwei(feeJson.data.rapid),
83 maxPriorityFeePerGas: feeToInt(
84 weiToGwei(feeJson.data.rapid) - suggestedBaseFeePerGas
85 )
86 },
87 average: {
88 price: minGas(weiToGwei(feeJson.data.fast)),
89 wait: formatWait(60),
90 maxFeePerGas: weiToGwei(feeJson.data.fast),
91 maxPriorityFeePerGas: feeToInt(
92 weiToGwei(feeJson.data.fast) - suggestedBaseFeePerGas
93 )
94 },
95 low: {
96 price: minGas(weiToGwei(feeJson.data.slow)),
97 wait: formatWait(180),
98 maxFeePerGas: weiToGwei(feeJson.data.slow),
99 maxPriorityFeePerGas: feeToInt(
100 weiToGwei(feeJson.data.slow) - suggestedBaseFeePerGas
101 )
102 },
103 };
104 } catch (e) {
105 console.warn(e);
106 return defaultGasValues(DEFAULT_GAS_PRICE_GWEI);
107 }
108};
110export default async function getSuggestedGasPrice(networkType) {
111 switch (networkType) {
112 case NETWORK_TYPES.GOERLI:
113 return getGasForNetwork('https://api-goerli.etherscan.io');
114 case NETWORK_TYPES.OFFLINE:
115 return defaultGasValues(DEFAULT_GAS_PRICE_GWEI);
116 case NETWORK_TYPES.LOCAL:
117 default:
118 return getGasForNetwork('https://api.etherscan.io');
119 }