> ## 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

> Operate across multiple blockchains with the TypeScript SDK

# Multi-Chain

This guide covers using `ChainClient` to perform privacy operations across multiple blockchains from a single SDK instance.

<Info>
  For an overview of multi-chain concepts, see [Multi-Chain Concepts](/sdk/concepts/multi-chain).
</Info>

## Setup

Initialize the parent SDK, then create chain clients for each blockchain you want to interact with:

```typescript theme={null}
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:

```typescript theme={null}
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:

```typescript theme={null}
// 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

```typescript theme={null}
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

```typescript theme={null}
// 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

```typescript theme={null}
await ethereum.vault.unshield({
  tokenAddress: '0x...',
  amount: 250000000000000000n,
  recipientAddress: '0x...destination',
});
```

### Balances

```typescript theme={null}
// Per-chain balances
const ethBalance = await ethereum.vault.getBalance('0x...');
const baseBalance = await base.vault.getBalance('0x...');

console.log('Ethereum shielded:', ethBalance.shieldedBalance);
console.log('Base shielded:', baseBalance.shieldedBalance);
```

## Cross-Chain Patterns

### Parallel Operations

Since chain clients are independent, you can run operations in parallel:

```typescript theme={null}
const [ethResult, baseResult] = await Promise.all([
  ethereum.vault.shield({ tokenAddress: '0x...', amount: 1000n }),
  base.vault.shield({ tokenAddress: '0x...', amount: 2000n }),
]);
```

### Multi-Chain Balance Aggregation

```typescript theme={null}
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.shieldedBalance, 0n);
}
```

### Chain Selection

```typescript theme={null}
// 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

```typescript theme={null}
// 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

* [Deposits Guide](./deposits) — detailed shield operations
* [Withdrawals Guide](./withdrawals) — withdrawal operations
* [Transfers Guide](./transfers) — private transfers
* [Multi-Chain Concepts](/sdk/concepts/multi-chain) — architecture overview
