diff --git a/packages/nextjs/components/blockexplorer/TransactionsTable.tsx b/packages/nextjs/components/blockexplorer/TransactionsTable.tsx
index d447aaea6..5f9d4611c 100644
--- a/packages/nextjs/components/blockexplorer/TransactionsTable.tsx
+++ b/packages/nextjs/components/blockexplorer/TransactionsTable.tsx
@@ -4,7 +4,7 @@ import { Address } from "~~/components/scaffold-eth";
import { TransactionWithFunction, getTargetNetwork } from "~~/utils/scaffold-eth";
import { TransactionsTableProps } from "~~/utils/scaffold-eth/";
-export const TransactionsTable = ({ blocks, transactionReceipts, isLoading }: TransactionsTableProps) => {
+export const TransactionsTable = ({ blocks, transactionReceipts }: TransactionsTableProps) => {
const targetNetwork = getTargetNetwork();
return (
@@ -22,64 +22,47 @@ export const TransactionsTable = ({ blocks, transactionReceipts, isLoading }: Tr
Value ({targetNetwork.nativeCurrency.symbol}) |
- {isLoading ? (
-
- {[...Array(20)].map((_, rowIndex) => (
-
- {[...Array(7)].map((_, colIndex) => (
-
-
- |
- ))}
-
- ))}
-
- ) : (
-
- {blocks.map(block =>
- (block.transactions as TransactionWithFunction[]).map(tx => {
- const receipt = transactionReceipts[tx.hash];
- const timeMined = new Date(Number(block.timestamp) * 1000).toLocaleString();
- const functionCalled = tx.input.substring(0, 10);
+
+ {blocks.map(block =>
+ (block.transactions as TransactionWithFunction[]).map(tx => {
+ const receipt = transactionReceipts[tx.hash];
+ const timeMined = new Date(Number(block.timestamp) * 1000).toLocaleString();
+ const functionCalled = tx.input.substring(0, 10);
- return (
-
-
-
- |
-
- {tx.functionName === "0x" ? "" : {tx.functionName}}
- {functionCalled !== "0x" && (
- {functionCalled}
- )}
- |
- {block.number?.toString()} |
- {timeMined} |
-
-
- |
-
- {!receipt?.contractAddress ? (
- tx.to &&
- ) : (
-
-
- (Contract Creation)
-
- )}
- |
-
- {formatEther(tx.value)} {targetNetwork.nativeCurrency.symbol}
- |
-
- );
- }),
- )}
-
- )}
+ return (
+
+
+
+ |
+
+ {tx.functionName === "0x" ? "" : {tx.functionName}}
+ {functionCalled !== "0x" && (
+ {functionCalled}
+ )}
+ |
+ {block.number?.toString()} |
+ {timeMined} |
+
+
+ |
+
+ {!receipt?.contractAddress ? (
+ tx.to &&
+ ) : (
+
+
+ (Contract Creation)
+
+ )}
+ |
+
+ {formatEther(tx.value)} {targetNetwork.nativeCurrency.symbol}
+ |
+
+ );
+ }),
+ )}
+
diff --git a/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts b/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts
index c927d6a32..0918c65e3 100644
--- a/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts
+++ b/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts
@@ -1,29 +1,41 @@
import { useCallback, useEffect, useState } from "react";
-import { Block, Transaction, TransactionReceipt } from "viem";
-import { usePublicClient } from "wagmi";
+import {
+ Block,
+ Hash,
+ Transaction,
+ TransactionReceipt,
+ createTestClient,
+ publicActions,
+ walletActions,
+ webSocket,
+} from "viem";
import { hardhat } from "wagmi/chains";
import { decodeTransactionData } from "~~/utils/scaffold-eth";
const BLOCKS_PER_PAGE = 20;
-export const useFetchBlocks = () => {
- const client = usePublicClient({ chainId: hardhat.id });
+export const testClient = createTestClient({
+ chain: hardhat,
+ mode: "hardhat",
+ transport: webSocket("ws://127.0.0.1:8545"),
+})
+ .extend(publicActions)
+ .extend(walletActions);
+export const useFetchBlocks = () => {
const [blocks, setBlocks] = useState([]);
const [transactionReceipts, setTransactionReceipts] = useState<{
[key: string]: TransactionReceipt;
}>({});
const [currentPage, setCurrentPage] = useState(0);
const [totalBlocks, setTotalBlocks] = useState(0n);
- const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const fetchBlocks = useCallback(async () => {
- setIsLoading(true);
setError(null);
try {
- const blockNumber = await client.getBlockNumber();
+ const blockNumber = await testClient.getBlockNumber();
setTotalBlocks(blockNumber);
const startingBlock = blockNumber - BigInt(currentPage * BLOCKS_PER_PAGE);
@@ -34,7 +46,7 @@ export const useFetchBlocks = () => {
const blocksWithTransactions = blockNumbersToFetch.map(async blockNumber => {
try {
- return client.getBlock({ blockNumber, includeTransactions: true });
+ return testClient.getBlock({ blockNumber, includeTransactions: true });
} catch (err) {
setError(err instanceof Error ? err : new Error("An error occurred."));
throw err;
@@ -50,7 +62,7 @@ export const useFetchBlocks = () => {
fetchedBlocks.flatMap(block =>
block.transactions.map(async tx => {
try {
- const receipt = await client.getTransactionReceipt({ hash: (tx as Transaction).hash });
+ const receipt = await testClient.getTransactionReceipt({ hash: (tx as Transaction).hash });
return { [(tx as Transaction).hash]: receipt };
} catch (err) {
setError(err instanceof Error ? err : new Error("An error occurred."));
@@ -65,47 +77,50 @@ export const useFetchBlocks = () => {
} catch (err) {
setError(err instanceof Error ? err : new Error("An error occurred."));
}
- setIsLoading(false);
- }, [client, currentPage]);
+ }, [currentPage]);
useEffect(() => {
fetchBlocks();
}, [fetchBlocks]);
useEffect(() => {
- const handleNewBlock = async (newBlock: Block) => {
+ const handleNewBlock = async (newBlock: any) => {
try {
- if (!blocks.some(block => block.number === newBlock.number)) {
- if (currentPage === 0) {
- setBlocks(prevBlocks => [newBlock, ...prevBlocks.slice(0, BLOCKS_PER_PAGE - 1)]);
-
- newBlock.transactions.forEach(tx => decodeTransactionData(tx as Transaction));
-
- const receipts = await Promise.all(
- newBlock.transactions.map(async tx => {
- try {
- const receipt = await client.getTransactionReceipt({ hash: (tx as Transaction).hash });
- return { [(tx as Transaction).hash]: receipt };
- } catch (err) {
- setError(err instanceof Error ? err : new Error("An error occurred."));
- throw err;
- }
- }),
+ if (currentPage === 0) {
+ if (newBlock.transactions.length > 0) {
+ const transactionsDetails = await Promise.all(
+ newBlock.transactions.map((txHash: string) => testClient.getTransaction({ hash: txHash as Hash })),
);
-
- setTransactionReceipts(prevReceipts => ({ ...prevReceipts, ...Object.assign({}, ...receipts) }));
- }
- if (newBlock.number) {
- setTotalBlocks(newBlock.number);
+ newBlock.transactions = transactionsDetails;
}
+
+ newBlock.transactions.forEach((tx: Transaction) => decodeTransactionData(tx as Transaction));
+
+ const receipts = await Promise.all(
+ newBlock.transactions.map(async (tx: Transaction) => {
+ try {
+ const receipt = await testClient.getTransactionReceipt({ hash: (tx as Transaction).hash });
+ return { [(tx as Transaction).hash]: receipt };
+ } catch (err) {
+ setError(err instanceof Error ? err : new Error("An error occurred fetching receipt."));
+ throw err;
+ }
+ }),
+ );
+
+ setBlocks(prevBlocks => [newBlock, ...prevBlocks.slice(0, BLOCKS_PER_PAGE - 1)]);
+ setTransactionReceipts(prevReceipts => ({ ...prevReceipts, ...Object.assign({}, ...receipts) }));
+ }
+ if (newBlock.number) {
+ setTotalBlocks(newBlock.number);
}
} catch (err) {
setError(err instanceof Error ? err : new Error("An error occurred."));
}
};
- return client.watchBlocks({ onBlock: handleNewBlock, includeTransactions: true });
- }, [blocks, client, currentPage]);
+ return testClient.watchBlocks({ onBlock: handleNewBlock, includeTransactions: true });
+ }, [currentPage]);
return {
blocks,
@@ -113,7 +128,6 @@ export const useFetchBlocks = () => {
currentPage,
totalBlocks,
setCurrentPage,
- isLoading,
error,
};
};
diff --git a/packages/nextjs/pages/blockexplorer/address/[address].tsx b/packages/nextjs/pages/blockexplorer/address/[address].tsx
index 6f975df55..6e936fe21 100644
--- a/packages/nextjs/pages/blockexplorer/address/[address].tsx
+++ b/packages/nextjs/pages/blockexplorer/address/[address].tsx
@@ -34,7 +34,7 @@ const publicClient = createPublicClient({
const AddressPage = ({ address, contractData }: PageProps) => {
const router = useRouter();
- const { blocks, transactionReceipts, currentPage, totalBlocks, setCurrentPage, isLoading } = useFetchBlocks();
+ const { blocks, transactionReceipts, currentPage, totalBlocks, setCurrentPage } = useFetchBlocks();
const [activeTab, setActiveTab] = useState("transactions");
const [isContract, setIsContract] = useState(false);
@@ -108,7 +108,7 @@ const AddressPage = ({ address, contractData }: PageProps) => {
)}
{activeTab === "transactions" && (
-
+
{
- const { blocks, transactionReceipts, currentPage, totalBlocks, setCurrentPage, isLoading, error } = useFetchBlocks();
+ const { blocks, transactionReceipts, currentPage, totalBlocks, setCurrentPage, error } = useFetchBlocks();
useEffect(() => {
if (getTargetNetwork().id === hardhat.id && error) {
@@ -51,7 +51,7 @@ const Blockexplorer: NextPage = () => {
return (
);
diff --git a/packages/nextjs/utils/scaffold-eth/block.ts b/packages/nextjs/utils/scaffold-eth/block.ts
index ae22f3152..4cd753fe3 100644
--- a/packages/nextjs/utils/scaffold-eth/block.ts
+++ b/packages/nextjs/utils/scaffold-eth/block.ts
@@ -14,5 +14,4 @@ interface TransactionReceipts {
export interface TransactionsTableProps {
blocks: Block[];
transactionReceipts: TransactionReceipts;
- isLoading: boolean;
}
diff --git a/packages/nextjs/utils/scaffold-eth/decodeTxData.ts b/packages/nextjs/utils/scaffold-eth/decodeTxData.ts
index a32ceabf5..423fe50f3 100644
--- a/packages/nextjs/utils/scaffold-eth/decodeTxData.ts
+++ b/packages/nextjs/utils/scaffold-eth/decodeTxData.ts
@@ -17,7 +17,7 @@ const interfaces = chainMetaData
: {};
export const decodeTransactionData = (tx: TransactionWithFunction) => {
- if (tx.input.length >= 10) {
+ if (tx.input.length >= 10 && !tx.input.startsWith("0x60e06040")) {
for (const [, contractAbi] of Object.entries(interfaces)) {
try {
const { functionName, args } = decodeFunctionData({