create-avalanche-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +43 -0
- package/dist/api.d.ts +34 -0
- package/dist/api.js +12 -0
- package/dist/api.js.map +1 -0
- package/dist/chunk-3YGRLI4R.js +91 -0
- package/dist/chunk-3YGRLI4R.js.map +1 -0
- package/dist/index.js +213 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
- package/templates/erc20-token/CLAUDE.md +45 -0
- package/templates/erc20-token/README.md +35 -0
- package/templates/erc20-token/app/globals.css +95 -0
- package/templates/erc20-token/app/layout.tsx +23 -0
- package/templates/erc20-token/app/page.tsx +5 -0
- package/templates/erc20-token/app/providers.tsx +30 -0
- package/templates/erc20-token/components/demo.tsx +178 -0
- package/templates/erc20-token/contracts/foundry.toml +9 -0
- package/templates/erc20-token/contracts/src/AvaKitToken.sol +53 -0
- package/templates/erc20-token/cursor/rules/avakit.mdc +31 -0
- package/templates/erc20-token/env.example +4 -0
- package/templates/erc20-token/gitignore +15 -0
- package/templates/erc20-token/lib/token-artifact.ts +239 -0
- package/templates/erc20-token/llms.txt +29 -0
- package/templates/erc20-token/manifest.json +6 -0
- package/templates/erc20-token/next.config.ts +7 -0
- package/templates/erc20-token/package.json +32 -0
- package/templates/erc20-token/postcss.config.mjs +7 -0
- package/templates/erc20-token/tsconfig.json +23 -0
- package/templates/minimal/CLAUDE.md +37 -0
- package/templates/minimal/README.md +32 -0
- package/templates/minimal/app/globals.css +95 -0
- package/templates/minimal/app/layout.tsx +23 -0
- package/templates/minimal/app/page.tsx +5 -0
- package/templates/minimal/app/providers.tsx +30 -0
- package/templates/minimal/components/demo.tsx +135 -0
- package/templates/minimal/cursor/rules/avakit.mdc +28 -0
- package/templates/minimal/env.example +4 -0
- package/templates/minimal/gitignore +10 -0
- package/templates/minimal/llms.txt +30 -0
- package/templates/minimal/manifest.json +6 -0
- package/templates/minimal/next.config.ts +7 -0
- package/templates/minimal/package.json +32 -0
- package/templates/minimal/postcss.config.mjs +7 -0
- package/templates/minimal/tsconfig.json +23 -0
- package/templates/nft-mint/CLAUDE.md +45 -0
- package/templates/nft-mint/README.md +36 -0
- package/templates/nft-mint/app/globals.css +95 -0
- package/templates/nft-mint/app/layout.tsx +23 -0
- package/templates/nft-mint/app/page.tsx +5 -0
- package/templates/nft-mint/app/providers.tsx +30 -0
- package/templates/nft-mint/components/demo.tsx +176 -0
- package/templates/nft-mint/contracts/foundry.toml +9 -0
- package/templates/nft-mint/contracts/src/AvaKitNFT.sol +57 -0
- package/templates/nft-mint/cursor/rules/avakit.mdc +32 -0
- package/templates/nft-mint/env.example +4 -0
- package/templates/nft-mint/gitignore +15 -0
- package/templates/nft-mint/lib/nft-artifact.ts +164 -0
- package/templates/nft-mint/llms.txt +31 -0
- package/templates/nft-mint/manifest.json +6 -0
- package/templates/nft-mint/next.config.ts +7 -0
- package/templates/nft-mint/package.json +32 -0
- package/templates/nft-mint/postcss.config.mjs +7 -0
- package/templates/nft-mint/tsconfig.json +23 -0
- package/templates/token-gated-app/CLAUDE.md +45 -0
- package/templates/token-gated-app/README.md +38 -0
- package/templates/token-gated-app/app/globals.css +95 -0
- package/templates/token-gated-app/app/layout.tsx +23 -0
- package/templates/token-gated-app/app/page.tsx +5 -0
- package/templates/token-gated-app/app/providers.tsx +30 -0
- package/templates/token-gated-app/components/demo.tsx +161 -0
- package/templates/token-gated-app/contracts/foundry.toml +9 -0
- package/templates/token-gated-app/contracts/src/AvaKitNFT.sol +57 -0
- package/templates/token-gated-app/cursor/rules/avakit.mdc +36 -0
- package/templates/token-gated-app/env.example +4 -0
- package/templates/token-gated-app/gitignore +15 -0
- package/templates/token-gated-app/lib/nft-artifact.ts +164 -0
- package/templates/token-gated-app/llms.txt +33 -0
- package/templates/token-gated-app/manifest.json +6 -0
- package/templates/token-gated-app/next.config.ts +7 -0
- package/templates/token-gated-app/package.json +32 -0
- package/templates/token-gated-app/postcss.config.mjs +7 -0
- package/templates/token-gated-app/tsconfig.json +23 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { getWalletClient } from "@avakit/core";
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
ConnectAvalanche,
|
|
7
|
+
shortenAddress,
|
|
8
|
+
useAvaAccount,
|
|
9
|
+
useAvaChain,
|
|
10
|
+
useAvaKit,
|
|
11
|
+
useBalance,
|
|
12
|
+
} from "@avakit/react";
|
|
13
|
+
import { Moon, Sun } from "lucide-react";
|
|
14
|
+
import { useTheme } from "next-themes";
|
|
15
|
+
import { useState } from "react";
|
|
16
|
+
import { formatEther } from "viem";
|
|
17
|
+
|
|
18
|
+
function ThemeToggle() {
|
|
19
|
+
const { resolvedTheme, setTheme } = useTheme();
|
|
20
|
+
return (
|
|
21
|
+
<Button
|
|
22
|
+
variant="outline"
|
|
23
|
+
size="icon"
|
|
24
|
+
aria-label="Toggle theme"
|
|
25
|
+
onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
|
|
26
|
+
>
|
|
27
|
+
<Sun className="hidden size-4 dark:block" />
|
|
28
|
+
<Moon className="block size-4 dark:hidden" />
|
|
29
|
+
</Button>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function Demo() {
|
|
34
|
+
const { address, isConnected } = useAvaAccount();
|
|
35
|
+
const { chain } = useAvaChain();
|
|
36
|
+
const { provider } = useAvaKit();
|
|
37
|
+
const { data: balance, isLoading, refetch } = useBalance();
|
|
38
|
+
const [txHash, setTxHash] = useState<string | null>(null);
|
|
39
|
+
const [txError, setTxError] = useState<string | null>(null);
|
|
40
|
+
const [sending, setSending] = useState(false);
|
|
41
|
+
|
|
42
|
+
async function sendTestTx() {
|
|
43
|
+
if (!provider || !address) return;
|
|
44
|
+
setSending(true);
|
|
45
|
+
setTxError(null);
|
|
46
|
+
setTxHash(null);
|
|
47
|
+
try {
|
|
48
|
+
const wallet = getWalletClient(chain, provider);
|
|
49
|
+
const hash = await wallet.sendTransaction({
|
|
50
|
+
account: address,
|
|
51
|
+
to: address,
|
|
52
|
+
value: 0n,
|
|
53
|
+
} as Parameters<typeof wallet.sendTransaction>[0]);
|
|
54
|
+
setTxHash(hash);
|
|
55
|
+
void refetch();
|
|
56
|
+
} catch (e) {
|
|
57
|
+
setTxError(e instanceof Error ? e.message : String(e));
|
|
58
|
+
} finally {
|
|
59
|
+
setSending(false);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className="mx-auto flex min-h-dvh max-w-xl flex-col gap-8 px-6 py-16">
|
|
65
|
+
<header className="flex items-center justify-between">
|
|
66
|
+
<span className="font-mono text-sm font-semibold">__PROJECT_NAME__</span>
|
|
67
|
+
<div className="flex items-center gap-2">
|
|
68
|
+
<ConnectAvalanche />
|
|
69
|
+
<ThemeToggle />
|
|
70
|
+
</div>
|
|
71
|
+
</header>
|
|
72
|
+
|
|
73
|
+
<div className="flex flex-col gap-2">
|
|
74
|
+
<h1 className="text-3xl font-semibold tracking-tight">Your first transaction on Avalanche</h1>
|
|
75
|
+
<p className="text-muted-foreground text-sm">
|
|
76
|
+
Connect a wallet, read your balance, and send a 0-AVAX transaction to yourself on{" "}
|
|
77
|
+
{chain.name}.
|
|
78
|
+
</p>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
{isConnected && address ? (
|
|
82
|
+
<div className="flex flex-col gap-4 rounded-xl border p-6">
|
|
83
|
+
<Row label="Network" value={chain.name} />
|
|
84
|
+
<Row label="Address" value={shortenAddress(address, 6)} mono />
|
|
85
|
+
<Row
|
|
86
|
+
label="Balance"
|
|
87
|
+
value={isLoading ? "…" : `${formatEther(balance ?? 0n)} ${chain.nativeCurrency.symbol}`}
|
|
88
|
+
mono
|
|
89
|
+
/>
|
|
90
|
+
|
|
91
|
+
<div className="flex flex-col gap-2 pt-2">
|
|
92
|
+
<Button onClick={sendTestTx} disabled={sending}>
|
|
93
|
+
{sending ? "Sending…" : "Send 0 AVAX to myself"}
|
|
94
|
+
</Button>
|
|
95
|
+
{chain.faucetUrl ? (
|
|
96
|
+
<a
|
|
97
|
+
href={chain.faucetUrl}
|
|
98
|
+
target="_blank"
|
|
99
|
+
rel="noreferrer"
|
|
100
|
+
className="text-muted-foreground text-center text-xs underline underline-offset-4"
|
|
101
|
+
>
|
|
102
|
+
Need test AVAX? Open the faucet
|
|
103
|
+
</a>
|
|
104
|
+
) : null}
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
{txHash ? (
|
|
108
|
+
<a
|
|
109
|
+
href={`${chain.explorerUrl}/tx/${txHash}`}
|
|
110
|
+
target="_blank"
|
|
111
|
+
rel="noreferrer"
|
|
112
|
+
className="text-sm break-all underline underline-offset-4"
|
|
113
|
+
>
|
|
114
|
+
✓ Sent: {txHash}
|
|
115
|
+
</a>
|
|
116
|
+
) : null}
|
|
117
|
+
{txError ? <p className="text-muted-foreground text-sm">{txError}</p> : null}
|
|
118
|
+
</div>
|
|
119
|
+
) : (
|
|
120
|
+
<div className="text-muted-foreground rounded-xl border border-dashed p-10 text-center text-sm">
|
|
121
|
+
Connect a wallet to begin.
|
|
122
|
+
</div>
|
|
123
|
+
)}
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function Row({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
|
|
129
|
+
return (
|
|
130
|
+
<div className="flex items-center justify-between gap-4">
|
|
131
|
+
<span className="text-muted-foreground text-sm">{label}</span>
|
|
132
|
+
<span className={mono ? "font-mono text-sm" : "text-sm"}>{value}</span>
|
|
133
|
+
</div>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: AvaKit + Avalanche conventions for this project
|
|
3
|
+
globs: ["**/*.ts", "**/*.tsx", "**/*.css"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AvaKit project rules
|
|
8
|
+
|
|
9
|
+
This is an Avalanche dapp built with AvaKit (`@avakit/react` + `@avakit/core`).
|
|
10
|
+
|
|
11
|
+
## UI
|
|
12
|
+
|
|
13
|
+
- Use **shadcn/ui only**. `@avakit/react` ships shadcn-styled components — match that style.
|
|
14
|
+
- **Black & white only** for now. Dark/light is wired via `next-themes`; every screen must work in both. Add brand colors later by editing the tokens in `app/globals.css`.
|
|
15
|
+
- Animations: **Framer Motion** or **GSAP** only.
|
|
16
|
+
|
|
17
|
+
## Wallet & chain
|
|
18
|
+
|
|
19
|
+
- Wallet button: `<ConnectAvalanche />`.
|
|
20
|
+
- Read state with hooks: `useAvaAccount`, `useAvaChain`, `useBalance`, `useContract`.
|
|
21
|
+
- For raw transactions, get a viem wallet client: `getWalletClient(chain, provider)` where `provider` comes from `useAvaKit()`.
|
|
22
|
+
- Default chain is Fuji testnet. Mainnet requires explicit opt-in.
|
|
23
|
+
|
|
24
|
+
## Safety
|
|
25
|
+
|
|
26
|
+
- Never hardcode RPC URLs or secrets. Use the chain config and `.env.local`.
|
|
27
|
+
- Private keys live in the wallet provider, never in app code.
|
|
28
|
+
- Social login requires `NEXT_PUBLIC_WEB3AUTH_CLIENT_ID` (free, dashboard.web3auth.io).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
> An Avalanche dapp scaffolded with AvaKit (https://github.com/mericcintosun/AvaKit). Next.js + @avakit/react + shadcn/ui. Social-login onboarding, deploy-ready, black & white with dark/light from day one.
|
|
4
|
+
|
|
5
|
+
## Project map
|
|
6
|
+
|
|
7
|
+
- [app/providers.tsx](app/providers.tsx): AvaKitProvider (chains + wallet adapters) and theme provider.
|
|
8
|
+
- [app/layout.tsx](app/layout.tsx): root layout and fonts.
|
|
9
|
+
- [app/page.tsx](app/page.tsx): renders the demo.
|
|
10
|
+
- [components/demo.tsx](components/demo.tsx): connect wallet, read balance, send a transaction.
|
|
11
|
+
- [app/globals.css](app/globals.css): shadcn tokens (black & white) + dark/light.
|
|
12
|
+
- [CLAUDE.md](CLAUDE.md): agent guide with the AvaKit API and project rules.
|
|
13
|
+
|
|
14
|
+
## Key APIs (@avakit/react)
|
|
15
|
+
|
|
16
|
+
- `<AvaKitProvider chains={[...]} adapters={[...]}>`
|
|
17
|
+
- `<ConnectAvalanche />` — drop-in wallet button
|
|
18
|
+
- `useAvaAccount()`, `useAvaChain()`, `useBalance()`, `useContract()`, `useAvaDeploy()`, `useAvaKit()`
|
|
19
|
+
|
|
20
|
+
## Key APIs (@avakit/core)
|
|
21
|
+
|
|
22
|
+
- `fuji`, `cChain`, `defineChain` from `@avakit/core/chains`
|
|
23
|
+
- `injectedAdapter()`, `web3authAdapter({ clientId })` (from `@avakit/core/web3auth`)
|
|
24
|
+
- `getPublicClient`, `getWalletClient`, `ensureChain`, `deployContract`, `getBalance`, `readContract`
|
|
25
|
+
|
|
26
|
+
## External docs
|
|
27
|
+
|
|
28
|
+
- Avalanche Builder Hub: https://build.avax.network/llms.txt
|
|
29
|
+
- Web3Auth dashboard (free client ID): https://dashboard.web3auth.io
|
|
30
|
+
- Fuji faucet: https://core.app/tools/testnet-faucet
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "next dev",
|
|
8
|
+
"build": "next build",
|
|
9
|
+
"start": "next start",
|
|
10
|
+
"typecheck": "tsc --noEmit"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@avakit/core": "__AVAKIT_DEP__",
|
|
14
|
+
"@avakit/react": "__AVAKIT_DEP__",
|
|
15
|
+
"lucide-react": "1.22.0",
|
|
16
|
+
"next": "16.2.9",
|
|
17
|
+
"next-themes": "0.4.6",
|
|
18
|
+
"react": "19.2.7",
|
|
19
|
+
"react-dom": "19.2.7",
|
|
20
|
+
"viem": "2.54.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@tailwindcss/postcss": "4.3.2",
|
|
24
|
+
"@types/node": "26.0.1",
|
|
25
|
+
"@types/react": "19.2.17",
|
|
26
|
+
"@types/react-dom": "19.2.3",
|
|
27
|
+
"postcss": "8.5.16",
|
|
28
|
+
"tailwindcss": "4.3.2",
|
|
29
|
+
"tw-animate-css": "1.4.0",
|
|
30
|
+
"typescript": "6.0.3"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# __PROJECT_NAME__ — Avalanche NFT dapp (scaffolded with AvaKit)
|
|
2
|
+
|
|
3
|
+
Operational guide for AI agents (Claude Code / Cursor) working in this project.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
Next.js 16 (App Router) · React 19 · `@avakit/react` · `@avakit/core` · viem · shadcn/ui · next-themes · Foundry (contract)
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
- `contracts/src/AvaKitNFT.sol` — a minimal, self-contained ERC-721 mint contract
|
|
12
|
+
- `lib/nft-artifact.ts` — the compiled ABI + bytecode (so the app deploys from the browser with no Foundry at runtime)
|
|
13
|
+
- `app/providers.tsx` — `<AvaKitProvider>` (chains + wallet adapters) + `ThemeProvider`
|
|
14
|
+
- `components/demo.tsx` — deploy the contract, then mint
|
|
15
|
+
|
|
16
|
+
## The flow
|
|
17
|
+
|
|
18
|
+
1. Connect a wallet (`<ConnectAvalanche />`).
|
|
19
|
+
2. Deploy: `useAvaDeploy().deploy({ abi, bytecode })` → returns the contract address.
|
|
20
|
+
3. Mint: `useContract({ address, abi }).write("mint", [])`.
|
|
21
|
+
4. Read state: `useContract(...).read("totalSupply")`, `.read("balanceOf", [address])`.
|
|
22
|
+
|
|
23
|
+
## Editing the contract
|
|
24
|
+
|
|
25
|
+
The bundled `lib/nft-artifact.ts` is generated from the Solidity source. After changing `contracts/src/AvaKitNFT.sol`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd contracts && forge build
|
|
29
|
+
# then copy out/AvaKitNFT.sol/AvaKitNFT.json's abi + bytecode.object into lib/nft-artifact.ts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Rules
|
|
33
|
+
|
|
34
|
+
- UI uses **shadcn/ui only** (components from `@avakit/react` are shadcn-styled).
|
|
35
|
+
- **Black & white only** for now; dark/light via `next-themes`. Add brand colors later in `app/globals.css`.
|
|
36
|
+
- Animations: **Framer Motion** or **GSAP** only.
|
|
37
|
+
- Never hardcode secrets; private keys live in the wallet provider.
|
|
38
|
+
- Deploying/minting costs gas — fund the wallet on Fuji first (in-app faucet link).
|
|
39
|
+
- Social login needs `NEXT_PUBLIC_WEB3AUTH_CLIENT_ID` in `.env.local` (free, dashboard.web3auth.io).
|
|
40
|
+
|
|
41
|
+
## Commands
|
|
42
|
+
|
|
43
|
+
- `pnpm dev` — dev server (http://localhost:3000)
|
|
44
|
+
- `pnpm build` — production build
|
|
45
|
+
- `cd contracts && forge build` — recompile the contract
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
An Avalanche **NFT mint** dapp scaffolded with [AvaKit](https://github.com/mericcintosun/AvaKit). Deploy an ERC-721 from your browser, then mint — no Foundry required to run it.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 1. (social login, optional) add a free Web3Auth client ID
|
|
9
|
+
cp .env.example .env.local
|
|
10
|
+
# → https://dashboard.web3auth.io (Sapphire Devnet, EVM)
|
|
11
|
+
|
|
12
|
+
# 2. run it
|
|
13
|
+
pnpm dev # http://localhost:3000
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then: connect a wallet → **Deploy NFT contract** → **Mint NFT**. Deploying and minting cost gas, so fund your wallet on Fuji first (in-app faucet link).
|
|
17
|
+
|
|
18
|
+
## How the contract works
|
|
19
|
+
|
|
20
|
+
- `contracts/src/AvaKitNFT.sol` — a minimal, self-contained ERC-721 (no external deps; compiles with `forge build` out of the box).
|
|
21
|
+
- `lib/nft-artifact.ts` — the compiled ABI + bytecode, bundled so the app can deploy straight from the browser via `useAvaDeploy()`.
|
|
22
|
+
|
|
23
|
+
To change the contract:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd contracts && forge build
|
|
27
|
+
# copy out/AvaKitNFT.sol/AvaKitNFT.json (abi + bytecode.object) into lib/nft-artifact.ts
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Stack
|
|
31
|
+
|
|
32
|
+
Next.js 16 · `@avakit/react` · `@avakit/core` · viem · shadcn/ui · Foundry
|
|
33
|
+
|
|
34
|
+
## AI-native
|
|
35
|
+
|
|
36
|
+
Ships with `CLAUDE.md`, `llms.txt`, and `.cursor/rules` so Claude Code / Cursor understand AvaKit, the deploy/mint flow, and the contract workflow.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
3
|
+
|
|
4
|
+
/* Scan @avakit/react's shadcn-style classes from node_modules. */
|
|
5
|
+
@source "../node_modules/@avakit/react/dist";
|
|
6
|
+
|
|
7
|
+
@custom-variant dark (&:is(.dark *));
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Black & white only (oklch chroma 0 = pure grayscale). Dark/light wired from
|
|
11
|
+
* day one via next-themes. Add brand colors later by editing these tokens —
|
|
12
|
+
* components never hardcode colors.
|
|
13
|
+
*/
|
|
14
|
+
:root {
|
|
15
|
+
--radius: 0.625rem;
|
|
16
|
+
--background: oklch(1 0 0);
|
|
17
|
+
--foreground: oklch(0.145 0 0);
|
|
18
|
+
--card: oklch(1 0 0);
|
|
19
|
+
--card-foreground: oklch(0.145 0 0);
|
|
20
|
+
--popover: oklch(1 0 0);
|
|
21
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
22
|
+
--primary: oklch(0.205 0 0);
|
|
23
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
24
|
+
--secondary: oklch(0.97 0 0);
|
|
25
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
26
|
+
--muted: oklch(0.97 0 0);
|
|
27
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
28
|
+
--accent: oklch(0.97 0 0);
|
|
29
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
30
|
+
--destructive: oklch(0.3 0 0);
|
|
31
|
+
--destructive-foreground: oklch(0.985 0 0);
|
|
32
|
+
--border: oklch(0.922 0 0);
|
|
33
|
+
--input: oklch(0.922 0 0);
|
|
34
|
+
--ring: oklch(0.708 0 0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.dark {
|
|
38
|
+
--background: oklch(0.145 0 0);
|
|
39
|
+
--foreground: oklch(0.985 0 0);
|
|
40
|
+
--card: oklch(0.205 0 0);
|
|
41
|
+
--card-foreground: oklch(0.985 0 0);
|
|
42
|
+
--popover: oklch(0.205 0 0);
|
|
43
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
44
|
+
--primary: oklch(0.985 0 0);
|
|
45
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
46
|
+
--secondary: oklch(0.269 0 0);
|
|
47
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
48
|
+
--muted: oklch(0.269 0 0);
|
|
49
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
50
|
+
--accent: oklch(0.269 0 0);
|
|
51
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
52
|
+
--destructive: oklch(0.7 0 0);
|
|
53
|
+
--destructive-foreground: oklch(0.205 0 0);
|
|
54
|
+
--border: oklch(1 0 0 / 10%);
|
|
55
|
+
--input: oklch(1 0 0 / 15%);
|
|
56
|
+
--ring: oklch(0.556 0 0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@theme inline {
|
|
60
|
+
--color-background: var(--background);
|
|
61
|
+
--color-foreground: var(--foreground);
|
|
62
|
+
--color-card: var(--card);
|
|
63
|
+
--color-card-foreground: var(--card-foreground);
|
|
64
|
+
--color-popover: var(--popover);
|
|
65
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
66
|
+
--color-primary: var(--primary);
|
|
67
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
68
|
+
--color-secondary: var(--secondary);
|
|
69
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
70
|
+
--color-muted: var(--muted);
|
|
71
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
72
|
+
--color-accent: var(--accent);
|
|
73
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
74
|
+
--color-destructive: var(--destructive);
|
|
75
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
76
|
+
--color-border: var(--border);
|
|
77
|
+
--color-input: var(--input);
|
|
78
|
+
--color-ring: var(--ring);
|
|
79
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
80
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
81
|
+
--radius-lg: var(--radius);
|
|
82
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
83
|
+
--font-sans: var(--font-geist-sans);
|
|
84
|
+
--font-mono: var(--font-geist-mono);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@layer base {
|
|
88
|
+
* {
|
|
89
|
+
border-color: var(--border);
|
|
90
|
+
}
|
|
91
|
+
body {
|
|
92
|
+
background-color: var(--background);
|
|
93
|
+
color: var(--foreground);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Geist, Geist_Mono } from "next/font/google";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import { Providers } from "./providers";
|
|
5
|
+
import "./globals.css";
|
|
6
|
+
|
|
7
|
+
const geistSans = Geist({ variable: "--font-geist-sans", subsets: ["latin"] });
|
|
8
|
+
const geistMono = Geist_Mono({ variable: "--font-geist-mono", subsets: ["latin"] });
|
|
9
|
+
|
|
10
|
+
export const metadata: Metadata = {
|
|
11
|
+
title: "__PROJECT_NAME__",
|
|
12
|
+
description: "An Avalanche dapp scaffolded with AvaKit.",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default function RootLayout({ children }: Readonly<{ children: ReactNode }>) {
|
|
16
|
+
return (
|
|
17
|
+
<html lang="en" suppressHydrationWarning>
|
|
18
|
+
<body className={`${geistSans.variable} ${geistMono.variable} font-sans antialiased`}>
|
|
19
|
+
<Providers>{children}</Providers>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type WalletAdapter, injectedAdapter } from "@avakit/core";
|
|
4
|
+
import { __CHAIN_CONST__ } from "@avakit/core/chains";
|
|
5
|
+
import { web3authAdapter } from "@avakit/core/web3auth";
|
|
6
|
+
import { AvaKitProvider } from "@avakit/react";
|
|
7
|
+
import { ThemeProvider } from "next-themes";
|
|
8
|
+
import { type ReactNode, useMemo } from "react";
|
|
9
|
+
|
|
10
|
+
export function Providers({ children }: { children: ReactNode }) {
|
|
11
|
+
const adapters = useMemo(() => {
|
|
12
|
+
const list: WalletAdapter[] = [];
|
|
13
|
+
// Social login appears only when a Web3Auth client ID is configured.
|
|
14
|
+
const clientId = process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID;
|
|
15
|
+
if (clientId) {
|
|
16
|
+
list.push(web3authAdapter({ clientId }));
|
|
17
|
+
}
|
|
18
|
+
// Injected (Core / MetaMask) is always available.
|
|
19
|
+
list.push(injectedAdapter());
|
|
20
|
+
return list;
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
|
25
|
+
<AvaKitProvider chains={[__CHAIN_CONST__]} adapters={adapters}>
|
|
26
|
+
{children}
|
|
27
|
+
</AvaKitProvider>
|
|
28
|
+
</ThemeProvider>
|
|
29
|
+
);
|
|
30
|
+
}
|