New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

ciphera-sdk

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ciphera-sdk

Zero-Knowledge KYC for Algorand — generate ZK proofs in the browser, verify KYC on-chain

latest
Source
npmnpm
Version
0.1.2
Version published
Maintainers
1
Created
Source
Ciphera Logo

Zero-Knowledge KYC for Algorand — TypeScript/JavaScript SDK

npm version License: MIT TypeScript Algorand

Generate ZK proofs in the browser. Verify KYC on-chain. Zero personal data exposed.

Install

npm install ciphera-sdk

What is Ciphera?

Ciphera is a privacy-preserving zero-knowledge KYC system on Algorand. Users prove they are verified Indian adults without exposing any personal information. ZK proofs are generated entirely in the browser using snarkjs — private inputs (Aadhaar hash, wallet secret) are computed locally and then destroyed.

How it works

StepActorAction
1UserUploads Aadhaar XML → SDK generates Groth16 ZK proof in-browser
2IssuerCalls verifyProof() → registers nullifier on Algorand
3dAppCalls verifyKYC() → checks on-chain registry

Quick Start

🌐 Browser — Generate ZK Proof

import { CipheraProver } from 'ciphera-sdk';

const prover = new CipheraProver({
  wasmUrl: 'https://your-cdn.com/kyc.wasm',
  zkeyUrl: 'https://your-cdn.com/kyc_final.zkey',
});

const result = await prover.generateProof({
  aadhaarHash: '123456789012345...',  // SHA-256 of Aadhaar XML as BN254 field element
  walletSecret: '987654321098765...',  // Random secret tied to user's wallet
  appId: 756272073,                    // NullifierRegistry app ID
  dobYear: 2000,                       // User's birth year (age >= 18 enforced by circuit)
});

console.log(result.nullifierHex);   // '3b1f8a2c...' — 32-byte hex for on-chain use
console.log(result.proveTimeMs);    // e.g. 4200ms
// → Send result.proof + result.publicSignals to your issuer backend

🖥️ Issuer Backend — Verify Proof & Register On-Chain

import { verifyProof, CipheraClient } from 'ciphera-sdk';
import verificationKey from './verification_key.json' assert { type: 'json' };

// 1. Verify the ZK proof
const verification = await verifyProof(
  verificationKey,
  proof,
  publicSignals,
  756272073  // Expected appId (prevents cross-app replay attacks)
);

if (!verification.valid) throw new Error(verification.error);

// 2. Register nullifier on Algorand Testnet
const client = new CipheraClient();
const txId = await client.registerNullifier(
  process.env.ISSUER_MNEMONIC!,
  verification.nullifierHex!,
  userWalletAddress
);

console.log('Registered:', CipheraClient.explorerTxUrl(txId));
// → https://allo.info/tx/<txid>

🏗️ dApp — Gate Access by KYC Status

import { CipheraClient } from 'ciphera-sdk';

const client = new CipheraClient();

// Check registry-level KYC
const status = await client.verifyKYC(userWalletAddress);
if (status.isVerified) {
  // Grant access
}

// Or check a specific nullifier directly
const registered = await client.isNullifierRegistered(nullifierHex);

API Reference

CipheraProver

new CipheraProver({ wasmUrl, zkeyUrl, smtDepth? })
MethodReturnsDescription
generateProof(inputs)Promise<KYCProofResult>Generate Groth16 ZK proof entirely in-browser

ProveInputs parameters:

ParameterTypeRequiredDescription
aadhaarHashstring | bigintSHA-256 of Aadhaar XML as BN254 field element
walletSecretstring | bigintRandom secret binding proof to wallet
appIdnumber | string | bigintNullifierRegistry app ID
dobYearnumber | stringYear of birth (circuit enforces age ≥ 18)
currentYearnumber | stringDefaults to current year
merkleSiblingsstring[]SMT proof path (20 elements, defaults to zeros)
merklePosstring[]SMT path bits (20 elements, defaults to zeros)

CipheraClient

new CipheraClient(config?)
MethodReturnsDescription
verifyKYC(walletAddress?)Promise<KYCStatus>Check registry KYC status
isNullifierRegistered(hex)Promise<boolean>Direct nullifier box check
registerNullifier(mnemonic, hex, wallet)Promise<string>Register on-chain (issuer only)
getCredentialAsaId()numberKYCRED ASA ID
CipheraClient.explorerTxUrl(txId)stringAllo.info TX explorer URL
CipheraClient.explorerAppUrl(appId)stringAllo.info app explorer URL

CipheraConfig options:

OptionTypeDefaultDescription
algodServerstringAlgorand Testnet (AlgoNode)Custom Algod endpoint
algodTokenstring""Algod API token
contractIdsPartial<ContractIds>Testnet defaultsOverride deployed contract IDs
wasmUrlstringPath/URL to kyc.wasm
zkeyUrlstringPath/URL to kyc_final.zkey

verifyProof(vk, proof, signals, appId?)

Verify a Groth16 ZK proof off-chain.

ParameterTypeDescription
verificationKeyVerificationKeyGroth16 verification key (from verification_key.json)
proofGroth16ProofProof object from the browser SDK
publicSignalsstring[]Public signals array
expectedAppIdnumber | string(Optional) Guard against cross-app attacks

Returns: { valid, nullifierHex?, publicSignals?, error? }

Crypto Utilities

import { mimcHash, computeNullifier, computeNullifierHex } from 'ciphera-sdk';

// Compute nullifier directly (without generating a full proof)
const hex = computeNullifierHex(aadhaarHash, appId, walletSecret);

// Low-level MiMC hash (Miyaguchi-Preneel, BN254 field)
const hash = mimcHash([field1, field2]);

Types

interface KYCProofResult {
  proof: Groth16Proof;
  publicSignals: KYCPublicSignals;
  nullifierHex: string;     // 32-byte hex for on-chain use
  proveTimeMs: number;      // Proof generation time in milliseconds
}

interface KYCStatus {
  isVerified: boolean;
  totalRegistered?: number;
  nullifier?: string;
  appId: number;
}

interface KYCPublicSignals {
  nullifier: string;        // BN254 field element (decimal string)
  merkleRoot: string;       // SMT root
  appId: string;            // Algorand app ID
  isIndian: "1";            // Circuit-enforced
  isAdult: "1";             // Circuit-enforced (age >= 18)
  isKYCVerified: "1";       // Circuit-enforced
}

Deployed Contracts (Algorand Testnet)

ContractApp IDExplorer
NullifierRegistry756272073allo.info ↗
SMTRegistry756272075allo.info ↗
KYCBoxStorage756272299allo.info ↗
CredentialManager756281076allo.info ↗
KYCRED ASA756281102allo.info ↗

GitHub · npm · PyPI · Issues

License

MIT © Aditya Pandey

Keywords

algorand

FAQs

Package last updated on 14 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts