SDK Reference
Complete function signatures, types, and constants for @zera-labs/sdk
All cryptographic operations use the BN254 scalar field (254-bit prime). Commitments and nullifiers are field elements. Proofs are Groth16 over BN254, formatted as Solana-compatible byte arrays.
Crypto Primitives
// Poseidon hashing — circomlibjs-compatible, BN254 X5getPoseidon(): Promise<Poseidon>poseidonHash(inputs: bigint[]): bigintposeidonHash2(left: bigint, right: bigint): bigint// Field ↔ bytes conversionfieldToBytes32BE(value: bigint): Uint8Arraybytes32BEToField(bytes: Uint8Array): bigintbigintToBytes32BE(value: bigint): Uint8Arraybytes32BEToBigint(bytes: Uint8Array): bigintfieldToSolanaBytes(value: bigint): Uint8Array// Keccak-256 (voucher system)computeKeccakCommitment(secret: string): stringcomputeRecipientHash(pubkey: PublicKey, salt: string): stringgenerateRandomHex(): string// Proof formattingformatProofForSolana(proof: SnarkjsProof): SolanaProofformatPublicInputsForSolana(signals: string[]): bigint[]
Note Types & Management
interface Note {amount: bigint // raw token amount (e.g. 10_000_000n = $10 USDC)asset: bigint // mint address → BN254 field elementsecret: bigint // random 254-bit secret (never leaves client)blinding: bigint // random 254-bit blinding factormemo: bigint[] // 4 arbitrary 32-byte field elements}interface SolanaProof {proofA: Uint8Array // 64 bytes (2 × G1 points)proofB: Uint8Array // 128 bytes (2 × G2 points)proofC: Uint8Array // 64 bytes (2 × G1 points)}createNote(amount: bigint, asset: PublicKey, memo?: bigint[]): NotecomputeCommitment(note: Note): bigint// = Poseidon(amount, secret, blinding, asset, memo[0], memo[1], memo[2], memo[3])computeNullifier(secret: bigint, commitment: bigint): bigint// = Poseidon(secret, commitment)hashPubkeyToField(pubkeyBytes: Uint8Array): bigint
Merkle Tree
class MerkleTree {static create(height?: number): Promise<MerkleTree>// Default: height=24, capacity=16,777,216 leaves// Node hash: Poseidon(left, right)// Empty leaf: 0ninsert(commitment: bigint): number // → leaf indexgetProof(leafIndex: number): {pathElements: bigint[] // sibling hashes (24 elements)pathIndices: number[] // 0=left, 1=right (24 elements)}getRoot(): bigint // current Merkle rootgetLeaf(index: number): bigintget nextIndex(): number // next available leaf slot}
Proof Generators
Four circuit types, all producing Groth16 proofs via snarkjs groth16.fullProve():
// Deposit — prove correct commitment formationgenerateDepositProof(note: Note,wasmPath: string,zkeyPath: string): Promise<{proof: SolanaProof,commitment: bigint,publicSignals: string[]}>// Withdraw — prove Merkle inclusion + nullifier + recipient bindinggenerateWithdrawProof(note: Note,leafIndex: number,tree: MerkleTree,recipientHash: bigint,wasmPath: string,zkeyPath: string): Promise<{proof: SolanaProof,nullifierHash: bigint,publicSignals: string[]}>// Transfer — 1-input 2-output with value conservationgenerateTransferProof(inputNote: Note,inputLeafIndex: number,tree: MerkleTree,outputNote1: Note,outputNote2: Note,wasmPath: string,zkeyPath: string): Promise<{proof: SolanaProof,nullifierHash: bigint,outputCommitment1: bigint,outputCommitment2: bigint,publicSignals: string[]}>// Relayed Withdraw — gasless via operator relay// Same as withdraw but includes relay fee parameters
Transaction Builders
// All builders return unsigned Solana Transactions// Automatically derive PDAs (pool config, vault, Merkle tree, nullifiers)buildDepositTransaction(params: DepositParams): Promise<Transaction>buildWithdrawTransaction(params: WithdrawParams): Promise<Transaction>buildTransferTransaction(params: TransferParams): Promise<Transaction>
PDA Derivation
derivePoolConfig(mint: PublicKey, programId?: PublicKey): PublicKeyderiveMerkleTree(mint: PublicKey, programId?: PublicKey): PublicKeyderiveVault(mint: PublicKey, programId?: PublicKey): PublicKeyderiveFeeVault(mint: PublicKey, programId?: PublicKey): PublicKeyderiveNullifier(nullifierHash: bigint, programId?: PublicKey): PublicKeygetAssociatedTokenAddress(mint: PublicKey, owner: PublicKey): PublicKey
High-Level Client & Storage
// High-level wrapperclass ZeraClient {static create(config: ZeraClientConfig): Promise<ZeraClient>syncTree(): Promise<void>deposit(amount: bigint, mint: PublicKey): Promise<{ tx: Transaction, note: Note }>withdraw(note: Note, recipient: PublicKey): Promise<{ tx: Transaction }>transfer(inputNote: Note, splitAmounts: [bigint, bigint]):Promise<{ tx: Transaction, notes: [Note, Note] }>}// On-chain state fetchingclass TreeStateClient {constructor(config: { rpcUrl: string, cacheEndpoint?: string })fetchPoolState(): Promise<PoolState>fetchCachedState(): Promise<CachedState>fetchAllLeaves(forceRefresh?: boolean): Promise<bigint[]>}// Note persistenceinterface NoteStore { save, load, delete, list }class MemoryNoteStore implements NoteStoreclass FileNoteStore implements NoteStore
Constants
TREE_HEIGHT = 24TREE_CAPACITY = 16_777_216BN254_PRIME = 21888242871839275222246405745257275088...617nUSDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"USDC_DECIMALS = 6ZERA_MINT = "8avjtjHAHFqp4g2RR9ALAGBpSTqKPZR8nRbzSTwZERA"NATIVE_SOL_MINT = "So11111111111111111111111111111111111111112"SHIELDED_POOL_PROGRAM_ID = "B83jSQx1CT1hPRBupinaJaEkCjrfeo6Ktncu31q3ZNeX"PRIVATE_CASH_PROGRAM_ID = "ESQxpH9XkBQT6EVeWwAzTZD1e9NrLMrY8RPQ9SidYsgF"FEE_BASIS_POINTS = 10 // 0.1%MIN_FEE_AMOUNT = 1n
