From 184fcbd38764e3a59e300d715cf14b3625dcb089 Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 7 Jan 2025 18:40:31 +0200 Subject: [PATCH 1/7] add copy button --- .../packages/contracts/worlds.json | 2 +- .../[worldAddress]/interact/FunctionField.tsx | 12 +++++- .../observe/TransactionTableRow.tsx | 16 +++++-- .../explorer/src/components/CopyButton.tsx | 43 +++++++++++++++++++ packages/explorer/src/utils.ts | 6 +++ 5 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 packages/explorer/src/components/CopyButton.tsx diff --git a/examples/local-explorer/packages/contracts/worlds.json b/examples/local-explorer/packages/contracts/worlds.json index 6fed600155..5c28f34f27 100644 --- a/examples/local-explorer/packages/contracts/worlds.json +++ b/examples/local-explorer/packages/contracts/worlds.json @@ -1,5 +1,5 @@ { "31337": { - "address": "0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b" + "address": "0xfdf868ea710ffd8cd33b829c5aff79edd15ecd5f" } } \ No newline at end of file diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx index 4b429cd10b..a0f4ffa64a 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx @@ -12,6 +12,7 @@ import { useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { useConnectModal } from "@rainbow-me/rainbowkit"; +import { CopyButton } from "../../../../../../components/CopyButton"; import { Button } from "../../../../../../components/ui/Button"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "../../../../../../components/ui/Form"; import { Input } from "../../../../../../components/ui/Input"; @@ -167,9 +168,14 @@ export function FunctionField({ worldAbi, functionAbi }: Props) { - {result &&
{result}
} + {result && ( +
+          {result}
+          
+        
+ )} {events && ( -
+
    {events.map((event, idx) => (
  • @@ -188,6 +194,8 @@ export function FunctionField({ worldAbi, functionAbi }: Props) {
  • ))}
+ +
)} {txUrl && ( diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx index ae6b2c544e..6ad87d90d8 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx @@ -1,6 +1,7 @@ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"; import { formatEther } from "viem"; import { Row, flexRender } from "@tanstack/react-table"; +import { CopyButton } from "../../../../../../components/CopyButton"; import { Separator } from "../../../../../../components/ui/Separator"; import { Skeleton } from "../../../../../../components/ui/Skeleton"; import { TableCell, TableRow } from "../../../../../../components/ui/Table"; @@ -85,14 +86,14 @@ export function TransactionTableRow({ row }: { row: Row })

Inputs

-
+
{calls.map((call, idx) => { if (!call.args || call.args.length === 0) { return null; } return ( -
+
{call.functionName}: {call.args?.map((arg, argIdx) => (
@@ -111,6 +112,11 @@ export function TransactionTableRow({ row }: { row: Row })
); })} + +
@@ -121,7 +127,7 @@ export function TransactionTableRow({ row }: { row: Row })

Error

-
+
{data.error.message}
@@ -134,7 +140,7 @@ export function TransactionTableRow({ row }: { row: Row })

Logs

{Array.isArray(logs) && logs.length > 0 ? ( -
+
    {logs.map((log, idx) => { const eventName = "eventName" in log ? log.eventName : null; @@ -157,6 +163,8 @@ export function TransactionTableRow({ row }: { row: Row }) ); })}
+ +
) : status === "pending" ? ( diff --git a/packages/explorer/src/components/CopyButton.tsx b/packages/explorer/src/components/CopyButton.tsx new file mode 100644 index 0000000000..fb8ce7e5e9 --- /dev/null +++ b/packages/explorer/src/components/CopyButton.tsx @@ -0,0 +1,43 @@ +import { CheckIcon, ClipboardIcon } from "lucide-react"; +import { useEffect, useState } from "react"; +import { cn } from "../utils"; +import { Button, ButtonProps } from "./ui/Button"; + +interface CopyButtonProps extends ButtonProps { + value: string; +} + +function copyToClipboard(value: string) { + navigator.clipboard.writeText(value); +} + +export function CopyButton({ className, variant = "outline", value, ...props }: CopyButtonProps) { + const [hasCopied, setHasCopied] = useState(false); + + useEffect(() => { + if (hasCopied) { + setTimeout(() => { + setHasCopied(false); + }, 2000); + } + }, [hasCopied]); + + return ( + + ); +} diff --git a/packages/explorer/src/utils.ts b/packages/explorer/src/utils.ts index 749d306cba..4561acefd8 100644 --- a/packages/explorer/src/utils.ts +++ b/packages/explorer/src/utils.ts @@ -2,6 +2,12 @@ import { formatEther } from "viem"; import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; +Object.defineProperty(BigInt.prototype, "toJSON", { + get() { + return () => String(this); + }, +}); + export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } From 666fd58ba4d6b8b16d850ad91f74ca197ca25325 Mon Sep 17 00:00:00 2001 From: karooolis Date: Wed, 8 Jan 2025 10:48:27 +0200 Subject: [PATCH 2/7] fix css class --- .../worlds/[worldAddress]/observe/TransactionTableRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx index 6ad87d90d8..f0e869fe9b 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx @@ -86,7 +86,7 @@ export function TransactionTableRow({ row }: { row: Row })

Inputs

-
+
{calls.map((call, idx) => { if (!call.args || call.args.length === 0) { return null; From e647ac3705cc857f8bf7af7fbebc2a54625223af Mon Sep 17 00:00:00 2001 From: karooolis Date: Wed, 8 Jan 2025 10:58:01 +0200 Subject: [PATCH 3/7] undo world address change --- examples/local-explorer/packages/contracts/worlds.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/local-explorer/packages/contracts/worlds.json b/examples/local-explorer/packages/contracts/worlds.json index 5c28f34f27..4d4f6774fa 100644 --- a/examples/local-explorer/packages/contracts/worlds.json +++ b/examples/local-explorer/packages/contracts/worlds.json @@ -1,5 +1,5 @@ { "31337": { - "address": "0xfdf868ea710ffd8cd33b829c5aff79edd15ecd5f" + "address": "0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b" } -} \ No newline at end of file +} From b6f22b32b5a84f6d7977178db62560202d607d2b Mon Sep 17 00:00:00 2001 From: Karolis Ramanauskas Date: Wed, 8 Jan 2025 10:59:08 +0200 Subject: [PATCH 4/7] Update worlds.json From c74ceecded8576b2b6f10e9f4afc02ee398aec1c Mon Sep 17 00:00:00 2001 From: Karolis Ramanauskas Date: Wed, 8 Jan 2025 15:52:49 +0200 Subject: [PATCH 5/7] Create five-berries-act.md --- .changeset/five-berries-act.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/five-berries-act.md diff --git a/.changeset/five-berries-act.md b/.changeset/five-berries-act.md new file mode 100644 index 0000000000..746eecd2ab --- /dev/null +++ b/.changeset/five-berries-act.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/explorer": patch +--- + +Added 'Copy to Clipboard' button to relevant sections for easier data copying. From 6065d5ec5e6f3e1aa3afe5cddd71fe12e84dbbcb Mon Sep 17 00:00:00 2001 From: karooolis Date: Fri, 17 Jan 2025 17:15:24 +0200 Subject: [PATCH 6/7] use viem's stringify --- .../worlds/[worldAddress]/explore/ExportButton.tsx | 3 ++- .../[worldAddress]/interact/FunctionField.tsx | 6 +++--- .../worlds/[worldAddress]/interact/InteractForm.tsx | 4 ++-- .../[worldAddress]/observe/TransactionTableRow.tsx | 13 ++++--------- .../src/app/(explorer)/queries/useTableDataQuery.ts | 4 ++-- .../src/app/(explorer)/queries/useTablesQuery.ts | 4 ++-- packages/explorer/src/utils.ts | 6 ------ 7 files changed, 15 insertions(+), 25 deletions(-) diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/ExportButton.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/ExportButton.tsx index 77f5a18cdd..4ecb59d0b6 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/ExportButton.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/ExportButton.tsx @@ -1,4 +1,5 @@ import { DownloadIcon } from "lucide-react"; +import { stringify } from "viem"; import { Button } from "../../../../../../components/ui/Button"; import { DropdownMenu, @@ -29,7 +30,7 @@ export function ExportButton({ tableData, isLoading }: { tableData?: TData; isLo { - const json = JSON.stringify(tableData?.rows, null, 2); + const json = stringify(tableData?.rows, null, 2); exportTableData(json, "data.json", "application/json"); }} > diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx index a0f4ffa64a..e53337e5d7 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx @@ -4,7 +4,7 @@ import { Coins, ExternalLinkIcon, Eye, LoaderIcon, Send } from "lucide-react"; import Link from "next/link"; import { useParams } from "next/navigation"; import { toast } from "sonner"; -import { Abi, AbiFunction, Address, Hex, decodeEventLog } from "viem"; +import { Abi, AbiFunction, Address, Hex, decodeEventLog, stringify } from "viem"; import { useAccount, useConfig } from "wagmi"; import { readContract, waitForTransactionReceipt, writeContract } from "wagmi/actions"; import { z } from "zod"; @@ -80,7 +80,7 @@ export function FunctionField({ worldAbi, functionAbi }: Props) { chainId, }); - setResult(JSON.stringify(result, null, 2)); + setResult(stringify(result, null, 2)); } else { toastId = toast.loading("Transaction submitted"); const txHash = await writeContract(wagmiConfig, { @@ -195,7 +195,7 @@ export function FunctionField({ worldAbi, functionAbi }: Props) { ))} - +
)} {txUrl && ( diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/InteractForm.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/InteractForm.tsx index b32e3b38b0..446af84e64 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/InteractForm.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/InteractForm.tsx @@ -2,7 +2,7 @@ import { Coins, Eye, Send } from "lucide-react"; import { useQueryState } from "nuqs"; -import { AbiFunction } from "viem"; +import { AbiFunction, stringify } from "viem"; import { useDeferredValue, useMemo } from "react"; import { Input } from "../../../../../../components/ui/Input"; import { Separator } from "../../../../../../components/ui/Separator"; @@ -92,7 +92,7 @@ export function InteractForm() { {data?.abi && filteredFunctions.map((abi) => ( - + ))}
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx index f0e869fe9b..149cb8a0a8 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx @@ -1,5 +1,5 @@ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"; -import { formatEther } from "viem"; +import { formatEther, stringify } from "viem"; import { Row, flexRender } from "@tanstack/react-table"; import { CopyButton } from "../../../../../../components/CopyButton"; import { Separator } from "../../../../../../components/ui/Separator"; @@ -99,9 +99,7 @@ export function TransactionTableRow({ row }: { row: Row })
arg {argIdx + 1}: - {typeof arg === "object" && arg !== null - ? JSON.stringify(arg, null, 2) - : String(arg)} + {typeof arg === "object" && arg !== null ? stringify(arg, null, 2) : String(arg)}
))} @@ -113,10 +111,7 @@ export function TransactionTableRow({ row }: { row: Row }) ); })} - +
@@ -164,7 +159,7 @@ export function TransactionTableRow({ row }: { row: Row }) })} - +
) : status === "pending" ? ( diff --git a/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts b/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts index c06601a2c8..6b11a3b600 100644 --- a/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts +++ b/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts @@ -1,5 +1,5 @@ import { useParams } from "next/navigation"; -import { Hex } from "viem"; +import { Hex, stringify } from "viem"; import { Table } from "@latticexyz/config"; import { useQuery } from "@tanstack/react-query"; import { useChain } from "../hooks/useChain"; @@ -32,7 +32,7 @@ export function useTableDataQuery({ table, query, isLiveQuery }: Props) { headers: { "Content-Type": "application/json", }, - body: JSON.stringify([ + body: stringify([ { address: worldAddress as Hex, query: decodedQuery, diff --git a/packages/explorer/src/app/(explorer)/queries/useTablesQuery.ts b/packages/explorer/src/app/(explorer)/queries/useTablesQuery.ts index 90c132fa81..10b3c6cbba 100644 --- a/packages/explorer/src/app/(explorer)/queries/useTablesQuery.ts +++ b/packages/explorer/src/app/(explorer)/queries/useTablesQuery.ts @@ -1,5 +1,5 @@ import { useParams } from "next/navigation"; -import { Hex } from "viem"; +import { Hex, stringify } from "viem"; import { isDefined } from "@latticexyz/common/utils"; import { Table } from "@latticexyz/config"; import mudConfig from "@latticexyz/store/mud.config"; @@ -29,7 +29,7 @@ export function useTablesQuery() { headers: { "Content-Type": "application/json", }, - body: JSON.stringify([ + body: stringify([ { address: worldAddress as Hex, query, diff --git a/packages/explorer/src/utils.ts b/packages/explorer/src/utils.ts index 4561acefd8..749d306cba 100644 --- a/packages/explorer/src/utils.ts +++ b/packages/explorer/src/utils.ts @@ -2,12 +2,6 @@ import { formatEther } from "viem"; import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; -Object.defineProperty(BigInt.prototype, "toJSON", { - get() { - return () => String(this); - }, -}); - export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } From 9a0f6168904a7d7fc26e12756f5fd9a85d03faae Mon Sep 17 00:00:00 2001 From: karooolis Date: Fri, 17 Jan 2025 17:21:49 +0200 Subject: [PATCH 7/7] add padding for read result --- examples/local-explorer/packages/contracts/worlds.json | 2 +- .../worlds/[worldAddress]/interact/FunctionField.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/local-explorer/packages/contracts/worlds.json b/examples/local-explorer/packages/contracts/worlds.json index 4d4f6774fa..6fed600155 100644 --- a/examples/local-explorer/packages/contracts/worlds.json +++ b/examples/local-explorer/packages/contracts/worlds.json @@ -2,4 +2,4 @@ "31337": { "address": "0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b" } -} +} \ No newline at end of file diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx index e53337e5d7..3633db657c 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/interact/FunctionField.tsx @@ -169,7 +169,7 @@ export function FunctionField({ worldAbi, functionAbi }: Props) { {result && ( -
+        
           {result}