Skip to main content

Client SDK

The zkbob-client-js library is the official SDK for interacting with the Telos Privacy pool from the client side. Use it to build custom wallets, DeFi integrations, or any application that needs to deposit, transfer, or withdraw shielded funds on Telos EVM.

Installation

npm install zkbob-client-js

or with yarn:

yarn add zkbob-client-js

Or pin a specific version in package.json:

"dependencies": {
"zkbob-client-js": "5.4.0"
}

Modes

The SDK operates in two modes:

ModeDescription
Account-lessRead-only. Fetch fees, limits, pool state, Merkle tree info — no user credentials required
FullRead + write. Attach a spending key to deposit, transfer, withdraw, and read shielded balances

Telos Pool Configuration

When initializing the client, use the Telos EVM pool configuration. The pool IDs and contract addresses for Telos are:

PoolPool IDPool Contract (proxy)Token
WTLOS400010xB5340818eE78D6221f631495346E2e55DA5BcA580xD102cE6A4dB07D247fcc28F366A623Df0938CA9E
USDC.e400020xe47A4F0099cA16d61C678Dc75911F91e11deDAa30xF1815bd50389c46847f0Bda824eC8da914045D14

The relayer endpoint for Telos Privacy is provided by the zkWallet infrastructure. Contact the Telos Foundation or check the zkWallet source for the current relayer URL.

Quickstart

1. Initialize the client (account-less)

import { ZkBobClient, ClientConfig } from 'zkbob-client-js';

const config: ClientConfig = {
pools: {
'WTLOS': {
chainId: 40, // Telos EVM
poolAddress: '0xB5340818eE78D6221f631495346E2e55DA5BcA58',
tokenAddress: '0xD102cE6A4dB07D247fcc28F366A623Df0938CA9E',
relayerUrl: 'https://RELAYER_URL', // TODO: get current relayer URL from Telos Foundation
},
'USDC.e': {
chainId: 40,
poolAddress: '0xe47A4F0099cA16d61C678Dc75911F91e11deDAa3',
tokenAddress: '0xF1815bd50389c46847f0Bda824eC8da914045D14',
relayerUrl: 'https://RELAYER_URL', // TODO: get current relayer URL from Telos Foundation
},
},
snarkParams: {
transferParamsUrl: 'https://r2.zkbob.com/transfer_params_22022023.bin',
transferVkUrl: 'https://r2.zkbob.com/transfer_verification_key_22022023.json',
},
};

const client = await ZkBobClient.create(config, 'WTLOS');
SNARK Parameters

The CDN hosting SNARK parameters only allows requests from localhost and zkbob domains. For production use, download the parameter files and bundle them with your app. See the react-template for an example.

2. Fetch pool info (account-less)

// Get transaction fee
const fee = await client.atomicTxFee();

// Get pool deposit/withdrawal limits
const limits = await client.getLimits(userAddress);
console.log('Deposit limit:', limits.deposit.total);
console.log('Withdrawal limit:', limits.withdraw.total);

3. Attach a user account (full mode)

Derive a spending key from a mnemonic or Web3 wallet signature:

import { ZkBobClient, AccountConfig, ProverMode, deriveSpendingKeyZkBob } from 'zkbob-client-js';

// From a mnemonic seed phrase
const sk = deriveSpendingKeyZkBob('your twelve word mnemonic seed phrase goes here');

const accountConfig: AccountConfig = {
sk,
pool: 'WTLOS',
proverMode: ProverMode.Local,
};

await client.login(accountConfig);

Or derive from a Web3 wallet (MetaMask):

import { ethers } from 'ethers';

// Sign the derivation message with the user's wallet
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const signature = await signer.signMessage('Sign this message to derive your Telos Privacy account key');

// Use the signature entropy as the mnemonic seed
const mnemonic = ethers.utils.entropyToMnemonic(signature.slice(0, 66));
const sk = deriveSpendingKeyZkBob(mnemonic);

4. Sync and read balance

// Sync with the relayer (may take time for large pools)
await client.updateState();

// Get shielded balance (in pool token units)
const balance = await client.getBalance();
console.log('Shielded balance:', balance);

// Get transaction history
const history = await client.getAllHistory();

5. Generate a shielded address

const zkAddress = await client.generateAddress();
console.log('My zk-address:', zkAddress);
// Share this address to receive private transfers

6. Deposit

import { TxType } from 'zkbob-client-js';

// Deposit 10 WTLOS into the shielded pool
const amountInPoolUnits = BigInt(10 * 1e9); // pool uses 9 decimal precision

const jobId = await client.deposit(amountInPoolUnits, async (data) => {
// Sign the deposit with the user's wallet
const provider = new ethers.providers.Web3Provider(window.ethereum);
return provider.getSigner().signMessage(ethers.utils.arrayify(data));
});

console.log('Deposit submitted, job ID:', jobId);

7. Transfer (private)

// Send 1 WTLOS privately to a zk-address
const recipientZkAddress = 'zkAddress_of_recipient...';
const amount = BigInt(1 * 1e9);

const jobId = await client.transfer([{ to: recipientZkAddress, amount }]);
console.log('Transfer submitted, job ID:', jobId);

8. Withdraw

// Withdraw 5 WTLOS to a public EVM address
const recipientAddress = '0xYourPublicEvmAddress';
const amount = BigInt(5 * 1e9);

const jobId = await client.withdraw(recipientAddress, amount);
console.log('Withdrawal submitted, job ID:', jobId);

9. Check job status

const status = await client.getJobStatus(jobId);
console.log('Status:', status.state); // 'waiting' | 'proving' | 'sent' | 'mined' | 'failed'
console.log('Tx hash:', status.txHash);

Switching Pools

You can switch between the WTLOS and USDC.e pools without reinitializing:

await client.switchToPool('USDC.e', accountConfig);

React Integration

The SDK relies on Rust/WASM under the hood and requires custom webpack config. The easiest way to get started in React is the react-template, which uses react-app-rewired to handle the WASM setup. Alternatively, use Next.js or Vite which give direct webpack access.

Reference Implementations