Inputs and outputs
Circuit statement
Given public inputs(VIRTUAL_CHAIN_ID, noteNullifiers[6], txNullifier, root, rkRoot, three commitments, three ciphertexts, gasFee, nullifiersHash, fee, feeTokenAddress), the prover knows:
- a signed EIP-1559 transaction to the recipient for
(token, amount), signed bypkforVIRTUAL_CHAIN_ID - input notes owned by the sender, each with a Merkle path to
root - the sender’s
nk, matching the nullifiers - the recipient’s inbox key, with a Merkle path to
rkRoot - trapdoors and ephemeral keys that make each commitment and ciphertext correct
Why the key registry root
The recipient’s inbox key must be registered. Proving membership underrkRoot means a sender can only encrypt to a real, owner-registered key. The contract checks that rkRoot is a known registry root (InvalidKeyRegistryRoot).
Fee change
The fee can be paid in a different token from the one sent. The separate fee change note returns the rest of the fee token to the sender.Contract execution
_checkSpend: relayer allowlist (iffee > 0), tx nullifier unused, root known- Check the key registry root
- Verify the proof with 46 public inputs
- Record nullifiers
- Insert three commitments in one batch
- Pay
feeoffeeTokenAddresstomsg.sender - Emit
ShieldedTransfer