2023-04-18 01:49:20 +00:00
|
|
|
import 'dotenv/config.js';
|
2023-04-21 22:51:09 +00:00
|
|
|
import { WebSocketProvider, formatUnits } from 'ethers';
|
|
|
|
import { Observable } from 'rxjs';
|
|
|
|
import { map, scan } from 'rxjs/operators';
|
|
|
|
|
|
|
|
import { GasPrices } from '../types/gasPrices';
|
|
|
|
|
|
|
|
const rpcUrl = process.env.RPC_URL || "wss://ropsten.infura.io/ws/v3/YOUR_INFURA_PROJECT_ID";
|
|
|
|
|
|
|
|
const provider = new WebSocketProvider(rpcUrl);
|
|
|
|
|
|
|
|
const blockGasPricesObservable = new Observable<GasPrices>((observer) => {
|
|
|
|
provider.on('block', async (blockNumber) => {
|
|
|
|
try {
|
|
|
|
const block = await provider.getBlock(blockNumber, true);
|
|
|
|
|
|
|
|
if (!block) throw new Error(`Error fetching block! ${blockNumber}`);
|
|
|
|
|
|
|
|
const gasPrices = block.prefetchedTransactions.map((tx) => tx.gasPrice);
|
|
|
|
const fast = Number(formatUnits(gasPrices[Math.floor(gasPrices.length * 0.9)], "gwei"));
|
|
|
|
const average = Number(formatUnits(gasPrices[Math.floor(gasPrices.length / 2)], "gwei"));
|
|
|
|
const slow = Number(formatUnits(gasPrices[Math.floor(gasPrices.length * 0.05)], "gwei"));
|
|
|
|
|
|
|
|
observer.next({ fast, average, slow } as GasPrices);
|
|
|
|
} catch (error) {
|
|
|
|
observer.error(`Error fetching block! ${error}`);
|
|
|
|
}
|
2023-04-18 20:35:09 +00:00
|
|
|
});
|
2023-04-21 22:51:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const averageGasPricesObservable = blockGasPricesObservable.pipe(
|
|
|
|
scan((acc, curr) => [...acc.slice(-19), curr], [] as GasPrices[]),
|
|
|
|
map((blocks) => {
|
|
|
|
const fastSum = blocks.reduce((sum, block) => sum + block.fast, 0);
|
|
|
|
const averageSum = blocks.reduce((sum, block) => sum + block.average, 0);
|
|
|
|
const slowSum = blocks.reduce((sum, block) => sum + block.slow, 0);
|
|
|
|
return {
|
|
|
|
fast: fastSum / blocks.length,
|
|
|
|
average: averageSum / blocks.length,
|
|
|
|
slow: slowSum / blocks.length,
|
|
|
|
};
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
export { averageGasPricesObservable };
|