Skip to content
Closed
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
8 changes: 5 additions & 3 deletions .github/workflows/rust-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ jobs:
- counter/native
- counter/pinocchio
- account-comparison
- zk-id
- zk/zk-id
- zk/zk-nullifier
- zk/zk-merkle-proof
- airdrop-implementations/simple-claim/program
include:
- example: basic-operations/native
Expand All @@ -51,10 +53,10 @@ jobs:
example: ${{ matrix.example }}
solana-cli-version: ${{ env.SOLANA_CLI_VERSION }}
rust-toolchain: ${{ env.RUST_TOOLCHAIN }}
install-circom: ${{ matrix.example == 'zk-id' }}
install-circom: ${{ startsWith(matrix.example, 'zk/') || startsWith(matrix.example, 'zk/') }}

- name: Setup ZK circuits
if: matrix.example == 'zk-id'
if: startsWith(matrix.example, 'zk/') || startsWith(matrix.example, 'zk/')
working-directory: ${{ matrix.example }}
run: ./scripts/setup.sh

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ test-ledger
.claude
build
pot

# ZK examples - not ready
zk/mixer/
zk/shielded-pool/
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@
For simple client side distribution visit [this example](https://github.com/Lightprotocol/example-token-distribution).

### Basic Operations
- **[create-nullifier](./basic-operations/anchor/create-nullifier)** - Basic Anchor example to create nullifiers.
- **[basic-operations/anchor](./basic-operations/anchor/)** - Anchor program with Rust and TypeScript tests
- **[basic-operations/native-rust](./basic-operations/native-rust/)** - Native Solana program with light-sdk and Rust tests.

Basic Operations include:
- **create** - Initialize a new compressed account.
- **update** - Modify data in an existing compressed account.
- **close** - Clear account data and preserve its address.
- **reinit** - Reinitialize a closed account with the same address.
- **burn** - Permanently delete a compressed account.
- **[create-nullifier](./basic-operations/anchor/create-nullifier)** - Basic Anchor example to create nullifiers for payments.
- **create** - Initialize a new compressed account
- [Anchor](./basic-operations/anchor/create) | [Native](./basic-operations/native/programs/create)
- **update** - Modify data in an existing compressed account
- [Anchor](./basic-operations/anchor/update) | [Native](./basic-operations/native/programs/update)
- **close** - Clear account data and preserve its address
- [Anchor](./basic-operations/anchor/close) | [Native](./basic-operations/native/programs/close)
- **reinit** - Reinitialize a closed account with the same address
- [Anchor](./basic-operations/anchor/reinit) | [Native](./basic-operations/native/programs/reinit)
- **burn** - Permanently delete a compressed account
- [Anchor](./basic-operations/anchor/burn) | [Native](./basic-operations/native/programs/burn)

### Counter Program

Expand All @@ -45,9 +47,16 @@ Full compressed account lifecycle (create, increment, decrement, reset, close):

- **[account-comparison](./account-comparison/)** - Compare compressed vs regular Solana accounts.

### zk-id Program
### ZK Programs

- **[zk-id](./zk-id)** - A minimal zk id Solana program that uses zero-knowledge proofs for identity verification with compressed accounts.
**Full Examples:**

- **[zk-id](./zk/zk-id)** - Identity verification using Groth16 proofs. Issuers create credentials; users prove ownership without revealing the credential.

**Basic Examples:**

- **[zk-nullifier](./zk/zk-nullifier)** - Creates one or four nullifiers. Uses Groth16 proofs and compressed accounts.
- **[zk-merkle-proof](./zk/zk-merkle-proof)** - Creates compressed accounts and verifies with Groth16 proofs (without nullifier).


## Light Protocol dependencies
Expand Down
153 changes: 153 additions & 0 deletions zk/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Makefile for building and testing all ZK examples
# Usage:
# make all - Build and test all examples
# make build - Build all Solana programs
# make test-rust - Run all Rust tests
# make test-ts - Run all TypeScript tests
# make clean - Clean all build artifacts

SHELL := /bin/bash

# ZK example directories
ZK_EXAMPLES := zk-nullifier zk-id zk-merkle-proof

.PHONY: all build deploy test-rust test-ts clean setup help $(ZK_EXAMPLES)

help:
@echo "ZK Examples Makefile"
@echo ""
@echo "Usage:"
@echo " make all - Build and test all examples (Rust + TypeScript)"
@echo " make build - Build all Solana programs"
@echo " make deploy - Deploy all programs to validator (builds first)"
@echo " make test-rust - Run all Rust tests (cargo test-sbf)"
@echo " make test-ts - Run all TypeScript tests (deploys first)"
@echo " make setup - Setup circuits for all examples"
@echo " make clean - Clean all build artifacts"
@echo ""
@echo "Individual examples:"
@echo " make zk-nullifier - Build and test zk-nullifier"
@echo " make zk-id - Build and test zk-id"
@echo " make zk-merkle-proof - Build and test zk-merkle-proof"

all: build test-rust test-ts
@echo "All examples built and tested successfully!"

build:
@echo "Building all ZK examples..."
@for dir in $(ZK_EXAMPLES); do \
echo "Building $$dir..."; \
cd $$dir && cargo build-sbf && cd ..; \
if [ $$? -ne 0 ]; then \
echo "Failed to build $$dir"; \
exit 1; \
fi; \
echo "$$dir built successfully"; \
done
@echo "All programs built successfully!"

deploy: build
@echo "Deploying all ZK programs..."
@for dir in $(ZK_EXAMPLES); do \
echo "Deploying $$dir..."; \
if [ -f "$$dir/target/deploy/"*.so ]; then \
solana program deploy $$dir/target/deploy/*.so; \
if [ $$? -ne 0 ]; then \
echo "Failed to deploy $$dir"; \
exit 1; \
fi; \
echo "$$dir deployed successfully"; \
else \
echo "No .so file found for $$dir, skipping deploy"; \
fi; \
done
@echo "All programs deployed!"

test-rust:
@echo "Running Rust tests for all ZK examples..."
@for dir in $(ZK_EXAMPLES); do \
echo "Testing $$dir (Rust)..."; \
cd $$dir && cargo test-sbf && cd ..; \
if [ $$? -ne 0 ]; then \
echo "Rust tests failed for $$dir"; \
exit 1; \
fi; \
echo "$$dir Rust tests passed"; \
done
@echo "All Rust tests passed!"

test-ts: deploy
@echo "Running TypeScript tests for all ZK examples..."
@for dir in $(ZK_EXAMPLES); do \
echo "Testing $$dir (TypeScript)..."; \
if [ -f "$$dir/package.json" ]; then \
cd $$dir && npm run test:ts && cd ..; \
if [ $$? -ne 0 ]; then \
echo "TypeScript tests failed for $$dir"; \
exit 1; \
fi; \
echo "$$dir TypeScript tests passed"; \
else \
echo "No package.json found in $$dir, skipping TS tests"; \
fi; \
done
@echo "All TypeScript tests passed!"

setup:
@echo "Setting up circuits for all ZK examples..."
@for dir in $(ZK_EXAMPLES); do \
echo "Setting up $$dir..."; \
if [ -f "$$dir/scripts/setup.sh" ]; then \
cd $$dir && ./scripts/setup.sh && cd ..; \
if [ $$? -ne 0 ]; then \
echo "Setup failed for $$dir"; \
exit 1; \
fi; \
echo "$$dir setup completed"; \
else \
echo "No setup script found in $$dir"; \
fi; \
done
@echo "All setups completed!"

clean:
@echo "Cleaning all ZK examples..."
@for dir in $(ZK_EXAMPLES); do \
echo "Cleaning $$dir..."; \
cd $$dir && cargo clean && cd ..; \
if [ -d "$$dir/build" ]; then \
rm -rf $$dir/build; \
fi; \
if [ -d "$$dir/node_modules" ]; then \
rm -rf $$dir/node_modules; \
fi; \
done
@echo "All examples cleaned!"

# Individual example targets
zk-nullifier:
@echo "Building, deploying, and testing zk-nullifier..."
@cd zk-nullifier && cargo build-sbf && cargo test-sbf
@solana program deploy zk-nullifier/target/deploy/zk_nullifier.so
@if [ -f "zk-nullifier/package.json" ]; then \
cd zk-nullifier && npm run test:ts; \
fi
@echo "zk-nullifier completed!"

zk-id:
@echo "Building, deploying, and testing zk-id..."
@cd zk-id && cargo build-sbf && cargo test-sbf
@solana program deploy zk-id/target/deploy/zk_id.so
@if [ -f "zk-id/package.json" ]; then \
cd zk-id && npm run test:ts; \
fi
@echo "zk-id completed!"

zk-merkle-proof:
@echo "Building, deploying, and testing zk-merkle-proof..."
@cd zk-merkle-proof && cargo build-sbf && cargo test-sbf
@solana program deploy zk-merkle-proof/target/deploy/zk_merkle_proof.so
@if [ -f "zk-merkle-proof/package.json" ]; then \
cd zk-merkle-proof && npm run test:ts; \
fi
@echo "zk-merkle-proof completed!"
59 changes: 59 additions & 0 deletions zk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# ZK Examples

Building a private Solana program requires a Merkle tree to store state, a way to track nullifiers, and an indexer to serve Merkle proofs.

You can use Light to:
- Track and store nullifiers rent-free in indexed address Merkle trees
- Store state rent-free in indexed state Merkle trees as compressed accounts

[Learn more in the documentation](https://www.zkcompression.com/zk/overview)

## Examples

**Full Examples:**

- **[zk-id](./zk-id)** - Identity verification using Groth16 proofs. Issuers create credentials; users prove ownership without revealing the credential.

**Basic Examples:**

- **[zk-nullifier](./zk-nullifier)** - Creates one or four nullifiers. Uses Groth16 proofs and compressed accounts.
- **[zk-merkle-proof](./zk-merkle-proof)** - Creates compressed accounts and verifies with Groth16 proofs (without nullifier).

## Building and Testing

A Makefile is provided for building, deploying, and testing all examples:

```bash
# Build all programs
make build

# Deploy all programs to local validator
make deploy

# Run Rust tests (cargo test-sbf)
make test-rust

# Run TypeScript tests (deploys programs first)
make test-ts

# Build and run all tests
make all

# Individual examples
make zk-nullifier
make zk-id
make zk-merkle-proof

# Show all available commands
make help
```

## Light Protocol V2 API

These examples use Light Protocol SDK v0.17+ with the V2 accounts layout:

- `light_sdk::cpi::v2::CpiAccounts` - V2 CPI accounts builder
- `light_sdk::cpi::v2::LightSystemProgramCpi` - V2 system program CPI
- `PackedAddressTreeInfo::into_new_address_params_assigned_packed()` - V2 address parameters

The V2 layout requires a `system_accounts_offset` parameter to locate system accounts in remaining accounts.
File renamed without changes.
19 changes: 19 additions & 0 deletions zk/zk-id/Anchor.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[toolchain]
anchor_version = "0.31.1"

[features]
resolution = true
skip-lint = false

[programs.localnet]
zk_id = "7pdkPiKhTPz3uQoZKxjArFSXhLJP4fyA6X3v974MFFNa"

[registry]
url = "https://api.apr.dev"

[provider]
cluster = "localnet"
wallet = "~/.config/solana/id.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions zk/zk-id/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[workspace]
members = ["programs/zk-id"]
resolver = "2"

[profile.release]
overflow-checks = true
lto = "fat"
codegen-units = 1

[profile.release.build-override]
opt-level = 3
incremental = false
codegen-units = 1
50 changes: 45 additions & 5 deletions zk-id/README.md → zk/zk-id/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,41 @@ This script will:

## Build and Test

### Using Makefile (recommended)

From the parent `zk/` directory:

```bash
# Build, deploy, and test this example
make zk-id

# Or run individual steps
make build # Build all programs
make deploy # Deploy to local validator
make test-ts # Run TypeScript tests
```

### Manual commands

**Build:**
```bash
# Build the program
cargo build-sbf
```

# Run tests and see tx
**Rust tests** (full ZK verification flow):
```bash
RUST_BACKTRACE=1 cargo test-sbf -- --nocapture
```

**TypeScript tests:**

Requires a running local validator with Light Protocol:
```bash
light test-validator # In separate terminal
npm install
npm run test:ts
```

## Structure

```
Expand All @@ -87,11 +114,24 @@ zk-id/
├── scripts/
│ └── setup.sh # Circuit compilation and setup script
├── src/
│ └── lib.rs # Solana program implementation
└── tests/
└── test.rs # Integration tests
│ ├── lib.rs # Solana program implementation
│ └── verifying_key.rs # Generated Groth16 verifying key
├── tests/
│ └── test.rs # Rust integration tests
└── ts-tests/
└── zk-id.test.ts # TypeScript tests
```

## Light Protocol V2 API

This example uses Light SDK v0.17+ with the V2 accounts layout:

- `system_accounts_offset` parameter to locate system accounts in remaining accounts
- `CpiAccounts::new()` from `light_sdk::cpi::v2`
- `into_new_address_params_assigned_packed(seed, Some(index))` for address parameters
- `sha::LightAccount` for accounts with Vec fields (uses SHA256 flat hashing)
- `poseidon::LightAccount` for accounts with fixed-size fields (uses Poseidon hashing)

## Cleaning Build Artifacts

To clean generated circuit files:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading