import React, { useState, useEffect, useContext, useMemo, useCallback, } from "react"; import { Block } from "@ethersproject/abstract-provider"; import { FixedNumber } from "@ethersproject/bignumber"; import { Line } from "react-chartjs-2"; import { Chart as ChartJS, LinearScale, CategoryScale, PointElement, LineElement, Filler, Tooltip, } from "chart.js"; import { Transition } from "@headlessui/react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn"; import { faCoins } from "@fortawesome/free-solid-svg-icons/faCoins"; import { faCube } from "@fortawesome/free-solid-svg-icons/faCube"; import { faGasPump } from "@fortawesome/free-solid-svg-icons/faGasPump"; import { faHistory } from "@fortawesome/free-solid-svg-icons/faHistory"; import BlockRow from "./BlockRow"; import { ExtendedBlock, readBlock } from "../../useErigonHooks"; import { RuntimeContext } from "../../useRuntime"; import { burntFeesChartOptions, burntFeesChartData, gasChartOptions, gasChartData, } from "./chart"; ChartJS.register( LinearScale, CategoryScale, PointElement, LineElement, Filler, Tooltip ); const MAX_BLOCK_HISTORY = 20; const PREV_BLOCK_COUNT = 15; type BlocksProps = { latestBlock: Block; targetBlockNumber: number; }; const Blocks: React.FC = ({ latestBlock, targetBlockNumber }) => { const { provider } = useContext(RuntimeContext); const [blocks, setBlocks] = useState([]); const [now, setNow] = useState(Date.now()); const [toggleChart, setToggleChart] = useState(true); const addBlock = useCallback( async (blockNumber: number) => { if (!provider) { return; } // Skip blocks before the hard fork during the transition if (blockNumber < targetBlockNumber) { return; } const extBlock = await readBlock(provider, blockNumber.toString()); setNow(Date.now()); setBlocks((_blocks) => { if (_blocks.length > 0 && blockNumber === _blocks[0].number) { return _blocks; } if (extBlock === null) { return _blocks; } // Leave the last block because of transition animation const newBlocks = [extBlock, ..._blocks].slice( 0, MAX_BLOCK_HISTORY + 1 ); // Little hack to fix out of order block notifications newBlocks.sort((a, b) => b.number - a.number); return newBlocks; }); }, [provider, targetBlockNumber] ); useEffect(() => { addBlock(latestBlock.number); }, [addBlock, latestBlock]); const data = useMemo( () => (toggleChart ? gasChartData(blocks) : burntFeesChartData(blocks)), [toggleChart, blocks] ); const chartOptions = toggleChart ? gasChartOptions : burntFeesChartOptions; // On page reload, pre-populate the last N blocks useEffect( () => { const addPreviousBlocks = async () => { for ( let i = latestBlock.number - PREV_BLOCK_COUNT; i < latestBlock.number; i++ ) { await addBlock(i); } }; setBlocks([]); addPreviousBlocks(); }, // eslint-disable-next-line react-hooks/exhaustive-deps [] ); return (
EIP-1559 is activated. Watch the fees burn.
Block
Gas used
Gas target
Base fee
Rewards
Burnt fees
Age
{blocks.map((b, i, all) => ( ))}
); }; export default React.memo(Blocks);