Privacy checklist
The pool hides which notes a transaction spends, who receives a transfer, and transfer amounts. Other data remains observable, and some SDK options reduce privacy. This page lists what an application should configure and communicate to users.
What is public
| Data | Visible to | Details |
|---|---|---|
| Deposit payer and amount | everyone (on chain) | Denominations |
| Withdrawal recipient and gross amount | everyone (on chain) | Withdraw |
| That a shielded transfer occurred, and when | everyone (on chain) | How it fits together |
| Submitter IP address and timing | relayer | How it fits together |
| Requested token pair and size | metaquoter | Swap |
| A handle, the address published under it, and when it was registered | everyone (on chain) | Names |
| Which handle is looked up, and when | the RPC serving the lookup | Names |
| RPC reads, including your deposit account | your RPC provider | Networks |
Incoming notes (with matches strategy) | FMD server | Syncing |
Checklist
Amounts
- Withdraw denominations. Use
previewWithdrawand showonLadder: falseto the user; offersuggestioninstead of changing the amount. Anetwithdrawal is almost never on the ladder. See Denominations. - Keep ladders enabled (
denominations: true, the default). - Do not round the net amount. Choosing
publicOutso the recipient receives a round figure makespublicOutdistinctive. - Avoid distinctive deposit amounts where the user can choose, since deposits are public.
- Consider
DenominationCoinSelector(viacreateWallet) to reduce change, and runredenominateto keep notes on the ladder.
Timing and linkage
- Spread large withdrawals across blocks and recipients; several withdrawals to one address are linked.
- Keep the spend cooldown (
selection.cooldownBlocks, default 1) and use a chain adapter that implementsblockNumber, which the cooldown requires. See Spend cooldown. - Keep the default SFRT selector. Largest-first selection creates a pattern that links spends. See Pluggable interfaces.
- Use
recipientCommitment, not an output index, to identify the payee note; outputs are shuffled. See Transfer. - Give each payer its own address with
addressAt(index). Payers comparing addresses then cannot tell they pay the same account. See Addresses. - Publish only the reserved address under a handle, which
registerNamedoes, and hand it out nowhere else. A registration re-shields its change in the same public transaction as that address, so the change is kept to one unit. - Look a handle up once, when a contact is saved, not before each payment. A lookup followed by a spend lets whoever served the lookup pair them. See Names.
- Accept only names under the parents your deployment lists.
lelantos.ethis not one of them. See Names.
Detection and keys
- Keep the
fullsync strategy unless bandwidth requiresmatches. Delegating detection cannot be revoked. See Sync strategies. - In a watch-only wallet, leave
allowDetectionKeyReleaseunset. The decision belongs to the account owner. See Watch-only wallets. - Treat viewing keys as permanent disclosure. They cannot be revoked. See Watch-only wallets.
- Treat a payment proof as disclosure of one payment. With the payee's address, its holder reads that output's asset, value and memo; it reveals nothing else. Send it only to whoever should learn it. See Proving a payment.
- Treat a handle's controller key as the handle. Its holder can publish another address under it. Clearing a record stops it resolving but does not erase it from chain history. See Names.
- Treat a claim-link key as the funds. Whoever holds it can spend what the link holds. See Claim-link keys.
- Derive subscription tokens from
ivk, and store the epoch after rotating. See Rotating the token.
Network
- Route traffic if IP privacy matters. Pass
http: { fetch }to send all SDK service requests through a proxy, and pointrpcUrlat an endpoint you trust. See HTTP options. - Do not query servers per note. Custom
NoteSourceimplementations must not request Merkle paths or nullifier status for specific notes. See Custom note source.
Local data
- Encrypt the notes file at rest. It links its holder to every commitment the wallet owns. See Custom storage.
- Do not log user input verbatim. SDK error messages omit rejected addresses and values; keep application logs consistent with that.