TypeScript ZKP SDK for privacy-preserving token operations — deposit, transfer, and withdraw via UTXO model and zk-SNARK proofs.
- Zero-Knowledge Proofs — Groth16 zk-SNARK via Go WASM for on-chain privacy
- UTXO Model — Poseidon2 commitments, Merkle trees, nullifiers
- Multi-Environment — Browser, Node.js, Electron/Tauri
- Modular — Factory pattern with event-driven modules, compose what you need
- 4 Storage Adapters — Memory, IndexedDB, File, KV
pnpm add @ocash/sdkimport { createSdk, SEPOLIA_TESTNET } from '@ocash/sdk';
const sdk = createSdk({
chains: [SEPOLIA_TESTNET],
onEvent: console.log,
});
await sdk.core.ready();
await sdk.wallet.open({ seed: 'your-secret-seed-phrase' });
await sdk.sync.syncOnce();
const balance = await sdk.wallet.getBalance({
chainId: SEPOLIA_TESTNET.chainId,
assetId: SEPOLIA_TESTNET.tokens![0]!.id,
});Pre-configured chain presets exported from @ocash/sdk:
| Preset | Chain | Chain ID |
|---|---|---|
ETH_MAINNET |
Ethereum | 1 |
BSC_MAINNET |
BNB Chain | 56 |
BASE_MAINNET |
Base | 8453 |
SEPOLIA_TESTNET |
Sepolia | 11155111 |
BSC_TESTNET |
BSC Testnet | 97 |
Also available: MAINNET_CHAINS and TESTNET_CHAINS arrays.
| Import | Environment | Extra |
|---|---|---|
@ocash/sdk |
Universal | MemoryStore |
@ocash/sdk/browser |
Browser | + IndexedDbStore |
@ocash/sdk/node |
Node.js | + FileStore |
sdk.core — WASM & circuit initialization
sdk.keys — BabyJubjub key derivation
sdk.crypto — Commitments, nullifiers, memo encryption
sdk.assets — Chain / token / relayer configuration
sdk.storage — Persistence adapter
sdk.wallet — Session, UTXOs, balance
sdk.sync — Memo / nullifier / Merkle sync
sdk.merkle — Merkle proofs & membership witnesses
sdk.planner — Coin selection, fee estimation
sdk.zkp — zk-SNARK proof generation
sdk.tx — Relayer request builder
sdk.ops — End-to-end orchestration
const keyPair = sdk.keys.deriveKeyPair(seed);
const prepared = await sdk.ops.prepareTransfer({
chainId,
assetId,
amount,
to: recipientAddress,
ownerKeyPair: keyPair,
publicClient,
});
const result = await sdk.ops.submitRelayerRequest({ prepared, publicClient });
const txHash = await result.waitRelayerTxHash;const prepared = await sdk.ops.prepareWithdraw({
chainId,
assetId,
amount,
recipient: evmAddress,
ownerKeyPair: keyPair,
publicClient,
});
const result = await sdk.ops.submitRelayerRequest({ prepared, publicClient });const ownerPub = sdk.keys.getPublicKeyBySeed(seed);
const prepared = await sdk.ops.prepareDeposit({
chainId,
assetId,
amount,
ownerPublicKey: ownerPub,
account: walletAddress,
publicClient,
});
if (prepared.approveNeeded) {
await walletClient.writeContract(prepared.approveRequest);
}
await walletClient.writeContract(prepared.depositRequest);createSdk(config) → Initialize
sdk.core.ready() → Load WASM & circuits
sdk.wallet.open({ seed }) → Derive keys, open storage
sdk.sync.start() → Background sync (or syncOnce)
sdk.ops.prepareTransfer() → Plan, prove, build request
sdk.wallet.close() → Release keys, flush storage
- Node.js >= 20.19.0
- Browser: WebAssembly + crypto.getRandomValues + fetch
pnpm install
pnpm run build
pnpm run test # Run tests
pnpm run dev # Browser demo
pnpm run demo:node # Node.js demo
pnpm run docs:dev # Documentation dev server