2021-07-01 18:21:40 +00:00
|
|
|
import React from "react";
|
|
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
2021-08-08 06:51:21 +00:00
|
|
|
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";
|
2021-07-19 03:38:38 +00:00
|
|
|
import DecoratedAddressLink from "../components/DecoratedAddressLink";
|
2021-07-01 18:21:40 +00:00
|
|
|
import TimestampAge from "../components/TimestampAge";
|
2021-07-14 07:24:28 +00:00
|
|
|
import AddressHighlighter from "../components/AddressHighlighter";
|
2021-07-01 18:21:40 +00:00
|
|
|
import TransactionDirection, {
|
|
|
|
Direction,
|
2021-07-05 03:34:40 +00:00
|
|
|
Flags,
|
2021-07-01 18:21:40 +00:00
|
|
|
} from "../components/TransactionDirection";
|
|
|
|
import TransactionValue from "../components/TransactionValue";
|
2021-07-03 00:40:02 +00:00
|
|
|
import { ENSReverseCache, ProcessedTransaction } from "../types";
|
2021-07-01 18:21:40 +00:00
|
|
|
import { FeeDisplay } from "./useFeeToggler";
|
|
|
|
import { formatValue } from "../components/formatter";
|
|
|
|
|
|
|
|
type TransactionItemProps = {
|
|
|
|
tx: ProcessedTransaction;
|
2021-07-03 00:40:02 +00:00
|
|
|
ensCache?: ENSReverseCache;
|
2021-07-01 18:21:40 +00:00
|
|
|
selectedAddress?: string;
|
|
|
|
feeDisplay: FeeDisplay;
|
|
|
|
};
|
|
|
|
|
|
|
|
const TransactionItem: React.FC<TransactionItemProps> = ({
|
|
|
|
tx,
|
2021-07-03 00:40:02 +00:00
|
|
|
ensCache,
|
2021-07-01 18:21:40 +00:00
|
|
|
selectedAddress,
|
|
|
|
feeDisplay,
|
|
|
|
}) => {
|
|
|
|
let direction: Direction | undefined;
|
|
|
|
if (selectedAddress) {
|
|
|
|
if (tx.from === selectedAddress && tx.to === selectedAddress) {
|
|
|
|
direction = Direction.SELF;
|
|
|
|
} else if (tx.from === selectedAddress) {
|
|
|
|
direction = Direction.OUT;
|
2021-07-21 04:42:49 +00:00
|
|
|
} else if (
|
|
|
|
tx.to === selectedAddress ||
|
|
|
|
tx.createdContractAddress === selectedAddress
|
|
|
|
) {
|
2021-07-01 18:21:40 +00:00
|
|
|
direction = Direction.IN;
|
|
|
|
} else {
|
|
|
|
direction = Direction.INTERNAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-03 00:40:02 +00:00
|
|
|
const ensFrom = ensCache && tx.from && ensCache[tx.from];
|
|
|
|
const ensTo = ensCache && tx.to && ensCache[tx.to];
|
2021-07-21 04:42:49 +00:00
|
|
|
const ensCreated =
|
|
|
|
ensCache &&
|
|
|
|
tx.createdContractAddress &&
|
|
|
|
ensCache[tx.createdContractAddress];
|
2021-07-05 03:34:40 +00:00
|
|
|
const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction;
|
2021-07-03 00:40:02 +00:00
|
|
|
|
2021-07-01 18:21:40 +00:00
|
|
|
return (
|
2021-07-05 03:34:40 +00:00
|
|
|
<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"
|
2021-07-05 03:34:40 +00:00
|
|
|
} 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>
|
|
|
|
<MethodName data={tx.data} />
|
|
|
|
<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">
|
2021-07-03 00:40:02 +00:00
|
|
|
{tx.from && (
|
2021-07-14 07:24:28 +00:00
|
|
|
<AddressHighlighter address={tx.from}>
|
2021-07-19 03:38:38 +00:00
|
|
|
<DecoratedAddressLink
|
2021-07-14 06:52:31 +00:00
|
|
|
address={tx.from}
|
|
|
|
ensName={ensFrom}
|
|
|
|
selectedAddress={selectedAddress}
|
2021-07-19 03:38:38 +00:00
|
|
|
miner={tx.miner === tx.from}
|
2021-07-14 06:52:31 +00:00
|
|
|
/>
|
2021-07-14 07:24:28 +00:00
|
|
|
</AddressHighlighter>
|
2021-07-03 00:40:02 +00:00
|
|
|
)}
|
2021-07-01 18:21:40 +00:00
|
|
|
</span>
|
|
|
|
<span>
|
2021-07-05 03:34:40 +00:00
|
|
|
<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">
|
2021-07-21 04:42:49 +00:00
|
|
|
{tx.to ? (
|
2021-07-15 01:51:33 +00:00
|
|
|
<AddressHighlighter address={tx.to}>
|
2021-07-19 03:38:38 +00:00
|
|
|
<DecoratedAddressLink
|
2021-07-15 01:51:33 +00:00
|
|
|
address={tx.to}
|
|
|
|
ensName={ensTo}
|
|
|
|
selectedAddress={selectedAddress}
|
2021-07-19 03:38:38 +00:00
|
|
|
miner={tx.miner === tx.to}
|
2021-07-15 01:51:33 +00:00
|
|
|
/>
|
|
|
|
</AddressHighlighter>
|
2021-07-21 04:42:49 +00:00
|
|
|
) : (
|
|
|
|
<AddressHighlighter address={tx.createdContractAddress!}>
|
|
|
|
<DecoratedAddressLink
|
|
|
|
address={tx.createdContractAddress!}
|
|
|
|
ensName={ensCreated}
|
|
|
|
selectedAddress={selectedAddress}
|
|
|
|
creation
|
|
|
|
/>
|
|
|
|
</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">
|
|
|
|
{feeDisplay === FeeDisplay.TX_FEE
|
|
|
|
? formatValue(tx.fee, 18)
|
|
|
|
: formatValue(tx.gasPrice, 9)}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default React.memo(TransactionItem);
|