Maximum Extractable Value (MEV) protection shields your transactions from front-running, sandwich attacks, and other forms of MEV extraction by routing them through OKX’s private transaction infrastructure.
What is MEV?
MEV (Maximum Extractable Value) refers to the profit that can be extracted by reordering, inserting, or censoring transactions within a block. Common MEV attacks include:
Front-running An attacker sees your pending transaction and submits a similar one with higher gas to execute first
Sandwich attacks An attacker places transactions before and after yours to profit from the price impact
Back-running An attacker executes a transaction immediately after yours to capitalize on price changes
Transaction reordering Miners or validators reorder transactions to maximize their profit
How MEV protection works
When you enable MEV protection, your transaction is:
Sent to OKX’s private mempool instead of the public mempool
Hidden from public searchers and MEV bots
Included directly in blocks by trusted validators
Protected from front-running and sandwich attacks
MEV protection requires API registration and whitelist approval. Contact [email protected] to request access.
Enabling MEV protection
To enable MEV protection, set enableMevProtection: true when broadcasting your transaction:
const broadcastResult = await client . dex . broadcastTransaction ({
signedTx: signedTransaction ,
chainIndex: '8453' ,
address: walletAddress ,
enableMevProtection: true // Enable MEV protection
});
Complete example
Here’s a complete swap workflow with MEV protection from the SDK source code:
import { OKXDexClient } from '@okx-dex/okx-dex-sdk' ;
import { ethers } from 'ethers' ;
import { createEVMWallet } from '@okx-dex/okx-dex-sdk/core/evm-wallet' ;
const provider = new ethers . JsonRpcProvider ( process . env . EVM_RPC_URL ! );
const wallet = createEVMWallet ( process . env . EVM_PRIVATE_KEY ! , provider );
const client = new OKXDexClient ({
apiKey: process . env . OKX_API_KEY ! ,
secretKey: process . env . OKX_SECRET_KEY ! ,
apiPassphrase: process . env . OKX_API_PASSPHRASE ! ,
projectId: process . env . OKX_PROJECT_ID ! ,
evm: { wallet }
});
const walletAddress = wallet . address ;
// Step 1: Get swap data
const swapData = await client . dex . getSwapData ({
chainIndex: '8453' ,
fromTokenAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' ,
toTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ,
amount: '3000000000000000' ,
slippagePercent: '0.05' ,
userWalletAddress: walletAddress
});
const txData = swapData . data [ 0 ]. tx ;
// Step 2: Sign the transaction
const nonce = await provider . getTransactionCount ( walletAddress );
const transaction = {
to: txData . to ,
value: txData . value ,
data: txData . data ,
gasLimit: txData . gas ,
gasPrice: txData . gasPrice ,
nonce: nonce ,
chainId: 8453
};
const signedTx = await wallet . signTransaction ( transaction );
// Step 3: Broadcast with MEV protection
const broadcastResult = await client . dex . broadcastTransaction ({
signedTx: signedTx ,
chainIndex: '8453' ,
address: walletAddress ,
enableMevProtection: true // Protected from MEV attacks
});
console . log ( 'Order ID:' , broadcastResult . data [ 0 ]. orderId );
console . log ( 'Transaction Hash:' , broadcastResult . data [ 0 ]. txHash );
When to use MEV protection
Use MEV protection for:
Large trades that create significant price impact
Time-sensitive swaps where front-running would be costly
High-value transactions (> $10,000 USD)
Volatile markets where sandwich attacks are common
Production applications serving end users
MEV protection may be optional for:
Small trades with minimal price impact
Testing environments where speed matters more
Stablecoin swaps with low volatility
Low-liquidity pairs where MEV is less profitable
Solana: Jito MEV protection
For Solana transactions, you can use Jito’s MEV protection by providing a Jito-signed transaction:
const broadcastResult = await client . dex . broadcastTransaction ({
signedTx: regularSignedTx ,
chainIndex: '501' , // Solana
address: walletAddress ,
jitoSignedTx: jitoSignedTransaction // Jito bundle
});
Jito bundles provide MEV protection on Solana by guaranteeing transaction ordering within a bundle.
Monitoring protected transactions
Track your MEV-protected transactions using the order ID:
const orders = await client . dex . getTransactionOrders ({
orderId: broadcastResult . data [ 0 ]. orderId ,
chainIndex: '8453' ,
address: walletAddress
});
console . log ( 'Status:' , orders . data [ 0 ]. orders [ 0 ]. txStatus );
console . log ( 'Transaction Hash:' , orders . data [ 0 ]. orders [ 0 ]. txHash );
See the Order tracking guide for more details.
Cost considerations
MEV protection may involve additional fees depending on your API tier. Check with OKX for current pricing.
While MEV protection may have a small cost, it often saves money by preventing:
Front-running losses
Sandwich attack slippage
Failed transactions due to MEV
Unfavorable price execution
Best practices
Always use MEV protection in production applications to protect your users from MEV attacks. const isProduction = process . env . NODE_ENV === 'production' ;
const enableMevProtection = isProduction ; // Always true in production
await client . dex . broadcastTransaction ({
signedTx ,
chainIndex: '8453' ,
address: walletAddress ,
enableMevProtection
});
Combine with slippage protection
Use MEV protection together with appropriate slippage settings for maximum protection. const swapData = await client . dex . getSwapData ({
chainIndex: '8453' ,
fromTokenAddress ,
toTokenAddress ,
amount ,
slippagePercent: '0.005' , // 0.5% slippage
userWalletAddress
});
const signedTx = await wallet . signTransaction ( transaction );
await client . dex . broadcastTransaction ({
signedTx ,
chainIndex: '8453' ,
address: walletAddress ,
enableMevProtection: true // MEV + slippage protection
});
Monitor transaction status
Track your protected transactions to ensure they’re confirmed. const broadcastResult = await client . dex . broadcastTransaction ({
signedTx ,
chainIndex: '8453' ,
address: walletAddress ,
enableMevProtection: true
});
const orderId = broadcastResult . data [ 0 ]. orderId ;
// Poll for status
const pollStatus = async () => {
const orders = await client . dex . getTransactionOrders ({
orderId ,
chainIndex: '8453' ,
address: walletAddress
});
const status = orders . data [ 0 ]. orders [ 0 ]. txStatus ;
if ( status === '2' ) {
console . log ( '✅ Transaction confirmed!' );
} else if ( status === '3' ) {
console . error ( '❌ Transaction failed' );
} else {
setTimeout ( pollStatus , 3000 ); // Poll every 3 seconds
}
};
pollStatus ();
Comparison: With vs without MEV protection
Aspect Without Protection With MEV Protection Visibility Public mempool Private mempool Front-running risk High None Sandwich attacks Possible Prevented Price execution May be unfavorable Guaranteed Confirmation time Variable Typically faster Cost Gas only Gas + potential MEV fee
Next steps
Transaction broadcasting Learn about the complete broadcasting workflow
Order tracking Monitor your transaction status
Slippage protection Configure slippage tolerance
API reference View the complete API reference