Skip to main content
Full Examples:
Description
ZK-IDIdentity verification using Groth16 proofs. Issuers create credentials; users prove ownership without revealing the credential.
Basic Examples:
Description
Simple-NullifierCreates one or four nullifiers. Uses Groth16 proofs and compressed accounts.
Simple-Merkle-ProofCreates compressed accounts and verifies with Groth16 proofs (without nullifier).

AI Assistant Prompt

For AI assistance with your ZK App, copy this prompt and add your design ideas:
---
argument-hint: <add_your_app_description>
description: Design a ZK App POC with rent-free nullifiers, compressed accounts, and Groth16 circuits
allowed-tools: [Bash, Read, Glob, Grep, Task, WebFetch]
---

Design a Solana program with tests that uses rent-free nullifiers, compressed accounts, and Groth16 circuits.


## Initial App Design
<ADD YOUR IDEA AND DESIGN HERE>

## Goal

Produce a **fully working POC** that builds and tests pass.

## Available commands

Via Bash tool:
- `cargo build-sbf`, `cargo test-sbf`, `cargo fmt`, `cargo clippy`
- `anchor build`, `anchor test`, `anchor deploy`
- `circom`, `snarkjs`, `solana`, `light`

## Documentation

- Nullifiers: https://zkcompression.com/zk/nullifiers
- Compressed Accounts with Poseidon Hashes: https://zkcompression.com/zk/compressed-account-zk

## Reference repos

program-examples/zk/zk-id/
├── programs/zk-id/src/
│   ├── lib.rs              # create_issuer, add_credential, zk_verify_credential
│   └── verifying_key.rs    # Groth16 key from circom trusted setup
├── circuits/
│   └── compressed_account_merkle_proof.circom  # Merkle proof + nullifier circuit
└── tests/
└── zk-id.ts            # Proof generation + on-chain verification



## Workflow

### Phase 1: Design application

**1.1 Define private state**

What data stays private? (credentials, balances, votes, etc.)

**1.2 Define public inputs**

What does the circuit prove publicly? (nullifier, merkle root, commitments)

**1.3 Define nullifier scheme**

nullifier = Poseidon(context, secret)



### Phase 2: Index reference implementation

    grep -r "LightAccountPoseidon" program-examples/zk/
    grep -r "Groth16Verifier" program-examples/zk/
    grep -r "derive_address.*nullifier" program-examples/zk/
    grep -r "read_state_merkle_tree_root" program-examples/zk/

Read matching files to understand patterns.

### Phase 3: Circuit development

**3.1 Write circom circuit**

Based on compressed_account_merkle_proof.circom:
- Merkle proof verification
- Nullifier computation
- Public input constraints

**3.2 Trusted setup**

    circom circuit.circom --r1cs --wasm --sym
    snarkjs groth16 setup circuit.r1cs pot_final.ptau circuit_0000.zkey
    snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
    snarkjs zkey export solidityverifier circuit_final.zkey  # adapt for Solana

**3.3 Add sensitive files to .gitignore**

    *.zkey
    *.ptau
    *.r1cs
    *_js/

### Phase 4: Program implementation

| Pattern | Function | Reference |
|---------|----------|-----------|
| Poseidon state | `LightAccountPoseidon::new_init()` | zk-id/lib.rs |
| Nullifier address | `derive_address([prefix, nullifier, ctx], tree, program)` | zk-id/lib.rs |
| Read root only | `read_state_merkle_tree_root()` | zk-id/lib.rs |
| Groth16 verify | `Groth16Verifier::new().verify()` | zk-id/lib.rs |

**Dependencies:**

    [dependencies]
    anchor-lang = "0.31.1"
    light-sdk = { version = "0.17.1", features = ["anchor", "poseidon", "merkle-tree", "v2"] }
    light-hasher = "5.0.0"
    light-sdk-types = { version = "0.17.1", features = ["v2"] }
    groth16-solana = { git = "https://github.com/Lightprotocol/groth16-solana", rev = "66c0dc87" }

    [dev-dependencies]
    light-program-test = "0.17.1"
    light-client = "0.17.1"

### Phase 5: Build and test loop

**Required commands (no shortcuts):**

For Anchor programs: `anchor build && anchor test`

For Native programs: `cargo build-sbf && cargo test-sbf`

**NO shortcuts allowed:**

- Do NOT use `cargo build` (must use `cargo build-sbf`)
- Do NOT use `cargo test` (must use `cargo test-sbf`)
- Do NOT skip SBF compilation
- Tests MUST run against real BPF bytecode

**On failure:** Spawn debugger agent with error context.

**Loop rules:**

1. Each debugger gets fresh context + previous debug reports
2. Each attempt tries something DIFFERENT
3. **NEVER GIVE UP** - keep spawning until fixed

Do NOT proceed until all tests pass.

### Phase 6: Cleanup (only after tests pass)

    rm -rf target/

## DeepWiki fallback

If no matching pattern in reference repos:

    mcp__deepwiki__ask_question("Lightprotocol/light-protocol", "How to {operation}?")