Encrypted mempool - submitting an encrypted transaction
Limonata's encrypted mempool lets you submit a transaction whose contents are hidden until its order in the block is already fixed. No validator and no searcher can see what you're doing in time to front-run or sandwich you. The payload is decrypted only after validators holding more than 2/3 of bonded stake combine their key shares - which only happens after ordering. That's the anti-MEV guarantee.
The threshold key is generated and held by the validator set itself, inside consensus - no trusted dealer, no keyper committee, no coordinator. It's live on testnet limonata_10777-1. Come break it.
The 30-second version
# 1. encrypt your payload to the chain's threshold public key
limonatad keyper encrypt \
--pubkey Aw2DNwiH87yToy7Q+HC3Bv4hBiihRYlqnqp5nKsTIfwN \
--message "buy 1000 LIMO at market"
# -> prints a (base64), nonce (base64), body (base64)
# 2. submit the ciphertext (the body is unreadable on-chain)
limonatad tx encmempool submit-encrypted \
--a <A> --nonce <NONCE> --body <BODY> \
--from <your-key> --keyring-backend test \
--chain-id limonata_10777-1 --node tcp://rpc.limonata.xyz:443 \
--gas auto --gas-adjustment 1.4 --fees 5000000aLIMO -y
That's it. Your ciphertext is now stored on-chain with a fixed decrypt height. The validators post their decryption shares automatically; about ~30 seconds later (15 blocks) the chain decrypts it and emits the plaintext in the order that was locked in at submission time.
What just happened
- Encrypt.
keyper encryptencrypts your message to the chain's single
threshold public key. The output is a hybrid ciphertext: a (an ephemeral public key), a nonce, and the AES-GCM-encrypted body.
- Submit.
submit-encryptedstores(a, nonce, body)on-chain and assigns
it a sequence number + a decrypt height (current height + 15). The order is fixed now, while the body is still unreadable.
- Validators cooperate. Each validator independently computes a partial
decryption from a using its stake-weighted key share and posts it. No single validator - and no coalition holding 2/3 or less of bonded stake - can decrypt anything.
- Decrypt. At the decrypt height, the chain combines the shares, decrypts the
body, and emits an encmempool_decrypted event with the plaintext, in deterministic order. Every node computes the identical result (it's consensus logic, not a side service).
Prove the anti-MEV property yourself
Submit a ciphertext, then before its decrypt height, query its on-chain data: the body is opaque bytes - there is nothing to front-run. Query again after the decrypt height and you'll see the encmempool_decrypted event with your exact message. The order was committed in step 2, the readability in step 4. A searcher watching the mempool sees only ciphertext until it's too late to reorder.
# watch for your decryption on the explorer or via:
limonatad q tx <SUBMIT_TXHASH> --node tcp://rpc.limonata.xyz:443 -o json
# note the decrypt_height in the encmempool_encrypted_submitted event, then check
# that block's results for encmempool_decrypted.
Getting the binary
Use the limonatad release that ships with the encrypted-mempool upgrade (the same binary validators run). keyper encrypt is a local, offline command - it never touches your keys or the network; it only needs the public threshold key above.
How the key is held
The threshold key is not held by any trusted party. It is generated and held by the validator set itself, on-chain, inside consensus:
- No trusted setup, no dealer, no keyper committee. Validators run a distributed
key generation inside consensus - the master secret never exists in one place. Validators take part simply by running the node binary: no extra daemon, no account, no fees, no key setup, no registration. DKG messages ride inside CometBFT vote extensions.
- Stake-weighted and sybil-resistant. Key shares are apportioned by bonded
stake over a fixed budget (256). Reconstructing the key needs shares representing more than 2/3 of committee stake (currently a threshold of 171 of 256). Seats do not matter, stake does - spinning up extra validators buys no decryption power.
- Fails closed. If stake concentration would let one operator (or a coalition
holding 2/3 or less of stake) decrypt alone, encrypted submissions are rejected until the distribution improves. The chain refuses to fake privacy.
- Auto-rekey. Membership changes and stake drift beyond 5% trigger an automatic
re-key, so decryption power always tracks real stake and never goes stale.
- Decrypted transactions execute on-chain. At reveal the decrypted transaction
is executed through the EVM (EncExec) - the full submit-sealed -> reveal -> execute loop is protocol logic, run identically by every node.
It's testnet-only for now - live on limonata_10777-1 since the encmempool-transparent-dkg-v1 upgrade (DKG finalized at block 998,805, epoch 1; source tag limonata-v0.3.2). The core property holds: your transaction's order is fixed before anyone can read it.
Why it matters
On most chains, whoever orders the block (or watches the public mempool) can see your trade and jump ahead of it - front-running, sandwiching, MEV extraction. An encrypted mempool removes the information advantage: by the time your transaction can be read, its position is already final. Limonata is testing this in the open. 🍋
Limonata