How it works
Merkle note system
All commitments are stored in a depth-20 Poseidon2 Merkle tree on-chain. The tree supports up to 2²⁰ (≈ 1 million) commitments. The SDK mirrors this tree locally so you can generate membership proofs without a server.
Local mirroring
The NoteManager class replays Shielded and Spent events from the contract, rebuilding the local tree leaf by leaf. After every insertion, it recomputes the sibling paths for all owned notes so they always have valid membership proofs.
Zero values
Empty positions in the tree use a pre-computed zeros chain: zeros[0] = 0, zeros[i] = Poseidon2(zeros[i-1], zeros[i-1]). This mirrors the Solidity implementation exactly, ensuring local and on-chain roots always match.
typescript
// Access the local tree via noteManager const root = sdk.noteManager.getCurrentRoot(); const notes = sdk.noteManager.getUnspentNotes(tokenAddress); const siblings = notes[0].siblings; // 20 sibling hashes for this note