# Single deposit and withdraw

> The smallest complete integration: deposit ETH, wait for approval, and withdraw to a fresh address.

This guide walks through the minimal viable Privacy Pools v2 flow end-to-end: install the SDK, deposit ETH, wait for attestation, and withdraw it to a different address.

## Setup

**SDK access:** The v2 SDK (`@privacy-pools-v2/sdk`) is not yet publicly available. Partners with early access are granted access to the `v2-monorepo` and consume the SDK from it as a workspace dependency. Reach out via X to request access: [@0xbowio](https://x.com/0xbowio).

## 1. Build a session

```ts

const rpcUrl = process.env.RPC_URL;
if (!rpcUrl) throw new Error("set RPC_URL to an HTTPS JSON-RPC endpoint");

const session = await PoolSessionBuilder.fromConfig({
    chainId: 11155111,
    rpcUrl,
    ownerAddress: address,
    protocolKeys: { ...keys, revocableKeyIndex: "0x0" },
    aspUrl: "https://api-dev.0xbow.io",
    relayers,
    walletInteractor: { type: "viem", walletClient },
}).withCircuitArtifacts(new FetchCircuitArtifacts("/circuits"))
  .create();
```

`FetchCircuitArtifacts` is a sample-app helper, not an SDK export. Copy the reference implementation or supply your own `ICircuitArtifacts` loader; [circuit artifacts](/sdk/circuit-artifacts) covers both. The builder also expects at least one relayer entry, and the [Quickstart](/introduction/quickstart) shows the Sepolia shape.

## 2. Deposit

```ts
const NATIVE_ETH = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
await session.deposit({
    tokenId: NATIVE_ETH,
    value:   "0x2386f26fc10000",         // 0.01 ETH in wei
});
```

## 3. Wait for attestation, sync

```ts
// Poll until the note is ACTIVE.
let note;
while (!note || note.status !== "ACTIVE") {
    await new Promise(r => setTimeout(r, 10_000));
    await session.discoverNotes();
    const acct = await session.exportAccount();
    note = acct.notes[0];
    console.log("Status:", note?.status);
}
```

## 4. Withdraw

```ts
const prepared = await session.prepareWithdraw({
    inputCommitments: [note.commitment],
    amount: netRecipientAmount,
    tokenId: NATIVE_ETH,
    recipientAddress: publicDestination,
});
const result = await session.relayWithdraw(prepared.relayerOptions[0]);
console.log("Withdrawn:", result.txHash);
```

## Gotchas

-   **[ASP](/concepts/asp-attestation) wait time**: deposits are often approved within 1 hour, but in some cases can take up to 7 days.
-   **ERC20 approval is automatic**: `session.deposit` checks the current allowance and submits a `token.approve(Entrypoint, ...)` transaction as part of the deposit flow when required, so no prior manual approval call is needed.
-   **Withdraw fee**: `amount` is the net recipient amount. The spent inputs cover `amount + relayer fee` (the fee is denominated in the withdrawn asset), and any remainder returns as a change note.
