Retrofit name resolvers into transaction/* pages

This commit is contained in:
Willian Mitsuda 2021-10-30 22:44:33 -03:00
parent 41be42d1ce
commit 7bfa479d6c
5 changed files with 71 additions and 4 deletions

View File

@ -11,6 +11,10 @@ import { useInternalOperations, useTxData } from "./useErigonHooks";
import { useETHUSDOracle } from "./usePriceOracle"; import { useETHUSDOracle } from "./usePriceOracle";
import { useAppConfigContext } from "./useAppConfig"; import { useAppConfigContext } from "./useAppConfig";
import { useSourcify, useTransactionDescription } from "./useSourcify"; import { useSourcify, useTransactionDescription } from "./useSourcify";
import {
transactionDataCollector,
useResolvedAddresses,
} from "./useResolvedAddresses";
const Details = React.lazy( const Details = React.lazy(
() => () =>
@ -36,6 +40,11 @@ const Transaction: React.FC = () => {
const { txhash } = params; const { txhash } = params;
const txData = useTxData(provider, txhash); const txData = useTxData(provider, txhash);
const addrCollector = useMemo(
() => transactionDataCollector(txData),
[txData]
);
const resolvedAddresses = useResolvedAddresses(provider, addrCollector);
const internalOps = useInternalOperations(provider, txData); const internalOps = useInternalOperations(provider, txData);
const sendsEthToMiner = useMemo(() => { const sendsEthToMiner = useMemo(() => {
@ -100,10 +109,15 @@ const Transaction: React.FC = () => {
internalOps={internalOps} internalOps={internalOps}
sendsEthToMiner={sendsEthToMiner} sendsEthToMiner={sendsEthToMiner}
ethUSDPrice={blockETHUSDPrice} ethUSDPrice={blockETHUSDPrice}
resolvedAddresses={resolvedAddresses}
/> />
</Route> </Route>
<Route path="/tx/:txhash/logs/" exact> <Route path="/tx/:txhash/logs/" exact>
<Logs txData={txData} metadata={metadata} /> <Logs
txData={txData}
metadata={metadata}
resolvedAddresses={resolvedAddresses}
/>
</Route> </Route>
</Switch> </Switch>
</React.Suspense> </React.Suspense>

View File

@ -38,6 +38,7 @@ import ModeTab from "../components/ModeTab";
import DecodedParamsTable from "./decoder/DecodedParamsTable"; import DecodedParamsTable from "./decoder/DecodedParamsTable";
import { rawInputTo4Bytes, use4Bytes } from "../use4Bytes"; import { rawInputTo4Bytes, use4Bytes } from "../use4Bytes";
import { DevDoc, UserDoc } from "../useSourcify"; import { DevDoc, UserDoc } from "../useSourcify";
import { ResolvedAddresses } from "../api/address-resolver";
type DetailsProps = { type DetailsProps = {
txData: TransactionData; txData: TransactionData;
@ -47,6 +48,7 @@ type DetailsProps = {
internalOps?: InternalOperation[]; internalOps?: InternalOperation[];
sendsEthToMiner: boolean; sendsEthToMiner: boolean;
ethUSDPrice: BigNumber | undefined; ethUSDPrice: BigNumber | undefined;
resolvedAddresses: ResolvedAddresses | undefined;
}; };
const Details: React.FC<DetailsProps> = ({ const Details: React.FC<DetailsProps> = ({
@ -57,6 +59,7 @@ const Details: React.FC<DetailsProps> = ({
internalOps, internalOps,
sendsEthToMiner, sendsEthToMiner,
ethUSDPrice, ethUSDPrice,
resolvedAddresses,
}) => { }) => {
const hasEIP1559 = const hasEIP1559 =
txData.confirmedData?.blockBaseFeePerGas !== undefined && txData.confirmedData?.blockBaseFeePerGas !== undefined &&
@ -154,6 +157,7 @@ const Details: React.FC<DetailsProps> = ({
address={txData.from} address={txData.from}
miner={txData.from === txData.confirmedData?.miner} miner={txData.from === txData.confirmedData?.miner}
txFrom txFrom
resolvedAddresses={resolvedAddresses}
/> />
</AddressHighlighter> </AddressHighlighter>
<Copy value={txData.from} /> <Copy value={txData.from} />
@ -171,6 +175,7 @@ const Details: React.FC<DetailsProps> = ({
address={txData.to} address={txData.to}
miner={txData.to === txData.confirmedData?.miner} miner={txData.to === txData.confirmedData?.miner}
txTo txTo
resolvedAddresses={resolvedAddresses}
/> />
</AddressHighlighter> </AddressHighlighter>
<Copy value={txData.to} /> <Copy value={txData.to} />
@ -188,6 +193,7 @@ const Details: React.FC<DetailsProps> = ({
address={txData.confirmedData.createdContractAddress!} address={txData.confirmedData.createdContractAddress!}
creation creation
txTo txTo
resolvedAddresses={resolvedAddresses}
/> />
</AddressHighlighter> </AddressHighlighter>
<Copy value={txData.confirmedData.createdContractAddress!} /> <Copy value={txData.confirmedData.createdContractAddress!} />

View File

@ -10,14 +10,21 @@ import DecodedParamsTable from "./decoder/DecodedParamsTable";
import DecodedLogSignature from "./decoder/DecodedLogSignature"; import DecodedLogSignature from "./decoder/DecodedLogSignature";
import { TransactionData } from "../types"; import { TransactionData } from "../types";
import { useTopic0 } from "../useTopic0"; import { useTopic0 } from "../useTopic0";
import { ResolvedAddresses } from "../api/address-resolver";
type LogEntryProps = { type LogEntryProps = {
txData: TransactionData; txData: TransactionData;
log: Log; log: Log;
logDesc: LogDescription | null | undefined; logDesc: LogDescription | null | undefined;
resolvedAddresses: ResolvedAddresses | undefined;
}; };
const LogEntry: React.FC<LogEntryProps> = ({ txData, log, logDesc }) => { const LogEntry: React.FC<LogEntryProps> = ({
txData,
log,
logDesc,
resolvedAddresses,
}) => {
const rawTopic0 = log.topics[0]; const rawTopic0 = log.topics[0];
const topic0 = useTopic0(rawTopic0); const topic0 = useTopic0(rawTopic0);
@ -62,6 +69,7 @@ const LogEntry: React.FC<LogEntryProps> = ({ txData, log, logDesc }) => {
miner={log.address === txData.confirmedData?.miner} miner={log.address === txData.confirmedData?.miner}
txFrom={log.address === txData.from} txFrom={log.address === txData.from}
txTo={log.address === txData.to} txTo={log.address === txData.to}
resolvedAddresses={resolvedAddresses}
/> />
</AddressHighlighter> </AddressHighlighter>
<Copy value={log.address} /> <Copy value={log.address} />

View File

@ -5,13 +5,15 @@ import LogEntry from "./LogEntry";
import { TransactionData } from "../types"; import { TransactionData } from "../types";
import { useAppConfigContext } from "../useAppConfig"; import { useAppConfigContext } from "../useAppConfig";
import { Metadata, useMultipleMetadata } from "../useSourcify"; import { Metadata, useMultipleMetadata } from "../useSourcify";
import { ResolvedAddresses } from "../api/address-resolver";
type LogsProps = { type LogsProps = {
txData: TransactionData; txData: TransactionData;
metadata: Metadata | null | undefined; metadata: Metadata | null | undefined;
resolvedAddresses: ResolvedAddresses | undefined;
}; };
const Logs: React.FC<LogsProps> = ({ txData, metadata }) => { const Logs: React.FC<LogsProps> = ({ txData, metadata, resolvedAddresses }) => {
const baseMetadatas = useMemo((): Record<string, Metadata | null> => { const baseMetadatas = useMemo((): Record<string, Metadata | null> => {
if (!txData.to || metadata === undefined) { if (!txData.to || metadata === undefined) {
return {}; return {};
@ -70,6 +72,7 @@ const Logs: React.FC<LogsProps> = ({ txData, metadata }) => {
txData={txData} txData={txData}
log={l} log={l}
logDesc={logDescs?.[i]} logDesc={logDescs?.[i]}
resolvedAddresses={resolvedAddresses}
/> />
))} ))}
</> </>

View File

@ -1,6 +1,6 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { JsonRpcProvider } from "@ethersproject/providers"; import { JsonRpcProvider } from "@ethersproject/providers";
import { ProcessedTransaction } from "./types"; import { ProcessedTransaction, TransactionData } from "./types";
import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; import { batchPopulate, ResolvedAddresses } from "./api/address-resolver";
export type AddressCollector = () => string[]; export type AddressCollector = () => string[];
@ -25,6 +25,42 @@ export const pageCollector =
return Array.from(uniqueAddresses); return Array.from(uniqueAddresses);
}; };
export const transactionDataCollector =
(txData: TransactionData | null | undefined): AddressCollector =>
() => {
if (!txData) {
return [];
}
const uniqueAddresses = new Set<string>();
// Standard fields
uniqueAddresses.add(txData.from);
if (txData.to) {
uniqueAddresses.add(txData.to);
}
if (txData.confirmedData?.createdContractAddress) {
uniqueAddresses.add(txData.confirmedData?.createdContractAddress);
}
// Dig token transfers
for (const t of txData.tokenTransfers) {
uniqueAddresses.add(t.from);
uniqueAddresses.add(t.to);
uniqueAddresses.add(t.token);
}
// Dig log addresses
if (txData.confirmedData) {
for (const l of txData.confirmedData.logs) {
uniqueAddresses.add(l.address);
// TODO: find a way to dig over decoded address log attributes
}
}
return Array.from(uniqueAddresses);
};
export const useResolvedAddresses = ( export const useResolvedAddresses = (
provider: JsonRpcProvider | undefined, provider: JsonRpcProvider | undefined,
addrCollector: AddressCollector addrCollector: AddressCollector