Split block confirmation data into its own hook

This commit is contained in:
Willian Mitsuda 2022-08-24 04:34:41 -03:00
parent 34f812aed0
commit e3a21bd4b2
No known key found for this signature in database
7 changed files with 67 additions and 60 deletions

View File

@ -1,10 +1,12 @@
import React from "react";
import React, { useContext } from "react";
import { formatEther } from "@ethersproject/units";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight";
import AddressHighlighter from "./AddressHighlighter";
import DecoratedAddressLink from "./DecoratedAddressLink";
import TransactionAddress from "./TransactionAddress";
import { RuntimeContext } from "../useRuntime";
import { useBlockDataFromTransaction } from "../useErigonHooks";
import { useChainInfo } from "../useChainInfo";
import { TransactionData, InternalOperation } from "../types";
@ -17,12 +19,12 @@ const InternalSelfDestruct: React.FC<InternalSelfDestructProps> = ({
txData,
internalOp,
}) => {
const { provider } = useContext(RuntimeContext);
const block = useBlockDataFromTransaction(provider, txData);
const {
nativeCurrency: { symbol },
} = useChainInfo();
const toMiner =
txData.confirmedData?.miner !== undefined &&
internalOp.to === txData.confirmedData.miner;
const toMiner = block?.miner !== undefined && internalOp.to === block.miner;
return (
<>

View File

@ -8,7 +8,7 @@ import AddressHighlighter from "./AddressHighlighter";
import DecoratedAddressLink from "./DecoratedAddressLink";
import USDAmount from "./USDAmount";
import { RuntimeContext } from "../useRuntime";
import { useHasCode } from "../useErigonHooks";
import { useBlockDataFromTransaction, useHasCode } from "../useErigonHooks";
import { useChainInfo } from "../useChainInfo";
import { useETHUSDOracle } from "../usePriceOracle";
import { TransactionData, InternalOperation } from "../types";
@ -22,17 +22,16 @@ const InternalTransfer: React.FC<InternalTransferProps> = ({
txData,
internalOp,
}) => {
const { provider } = useContext(RuntimeContext);
const block = useBlockDataFromTransaction(provider, txData);
const {
nativeCurrency: { symbol, decimals },
} = useChainInfo();
const fromMiner =
txData.confirmedData?.miner !== undefined &&
internalOp.from === txData.confirmedData.miner;
const toMiner =
txData.confirmedData?.miner !== undefined &&
internalOp.to === txData.confirmedData.miner;
block?.miner !== undefined && internalOp.from === block.miner;
const toMiner = block?.miner !== undefined && internalOp.to === block.miner;
const { provider } = useContext(RuntimeContext);
const blockETHUSDPrice = useETHUSDOracle(
provider,
txData.confirmedData?.blockNumber

View File

@ -4,7 +4,7 @@ import DecoratedAddressLink from "./DecoratedAddressLink";
import { useSelectedTransaction } from "../useSelectedTransaction";
import { useBlockNumberContext } from "../useBlockTagContext";
import { RuntimeContext } from "../useRuntime";
import { useHasCode } from "../useErigonHooks";
import { useBlockDataFromTransaction, useHasCode } from "../useErigonHooks";
import { AddressContext, ChecksummedAddress } from "../types";
type TransactionAddressProps = {
@ -23,6 +23,8 @@ const TransactionAddress: React.FC<TransactionAddressProps> = ({
const creation = address === txData?.confirmedData?.createdContractAddress;
const { provider } = useContext(RuntimeContext);
const block = useBlockDataFromTransaction(provider, txData);
const blockNumber = useBlockNumberContext();
const toHasCode = useHasCode(
provider,
@ -39,7 +41,7 @@ const TransactionAddress: React.FC<TransactionAddressProps> = ({
<DecoratedAddressLink
address={address}
addressCtx={addressCtx}
miner={address === txData?.confirmedData?.miner}
miner={address === block?.miner}
txFrom={address === txData?.from}
txTo={address === txData?.to || creation}
creation={creation}

View File

@ -44,6 +44,7 @@ import {
} from "../sourcify/useSourcify";
import { RuntimeContext } from "../useRuntime";
import {
useBlockDataFromTransaction,
useSendsToMiner,
useTokenTransfers,
useTransactionError,
@ -57,10 +58,10 @@ type DetailsProps = {
const Details: React.FC<DetailsProps> = ({ txData }) => {
const { provider } = useContext(RuntimeContext);
const block = useBlockDataFromTransaction(provider, txData);
const hasEIP1559 =
txData.confirmedData?.blockBaseFeePerGas !== undefined &&
txData.confirmedData?.blockBaseFeePerGas !== null;
block?.baseFeePerGas !== undefined && block?.baseFeePerGas !== null;
const fourBytes =
txData.to !== null ? extract4Bytes(txData.data) ?? "0x" : "0x";
@ -74,7 +75,7 @@ const Details: React.FC<DetailsProps> = ({ txData }) => {
const [sendsEthToMiner, internalOps] = useSendsToMiner(
provider,
txData.confirmedData ? txData.transactionHash : undefined,
txData.confirmedData?.miner
block?.miner
);
const tokenTransfers = useTokenTransfers(txData);
@ -222,22 +223,24 @@ const Details: React.FC<DetailsProps> = ({ txData }) => {
confirmations={txData.confirmedData.confirmations}
/>
</div>
<div className="flex space-x-2 items-baseline pl-3">
<RelativePosition
pos={txData.confirmedData.transactionIndex}
total={txData.confirmedData.blockTransactionCount - 1}
/>
<PercentagePosition
perc={
txData.confirmedData.transactionIndex /
(txData.confirmedData.blockTransactionCount - 1)
}
/>
</div>
{block && (
<div className="flex space-x-2 items-baseline pl-3">
<RelativePosition
pos={txData.confirmedData.transactionIndex}
total={block.transactionCount - 1}
/>
<PercentagePosition
perc={
txData.confirmedData.transactionIndex /
(block.transactionCount - 1)
}
/>
</div>
)}
</div>
</InfoRow>
<InfoRow title="Timestamp">
<Timestamp value={txData.confirmedData.timestamp} />
{block && <Timestamp value={block.timestamp} />}
</InfoRow>
</>
)}
@ -366,18 +369,10 @@ const Details: React.FC<DetailsProps> = ({ txData }) => {
</div>
</InfoRow>
)}
{txData.confirmedData && hasEIP1559 && (
{block && hasEIP1559 && (
<InfoRow title="Block Base Fee">
<FormattedBalance
value={txData.confirmedData.blockBaseFeePerGas!}
decimals={9}
/>{" "}
Gwei (
<FormattedBalance
value={txData.confirmedData.blockBaseFeePerGas!}
decimals={0}
/>{" "}
wei)
<FormattedBalance value={block.baseFeePerGas!} decimals={9} /> Gwei (
<FormattedBalance value={block.baseFeePerGas!} decimals={0} /> wei)
</InfoRow>
)}
{txData.confirmedData && (

View File

@ -1,24 +1,30 @@
import React from "react";
import React, { useContext } from "react";
import { BigNumber } from "@ethersproject/bignumber";
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 FormattedBalance from "../components/FormattedBalance";
import PercentageGauge from "../components/PercentageGauge";
import { TransactionData } from "../types";
import { RuntimeContext } from "../useRuntime";
import { useBlockDataFromTransaction } from "../useErigonHooks";
import { useChainInfo } from "../useChainInfo";
import { TransactionData } from "../types";
type RewardSplitProps = {
txData: TransactionData;
};
const RewardSplit: React.FC<RewardSplitProps> = ({ txData }) => {
const { provider } = useContext(RuntimeContext);
const block = useBlockDataFromTransaction(provider, txData);
const {
nativeCurrency: { symbol },
} = useChainInfo();
const paidFees = txData.gasPrice.mul(txData.confirmedData!.gasUsed);
const burntFees = txData.confirmedData!.blockBaseFeePerGas!.mul(
txData.confirmedData!.gasUsed
);
const burntFees = block
? block.baseFeePerGas!.mul(txData.confirmedData!.gasUsed)
: BigNumber.from(0);
const minerReward = paidFees.sub(burntFees);
const burntPerc =

View File

@ -50,11 +50,7 @@ export type ConfirmedTransactionData = {
status: boolean;
blockNumber: number;
transactionIndex: number;
blockBaseFeePerGas?: BigNumber | undefined | null;
blockTransactionCount: number;
confirmations: number;
timestamp: number;
miner: string;
createdContractAddress?: string;
fee: BigNumber;
gasUsed: BigNumber;

View File

@ -155,12 +155,15 @@ const blockDataFetcher = async (
return await readBlock(provider, blockNumberOrHash);
};
// TODO: some callers may use only block headers?
export const useBlockData = (
provider: JsonRpcProvider | undefined,
blockNumberOrHash: string
blockNumberOrHash: string | undefined
): ExtendedBlock | null | undefined => {
const { data, error } = useSWRImmutable(
provider !== undefined ? [provider, blockNumberOrHash] : null,
provider !== undefined && blockNumberOrHash !== undefined
? [provider, blockNumberOrHash]
: null,
blockDataFetcher
);
if (error) {
@ -169,6 +172,19 @@ export const useBlockData = (
return data;
};
export const useBlockDataFromTransaction = (
provider: JsonRpcProvider | undefined,
txData: TransactionData | null | undefined
): ExtendedBlock | null | undefined => {
const block = useBlockData(
provider,
txData?.confirmedData
? txData.confirmedData.blockNumber.toString()
: undefined
);
return block;
};
export const useTxData = (
provider: JsonRpcProvider | undefined,
txhash: string
@ -191,11 +207,6 @@ export const useTxData = (
return;
}
let _block: ExtendedBlock | null | undefined;
if (_response.blockNumber) {
_block = await readBlock(provider, _response.blockNumber.toString());
}
document.title = `Transaction ${_response.hash} | Otterscan`;
setTxData({
@ -217,11 +228,7 @@ export const useTxData = (
status: _receipt.status === 1,
blockNumber: _receipt.blockNumber,
transactionIndex: _receipt.transactionIndex,
blockBaseFeePerGas: _block!.baseFeePerGas,
blockTransactionCount: _block!.transactionCount,
confirmations: _receipt.confirmations,
timestamp: _block!.timestamp,
miner: _block!.miner,
createdContractAddress: _receipt.contractAddress,
fee: _response.gasPrice!.mul(_receipt.gasUsed),
gasUsed: _receipt.gasUsed,