create-avalanche-app 0.1.4 → 0.1.5

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.
@@ -0,0 +1,239 @@
1
+ // Auto-generated from contracts/src/AvaKitToken.sol via `forge build`.
2
+ // Re-generate after editing the contract: cd contracts && forge build, then
3
+ // copy abi + bytecode.object here.
4
+
5
+ import type { Abi, Hex } from "viem";
6
+
7
+ export const abi = [
8
+ {
9
+ "type": "function",
10
+ "name": "allowance",
11
+ "inputs": [
12
+ {
13
+ "name": "",
14
+ "type": "address",
15
+ "internalType": "address"
16
+ },
17
+ {
18
+ "name": "",
19
+ "type": "address",
20
+ "internalType": "address"
21
+ }
22
+ ],
23
+ "outputs": [
24
+ {
25
+ "name": "",
26
+ "type": "uint256",
27
+ "internalType": "uint256"
28
+ }
29
+ ],
30
+ "stateMutability": "view"
31
+ },
32
+ {
33
+ "type": "function",
34
+ "name": "approve",
35
+ "inputs": [
36
+ {
37
+ "name": "spender",
38
+ "type": "address",
39
+ "internalType": "address"
40
+ },
41
+ {
42
+ "name": "value",
43
+ "type": "uint256",
44
+ "internalType": "uint256"
45
+ }
46
+ ],
47
+ "outputs": [
48
+ {
49
+ "name": "",
50
+ "type": "bool",
51
+ "internalType": "bool"
52
+ }
53
+ ],
54
+ "stateMutability": "nonpayable"
55
+ },
56
+ {
57
+ "type": "function",
58
+ "name": "balanceOf",
59
+ "inputs": [
60
+ {
61
+ "name": "",
62
+ "type": "address",
63
+ "internalType": "address"
64
+ }
65
+ ],
66
+ "outputs": [
67
+ {
68
+ "name": "",
69
+ "type": "uint256",
70
+ "internalType": "uint256"
71
+ }
72
+ ],
73
+ "stateMutability": "view"
74
+ },
75
+ {
76
+ "type": "function",
77
+ "name": "decimals",
78
+ "inputs": [],
79
+ "outputs": [
80
+ {
81
+ "name": "",
82
+ "type": "uint8",
83
+ "internalType": "uint8"
84
+ }
85
+ ],
86
+ "stateMutability": "view"
87
+ },
88
+ {
89
+ "type": "function",
90
+ "name": "mint",
91
+ "inputs": [],
92
+ "outputs": [],
93
+ "stateMutability": "nonpayable"
94
+ },
95
+ {
96
+ "type": "function",
97
+ "name": "name",
98
+ "inputs": [],
99
+ "outputs": [
100
+ {
101
+ "name": "",
102
+ "type": "string",
103
+ "internalType": "string"
104
+ }
105
+ ],
106
+ "stateMutability": "view"
107
+ },
108
+ {
109
+ "type": "function",
110
+ "name": "symbol",
111
+ "inputs": [],
112
+ "outputs": [
113
+ {
114
+ "name": "",
115
+ "type": "string",
116
+ "internalType": "string"
117
+ }
118
+ ],
119
+ "stateMutability": "view"
120
+ },
121
+ {
122
+ "type": "function",
123
+ "name": "totalSupply",
124
+ "inputs": [],
125
+ "outputs": [
126
+ {
127
+ "name": "",
128
+ "type": "uint256",
129
+ "internalType": "uint256"
130
+ }
131
+ ],
132
+ "stateMutability": "view"
133
+ },
134
+ {
135
+ "type": "function",
136
+ "name": "transfer",
137
+ "inputs": [
138
+ {
139
+ "name": "to",
140
+ "type": "address",
141
+ "internalType": "address"
142
+ },
143
+ {
144
+ "name": "value",
145
+ "type": "uint256",
146
+ "internalType": "uint256"
147
+ }
148
+ ],
149
+ "outputs": [
150
+ {
151
+ "name": "",
152
+ "type": "bool",
153
+ "internalType": "bool"
154
+ }
155
+ ],
156
+ "stateMutability": "nonpayable"
157
+ },
158
+ {
159
+ "type": "function",
160
+ "name": "transferFrom",
161
+ "inputs": [
162
+ {
163
+ "name": "from",
164
+ "type": "address",
165
+ "internalType": "address"
166
+ },
167
+ {
168
+ "name": "to",
169
+ "type": "address",
170
+ "internalType": "address"
171
+ },
172
+ {
173
+ "name": "value",
174
+ "type": "uint256",
175
+ "internalType": "uint256"
176
+ }
177
+ ],
178
+ "outputs": [
179
+ {
180
+ "name": "",
181
+ "type": "bool",
182
+ "internalType": "bool"
183
+ }
184
+ ],
185
+ "stateMutability": "nonpayable"
186
+ },
187
+ {
188
+ "type": "event",
189
+ "name": "Approval",
190
+ "inputs": [
191
+ {
192
+ "name": "owner",
193
+ "type": "address",
194
+ "indexed": true,
195
+ "internalType": "address"
196
+ },
197
+ {
198
+ "name": "spender",
199
+ "type": "address",
200
+ "indexed": true,
201
+ "internalType": "address"
202
+ },
203
+ {
204
+ "name": "value",
205
+ "type": "uint256",
206
+ "indexed": false,
207
+ "internalType": "uint256"
208
+ }
209
+ ],
210
+ "anonymous": false
211
+ },
212
+ {
213
+ "type": "event",
214
+ "name": "Transfer",
215
+ "inputs": [
216
+ {
217
+ "name": "from",
218
+ "type": "address",
219
+ "indexed": true,
220
+ "internalType": "address"
221
+ },
222
+ {
223
+ "name": "to",
224
+ "type": "address",
225
+ "indexed": true,
226
+ "internalType": "address"
227
+ },
228
+ {
229
+ "name": "value",
230
+ "type": "uint256",
231
+ "indexed": false,
232
+ "internalType": "uint256"
233
+ }
234
+ ],
235
+ "anonymous": false
236
+ }
237
+ ] as const satisfies Abi;
238
+
239
+ export const bytecode = "0x6080604052348015600e575f5ffd5b5061066f8061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c8063313ce56711610063578063313ce5671461013657806370a082311461015057806395d89b411461016f578063a9059cbb14610191578063dd62ed3e146101a4575f5ffd5b806306fdde031461009f578063095ea7b3146100e05780631249c58b1461010357806318160ddd1461010d57806323b872dd14610123575b5f5ffd5b6100ca6040518060400160405280600c81526020016b20bb30a5b4ba102a37b5b2b760a11b81525081565b6040516100d791906103f4565b60405180910390f35b6100f36100ee366004610444565b6101ce565b60405190151581526020016100d7565b61010b61023a565b005b6101155f5481565b6040519081526020016100d7565b6100f361013136600461046c565b6102b2565b61013e601281565b60405160ff90911681526020016100d7565b61011561015e3660046104a6565b60016020525f908152604090205481565b6100ca604051806040016040528060038152602001621052d560ea1b81525081565b6100f361019f366004610444565b61037e565b6101156101b23660046104c6565b600260209081525f928352604080842090915290825290205481565b335f8181526002602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102289086815260200190565b60405180910390a35060015b92915050565b5f6102476012600a6105ee565b6102529060646105fc565b9050805f5f8282546102649190610613565b9091555050335f818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350565b6001600160a01b0383165f9081526002602090815260408083203384529091528120805483919083906102e6908490610626565b90915550506001600160a01b0384165f9081526001602052604081208054849290610312908490610626565b90915550506001600160a01b038084165f81815260016020526040908190208054860190555190918616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061036c9086815260200190565b60405180910390a35060019392505050565b335f9081526001602052604081208054839190839061039e908490610626565b90915550506001600160a01b0383165f81815260016020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906102289086815260200190565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461043f575f5ffd5b919050565b5f5f60408385031215610455575f5ffd5b61045e83610429565b946020939093013593505050565b5f5f5f6060848603121561047e575f5ffd5b61048784610429565b925061049560208501610429565b929592945050506040919091013590565b5f602082840312156104b6575f5ffd5b6104bf82610429565b9392505050565b5f5f604083850312156104d7575f5ffd5b6104e083610429565b91506104ee60208401610429565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b6001815b60018411156105465780850481111561052a5761052a6104f7565b600184161561053857908102905b60019390931c92800261050f565b935093915050565b5f8261055c57506001610234565b8161056857505f610234565b816001811461057e5760028114610588576105a4565b6001915050610234565b60ff841115610599576105996104f7565b50506001821b610234565b5060208310610133831016604e8410600b84101617156105c7575081810a610234565b6105d35f19848461050b565b805f19048211156105e6576105e66104f7565b029392505050565b5f6104bf60ff84168361054e565b8082028115828204841417610234576102346104f7565b80820180821115610234576102346104f7565b81810381811115610234576102346104f756fea26469706673582212203ba8f5901a64d91a7beec3bdc98521ea0a7279a4ebafb699842fb133050e658e64736f6c634300081c0033" as Hex;
@@ -0,0 +1,31 @@
1
+ # __PROJECT_NAME__
2
+
3
+ > Launch your own Avalanche L1 with one command, then explore it in a built-in dashboard (live blocks, transactions, balance, contract deploy). Next.js + @avakit/react + viem + avalanche-cli, no third-party explorer.
4
+
5
+ ## Project map
6
+
7
+ - [scripts/l1.sh](scripts/l1.sh): `pnpm l1` — create + deploy a local Subnet-EVM L1, write l1.config.json.
8
+ - [scripts/l1-fuji.sh](scripts/l1-fuji.sh): `pnpm l1:fuji` — deploy the L1 to the Fuji testnet (advanced).
9
+ - [l1.config.json](l1.config.json): your chain (name, token, evmChainId, rpcUrl, blockchainIdHex, faucetAccount).
10
+ - [lib/l1.ts](lib/l1.ts): config → AvaKit chain (`defineChain`) + `isConfigured`.
11
+ - [components/demo.tsx](components/demo.tsx): the dashboard/explorer — polls RPC for blocks/txs/gas/balance, deploys + mints the demo token.
12
+ - [contracts/src/AvaKitToken.sol](contracts/src/AvaKitToken.sol) + [lib/token-artifact.ts](lib/token-artifact.ts): bundled ERC-20 for browser deploy.
13
+ - [CLAUDE.md](CLAUDE.md): agent guide — the flow, an explainer for every L1 config decision, the EWOQ warning, and the Fuji graduation path.
14
+
15
+ ## Key APIs
16
+
17
+ - Chain: `chain` and `isConfigured` from `@/lib/l1`.
18
+ - Explorer reads (all read-only viem): `getPublicClient(chain)` → `getBlockNumber()`, `getGasPrice()`, `getBlock({ blockNumber, includeTransactions: true })`, `getBalance({ address })`.
19
+ - Deploy: `deployContract({ artifact: { abi, bytecode }, chain, provider, account })` from `@avakit/core`.
20
+ - Write: `getWalletClient(chain, provider).writeContract({ address, abi, functionName: "mint", account })`.
21
+
22
+ ## Config decisions
23
+
24
+ Subnet-EVM VM, EVM chain id (default 9999), native token symbol, `--sovereign=false` for a
25
+ zero-prompt local chain (Fuji path uses a sovereign PoA L1), `--test-defaults` (EWOQ pre-funded).
26
+
27
+ ## External docs
28
+
29
+ - Create/deploy an L1 locally: https://build.avax.network/docs/tooling/avalanche-cli/create-deploy-avalanche-l1s/deploy-locally
30
+ - Deploy on Fuji: https://build.avax.network/docs/tooling/avalanche-cli/create-deploy-avalanche-l1s/deploy-on-fuji-testnet
31
+ - avalanche-cli: https://build.avax.network/docs/tooling/avalanche-cli/get-avalanche-cli
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "l1-launch",
3
+ "title": "Launch your own L1",
4
+ "description": "Spin up your own Avalanche L1 with one command, then explore blocks, send txs, and deploy a contract in a built-in dashboard",
5
+ "contracts": true
6
+ }
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ reactStrictMode: true,
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,34 @@
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
+ "l1": "bash scripts/l1.sh",
12
+ "l1:fuji": "bash scripts/l1-fuji.sh"
13
+ },
14
+ "dependencies": {
15
+ "@avakit/core": "__AVAKIT_DEP__",
16
+ "@avakit/react": "__AVAKIT_DEP__",
17
+ "lucide-react": "1.22.0",
18
+ "next": "16.2.9",
19
+ "next-themes": "0.4.6",
20
+ "react": "19.2.7",
21
+ "react-dom": "19.2.7",
22
+ "viem": "2.54.1"
23
+ },
24
+ "devDependencies": {
25
+ "@tailwindcss/postcss": "4.3.2",
26
+ "@types/node": "26.0.1",
27
+ "@types/react": "19.2.17",
28
+ "@types/react-dom": "19.2.3",
29
+ "postcss": "8.5.16",
30
+ "tailwindcss": "4.3.2",
31
+ "tw-animate-css": "1.4.0",
32
+ "typescript": "6.0.3"
33
+ }
34
+ }
@@ -0,0 +1,11 @@
1
+ # pnpm settings for this scaffolded app.
2
+ # allowBuilds: pre-approve native postinstall scripts so `pnpm install` / `pnpm dev`
3
+ # don't fail with ERR_PNPM_IGNORED_BUILDS on pnpm 10+.
4
+ # minimumReleaseAgeExclude: pnpm's supply-chain age gate blocks very fresh releases;
5
+ # exempt AvaKit's own packages so a new @avakit publish never breaks a fresh install
6
+ # (third-party deps keep the protection). Delete this file to opt back into defaults.
7
+ allowBuilds:
8
+ sharp: true
9
+ minimumReleaseAgeExclude:
10
+ - '@avakit/core'
11
+ - '@avakit/react'
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Graduate your L1 to the Fuji TESTNET (advanced).
4
+ #
5
+ # Unlike `pnpm l1` (fully local, instant, free), deploying to Fuji is a real,
6
+ # multi-step operation. This script wraps the avalanche-cli commands and, where
7
+ # the CLI needs interactive input or your own keys, walks you through it. Read
8
+ # the caveats below before running — a Fuji L1 needs an always-on validator and
9
+ # a periodically-topped-up balance, or it stops producing blocks.
10
+ #
11
+ # Configure via env (all optional; must match the chain you created with pnpm l1):
12
+ # L1_NAME=mychain FUJI_KEY=mykey pnpm l1:fuji
13
+
14
+ set -uo pipefail
15
+
16
+ NAME="${L1_NAME:-mychain}"
17
+ KEY="${FUJI_KEY:-}"
18
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
19
+ CONFIG="$ROOT/l1.config.json"
20
+
21
+ say() { printf "\033[1;37m▸\033[0m %s\n" "$1"; }
22
+ warn() { printf "\033[1;33m!\033[0m %s\n" "$1"; }
23
+ die() { printf "\033[1;31m✖\033[0m %s\n" "$1" >&2; exit 1; }
24
+
25
+ command -v avalanche >/dev/null 2>&1 || die "avalanche-cli not found. See CLAUDE.md."
26
+
27
+ cat <<'EOF'
28
+ ────────────────────────────────────────────────────────────────────────
29
+ Deploy your L1 to Fuji — what you need first (one-time):
30
+
31
+ 1. A Fuji key funded with test AVAX:
32
+ avalanche key create mykey # creates a key
33
+ # fund its C-Chain address from the Builder Hub faucet:
34
+ # https://build.avax.network/console/primary-network/faucet
35
+ # then move funds to the P-Chain:
36
+ avalanche key transfer --key mykey --amount 2 --sender-blockchain c --receiver-blockchain p
37
+
38
+ 2. Budget ~1-2 test AVAX PER validator — an L1 validator pays a continuous
39
+ P-Chain fee (~1 AVAX ≈ 1 month). When the balance hits zero the validator
40
+ goes inactive and your L1 STOPS. Top up with:
41
+ avalanche blockchain addValidator / IncreaseL1ValidatorBalance
42
+
43
+ 3. A bootstrap validator node that STAYS RUNNING. Your machine can be it
44
+ (--use-local-machine below), but if this process exits, block production
45
+ stops. For an always-on chain, run a real node instead.
46
+ ────────────────────────────────────────────────────────────────────────
47
+ EOF
48
+
49
+ [ -n "$KEY" ] || die "Set FUJI_KEY to your funded avalanche-cli key name, e.g. FUJI_KEY=mykey pnpm l1:fuji"
50
+
51
+ say "Deploying '$NAME' to Fuji with key '$KEY' (your machine as bootstrap validator)…"
52
+ warn "This is interactive: the CLI will ask you to confirm the CreateSubnet / CreateChain /"
53
+ warn "ConvertSubnetToL1 transactions and to set up the local-machine validator. Follow its prompts."
54
+
55
+ # --use-local-machine turns this machine into the bootstrap validator; the CLI
56
+ # handles subnet creation, chain creation, and conversion to a sovereign L1.
57
+ avalanche blockchain deploy "$NAME" \
58
+ --fuji \
59
+ --key "$KEY" \
60
+ --use-local-machine \
61
+ || die "Fuji deploy did not complete. Re-run after addressing the CLI's output."
62
+
63
+ # Discover the Fuji RPC + hex blockchain ID for the deployed L1.
64
+ say "Reading Fuji chain details…"
65
+ OUT="$(avalanche blockchain describe "$NAME" 2>/dev/null)"
66
+ RPC="$(printf '%s' "$OUT" | grep -oE 'https?://[^ ]*/ext/bc/[A-Za-z0-9]+/rpc' | head -1)"
67
+ BID="$(printf '%s' "$OUT" | grep -iE 'BlockchainID \(HEX\)' | grep -oiE '0x[0-9a-f]{64}' | head -1)"
68
+ CID="$(printf '%s' "$OUT" | grep -iE 'ChainID' | grep -oE '[0-9]+' | head -1)"
69
+
70
+ [ -n "$RPC" ] || die "Could not read the Fuji RPC. Run: avalanche blockchain describe $NAME"
71
+
72
+ TOKEN="$(node -e "process.stdout.write(String(require('$CONFIG').token||'MYL1'))" 2>/dev/null || echo MYL1)"
73
+ CID="${CID:-$(node -e "process.stdout.write(String(require('$CONFIG').evmChainId||9999))" 2>/dev/null || echo 9999)}"
74
+
75
+ cat > "$CONFIG" <<EOF
76
+ {
77
+ "configured": true,
78
+ "network": "fuji",
79
+ "name": "$NAME",
80
+ "token": "$TOKEN",
81
+ "evmChainId": $CID,
82
+ "rpcUrl": "$RPC",
83
+ "blockchainIdHex": "${BID:-}",
84
+ "faucetAccount": { "address": "", "privateKey": "" }
85
+ }
86
+ EOF
87
+
88
+ say "Updated l1.config.json → $RPC (network: fuji)"
89
+ cat <<EOF
90
+
91
+ ✔ Your L1 is on Fuji.
92
+
93
+ • pnpm dev → the built-in explorer now points at your Fuji L1's RPC.
94
+ • Connect your OWN funded wallet (no EWOQ on Fuji).
95
+ • Keep this machine / your validator node running, and keep the validator
96
+ balance topped up, or the L1 stops producing blocks.
97
+
98
+ There is no automatic hosted explorer for a custom Fuji L1 — this app's built-in
99
+ explorer is your window into the chain.
100
+ EOF
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Launch your own local Avalanche L1 — one command.
4
+ #
5
+ # Creates a Subnet-EVM blockchain and deploys it to a local Avalanche network,
6
+ # then writes the discovered RPC URL + blockchain ID into l1.config.json so the
7
+ # app can talk to your chain. Everything runs on your machine — no test AVAX, no
8
+ # faucet, no always-on node. To graduate the same chain to the Fuji testnet, see
9
+ # `pnpm l1:fuji` (scripts/l1-fuji.sh) and CLAUDE.md.
10
+ #
11
+ # Configure via env (all optional):
12
+ # L1_NAME=mychain L1_CHAIN_ID=9999 L1_TOKEN=MYL1 pnpm l1
13
+ #
14
+ # Requires avalanche-cli. It downloads avalanchego + Subnet-EVM on first run.
15
+
16
+ set -uo pipefail
17
+
18
+ NAME="${L1_NAME:-mychain}"
19
+ CHAIN_ID="${L1_CHAIN_ID:-9999}"
20
+ TOKEN="${L1_TOKEN:-MYL1}"
21
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
22
+ CONFIG="$ROOT/l1.config.json"
23
+
24
+ # EWOQ: avalanche-cli's well-known local dev key, pre-funded on every local
25
+ # chain. PUBLIC — for local networks only, never a real network. Import it into
26
+ # your wallet to transact on your L1.
27
+ EWOQ_PK="0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"
28
+ EWOQ_ADDR="0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"
29
+
30
+ say() { printf "\033[1;37m▸\033[0m %s\n" "$1"; }
31
+ die() { printf "\033[1;31m✖\033[0m %s\n" "$1" >&2; exit 1; }
32
+
33
+ # --- 0. avalanche-cli present? ---------------------------------------------
34
+ if ! command -v avalanche >/dev/null 2>&1; then
35
+ cat >&2 <<'EOF'
36
+ ✖ avalanche-cli not found. Install it:
37
+
38
+ curl -sSfL https://raw.githubusercontent.com/ava-labs/avalanche-cli/main/scripts/install.sh | sh -s -- -b /usr/local/bin
39
+
40
+ # or: brew install ava-labs/tap/avalanche-cli
41
+
42
+ Then re-run: pnpm l1
43
+ EOF
44
+ exit 1
45
+ fi
46
+
47
+ # --- 1. Create the L1 -------------------------------------------------------
48
+ # --sovereign=false keeps this fully non-interactive for local dev (a true
49
+ # sovereign L1 prompts for a validator-manager owner). --test-defaults uses
50
+ # local dev settings (EWOQ pre-funded, fast finality). CLAUDE.md explains each
51
+ # knob (VM, consensus, chain ID, sovereignty) and the Fuji path uses a real
52
+ # sovereign L1.
53
+ say "Creating L1 '$NAME' (Subnet-EVM · chainId $CHAIN_ID · token $TOKEN)…"
54
+ avalanche blockchain create "$NAME" \
55
+ --evm --latest \
56
+ --evm-chain-id "$CHAIN_ID" \
57
+ --evm-token "$TOKEN" \
58
+ --test-defaults \
59
+ --sovereign=false \
60
+ --force </dev/null >/dev/null 2>&1 \
61
+ || die "Failed to create '$NAME'. Try: avalanche blockchain delete $NAME"
62
+
63
+ # --- 2. Deploy it to a local network ----------------------------------------
64
+ say "Deploying '$NAME' locally (first run boots the local network)…"
65
+ avalanche blockchain deploy "$NAME" --local </dev/null || die "Deploy of '$NAME' failed."
66
+
67
+ # --- 3. Discover RPC URL + hex blockchain ID --------------------------------
68
+ # `describe` prints both. We grep by shape (robust across CLI versions).
69
+ say "Reading chain details…"
70
+ OUT="$(avalanche blockchain describe "$NAME" 2>/dev/null)"
71
+ RPC="$(printf '%s' "$OUT" | grep -oE 'http://127\.0\.0\.1:[0-9]+/ext/bc/[A-Za-z0-9]+/rpc' | head -1)"
72
+ BID="$(printf '%s' "$OUT" | grep -iE 'BlockchainID \(HEX\)' | grep -oiE '0x[0-9a-f]{64}' | head -1)"
73
+
74
+ [ -n "$RPC" ] || die "Could not read '$NAME' RPC. Run: avalanche blockchain describe $NAME"
75
+
76
+ # --- 4. Write l1.config.json ------------------------------------------------
77
+ cat > "$CONFIG" <<EOF
78
+ {
79
+ "configured": true,
80
+ "network": "local",
81
+ "name": "$NAME",
82
+ "token": "$TOKEN",
83
+ "evmChainId": $CHAIN_ID,
84
+ "rpcUrl": "$RPC",
85
+ "blockchainIdHex": "${BID:-}",
86
+ "faucetAccount": { "address": "$EWOQ_ADDR", "privateKey": "$EWOQ_PK" }
87
+ }
88
+ EOF
89
+
90
+ say "Wrote l1.config.json → $RPC"
91
+ cat <<EOF
92
+
93
+ ✔ Your L1 is live locally.
94
+
95
+ Next:
96
+ 1. Import the EWOQ dev key into your wallet (Core / MetaMask) — pre-funded on your chain:
97
+ $EWOQ_PK
98
+ (public dev key, local only)
99
+ 2. pnpm dev → http://localhost:3000 (your chain dashboard + explorer)
100
+ 3. Deploy the demo token, watch blocks and transactions land in real time.
101
+
102
+ Manage the network:
103
+ avalanche network stop # pause (keeps state)
104
+ avalanche network clean # wipe (new blockchain ID — re-run pnpm l1)
105
+
106
+ Graduate to the Fuji testnet (advanced, needs test AVAX + an always-on node):
107
+ pnpm l1:fuji
108
+ EOF
@@ -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
+ }