Merge branch 'develop' into feature/trace-tx

This commit is contained in:
Willian Mitsuda 2021-11-07 09:15:02 -03:00
commit 00ecea2c54
8 changed files with 139 additions and 131 deletions

View File

@ -1,9 +1,8 @@
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight";
import AddressHighlighter from "./components/AddressHighlighter";
import TransactionAddress from "./components/TransactionAddress";
import ValueHighlighter from "./components/ValueHighlighter";
import DecoratedAddressLink from "./components/DecoratedAddressLink";
import FormattedBalance from "./components/FormattedBalance";
import {
AddressContext,
@ -34,27 +33,19 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({
<div className="grid grid-cols-5 gap-x-1">
<div className="flex space-x-1">
<span className="font-bold">From</span>
<AddressHighlighter address={t.from}>
<DecoratedAddressLink
address={t.from}
addressCtx={AddressContext.FROM}
txFrom={t.from === txData.from}
txTo={t.from === txData.to}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<TransactionAddress
address={t.from}
addressCtx={AddressContext.FROM}
resolvedAddresses={resolvedAddresses}
/>
</div>
<div className="flex space-x-1">
<span className="font-bold">To</span>
<AddressHighlighter address={t.to}>
<DecoratedAddressLink
address={t.to}
addressCtx={AddressContext.TO}
txFrom={t.to === txData.from}
txTo={t.to === txData.to}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<TransactionAddress
address={t.to}
addressCtx={AddressContext.TO}
resolvedAddresses={resolvedAddresses}
/>
</div>
<div className="col-span-3 flex space-x-1">
<span className="font-bold">For</span>
@ -66,12 +57,10 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({
/>
</ValueHighlighter>
</span>
<AddressHighlighter address={t.token}>
<DecoratedAddressLink
address={t.token}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
<TransactionAddress
address={t.token}
resolvedAddresses={resolvedAddresses}
/>
</div>
</div>
</div>

View File

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

View File

@ -0,0 +1,38 @@
import React from "react";
import AddressHighlighter from "./AddressHighlighter";
import DecoratedAddressLink from "./DecoratedAddressLink";
import { ResolvedAddresses } from "../api/address-resolver";
import { useSelectedTransaction } from "../useSelectedTransaction";
import { AddressContext } from "../types";
type TransactionAddressProps = {
address: string;
addressCtx?: AddressContext | undefined;
resolvedAddresses: ResolvedAddresses | undefined;
};
const TransactionAddress: React.FC<TransactionAddressProps> = ({
address,
addressCtx,
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}
addressCtx={addressCtx}
miner={address === txData?.confirmedData?.miner}
txFrom={address === txData?.from}
txTo={address === txData?.to || creation}
creation={creation}
resolvedAddresses={resolvedAddresses}
/>
</AddressHighlighter>
);
};
export default TransactionAddress;

View File

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

View File

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

View File

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

View File

@ -77,7 +77,6 @@ const DecodedParamRow: React.FC<DecodedParamRowProps> = ({
) : paramType.baseType === "address" ? (
<AddressDecoder
r={r.toString()}
txContext={txContext}
resolvedAddresses={resolvedAddresses}
/>
) : paramType.baseType === "bool" ? (

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);