From 713e8b99f4f7f72d08eadb627004cd31d7453c5c Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 16 Mar 2026 12:24:05 +0000 Subject: [PATCH 1/2] [#152] Link tx hashes to block explorer Added EXPLORER_URL constant (testnet/mainnet aware) and replaced all plain-text tx hash displays with clickable links to BaseScan. Updated TradingWidget, DonateWidget, and register-agent page (4 occurrences). Fixes #152 Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/contracts/constants.ts | 5 +++++ src/app/register-agent/page.tsx | 22 +++++++++++++++++++--- src/components/DonateWidget.tsx | 12 ++++++++++-- src/components/TradingWidget.tsx | 12 ++++++++++-- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/lib/contracts/constants.ts b/lib/contracts/constants.ts index 453a9597..462bea6d 100644 --- a/lib/contracts/constants.ts +++ b/lib/contracts/constants.ts @@ -15,6 +15,11 @@ const chainId = Number(process.env.NEXT_PUBLIC_CHAIN_ID || "84532"); export const IS_TESTNET = chainId === 84532; export const BASE_CHAIN_ID = chainId; +/** Block explorer base URL (no trailing slash) */ +export const EXPLORER_URL = IS_TESTNET + ? "https://sepolia.basescan.org" + : "https://basescan.org"; + // --------------------------------------------------------------------------- // PlotLink contracts // --------------------------------------------------------------------------- diff --git a/src/app/register-agent/page.tsx b/src/app/register-agent/page.tsx index 7f4da512..897276a8 100644 --- a/src/app/register-agent/page.tsx +++ b/src/app/register-agent/page.tsx @@ -6,7 +6,7 @@ import { decodeEventLog, type Hex } from "viem"; import { useRouter } from "next/navigation"; import { publicClient } from "../../../lib/rpc"; import { erc8004Abi } from "../../../lib/contracts/erc8004"; -import { ERC8004_REGISTRY, BASE_CHAIN_ID } from "../../../lib/contracts/constants"; +import { ERC8004_REGISTRY, BASE_CHAIN_ID, EXPLORER_URL } from "../../../lib/contracts/constants"; import { ConnectWallet } from "../../components/ConnectWallet"; // --------------------------------------------------------------------------- @@ -439,7 +439,15 @@ export default function RegisterAgentPage() { {regTxHash && (
- Tx: {regTxHash.slice(0, 10)}...{regTxHash.slice(-8)} + Tx:{" "} + + {regTxHash.slice(0, 10)}...{regTxHash.slice(-8)} +
)} @@ -670,7 +678,15 @@ export default function RegisterAgentPage() { {bindTxHash && (
- Tx: {bindTxHash.slice(0, 10)}...{bindTxHash.slice(-8)} + Tx:{" "} + + {bindTxHash.slice(0, 10)}...{bindTxHash.slice(-8)} +
)} diff --git a/src/components/DonateWidget.tsx b/src/components/DonateWidget.tsx index c3374521..f091abcb 100644 --- a/src/components/DonateWidget.tsx +++ b/src/components/DonateWidget.tsx @@ -7,7 +7,7 @@ import { parseUnits, formatUnits } from "viem"; import { publicClient } from "../../lib/rpc"; import { erc20Abi } from "../../lib/price"; import { storyFactoryAbi } from "../../lib/contracts/abi"; -import { STORY_FACTORY, PLOT_TOKEN, IS_TESTNET } from "../../lib/contracts/constants"; +import { STORY_FACTORY, PLOT_TOKEN, IS_TESTNET, EXPLORER_URL } from "../../lib/contracts/constants"; type TxState = "idle" | "approving" | "confirming" | "pending" | "indexing" | "done" | "error"; @@ -190,7 +190,15 @@ export function DonateWidget({ storylineId }: DonateWidgetProps) { {error &&

{error}

} {txHash && txState === "done" && (

- Tx: {txHash.slice(0, 10)}...{txHash.slice(-8)} + Tx:{" "} + + {txHash.slice(0, 10)}...{txHash.slice(-8)} +

)} diff --git a/src/components/TradingWidget.tsx b/src/components/TradingWidget.tsx index ed7904cd..1d7bdc51 100644 --- a/src/components/TradingWidget.tsx +++ b/src/components/TradingWidget.tsx @@ -6,7 +6,7 @@ import { useQuery } from "@tanstack/react-query"; import { parseUnits, formatUnits, type Address } from "viem"; import { publicClient } from "../../lib/rpc"; import { mcv2BondAbi, erc20Abi } from "../../lib/price"; -import { MCV2_BOND, PLOT_TOKEN, IS_TESTNET } from "../../lib/contracts/constants"; +import { MCV2_BOND, PLOT_TOKEN, IS_TESTNET, EXPLORER_URL } from "../../lib/contracts/constants"; type Tab = "buy" | "sell"; type TxState = "idle" | "approving" | "confirming" | "pending" | "done" | "error"; @@ -269,7 +269,15 @@ export function TradingWidget({ tokenAddress }: { tokenAddress: Address }) { {error &&

{error}

} {txHash && txState === "done" && (

- Tx: {txHash.slice(0, 10)}...{txHash.slice(-8)} + Tx:{" "} + + {txHash.slice(0, 10)}...{txHash.slice(-8)} +

)} From 8bef8389a2f4939006ef21280935d2a4f96b033a Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 16 Mar 2026 12:26:26 +0000 Subject: [PATCH 2/2] [#152] Add explorer link to ClaimRoyalties tx hash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completes the audit — ClaimRoyalties now tracks and displays the claim tx hash with a clickable BaseScan link. The create/publish flow doesn't display tx hashes so no change needed there. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/ClaimRoyalties.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/ClaimRoyalties.tsx b/src/components/ClaimRoyalties.tsx index 0c1d78be..c6aca146 100644 --- a/src/components/ClaimRoyalties.tsx +++ b/src/components/ClaimRoyalties.tsx @@ -6,7 +6,7 @@ import { useQuery } from "@tanstack/react-query"; import { formatUnits, type Address } from "viem"; import { publicClient } from "../../lib/rpc"; import { mcv2BondAbi } from "../../lib/price"; -import { MCV2_BOND, IS_TESTNET } from "../../lib/contracts/constants"; +import { MCV2_BOND, IS_TESTNET, EXPLORER_URL } from "../../lib/contracts/constants"; type TxState = "idle" | "confirming" | "pending" | "done" | "error"; @@ -20,6 +20,7 @@ export function ClaimRoyalties({ tokenAddress, plotCount, beneficiary }: ClaimRo const [txState, setTxState] = useState("idle"); const [error, setError] = useState(null); const [claimedAmount, setClaimedAmount] = useState(BigInt(0)); + const [txHash, setTxHash] = useState(null); const { writeContractAsync } = useWriteContract(); @@ -55,6 +56,7 @@ export function ClaimRoyalties({ tokenAddress, plotCount, beneficiary }: ClaimRo functionName: "claimRoyalties", args: [tokenAddress], }); + setTxHash(hash); setTxState("pending"); await publicClient.waitForTransactionReceipt({ hash }); @@ -107,6 +109,19 @@ export function ClaimRoyalties({ tokenAddress, plotCount, beneficiary }: ClaimRo )} + {txHash && txState === "done" && ( +

+ Tx:{" "} + + {txHash.slice(0, 10)}...{txHash.slice(-8)} + +

+ )} {error &&

{error}

} );