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.depositchecks the current allowance and submits atoken.approve(Entrypoint, ...)transaction as part of the deposit flow when required, so no prior manual approval call is needed. - Withdraw fee:
amountis the net recipient amount. The spent inputs coveramount + relayer fee(the fee is denominated in the withdrawn asset), and any remainder returns as a change note.