Skip to main content

Setup & Configuration

Installation

See Installation Guide for npm registry setup, then:

npm install @zk-privacy/eb-sdk @zk-privacy/eb-contracts viem

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

FieldTypeDescription
chainIdnumberChain ID for multi-token mode (8453 = Base)
chainChainViem chain (default: Base mainnet)
rpcUrlstringRPC endpoint URL (auto-detected)
contractAddressSingle contract (legacy mode)
transferCircuitCircuitSourceTransfer circuit (default: auto)
unshieldCircuitCircuitSourceUnshield circuit (default: auto)
stakeCircuitCircuitSourceL3 stake circuit (default: auto)
unstakeCircuitCircuitSourceL3 unstake circuit (default: auto)
enableL3booleanEnable L3 operations
relayerUrlstringRelayer URL for gasless ops
onProgress(stage, progress?) => voidInitialization callback
onLog(level, category, message, data?) => voidSDK log callback
threadsnumberProver threads (default: auto)
cacheVersionnumberCache version (default: 1)
storageStorageAdapterPersistent storage (default: IndexedDB in browser, memory in Node)
lazyLoadbooleanSkip heavy asset loading on initialize() (default: false)
onAssetLoading(asset: 'solver' | 'prover', progress?) => voidCallback 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',
};