Skip to main content

Keystore tree

The keystore tree is a Merkle tree (depth 18) of registered accounts. Registering puts your account in the tree and publishes your viewing public key on-chain, which is what lets senders encrypt notes addressed to you in discoverable mode.

Properties

  • Depth 18: the tree is 18 levels deep, supporting up to 2^18 (262,144) registered accounts. That sizing targets the early stage, and the depth is a circuit parameter (see Transact circuit).
  • Public by design: registration is a deliberate opt-in that says "I want to receive discoverable notes," and anyone can read the tree to find someone's viewing key.

The account leaf

Each registered account contributes one leaf, Poseidon(ownerAddress, privateNullifyingKeyHash, authDigest). The three committed values play distinct roles:

  • Owner address: ties the leaf to your wallet.
  • Nullifying key hash: the on-chain commitment to your private nullifying key, set once at registration and proved by every spend. This is how a transfer, withdrawal, or ragequit shows that the note's owner is registered without revealing which leaf is yours.
  • authDigest: commits to your current revocable-key authorization, and can be rotated in place at any time, not only after a compromise.

Your viewing public key is deliberately not in the leaf. It lives in a separate on-chain mapping (Keystore.viewingKeys(address)) that senders read to encrypt discoverable notes to you, so publishing it for discovery never exposes your spend authority.

What registration enables

Once you are registered, a sender can use the canonical recipientDiscoveryData: { evmAddress } variant: the SDK resolves your viewing public key from the keystore and encrypts to it. On your side, discoverNotes() then finds discoverable-mode notes automatically, with no out-of-band hand-off per payment.

What it doesn't do

Registration does not gate receiving. Anyone can still send you a note out-of-band, and registering just adds the more convenient path. It also does not publish your nullifying or revocable keys, because only the viewing public key goes on-chain.

Cost

Registration takes two on-chain transactions (setAuthPolicy and setViewingKey), a one-time cost whose gas varies with network conditions.

See register your viewing key for the operational flow.