Extract utility component TransactionAddress

This commit is contained in:
Willian Mitsuda 2021-11-07 08:21:56 -03:00
parent e2ba28b64e
commit b723182ad3
7 changed files with 117 additions and 105 deletions

View File

@ -15,6 +15,7 @@ import {
transactionDataCollector, transactionDataCollector,
useResolvedAddresses, useResolvedAddresses,
} from "./useResolvedAddresses"; } from "./useResolvedAddresses";
import { SelectedTransactionContext } from "./useSelectedTransaction";
const Details = React.lazy( const Details = React.lazy(
() => () =>
@ -76,54 +77,56 @@ const Transaction: React.FC = () => {
const txDesc = useTransactionDescription(metadata, txData); const txDesc = useTransactionDescription(metadata, txData);
return ( return (
<StandardFrame> <SelectedTransactionContext.Provider value={txData}>
<StandardSubtitle>Transaction Details</StandardSubtitle> <StandardFrame>
{txData === null && ( <StandardSubtitle>Transaction Details</StandardSubtitle>
<ContentFrame> {txData === null && (
<div className="py-4 text-sm"> <ContentFrame>
Transaction <span className="font-hash">{txhash}</span> not found. <div className="py-4 text-sm">
</div> Transaction <span className="font-hash">{txhash}</span> not found.
</ContentFrame> </div>
)} </ContentFrame>
{txData && ( )}
<SelectionContext.Provider value={selectionCtx}> {txData && (
<Tab.Group> <SelectionContext.Provider value={selectionCtx}>
<Tab.List className="flex space-x-2 border-l border-r border-t rounded-t-lg bg-white"> <Tab.Group>
<NavTab href={`/tx/${txhash}`}>Overview</NavTab> <Tab.List className="flex space-x-2 border-l border-r border-t rounded-t-lg bg-white">
{txData.confirmedData?.blockNumber !== undefined && ( <NavTab href={`/tx/${txhash}`}>Overview</NavTab>
<NavTab href={`/tx/${txhash}/logs`}> {txData.confirmedData?.blockNumber !== undefined && (
Logs <NavTab href={`/tx/${txhash}/logs`}>
{txData && ` (${txData.confirmedData?.logs?.length ?? 0})`} Logs
</NavTab> {txData && ` (${txData.confirmedData?.logs?.length ?? 0})`}
)} </NavTab>
</Tab.List> )}
</Tab.Group> </Tab.List>
<React.Suspense fallback={null}> </Tab.Group>
<Switch> <React.Suspense fallback={null}>
<Route path="/tx/:txhash/" exact> <Switch>
<Details <Route path="/tx/:txhash/" exact>
txData={txData} <Details
txDesc={txDesc} txData={txData}
userDoc={metadata?.output.userdoc} txDesc={txDesc}
devDoc={metadata?.output.devdoc} userDoc={metadata?.output.userdoc}
internalOps={internalOps} devDoc={metadata?.output.devdoc}
sendsEthToMiner={sendsEthToMiner} internalOps={internalOps}
ethUSDPrice={blockETHUSDPrice} sendsEthToMiner={sendsEthToMiner}
resolvedAddresses={resolvedAddresses} ethUSDPrice={blockETHUSDPrice}
/> resolvedAddresses={resolvedAddresses}
</Route> />
<Route path="/tx/:txhash/logs/" exact> </Route>
<Logs <Route path="/tx/:txhash/logs/" exact>
txData={txData} <Logs
metadata={metadata} txData={txData}
resolvedAddresses={resolvedAddresses} metadata={metadata}
/> resolvedAddresses={resolvedAddresses}
</Route> />
</Switch> </Route>
</React.Suspense> </Switch>
</SelectionContext.Provider> </React.Suspense>
)} </SelectionContext.Provider>
</StandardFrame> )}
</StandardFrame>
</SelectedTransactionContext.Provider>
); );
}; };

View File

@ -0,0 +1,34 @@
import React from "react";
import AddressHighlighter from "./AddressHighlighter";
import DecoratedAddressLink from "./DecoratedAddressLink";
import { ResolvedAddresses } from "../api/address-resolver";
import { useSelectedTransaction } from "../useSelectedTransaction";
type TransactionAddressProps = {
address: string;
resolvedAddresses: ResolvedAddresses | undefined;
};
const TransactionAddress: React.FC<TransactionAddressProps> = ({
address,
resolvedAddresses,
}) => {
const txData = useSelectedTransaction();
// TODO: push down creation coloring logic into DecoratedAddressLink
const creation = address === txData?.confirmedData?.createdContractAddress;
return (
<AddressHighlighter address={address}>
<DecoratedAddressLink
address={address}
miner={address === txData?.confirmedData?.miner}
txFrom={address === txData?.from}
txTo={address === txData?.to || creation}
creation={creation}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
);
};
export default TransactionAddress;

View File

@ -15,8 +15,7 @@ import ContentFrame from "../ContentFrame";
import InfoRow from "../components/InfoRow"; import InfoRow from "../components/InfoRow";
import BlockLink from "../components/BlockLink"; import BlockLink from "../components/BlockLink";
import BlockConfirmations from "../components/BlockConfirmations"; import BlockConfirmations from "../components/BlockConfirmations";
import AddressHighlighter from "../components/AddressHighlighter"; import TransactionAddress from "../components/TransactionAddress";
import DecoratedAddressLink from "../components/DecoratedAddressLink";
import Copy from "../components/Copy"; import Copy from "../components/Copy";
import Nonce from "../components/Nonce"; import Nonce from "../components/Nonce";
import Timestamp from "../components/Timestamp"; import Timestamp from "../components/Timestamp";
@ -152,14 +151,10 @@ const Details: React.FC<DetailsProps> = ({
<InfoRow title="From / Nonce"> <InfoRow title="From / Nonce">
<div className="flex divide-x-2 divide-dotted divide-gray-300"> <div className="flex divide-x-2 divide-dotted divide-gray-300">
<div className="flex items-baseline space-x-2 -ml-1 mr-3"> <div className="flex items-baseline space-x-2 -ml-1 mr-3">
<AddressHighlighter address={txData.from}> <TransactionAddress
<DecoratedAddressLink address={txData.from}
address={txData.from} resolvedAddresses={resolvedAddresses}
miner={txData.from === txData.confirmedData?.miner} />
txFrom
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<Copy value={txData.from} /> <Copy value={txData.from} />
</div> </div>
<div className="flex items-baseline pl-3"> <div className="flex items-baseline pl-3">
@ -170,14 +165,10 @@ const Details: React.FC<DetailsProps> = ({
<InfoRow title={txData.to ? "Interacted With (To)" : "Contract Created"}> <InfoRow title={txData.to ? "Interacted With (To)" : "Contract Created"}>
{txData.to ? ( {txData.to ? (
<div className="flex items-baseline space-x-2 -ml-1"> <div className="flex items-baseline space-x-2 -ml-1">
<AddressHighlighter address={txData.to}> <TransactionAddress
<DecoratedAddressLink address={txData.to}
address={txData.to} resolvedAddresses={resolvedAddresses}
miner={txData.to === txData.confirmedData?.miner} />
txTo
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<Copy value={txData.to} /> <Copy value={txData.to} />
</div> </div>
) : txData.confirmedData === undefined ? ( ) : txData.confirmedData === undefined ? (
@ -186,16 +177,10 @@ const Details: React.FC<DetailsProps> = ({
</span> </span>
) : ( ) : (
<div className="flex items-baseline space-x-2 -ml-1"> <div className="flex items-baseline space-x-2 -ml-1">
<AddressHighlighter <TransactionAddress
address={txData.confirmedData?.createdContractAddress!} address={txData.confirmedData?.createdContractAddress!}
> resolvedAddresses={resolvedAddresses}
<DecoratedAddressLink />
address={txData.confirmedData.createdContractAddress!}
creation
txTo
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<Copy value={txData.confirmedData.createdContractAddress!} /> <Copy value={txData.confirmedData.createdContractAddress!} />
</div> </div>
)} )}

View File

@ -2,8 +2,7 @@ import React, { useMemo } from "react";
import { Log } from "@ethersproject/abstract-provider"; import { Log } from "@ethersproject/abstract-provider";
import { Fragment, Interface, LogDescription } from "@ethersproject/abi"; import { Fragment, Interface, LogDescription } from "@ethersproject/abi";
import { Tab } from "@headlessui/react"; import { Tab } from "@headlessui/react";
import AddressHighlighter from "../components/AddressHighlighter"; import TransactionAddress from "../components/TransactionAddress";
import DecoratedAddressLink from "../components/DecoratedAddressLink";
import Copy from "../components/Copy"; import Copy from "../components/Copy";
import ModeTab from "../components/ModeTab"; import ModeTab from "../components/ModeTab";
import DecodedParamsTable from "./decoder/DecodedParamsTable"; import DecodedParamsTable from "./decoder/DecodedParamsTable";
@ -63,15 +62,10 @@ const LogEntry: React.FC<LogEntryProps> = ({
<div className="font-bold text-right">Address</div> <div className="font-bold text-right">Address</div>
<div className="col-span-11 mr-auto"> <div className="col-span-11 mr-auto">
<div className="flex items-baseline space-x-2 -ml-1 mr-3"> <div className="flex items-baseline space-x-2 -ml-1 mr-3">
<AddressHighlighter address={log.address}> <TransactionAddress
<DecoratedAddressLink address={log.address}
address={log.address} resolvedAddresses={resolvedAddresses}
miner={log.address === txData.confirmedData?.miner} />
txFrom={log.address === txData.from}
txTo={log.address === txData.to}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<Copy value={log.address} /> <Copy value={log.address} />
</div> </div>
</div> </div>

View File

@ -1,31 +1,22 @@
import React from "react"; import React from "react";
import AddressHighlighter from "../../components/AddressHighlighter";
import DecoratedAddressLink from "../../components/DecoratedAddressLink";
import Copy from "../../components/Copy"; import Copy from "../../components/Copy";
import { TransactionData } from "../../types";
import { ResolvedAddresses } from "../../api/address-resolver"; import { ResolvedAddresses } from "../../api/address-resolver";
import TransactionAddress from "../../components/TransactionAddress";
type AddressDecoderProps = { type AddressDecoderProps = {
r: any; r: any;
txData: TransactionData;
resolvedAddresses?: ResolvedAddresses | undefined; resolvedAddresses?: ResolvedAddresses | undefined;
}; };
const AddressDecoder: React.FC<AddressDecoderProps> = ({ const AddressDecoder: React.FC<AddressDecoderProps> = ({
r, r,
txData,
resolvedAddresses, resolvedAddresses,
}) => ( }) => (
<div className="flex items-baseline space-x-2 -ml-1 mr-3"> <div className="flex items-baseline space-x-2 -ml-1 mr-3">
<AddressHighlighter address={r.toString()}> <TransactionAddress
<DecoratedAddressLink address={r.toString()}
address={r.toString()} resolvedAddresses={resolvedAddresses}
miner={r.toString() === txData.confirmedData?.miner} />
txFrom={r.toString() === txData.from}
txTo={r.toString() === txData.to}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<Copy value={r.toString()} /> <Copy value={r.toString()} />
</div> </div>
); );

View File

@ -75,11 +75,7 @@ const DecodedParamRow: React.FC<DecodedParamRowProps> = ({
{paramType.baseType === "uint256" ? ( {paramType.baseType === "uint256" ? (
<Uint256Decoder r={r} /> <Uint256Decoder r={r} />
) : paramType.baseType === "address" ? ( ) : paramType.baseType === "address" ? (
<AddressDecoder <AddressDecoder r={r} resolvedAddresses={resolvedAddresses} />
r={r}
txData={txData}
resolvedAddresses={resolvedAddresses}
/>
) : paramType.baseType === "bool" ? ( ) : paramType.baseType === "bool" ? (
<BooleanDecoder r={r} /> <BooleanDecoder r={r} />
) : paramType.baseType === "bytes" ? ( ) : paramType.baseType === "bytes" ? (

View File

@ -0,0 +1,9 @@
import { createContext, useContext } from "react";
import { TransactionData } from "./types";
export const SelectedTransactionContext = createContext<
TransactionData | null | undefined
>(undefined);
export const useSelectedTransaction = () =>
useContext(SelectedTransactionContext);