Documentation Index
Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
Use this file to discover all available pages before exploring further.
Multi-Chain
This guide covers using ChainClient to perform privacy operations across multiple blockchains from a single SDK instance.
Setup
Initialize the parent SDK, then create chain clients for each blockchain you want to interact with:
import { PrivacyBoost } from '@sunnyside-io/privacy-boost';
// Initialize with your primary chain
const sdk = await PrivacyBoost.create({
serverUrl: 'https://op.example.com',
appId: 'my-app',
});
// Create chain clients — only serverUrl is required
const ethereum = sdk.forChain({ serverUrl: 'https://eth.example.com' });
const base = sdk.forChain({ serverUrl: 'https://base.example.com' });
You can pass additional configuration to override auto-discovered values:
const ethereum = sdk.forChain({
serverUrl: 'https://eth.example.com',
chainId: 42161,
wethContractAddress: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
rpcUrl: 'https://eth.example.com/rpc',
});
Authentication
Each chain client must be authenticated before use. Authentication shares your identity keys from the parent SDK but obtains a chain-specific JWT:
// Create a wallet adapter (same as parent SDK auth)
const adapter = {
async connect() { /* ... */ },
async signMessage(msg: string) { /* ... */ },
async signTypedData(data: string) { /* ... */ },
async sendTransaction(tx: unknown) { /* ... */ },
async getAddress() { /* ... */ },
async getChainId() { /* ... */ },
async disconnect() {},
};
// Authenticate on each chain
await ethereum.authenticate(adapter);
await base.authenticate(adapter);
// Check auth status
console.log('Ethereum authenticated:', ethereum.isAuthenticated);
console.log('Ethereum chain ID:', ethereum.chainId);
Operations
Once authenticated, a ChainClient provides the same vault, transactions, and audit resources as the parent SDK:
Deposits
const result = await ethereum.vault.shield({
tokenAddress: '0x...token-on-ethereum',
amount: 1000000000000000000n, // 1 token
onProgress: ({ step, message }) => {
console.log(`[Ethereum] ${step}: ${message}`);
},
});
console.log('Ethereum deposit tx:', result.txHash);
Private Transfers
// Look up recipient on a specific chain
const identity = await base.resolveIdentity('0x1234...abcd');
await base.vault.send({
to: identity.privacyAddress,
tokenAddress: '0x...token-on-base',
amount: 500000000000000000n,
});
Withdrawals
await ethereum.vault.unshield({
tokenAddress: '0x...',
amount: 250000000000000000n,
recipientAddress: '0x...destination',
});
Balances
// Per-chain balances
const ethBalance = await ethereum.vault.getBalance('0x...');
const baseBalance = await base.vault.getBalance('0x...');
console.log('Ethereum shielded:', ethBalance.shielded);
console.log('Base shielded:', baseBalance.shielded);
Cross-Chain Patterns
Parallel Operations
Since chain clients are independent, you can run operations in parallel:
const [ethResult, baseResult] = await Promise.all([
ethereum.vault.shield({ tokenAddress: '0x...', amount: 1000n }),
base.vault.shield({ tokenAddress: '0x...', amount: 2000n }),
]);
Multi-Chain Balance Aggregation
async function getTotalBalance(
chains: { client: ChainClient; token: string }[]
): Promise<bigint> {
const balances = await Promise.all(
chains.map(({ client, token }) => client.vault.getBalance(token))
);
return balances.reduce((sum, b) => sum + b.shielded, 0n);
}
Chain Selection
// Store chain clients in a map for easy selection
const chains = new Map([
['ethereum', sdk.forChain({ serverUrl: 'https://eth.example.com' })],
['base', sdk.forChain({ serverUrl: 'https://base.example.com' })],
['optimism', sdk.forChain({ serverUrl: 'https://op.example.com' })],
]);
// Select chain by name
function getChain(name: string): ChainClient {
const client = chains.get(name);
if (!client) throw new Error(`Unknown chain: ${name}`);
return client;
}
await getChain('ethereum').vault.shield({ tokenAddress: '0x...', amount: 1000n });
Cleanup
// Clear a single chain's session (JWT + pending state)
ethereum.clearSession();
// Dispose a single chain client
ethereum.dispose();
// Dispose everything (parent SDK + all chain clients)
sdk.dispose();
Next Steps