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.
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.
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.