Add new eoa/contract legend to addresses in search results list/tx details page

This commit is contained in:
Willian Mitsuda 2022-03-01 23:33:07 -03:00
parent 8f78380521
commit 6220d230fa
4 changed files with 65 additions and 3 deletions

View File

@ -9,12 +9,14 @@ type TransactionAddressProps = {
address: string;
addressCtx?: AddressContext | undefined;
metadata?: Metadata | null | undefined;
eoa?: boolean | undefined;
};
const TransactionAddress: React.FC<TransactionAddressProps> = ({
address,
addressCtx,
metadata,
eoa,
}) => {
const txData = useSelectedTransaction();
// TODO: push down creation coloring logic into DecoratedAddressLink
@ -30,6 +32,7 @@ const TransactionAddress: React.FC<TransactionAddressProps> = ({
txTo={address === txData?.to || creation}
creation={creation}
metadata={metadata}
eoa={eoa}
/>
</AddressHighlighter>
);

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useContext } from "react";
import { BlockTag } from "@ethersproject/abstract-provider";
import { BigNumber } from "@ethersproject/bignumber";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@ -16,6 +16,8 @@ import TransactionDirection, {
import TransactionValue from "../components/TransactionValue";
import { ChecksummedAddress, ProcessedTransaction } from "../types";
import { FeeDisplay } from "./useFeeToggler";
import { RuntimeContext } from "../useRuntime";
import { useHasCode } from "../useErigonHooks";
import { formatValue } from "../components/formatter";
import ETH2USDValue from "../components/ETH2USDValue";
import { Metadata } from "../sourcify/useSourcify";
@ -35,6 +37,13 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
priceMap,
metadatas,
}) => {
const { provider } = useContext(RuntimeContext);
const toHasCode = useHasCode(
provider,
tx.to ?? undefined,
tx.blockNumber - 1
);
let direction: Direction | undefined;
if (selectedAddress) {
if (tx.from === selectedAddress && tx.to === selectedAddress) {
@ -107,6 +116,7 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
selectedAddress={selectedAddress}
miner={tx.miner === tx.to}
metadata={metadatas[tx.to]}
eoa={toHasCode === undefined ? undefined : !toHasCode}
/>
</AddressHighlighter>
) : (
@ -116,6 +126,7 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
selectedAddress={selectedAddress}
creation
metadata={metadatas[tx.createdContractAddress!]}
eoa={false}
/>
</AddressHighlighter>
)}

View File

@ -45,7 +45,7 @@ import {
import { DevDoc, Metadata, useError, UserDoc } from "../sourcify/useSourcify";
import { RuntimeContext } from "../useRuntime";
import { useContractsMetadata } from "../hooks";
import { useTransactionError } from "../useErigonHooks";
import { useHasCode, useTransactionError } from "../useErigonHooks";
type DetailsProps = {
txData: TransactionData;
@ -118,6 +118,12 @@ const Details: React.FC<DetailsProps> = ({
: undefined;
const [expanded, setExpanded] = useState<boolean>(false);
const toHasCode = useHasCode(
provider,
txData.to,
txData.confirmedData ? txData.confirmedData.blockNumber - 1 : undefined
);
return (
<ContentFrame tabs>
<InfoRow title="Transaction Hash">
@ -264,6 +270,7 @@ const Details: React.FC<DetailsProps> = ({
<TransactionAddress
address={txData.to}
metadata={metadatas?.[txData.to]}
eoa={toHasCode === undefined ? undefined : !toHasCode}
/>
<Copy value={txData.to} />
</div>

View File

@ -1,5 +1,9 @@
import { useState, useEffect } from "react";
import { Block, BlockWithTransactions } from "@ethersproject/abstract-provider";
import {
Block,
BlockWithTransactions,
BlockTag,
} from "@ethersproject/abstract-provider";
import { JsonRpcProvider } from "@ethersproject/providers";
import { getAddress } from "@ethersproject/address";
import { Contract } from "@ethersproject/contracts";
@ -679,3 +683,40 @@ export const useAddressBalance = (
return balance;
};
/**
* This is a generic fetch for SWR, where the key is an array, whose
* element 0 is the JSON-RPC method, and the remaining are the method
* arguments.
*/
export const providerFetcher =
(provider: JsonRpcProvider | undefined) =>
async (...key: any[]): Promise<any | undefined> => {
if (provider === undefined) {
return undefined;
}
for (const a of key) {
if (a === undefined) {
return undefined;
}
}
const method = key[0];
const args = key.slice(1);
const result = await provider.send(method, args);
// console.log(`providerFetcher: ${method} ${args} === ${result}`);
return result;
};
export const useHasCode = (
provider: JsonRpcProvider | undefined,
address: ChecksummedAddress | undefined,
blockTag: BlockTag = "latest"
): boolean | undefined => {
const fetcher = providerFetcher(provider);
const { data, error } = useSWR(["ots_hasCode", address, blockTag], fetcher);
if (error) {
return undefined;
}
return data as boolean | undefined;
};