Skip to main content
Use this as a practical Windsurf playbook for shipping SDK-powered privacy apps. The prompts below use the Cloak SDK (@cloak.dev/sdk).

Quick launch

Use in Cursor

Open the Cursor starter prompt.

Use in Claude Code

Open the Claude starter prompt.

Use in Windsurf

Open the Windsurf starter prompt.

1) Rules file

Create .windsurf/rules.md:

Windsurf Rules for SDK

We integrate @cloak.dev/sdk.

Constants

  • Program ID: zh1eLd6rSphLejbFfJEneUwzHRfMKxgzrgkfwA6qRkW
  • Circuit base URL: https://storage.googleapis.com/cloak-circuits/circuits/0.2.0 (the ceremony bundle). Never hand-write the string: read the exported DEFAULT_CIRCUITS_URL constant, or call resolveCircuitsBase() to get the SDK default. Never point at 0.1.0; the program no longer accepts those artifacts and they fail with 0x1010 (ProofInvalid).

Capability groups (must check all)

  1. Note API
  2. UTXO API
  3. Scanner/compliance
  4. Viewing keys + metadata encryption
  5. Relay/proof/Merkle helpers
  6. Utility modules (fees/errors/network/wallet/storage)

Runtime rules

  • Prefer UTXO flows for new features.
  • Keep transaction amounts as bigint.
  • Do not add an app-level viewing-key registration step. transact() and swapUtxo() register automatically before every flow (transfer, partialWithdraw, fullWithdraw and swapWithChange route through them), deriving nk from the UTXO keypair when it is not supplied. Call the exported registerViewingKey only for standalone compliance or history scanning.
  • Build cache-first history with explicit rescan.

Security rules

  • Never output secrets in logs.
  • Never include raw private material in telemetry.
  • Transaction signatures are public and can be logged for support/debugging.
  • Use SDK defaults for program and circuits. Do not expose those as user-facing config. The relay has no SDK default: pass relayUrl explicitly on every call. The SDK reads no environment variable for it; if the value should be configurable, read CLOAK_RELAY_URL in your own code and pass it as relayUrl. Omitting relayUrl throws Viewing key registration is mandatory: relayUrl is required. before any network call, deposits included.
  • Never pass relayUrl: "" to “skip the relay”. Under the default enforceViewingKeyRegistration it throws the same error as omitting it, and it only signals caller-signed direct submission when enforceViewingKeyRegistration: false is set as well, which submits a send or withdrawal under the user’s own key and publicly links it.
  • In browser code, authenticate the sender with signMessage + walletPublicKey in the transact options. Never emit depositorKeypair in browser send or withdraw code.
  • Never substitute the authenticated sender with an ephemeral or service key. That key is the one screened, so it must be the end user’s own wallet key.
  • Never tell the user they must use a particular RPC provider. The RPC endpoint is the app owner’s choice.

Docs

  • /llms.txt
  • /llms-full.txt
  • /sdk/llms.txt
  • /sdk/api-reference
  • /sdk/request-authentication
  • /sdk/utxo-transactions
  • /sdk/error-handling

2) Starter prompt

Implement this feature using the complete @cloak.dev/sdk model.Step 1: output a capability matrix (all 6 groups) with used/not-used + reason.Step 2: implement with:
  • bigint-safe logic
  • wallet-adapter-compatible flow, following /sdk/request-authentication for the authenticated sender
  • keypair-bytes fallback where relevant
  • scanner/compliance handling
  • robust error UX; rely on SDK stale-root retries by default
Step 3: run checks and return changed files + rationale + verification summary.

3) Prompt pack

Generate deposit/send/withdraw/swap handlers, history scanner integration, cache, and CSV export.
Patch existing app code to current SDK contracts with minimal UI churn.
Improve error categorization, progress states, stale-root handling, and operational resilience.