Skip to main content

Single deposit and withdraw

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.

1. Build a session

import { PoolSessionBuilder } from "@privacy-pools-v2/sdk";
import { FetchCircuitArtifacts } from "./FetchCircuitArtifacts";

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 covers both. The builder also expects at least one relayer entry, and the Quickstart shows the Sepolia shape.

2. Deposit

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

3. Wait for attestation, sync

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

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