10

V0.5 Testnet · For builders

Reference

Constants

Value
Registration messagemenoid_Wallet
Key tagsmenoid/spend · menoid/encryption
BabyJubJub order l2736030358979909402780800718157159386076813972158567259200215660948447373041
Inputs per proof4 (MAX_INPUTS)
Outputstransfer 3 (receiver, change, relayer) · withdraw 2 + a public payout
Merkle treesdepth 20 (1,048,576 leaves per pool) · last 10 roots
Amounts0 ≤ amount < 2¹²⁸
Domain separators1 commitment · 2 nullifier
Proof systemGroth16 (BN254) · Circom · snarkjs
Note encryptionECIES (secp256k1 on EVM)

Public signals

CircuitSignalsLayout
Deposit5[depositAmount, c1, c2, c2_enabled, uc2]
Transfer19[relayer, enabled×4, roots×4, nullifiers×4, output_enabled×3, c_outs×3]
Withdraw19[receiver, relayer, enabled×4, roots×4, nullifiers×4, withdrawAmount, out_enabled×2, c_outs×2]

Events

EventWhen
WalletRegistered(wallet, userCommitment, encryptionPublicKey)a wallet enabled Noid mode
NoteCreated(poolId, commitment, encryptedNote)a note was created
NullifierSpent(nullifier)a note was spent
NewPool(poolId)a tree filled and a new pool opened

Every formula

Same on EVM, Solana, Aptos and Sui
signature      = sign("menoid_Wallet")
sk             = keccak256("menoid/spend" ‖ signature) mod l
spendPk        = sk · Base8   // BabyJubJub
encPriv        = keccak256("menoid/encryption" ‖ signature)
encPub         = encPriv · G
userCommitment = Poseidon(address, spendPk.x, spendPk.y)
 
commitment     = Poseidon(1, amount, r, userCommitment)
nullifier      = Poseidon(2, commitment, r, sk)
 
deposit:   depositAmount = a1 + c2_enabled · a2
transfer:  Σ inputs      = Σ outputs
withdraw:  Σ inputs      = Σ outputs + withdrawAmount

Testnet only

V0.5 runs on testnets and is unaudited. Its proving keys come from a local setup, suitable for testnet only. Use test tokens — never real funds.