Skip to content

Commit 983dc37

Browse files
tilo-14sergeytimoshintilo-14ananas-block
authored
Add zk-nullifier example and reorganize zk/ folder (#28)
* feat(zk): add nullifier registry example and reorganize zk folder - Add nullifier program using compressed addresses - Reorganize zk examples into zk/ directory (zk-id, nullifier) - Add Makefile for building and testing zk examples - Update CI workflows for zk examples - Fix Photon indexer caching in setup action * ci: skip AVM install on cache hit --------- Co-authored-by: Sergey Timoshin <timoshin.sergey@gmail.com> Co-authored-by: tilo-14 <tilo@luminouslabs.com> Co-authored-by: ananas-block <58553958+ananas-block@users.noreply.github.com>
1 parent 99d260f commit 983dc37

49 files changed

Lines changed: 14829 additions & 113 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/setup/action.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ runs:
6969

7070
- name: Cache AVM and Anchor
7171
if: inputs.node-version != ''
72+
id: cache-avm
7273
uses: actions/cache@v4
7374
with:
7475
path: |
@@ -78,6 +79,7 @@ runs:
7879

7980
- name: Cache Photon indexer
8081
if: inputs.photon-indexer == 'true'
82+
id: cache-photon
8183
uses: actions/cache@v4
8284
with:
8385
path: ~/.cargo/bin/photon
@@ -97,13 +99,18 @@ runs:
9799
fi
98100
99101
- name: Install Anchor CLI
100-
if: inputs.node-version != ''
102+
if: inputs.node-version != '' && steps.cache-avm.outputs.cache-hit != 'true'
101103
shell: bash
102104
run: |
103105
cargo install --git https://github.com/coral-xyz/anchor avm --locked --force
104106
avm install ${{ inputs.anchor-version }}
105107
avm use ${{ inputs.anchor-version }}
106108
109+
- name: Set Anchor version
110+
if: inputs.node-version != '' && steps.cache-avm.outputs.cache-hit == 'true'
111+
shell: bash
112+
run: avm use ${{ inputs.anchor-version }}
113+
107114
- name: Install Light CLI
108115
shell: bash
109116
run: npm install -g @lightprotocol/zk-compression-cli@0.27.1-alpha.2
@@ -137,7 +144,7 @@ runs:
137144
run: npm install -g snarkjs
138145

139146
- name: Install Photon indexer
140-
if: inputs.photon-indexer == 'true'
147+
if: inputs.photon-indexer == 'true' && steps.cache-photon.outputs.cache-hit != 'true'
141148
shell: bash
142149
env:
143150
RUSTFLAGS: "-A dead-code"

.github/workflows/rust-tests.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ jobs:
2929
- counter/native
3030
- counter/pinocchio
3131
- account-comparison
32-
- zk-id
3332
- airdrop-implementations/simple-claim/program
3433
include:
3534
- example: basic-operations/native
@@ -51,12 +50,6 @@ jobs:
5150
example: ${{ matrix.example }}
5251
solana-cli-version: ${{ env.SOLANA_CLI_VERSION }}
5352
rust-toolchain: ${{ env.RUST_TOOLCHAIN }}
54-
install-circom: ${{ matrix.example == 'zk-id' }}
55-
56-
- name: Setup ZK circuits
57-
if: matrix.example == 'zk-id'
58-
working-directory: ${{ matrix.example }}
59-
run: ./scripts/setup.sh
6053

6154
- name: Build and test
6255
working-directory: ${{ matrix.example }}

.github/workflows/typescript-tests.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ jobs:
3434
- basic-operations/anchor/update
3535
- basic-operations/anchor/close
3636
- basic-operations/anchor/reinit
37+
- zk/zk-id
38+
- zk/nullifier
3739
steps:
3840
- uses: actions/checkout@v4
3941

@@ -45,6 +47,12 @@ jobs:
4547
solana-cli-version: ${{ env.SOLANA_CLI_VERSION }}
4648
rust-toolchain: ${{ env.RUST_TOOLCHAIN }}
4749
photon-indexer: "true"
50+
install-circom: ${{ matrix.example == 'zk/zk-id' }}
51+
52+
- name: Setup ZK circuits
53+
if: matrix.example == 'zk/zk-id'
54+
working-directory: ${{ matrix.example }}
55+
run: ./scripts/setup.sh
4856

4957
- name: Install dependencies
5058
working-directory: ${{ matrix.example }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ test-ledger
88
.claude
99
build
1010
pot
11+
12+
# ZK examples - not ready
13+
zk/mixer/
14+
zk/shielded-pool/
15+
zk/zk-merkle-proof/

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@ Full compressed account lifecycle (create, increment, decrement, reset, close):
4747

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

50-
### zk-id Program
50+
### ZK Programs
51+
52+
53+
- **[zk-id](./zk/zk-id)** - Identity verification using Groth16 proofs. Issuers create credentials; users prove ownership without revealing the credential.
54+
- **[nullifier](./zk/nullifier)** - Simple Program to Create Nullifiers. Requires no custom circuit.
5155

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

5457

5558
## Light Protocol dependencies

scripts/format.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ cargo +nightly fmt --manifest-path counter/anchor/Cargo.toml
88
cargo +nightly fmt --manifest-path counter/native/Cargo.toml
99
cargo +nightly fmt --manifest-path counter/pinocchio/Cargo.toml
1010
cargo +nightly fmt --manifest-path account-comparison/Cargo.toml
11+
cargo +nightly fmt --manifest-path zk/nullifier/Cargo.toml
12+
cargo +nightly fmt --manifest-path zk/zk-id/Cargo.toml
1113

1214
# Run clippy on each project individually
1315
cargo clippy --manifest-path create-and-update/Cargo.toml \
@@ -59,3 +61,23 @@ cargo clippy --manifest-path account-comparison/Cargo.toml \
5961
-A unexpected-cfgs \
6062
-A clippy::doc_lazy_continuation \
6163
-D warnings
64+
65+
cargo clippy --manifest-path zk/nullifier/Cargo.toml \
66+
--no-deps \
67+
--all-features \
68+
-- -A clippy::result_large_err \
69+
-A clippy::empty-docs \
70+
-A clippy::to-string-trait-impl \
71+
-A unexpected-cfgs \
72+
-A clippy::doc_lazy_continuation \
73+
-D warnings
74+
75+
cargo clippy --manifest-path zk/zk-id/Cargo.toml \
76+
--no-deps \
77+
--all-features \
78+
-- -A clippy::result_large_err \
79+
-A clippy::empty-docs \
80+
-A clippy::to-string-trait-impl \
81+
-A unexpected-cfgs \
82+
-A clippy::doc_lazy_continuation \
83+
-D warnings

scripts/lint.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ cd counter/pinocchio && cargo fmt --check && cd ../..
2020
echo "Checking account-comparison..."
2121
cd account-comparison && cargo fmt --check && cd ..
2222

23+
echo "Checking zk/nullifier..."
24+
cd zk/nullifier && cargo fmt --check && cd ../..
25+
26+
echo "Checking zk/zk-id..."
27+
cd zk/zk-id && cargo fmt --check && cd ../..
28+
2329
echo "Running clippy..."
2430

2531
# Run clippy for each crate
@@ -38,4 +44,10 @@ cargo clippy --manifest-path counter/pinocchio/Cargo.toml --all-targets --all-fe
3844
echo "Running clippy on account-comparison..."
3945
cargo clippy --manifest-path account-comparison/Cargo.toml --all-targets --all-features -- -D warnings
4046

47+
echo "Running clippy on zk/nullifier..."
48+
cargo clippy --manifest-path zk/nullifier/Cargo.toml --all-targets --all-features -- -D warnings
49+
50+
echo "Running clippy on zk/zk-id..."
51+
cargo clippy --manifest-path zk/zk-id/Cargo.toml --all-targets --all-features -- -D warnings
52+
4153
echo "Lint checks completed successfully!"

zk-id/src/verifying_key.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

zk/Makefile

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Makefile for building and testing all ZK examples
2+
# Usage:
3+
# make all - Build and test all examples
4+
# make build - Build all Solana programs
5+
# make test-rust - Run all Rust tests
6+
# make test-ts - Run all TypeScript tests
7+
# make clean - Clean all build artifacts
8+
9+
SHELL := /bin/bash
10+
11+
# ZK example directories
12+
ZK_EXAMPLES := nullifier zk-id
13+
14+
.PHONY: all build deploy test-rust test-ts clean setup help $(ZK_EXAMPLES)
15+
16+
help:
17+
@echo "ZK Examples Makefile"
18+
@echo ""
19+
@echo "Usage:"
20+
@echo " make all - Build and test all examples (Rust + TypeScript)"
21+
@echo " make build - Build all Solana programs"
22+
@echo " make deploy - Deploy all programs to validator (builds first)"
23+
@echo " make test-rust - Run all Rust tests (cargo test-sbf)"
24+
@echo " make test-ts - Run all TypeScript tests (deploys first)"
25+
@echo " make setup - Setup circuits for all examples"
26+
@echo " make clean - Clean all build artifacts"
27+
@echo ""
28+
@echo "Individual examples:"
29+
@echo " make nullifier - Build and test nullifier"
30+
@echo " make zk-id - Build and test zk-id"
31+
32+
all: build test-rust test-ts
33+
@echo "All examples built and tested successfully!"
34+
35+
build:
36+
@echo "Building all ZK examples..."
37+
@for dir in $(ZK_EXAMPLES); do \
38+
echo "Building $$dir..."; \
39+
cd $$dir && cargo build-sbf && cd ..; \
40+
if [ $$? -ne 0 ]; then \
41+
echo "Failed to build $$dir"; \
42+
exit 1; \
43+
fi; \
44+
echo "$$dir built successfully"; \
45+
done
46+
@echo "All programs built successfully!"
47+
48+
deploy: build
49+
@echo "Deploying all ZK programs..."
50+
@for dir in $(ZK_EXAMPLES); do \
51+
echo "Deploying $$dir..."; \
52+
if [ -f "$$dir/target/deploy/"*.so ]; then \
53+
solana program deploy $$dir/target/deploy/*.so; \
54+
if [ $$? -ne 0 ]; then \
55+
echo "Failed to deploy $$dir"; \
56+
exit 1; \
57+
fi; \
58+
echo "$$dir deployed successfully"; \
59+
else \
60+
echo "No .so file found for $$dir, skipping deploy"; \
61+
fi; \
62+
done
63+
@echo "All programs deployed!"
64+
65+
test-rust:
66+
@echo "Running Rust tests for all ZK examples..."
67+
@for dir in $(ZK_EXAMPLES); do \
68+
echo "Testing $$dir (Rust)..."; \
69+
cd $$dir && cargo test-sbf && cd ..; \
70+
if [ $$? -ne 0 ]; then \
71+
echo "Rust tests failed for $$dir"; \
72+
exit 1; \
73+
fi; \
74+
echo "$$dir Rust tests passed"; \
75+
done
76+
@echo "All Rust tests passed!"
77+
78+
test-ts: deploy
79+
@echo "Running TypeScript tests for all ZK examples..."
80+
@for dir in $(ZK_EXAMPLES); do \
81+
echo "Testing $$dir (TypeScript)..."; \
82+
if [ -f "$$dir/package.json" ]; then \
83+
cd $$dir && npm run test:ts && cd ..; \
84+
if [ $$? -ne 0 ]; then \
85+
echo "TypeScript tests failed for $$dir"; \
86+
exit 1; \
87+
fi; \
88+
echo "$$dir TypeScript tests passed"; \
89+
else \
90+
echo "No package.json found in $$dir, skipping TS tests"; \
91+
fi; \
92+
done
93+
@echo "All TypeScript tests passed!"
94+
95+
setup:
96+
@echo "Setting up circuits for all ZK examples..."
97+
@for dir in $(ZK_EXAMPLES); do \
98+
echo "Setting up $$dir..."; \
99+
if [ -f "$$dir/scripts/setup.sh" ]; then \
100+
cd $$dir && ./scripts/setup.sh && cd ..; \
101+
if [ $$? -ne 0 ]; then \
102+
echo "Setup failed for $$dir"; \
103+
exit 1; \
104+
fi; \
105+
echo "$$dir setup completed"; \
106+
else \
107+
echo "No setup script found in $$dir"; \
108+
fi; \
109+
done
110+
@echo "All setups completed!"
111+
112+
clean:
113+
@echo "Cleaning all ZK examples..."
114+
@for dir in $(ZK_EXAMPLES); do \
115+
echo "Cleaning $$dir..."; \
116+
cd $$dir && cargo clean && cd ..; \
117+
if [ -d "$$dir/build" ]; then \
118+
rm -rf $$dir/build; \
119+
fi; \
120+
if [ -d "$$dir/node_modules" ]; then \
121+
rm -rf $$dir/node_modules; \
122+
fi; \
123+
done
124+
@echo "All examples cleaned!"
125+
126+
# Individual example targets
127+
nullifier:
128+
@echo "Building, deploying, and testing nullifier..."
129+
@cd nullifier && cargo build-sbf && cargo test-sbf
130+
@solana program deploy nullifier/target/deploy/nullifier.so
131+
@if [ -f "nullifier/package.json" ]; then \
132+
cd nullifier && npm run test:ts; \
133+
fi
134+
@echo "nullifier completed!"
135+
136+
zk-id:
137+
@echo "Building, deploying, and testing zk-id..."
138+
@cd zk-id && cargo build-sbf && cargo test-sbf
139+
@solana program deploy zk-id/target/deploy/zk_id.so
140+
@if [ -f "zk-id/package.json" ]; then \
141+
cd zk-id && npm run test:ts; \
142+
fi
143+
@echo "zk-id completed!"
144+

zk/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ZK Examples
2+
3+
Building a private Solana program requires a Merkle tree to store state, a way to track nullifiers, and an indexer to serve Merkle proofs.
4+
5+
You can use Light to:
6+
- Track and store nullifiers rent-free in address Merkle trees, indexed by Solana RPCs.
7+
- Store state rent-free in state Merkle trees as compressed accounts, indexed by Solana RPCs.
8+
9+
[Learn more in the documentation](https://www.zkcompression.com/zk/overview)
10+
11+
## Examples
12+
13+
- **[zk-id](./zk-id)** - Identity verification using Groth16 proofs. Issuers create credentials; users prove ownership without revealing the credential.
14+
- **[nullifier](./nullifier)** - Simple Program to Create Nullifiers. Requires no custom circuit.
15+
16+
## Building and Testing
17+
18+
A Makefile is provided for building, deploying, and testing all examples:
19+
20+
```bash
21+
# Build all programs
22+
make build
23+
24+
# Deploy all programs to local validator
25+
make deploy
26+
27+
# Run Rust tests (cargo test-sbf)
28+
make test-rust
29+
30+
# Run TypeScript tests (deploys programs first)
31+
make test-ts
32+
33+
# Build and run all tests
34+
make all
35+
36+
# Individual examples
37+
make zk-nullifier
38+
make zk-id
39+
40+
# Show all available commands
41+
make help
42+
```

0 commit comments

Comments
 (0)