Skip to content

Commit

Permalink
confirmations, move helper components outside
Browse files Browse the repository at this point in the history
  • Loading branch information
karooolis committed Sep 27, 2024
1 parent 4f396bc commit 6a214c8
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 120 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ExternalLinkIcon } from "lucide-react";
import { Hex } from "viem";
import { useChain } from "../../../../hooks/useChain";
import { explorerForChainId } from "../../../../utils/explorerForChainId";

export function BlockExplorerLink({ hash }: { hash?: Hex }) {
const { id: chainId } = useChain();
const explorerUrl = explorerForChainId({ hash, chainId });
if (!explorerUrl) return null;

return (
<a href={`${explorerUrl}/tx/${hash}`} target="_blank" rel="noopener noreferrer" className="flex hover:underline">
<ExternalLinkIcon className="mr-2 h-3 w-3" /> Link
</a>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Hex } from "viem";
import { useTransactionConfirmations } from "wagmi";
import { useChain } from "../../../../hooks/useChain";

export function Confirmations({ hash }: { hash?: Hex }) {
const { id: chainId } = useChain();
const { data: confirmations } = useTransactionConfirmations({
hash,
chainId,
query: {
refetchInterval: 1000,
},
});

if (!confirmations) return null;
return (
<span className="flex items-center text-xs font-extrabold text-green-600">
<span
className="mr-2 inline-block h-[8px] w-[8px] animate-pulse rounded-full"
style={{
background: "rgb(64, 182, 107)",
}}
></span>
<span className="opacity-70">{confirmations.toString()}</span>
</span>
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { ExternalLinkIcon } from "lucide-react";
import { Hex } from "viem";
import { Row, flexRender } from "@tanstack/react-table";
import { Separator } from "../../../../../../components/ui/Separator";
import { TableCell, TableRow } from "../../../../../../components/ui/Table";
import { TruncatedHex } from "../../../../../../components/ui/TruncatedHex";
import { useChain } from "../../../../hooks/useChain";
import { explorerForChainId } from "../../../../utils/explorerForChainId";
import { BlockExplorerLink } from "./BlockExplorerLink";
import { Confirmations } from "./Confirmations";
import { WatchedTransaction } from "./TransactionsTable";
import { columns } from "./columns";
import { columns } from "./TransactionsTable";

function TranctionTableRowDataCell({ label, children }: { label: string; children: React.ReactNode }) {
return (
Expand All @@ -18,18 +16,7 @@ function TranctionTableRowDataCell({ label, children }: { label: string; childre
);
}

function BlockExplorerLink({ hash, chainId }: { hash?: Hex; chainId: number }) {
const explorerUrl = explorerForChainId({ hash, chainId });
if (!explorerUrl) return null;

return (
<a href={`${explorerUrl}/tx/${hash}`} target="_blank" rel="noopener noreferrer" className="flex hover:underline">
<ExternalLinkIcon className="mr-2 h-3 w-3" /> Link
</a>
);
}
export function TransactionTableRow({ row }: { row: Row<WatchedTransaction> }) {
const { id: chainId } = useChain();
const data = row?.original;
return (
<>
Expand All @@ -54,35 +41,19 @@ export function TransactionTableRow({ row }: { row: Row<WatchedTransaction> }) {
<TranctionTableRowDataCell label="From">
{data?.transaction?.from && <TruncatedHex hex={data.transaction.from} />}
</TranctionTableRowDataCell>
<TranctionTableRowDataCell label="Explorer URL">
<BlockExplorerLink hash={data.transaction?.hash} chainId={chainId} />
<TranctionTableRowDataCell label="Confirmations">
<Confirmations hash={data.transaction?.hash} />
</TranctionTableRowDataCell>
<TranctionTableRowDataCell label="Tx value">
{data.transaction?.value?.toString()}
</TranctionTableRowDataCell>
<TranctionTableRowDataCell label="Gas used">
{data?.receipt?.gasUsed.toString()}
</TranctionTableRowDataCell>
<TranctionTableRowDataCell label="Base fee">
{data?.transaction?.maxFeePerGas?.toString()}
</TranctionTableRowDataCell>
<TranctionTableRowDataCell label="Priority fee">
{data?.transaction?.maxFeePerGas?.toString()}
</TranctionTableRowDataCell>
<TranctionTableRowDataCell label="Gas price">
{data.receipt?.effectiveGasPrice.toString()}
<TranctionTableRowDataCell label="Explorer URL">
<BlockExplorerLink hash={data.transaction?.hash} />
</TranctionTableRowDataCell>
</div>

<Separator className="mt-6" />

<div className="mt-6">
<h3 className="pb-2 text-xs font-bold uppercase text-muted-foreground">Errors:</h3>
<p className="text-sm">{data.status === "success" ? "No errors" : "Transaction failed"}</p>
</div>

<Separator className="mt-6" />

<div className="mt-6 pb-2">
<h3 className="pb-2 text-xs font-bold uppercase text-muted-foreground">Inputs:</h3>

Expand All @@ -103,18 +74,21 @@ export function TransactionTableRow({ row }: { row: Row<WatchedTransaction> }) {
<div className="mt-2 break-all border border-white/20 p-2">
{Array.isArray(data.logs) && data.logs.length > 0 && (
<ul>
{data.logs.map((eventLog, idx) => (
{data.logs.map((log, idx) => (
<li key={idx}>
<span className="text-xs">{eventLog.eventName}:</span>
{/* @ts-expect-error TODO: types needs fixing */}
<span className="text-xs">{log.eventName}:</span>
<ul className="list-inside pt-1">
{Object.entries(eventLog.args).map(([key, value]) => (
{/* @ts-expect-error TODO: types needs fixing */}
{Object.entries(log.args as never).map(([key, value]) => (
<li key={key} className="mt-1 flex">
<span className="flex-shrink-0 text-xs text-muted-foreground">{key}: </span>
<span className="ml-2 text-xs">{value}</span>
<span className="ml-2 text-xs">{value as never}</span>
</li>
))}
</ul>

{/* @ts-expect-error TODO: types needs fixing */}
{idx < data.logs.length - 1 && <Separator className="my-4" />}
</li>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ import {
import { useConfig, useWatchBlocks } from "wagmi";
import React, { useState } from "react";
import { ExpandedState, flexRender, getCoreRowModel, getExpandedRowModel, useReactTable } from "@tanstack/react-table";
import { createColumnHelper } from "@tanstack/react-table";
import { getTransaction, getTransactionReceipt } from "@wagmi/core";
import { Badge } from "../../../../../../components/ui/Badge";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../../../../../../components/ui/Table";
import { TruncatedHex } from "../../../../../../components/ui/TruncatedHex";
import { useChain } from "../../../../hooks/useChain";
import { useWorldAbiQuery } from "../../../../queries/useWorldAbiQuery";
import { TimeAgoCell } from "./TimeAgoCell";
import { TransactionTableRow } from "./TransactionTableRow";
import { columns } from "./columns";

export type WatchedTransaction = {
hash: Hex;
Expand All @@ -30,6 +33,49 @@ export type WatchedTransaction = {
status: "pending" | "success" | "failed";
};

const columnHelper = createColumnHelper<WatchedTransaction>();
export const columns = [
columnHelper.accessor("transaction.blockNumber", {
header: "",
cell: (row) => <Badge variant="outline">#{row.getValue()?.toString()}</Badge>,
}),
columnHelper.accessor("hash", {
header: "tx hash:",
cell: (row) => <TruncatedHex hex={row.getValue()} />,
}),
columnHelper.accessor("functionData.functionName", {
header: "function:",
cell: (row) => <Badge variant="secondary">{row.getValue()}</Badge>,
}),
columnHelper.accessor("transaction.from", {
header: "from:",
cell: (row) => {
const from = row.getValue();
if (!from) return null;
return <TruncatedHex hex={from} />;
},
}),
columnHelper.accessor("status", {
header: "status:",
cell: (row) => {
const status = row.getValue();
if (status === "success") {
return <Badge variant="success">success</Badge>;
} else if (status === "failed") {
return <Badge variant="destructive">failed</Badge>;
}
return <Badge variant="outline">pending</Badge>;
},
}),
columnHelper.accessor("timestamp", {
header: "time ago:",
cell: (row) => {
const timestamp = row.getValue();
return <TimeAgoCell timestamp={timestamp} />;
},
}),
];

export function TransactionsTable() {
const { id: chainId } = useChain();
const { worldAddress } = useParams();
Expand Down Expand Up @@ -107,7 +153,7 @@ export function TransactionsTable() {
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => <TransactionTableRow key={row.id} row={row} abi={abi} />)
table.getRowModel().rows.map((row) => <TransactionTableRow key={row.id} row={row} />)
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
Expand Down

This file was deleted.

25 changes: 0 additions & 25 deletions packages/explorer/src/components/ElapsedTime.tsx

This file was deleted.

0 comments on commit 6a214c8

Please sign in to comment.