ZK Privacy SDK
This SDK lets you add private token balances to EVM applications. Balances are encrypted on-chain -- only the owner can see amounts and transfer history. Transfers are verified by zero-knowledge proofs, so the chain can confirm validity without seeing the values.
Built on viem, the SDK is modular -- pick only the capabilities you need.
Building a mobile app? See React Native — same Solver / Prover contracts, mobile-native runtime via UniFFI + Expo Modules.
Three capability tiers
| Tier | What you can do | What you need |
|---|---|---|
| EVM | Send tokens to encrypted addresses, register, auto-encrypt | Wallet client |
| Decrypt | Read + decrypt balances and history | + Runtime (decryption) + read-only account |
| Full | All of the above + encrypted transfers | + Runtime (decryption + proving) + full account |
You create one runtime that bundles the services you need: a decryption service for reading balances, and optionally a proving service for generating ZK proofs when sending transfers. Everything runs client-side -- no private data leaves your machine.
Why tiers matter
The decryption and proving services are WASM modules that lazy-load when first used. Picking the minimal tier for your use case keeps your app's bundle small:
- EVM tier -- no WASM at all, pure RPC calls
- Decrypt tier -- loads the decryption WASM (~small)
- Full tier -- loads both decryption and proving WASM (~larger, but lazy-loaded on first use so it doesn't block your app startup)
If you're building a portfolio viewer, use Decrypt. If you're building an onboarding page, use EVM. Only load the prover when you actually need to send encrypted transfers.
Each tier maps to a client factory:
import { createEvmClient, createDecryptClient, createFullClient } from '@cardinal-cryptography/sdk'
Supported networks
The SDK ships with deployment defaults baked in — token addresses, bundler URL, paymaster URL, and the SharedAccount address all resolve automatically when you pass a supported viem chain. See Live Deployments for the canonical list of networks, chain IDs, and addresses.
Quick example
import { createRuntime, createFullClient } from '@cardinal-cryptography/sdk'
import { createPublicClient, http } from 'viem'
import { baseSepolia } from 'viem/chains'
const runtime = await createRuntime()
const account = runtime.createAccountFromMnemonic('your mnemonic here')
const client = await createFullClient({
client: createPublicClient({ chain: baseSepolia, transport: http() }),
zkpAccount: account,
})
// Check your encrypted balance
const balance = await client.getDecryptedBalance({ token: 'zkUSD' })
// Send a private transfer
await client.sendEncryptedTransfer({
token: 'zkUSD',
amount: 50n,
to: 'zk1recipientAddress...',
})
Next steps
Getting Started
Set up the SDK and make your first private transfer.
React Native
Mobile-native SDK variant for React Native apps (iOS + Android).
Guides
Step-by-step recipes for common SDK tasks.
Concepts
Architecture, keys, transaction lifecycle.
Reference
Complete API reference for the public SDK surface.
Live Deployments
Networks, chain IDs, and canonical addresses.