diff --git a/src/Block.tsx b/src/Block.tsx index 3064c99..00ca0dc 100644 --- a/src/Block.tsx +++ b/src/Block.tsx @@ -1,6 +1,6 @@ -import React, { useEffect, useState, useMemo, useContext } from "react"; +import React, { useEffect, useMemo, useContext } from "react"; import { useParams, NavLink } from "react-router-dom"; -import { ethers, BigNumber } from "ethers"; +import { ethers } from "ethers"; import StandardFrame from "./StandardFrame"; import StandardSubtitle from "./StandardSubtitle"; import NavBlock from "./block/NavBlock"; @@ -14,79 +14,17 @@ import HexValue from "./components/HexValue"; import { RuntimeContext } from "./useRuntime"; import { useLatestBlockNumber } from "./useLatestBlock"; import { blockTxsURL } from "./url"; +import { useBlockData } from "./useErigonHooks"; type BlockParams = { blockNumberOrHash: string; }; -interface ExtendedBlock extends ethers.providers.Block { - blockReward: BigNumber; - unclesReward: BigNumber; - feeReward: BigNumber; - size: number; - sha3Uncles: string; - stateRoot: string; - totalDifficulty: BigNumber; -} - const Block: React.FC = () => { const { provider } = useContext(RuntimeContext); const params = useParams(); - const [block, setBlock] = useState(); - useEffect(() => { - if (!provider) { - return; - } - - const readBlock = async () => { - let blockPromise: Promise; - if (ethers.utils.isHexString(params.blockNumberOrHash, 32)) { - blockPromise = provider.send("eth_getBlockByHash", [ - params.blockNumberOrHash, - false, - ]); - } else { - blockPromise = provider.send("eth_getBlockByNumber", [ - params.blockNumberOrHash, - false, - ]); - } - const [_rawBlock, _rawIssuance, _rawReceipts] = await Promise.all([ - blockPromise, - provider.send("erigon_issuance", [params.blockNumberOrHash]), - provider.send("eth_getBlockReceipts", [params.blockNumberOrHash]), - ]); - const receipts = (_rawReceipts as any[]).map((r) => - provider.formatter.receipt(r) - ); - const fees = receipts.reduce( - (acc, r) => acc.add(r.effectiveGasPrice.mul(r.gasUsed)), - BigNumber.from(0) - ); - - const _block = provider.formatter.block(_rawBlock); - const extBlock: ExtendedBlock = { - blockReward: provider.formatter.bigNumber( - _rawIssuance.blockReward ?? 0 - ), - unclesReward: provider.formatter.bigNumber( - _rawIssuance.uncleReward ?? 0 - ), - feeReward: fees, - size: provider.formatter.number(_rawBlock.size), - sha3Uncles: _rawBlock.sha3Uncles, - stateRoot: _rawBlock.stateRoot, - totalDifficulty: provider.formatter.bigNumber( - _rawBlock.totalDifficulty - ), - ..._block, - }; - setBlock(extBlock); - }; - readBlock(); - }, [provider, params.blockNumberOrHash]); - + const block = useBlockData(provider, params.blockNumberOrHash); useEffect(() => { if (block) { document.title = `Block #${block.number} | Otterscan`; diff --git a/src/useErigonHooks.ts b/src/useErigonHooks.ts index 50d4bf3..ecbda33 100644 --- a/src/useErigonHooks.ts +++ b/src/useErigonHooks.ts @@ -1,8 +1,79 @@ -import { ethers } from "ethers"; +import { ethers, BigNumber } from "ethers"; import { useState, useEffect } from "react"; import { getInternalOperations } from "./nodeFunctions"; import { TransactionData, InternalOperation } from "./types"; +export interface ExtendedBlock extends ethers.providers.Block { + blockReward: BigNumber; + unclesReward: BigNumber; + feeReward: BigNumber; + size: number; + sha3Uncles: string; + stateRoot: string; + totalDifficulty: BigNumber; +} + +export const useBlockData = ( + provider: ethers.providers.JsonRpcProvider | undefined, + blockNumberOrHash: string +) => { + const [block, setBlock] = useState(); + useEffect(() => { + if (!provider) { + return; + } + + const readBlock = async () => { + let blockPromise: Promise; + if (ethers.utils.isHexString(blockNumberOrHash, 32)) { + blockPromise = provider.send("eth_getBlockByHash", [ + blockNumberOrHash, + false, + ]); + } else { + blockPromise = provider.send("eth_getBlockByNumber", [ + blockNumberOrHash, + false, + ]); + } + const [_rawBlock, _rawIssuance, _rawReceipts] = await Promise.all([ + blockPromise, + provider.send("erigon_issuance", [blockNumberOrHash]), + provider.send("eth_getBlockReceipts", [blockNumberOrHash]), + ]); + const receipts = (_rawReceipts as any[]).map((r) => + provider.formatter.receipt(r) + ); + const fees = receipts.reduce( + (acc, r) => acc.add(r.effectiveGasPrice.mul(r.gasUsed)), + BigNumber.from(0) + ); + + const _block = provider.formatter.block(_rawBlock); + const extBlock: ExtendedBlock = { + blockReward: provider.formatter.bigNumber( + _rawIssuance.blockReward ?? 0 + ), + unclesReward: provider.formatter.bigNumber( + _rawIssuance.uncleReward ?? 0 + ), + feeReward: fees, + size: provider.formatter.number(_rawBlock.size), + sha3Uncles: _rawBlock.sha3Uncles, + stateRoot: _rawBlock.stateRoot, + totalDifficulty: provider.formatter.bigNumber( + _rawBlock.totalDifficulty + ), + ..._block, + }; + setBlock(extBlock); + }; + readBlock(); + }, [provider, blockNumberOrHash]); + + return block; +}; + export const useInternalOperations = ( provider: ethers.providers.JsonRpcProvider | undefined, txData: TransactionData | undefined