From 0dda4f03bcb2c13382697a824c1d15965ff33de9 Mon Sep 17 00:00:00 2001 From: Assad Isah Date: Sat, 20 Sep 2025 10:42:08 +0100 Subject: [PATCH] feat: add ContractDemo component for interacting with Proof of Fandom contract --- app/profile/page.tsx | 95 ++++++++++++++++++++++++++++++++ components/web3/ContractDemo.tsx | 95 ++++++++++++++++++++++++++++++++ lib/abi/ProofOfFandom.json | 28 ++++++++++ lib/abi/contracts.ts | 12 ++++ 4 files changed, 230 insertions(+) create mode 100644 app/profile/page.tsx create mode 100644 components/web3/ContractDemo.tsx create mode 100644 lib/abi/ProofOfFandom.json create mode 100644 lib/abi/contracts.ts diff --git a/app/profile/page.tsx b/app/profile/page.tsx new file mode 100644 index 0000000..f304d50 --- /dev/null +++ b/app/profile/page.tsx @@ -0,0 +1,95 @@ +'use client' + +import { proofOfFandomContract } from '@/lib/contracts' +import { + useAccount, + useReadContract, + useWriteContract, + useWaitForTransactionReceipt, +} from 'wagmi' +import { useState } from 'react' + +export default function ContractDemo() { + const { address, isConnected } = useAccount() + const [minted, setMinted] = useState(false) + + const { data: balance, isLoading: isBalanceLoading } = useReadContract({ + ...proofOfFandomContract, + functionName: 'balanceOf', + args: [address!], + query: { + enabled: isConnected, + }, + }) + + const { data: hash, writeContract, isPending } = useWriteContract() + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + const handleMint = () => { + writeContract({ + ...proofOfFandomContract, + functionName: 'mint', + args: [], + }) + } + + if (isConfirmed && !minted) { + setMinted(true) + } + + if (!isConnected) { + return ( +

+ Please connect your wallet to interact with the contract. +

+ ) + } + + return ( +
+

Proof of Fandom Contract

+ +
+

Your Fandom Token Balance:

+ {isBalanceLoading ? ( + Loading... + ) : ( + + {balance?.toString() ?? '0'} + + )} +
+ +
+ + {hash && ( +

+ Transaction Hash: {`${hash.slice(0, 6)}...${hash.slice(-4)}`} +

+ )} + {minted && ( +

Minted Successfully!

+ )} +
+

+ Note: This interacts with a dummy contract address. The transaction will + be sent but is expected to fail on-chain. This demo is to verify the + frontend flow. +

+
+ ) +} diff --git a/components/web3/ContractDemo.tsx b/components/web3/ContractDemo.tsx new file mode 100644 index 0000000..f304d50 --- /dev/null +++ b/components/web3/ContractDemo.tsx @@ -0,0 +1,95 @@ +'use client' + +import { proofOfFandomContract } from '@/lib/contracts' +import { + useAccount, + useReadContract, + useWriteContract, + useWaitForTransactionReceipt, +} from 'wagmi' +import { useState } from 'react' + +export default function ContractDemo() { + const { address, isConnected } = useAccount() + const [minted, setMinted] = useState(false) + + const { data: balance, isLoading: isBalanceLoading } = useReadContract({ + ...proofOfFandomContract, + functionName: 'balanceOf', + args: [address!], + query: { + enabled: isConnected, + }, + }) + + const { data: hash, writeContract, isPending } = useWriteContract() + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + const handleMint = () => { + writeContract({ + ...proofOfFandomContract, + functionName: 'mint', + args: [], + }) + } + + if (isConfirmed && !minted) { + setMinted(true) + } + + if (!isConnected) { + return ( +

+ Please connect your wallet to interact with the contract. +

+ ) + } + + return ( +
+

Proof of Fandom Contract

+ +
+

Your Fandom Token Balance:

+ {isBalanceLoading ? ( + Loading... + ) : ( + + {balance?.toString() ?? '0'} + + )} +
+ +
+ + {hash && ( +

+ Transaction Hash: {`${hash.slice(0, 6)}...${hash.slice(-4)}`} +

+ )} + {minted && ( +

Minted Successfully!

+ )} +
+

+ Note: This interacts with a dummy contract address. The transaction will + be sent but is expected to fail on-chain. This demo is to verify the + frontend flow. +

+
+ ) +} diff --git a/lib/abi/ProofOfFandom.json b/lib/abi/ProofOfFandom.json new file mode 100644 index 0000000..9486142 --- /dev/null +++ b/lib/abi/ProofOfFandom.json @@ -0,0 +1,28 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/lib/abi/contracts.ts b/lib/abi/contracts.ts new file mode 100644 index 0000000..47bcfeb --- /dev/null +++ b/lib/abi/contracts.ts @@ -0,0 +1,12 @@ +import proofOfFandomAbi from './abi/ProofOfFandom.json' +import { flare, songbird } from './chains' + +const proofOfFandomAddress = + '0x1234567890123456789012345678901234567890' as const + +export const proofOfFandomContract = { + address: proofOfFandomAddress, + abi: proofOfFandomAbi, + + chains: [flare.id, songbird.id], +}