feat(sdk): add zero-knowledge commitment and proof verification (#173) - #298
Conversation
…nsa#173) Merchants require privacy for transaction volumes: the indexer must be able to verify a state transition without ever storing the plaintext. Adds the SDK-side commitment scheme, a pluggable verifier, and the indexer ingestion path: - packages/sdk: createCommitment()/createOpeningProof()/verifyOpeningProof() — a binding and hiding SHA-256 commitment (blinding || canonical payload), with the ZkVerifier interface as the seam a real zk-SNARK circuit can implement later. Exported as @accensa/sdk/zk-proof. - zk_commitments table (migration 005 + ensureZkCommitmentsSchema): records only the commitment and a one-way hash of the canonical payload — never the plaintext — scoped per merchant. - POST /api/sync/proofs: verifies the opening proof entirely in memory, then persists the commitment; session-authenticated, idempotent per merchant. Closes accensa#173
|
@lorenzo-romano is attempting to deploy a commit to the ACCENSA Team on Vercel. A member of the Team first needs to authorize it. |
|
@lorenzo-romano Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
MergeKeeper review Scope: in scope for linked issue Successfully implements zero-knowledge commitment and opening proof verification for the indexer and SDK according to issue #173. Reviewed commit: |
|
MergeKeeper merge status Status: blocked Reason: One or more required CI checks failed. Failing checks:
Next steps:
|
Summary
Implements #173 — zero-knowledge proof verification for off-chain privacy. Merchants require privacy for transaction volumes: the indexer must be able to accept and verify a state transition without ever storing the plaintext.
SDK (
@accensa/sdk/zk-proof)createCommitment(payload)— binding and hiding commitment:SHA-256(blinding || canonical_json(payload)), with fresh random blinding per commitment (the same payload commits differently each time).createOpeningProof(payload, blinding)/verifyOpeningProof(commitment, proof)— the prover opens a commitment; the verifier recomputes and compares in constant time.ZkVerifierinterface — the pluggable seam the indexer verifies through; a future migration to a real zk-SNARK circuit (e.g. SnarkJS groth16) implements the same interface without changing the sync API.canonicalJson— deterministic key-sorted serialization so the same logical payload commits to the same bytes on every platform.Indexer
POST /api/sync/proofs— the privacy-preserving ingestion path: verifies the opening proof entirely in memory, then persists only the commitment and a one-way SHA-256 of the canonical payload. Session-authenticated (the signed-in merchant can only submit for themselves), idempotent per merchant (ON CONFLICT DO NOTHING).zk_commitmentstable (migration 005 +ensureZkCommitmentsSchema) — records the commitment + payload hash, never the plaintext, so a leaked table exposes nothing about the underlying data.Tests
packages/sdk/src/zk-proof.test.ts— binding, hiding, canonical-JSON stability, tampered payload/blinding rejection, scheme/malformed-input rejection, and the SHA-256 NIST test vector.Test Plan
Closes #173