From 99fd63c14d76d1359cc1959be1503253b44cd51a Mon Sep 17 00:00:00 2001 From: tim Date: Mon, 13 Oct 2025 15:59:56 -0400 Subject: [PATCH] token count example component --- src/app/page.tsx | 6 +- src/components/token-count-display.tsx | 96 ++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/components/token-count-display.tsx diff --git a/src/app/page.tsx b/src/app/page.tsx index 4249939..d370c81 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { SwapForm } from '@/components/swap-form'; +import { TokenCountDisplay } from '@/components/token-count-display'; export default function HomePage() { const { t } = useTranslation(); @@ -16,7 +17,10 @@ export default function HomePage() { - +
+ + +
diff --git a/src/components/token-count-display.tsx b/src/components/token-count-display.tsx new file mode 100644 index 0000000..001348b --- /dev/null +++ b/src/components/token-count-display.tsx @@ -0,0 +1,96 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { usePublicClient } from 'wagmi'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import IPartyPlannerABI from '@/contracts/IPartyPlannerABI'; + +const PARTY_PLANNER_ADDRESS = '0xB35D3C9b9f2Fd72FAAb282E8Dd56da31FAA30E3d' as const; + +export function TokenCountDisplay() { + const publicClient = usePublicClient(); + const [mounted, setMounted] = useState(false); + const [tokenCount, setTokenCount] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Handle hydration for Next.js static export + useEffect(() => { + setMounted(true); + }, []); + + useEffect(() => { + if (!mounted) return; + + const fetchTokenCount = async () => { + if (!publicClient) { + setLoading(false); + return; + } + + try { + setLoading(true); + setError(null); + + // In viem 2.x, readContract is a method on the client + const count = await publicClient.readContract({ + address: PARTY_PLANNER_ADDRESS, + abi: IPartyPlannerABI, + functionName: 'tokenCount', // Fully typed from ABI + }); + + setTokenCount(count); + } catch (err) { + console.error('Error reading token count:', err); + setError(err instanceof Error ? err.message : 'Failed to read token count'); + } finally { + setLoading(false); + } + }; + + fetchTokenCount(); + }, [publicClient, mounted]); + + // Don't render until client-side hydration is complete + if (!mounted) { + return ( + + + Party Planner Token Count + + +

Loading...

+
+
+ ); + } + + return ( + + + Party Planner Token Count + + + {loading && ( +

Loading token count...

+ )} + + {error && ( +

Error: {error}

+ )} + + {tokenCount !== null && !loading && ( +
+

{tokenCount.toString()}

+

+ Total tokens in Party Planner +

+

+ Contract: {PARTY_PLANNER_ADDRESS} +

+
+ )} +
+
+ ); +}