NoteManager
The NoteManager is the local index of your notes: what you have, each note's status, and the discovery cursor. It is held in the session's storage adapter, which you configure. Storage is not configured by default, so without a persistentStorage config the index lives in memory only and is lost on reload.
Note status states
INACTIVE A draft or unclaimed note the session is aware of but cannot yet spend. The typical case is a recipient-side draft generated as part of a send, before the corresponding commitment lands on-chain or is imported.PENDING The note exists locally but isn't spendable yet: a deposit is awaiting ASP attestation, and a transact output is awaiting chain confirmation.ACTIVE The note is attested and confirmed, so it is spendable.SPENT The nullifier has been published on-chain, and the note can't be re-spent.REJECTED The ASP explicitly refused the deposit's label. The note is recoverable via ragequit.EXITED The note has been ragequit and the public exit completed.Status transition matrix
The legal transitions are:
| From | To | Trigger |
|---|---|---|
INACTIVE | PENDING | commitment observed on-chain |
INACTIVE | EXITED | ragequit |
PENDING | ACTIVE | attestation lands |
PENDING | ACTIVE | discoverable-mode re-decryption |
PENDING | REJECTED | attestation refuses |
PENDING | EXITED | ragequit |
ACTIVE | SPENT | transact submission lands |
ACTIVE | EXITED | ragequit |
ACTIVE | REJECTED | label revoked on the ASP after activation |
REJECTED | EXITED | ragequit |
Illegal transitions throw InvalidStatusTransitionError. State can still drift if note updates aren't persisted before reload. The most common symptom is re-running discovery flipping SPENT back to ACTIVE. If you see balances refuse to decrease across a page reload, call session.discoverNotes(), which flushes the NoteManager internally. See Failure modes.
Persistence
Choose one of these adapters through persistentStorage. None is selected by default, so until you set one the NoteManager keeps its index in memory only.
{type: "local", prefix} Browser localStorage, used only when you select this type. The default prefix is then privacy-pool, and the cursor and note state persist under keys carrying that prefix.{type: "file", dirPath, filename?} Node disk persistence, with JSON files per account.{type: "memory"} An in-process Map, for tests and one-shot scripts.Cursor
The NoteManager keeps a sync cursor (the last-synced block number). Subsequent discoverNotes() calls start from the cursor instead of from genesis, which keeps steady-state syncs fast. Clearing the cursor forces a full rescan, which can be slow on a cold start.
Direct access
Usually you go through session.exportAccount(). The NoteManager isn't a public API of the session, but imports and mutations happen through these session methods:
importReceivedNote(note): adds a note manually.discoverNotes(): reconciles from the chain.exportAccount(): takes a snapshot.