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 .github/workflows/web-starter-playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Install Nargo
uses: noir-lang/[email protected]
with:
toolchain: stable
toolchain: 1.0.0-beta.11

- name: Install bb
run: |
Expand Down Expand Up @@ -81,6 +81,9 @@ jobs:

- name: Run Playwright tests (next)
working-directory: web-starter/web/nextjs
env:
CI: true
NODE_OPTIONS: "--max-old-space-size=4096"
run: |
yarn test:e2e

Expand Down
262 changes: 262 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

This is a reference repository of examples for writing zero-knowledge circuits and applications with [Noir](https://noir-lang.org/). Each subdirectory is a standalone example project demonstrating different Noir use cases and integration patterns.

## Prerequisites

- **Noir (nargo)**: Install via `noirup` - [installation instructions](https://noir-lang.org/docs/getting_started/installation)
- **Barretenberg (bb)**: Install via `bbup` - the proving backend for Noir circuits
- **Node.js/Yarn**: For JavaScript/TypeScript examples
- **Foundry**: Required for Solidity verification examples (`curl -L https://foundry.paradigm.xyz | bash`)

Quick setup for all examples:
```bash
chmod +x ./scripts/setup-all.sh
./scripts/setup-all.sh
```

## Core Development Commands

### Noir Circuit Development

```bash
# Compile a Noir circuit
nargo compile

# Run tests in a Noir circuit
nargo test

# Execute circuit to generate witness
nargo execute

# Generate verifier contract (for Solidity integration)
nargo codegen-verifier

# Prove with bb CLI
bb prove -b ./target/<circuit_name>.json -w target/<circuit_name>.gz -o ./target --oracle_hash keccak

# Generate verification key
bb write_vk --oracle_hash keccak -b ./target/<circuit_name>.json -o ./target

# Generate Solidity verifier
bb write_solidity_verifier -k ./target/vk -o <output_path>/Verifier.sol
```

### JavaScript/TypeScript Proof Generation

Most examples use `yarn` for package management:
```bash
# Install dependencies
yarn install

# Generate proofs (common script name)
yarn generate-proof

# Run tests
yarn test
```

### Foundry (Solidity Examples)

```bash
# Test Solidity contracts with proof verification
forge test --optimize --optimizer-runs 5000 --gas-report -vvv

# Build contracts
forge build

# Deploy (example from solidity-example)
forge script script/Deploy.s.sol:DeployScript --rpc-url <RPC_URL> --broadcast --legacy
```

## Project Structure

### Main Examples

- **`solidity-example/`** - End-to-end example of generating Noir proofs and verifying them on-chain with Solidity verifiers
- `/circuits` - Noir circuit source
- `/js` - JavaScript proof generation using `@noir-lang/noir_js` and `@aztec/bb.js`
- `/contract` - Foundry project with Solidity verifier contracts
- Build: `(cd circuits && ./build.sh)` compiles circuit and generates Solidity verifier

- **`recursion/`** - Demonstrates recursive proof generation where one circuit verifies another circuit's proof
- `/circuits/inner` - Inner circuit that gets proven first
- `/circuits/recursive` - Outer circuit that verifies the inner proof
- `/js` - TypeScript code for generating both proofs
- Build: `(cd circuits && ./build.sh)` compiles both circuits

- **`web-starter/`** - Browser-based proof generation examples
- `/circuits` - Simple Noir circuit
- `/web/vite` - Vite bundler setup
- `/web/webpack` - Webpack bundler setup
- `/web/nextjs` - Next.js integration
- Each web framework requires: circuit compilation (`./circuits/build.sh`), then framework-specific setup

- **`bignum_example/`** - Demonstrates `noir-bignum` library for BLS12-381 field arithmetic
- Minimal example focusing only on Noir circuit usage
- Run: `nargo execute` in circuits directory

- **`lib_examples/`** - Examples using Noir libraries
- `base64_example/` - Base64 encoding/decoding using `noir-base64` library
- Uses workspace structure with shared Nargo.toml

- **`stealthdrop/`** - Complex example using ecrecover, Merkle trees, and PLUME signatures
- Demonstrates integration of multiple cryptographic libraries
- Uses `noir_bigcurve`, `ecrecover`, and custom merkle tree implementations

- **`noir_by_example/`** - Small focused examples of Noir language features
- `loops/` - Loop constructs in Noir
- `generic_traits/` - Generic types and traits
- `simple_macros/` - Macro usage
- Each has both `/noir` (circuit) and `/rust` (host code) directories

## Architecture Patterns

### Noir Circuit Structure

Noir circuits are defined in `src/main.nr` files within a Nargo project:
- `Nargo.toml` - Project configuration (similar to Cargo.toml)
- `Prover.toml` - Input values for circuit execution
- `src/main.nr` - Main circuit logic
- Compiled artifacts go to `target/` directory

Circuit main function signature:
```noir
fn main(private_input: Field, public_output: pub Field) {
// Circuit constraints
}
```

### JavaScript Proof Generation Pattern

Common pattern across examples using `@noir-lang/noir_js` and `@aztec/bb.js`:
1. Import compiled circuit artifacts from `target/` directory
2. Initialize Noir program with artifacts
3. Generate witness from inputs
4. Use Barretenberg backend to generate proof
5. (Optional) Verify proof or pass to Solidity verifier

### Solidity Verification Pattern

1. Generate Solidity verifier using `bb write_solidity_verifier`
2. Deploy verifier contract to EVM chain
3. Format proof and public inputs for Solidity
4. Call verifier contract's `verify()` function

## Version Compatibility

Different examples may use different Noir/bb versions:
- `solidity-example/`: Noir 1.0.0-beta.8, bb 0.87.0
- `recursion/`: Noir 1.0.0-beta.6, bb 0.84.0
- `web-starter/`: Noir 1.0.0-beta.11, bb 0.87.0

Check each project's README for specific version requirements. Version mismatches between nargo and bb can cause compilation or proof generation issues.

## Testing Strategy

- **Noir unit tests**: Use `#[test]` annotations in `.nr` files, run with `nargo test`
- **JavaScript tests**: Usually TypeScript files with test runner (Node.js `--test` or similar)
- **Solidity tests**: Foundry tests in `/test` directories
- **E2E tests**: Some examples have Playwright tests for browser proving

## Common Build Scripts

Most circuit directories contain a `build.sh` script that:
1. Compiles the Noir circuit with `nargo compile`
2. Generates verification key with `bb write_vk`
3. (For Solidity examples) Generates Solidity verifier contract

Always run the build script after modifying circuits.

## Contributing Notes

When adding new examples (per CONTRIBUTING.md):
1. Include Noir circuits
2. Provide execution context (JS/browser/Solidity)
3. Write comprehensive README with setup/run instructions
4. Add automated tests and CI workflow in `.github/workflows/`

Original authors/maintainers for questions: @critesjosh, @signorecello

## PR Review Guidelines

When reviewing pull requests that add new examples, ensure the following requirements are met:

### Example Quality
- **Simplicity**: New examples should be simple and easy to understand. They should focus on demonstrating a specific concept or integration pattern without unnecessary complexity.
- **Clear Purpose**: The example should have a well-defined educational goal that's distinct from existing examples.

### README Requirements
Every new example MUST include a comprehensive README.md that explains:

1. **What the example is**: Clear description of what the example demonstrates and why it's useful
2. **What's included**: Overview of the folder structure and key files
- Example: "`/circuits` - Noir circuit source, `/js` - Proof generation code, `/contract` - Solidity verifier"
3. **How to run**: Step-by-step instructions including:
- Prerequisites and installation steps
- Build commands
- Execution commands
- Expected output
- Common troubleshooting tips

### CI/CD Requirements
New examples MUST include a GitHub Actions workflow in `.github/workflows/` that:

1. **Runs on PRs**: Tests should run when the example's files are modified
```yaml
on:
pull_request:
paths:
- "example-name/**"
```

2. **Runs nightly**: Include a scheduled run at 2 AM UTC
```yaml
schedule:
- cron: "0 2 * * *"
```

3. **Includes workflow_dispatch**: Allow manual triggering
```yaml
workflow_dispatch:
```

4. **Notifies on failure**: Must create an issue when nightly tests fail
```yaml
permissions:
issues: write

- name: Create issue on failure (nightly)
if: failure() && github.event_name == 'schedule'
uses: actions/github-script@v6
with:
script: |
github.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '[Nightly] Example-name workflow failed',
body: `The nightly example-name workflow failed. Please investigate.\n\n/cc @noir-lang/developerrelations`,
labels: ['nightly', 'bug']
})
```

5. **Comprehensive testing**: Should test the complete workflow:
- Compile Noir circuits (`nargo compile`)
- Run Noir unit tests (`nargo test`)
- Execute proof generation
- (If applicable) Verify proofs on-chain or in JavaScript

### Review Checklist
- [ ] Example is simple and focused on one concept
- [ ] README explains what, why, and how
- [ ] README includes folder structure overview
- [ ] README has complete setup and run instructions
- [ ] CI workflow runs on PRs with path filter
- [ ] CI workflow runs nightly (cron schedule)
- [ ] CI workflow creates issues on nightly failures
- [ ] Tests cover the complete example workflow
- [ ] Example works with current stable Noir/bb versions (or documents version requirements)
54 changes: 38 additions & 16 deletions scripts/setup-all.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#!/usr/bin/env bash

# This script was created to make it easy to set up the environment for OpenAI Codex.
# It automates the installation and setup of all necessary dependencies for the
# noir-examples repository, including Noir, Barretenberg, Node.js packages, and Rust projects.
# This script automates the installation and setup of all necessary dependencies
# for the noir-examples repository, including Noir, Barretenberg, Node.js packages,
# and Rust projects.
#
# Usage: ./scripts/setup-all.sh
# Make executable first: chmod +x ./scripts/setup-all.sh

set -euo pipefail

Expand All @@ -17,30 +20,49 @@ curl -sSL https://raw.githubusercontent.com/AztecProtocol/aztec-packages/refs/he
export PATH="$HOME/.bbup/bin:$PATH"
bbup

echo "\n--- Compiling all Noir circuits ---"
find . -name 'Nargo.toml' | while read -r nargo_toml; do
echo ""
echo "--- Compiling all Noir circuits ---"
find . -name 'Nargo.toml' -not -path "*/node_modules/*" -not -path "*/target/*" | while read -r nargo_toml; do
dir=$(dirname "$nargo_toml")
echo "Compiling Noir circuit in $dir"
(cd "$dir" && nargo compile || echo "Failed to compile in $dir")
# Skip workspace members - they'll be compiled by workspace root
if grep -q "^\[workspace\]" "$nargo_toml" 2>/dev/null; then
echo "Compiling Noir workspace in $dir"
(cd "$dir" && nargo compile || echo "Failed to compile in $dir")
elif ! grep -q "members" "$(dirname "$dir")/Nargo.toml" 2>/dev/null; then
# Only compile if not a workspace member
echo "Compiling Noir circuit in $dir"
(cd "$dir" && nargo compile || echo "Failed to compile in $dir")
fi
done

echo "\n--- Installing Node.js dependencies ---"
find . -name 'package.json' | while read -r pkg; do
echo ""
echo "--- Installing Node.js dependencies ---"
find . -name 'package.json' \
-not -path "*/node_modules/*" \
-not -path "*/.next/*" \
-not -path "*/dist/*" \
-not -path "*/target/*" | while read -r pkg; do
dir=$(dirname "$pkg")
if [ -f "$dir/package-lock.json" ] || [ -f "$dir/yarn.lock" ]; then
echo "Installing Node.js deps in $dir"
(cd "$dir" && (npm install || yarn install) || echo "Failed to install Node.js deps in $dir")
echo "Installing Node.js deps in $dir"
if [ -f "$dir/yarn.lock" ]; then
(cd "$dir" && yarn install || echo "Failed to install Node.js deps in $dir")
elif [ -f "$dir/package-lock.json" ]; then
(cd "$dir" && npm install || echo "Failed to install Node.js deps in $dir")
else
echo "Installing Node.js deps in $dir"
# Default to npm if no lockfile exists
(cd "$dir" && npm install || echo "Failed to install Node.js deps in $dir")
fi
done

echo "\n--- Installing Rust dependencies ---"
find . -name 'Cargo.toml' | while read -r cargo; do
echo ""
echo "--- Installing Rust dependencies ---"
find . -name 'Cargo.toml' \
-not -path "*/node_modules/*" \
-not -path "*/target/*" | while read -r cargo; do
dir=$(dirname "$cargo")
echo "Building Rust project in $dir"
(cd "$dir" && cargo build || echo "Failed to build Rust project in $dir")
done

echo "\nAll done!"
echo ""
echo "All done!"
11 changes: 8 additions & 3 deletions web-starter/web/nextjs/playwright.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@ const config = {
webServer: {
command: 'yarn build && yarn start',
port: 3000,
timeout: 120 * 1000,
reuseExistingServer: !process.env.CI,
timeout: 180 * 1000, // Increased to 3 minutes for CI
},
use: {
baseURL: 'http://localhost:3000',
headless: true,
},
// Global test timeout for proof generation
timeout: 300000, // 5 minutes
expect: {
timeout: 180 * 1000, // 3 minutes for assertions
},
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'firefox', use: { browserName: 'firefox' } },
{ name: 'webkit', use: { browserName: 'webkit' } },
// WebKit skipped in CI due to high memory usage during proof generation
...(process.env.CI ? [] : /** @type {any} */ ([{ name: 'webkit', use: { browserName: 'webkit' } }])),
],
};

Expand Down
Loading