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

# Getting Started

> Integrate the Privacy Boost TypeScript SDK into your application

# Getting Started

This guide walks through the core integration flow: initialize the SDK, authenticate a wallet, and perform your first private transactions.

<Info>
  For a minimal copy-paste example, see the [TypeScript Quickstart](/sdk/quickstart/typescript). This guide explains each step in detail.
</Info>

## Prerequisites

* The SDK [installed](/sdk/typescript/installation) in your project
* An [App ID](/sdk/concepts/app-setup) and server URL (see [Configuration](/sdk/concepts/configuration))
* A wallet (MetaMask, WalletConnect, etc.)
* Familiarity with [authentication options](/sdk/concepts/authentication) (optional for development, required for production)

## Step 1: Initialize the SDK

```typescript theme={null}
import { PrivacyBoost } from '@sunnyside-io/privacy-boost';

const sdk = await PrivacyBoost.create({
  appId: 'your-app-id',
  serverUrl: 'https://optimism.sepolia.privacyboost.io',
  wethContractAddress: '0x4200000000000000000000000000000000000006',
});
```

### Configuration Options

| Option                  | Type     | Required | Description                                           |
| ----------------------- | -------- | -------- | ----------------------------------------------------- |
| `appId`                 | `string` | Yes      | Application identifier                                |
| `serverUrl`             | `string` | Yes      | Privacy Boost server endpoint                         |
| `chainId`               | `number` | No       | EVM chain ID (auto-discovered from server)            |
| `shieldContractAddress` | `string` | No       | Shield contract address (auto-discovered from server) |
| `wethContractAddress`   | `string` | No       | WETH contract for ETH handling                        |

## Step 2: Authenticate

Connect a wallet and authenticate in a single call:

### Using Browser Wallet (MetaMask, etc.)

```typescript theme={null}
// Create a wallet adapter that wraps window.ethereum
const adapter = {
  async connect() {
    const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
    const chainId = await window.ethereum.request({ method: 'eth_chainId' });
    return { address: accounts[0], chainId: parseInt(chainId, 16) };
  },
  async disconnect() {},
  async signMessage(message: string) {
    const accounts = await window.ethereum.request({ method: 'eth_accounts' });
    return window.ethereum.request({ method: 'personal_sign', params: [message, accounts[0]] });
  },
  async signTypedData(typedDataJson: string) {
    const accounts = await window.ethereum.request({ method: 'eth_accounts' });
    return window.ethereum.request({ method: 'eth_signTypedData_v4', params: [accounts[0], typedDataJson] });
  },
  async sendTransaction(tx: unknown) {
    return window.ethereum.request({ method: 'eth_sendTransaction', params: [tx] });
  },
  async getAddress() {
    const accounts = await window.ethereum.request({ method: 'eth_accounts' });
    return accounts[0];
  },
  async getChainId() {
    const chainId = await window.ethereum.request({ method: 'eth_chainId' });
    return parseInt(chainId, 16);
  },
};

// Authenticate — connects wallet, derives keys, and authenticates with server
const result = await sdk.auth.authenticate(adapter);

if (result.status === 'authenticated') {
  console.log('Privacy Address:', result.privacyAddress);
  console.log('MPK:', result.mpk);
} else if (result.status === 'credentialRequired') {
  // Prompt user for credential, then submit
  const loginResult = await result.submit(credential);
}
```

<Info>
  **When does `credentialRequired` fire?**
  `credentialRequired` only fires when persistence with `pin` or `password` unlock is configured. For the simple case (no persistence), `authenticate()` always returns `authenticated` directly.
</Info>

<Info>
  **Using React?** The React SDK provides `createWalletAdapter()` and `authenticateWithWalletAdapter()` which handle this for you. See the [React Getting Started](/sdk/react/getting-started) guide.
</Info>

### Authentication State

```typescript theme={null}
// Check authentication status
console.log('Authenticated:', sdk.auth.isAuthenticated());
console.log('Privacy Address:', sdk.auth.getPrivacyAddress());
```

## Step 3: Check Balance

Each token has two balances: a **shielded balance** (tokens inside the private pool, only visible to you) and a **wallet balance** (your public on-chain balance). Both are returned together in a `TokenBalance` object.

```typescript theme={null}
// Get balance for a specific token
const tokenAddress = '0x...';
const balance = await sdk.vault.getBalance(tokenAddress);
console.log('Shielded:', balance.shieldedBalance);
console.log('Wallet:', balance.walletBalance);

// Get all balances
const allBalances = await sdk.vault.getAllBalances();
for (const b of allBalances) {
  console.log(`${b.symbol}: ${b.shieldedBalance} (shielded), ${b.walletBalance} (wallet)`);
}
```

## Step 4: Deposit Tokens

Move tokens from your public wallet into the shielded pool. Once deposited, your balance is private — only you can see it.

```typescript theme={null}
const result = await sdk.vault.shield({
  tokenAddress: '0x...',
  amount: 1000000000000000000n, // 1 token (18 decimals)
  onProgress: ({ step, message }) => {
    console.log(`${step}: ${message}`);
  },
});

console.log('Deposit tx:', result.txHash);
console.log('Commitment:', result.commitment);
```

### Deposit Steps

The deposit operation goes through several steps:

1. **wrapping** - If depositing ETH, wrap to WETH
2. **approving** - Approve token spending
3. **shielding** - Execute the deposit transaction
4. **compliance** - Wait for compliance check

## Step 5: Send Private Transfer

Send tokens privately to another user's privacy address. The recipient shares their privacy address with you (similar to sharing a bank account number). No on-chain observer can see the sender, recipient, or amount.

```typescript theme={null}
const result = await sdk.vault.send({
  to: '0x04...recipient-privacy-address',
  tokenAddress: '0x...',
  amount: 500000000000000000n, // 0.5 tokens
});

console.log('Transfer requestId:', result.requestId);
```

The recipient will see the tokens in their shielded balance after the transaction confirms.

<Note>
  For `send()` and `unshield()`, the returned `txHash` is a **local placeholder** until the canonical on-chain hash is available. Track status by `requestId` (e.g. `sdk.transactions.getTransferStatus(requestId)` / `sdk.transactions.getUnshieldStatus(requestId)`). For `shield()`, `txHash` is the real on-chain hash because the wallet signs and submits it directly.
</Note>

## Step 6: Withdraw Tokens

Move tokens out of the shielded pool to any public Ethereum address. This is how you "cash out" back to a regular wallet.

```typescript theme={null}
const result = await sdk.vault.unshield({
  tokenAddress: '0x...',
  amount: 250000000000000000n, // 0.25 tokens
  recipientAddress: '0x...any-public-address',
  // Optional: when the token is WETH, automatically unwrap to native ETH
  // after the unshield lands. Requires `wethContractAddress` to be set.
  unwrapWeth: false,
  onProgress: ({ step, message }) => {
    console.log(`${step}: ${message}`);
  },
});

console.log('Withdraw requestId:', result.requestId);
```

## Step 7: Multi-Chain (Optional)

To operate on additional blockchains, create chain clients from the same SDK instance. Each chain client shares your identity but has independent auth, balances, and transactions:

```typescript theme={null}
// Create a chain client (only serverUrl is required; rest is auto-discovered)
const ethereum = sdk.forChain({ serverUrl: 'https://eth.example.com' });

// Authenticate on the new chain
await ethereum.authenticate(adapter);

// Use it just like the primary SDK
await ethereum.vault.shield({
  tokenAddress: '0x...token-on-ethereum',
  amount: 1000000000000000000n,
});

const ethBalance = await ethereum.vault.getBalance('0x...');
```

See the [Multi-Chain guide](/sdk/typescript/guides/multi-chain) for patterns like parallel operations and cross-chain balance aggregation.

## What's Next

You've completed the core flow: init → auth → balance → deposit → send → withdraw. Here's where to go from here:

<CardGroup cols={2}>
  <Card title="Deposits" href="/sdk/typescript/guides/deposits">
    Deposit tokens into the shielded pool
  </Card>

  <Card title="Withdrawals" href="/sdk/typescript/guides/withdrawals">
    Withdraw tokens from the shielded pool
  </Card>

  <Card title="Private Transfers" href="/sdk/typescript/guides/transfers">
    Send tokens privately between users
  </Card>

  <Card title="Error Handling" href="/sdk/typescript/guides/error-handling">
    Error codes and retry patterns
  </Card>

  <Card title="Multi-Chain" href="/sdk/typescript/guides/multi-chain">
    Operate across multiple blockchains
  </Card>

  <Card title="API Reference" href="/sdk/typescript/api-reference">
    Complete method signatures and type definitions
  </Card>
</CardGroup>

For cross-platform concepts (key management, auth methods, error codes), see the [Setup section](/sdk/concepts/app-setup).
