Setup & Configuration
Installation
See Installation Guide for npm registry setup, then:
npm install @zk-privacy/eb-sdk @zk-privacy/eb-contracts viem
createClient (recommended)
Factory that creates and initializes the client in one step. Heavy assets load lazily on first use.
import { createClient } from '@zk-privacy/eb-sdk';
const client = await createClient({
chainId: 8453,
relayerUrl: 'https://eb-relayer.zkprivacy.dev',
onProgress: (stage, progress) => console.log(`${stage}: ${progress}%`),
});
EBClient (advanced)
Use when you need a synchronous reference before initialization, or want to control the init lifecycle manually.
import { EBClient } from '@zk-privacy/eb-sdk';
const client = new EBClient({ chainId: 8453 });
await client.initialize();
Configuration
| Field | Type | Description |
|---|---|---|
chainId | number | Chain ID for multi-token mode (8453 = Base) |
chain | Chain | Viem chain (default: Base mainnet) |
rpcUrl | string | RPC endpoint URL (auto-detected) |
contract | Address | Single contract (legacy mode) |
transferCircuit | CircuitSource | Transfer circuit (default: auto) |
unshieldCircuit | CircuitSource | Unshield circuit (default: auto) |
stakeCircuit | CircuitSource | L3 stake circuit (default: auto) |
unstakeCircuit | CircuitSource | L3 unstake circuit (default: auto) |
enableL3 | boolean | Enable L3 operations |
relayerUrl | string | Relayer URL for gasless ops |
onProgress | (stage, progress?) => void | Initialization callback |
onLog | (level, category, message, data?) => void | SDK log callback |
threads | number | Prover threads (default: auto) |
cacheVersion | number | Cache version (default: 1) |
storage | StorageAdapter | Persistent storage (default: IndexedDB in browser, memory in Node) |
lazyLoad | boolean | Skip heavy asset loading on initialize() (default: false) |
onAssetLoading | (asset: 'solver' | 'prover', progress?) => void | Callback when lazy assets start loading |
Client Methods
initialize()
Called automatically by createClient(). Only needed with new EBClient().
await client.initialize();
wallet(config)
Create a connected wallet. See Wallet API.
const wallet = client.wallet({
spendingKey: keys.spendingKey,
account: privateKeyToAccount('0x...'),
// OR
walletClient: metamaskWalletClient,
});
isMultiToken() / getCurrencies()
if (client.isMultiToken()) {
const currencies = client.getCurrencies();
}
isL3Enabled() / hasRelayer()
if (client.isL3Enabled()) { /* L3 stake/unstake available */ }
if (client.hasRelayer()) { /* gasless ops available */ }
destroy()
await client.destroy();
Key Derivation
generateMnemonic()
import { generateMnemonic } from '@zk-privacy/eb-sdk';
const mnemonic = generateMnemonic();
keysFromMnemonic(mnemonic, accountIndex?)
import { keysFromMnemonic } from '@zk-privacy/eb-sdk';
const keys0 = keysFromMnemonic(mnemonic, 0);
const keys1 = keysFromMnemonic(mnemonic, 1);
keysFromSignature(signature, accountIndex?)
import { keysFromSignature } from '@zk-privacy/eb-sdk';
const signature = await walletClient.signMessage({
message: `zkPrivacy spending key for ${address}`,
});
const keys = keysFromSignature(signature, 0);
keysFromSpendingKey(spendingKey)
import { keysFromSpendingKey } from '@zk-privacy/eb-sdk';
const keys = keysFromSpendingKey(0x123n);
Address Encoding
import { bpkToAddress, addressToBpk, isValidAddress } from '@zk-privacy/eb-sdk';
const address = bpkToAddress(keys.BPK);
const bpk = addressToBpk(address);
if (isValidAddress(input)) {
const bpk = addressToBpk(input);
}
Contract Addresses
Base Mainnet (Chain ID: 8453)
const CURRENCY_TOKENS = {
ebUSD: '0x9f6d30758b85bd2f4b6107550756162e04ce1650',
ebEUR: '0x06f9706c8defcebd9cafe7c49444fc768e89d7a7',
ebPLN: '0xbdcdbe9a1ee3ce45b6eea8ec4d7cb07cd8444720',
swapRegistry: '0x667d6c4d1e69399a8b881b474100dccf73ce42a0',
};