SIGN IN SIGN UP

Add AetherSplitter, a privacy_invoke anonymizer

An on-chain amount-entropy primitive: one input becomes N caller-
specified non-round notes inside a single pool operation, instead of N
separate transactions each paying a pool fee and leaving a timing trail.

Multi-output was verified against the references before building — the
${openNoteIds[N]} placeholder is zero-indexed with an [0-9]+ pattern,
privacy_invoke returns a Span<OpenNoteDeposit> the pool iterates, and
only the invoke phase is capped at one per transaction.

Proportions are always caller-supplied; Cairo has no good randomness
source and the planner's splits must stay deterministic. The sum
invariant is asserted twice — once against the plan, once re-derived
from the deposits actually returned — because a helper that silently
loses value is a critical bug, not a rounding detail. Caller is
pool-gated, and the guards cover zero amounts, empty and oversized
arrays, duplicate note ids, overflow, and fees above a pinned cap.

Documented honestly in contracts/README.md: open-note amounts are
plaintext by design, so where the amount is known at proof time, N
transfer actions create encrypted notes and are strictly more private.
The splitter's unambiguous win is the execution-time case — splitting
by basis points over a balance measured on-chain, which a client cannot
do — plus enforced reconciliation.

Unaudited draft. 29 snforge tests. Deploy script prints, never executes,
and touches no key material.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
S
Shariq Shaukat committed
7e3a94d3d25aa541e6233c3f8963d30e20d1db51
Parent: 6456547