From e5c7c3b714b63346c803e353381129db445fac80 Mon Sep 17 00:00:00 2001 From: karooolis Date: Wed, 28 Aug 2024 11:03:01 +0300 Subject: [PATCH 1/4] fetch partial abi on load --- packages/explorer/src/app/api/world/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/explorer/src/app/api/world/route.ts b/packages/explorer/src/app/api/world/route.ts index f9f8b45fd5..159c5aef0a 100644 --- a/packages/explorer/src/app/api/world/route.ts +++ b/packages/explorer/src/app/api/world/route.ts @@ -27,7 +27,7 @@ async function getParameters(worldAddress: Address) { fromBlock: "earliest", toBlock, }); - const fromBlock = logs[0].blockNumber; + const fromBlock = logs[0]?.blockNumber ?? 0n; return { fromBlock, toBlock }; } From de8a1440934fb0da0c2b18535acbeda4d7cf62c4 Mon Sep 17 00:00:00 2001 From: karooolis Date: Wed, 28 Aug 2024 13:17:54 +0300 Subject: [PATCH 2/4] add global store, loading skeletons, fetch abi --- examples/local-explorer/mprocs.yaml | 2 +- packages/explorer/src/app/Providers.tsx | 5 ++- packages/explorer/src/app/layout.tsx | 2 - .../explorer/EditableTableCell.tsx | 4 +- .../worlds/[worldAddress]/interact/Form.tsx | 45 +++++++++++++------ .../worlds/[worldAddress]/interact/page.tsx | 23 +--------- .../interact/useContractMutation.ts | 4 +- .../src/app/worlds/[worldAddress]/layout.tsx | 12 +++++ .../explorer/src/components/AccountSelect.tsx | 11 +++-- .../explorer/src/components/LatestBlock.tsx | 29 ++++++------ .../explorer/src/components/Navigation.tsx | 4 ++ .../explorer/src/components/ui/Skeleton.tsx | 7 +++ packages/explorer/src/queries/useAbiQuery.ts | 24 ++++++++++ packages/explorer/src/store.ts | 13 ------ .../explorer/src/store/AppStoreProvider.tsx | 21 +++++++++ packages/explorer/src/store/createAppStore.ts | 15 +++++++ packages/explorer/src/store/index.ts | 3 ++ packages/explorer/src/store/useAppStore.ts | 13 ++++++ 18 files changed, 164 insertions(+), 73 deletions(-) create mode 100644 packages/explorer/src/app/worlds/[worldAddress]/layout.tsx create mode 100644 packages/explorer/src/components/ui/Skeleton.tsx create mode 100644 packages/explorer/src/queries/useAbiQuery.ts delete mode 100644 packages/explorer/src/store.ts create mode 100644 packages/explorer/src/store/AppStoreProvider.tsx create mode 100644 packages/explorer/src/store/createAppStore.ts create mode 100644 packages/explorer/src/store/index.ts create mode 100644 packages/explorer/src/store/useAppStore.ts diff --git a/examples/local-explorer/mprocs.yaml b/examples/local-explorer/mprocs.yaml index ab44f56d3e..2e20f8bbab 100644 --- a/examples/local-explorer/mprocs.yaml +++ b/examples/local-explorer/mprocs.yaml @@ -17,4 +17,4 @@ procs: SQLITE_FILENAME: "indexer.db" explorer: cwd: packages/contracts - shell: pnpm explorer + shell: pnpm explorer --env development diff --git a/packages/explorer/src/app/Providers.tsx b/packages/explorer/src/app/Providers.tsx index 4ca56ec072..d930de1dba 100644 --- a/packages/explorer/src/app/Providers.tsx +++ b/packages/explorer/src/app/Providers.tsx @@ -6,6 +6,7 @@ import { ReactNode } from "react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { createConfig, http } from "@wagmi/core"; import { localhost } from "@wagmi/core/chains"; +import { AppStoreProvider } from "../store"; const queryClient = new QueryClient(); @@ -28,7 +29,9 @@ export const wagmiConfig = createConfig({ export function Providers({ children }: { children: ReactNode }) { return ( - {children} + + {children} + ); } diff --git a/packages/explorer/src/app/layout.tsx b/packages/explorer/src/app/layout.tsx index 9ad2c8bfea..4bcb74b30b 100644 --- a/packages/explorer/src/app/layout.tsx +++ b/packages/explorer/src/app/layout.tsx @@ -3,7 +3,6 @@ import { Inter, JetBrains_Mono } from "next/font/google"; import { Toaster } from "sonner"; import { Theme } from "@radix-ui/themes"; import "@radix-ui/themes/styles.css"; -import { Navigation } from "../components/Navigation"; import { Providers } from "./Providers"; import "./globals.css"; @@ -39,7 +38,6 @@ export default function RootLayout({ fontFamily: "var(--font-jetbrains-mono)", }} > - {children} diff --git a/packages/explorer/src/app/worlds/[worldAddress]/explorer/EditableTableCell.tsx b/packages/explorer/src/app/worlds/[worldAddress]/explorer/EditableTableCell.tsx index 4040cc825b..15822d6c74 100644 --- a/packages/explorer/src/app/worlds/[worldAddress]/explorer/EditableTableCell.tsx +++ b/packages/explorer/src/app/worlds/[worldAddress]/explorer/EditableTableCell.tsx @@ -13,7 +13,7 @@ import { waitForTransactionReceipt, writeContract } from "@wagmi/core"; import { Checkbox } from "../../../../components/ui/Checkbox"; import { ACCOUNT_PRIVATE_KEYS } from "../../../../consts"; import { camelCase, cn } from "../../../../lib/utils"; -import { useStore } from "../../../../store"; +import { useAppStore } from "../../../../store"; import { wagmiConfig } from "../../../Providers"; import { TableConfig } from "../../../api/table/route"; @@ -27,7 +27,7 @@ type Props = { export function EditableTableCell({ name, config, keyTuple, value: defaultValue }: Props) { const queryClient = useQueryClient(); const chainId = useChainId(); - const { account } = useStore(); + const { account } = useAppStore(); const { worldAddress } = useParams(); const [value, setValue] = useState(defaultValue); diff --git a/packages/explorer/src/app/worlds/[worldAddress]/interact/Form.tsx b/packages/explorer/src/app/worlds/[worldAddress]/interact/Form.tsx index cf01952cd9..0afb199ab1 100644 --- a/packages/explorer/src/app/worlds/[worldAddress]/interact/Form.tsx +++ b/packages/explorer/src/app/worlds/[worldAddress]/interact/Form.tsx @@ -4,23 +4,23 @@ import { Coins, Eye, Send } from "lucide-react"; import { AbiFunction } from "viem"; import { useDeferredValue, useState } from "react"; import { Input } from "../../../../components/ui/Input"; +import { Separator } from "../../../../components/ui/Separator"; +import { Skeleton } from "../../../../components/ui/Skeleton"; import { useHashState } from "../../../../hooks/useHashState"; import { cn } from "../../../../lib/utils"; +import { useAbiQuery } from "../../../../queries/useAbiQuery"; import { FunctionField } from "./FunctionField"; -type Props = { - abi: AbiFunction[]; -}; - -export function Form({ abi }: Props) { +export function Form() { const [hash] = useHashState(); + const { data: abi, isFetched } = useAbiQuery(); const [filterValue, setFilterValue] = useState(""); const deferredFilterValue = useDeferredValue(filterValue); - const filteredFunctions = abi.filter((item) => item.name.toLowerCase().includes(deferredFilterValue.toLowerCase())); + const filteredFunctions = abi?.filter((item) => item.name.toLowerCase().includes(deferredFilterValue.toLowerCase())); return ( -
-
+
+

Jump to:

@@ -39,11 +39,16 @@ export function Form({ abi }: Props) { maxHeight: "calc(100vh - 160px)", }} > - {filteredFunctions.map((abi, index) => { - if ((abi as AbiFunction).type !== "function") { - return null; - } + {!isFetched && + Array.from({ length: 10 }).map((_, index) => { + return ( +
  • + +
  • + ); + })} + {filteredFunctions?.map((abi, index) => { return (
  • -
    - {filteredFunctions.map((abi) => { +
    + {!isFetched && ( + <> + + + + + + + + + )} + + {filteredFunctions?.map((abi) => { return ; })}
    diff --git a/packages/explorer/src/app/worlds/[worldAddress]/interact/page.tsx b/packages/explorer/src/app/worlds/[worldAddress]/interact/page.tsx index 46df999240..a3a3355c97 100644 --- a/packages/explorer/src/app/worlds/[worldAddress]/interact/page.tsx +++ b/packages/explorer/src/app/worlds/[worldAddress]/interact/page.tsx @@ -1,24 +1,5 @@ -import { headers } from "next/headers"; -import { Hex } from "viem"; import { Form } from "./Form"; -async function getABI(worldAddress: Hex) { - const headersList = headers(); - const protocol = headersList.get("x-forwarded-proto"); - const host = headersList.get("host"); - - const res = await fetch(`${protocol}://${host}/api/world?${new URLSearchParams({ address: worldAddress })}`); - const data = await res.json(); - - if (!res.ok) { - throw new Error(data.error); - } - - return data; -} - -export default async function InteractPage({ params }: { params: { worldAddress: Hex } }) { - const { worldAddress } = params; - const data = await getABI(worldAddress); - return
    ; +export default async function InteractPage() { + return ; } diff --git a/packages/explorer/src/app/worlds/[worldAddress]/interact/useContractMutation.ts b/packages/explorer/src/app/worlds/[worldAddress]/interact/useContractMutation.ts index d14a3ea16c..720fe207c4 100644 --- a/packages/explorer/src/app/worlds/[worldAddress]/interact/useContractMutation.ts +++ b/packages/explorer/src/app/worlds/[worldAddress]/interact/useContractMutation.ts @@ -6,7 +6,7 @@ import { useChainId } from "wagmi"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { readContract, waitForTransactionReceipt, writeContract } from "@wagmi/core"; import { ACCOUNT_PRIVATE_KEYS } from "../../../../consts"; -import { useStore } from "../../../../store"; +import { useAppStore } from "../../../../store"; import { wagmiConfig } from "../../../Providers"; import { FunctionType } from "./FunctionField"; @@ -18,7 +18,7 @@ type UseContractMutationProps = { export function useContractMutation({ abi, operationType }: UseContractMutationProps) { const queryClient = useQueryClient(); const chainId = useChainId(); - const { account } = useStore(); + const { account } = useAppStore(); const { worldAddress } = useParams(); return useMutation({ diff --git a/packages/explorer/src/app/worlds/[worldAddress]/layout.tsx b/packages/explorer/src/app/worlds/[worldAddress]/layout.tsx new file mode 100644 index 0000000000..30e9291148 --- /dev/null +++ b/packages/explorer/src/app/worlds/[worldAddress]/layout.tsx @@ -0,0 +1,12 @@ +"use client"; + +import { Navigation } from "../../../components/Navigation"; + +export default function WorldLayout({ children }: { children: React.ReactNode }) { + return ( +
    + + {children} +
    + ); +} diff --git a/packages/explorer/src/components/AccountSelect.tsx b/packages/explorer/src/components/AccountSelect.tsx index 9127682ad8..5f828734bc 100644 --- a/packages/explorer/src/components/AccountSelect.tsx +++ b/packages/explorer/src/components/AccountSelect.tsx @@ -1,11 +1,16 @@ import { Address, formatEther } from "viem"; import { useBalance } from "wagmi"; import { ACCOUNTS } from "../consts"; -import { useStore } from "../store"; +import { useAppStore } from "../store"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/Select"; import { TruncatedHex } from "./ui/TruncatedHex"; -function AccountSelectItem({ address, name }: { address: Address; name: string }) { +type Props = { + address: Address; + name: string; +}; + +function AccountSelectItem({ address, name }: Props) { const balance = useBalance({ address, query: { @@ -25,7 +30,7 @@ function AccountSelectItem({ address, name }: { address: Address; name: string } } export function AccountSelect() { - const { account, setAccount } = useStore(); + const { account, setAccount } = useAppStore(); return (