Skip to content

zuldotso/zul-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@zuldotso/zul-sdk

Client SDK for Zul — a Solana-RPC-compatible privacy Layer 2. One isomorphic (browser + Node) package over three surfaces:

  • chainconnect(), the field/poseidon/merkle primitives, program ids
  • bridge — SOL (Solana devnet L1) ↔ ZUL (L2): depositIx, withdrawIx, claimIxs, getWithdrawalProof, findBatchForRoot
  • shielded — the privacy pool: buildShield / buildTransfer / buildUnshield (Groth16), the scanning wallet syncWallet, deriveSpendingKey, and note selection
npm i @zuldotso/zul-sdk

Bridge — deposit SOL → ZUL

import { Connection, Transaction } from "@solana/web3.js";
import { depositIx, DEVNET_RPC } from "@zuldotso/zul-sdk";

const conn = new Connection(DEVNET_RPC, "confirmed");
const tx = new Transaction().add(depositIx(wallet.publicKey, 20_000_000n, wallet.publicKey));
// sign with the wallet + send to devnet; the bridge watcher credits the L2.

Shielded — shield, then unshield privately

import { Connection } from "@solana/web3.js";
import {
  ZUL_RPC, NATIVE_ASSET_ID, deriveSpendingKey, ownerPk, encryptionKeypair,
  buildShield, buildUnshield, syncWallet, selectForUnshield, poolIx,
  unshieldArtifacts,
} from "@zuldotso/zul-sdk";

const conn = new Connection(ZUL_RPC, "confirmed");
const s = deriveSpendingKey(await wallet.signMessage(MSG)); // recoverable identity
const enc = encryptionKeypair(s);

// shield 5 ZUL
const sh = await buildShield({
  asset: { kind: "native" }, assetId: NATIVE_ASSET_ID, amount: 5_000_000_000n,
  recipientPk: await ownerPk(s), recipientEncPk: enc.publicKey,
});
// submit poolIx(wallet.publicKey, sh.data) on the L2…

// later: scan + unshield 3 ZUL to a public address
const w = await syncWallet(conn, s);
const note = selectForUnshield(w.store.unspent(NATIVE_ASSET_ID), 3_000_000_000n);
const un = await buildUnshield({
  spendingKey: s, asset: { kind: "native" }, assetId: NATIVE_ASSET_ID,
  input: note!, amount: 3_000_000_000n, recipient: recipientPubkey.toBytes(),
  changePk: await ownerPk(s), changeEncPk: enc.publicKey,
  tree: w.tree, artifacts: unshieldArtifacts,
});

Notes

  • Proving fetches the hosted artifacts (transferArtifacts / unshieldArtifacts URLs) in the browser, or pass { wasm, zkey } as Uint8Array in Node.
  • Browser bundlers must stub Node built-ins for snarkjs (fs/os/cryptofalse) and, if importing TS sources directly, map .js.ts. See zulweb/next.config.ts for a Next.js example.
  • The shielded wallet keeps no statesyncWallet re-derives every owned note from chain history each call (the pool account stores only the tree frontier).
  • Defaults target the live devnet deployment (rpc.zul.so, settlement 2hwZWD…); pass your own Connection to point elsewhere.

About

Client SDK for Zul

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors