submit_encrypted
Call Re-added v361 → v385, v391 → current Changed in v391 #1Submits an encrypted transaction wrapper for MEV -protected execution.
View calls on chainCall Workflow
Click items to navigate. Pan and zoom to explore.
The Big Picture
This is the user-facing call for MEV protection. You encrypt your actual transaction (a swap, stake, etc.) using the announced NextKey, then submit the encrypted blob via this call. The current block author can't read your transaction, only the next block author (who announced the key) can decrypt and execute it.
Why This Matters
MEV attacks cost DeFi users billions. When you submit a large swap in the open, bots can see it, buy ahead of you (driving up price), then sell after you buy (profiting from your trade). Encrypting your transaction means nobody can see what you're doing until it's too late to front-run.
Example Scenario
You want to swap 1000 TAO for Alpha on subnet 5. Instead of submitting swap_stake openly, you: 1) Read NextKey from storage, 2) Sign your swap_stake transaction, 3) Hash it to create commitment, 4) Encrypt it with ML-KEM+XChaCha20, 5) Call submit_encrypted(commitment, ciphertext). The next block author decrypts and executes your swap, but they announced their key before seeing your encrypted submission.
Common Questions
- What if decryption fails?
- The validator calls mark_decryption_failed and DecryptionFailed event fires. Your transaction doesn't execute, but this is rare - usually only from client-side encryption bugs.
- Do I need to adjust my nonce?
- Yes — this is a common trap. The outer submit_encrypted call uses nonce N, but the inner transaction must use nonce N+1 (since the outer call increments the account nonce first). Step by step for direct callers: 1) Query system.account for current nonce N, 2) Sign the inner extrinsic with nonce N+1, 3) Hash it to create commitment, 4) Encrypt the signed inner extrinsic, 5) Sign submit_encrypted with nonce N.
- Can I use this with hotkey-signed transactions?
- No. MEV Shield requires the same coldkey to sign both the outer submit_encrypted call and the inner transaction. Per the official Bittensor documentation: "MEV shield should not be used for transactions that are signed by a hotkey" as it "may result in unintended consequences that could result in asset loss."
- Is there extra cost for encrypted transactions?
- You pay normal transaction fees for submit_encrypted, plus the inner transaction fees when executed. The encryption overhead is minimal compared to MEV protection benefits.
Use Cases
- Protect large swaps from sandwich attacks
- Hide staking operations from front-runners
- Submit time-sensitive trades privately
- Build MEV-resistant DeFi applications
From Chain Metadata
Users submit an encrypted wrapper. Client‑side: 1. Read `NextKey` (ML‑KEM encapsulation key bytes) from storage. 2. Sign your extrinsic so that it can be executed when added to the pool, i.e. you may need to increment the nonce if you submit using the same account. 3. Encrypt: plaintext = signed_extrinsic key_hash = xxhash128(NextKey) kem_len = Length of kem_ct in bytes (u16) kem_ct = Ciphertext from ML‑KEM‑768 nonce = Random 24 bytes used for XChaCha20‑Poly1305 aead_ct = Ciphertext from XChaCha20‑Poly1305 with ML‑KEM‑768 + XChaCha20‑Poly1305, producing ciphertext = key_hash || kem_len || kem_ct || nonce || aead_ct
Input Parameters
| # | Name | Type | Description |
|---|---|---|---|
| 0 | ciphertext | BoundedVec | ciphertext (BoundedVec) |
Permissions
Permission data inferred from metadata. May be incomplete.
Requirements
- NextKey is available in storage (key has been announced)
- Commitment matches hash of the encrypted inner transaction
- Ciphertext is valid ML-KEM + XChaCha20-Poly1305 format
- Submission with this ID doesn't already exist
Effects
Events Emitted
Storage Modified
Postconditions
- Submission stored in Submissions map
- EncryptedSubmitted event emitted
- Transaction queued for decryption by next block author
Side Effects
- User's nonce may need to be pre-incremented for inner transaction
- Submission tied to current epoch's key hash
Code Examples
import { ApiPromise, WsProvider } from "@polkadot/api";
import { stringCamelCase } from "@polkadot/util";
const provider = new WsProvider("wss://entrypoint-finney.opentensor.ai:443");
const api = await ApiPromise.create({ provider });
// Build submit_encrypted call
const ciphertext = 0 as any /* BoundedVec */;
const call = api.tx[stringCamelCase("MevShield")][stringCamelCase("submit_encrypted")](
ciphertext
);On-Chain Activity
Significant regular use
#32 most used call
Over 95% of submissions succeed
As of block 7,429,232
Version History
Runtime Info
View Source- Pallet Index
- 30
- Call Index
- 1
- First Version
- v361
- Current Version
- v393