You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> When prompted, choose your preferred solidity framework (Hardhat or Foundry)
97
+
95
98
In the same terminal, start your local network (a blockchain emulator in your computer):
96
99
97
100
```sh
@@ -163,8 +166,23 @@ Our contract will support three main functions:
163
166
164
167
🔍 Next, switch to the **`Debug Contracts`** page. For now, you should see just one contract there — **`Voting`**.
165
168
169
+
<Tabs>
170
+
<Tablabel="Hardhat">
171
+
172
+
**Hardhat**
173
+
166
174
📁 The contract lives in **`packages/hardhat/contracts/Voting.sol`**
167
175
176
+
</Tab>
177
+
<Tablabel="Foundry">
178
+
179
+
**Foundry**
180
+
181
+
📁 The contract lives in **`packages/foundry/contracts/Voting.sol`**
182
+
183
+
</Tab>
184
+
</Tabs>
185
+
168
186
🔍 Open it up and check out the placeholder functions. Each of them represents a key piece of the voting logic.
169
187
If you can already explain what they’re supposed to do, you’re ahead of the game! 😎
170
188
@@ -364,23 +382,58 @@ Scroll down to the functions **`getVotingData()`** and **`getVoterData(address _
364
382
365
383
Then run:
366
384
385
+
<Tabs>
386
+
<Tablabel="Hardhat">
387
+
388
+
**Hardhat**
389
+
367
390
```sh
368
391
yarn test --grep "Checkpoint2"
369
392
```
370
393
394
+
</Tab>
395
+
<Tablabel="Foundry">
396
+
397
+
**Foundry**
398
+
399
+
```sh
400
+
yarn test --match-test "Checkpoint2"
401
+
```
402
+
403
+
</Tab>
404
+
</Tabs>
405
+
371
406
### 🚀 Tests Passed? You’re Almost There!
372
407
373
408
Great job! If your tests are passing, you’re just one step away from deployment! 🚀
374
409
375
410
Before deploying, make one important change:
376
411
412
+
<Tabs>
413
+
<Tablabel="Hardhat">
414
+
415
+
**Hardhat**
416
+
377
417
1. Open **`00_deploy_your_voting_contract.ts`**
378
418
2. Set your address as the `ownerAddress`
379
419
3. Uncomment deployment of both `poseidon3` and `leanIMT`
380
420
4. Set LeanIMT library address (`leanIMT.address`) at line 62
381
421
382
422
> 💡 **Poseidon3** is the hash function we use. More on that later.
383
423
424
+
</Tab>
425
+
<Tablabel="Foundry">
426
+
427
+
**Foundry**
428
+
429
+
1. Open **`DeployVoting.s.sol`**
430
+
2. Set your address as the `ownerAddress`
431
+
432
+
> 💡 In Foundry, library linking is handled automatically at compile time — no need to deploy PoseidonT3 or LeanIMT separately.
433
+
434
+
</Tab>
435
+
</Tabs>
436
+
384
437
Once that’s done, you’re ready to deploy! 🔗
385
438
386
439
Run `yarn deploy` and check out the front-end
@@ -952,12 +1005,31 @@ You’ve built the circuit, created the verifier contract — now it’s time to
952
1005
953
1006
### 🔹 Step 1: Bring in the Verifier Contract
954
1007
1008
+
<Tabs>
1009
+
<Tablabel="Hardhat">
1010
+
1011
+
**Hardhat**
1012
+
955
1013
1. Replace the placeholder verifier contract **`Verifier.sol`** in **`packages/hardhat/contracts`** with the newly generated contract located in **`packages/circuits/target`**.
956
1014
2. Open **`00_deploy_your_voting_contract.ts`** and:
957
1015
- Uncomment the verifier deployment
958
1016
- Comment out the `verifierAddress`
959
1017
- Update the `args` to match your setup
960
1018
1019
+
</Tab>
1020
+
<Tablabel="Foundry">
1021
+
1022
+
**Foundry**
1023
+
1024
+
1. Replace the placeholder verifier contract **`Verifier.sol`** in **`packages/foundry/contracts`** with the newly generated contract located in **`packages/circuits/target`**.
1025
+
2. Open **`DeployVoting.s.sol`** and:
1026
+
- Uncomment the verifier deployment
1027
+
- Comment out the placeholder `verifierAddress`
1028
+
- Update the constructor call to match your setup
1029
+
1030
+
</Tab>
1031
+
</Tabs>
1032
+
961
1033
3. In **`Voting.sol`**:
962
1034
- At the top, import the verifier contract (just uncomment the existing line)
963
1035
- In the constructor, initialize the verifier and store it in a variable called `i_verifier`
Once implemented, run your tests to make sure everything works:
1118
1190
1191
+
<Tabs>
1192
+
<Tablabel="Hardhat">
1193
+
1194
+
**Hardhat**
1195
+
1119
1196
```sh
1120
1197
yarn test --grep "Checkpoint6"
1121
1198
```
1122
1199
1200
+
</Tab>
1201
+
<Tablabel="Foundry">
1202
+
1203
+
**Foundry**
1204
+
1205
+
```sh
1206
+
yarn test --match-test "Checkpoint6"
1207
+
```
1208
+
1209
+
</Tab>
1210
+
</Tabs>
1211
+
1123
1212
### **✅ Tests Passed? You're So Close!**
1124
1213
1125
1214
If your tests are green, congratulations — you’ve just completed the **core `Voting.sol` contract!** 🎉
@@ -1813,10 +1902,27 @@ For **production-grade apps**, you should generate your own API keys to avoid hi
1813
1902
1814
1903
Configure your keys here:
1815
1904
1905
+
<Tabs>
1906
+
<Tablabel="Hardhat">
1907
+
1908
+
**Hardhat**
1909
+
1816
1910
- 🔷 **`ALCHEMY_API_KEY`** in `packages/hardhat/.env` and `packages/nextjs/.env.local` → [Get key from Alchemy](https://dashboard.alchemy.com/)
1817
1911
- 🔑 **`NEXT_PUBLIC_PIMLICO_API_KEY`** in `packages/nextjs/.env.local` → [Get key from Pimlico](https://dashboard.pimlico.io/)
1818
1912
- 📃 **`ETHERSCAN_API_KEY`** in `packages/hardhat/.env` → [Get key from Etherscan](https://etherscan.io/myapikey)
1819
1913
1914
+
</Tab>
1915
+
<Tablabel="Foundry">
1916
+
1917
+
**Foundry**
1918
+
1919
+
- 🔷 **`ALCHEMY_API_KEY`** in `packages/foundry/.env` and `packages/nextjs/.env.local` → [Get key from Alchemy](https://dashboard.alchemy.com/)
1920
+
- 🔑 **`NEXT_PUBLIC_PIMLICO_API_KEY`** in `packages/nextjs/.env.local` → [Get key from Pimlico](https://dashboard.pimlico.io/)
1921
+
- 📃 **`ETHERSCAN_API_KEY`** in `packages/foundry/.env` → [Get key from Etherscan](https://etherscan.io/myapikey)
1922
+
1923
+
</Tab>
1924
+
</Tabs>
1925
+
1820
1926
> 💬 Hint: Store environment variables for **Next.js** in Vercel/system env config for live apps, and use `.env.local` for local testing.
1821
1927
1822
1928
### Deploying Your Smart Contracts
@@ -1827,11 +1933,28 @@ Configure your keys here:
1827
1933
1828
1934
⛽️ You will need to send ETH to your deployer address with your wallet, or obtain it from a public faucet of your chosen network.
1829
1935
1830
-
> 🚨 Don’t forget to set the owner address inside the 00_deploy_your_voting_contract.ts .
1936
+
<Tabs>
1937
+
<Tablabel="Hardhat">
1938
+
1939
+
**Hardhat**
1940
+
1941
+
> 🚨 Don't forget to set the owner address inside the `00_deploy_your_voting_contract.ts`.
1942
+
1943
+
🚀 Run `yarn deploy --network sepolia` to deploy your smart contract to Sepolia.
1944
+
1945
+
> 💬 Hint: You can set the defaultNetwork in hardhat.config.ts to sepolia OR you can yarn deploy --network sepolia.
1831
1946
1832
-
🚀 Run `yarn deploy --network sepolia` to deploy your smart contract to Sepolia.
1947
+
</Tab>
1948
+
<Tablabel="Foundry">
1833
1949
1834
-
> 💬 Hint: You can set the defaultNetwork in hardhat.config.ts to sepolia OR you can yarn deploy --network sepolia.
1950
+
**Foundry**
1951
+
1952
+
> 🚨 Don't forget to set the owner address inside the `DeployVoting.s.sol`.
1953
+
1954
+
🚀 Run `yarn deploy --network sepolia` to deploy your smart contract to Sepolia.
1955
+
1956
+
</Tab>
1957
+
</Tabs>
1835
1958
1836
1959
💻 Inside `scaffold.config.ts` change the `targetNetwork` to `chains.sepolia`. View your front-end at http://localhost:3000 and verify you see the correct network Sepolia.
1837
1960
@@ -1953,3 +2076,15 @@ But this is just the beginning. The same **commitment + nullifier** pattern that
1953
2076
This challenge is your **entry point into a new design space.** 💥
1954
2077
1955
2078
**What will you build with Noir and ZK circuits? 🧪✨**
2079
+
2080
+
## AI-Guided Learning Mode (Optional)
2081
+
2082
+
This challenge supports an interactive AI learning mode. Instead of reading instructions above, you can let an AI guide you step by step.
2083
+
2084
+
**How to use:**
2085
+
1. Open a terminal in the project root
2086
+
2. Run `/start` to begin the guided challenge
2087
+
3. The AI will teach concepts and give you coding tasks
2088
+
4. Say `check` to validate your code, `hint` for help, or `/skip` to skip a task
2089
+
2090
+
> Note: If you chose Foundry as your framework, the screenshots in this README show the Hardhat version, but the contract logic and challenge flow are identical.
Copy file name to clipboardExpand all lines: extension/.ai/CHALLENGE.yaml
+15-5Lines changed: 15 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,9 @@ difficulty: "advanced"
5
5
estimated_time: "6 - 16 hours"
6
6
7
7
setup:
8
-
file: "packages/hardhat/contracts/Voting.sol"
8
+
file:
9
+
hardhat: "packages/hardhat/contracts/Voting.sol"
10
+
foundry: "packages/foundry/contracts/Voting.sol"
9
11
10
12
welcome_message: |
11
13
Welcome to the ZK Voting Challenge!
@@ -169,8 +171,12 @@ checkpoints:
169
171
4. Check `getVotingData()` — you should see Merkle tree data (size, depth, root).
170
172
171
173
Say **"check"** when you're ready!
172
-
file: "packages/hardhat/contracts/Voting.sol"
173
-
test: "yarn test --grep 'Checkpoint2'"
174
+
file:
175
+
hardhat: "packages/hardhat/contracts/Voting.sol"
176
+
foundry: "packages/foundry/contracts/Voting.sol"
177
+
test:
178
+
hardhat: "yarn test --grep 'Checkpoint2'"
179
+
foundry: "yarn test --match-test 'Checkpoint2'"
174
180
hints:
175
181
- "The two guard checks use existing state: `s_voters` (allowlist) and the new `s_hasRegistered` mapping."
176
182
- |
@@ -719,8 +725,12 @@ checkpoints:
719
725
4. Head to the **Voting** page — the full voting flow is now functional on the contract side!
720
726
721
727
Say **"check"** when you're ready!
722
-
file: "packages/hardhat/contracts/Voting.sol"
723
-
test: "yarn test --grep 'Checkpoint6'"
728
+
file:
729
+
hardhat: "packages/hardhat/contracts/Voting.sol"
730
+
foundry: "packages/foundry/contracts/Voting.sol"
731
+
test:
732
+
hardhat: "yarn test --grep 'Checkpoint6'"
733
+
foundry: "yarn test --match-test 'Checkpoint6'"
724
734
hints:
725
735
- "Don't forget the setup steps: replace Verifier.sol, update the deploy script, uncomment the import, add the two state variables, and initialize `i_verifier` in the constructor."
Copy file name to clipboardExpand all lines: extension/.ai/instructions/skip-content.md
+5-2Lines changed: 5 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,10 @@ Read `.ai/CHALLENGE.yaml` and find the current checkpoint by its ID.
14
14
15
15
- If the current checkpoint does NOT have a `task` field, tell the user:
16
16
"This checkpoint doesn't have a coding task to skip. Say 'hint' if you need help with the current question."
17
-
- If it has a `task` field, continue to Step 3
17
+
- If it has a `task` field, continue to Step 2b
18
+
19
+
### Step 2b: Resolve Framework-Specific Fields
20
+
CHALLENGE.yaml `file:` and `test:` fields contain framework-specific values (e.g. `hardhat:` and `foundry:`). Detect which framework this project uses by checking which directory exists (`packages/hardhat/` vs `packages/foundry/`). Use the matching key for all `file:` and `test:` lookups throughout the skip flow.
18
21
19
22
### Step 3: Show the Solution
20
23
Display the solution from `task.solution` with an explanation:
@@ -38,7 +41,7 @@ Read the current contract file (`task.file`) and apply the solution code:
38
41
- Be careful to place code in the correct sections of the contract
39
42
40
43
### Step 5: Run Tests
41
-
Execute the `task.test` command (e.g., `yarn test --grep "Checkpoint1"`) to verify the solution works.
44
+
Execute the `task.test` command (resolved for the detected framework, e.g., `yarn test --grep "Checkpoint1"` for Hardhat or `yarn test --match-test "Checkpoint1"` for Foundry) to verify the solution works.
42
45
- If tests pass: continue to Step 6
43
46
- If tests fail: debug and fix (this shouldn't happen with correct solutions)
Copy file name to clipboardExpand all lines: extension/.ai/instructions/start-content.md
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,6 +33,9 @@ Read the file `.ai/CHALLENGE.yaml` to understand:
33
33
- All checkpoints with their context, questions, tasks, and code unlocks
34
34
- Whether each checkpoint is a **concept checkpoint** (has `unlocks`) or a **code-writing checkpoint** (has `task`)
35
35
36
+
### Step 1b: Resolve Framework-Specific Fields
37
+
CHALLENGE.yaml `file:` and `test:` fields contain framework-specific values (e.g. `hardhat:` and `foundry:`). Detect which framework this project uses by checking which directory exists (`packages/hardhat/` vs `packages/foundry/`). Use the matching key for all `file:` and `test:` lookups throughout the challenge.
38
+
36
39
### Step 2: Apply Setup (if applicable)
37
40
Check if CHALLENGE.yaml has a `setup.template` field:
38
41
@@ -274,7 +277,7 @@ The user will respond with one of:
274
277
275
278
### Phase 5: Validate with Tests
276
279
277
-
Run the test command from `task.test` (e.g., `yarn test --grep "Checkpoint1"`).
280
+
Run the test command from `task.test` (resolved for the detected framework, e.g., `yarn test --grep "Checkpoint1"` for Hardhat or `yarn test --match-test "Checkpoint1"` for Foundry).
0 commit comments