submit_encrypted

Call Re-added v361 → v385, v391 → current Changed in v391 #1

Submits an encrypted transaction wrapper for MEV -protected execution.

View calls on chain

Click items to navigate. Pan and zoom to explore.

Used by: stakersvalidatorsdeveloperswallets

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

Part of: MEV Shield

Input Parameters

#NameTypeDescription
0
ciphertext
BoundedVec ciphertext (BoundedVec)

Permissions

Origin
Unknown
Required Role

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

Usage Frequency
●●●●○○ Active 100K–1M extrinsics

Significant regular use

#32 most used call

Success Rate Near-certain

Over 95% of submissions succeed

As of block 7,429,232

Version History

v361 block 7,063,679 2 args
v391 block 7,782,857 1 args Current

Runtime Info

View Source
Pallet Index
30
Call Index
1
First Version
v361
Current Version
v393