diff --git a/agw-connectkit-nextjs/src/app/layout.tsx b/agw-connectkit-nextjs/src/app/layout.tsx index 622b926..b79cf19 100644 --- a/agw-connectkit-nextjs/src/app/layout.tsx +++ b/agw-connectkit-nextjs/src/app/layout.tsx @@ -1,8 +1,8 @@ +import "@rainbow-me/rainbowkit/styles.css"; import type { Metadata } from "next"; import localFont from "next/font/local"; -import NextAbstractWalletProvider from "../components/NextAbstractWalletProvider"; +import NextAbstractWalletProvider from "../components/provider/NextAbstractWalletProvider"; import "./globals.css"; -import "@rainbow-me/rainbowkit/styles.css"; // Default Fonts from Next.js const geistSans = localFont({ diff --git a/agw-connectkit-nextjs/src/app/page.tsx b/agw-connectkit-nextjs/src/app/page.tsx index 1d01003..0e9af36 100644 --- a/agw-connectkit-nextjs/src/app/page.tsx +++ b/agw-connectkit-nextjs/src/app/page.tsx @@ -1,230 +1,46 @@ "use client"; -import Image from "next/image"; -import { - useLoginWithAbstract, - useWriteContractSponsored, -} from "@abstract-foundation/agw-react"; -import { useAccount, useWaitForTransactionReceipt } from "wagmi"; -import { getGeneralPaymasterInput } from "viem/zksync"; -import { parseAbi } from "viem"; +import { useLoginWithAbstract } from "@abstract-foundation/agw-react"; import { ConnectKitButton } from "connectkit"; +import { useAccount } from "wagmi"; + +import Header from "@/components/Header"; +import ResourcesSection from "@/components/ResourceSection"; +import BackgroundEffects from "@/components/ui/BackgroundEffect"; +import LoadingSpinner from "@/components/ui/LoadingSpinner"; +import ConnectedWallet from "@/components/wallet/ConnectWallet"; +import { useContract } from "@/hooks/useContract"; export default function Home() { const { logout } = useLoginWithAbstract(); const { address, status } = useAccount(); - const { writeContractSponsored, data: transactionHash } = - useWriteContractSponsored(); - const { data: transactionReceipt } = useWaitForTransactionReceipt({ - hash: transactionHash, - }); + const { mintToken, transactionReceipt, canSubmitTransaction } = useContract(); return (
- {/* Grids and aurora gradients */} -
-
-
+ - {/* Main content */}
-
-
- Abstract logo - 🤝 - Family logo + +
+ {status === "connected" ? ( + mintToken(address!)} + canSubmitTransaction={canSubmitTransaction} + transactionReceipt={transactionReceipt} /> -
-

- Get started by editing{" "} - - src/app/page.tsx - - . -

- -
- {status === "connected" ? ( -
-
-
-

- Connected to Abstract Global Wallet -

-

{address}

-

- - View on Explorer - -

-
-
- - -
- {!!transactionReceipt && ( - -

- Transaction Status: {transactionReceipt?.status} -

-

- {transactionReceipt?.transactionHash?.slice(0, 8)}... - {transactionReceipt?.transactionHash?.slice(-6)} -

-
- )} -
-
- ) : status === "reconnecting" || status === "connecting" ? ( -
- Loading -
- ) : ( - - )} -
+ ) : status === "reconnecting" || status === "connecting" ? ( + + ) : ( + + )}
- {/* Cards section */} -
- - - - -

- Documentation -

-

Explore our developer docs.

-
- - - - - -

- GitHub Examples -

-

- View our example repos on GitHub. -

-
- - - - - -

- YouTube Channel -

-

- Watch our video tutorials on YouTube. -

-
-
+
); } diff --git a/agw-connectkit-nextjs/src/components/Header.tsx b/agw-connectkit-nextjs/src/components/Header.tsx new file mode 100644 index 0000000..be4bf2b --- /dev/null +++ b/agw-connectkit-nextjs/src/components/Header.tsx @@ -0,0 +1,35 @@ +import Image from "next/image"; + +export default function Header() { + return ( +
+
+ Abstract logo + 🤝 + Family logo +
+

+ Get started by editing{" "} + + src/app/page.tsx + + . +

+
+ ); +} diff --git a/agw-connectkit-nextjs/src/components/ResourceCard.tsx b/agw-connectkit-nextjs/src/components/ResourceCard.tsx new file mode 100644 index 0000000..c3a348c --- /dev/null +++ b/agw-connectkit-nextjs/src/components/ResourceCard.tsx @@ -0,0 +1,26 @@ +import { ReactNode } from "react"; + +interface ResourceCardProps { + href: string; + icon: ReactNode; + title: string; + description: string; +} + +export const ResourceCard = ({ + href, + icon, + title, + description, +}: ResourceCardProps) => ( + +
{icon}
+

{title}

+

{description}

+
+); diff --git a/agw-connectkit-nextjs/src/components/ResourceSection.tsx b/agw-connectkit-nextjs/src/components/ResourceSection.tsx new file mode 100644 index 0000000..a53e86f --- /dev/null +++ b/agw-connectkit-nextjs/src/components/ResourceSection.tsx @@ -0,0 +1,58 @@ +export default function ResourcesSection() { + return ( +
+ + + + +

Documentation

+

Explore our developer docs.

+
+ + + + + +

+ GitHub Examples +

+

View our example repos on GitHub.

+
+ + + + + +

+ YouTube Channel +

+

+ Watch our video tutorials on YouTube. +

+
+
+ ); +} diff --git a/agw-connectkit-nextjs/src/components/icons/Icons.tsx b/agw-connectkit-nextjs/src/components/icons/Icons.tsx new file mode 100644 index 0000000..9927444 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/icons/Icons.tsx @@ -0,0 +1,37 @@ +interface IconProps { + className?: string; +} + +export const LogoutIcon = ({ className = "w-4 h-4" }: IconProps) => ( + + + +); + +export const LightningIcon = ({ className = "w-4 h-4" }: IconProps) => ( + + + +); diff --git a/agw-connectkit-nextjs/src/components/NextAbstractWalletProvider.tsx b/agw-connectkit-nextjs/src/components/provider/NextAbstractWalletProvider.tsx similarity index 100% rename from agw-connectkit-nextjs/src/components/NextAbstractWalletProvider.tsx rename to agw-connectkit-nextjs/src/components/provider/NextAbstractWalletProvider.tsx index eea50a7..2f388af 100644 --- a/agw-connectkit-nextjs/src/components/NextAbstractWalletProvider.tsx +++ b/agw-connectkit-nextjs/src/components/provider/NextAbstractWalletProvider.tsx @@ -1,10 +1,10 @@ "use client"; +import { abstractWalletConnector } from "@abstract-foundation/agw-react/connectors"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { WagmiProvider, createConfig, http } from "wagmi"; import { ConnectKitProvider } from "connectkit"; import { abstractTestnet } from "viem/chains"; -import { abstractWalletConnector } from "@abstract-foundation/agw-react/connectors"; +import { WagmiProvider, createConfig, http } from "wagmi"; export default function AbstractWalletWrapper({ children, diff --git a/agw-connectkit-nextjs/src/components/ui/BackgroundEffect.tsx b/agw-connectkit-nextjs/src/components/ui/BackgroundEffect.tsx new file mode 100644 index 0000000..42e4d08 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/ui/BackgroundEffect.tsx @@ -0,0 +1,10 @@ +export default function BackgroundEffects() { + return ( + <> + {/* Grids and aurora gradients */} +
+
+
+ + ); +} diff --git a/agw-connectkit-nextjs/src/components/ui/Button.tsx b/agw-connectkit-nextjs/src/components/ui/Button.tsx new file mode 100644 index 0000000..9400fb7 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/ui/Button.tsx @@ -0,0 +1,38 @@ +import { ReactNode } from "react"; + +interface ButtonProps { + onClick?: () => void; + disabled?: boolean; + variant?: "primary" | "secondary" | "gradient"; + children: ReactNode; + className?: string; +} + +export const Button = ({ + onClick, + disabled, + variant = "primary", + children, + className = "", +}: ButtonProps) => { + const baseClasses = + "rounded-full border border-solid transition-colors flex items-center justify-center text-white gap-2 text-sm h-10 px-5 font-[family-name:var(--font-roobert)]"; + + const variantClasses = { + primary: "border-white/20 bg-white/10 hover:bg-white/20", + secondary: "border-white/10 bg-white/5 hover:bg-white/10", + gradient: disabled + ? "bg-gray-500 cursor-not-allowed opacity-50 border-gray-500" + : "bg-gradient-to-r from-green-400 to-green-600 hover:from-green-500 hover:to-green-700 border-transparent", + }; + + return ( + + ); +}; diff --git a/agw-connectkit-nextjs/src/components/ui/LoadingSpinner.tsx b/agw-connectkit-nextjs/src/components/ui/LoadingSpinner.tsx new file mode 100644 index 0000000..291bde4 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/ui/LoadingSpinner.tsx @@ -0,0 +1,9 @@ +import Image from "next/image"; + +export default function LoadingSpinner() { + return ( +
+ Loading +
+ ); +} diff --git a/agw-connectkit-nextjs/src/components/wallet/ConnectWallet.tsx b/agw-connectkit-nextjs/src/components/wallet/ConnectWallet.tsx new file mode 100644 index 0000000..845ea87 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/wallet/ConnectWallet.tsx @@ -0,0 +1,103 @@ +interface ConnectedWalletProps { + address: string; + onLogout: () => void; + onSubmitTransaction: () => void; + canSubmitTransaction: boolean; + transactionReceipt?: { + transactionHash: string; + status: string; + } | null; +} + +export default function ConnectedWallet({ + address, + onLogout, + onSubmitTransaction, + canSubmitTransaction, + transactionReceipt, +}: ConnectedWalletProps) { + return ( +
+
+
+

+ Connected to Abstract Global Wallet +

+

{address}

+

+ + View on Explorer + +

+
+
+ + +
+ {!!transactionReceipt && ( + +

+ Transaction Status: {transactionReceipt?.status} +

+

+ {transactionReceipt?.transactionHash?.slice(0, 8)}... + {transactionReceipt?.transactionHash?.slice(-6)} +

+
+ )} +
+
+ ); +} diff --git a/agw-connectkit-nextjs/src/components/wallet/TransactionResult.tsx b/agw-connectkit-nextjs/src/components/wallet/TransactionResult.tsx new file mode 100644 index 0000000..588cd96 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/wallet/TransactionResult.tsx @@ -0,0 +1,23 @@ +interface TransactionResultProps { + transactionHash: string; + status: string; +} + +export const TransactionResult = ({ + transactionHash, + status, +}: TransactionResultProps) => ( + +

+ Transaction Status: {status} +

+

+ {transactionHash?.slice(0, 8)}...{transactionHash?.slice(-6)} +

+
+); diff --git a/agw-connectkit-nextjs/src/components/wallet/WalletActions.tsx b/agw-connectkit-nextjs/src/components/wallet/WalletActions.tsx new file mode 100644 index 0000000..2585934 --- /dev/null +++ b/agw-connectkit-nextjs/src/components/wallet/WalletActions.tsx @@ -0,0 +1,30 @@ +import { LightningIcon, LogoutIcon } from "../icons/Icons"; +import { Button } from "../ui/Button"; + +interface WalletActionsProps { + onLogout: () => void; + onSubmitTransaction: () => void; + canSubmitTransaction: boolean; +} + +export const WalletActions = ({ + onLogout, + onSubmitTransaction, + canSubmitTransaction, +}: WalletActionsProps) => ( +
+ + +
+); diff --git a/agw-connectkit-nextjs/src/components/wallet/WalletInfo.tsx b/agw-connectkit-nextjs/src/components/wallet/WalletInfo.tsx new file mode 100644 index 0000000..a80e80d --- /dev/null +++ b/agw-connectkit-nextjs/src/components/wallet/WalletInfo.tsx @@ -0,0 +1,22 @@ +interface WalletInfoProps { + address: string; +} + +export const WalletInfo = ({ address }: WalletInfoProps) => ( +
+

+ Connected to Abstract Global Wallet +

+

{address}

+

+ + View on Explorer + +

+
+); diff --git a/agw-connectkit-nextjs/src/hooks/useContract.ts b/agw-connectkit-nextjs/src/hooks/useContract.ts new file mode 100644 index 0000000..cf579b1 --- /dev/null +++ b/agw-connectkit-nextjs/src/hooks/useContract.ts @@ -0,0 +1,31 @@ +import { useWriteContractSponsored } from "@abstract-foundation/agw-react"; +import { parseAbi } from "viem"; +import { getGeneralPaymasterInput } from "viem/zksync"; +import { useWaitForTransactionReceipt } from "wagmi"; + +export const useContract = () => { + const { writeContractSponsored, data: transactionHash } = + useWriteContractSponsored(); + const { data: transactionReceipt } = useWaitForTransactionReceipt({ + hash: transactionHash, + }); + + const mintToken = (address: string) => { + writeContractSponsored({ + abi: parseAbi(["function mint(address,uint256) external"]), + address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", + functionName: "mint", + args: [address as `0x${string}`, BigInt(1)], + paymaster: "0x5407B5040dec3D339A9247f3654E59EEccbb6391", + paymasterInput: getGeneralPaymasterInput({ + innerInput: "0x", + }), + }); + }; + + return { + mintToken, + transactionReceipt, + canSubmitTransaction: !!writeContractSponsored, + }; +};