Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"mpp-abstract-agent-example",
"mpp-abstract-hono-example",
"mpp-demo",
"agw-nextjs"
"agw-nextjs",
"agw-thirdweb-nextjs",
"@abstract-foundation/agw-thirdweb",
"@abstract-foundation/agw-example-ui"
]
}
1 change: 1 addition & 0 deletions examples/agw-nextjs/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const appNodeModules = path.join(__dirname, "node_modules");

/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ["@abstract-foundation/agw-example-ui"],
webpack: (config) => {
config.resolve.alias = {
...config.resolve.alias,
Expand Down
1 change: 1 addition & 0 deletions examples/agw-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"@abstract-foundation/agw-client": "workspace:*",
"@abstract-foundation/agw-example-ui": "workspace:*",
"@abstract-foundation/agw-react": "workspace:*",
"@tanstack/react-query": "^5.71.5",
"next": "15.5.12",
Expand Down
54 changes: 11 additions & 43 deletions examples/agw-nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,25 @@
import "@abstract-foundation/agw-example-ui/styles.css";
import { favicon } from "@abstract-foundation/agw-example-ui";
import { ExampleRootLayout } from "@abstract-foundation/agw-example-ui/layout";
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import localFont from "next/font/local";
import NextAbstractWalletProvider from "@/components/NextAbstractWalletProvider";
import "./globals.css";

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "Abstract Global Wallet",
description: "Integrate Abstract Global Wallet with Next.js",
icons: {
icon: favicon.src,
},
};

// Abstract Fonts
const avenueMono = localFont({
src: "../fonts/Avenue Mono.ttf",
variable: "--font-avenue-mono",
weight: "100, 900",
});

const roobert = localFont({
src: [
{ path: "../fonts/Roobert-Light.ttf", weight: "300", style: "normal" },
{ path: "../fonts/Roobert-Regular.ttf", weight: "400", style: "normal" },
{ path: "../fonts/Roobert-Medium.ttf", weight: "500", style: "normal" },
{ path: "../fonts/Roobert-SemiBold.ttf", weight: "600", style: "normal" },
{ path: "../fonts/Roobert-Bold.ttf", weight: "700", style: "normal" },
{ path: "../fonts/Roobert-Heavy.ttf", weight: "800", style: "normal" },
],
variable: "--font-roobert",
});

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<NextAbstractWalletProvider>
<body
className={`${geistSans.variable} ${geistMono.variable} ${avenueMono.variable} ${roobert.variable} antialiased`}
>
{children}
</body>
</NextAbstractWalletProvider>
</html>
<ExampleRootLayout>
<NextAbstractWalletProvider>{children}</NextAbstractWalletProvider>
</ExampleRootLayout>
);
}
32 changes: 2 additions & 30 deletions examples/agw-nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,14 @@
"use client";

import Image from "next/image";
import { ExamplePage } from "@abstract-foundation/agw-example-ui";
import { useAccount } from "wagmi";
import { BackgroundEffects } from "@/components/ui/BackgroundEffects";
import { ResourceCards } from "@/components/ui/ResourceCards";
import { ConnectedState } from "@/components/wallet/ConnectedState";
import { SignInButton } from "@/components/wallet/SignInButton";

export default function Home() {
const { address } = useAccount();

return (
<div className="relative grid grid-rows-[1fr_auto] min-h-screen p-8 pb-20 sm:p-20 font-[family-name:var(--font-avenue-mono)] bg-black overflow-hidden">
<BackgroundEffects />

<main className="relative flex flex-col items-center justify-center z-10 text-white text-center">
<div className="flex flex-col items-center gap-8">
<Image
src="/abstract.svg"
alt="Abstract logo"
width={240}
height={32}
quality={100}
priority
/>
<p className="text-md font-[family-name:var(--font-roobert)]">
Get started by editing{" "}
<code className="bg-white/[.06] px-1 py-0.5 rounded font-semibold">
src/app/page.tsx
</code>
.
</p>

{address ? <ConnectedState /> : <SignInButton />}
</div>
</main>

<ResourceCards />
</div>
<ExamplePage>{address ? <ConnectedState /> : <SignInButton />}</ExamplePage>
);
}
43 changes: 4 additions & 39 deletions examples/agw-nextjs/src/components/wallet/ConnectedState.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConnectedWalletCard } from "@abstract-foundation/agw-example-ui";
import { useLoginWithAbstract } from "@abstract-foundation/agw-react";
import { useAccount } from "wagmi";
import { SendTransaction } from "./SendTransaction";
Expand All @@ -9,44 +10,8 @@ export function ConnectedState() {
if (!address) return null;

return (
<div className="bg-white/5 border border-white/10 rounded-lg p-6 shadow-lg backdrop-blur-sm w-full max-w-sm">
<div className="flex flex-col items-center gap-4">
{/* Wallet Status */}
<div className="text-center">
<p className="text-sm sm:text-base font-medium font-[family-name:var(--font-roobert)] mb-1">
Connected to Abstract Global Wallet
</p>
<p className="text-xs text-gray-400 font-mono break-all">{address}</p>
</div>

{/* Action Buttons */}
<div className="flex flex-col w-full gap-4">
<div className="flex flex-col gap-2 w-full">
<button
type="button"
className="rounded-full border border-solid border-white/20 transition-colors flex items-center justify-center bg-white/10 text-white gap-2 hover:bg-white/20 hover:cursor-pointer text-sm px-5 font-[family-name:var(--font-roobert)] w-full sm:flex-1 h-10 py-2"
onClick={logout}
>
<svg
className="w-4 h-4 flex-shrink-0"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
Disconnect
</button>
<SendTransaction />
</div>
</div>
</div>
</div>
<ConnectedWalletCard address={address} onDisconnect={logout}>
<SendTransaction />
</ConnectedWalletCard>
);
}
70 changes: 16 additions & 54 deletions examples/agw-nextjs/src/components/wallet/SendTransaction.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import {
SubmitTransactionButton,
TransactionStatus,
} from "@abstract-foundation/agw-example-ui";
import { useWriteContractSponsored } from "@abstract-foundation/agw-react";
import { parseAbi } from "viem";
import { getGeneralPaymasterInput } from "viem/zksync";
Expand Down Expand Up @@ -34,62 +38,20 @@ export function SendTransaction() {

return (
<div className="flex flex-col w-full border-solid">
<button
type="button"
className={`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)] w-full
${
isPending || hasTransaction
? "bg-gray-500 cursor-not-allowed opacity-50"
: "bg-gradient-to-r from-green-400 to-green-600 hover:from-green-500 hover:to-green-700 hover:cursor-pointer border-transparent"
}`}
<SubmitTransactionButton
onClick={onSubmitTransaction}
disabled={!address || isPending || hasTransaction}
>
<svg
className="w-4 h-4 flex-shrink-0"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M13 10V3L4 14h7v7l9-11h-7z"
/>
</svg>
<span className="w-full text-center">Submit tx</span>
</button>

{transactionHash && (
<div className="mt-4 p-4 bg-white/5 border border-white/10 rounded-lg text-center w-full">
<div className="flex flex-col items-center gap-2">
<p className="text-sm sm:text-base font-medium font-[family-name:var(--font-roobert)]">
{transactionReceipt ? (
<>
Transaction Success
<span className="ml-1 text-green-500">✅</span>
</>
) : (
<>
Transaction Pending
<span className="ml-1 text-yellow-500">⏳</span>
</>
)}
</p>

<a
href={`https://sepolia.abscan.org/tx/${transactionReceipt?.transactionHash}`}
target="_blank"
rel="noopener noreferrer"
className="text-sm text-blue-400 hover:text-blue-300 underline"
>
View on Explorer
</a>
</div>
</div>
)}
isPending={isPending}
/>
<TransactionStatus
transactionHash={transactionHash}
isSuccess={hasTransaction}
explorerHref={
transactionReceipt
? `https://sepolia.abscan.org/tx/${transactionReceipt.transactionHash}`
: undefined
}
/>
</div>
);
}
29 changes: 4 additions & 25 deletions examples/agw-nextjs/src/components/wallet/SignInButton.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
import { SignInWithAbstractButton } from "@abstract-foundation/agw-example-ui";
import { useLoginWithAbstract } from "@abstract-foundation/agw-react";
import Image from "next/image";
import { useAccount } from "wagmi";

export function SignInButton() {
const { login } = useLoginWithAbstract();
const { status } = useAccount();

if (status === "connecting" || status === "reconnecting") {
return (
<div className="flex items-center justify-center w-10 h-10">
<div className="animate-spin">
<Image src="/abs.svg" alt="Loading" width={24} height={24} />
</div>
</div>
);
}

return (
<button
type="button"
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] hover:text-white hover:cursor-pointer dark:hover:bg-[#e0e0e0] dark:hover:text-black text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 font-[family-name:var(--font-roobert)]"
<SignInWithAbstractButton
onClick={login}
>
<Image
className="dark:invert"
src="/abs.svg"
alt="Abstract logomark"
width={20}
height={20}
style={{ filter: "brightness(0)" }}
/>
Sign in with Abstract
</button>
isLoading={status === "connecting" || status === "reconnecting"}
/>
);
}
39 changes: 39 additions & 0 deletions examples/agw-thirdweb-nextjs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# npmrc
.npmrc
Loading
Loading