ZUL://DOCSPRIVACY LAYER 2 — SETTLED ON SOLANA
INDEX
INTERFACES — /docs/sdk

TypeScript SDK

The TypeScript SDK lives in the monorepo's sdk/ workspace. It is a thin layer over a standard Solana Connection pointed at the L2 RPC, plus the two clients that need real protocol knowledge: the bridge and the shielded pool.

DISTRIBUTION

The SDK is a workspace package, consumed by the explorer and bridge UI inside the repository. It is not published to a public registry — build it from source via the monorepo's pnpm workspace.

Plain chain access

For everything non-private, you don't need the SDK at all — any Solana client library works against the RPC (see Run it locally). The SDK's value begins where standard tooling stops.

Bridge client

  • deposit — builds the L1 vault transfer with the L2 recipient memo.
  • withdraw — builds the L2 burn/lock transaction.
  • claim — fetches the SMT inclusion proof from the node and submits the L1 claim after the window. See Withdrawals & claims.

Shielded client

  • Note store — an encrypted local store of your notes and spending keys.
  • Scanner — walks blocks, trial-decrypts note ciphertexts (X25519 + XChaCha20-Poly1305), and ingests the ones that open.
  • Prover — generates Groth16 proofs in the browser via snarkjs WASM.
  • Builders — assemble shield / transfer / unshield instructions for the pool builtin.
SHAPE (TYPESCRIPT)
const zul = new Connection(ZUL_RPC, "confirmed");

// bridge
await bridge.deposit({ from: l1Wallet, lamports, l2Recipient });
await bridge.withdraw({ owner: l2Wallet, lamports });
await bridge.claim({ withdrawal });          // after the window

// shielded
await pool.scan(zul);                        // find incoming notes
await pool.shield({ asset, amount });
await pool.transfer({ to: recipientPk, asset, amount }); // proof in-browser
await pool.unshield({ to: publicAddress, asset, amount });

Encoding discipline

Pool instructions are binary-encoded and must match the node's Rust types exactly. The repository pins this with a cross-test that byte-compares the SDK's encoding against the Rust serialization — the boundary most likely to drift silently is the one most heavily tested.