privacy protocol logo
Skip to Content
Cloak SDKQuickstart

Quickstart

This walks through the full lifecycle with the core (framework-agnostic) API. For React, see React Hooks.

1. Create a client

import { createCloakClient, LocalStorageNoteStore } from "@privacy-protocol/cloak" import { createPublicClient, createWalletClient, custom, http } from "viem" import { sepolia } from "viem/chains" const POOL = "0xYourCloakPool" const RELAYER = "https://cloak-relayer.onrender.com" const publicClient = createPublicClient({ chain: sepolia, transport: http() }) const walletClient = createWalletClient({ chain: sepolia, transport: custom(window.ethereum) }) const cloak = createCloakClient({ publicClient, walletClient, chainId: sepolia.id, poolAddress: POOL, relayerUrl: RELAYER, // Persist notes! Notes are the funds. Defaults to in-memory (lost on reload). store: new LocalStorageNoteStore(sepolia.id, POOL), })

2. Deposit

The user signs and pays for the deposit — it is public by design.

import { ETH_ADDRESS } from "@privacy-protocol/cloak" // Deposit 0.1 ETH const note = await cloak.deposit({ asset: ETH_ADDRESS, amount: 10n ** 17n }) // ERC-20: the SDK handles approval automatically const usdcNote = await cloak.deposit({ asset: "0xToken", amount: 1_000_000n })

The returned note is saved to your store. Let the anonymity set grow before spending.

3. Send a transaction anonymously

send forwards an arbitrary call through an ephemeral proxy, relayed so your address never appears.

import { encodeFunctionData } from "viem" await cloak.send({ note, target: "0xSomeContract", data: encodeFunctionData({ abi, functionName: "mint", args: [1n] }), value: 5n * 10n ** 16n, // 0.05 ETH sent with the call returnAsset: ETH_ADDRESS, // capture any ETH the call returns })

The remaining balance (amount − value − fee) comes back automatically as a new change note in your store.

4. Withdraw privately

To move funds to a fresh address with no visible link to the deposit:

await cloak.withdraw({ note, to: "0xFreshAddress" }) // whole note await cloak.withdraw({ note, to: "0xFreshAddress", amount: 3n * 10n ** 16n }) // partial

5. Claim returned funds

Funds a call sent back to the proxy become claim notes. Sync, then withdraw them:

await cloak.sync() for (const claim of await cloak.getClaimables()) { await cloak.claim({ claimNote: claim, to: "0xFreshAddress" }) }

6. List spendable notes

await cloak.sync() const notes = await cloak.getNotes() const balance = notes.reduce((sum, n) => sum + n.amount, 0n)
Last updated on