Whole integration, one page. Code below comes from package-pinned starter. Follow order as written.

Before you start

You need:
  • packages from SDK install;
  • proving files named by SDK runtime;
  • resolveMembership, isNullifierSpent, and runtimeFeeReadClient adapters;
  • private storage for recovery backup;
  • wallet submission boundary for unsigned transaction requests.
Use SDK setup for tested environment details. Use proving files for file checks.

1. Create client

Starter reads runtime, checks local proving files, wires snarkjs, reads deposit events, then adds three app-owned adapters.
readDeposits and isNullifierSpent return source identity with their values. Membership and fee adapters receive active runtime and must read same pool.

2. Prepare a deposit

Create recovery key inside trusted client. Pass same key into deposits.prepare.
recovery.createKey() returns 32 bytes. deposits.prepare() returns recovery data, proof data, and unsigned transaction. No chain write has happened yet.

3. Save and test recovery

Starter stores recovery key and encrypted envelope in one JSON value. Parse it and run recovery.restore before giving deposit request to wallet.
Keep recoveryData in durable private storage. Restore accepts envelope only when it matches active client runtime and recovery key.

4. Submit deposit

Pass deposit.transaction to app wallet layer after backup roundtrip succeeds. Review and simulate request, submit once, then keep returned transaction hash. Wait until matching deposit event is available before reading new balance.

5. Read the private balance

balances.get asks app readers for deposit events and spent state. Matching encrypted deposits open locally with recovery key.
availableBalanceWei is decimal wei string. deposits contains recovered bundles and their notes. Spent notes remain visible with status "spent"; their amounts stay out of availableBalanceWei.
Reader failure rejects call. Keep previous displayed balance and show refresh action in app UI.

6. Prepare a withdrawal

Use bundle and child index from same balance result. Pass recipient plus fee bounds user reviewed.
withdrawals.prepare resolves membership, checks note status, reads fee, builds proof, then checks fee and note status again. Result contains exact gross amount, fee, recipient amount, destination, and unsigned transaction. Review these fields before submission: Submit withdrawal.transaction through app transaction boundary. Keep returned hash.

7. Reconcile the result

Wallet or RPC timeout can leave submission status unclear. Check original hash when present, then check exact prepared operation.
For deposit, effectObserved checks deposit.binding.commitment. For withdrawal, it checks withdrawal.nullifier. Starter has no resend branch. New submission starts only after original result is known.

Keep between sessions

Keep recovery JSON and any unresolved transaction hash. Recovery JSON contains secret key material.
Anyone holding recovery backup can restore its private notes. Keep it out of logs, analytics, URLs, support messages, and shared clipboard history.
Need field-level details? Open API reference. Need focused guides? Use deposit, recovery, withdrawal, and errors and status.