import React, { useContext, useMemo, useState } from "react"; import { Tab } from "@headlessui/react"; import { TransactionDescription } from "@ethersproject/abi"; import { BigNumber } from "@ethersproject/bignumber"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCheckCircle } from "@fortawesome/free-solid-svg-icons/faCheckCircle"; import { faCube } from "@fortawesome/free-solid-svg-icons/faCube"; import { faTimesCircle } from "@fortawesome/free-solid-svg-icons/faTimesCircle"; import ContentFrame from "../ContentFrame"; import InfoRow from "../components/InfoRow"; import BlockLink from "../components/BlockLink"; import ModeTab from "../components/ModeTab"; import ExpanderSwitch from "../components/ExpanderSwitch"; import BlockConfirmations from "../components/BlockConfirmations"; import TransactionAddress from "../components/TransactionAddress"; import Copy from "../components/Copy"; import Nonce from "../components/Nonce"; import NavNonce from "./NavNonce"; import Timestamp from "../components/Timestamp"; import InternalTransactionOperation from "../components/InternalTransactionOperation"; import MethodName from "../components/MethodName"; import TransactionType from "../components/TransactionType"; import RewardSplit from "./RewardSplit"; import GasValue from "../components/GasValue"; import USDValue from "../components/USDValue"; import FormattedBalance from "../components/FormattedBalance"; import ETH2USDValue from "../components/ETH2USDValue"; import TokenTransferItem from "../TokenTransferItem"; import { TransactionData, InternalOperation, ChecksummedAddress, } from "../types"; import PercentageBar from "../components/PercentageBar"; import ExternalLink from "../components/ExternalLink"; import RelativePosition from "../components/RelativePosition"; import PercentagePosition from "../components/PercentagePosition"; import DecodedParamsTable from "./decoder/DecodedParamsTable"; import InputDecoder from "./decoder/InputDecoder"; import { extract4Bytes, use4Bytes, useTransactionDescription, } from "../use4Bytes"; import { DevDoc, Metadata, useError, UserDoc } from "../sourcify/useSourcify"; import { RuntimeContext } from "../useRuntime"; import { useContractsMetadata } from "../hooks"; import { useTransactionError } from "../useErigonHooks"; import { useChainInfo } from "../useChainInfo"; type DetailsProps = { txData: TransactionData; txDesc: TransactionDescription | null | undefined; toMetadata: Metadata | null | undefined; userDoc?: UserDoc | undefined; devDoc?: DevDoc | undefined; internalOps?: InternalOperation[]; sendsEthToMiner: boolean; ethUSDPrice: BigNumber | undefined; }; const Details: React.FC = ({ txData, txDesc, toMetadata, userDoc, devDoc, internalOps, sendsEthToMiner, ethUSDPrice, }) => { const hasEIP1559 = txData.confirmedData?.blockBaseFeePerGas !== undefined && txData.confirmedData?.blockBaseFeePerGas !== null; const fourBytes = txData.to !== null ? extract4Bytes(txData.data) ?? "0x" : "0x"; const fourBytesEntry = use4Bytes(fourBytes); const fourBytesTxDesc = useTransactionDescription( fourBytesEntry, txData.data, txData.value ); const resolvedTxDesc = txDesc ?? fourBytesTxDesc; const userMethod = txDesc ? userDoc?.methods[txDesc.signature] : undefined; const devMethod = txDesc ? devDoc?.methods[txDesc.signature] : undefined; const { provider } = useContext(RuntimeContext); const { nativeName, nativeSymbol } = useChainInfo(); const addresses = useMemo(() => { const _addresses: ChecksummedAddress[] = []; if (txData.to) { _addresses.push(txData.to); } if (txData.confirmedData?.createdContractAddress) { _addresses.push(txData.confirmedData.createdContractAddress); } for (const t of txData.tokenTransfers) { _addresses.push(t.from); _addresses.push(t.to); _addresses.push(t.token); } return _addresses; }, [txData]); const metadatas = useContractsMetadata(addresses, provider); const [errorMsg, outputData, isCustomError] = useTransactionError( provider, txData.transactionHash ); const errorDescription = useError( toMetadata, isCustomError ? outputData : undefined ); const userError = errorDescription ? userDoc?.errors?.[errorDescription.signature]?.[0] : undefined; const devError = errorDescription ? devDoc?.errors?.[errorDescription.signature]?.[0] : undefined; const [expanded, setExpanded] = useState(false); return (
{txData.transactionHash}
{txData.confirmedData === undefined ? ( Pending ) : txData.confirmedData.status ? ( Success ) : ( <>
Fail {errorMsg && ( <> {" "} with revert message: ' {errorMsg}' )} {isCustomError && ( <> {" "} with custom error {errorDescription && ( <> {" '"} {errorDescription.name} {"'"} )} )}
{isCustomError && ( )}
{expanded && ( Decoded Raw {errorDescription === undefined ? ( <>Waiting for data... ) : errorDescription === null ? ( <>Can't decode data ) : errorDescription.args.length === 0 ? ( <>No parameters ) : ( )}