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
1 change: 1 addition & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"mpp-abstract-agent-example",
"mpp-abstract-hono-example",
"mpp-demo",
"agw-nextjs",
"@abstract-foundation/agw-cli-app"
]
}
1 change: 1 addition & 0 deletions .claude/scheduled_tasks.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"sessionId":"75073da7-cb03-4337-a5e7-856f5b05a515","pid":1449,"acquiredAt":1776552103747}
5 changes: 5 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
"quoteStyle": "double"
}
},
"css": {
"parser": {
"tailwindDirectives": true
}
},
"assist": {
"enabled": true,
"actions": {
Expand Down
6 changes: 6 additions & 0 deletions examples/agw-nextjs/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
26 changes: 26 additions & 0 deletions examples/agw-nextjs/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import path from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const appNodeModules = path.join(__dirname, "node_modules");

/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.resolve.alias = {
...config.resolve.alias,
wagmi: path.join(appNodeModules, "wagmi"),
viem: path.join(appNodeModules, "viem"),
"@tanstack/react-query": path.join(
appNodeModules,
"@tanstack/react-query",
),
};
config.resolve.extensionAlias = {
".js": [".ts", ".tsx", ".js", ".jsx"],
};
return config;
},
};

export default nextConfig;
29 changes: 29 additions & 0 deletions examples/agw-nextjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "agw-nextjs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@abstract-foundation/agw-client": "workspace:*",
"@abstract-foundation/agw-react": "workspace:*",
"@tanstack/react-query": "^5.71.5",
"next": "15.5.12",
"react": "catalog:",
"react-dom": "catalog:",
"viem": "catalog:",
"wagmi": "catalog:"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"tailwindcss": "^4",
"typescript": "catalog:"
}
}
5 changes: 5 additions & 0 deletions examples/agw-nextjs/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
plugins: ["@tailwindcss/postcss"],
};

export default config;
5 changes: 5 additions & 0 deletions examples/agw-nextjs/public/abs-green.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions examples/agw-nextjs/public/abs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions examples/agw-nextjs/public/abstract.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/agw-nextjs/src/app/favicon.ico
Binary file not shown.
26 changes: 26 additions & 0 deletions examples/agw-nextjs/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@import "tailwindcss";

:root {
--background: #ffffff;
--foreground: #171717;
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
57 changes: 57 additions & 0 deletions examples/agw-nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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",
};

// 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>
);
}
42 changes: 42 additions & 0 deletions examples/agw-nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"use client";

import Image from "next/image";
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>
);
}
16 changes: 16 additions & 0 deletions examples/agw-nextjs/src/components/NextAbstractWalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import { AbstractWalletProvider } from "@abstract-foundation/agw-react";
import { abstractTestnet } from "viem/chains";

export default function AbstractWalletWrapper({
children,
}: {
children: React.ReactNode;
}) {
return (
<AbstractWalletProvider chain={abstractTestnet}>
{children}
</AbstractWalletProvider>
);
}
12 changes: 12 additions & 0 deletions examples/agw-nextjs/src/components/ui/BackgroundEffects.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function BackgroundEffects() {
return (
<>
{/* Grid background */}
<div className="absolute inset-0 bg-[linear-gradient(to_right,#0f0f0f_1px,transparent_1px),linear-gradient(to_bottom,#0f0f0f_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]" />

{/* Aurora gradients */}
<div className="absolute top-0 left-0 right-0 h-[70vh] bg-gradient-to-b from-[#00ff00] to-transparent opacity-15 blur-[100px]"></div>
<div className="absolute bottom-0 right-0 w-1/2 h-1/2 bg-gradient-to-tl from-[#00ff00] to-transparent opacity-10 blur-3xl"></div>
</>
);
}
58 changes: 58 additions & 0 deletions examples/agw-nextjs/src/components/ui/ResourceCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export function ResourceCards() {
return (
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 w-full max-w-4xl mx-auto mt-8 font-[family-name:var(--font-roobert)]">
<a
href="https://docs.abs.xyz"
target="_blank"
rel="noopener noreferrer"
className="flex flex-col items-center justify-center p-4 bg-white/5 border border-white/10 rounded-lg hover:bg-white/10 hover:border-white/20 transition-all h-full text-center backdrop-blur-sm"
>
<svg
className="w-6 h-6 mb-2 opacity-70"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zm-1 2l5 5h-5V4zM6 20V4h6v6h6v10H6z" />
</svg>
<h3 className="text-lg font-semibold mb-2 opacity-90">Documentation</h3>
<p className="text-sm opacity-70">Explore our developer docs.</p>
</a>

<a
href="https://github.com/Abstract-Foundation/examples"
target="_blank"
rel="noopener noreferrer"
className="flex flex-col items-center justify-center p-4 bg-white/5 border border-white/10 rounded-lg hover:bg-white/10 hover:border-white/20 transition-all h-full text-center backdrop-blur-sm"
>
<svg className="w-6 h-6 mb-2" viewBox="0 0 24 24" fill="currentColor">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.009-.866-.013-1.7-2.782.603-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.463-1.11-1.463-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.831.092-.646.35-1.086.636-1.336-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.564 9.564 0 0112 6.844c.85.004 1.705.114 2.504.336 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.167 22 16.42 22 12c0-5.523-4.477-10-10-10z"
/>
</svg>
<h3 className="text-lg font-semibold mb-2 opacity-90">
GitHub Examples
</h3>
<p className="text-sm opacity-70">View our example repos on GitHub.</p>
</a>

<a
href="https://youtube.com/@AbstractBlockchain"
target="_blank"
rel="noopener noreferrer"
className="flex flex-col items-center justify-center p-4 bg-white/5 border border-white/10 rounded-lg hover:bg-white/10 hover:border-white/20 transition-all h-full text-center backdrop-blur-sm"
>
<svg className="w-6 h-6 mb-2" viewBox="0 0 24 24" fill="currentColor">
<path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z" />
</svg>
<h3 className="text-lg font-semibold mb-2 opacity-90">
YouTube Channel
</h3>
<p className="text-sm opacity-70">
Watch our video tutorials on YouTube.
</p>
</a>
</div>
);
}
52 changes: 52 additions & 0 deletions examples/agw-nextjs/src/components/wallet/ConnectedState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useLoginWithAbstract } from "@abstract-foundation/agw-react";
import { useAccount } from "wagmi";
import { SendTransaction } from "./SendTransaction";

export function ConnectedState() {
const { address } = useAccount();
const { logout } = useLoginWithAbstract();

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>
);
}
Loading
Loading