Skip to content

Conversation

@tilo-14
Copy link
Contributor

@tilo-14 tilo-14 commented Jan 12, 2026

Summary

  • Add zk-nullifier example: minimal nullifier implementation using compressed PDAs
  • Move zk-id from root to zk/ folder for better organization
  • Update CI to test both zk/zk-id and zk/zk-nullifier

Test plan

  • CI passes for zk/zk-id
  • CI passes for zk/zk-nullifier

Summary by CodeRabbit

  • Documentation
    • Enhanced README with per-operation entries for create, update, close, reinit, and burn, including Anchor and Native cross-links.
    • Renamed "zk-id Program" to "ZK Programs" and reorganized content.
    • Added Full Examples (zk-id with Groth16-based identity verification) and Basic Examples (zk-nullifier, zk-merkle-proof) with purposes and proof usage.
    • Minor formatting and linking improvements.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (12)
  • zk/zk-id/circuits/merkle_proof.circom is excluded by none and included by none
  • zk/zk-id/src/lib.rs is excluded by none and included by none
  • zk/zk-merkle-proof/Anchor.toml is excluded by none and included by none
  • zk/zk-nullifier/Cargo.lock is excluded by !**/*.lock and included by none
  • zk/zk-nullifier/Cargo.toml is excluded by none and included by none
  • zk/zk-nullifier/circuits/nullifier.circom is excluded by none and included by none
  • zk/zk-nullifier/circuits/nullifier_1.circom is excluded by none and included by none
  • zk/zk-nullifier/circuits/nullifier_4.circom is excluded by none and included by none
  • zk/zk-nullifier/scripts/setup.sh is excluded by none and included by none
  • zk/zk-nullifier/src/lib.rs is excluded by none and included by none
  • zk/zk-nullifier/src/nullifier_1.rs is excluded by none and included by none
  • zk/zk-nullifier/src/nullifier_batch_4.rs is excluded by none and included by none

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

README.md reorganized: per-operation entries (create, update, close, reinit, burn) added with Anchor and Native cross-links; zk-id section retitled to "ZK Programs" and expanded with Full and Basic examples including zk-id, zk-nullifier, and zk-merkle-proof; minor formatting and path corrections applied.

Changes

Cohort / File(s) Summary
Documentation
README.md
Replaced general operation descriptions with detailed per-operation entries (create, update, close, reinit, burn); added Anchor and Native implementation cross-links; renamed/retitled zk-id section to "ZK Programs" and expanded with Full Examples (zk-id) and Basic Examples (zk-nullifier, zk-merkle-proof); corrected zk-id path references and adjusted formatting.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

📘 Operations split and neatly shown,
Anchor links and Native known,
ZK Programs bloom with examples bright,
Paths fixed up, the docs feel right. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions 'Add zk-nullifier example and reorganize zk/ folder' but the README.md changes focus on documentation updates (adding cross-links, reorganizing ZK Programs section, and adding example descriptions) rather than adding a new zk-nullifier example or folder reorganization. Update the title to reflect the actual changes: 'Update README with ZK programs documentation and cross-links' or similar, as the substantial work in this PR is documentation restructuring, not folder reorganization.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-nullifier

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tilo-14 tilo-14 force-pushed the feat/add-nullifier branch from 83c4c38 to 1e5f303 Compare January 12, 2026 21:51
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @README.md:
- Around line 21-22: Update the README entry for the "close" operation to state
that it not only clears account data and preserves the account address but also
reclaims the account's rent (freeing lamports) — highlight that this
distinguishes close from burn and that the preserved address can be reused for
reinitialization; change the line starting with "**close** - Clear account data
and preserve its address" to include "reclaims rent" and a short contrast to
"burn" while leaving the Anchor and Native links intact.
- Around line 25-26: Update the README entry for the "burn" operation to
explicitly state that burning permanently deletes a compressed account and
prevents the account address from being reused; reference the "burn" operation
name (and its links "Anchor" and "Native") and add a short contrasting clause
noting that this differs from "close" operations which allow address
reinitialization.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99d260f and 1e5f303.

⛔ Files ignored due to path filters (64)
  • .github/workflows/rust-tests.yml is excluded by none and included by none
  • zk/zk-id/.gitignore is excluded by none and included by none
  • zk/zk-id/Anchor.toml is excluded by none and included by none
  • zk/zk-id/CLAUDE.md is excluded by none and included by none
  • zk/zk-id/Cargo.lock is excluded by !**/*.lock and included by none
  • zk/zk-id/Cargo.toml is excluded by none and included by none
  • zk/zk-id/README.md is excluded by none and included by none
  • zk/zk-id/Xargo.toml is excluded by none and included by none
  • zk/zk-id/build.rs is excluded by none and included by none
  • zk/zk-id/circuits/README.md is excluded by none and included by none
  • zk/zk-id/circuits/compressed_account.circom is excluded by none and included by none
  • zk/zk-id/circuits/compressed_account_merkle_proof.circom is excluded by none and included by none
  • zk/zk-id/circuits/credential.circom is excluded by none and included by none
  • zk/zk-id/circuits/merkle_proof.circom is excluded by none and included by none
  • zk/zk-id/package-lock.json is excluded by !**/package-lock.json and included by none
  • zk/zk-id/package.json is excluded by none and included by none
  • zk/zk-id/scripts/clean.sh is excluded by none and included by none
  • zk/zk-id/scripts/setup.sh is excluded by none and included by none
  • zk/zk-id/src/lib.rs is excluded by none and included by none
  • zk/zk-id/src/verifying_key.rs is excluded by none and included by none
  • zk/zk-id/tests/circuit.rs is excluded by none and included by none
  • zk/zk-id/tests/test.rs is excluded by none and included by none
  • zk/zk-merkle-proof/.gitignore is excluded by none and included by none
  • zk/zk-merkle-proof/Cargo.lock is excluded by !**/*.lock and included by none
  • zk/zk-merkle-proof/Cargo.toml is excluded by none and included by none
  • zk/zk-merkle-proof/README.md is excluded by none and included by none
  • zk/zk-merkle-proof/Xargo.toml is excluded by none and included by none
  • zk/zk-merkle-proof/build.rs is excluded by none and included by none
  • zk/zk-merkle-proof/circuits/README.md is excluded by none and included by none
  • zk/zk-merkle-proof/circuits/account_merkle_proof.circom is excluded by none and included by none
  • zk/zk-merkle-proof/circuits/compressed_account.circom is excluded by none and included by none
  • zk/zk-merkle-proof/circuits/compressed_account_merkle_proof.circom is excluded by none and included by none
  • zk/zk-merkle-proof/circuits/credential.circom is excluded by none and included by none
  • zk/zk-merkle-proof/circuits/merkle_proof.circom is excluded by none and included by none
  • zk/zk-merkle-proof/package-lock.json is excluded by !**/package-lock.json and included by none
  • zk/zk-merkle-proof/package.json is excluded by none and included by none
  • zk/zk-merkle-proof/scripts/clean.sh is excluded by none and included by none
  • zk/zk-merkle-proof/scripts/setup.sh is excluded by none and included by none
  • zk/zk-merkle-proof/src/lib.rs is excluded by none and included by none
  • zk/zk-merkle-proof/src/verifying_key.rs is excluded by none and included by none
  • zk/zk-merkle-proof/tests/test.rs is excluded by none and included by none
  • zk/zk-nullifier/.gitignore is excluded by none and included by none
  • zk/zk-nullifier/Anchor.toml is excluded by none and included by none
  • zk/zk-nullifier/CLAUDE.md is excluded by none and included by none
  • zk/zk-nullifier/Cargo.lock is excluded by !**/*.lock and included by none
  • zk/zk-nullifier/Cargo.toml is excluded by none and included by none
  • zk/zk-nullifier/README.md is excluded by none and included by none
  • zk/zk-nullifier/Xargo.toml is excluded by none and included by none
  • zk/zk-nullifier/build.rs is excluded by none and included by none
  • zk/zk-nullifier/circuits/batch_nullifier.circom is excluded by none and included by none
  • zk/zk-nullifier/circuits/batchnullifier.circom is excluded by none and included by none
  • zk/zk-nullifier/circuits/nullifier.circom is excluded by none and included by none
  • zk/zk-nullifier/nullifier-flow.mmd is excluded by none and included by none
  • zk/zk-nullifier/package-lock.json is excluded by !**/package-lock.json and included by none
  • zk/zk-nullifier/package.json is excluded by none and included by none
  • zk/zk-nullifier/programs/zk_nullifier is excluded by none and included by none
  • zk/zk-nullifier/scripts/clean.sh is excluded by none and included by none
  • zk/zk-nullifier/scripts/setup.sh is excluded by none and included by none
  • zk/zk-nullifier/sequence-diagram.mmd is excluded by none and included by none
  • zk/zk-nullifier/src/batch_verifying_key.rs is excluded by none and included by none
  • zk/zk-nullifier/src/lib.rs is excluded by none and included by none
  • zk/zk-nullifier/src/verifying_key.rs is excluded by none and included by none
  • zk/zk-nullifier/tests/test_batch.rs is excluded by none and included by none
  • zk/zk-nullifier/tests/test_single.rs is excluded by none and included by none
📒 Files selected for processing (1)
  • README.md
🧰 Additional context used
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.rs : Implement credential nullifier pattern to ensure each credential can only be used once per `verification_id`, using the event account address as a nullifier
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:10.392Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In src/merkle_tree.rs, implement BatchedMerkleTreeAccount::update_tree_from_input_queue method for batch nullify operations on StateV2 trees. The method must verify ZKP proving correctness of: old_root + queue nullifiers → new_root, update tree root, increment tree sequence_number, increment tree nullifier_next_index by zkp_batch_size, mark ZKP batch as inserted, transition batch state to Inserted when all ZKP batches complete, and zero out bloom filter when current batch is 50% inserted.
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:27:00.938Z
Learning: Applies to zk-id/**/*.rs : Nullifier computation: Nullifier = Poseidon(verification_id, credential_private_key) to prevent double-use per verification context
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/circuits/README.md:0-0
Timestamp: 2026-01-10T19:25:50.479Z
Learning: Applies to zk-id/circuits/**/*credential*.circom : Implement nullifier generation using Poseidon hash of verification_id and credential_secret to prevent double-spending
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: This is a minimal example for verifying zk inclusion proofs and not a full zk identity protocol or production-ready implementation - refer to Iden3 or Semaphore for production identity protocols
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.rs : Verify zero-knowledge proofs of credential ownership using the `zk_verify_credential` instruction with Groth16 verification and create encrypted event accounts to store verification results on-chain
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:14.561Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In `BatchedMerkleTreeAccount::insert_nullifier_into_queue`, update hash chain store with Poseidon hash: `Poseidon(prev_hash_chain, nullifier)`
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.rs : Ensure credential verification is private by not exposing the credential during zk proof verification (use a relayer or freshly funded keypair for full privacy of the transaction payer)
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:27:00.938Z
Learning: Applies to zk-id/**/*.circom : Circuit must verify nullifier equals Poseidon(verification_id, credentialPrivateKey)
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:27:00.938Z
Learning: Applies to zk-id/**/*.circom : ZK circuit must verify 26-level Merkle proof of credential account inclusion
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/anchor/README.md:0-0
Timestamp: 2026-01-10T19:25:03.366Z
Learning: Each operation (create, update, close, reinit, burn) is an independent Anchor project with its own workspace, program, and tests
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/src/**/*.rs : Verify current state matches on-chain data before executing close, update, or burn operations
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/native/README.md:0-0
Timestamp: 2026-01-10T19:25:12.548Z
Learning: Applies to basic-operations/native/**/{src,programs}/**/*.rs : Native Solana programs must implement five core operations: create (initialize compressed account), update (modify data), close (reclaim rent), reinit (reinitialize closed account), and burn (permanently destroy)
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2026-01-12T14:27:56.316Z
Learning: Applies to programs/compressed-token/program/docs/ctoken/{CREATE,CLOSE,TRANSFER,TRANSFER_CHECKED,APPROVE,REVOKE,MINT_TO,MINT_TO_CHECKED,BURN,BURN_CHECKED,FREEZE_ACCOUNT,THAW_ACCOUNT}.md : CToken account operations documentation should be organized in a ctoken/ subdirectory with files for account creation, closure, transfers, approval delegation, minting, burning, and freeze/thaw operations
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: All basic-operations programs should demonstrate create, update, close, reinit, and burn operations
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.md : All documentation for accounts, operations, and concepts must reference corresponding markdown files (TREE_ACCOUNT.md, QUEUE_ACCOUNT.md, etc.) and source file locations
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2026-01-12T14:27:56.316Z
Learning: Applies to programs/compressed-token/program/docs/compressed_token/{TRANSFER2,MINT_ACTION,FREEZE,THAW,CREATE_TOKEN_POOL,ADD_TOKEN_POOL}.md : Compressed token operations documentation should be organized in a compressed_token/ subdirectory with separate files for TRANSFER2.md (batch transfer with compress/decompress), MINT_ACTION.md (mint operations), FREEZE.md (freeze operations), THAW.md (thaw operations), CREATE_TOKEN_POOL.md (initial token pool creation), and ADD_TOKEN_POOL.md (additional token pools)
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/burn/src/**/*.rs : Burn operations must permanently delete accounts via `LightAccount::new_burn()` so addresses cannot be reused
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/close/src/**/*.rs : Close operations must preserve the account address for potential reinitialization via `LightAccount::new_close()`
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-07T03:17:28.803Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/README.md : Document program instructions and their parameters (instruction index, instruction name, and builder pattern usage) in README.md
📚 Learning: 2026-01-10T19:26:21.240Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/src/**/*.rs : Verify current state matches on-chain data before executing close, update, or burn operations

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:12.548Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/native/README.md:0-0
Timestamp: 2026-01-10T19:25:12.548Z
Learning: Applies to basic-operations/native/**/{src,programs}/**/*.rs : Native Solana programs must implement five core operations: create (initialize compressed account), update (modify data), close (reclaim rent), reinit (reinitialize closed account), and burn (permanently destroy)

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:21.661Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: counter/anchor/README.md:0-0
Timestamp: 2026-01-10T19:25:21.661Z
Learning: Applies to counter/anchor/**/*.test.ts : Demonstrate client-side interaction with compressed accounts using `lightprotocol/stateless.js` and `lightprotocol/zk-compression-cli` libraries in TypeScript tests

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:26:31.226Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: counter/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:31.226Z
Learning: Applies to counter/**/{anchor,native,pinocchio}/src/**/*.rs : Use LightAccount::new_init() for counter account creation, new_mut() for state updates, and new_close() for account deletion

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:03.366Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/anchor/README.md:0-0
Timestamp: 2026-01-10T19:25:03.366Z
Learning: Applies to basic-operations/anchor/**/*.test.ts : TypeScript tests must demonstrate client-side interaction with compressed accounts using 'lightprotocol/stateless.js'

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:26:21.240Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/reinit/src/**/*.rs : Reinitialize closed accounts using `LightAccount::new_empty()` with proof that the address is currently empty

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:26:21.240Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/anchor/**/src/**/*.rs : Use Poseidon hashing via `light_sdk::account::LightAccount` in Anchor framework implementations

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:26:21.240Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/burn/src/**/*.rs : Burn operations must permanently delete accounts via `LightAccount::new_burn()` so addresses cannot be reused

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:26:21.240Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/close/src/**/*.rs : Close operations must preserve the account address for potential reinitialization via `LightAccount::new_close()`

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:26:01.412Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: account-comparison/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:01.412Z
Learning: Applies to account-comparison/programs/**/tests/test_compressed_account.rs : Include Light Protocol tests in test_compressed_account.rs to verify compressed account operations using LightAccount primitives

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:43.342Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: This is a minimal example for verifying zk inclusion proofs and not a full zk identity protocol or production-ready implementation - refer to Iden3 or Semaphore for production identity protocols

Applied to files:

  • README.md
📚 Learning: 2025-11-24T17:54:42.219Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/system/README.md:0-0
Timestamp: 2025-11-24T17:54:42.219Z
Learning: Light Protocol system program is usable for ZK Compression on Solana

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:43.342Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.rs : Verify zero-knowledge proofs of credential ownership using the `zk_verify_credential` instruction with Groth16 verification and create encrypted event accounts to store verification results on-chain

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:43.342Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.js : Use SnarkJS library for generating and verifying zero-knowledge proofs in JavaScript

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:43.342Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.circom : Define zero-knowledge circuits in Circom language files using the compressed_account_merkle_proof circuit pattern

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:25:43.342Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/README.md:0-0
Timestamp: 2026-01-10T19:25:43.342Z
Learning: Applies to zk-id/**/*.rs : Ensure credential verification is private by not exposing the credential during zk proof verification (use a relayer or freshly funded keypair for full privacy of the transaction payer)

Applied to files:

  • README.md
📚 Learning: 2025-11-24T17:54:38.537Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/README.md:0-0
Timestamp: 2025-11-24T17:54:38.537Z
Learning: Implement compressed token program interfaces for third-party token creation and usage on Solana using ZK Compression

Applied to files:

  • README.md
📚 Learning: 2025-11-24T17:54:33.614Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/anchor/README.md:0-0
Timestamp: 2025-11-24T17:54:33.614Z
Learning: Implement the Compressed Token Program interface for creating and using compressed tokens on Solana with ZK Compression

Applied to files:

  • README.md
📚 Learning: 2026-01-10T19:27:00.938Z
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk-id/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:27:00.938Z
Learning: Applies to zk-id/**/*.circom : ZK circuit must verify 26-level Merkle proof of credential account inclusion

Applied to files:

  • README.md
🔇 Additional comments (2)
README.md (2)

52-52: LGTM! Path correctly updated for zk/ folder reorganization.

The path update from ./zk-id to ./zk/zk-id correctly reflects the repository reorganization described in the PR objectives, where the zk-id example was moved into the zk/ folder for better organization.


16-16: No change needed—create-nullifier is intentionally Anchor-only.

The CLAUDE.md documentation explicitly defines five core basic operations (create, update, close, reinit, burn) that require both Anchor and Native implementations for platform parity. Create-nullifier is a supplementary feature that exists only in Anchor, and the README correctly reflects this distinction by linking it separately. The "pattern inconsistency" you identified is actually intentional architecture.

Likely an incorrect or invalid review comment.

Comment on lines +21 to +22
- **close** - Clear account data and preserve its address
- [Anchor](./basic-operations/anchor/close) | [Native](./basic-operations/native/programs/close)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Enhance the close operation description to mention rent reclamation.

The description should highlight that close operations reclaim rent, which is a key benefit of this operation compared to burn.

Based on learnings, close operations preserve the account address for potential reinitialization while reclaiming rent.

📝 Suggested enhancement
-- **close** - Clear account data and preserve its address
+- **close** - Reclaim rent and preserve the account address for reinitialization
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **close** - Clear account data and preserve its address
- [Anchor](./basic-operations/anchor/close) | [Native](./basic-operations/native/programs/close)
- **close** - Reclaim rent and preserve the account address for reinitialization
- [Anchor](./basic-operations/anchor/close) | [Native](./basic-operations/native/programs/close)
🤖 Prompt for AI Agents
In @README.md around lines 21 - 22, Update the README entry for the "close"
operation to state that it not only clears account data and preserves the
account address but also reclaims the account's rent (freeing lamports) —
highlight that this distinguishes close from burn and that the preserved address
can be reused for reinitialization; change the line starting with "**close** -
Clear account data and preserve its address" to include "reclaims rent" and a
short contrast to "burn" while leaving the Anchor and Native links intact.

Comment on lines +25 to +26
- **burn** - Permanently delete a compressed account
- [Anchor](./basic-operations/anchor/burn) | [Native](./basic-operations/native/programs/burn)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Clarify that burn prevents address reuse.

The description should explicitly state that burned accounts cannot have their addresses reused, which is the critical distinction from close operations.

Based on learnings, burn operations permanently delete accounts so addresses cannot be reused, unlike close operations which preserve addresses for reinitialization.

📝 Suggested enhancement
-- **burn** - Permanently delete a compressed account
+- **burn** - Permanently delete a compressed account (address cannot be reused)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **burn** - Permanently delete a compressed account
- [Anchor](./basic-operations/anchor/burn) | [Native](./basic-operations/native/programs/burn)
- **burn** - Permanently delete a compressed account (address cannot be reused)
- [Anchor](./basic-operations/anchor/burn) | [Native](./basic-operations/native/programs/burn)
🤖 Prompt for AI Agents
In @README.md around lines 25 - 26, Update the README entry for the "burn"
operation to explicitly state that burning permanently deletes a compressed
account and prevents the account address from being reused; reference the "burn"
operation name (and its links "Anchor" and "Native") and add a short contrasting
clause noting that this differs from "close" operations which allow address
reinitialization.

@tilo-14 tilo-14 force-pushed the feat/add-nullifier branch 4 times, most recently from 9f9450b to 034f8aa Compare January 12, 2026 23:52
@tilo-14 tilo-14 force-pushed the feat/add-nullifier branch from 034f8aa to 04247d5 Compare January 13, 2026 00:14
@tilo-14 tilo-14 force-pushed the feat/add-nullifier branch 2 times, most recently from 237112c to ae715e7 Compare January 13, 2026 00:44
- Move zk-id from root to zk/ folder
- Add zk-nullifier: single and batch (4x) nullifier creation with Groth16
- Add zk-merkle-proof: merkle proof verification with compressed accounts
- Update CI to test zk/zk-id, zk/zk-nullifier, zk/zk-merkle-proof
@tilo-14 tilo-14 force-pushed the feat/add-nullifier branch from ae715e7 to 8bab0d0 Compare January 13, 2026 01:14
- zk-nullifier: Remove unused blake3 dependency
- zk-id: Update merkle proof circuit import path
- zk-merkle-proof: Add Anchor.toml, fix circuit import
@tilo-14 tilo-14 force-pushed the feat/add-nullifier branch from 881199e to edd47a2 Compare January 13, 2026 01:49
… pattern

- verifying_key.rs → nullifier_1.rs
- batch_verifying_key.rs → nullifier_batch_4.rs
component hasher[levels];

component indexBits = Num2Bits(levels);
component indexBits = Num2Bits_strict(levels);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why strict?

Comment on lines 16 to 21
// Range check: leafIndex < 2^levels
component indexRange = LessThan(levels + 1);
indexRange.in[0] <== leafIndex;
indexRange.in[1] <== 1 << levels;
indexRange.out === 1;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not required

Comment on lines 14 to 17
nullifiers[i] = Nullifier();
nullifiers[i].verification_id <== verification_id;
nullifiers[i].nullifier <== nullifier[i];
nullifiers[i].secret <== secret[i];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import and use template Nullifier() {

tilo-14 added 2 commits January 13, 2026 02:28
zk-nullifier:
- Split nullifier.circom into template + nullifier_main.circom
- Fixes multiple main components error when batchnullifier includes nullifier

zk-merkle-proof & zk-id:
- Replace Num2Bits_strict(levels) with Num2Bits(levels)
- Remove redundant LessThan range check (Num2Bits already constrains)
- Remove unused comparators.circom import
… pattern

- nullifier.circom: template-only library (Nullifier + BatchNullifier)
- nullifier_1.circom: entry point for single nullifier
- nullifier_4.circom: entry point for batch of 4 nullifiers
- Update setup.sh to compile new circuit files

Following circomlib best practice: templates in library files, minimal entry points.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants