otterscan/src/search/TransactionItem.tsx

150 lines
5.1 KiB
TypeScript
Raw Normal View History

2021-07-01 18:21:40 +00:00
import React from "react";
2021-08-31 19:49:52 +00:00
import { BlockTag } from "@ethersproject/abstract-provider";
import { BigNumber } from "@ethersproject/bignumber";
2021-07-01 18:21:40 +00:00
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons/faExclamationCircle";
2021-07-01 18:21:40 +00:00
import MethodName from "../components/MethodName";
import BlockLink from "../components/BlockLink";
import TransactionLink from "../components/TransactionLink";
import DecoratedAddressLink from "../components/DecoratedAddressLink";
2021-07-01 18:21:40 +00:00
import TimestampAge from "../components/TimestampAge";
import AddressHighlighter from "../components/AddressHighlighter";
2021-07-01 18:21:40 +00:00
import TransactionDirection, {
Direction,
Flags,
2021-07-01 18:21:40 +00:00
} from "../components/TransactionDirection";
import TransactionValue from "../components/TransactionValue";
import { ChecksummedAddress, ProcessedTransaction } from "../types";
2021-07-01 18:21:40 +00:00
import { FeeDisplay } from "./useFeeToggler";
import { formatValue } from "../components/formatter";
2021-08-31 19:49:52 +00:00
import ETH2USDValue from "../components/ETH2USDValue";
2021-10-31 00:10:15 +00:00
import { ResolvedAddresses } from "../api/address-resolver";
import { Metadata } from "../useSourcify";
2021-07-01 18:21:40 +00:00
type TransactionItemProps = {
tx: ProcessedTransaction;
resolvedAddresses?: ResolvedAddresses;
2021-07-01 18:21:40 +00:00
selectedAddress?: string;
feeDisplay: FeeDisplay;
2021-08-31 19:49:52 +00:00
priceMap: Record<BlockTag, BigNumber>;
metadatas?:
| Record<ChecksummedAddress, Metadata | null | undefined>
| undefined;
2021-07-01 18:21:40 +00:00
};
const TransactionItem: React.FC<TransactionItemProps> = ({
tx,
resolvedAddresses,
2021-07-01 18:21:40 +00:00
selectedAddress,
feeDisplay,
2021-08-31 19:49:52 +00:00
priceMap,
metadatas,
2021-07-01 18:21:40 +00:00
}) => {
let direction: Direction | undefined;
if (selectedAddress) {
if (tx.from === selectedAddress && tx.to === selectedAddress) {
direction = Direction.SELF;
} else if (tx.from === selectedAddress) {
direction = Direction.OUT;
} else if (
tx.to === selectedAddress ||
tx.createdContractAddress === selectedAddress
) {
2021-07-01 18:21:40 +00:00
direction = Direction.IN;
} else {
direction = Direction.INTERNAL;
}
}
const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction;
2021-07-01 18:21:40 +00:00
return (
<div
2021-07-05 20:44:57 +00:00
className={`grid grid-cols-12 gap-x-1 items-baseline text-sm border-t border-gray-200 ${
2021-08-31 07:02:26 +00:00
flash
? "bg-yellow-100 hover:bg-yellow-200"
: "hover:bg-skin-table-hover"
} px-2 py-3`}
>
2021-07-01 18:21:40 +00:00
<div className="col-span-2 flex space-x-1 items-baseline">
{tx.status === 0 && (
<span className="text-red-600" title="Transaction reverted">
<FontAwesomeIcon icon={faExclamationCircle} />
</span>
)}
<span className="truncate">
<TransactionLink txHash={tx.hash} />
</span>
</div>
{tx.to !== null ? <MethodName data={tx.data} /> : <span></span>}
2021-07-01 18:21:40 +00:00
<span>
<BlockLink blockTag={tx.blockNumber} />
</span>
<TimestampAge timestamp={tx.timestamp} />
<span className="col-span-2 flex justify-between items-baseline space-x-2 pr-2">
2021-07-15 01:51:33 +00:00
<span className="truncate">
{tx.from && (
<AddressHighlighter address={tx.from}>
<DecoratedAddressLink
2021-07-14 06:52:31 +00:00
address={tx.from}
selectedAddress={selectedAddress}
miner={tx.miner === tx.from}
resolvedAddresses={resolvedAddresses}
2021-07-14 06:52:31 +00:00
/>
</AddressHighlighter>
)}
2021-07-01 18:21:40 +00:00
</span>
<span>
<TransactionDirection
direction={direction}
flags={tx.internalMinerInteraction ? Flags.MINER : undefined}
/>
2021-07-01 18:21:40 +00:00
</span>
</span>
2021-07-15 01:51:33 +00:00
<span className="col-span-2 flex items-baseline" title={tx.to}>
<span className="truncate">
{tx.to ? (
2021-07-15 01:51:33 +00:00
<AddressHighlighter address={tx.to}>
<DecoratedAddressLink
2021-07-15 01:51:33 +00:00
address={tx.to}
selectedAddress={selectedAddress}
miner={tx.miner === tx.to}
resolvedAddresses={resolvedAddresses}
metadata={metadatas?.[tx.to]}
2021-07-15 01:51:33 +00:00
/>
</AddressHighlighter>
) : (
<AddressHighlighter address={tx.createdContractAddress!}>
<DecoratedAddressLink
address={tx.createdContractAddress!}
selectedAddress={selectedAddress}
creation
resolvedAddresses={resolvedAddresses}
metadata={metadatas?.[tx.createdContractAddress!]}
/>
</AddressHighlighter>
2021-07-15 01:51:33 +00:00
)}
</span>
2021-07-01 18:21:40 +00:00
</span>
<span className="col-span-2 truncate">
<TransactionValue value={tx.value} />
</span>
<span className="font-balance text-xs text-gray-500 truncate">
2021-08-31 19:49:52 +00:00
{feeDisplay === FeeDisplay.TX_FEE && formatValue(tx.fee, 18)}
{feeDisplay === FeeDisplay.TX_FEE_USD &&
(priceMap[tx.blockNumber] ? (
<ETH2USDValue
ethAmount={tx.fee}
eth2USDValue={priceMap[tx.blockNumber]}
/>
) : (
"N/A"
))}
{feeDisplay === FeeDisplay.GAS_PRICE && formatValue(tx.gasPrice, 9)}
2021-07-01 18:21:40 +00:00
</span>
</div>
);
};
2021-10-31 01:14:16 +00:00
export default TransactionItem;