diff --git a/src/AddressTransactions.tsx b/src/AddressTransactions.tsx index 17c8888..d7222c0 100644 --- a/src/AddressTransactions.tsx +++ b/src/AddressTransactions.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useContext, useCallback } from "react"; +import React, { useEffect, useContext, useCallback, useMemo } from "react"; import { useParams, useNavigate, @@ -21,8 +21,9 @@ import Contracts from "./address/Contracts"; import { RuntimeContext } from "./useRuntime"; import { useAppConfigContext } from "./useAppConfig"; import { useAddressOrENSFromURL } from "./useResolvedAddresses"; -import { useSingleMetadata } from "./sourcify/useSourcify"; +import { useMultipleMetadata } from "./sourcify/useSourcify"; import { ChecksummedAddress } from "./types"; +import { useAddressesWithCode } from "./useErigonHooks"; const AddressTransactions: React.FC = () => { const { provider } = useContext(RuntimeContext); @@ -58,11 +59,24 @@ const AddressTransactions: React.FC = () => { }, [addressOrName, checksummedAddress, isENS]); const { sourcifySource } = useAppConfigContext(); - const addressMetadata = useSingleMetadata( - checksummedAddress, + const checksummedAddressAsArray = useMemo( + () => (checksummedAddress !== undefined ? [checksummedAddress] : []), + [checksummedAddress] + ); + const contractAddresses = useAddressesWithCode( + provider, + checksummedAddressAsArray + ); + const metadatas = useMultipleMetadata( + undefined, + contractAddresses, provider?.network.chainId, sourcifySource ); + const addressMetadata = + checksummedAddress !== undefined + ? metadatas[checksummedAddress] + : undefined; return ( @@ -94,34 +108,34 @@ const AddressTransactions: React.FC = () => { - - Overview - - - - Contract - {addressMetadata === undefined ? ( - - - - ) : addressMetadata === null ? ( - - - - ) : ( - - - - )} - - + Overview + {(contractAddresses?.length ?? 0) > 0 && ( + + + Contract + {addressMetadata === undefined ? ( + + + + ) : addressMetadata === null ? ( + + + + ) : ( + + + + )} + + + )} @@ -142,7 +156,12 @@ const AddressTransactions: React.FC = () => { element={ } /> diff --git a/src/address/AddressTransactionResults.tsx b/src/address/AddressTransactionResults.tsx index 07f8e4f..f1a373e 100644 --- a/src/address/AddressTransactionResults.tsx +++ b/src/address/AddressTransactionResults.tsx @@ -114,6 +114,9 @@ const AddressTransactionResults: React.FC = ({ if (t.to) { _addresses.push(t.to); } + if (t.createdContractAddress) { + _addresses.push(t.createdContractAddress); + } } } return _addresses; diff --git a/src/block/BlockTransactionResults.tsx b/src/block/BlockTransactionResults.tsx index fc5bf9f..01d867c 100644 --- a/src/block/BlockTransactionResults.tsx +++ b/src/block/BlockTransactionResults.tsx @@ -40,7 +40,16 @@ const BlockTransactionResults: React.FC = ({ return []; } - return page.map((t) => t.to).filter((to): to is string => to !== undefined); + const _addresses: ChecksummedAddress[] = []; + for (const t of page) { + if (t.to) { + _addresses.push(t.to); + } + if (t.createdContractAddress) { + _addresses.push(t.createdContractAddress); + } + } + return _addresses; }, [page]); const metadatas = useContractsMetadata(addresses, provider); diff --git a/src/hooks.ts b/src/hooks.ts index a81f10b..e924314 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -1,13 +1,19 @@ +import { useMemo } from "react"; import { JsonRpcProvider } from "@ethersproject/providers"; import { ChecksummedAddress } from "./types"; -import { - Metadata, - useDedupedAddresses, - useMultipleMetadata, -} from "./sourcify/useSourcify"; +import { Metadata, useMultipleMetadata } from "./sourcify/useSourcify"; import { useAppConfigContext } from "./useAppConfig"; import { useAddressesWithCode } from "./useErigonHooks"; +export const useDedupedAddresses = ( + addresses: ChecksummedAddress[] +): ChecksummedAddress[] => { + return useMemo(() => { + const deduped = new Set(addresses); + return [...deduped]; + }, [addresses]); +}; + export const useContractsMetadata = ( addresses: ChecksummedAddress[], provider: JsonRpcProvider | undefined, diff --git a/src/search/TransactionItem.tsx b/src/search/TransactionItem.tsx index 929d2cd..b6cfe1e 100644 --- a/src/search/TransactionItem.tsx +++ b/src/search/TransactionItem.tsx @@ -99,7 +99,10 @@ const TransactionItem: React.FC = ({ /> - + {tx.to ? ( diff --git a/src/search/search.ts b/src/search/search.ts index 25bda65..57a5958 100644 --- a/src/search/search.ts +++ b/src/search/search.ts @@ -52,7 +52,7 @@ export class SearchController { idx: _receipt.transactionIndex, hash: t.hash, from: t.from, - to: t.to, + to: t.to ?? null, createdContractAddress: _receipt.contractAddress, value: t.value, fee: _receipt.gasUsed.mul(t.gasPrice!), diff --git a/src/sourcify/useSourcify.ts b/src/sourcify/useSourcify.ts index 85baaaa..f5fae67 100644 --- a/src/sourcify/useSourcify.ts +++ b/src/sourcify/useSourcify.ts @@ -121,25 +121,6 @@ export const useSourcify = ( return rawMetadata; }; -export const useSingleMetadata = ( - address: ChecksummedAddress | undefined, - chainId: number | undefined, - source: SourcifySource -) => { - const addresses = useMemo(() => (address ? [address] : []), [address]); - const metadatas = useMultipleMetadata(undefined, addresses, chainId, source); - return address !== undefined ? metadatas[address] : undefined; -}; - -export const useDedupedAddresses = ( - addresses: ChecksummedAddress[] -): ChecksummedAddress[] => { - return useMemo(() => { - const deduped = new Set(addresses); - return [...deduped]; - }, [addresses]); -}; - export const useMultipleMetadata = ( baseMetadatas: Record | undefined, addresses: ChecksummedAddress[] | undefined, diff --git a/src/types.ts b/src/types.ts index fde36bb..adedc86 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,7 +16,7 @@ export type ProcessedTransaction = { idx: number; hash: string; from?: string; - to?: string; + to: string | null; createdContractAddress?: string; internalMinerInteraction?: boolean; value: BigNumber; diff --git a/src/useErigonHooks.ts b/src/useErigonHooks.ts index f722f03..30effa2 100644 --- a/src/useErigonHooks.ts +++ b/src/useErigonHooks.ts @@ -95,33 +95,38 @@ export const useBlockTransactions = ( const _receipts = result.receipts; const rawTxs = _block.transactions - .map( - (t, i): ProcessedTransaction => ({ + .map((t, i): ProcessedTransaction => { + const _rawReceipt = _receipts[i]; + // Empty logs on purpose because of ethers formatter requires it + _rawReceipt.logs = []; + const _receipt = provider.formatter.receipt(_rawReceipt); + + return { blockNumber: blockNumber, timestamp: _block.timestamp, miner: _block.miner, idx: i, hash: t.hash, from: t.from, - to: t.to, - createdContractAddress: _receipts[i].contractAddress, + to: t.to ?? null, + createdContractAddress: _receipt.contractAddress, value: t.value, fee: t.type !== 2 ? provider.formatter - .bigNumber(_receipts[i].gasUsed) + .bigNumber(_receipt.gasUsed) .mul(t.gasPrice!) : provider.formatter - .bigNumber(_receipts[i].gasUsed) + .bigNumber(_receipt.gasUsed) .mul(t.maxPriorityFeePerGas!.add(_block.baseFeePerGas!)), gasPrice: t.type !== 2 ? t.gasPrice! : t.maxPriorityFeePerGas!.add(_block.baseFeePerGas!), data: t.data, - status: provider.formatter.number(_receipts[i].status), - }) - ) + status: provider.formatter.number(_receipt.status), + }; + }) .reverse(); setTxs(rawTxs); setTotalTxs(result.fullblock.transactionCount); @@ -457,8 +462,10 @@ export const useAddressesWithCode = ( const [results, setResults] = useState(); useEffect(() => { + // Reset + setResults(undefined); + if (provider === undefined) { - setResults(undefined); return; } diff --git a/src/useResolvedAddresses.ts b/src/useResolvedAddresses.ts index dc0df3a..9250232 100644 --- a/src/useResolvedAddresses.ts +++ b/src/useResolvedAddresses.ts @@ -27,6 +27,11 @@ export const useAddressOrENSFromURL = ( // If it looks like it is an ENS name, try to resolve it useEffect(() => { + // Reset + setENS(false); + setError(false); + setChecksummedAddress(undefined); + // TODO: handle and offer fallback to bad checksummed addresses if (isAddress(addressOrName)) { // Normalize to checksummed address @@ -81,6 +86,9 @@ export const pageCollector = if (tx.to) { uniqueAddresses.add(tx.to); } + if (tx.createdContractAddress) { + uniqueAddresses.add(tx.createdContractAddress); + } } return Array.from(uniqueAddresses);