Merge branch 'feature/burn-mint-decorations' into feature/self-destruct-trace

This commit is contained in:
Willian Mitsuda 2021-07-19 00:56:17 -03:00
commit 177929069f
10 changed files with 135 additions and 42 deletions

View File

@ -13,7 +13,7 @@ import NavButton from "./components/NavButton";
import Timestamp from "./components/Timestamp"; import Timestamp from "./components/Timestamp";
import GasValue from "./components/GasValue"; import GasValue from "./components/GasValue";
import BlockLink from "./components/BlockLink"; import BlockLink from "./components/BlockLink";
import AddressOrENSName from "./components/AddressOrENSName"; import DecoratedAddressLink from "./components/DecoratedAddressLink";
import TransactionValue from "./components/TransactionValue"; import TransactionValue from "./components/TransactionValue";
import HexValue from "./components/HexValue"; import HexValue from "./components/HexValue";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
@ -159,10 +159,7 @@ const Block: React.FC = () => {
in this block in this block
</InfoRow> </InfoRow>
<InfoRow title="Mined by"> <InfoRow title="Mined by">
<AddressOrENSName <DecoratedAddressLink address={block.miner} miner />
address={block.miner}
minerAddress={block.miner}
/>
</InfoRow> </InfoRow>
<InfoRow title="Block Reward"> <InfoRow title="Block Reward">
<TransactionValue value={block.blockReward.add(block.feeReward)} /> <TransactionValue value={block.blockReward.add(block.feeReward)} />

View File

@ -2,11 +2,10 @@ import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCaretRight } from "@fortawesome/free-solid-svg-icons"; import { faCaretRight } from "@fortawesome/free-solid-svg-icons";
import AddressHighlighter from "./components/AddressHighlighter"; import AddressHighlighter from "./components/AddressHighlighter";
import AddressOrENSName from "./components/AddressOrENSName"; import DecoratedAddressLink from "./components/DecoratedAddressLink";
import AddressLink from "./components/AddressLink";
import TokenLogo from "./components/TokenLogo"; import TokenLogo from "./components/TokenLogo";
import FormattedBalance from "./components/FormattedBalance"; import FormattedBalance from "./components/FormattedBalance";
import { TokenMetas, TokenTransfer } from "./types"; import { AddressContext, TokenMetas, TokenTransfer } from "./types";
type TokenTransferItemProps = { type TokenTransferItemProps = {
t: TokenTransfer; t: TokenTransfer;
@ -17,7 +16,7 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({
t, t,
tokenMetas, tokenMetas,
}) => ( }) => (
<div className="flex items-baseline space-x-2 truncate"> <div className="flex items-baseline space-x-2 px-2 py-1 truncate hover:bg-gray-100">
<span className="text-gray-500"> <span className="text-gray-500">
<FontAwesomeIcon icon={faCaretRight} size="1x" /> <FontAwesomeIcon icon={faCaretRight} size="1x" />
</span> </span>
@ -25,13 +24,16 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({
<div className="flex space-x-1"> <div className="flex space-x-1">
<span className="font-bold">From</span> <span className="font-bold">From</span>
<AddressHighlighter address={t.from}> <AddressHighlighter address={t.from}>
<AddressOrENSName address={t.from} /> <DecoratedAddressLink
address={t.from}
addressCtx={AddressContext.FROM}
/>
</AddressHighlighter> </AddressHighlighter>
</div> </div>
<div className="flex space-x-1"> <div className="flex space-x-1">
<span className="font-bold">To</span> <span className="font-bold">To</span>
<AddressHighlighter address={t.to}> <AddressHighlighter address={t.to}>
<AddressOrENSName address={t.to} /> <DecoratedAddressLink address={t.to} addressCtx={AddressContext.TO} />
</AddressHighlighter> </AddressHighlighter>
</div> </div>
<div className="col-span-3 flex space-x-1"> <div className="col-span-3 flex space-x-1">
@ -48,7 +50,7 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({
<div className="self-center"> <div className="self-center">
<TokenLogo address={t.token} name={tokenMetas[t.token].name} /> <TokenLogo address={t.token} name={tokenMetas[t.token].name} />
</div> </div>
<AddressLink <DecoratedAddressLink
address={t.token} address={t.token}
text={`${tokenMetas[t.token].name} (${ text={`${tokenMetas[t.token].name} (${
tokenMetas[t.token].symbol tokenMetas[t.token].symbol
@ -56,7 +58,7 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({
/> />
</> </>
) : ( ) : (
<AddressOrENSName address={t.token} /> <DecoratedAddressLink address={t.token} />
)} )}
</span> </span>
</div> </div>

View File

@ -4,11 +4,18 @@ import { NavLink } from "react-router-dom";
type AddressLinkProps = { type AddressLinkProps = {
address: string; address: string;
text?: string; text?: string;
dontOverrideColors?: boolean;
}; };
const AddressLink: React.FC<AddressLinkProps> = ({ address, text }) => ( const AddressLink: React.FC<AddressLinkProps> = ({
address,
text,
dontOverrideColors,
}) => (
<NavLink <NavLink
className="text-link-blue hover:text-link-blue-hover font-address truncate" className={`${
dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover"
} font-address truncate`}
to={`/address/${address}`} to={`/address/${address}`}
> >
<p className="truncate" title={text ?? address}> <p className="truncate" title={text ?? address}>

View File

@ -1,6 +1,4 @@
import React from "react"; import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCoins } from "@fortawesome/free-solid-svg-icons";
import Address from "./Address"; import Address from "./Address";
import AddressLink from "./AddressLink"; import AddressLink from "./AddressLink";
import ENSName from "./ENSName"; import ENSName from "./ENSName";
@ -10,21 +8,18 @@ type AddressOrENSNameProps = {
address: string; address: string;
ensName?: string; ensName?: string;
selectedAddress?: string; selectedAddress?: string;
minerAddress?: string; text?: string;
dontOverrideColors?: boolean;
}; };
const AddressOrENSName: React.FC<AddressOrENSNameProps> = ({ const AddressOrENSName: React.FC<AddressOrENSNameProps> = ({
address, address,
ensName, ensName,
selectedAddress, selectedAddress,
minerAddress, text,
dontOverrideColors,
}) => ( }) => (
<div className="flex items-baseline space-x-1 truncate"> <>
{minerAddress !== undefined && minerAddress === address && (
<span className="text-yellow-400" title="Miner address">
<FontAwesomeIcon icon={faCoins} size="1x" />
</span>
)}
{address === selectedAddress ? ( {address === selectedAddress ? (
<> <>
{ensName ? ( {ensName ? (
@ -36,13 +31,21 @@ const AddressOrENSName: React.FC<AddressOrENSNameProps> = ({
) : ( ) : (
<> <>
{ensName ? ( {ensName ? (
<ENSNameLink name={ensName} address={address} /> <ENSNameLink
name={ensName}
address={address}
dontOverrideColors={dontOverrideColors}
/>
) : ( ) : (
<AddressLink address={address} /> <AddressLink
address={address}
text={text}
dontOverrideColors={dontOverrideColors}
/>
)} )}
</> </>
)} )}
</div> </>
); );
export default React.memo(AddressOrENSName); export default React.memo(AddressOrENSName);

View File

@ -0,0 +1,63 @@
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faMoneyBillAlt,
faBurn,
faCoins,
} from "@fortawesome/free-solid-svg-icons";
import AddressOrENSName from "./AddressOrENSName";
import { AddressContext, ZERO_ADDRESS } from "../types";
type DecoratedAddressLinkProps = {
address: string;
ensName?: string;
selectedAddress?: string;
text?: string;
addressCtx?: AddressContext;
miner?: boolean;
};
const DecoratedAddresssLink: React.FC<DecoratedAddressLinkProps> = ({
address,
ensName,
selectedAddress,
text,
addressCtx,
miner,
}) => {
const mint = addressCtx === AddressContext.FROM && address === ZERO_ADDRESS;
const burn = addressCtx === AddressContext.TO && address === ZERO_ADDRESS;
return (
<div
className={`flex items-baseline space-x-1 ${
mint ? "italic text-green-500 hover:text-green-700" : ""
} ${burn ? "line-through text-orange-500 hover:text-orange-700" : ""}`}
>
{mint && (
<span className="text-green-500" title="Mint address">
<FontAwesomeIcon icon={faMoneyBillAlt} size="1x" />
</span>
)}
{burn && (
<span className="text-orange-500" title="Burn address">
<FontAwesomeIcon icon={faBurn} size="1x" />
</span>
)}
{miner && (
<span className="text-yellow-400" title="Miner address">
<FontAwesomeIcon icon={faCoins} size="1x" />
</span>
)}
<AddressOrENSName
address={address}
ensName={ensName}
selectedAddress={selectedAddress}
text={text}
dontOverrideColors={mint || burn}
/>
</div>
);
};
export default React.memo(DecoratedAddresssLink);

View File

@ -5,11 +5,18 @@ import ENSLogo from "./ensLogo.svg";
type ENSNameLinkProps = { type ENSNameLinkProps = {
name: string; name: string;
address: string; address: string;
dontOverrideColors?: boolean;
}; };
const ENSNameLink: React.FC<ENSNameLinkProps> = ({ name, address }) => ( const ENSNameLink: React.FC<ENSNameLinkProps> = ({
name,
address,
dontOverrideColors,
}) => (
<NavLink <NavLink
className="flex items-baseline space-x-1 font-sans text-link-blue hover:text-link-blue-hover truncate" className={`flex items-baseline space-x-1 font-sans ${
dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover"
} truncate`}
to={`/address/${name}`} to={`/address/${name}`}
title={`${name}: ${address}`} title={`${name}: ${address}`}
> >

View File

@ -3,7 +3,7 @@ import { ethers } from "ethers";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleRight, faCoins } from "@fortawesome/free-solid-svg-icons"; import { faAngleRight, faCoins } from "@fortawesome/free-solid-svg-icons";
import AddressHighlighter from "./AddressHighlighter"; import AddressHighlighter from "./AddressHighlighter";
import AddressLink from "./AddressLink"; import DecoratedAddressLink from "./DecoratedAddressLink";
import { TransactionData, Transfer } from "../types"; import { TransactionData, Transfer } from "../types";
type InternalTransferProps = { type InternalTransferProps = {
@ -38,7 +38,7 @@ const InternalTransfer: React.FC<InternalTransferProps> = ({
<FontAwesomeIcon icon={faCoins} size="1x" /> <FontAwesomeIcon icon={faCoins} size="1x" />
</span> </span>
)} )}
<AddressLink address={transfer.from} /> <DecoratedAddressLink address={transfer.from} />
</div> </div>
</AddressHighlighter> </AddressHighlighter>
</div> </div>
@ -55,7 +55,7 @@ const InternalTransfer: React.FC<InternalTransferProps> = ({
<FontAwesomeIcon icon={faCoins} size="1x" /> <FontAwesomeIcon icon={faCoins} size="1x" />
</span> </span>
)} )}
<AddressLink address={transfer.to} /> <DecoratedAddressLink address={transfer.to} />
</div> </div>
</AddressHighlighter> </AddressHighlighter>
</div> </div>

View File

@ -4,7 +4,7 @@ import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons";
import MethodName from "../components/MethodName"; import MethodName from "../components/MethodName";
import BlockLink from "../components/BlockLink"; import BlockLink from "../components/BlockLink";
import TransactionLink from "../components/TransactionLink"; import TransactionLink from "../components/TransactionLink";
import AddressOrENSName from "../components/AddressOrENSName"; import DecoratedAddressLink from "../components/DecoratedAddressLink";
import TimestampAge from "../components/TimestampAge"; import TimestampAge from "../components/TimestampAge";
import AddressHighlighter from "../components/AddressHighlighter"; import AddressHighlighter from "../components/AddressHighlighter";
import TransactionDirection, { import TransactionDirection, {
@ -71,11 +71,11 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
<span className="truncate"> <span className="truncate">
{tx.from && ( {tx.from && (
<AddressHighlighter address={tx.from}> <AddressHighlighter address={tx.from}>
<AddressOrENSName <DecoratedAddressLink
address={tx.from} address={tx.from}
ensName={ensFrom} ensName={ensFrom}
selectedAddress={selectedAddress} selectedAddress={selectedAddress}
minerAddress={tx.miner} miner={tx.miner === tx.from}
/> />
</AddressHighlighter> </AddressHighlighter>
)} )}
@ -91,11 +91,11 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
<span className="truncate"> <span className="truncate">
{tx.to && ( {tx.to && (
<AddressHighlighter address={tx.to}> <AddressHighlighter address={tx.to}>
<AddressOrENSName <DecoratedAddressLink
address={tx.to} address={tx.to}
ensName={ensTo} ensName={ensTo}
selectedAddress={selectedAddress} selectedAddress={selectedAddress}
minerAddress={tx.miner} miner={tx.miner === tx.to}
/> />
</AddressHighlighter> </AddressHighlighter>
)} )}

View File

@ -9,7 +9,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 AddressHighlighter from "../components/AddressHighlighter"; import AddressHighlighter from "../components/AddressHighlighter";
import AddressOrENSName from "../components/AddressOrENSName"; import DecoratedAddressLink from "../components/DecoratedAddressLink";
import Copy from "../components/Copy"; import Copy from "../components/Copy";
import Timestamp from "../components/Timestamp"; import Timestamp from "../components/Timestamp";
import InternalTransfer from "../components/InternalTransfer"; import InternalTransfer from "../components/InternalTransfer";
@ -65,7 +65,10 @@ const Details: React.FC<DetailsProps> = ({
<InfoRow title="From"> <InfoRow title="From">
<div className="flex items-baseline space-x-2 -ml-1"> <div className="flex items-baseline space-x-2 -ml-1">
<AddressHighlighter address={txData.from}> <AddressHighlighter address={txData.from}>
<AddressOrENSName address={txData.from} minerAddress={txData.miner} /> <DecoratedAddressLink
address={txData.from}
miner={txData.from === txData.miner}
/>
</AddressHighlighter> </AddressHighlighter>
<Copy value={txData.from} /> <Copy value={txData.from} />
</div> </div>
@ -73,7 +76,10 @@ const Details: React.FC<DetailsProps> = ({
<InfoRow title="Interacted With (To)"> <InfoRow title="Interacted With (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}> <AddressHighlighter address={txData.to}>
<AddressOrENSName address={txData.to} minerAddress={txData.miner} /> <DecoratedAddressLink
address={txData.to}
miner={txData.to === txData.miner}
/>
</AddressHighlighter> </AddressHighlighter>
<Copy value={txData.to} /> <Copy value={txData.to} />
</div> </div>
@ -97,7 +103,7 @@ const Details: React.FC<DetailsProps> = ({
</InfoRow> </InfoRow>
{txData.tokenTransfers.length > 0 && ( {txData.tokenTransfers.length > 0 && (
<InfoRow title={`Tokens Transferred (${txData.tokenTransfers.length})`}> <InfoRow title={`Tokens Transferred (${txData.tokenTransfers.length})`}>
<div className="space-y-2"> <div>
{txData.tokenTransfers.map((t, i) => ( {txData.tokenTransfers.map((t, i) => (
<TokenTransferItem key={i} t={t} tokenMetas={txData.tokenMetas} /> <TokenTransferItem key={i} t={t} tokenMetas={txData.tokenMetas} />
))} ))}

View File

@ -57,6 +57,14 @@ export type TransactionData = {
logs: ethers.providers.Log[]; logs: ethers.providers.Log[];
}; };
// The VOID...
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
export enum AddressContext {
FROM,
TO,
}
export type From = { export type From = {
current: string; current: string;
depth: number; depth: number;