पहले पार्ट में, हमने अपना "सिक्योर कम्युनिकेशन चैनल" सेटअप कर लिया था। इस भाग में, हम स्वैप लॉजिक (swap logic) लिखने जा रहे हैं। हमारा काम Uniswap V3 के लिए एक ऐसा ट्रांजैक्शन तैयार करना है जो न केवल प्राइवेट हो, बल्कि उसके सफल होने की पक्की गारंटी भी हो।
1. स्वैप ट्रांजैक्शन की तैयारी
उदाहरण के लिए, हम ETH से USDC का स्वैप सेट करेंगे। बंडल (bundle) के लिए ट्रांजैक्शन को वैलिड बनाने के लिए, हमें ट्रांजैक्शन ऑब्जेक्ट को पहले से तैयार करना होगा, बिना इसे सीधे नेटवर्क पर भेजे।
हमें इन चीजों की जरूरत होगी:
- Uniswap V3 Router का एड्रेस।
exactInputSingleफंक्शन के लिए ABI (कम से कम मिनिमल वाला)।- प्रायोरिटी (priority) को ध्यान में रखते हुए गैस का कैलकुलेशन।
खास नियम: Flashbots बंडलों में, स्टैंडर्ड
gasPriceकोmaxFeePerGasऔरmaxPriorityFeePerGasसे बदल दिया जाता है। असल में यह priorityFee (वैलिडेटर के लिए "बख्शीश") ही तय करती है कि आपका बंडल ब्लॉक में जगह बना पाएगा या नहीं।
2. कोड: असेंबली और सिमुलेशन
आइए अपने प्रोजेक्ट में swap.ts फाइल जोड़ते हैं। यहाँ सबसे ज्यादा ध्यान .simulate() मेथड पर दिया गया है। यह Flashbots का "किलर फीचर" है, जो आपको असली गैस पर एक पैसा भी खर्च किए बिना, ब्लॉकचेन की मौजूदा स्थिति पर ट्रांजैक्शन चलाकर देखने की अनुमति देता है।
import { ethers } from "ethers";
import { FlashbotsBundleRawTransaction } from "@flashbots/ethers-provider-bundle";
// Uniswap V3 Router के साथ इंटरैक्ट करने के लिए मिनिमल ABI
const ROUTER_ABI = [
"function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountOut)"
];
const ROUTER_ADDRESS = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
export async function createAndSimulateBundle(wallet: ethers.Wallet, flashbotsProvider: any, provider: ethers.Provider) {
const block = await provider.getBlock("latest");
const nextBlockNumber = block!.number + 1;
// 1. इंटरफ़ेस सेट करें और ट्रांजैक्शन डेटा तैयार करें
const iface = new ethers.Interface(ROUTER_ABI);
const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 मिनट का समय
const amountIn = ethers.parseEther("0.1"); // 0.1 ETH स्वैप कर रहे हैं
const params = {
tokenIn: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
fee: 3000, // 0.3% पूल
recipient: wallet.address,
deadline: deadline,
amountIn: amountIn,
amountOutMinimum: 0, // प्रोडक्शन में, हमेशा स्लिपेज (slippage) कैलकुलेट करें!
sqrtPriceLimitX96: 0
};
const data = iface.encodeFunctionData("exactInputSingle", [params]);
// 2. ट्रांजैक्शन का स्ट्रक्चर
const transaction = {
to: ROUTER_ADDRESS,
value: amountIn,
data: data,
chainId: 1,
type: 2, // EIP-1559
gasLimit: 250000,
maxFeePerGas: ethers.parseUnits("50", "gwei"),
maxPriorityFeePerGas: ethers.parseUnits("2", "gwei"), // वैलिडेटर के लिए "रिश्वत"
nonce: await wallet.getNonce()
};
// 3. साइन्ड बंडल (signed bundle) तैयार करें
const signedBundle = await flashbotsProvider.signBundle([
{
signer: wallet,
transaction: transaction
}
]);
// 4. सिमुलेशन (सबसे जरूरी स्टेप)
console.log("बंडल सिमुलेशन शुरू हो रहा है...");
const simulation = await flashbotsProvider.simulate(signedBundle, nextBlockNumber);
if ("error" in simulation) {
console.error(`सिमुलेशन फेल हो गया: ${simulation.error.message}`);
return;
}
console.log("सिमुलेशन एकदम सही है!", JSON.stringify(simulation, null, 2));
return signedBundle;
}
3. टेक्निकल बात: सिमुलेशन क्यों जरूरी है?
"पब्लिक" मेमपूल (mempool) में, अगर आपका ट्रांजैक्शन फेल हो जाता है (जैसे गैस लिमिट कम होना या कीमत बदल जाना), तो भी वह ब्लॉक में शामिल हो जाता है और आपको गैस फीस भरनी पड़ती है।
Flashbots की दुनिया में:
- अगर सिमुलेशन में कोई एरर आता है — तो आप बस बंडल भेजते ही नहीं। कोई नुकसान नहीं।
- अगर बंडल भेज दिया गया है लेकिन ब्लॉक में परिस्थितियाँ बदल गईं और ट्रांजैक्शन घाटे का सौदा बन गया — तो वैलिडेटर उसे बस इग्नोर कर देगा।
नतीजा: आप गैस फीस तभी देते हैं जब आपका Stealth Swap वाकई में कामयाब होता है।
4. "रिश्वत" (Priority Fee) कैसे तय करें
वैलिडेटर बंडलों को इस आधार पर चुनते हैं कि उन्हें उससे कितना मुनाफा हो रहा है। बंडल के मुनाफे (Gas Price Score) का हिसाब ऐसे लगाया जाता है:

अगर आप एक नॉर्मल स्वैप कर रहे हैं, तो 1-2 gwei की maxPriorityFeePerGas आमतौर पर काफी होती है। लेकिन जब मार्केट में बहुत ज्यादा हलचल (volatility) होती है, तो ब्लॉक में जगह पाने की होड़ बढ़ जाती है, यहाँ तक कि इन प्राइवेट रास्तों पर भी।
अभी हम कहाँ तक पहुँचे?
हमारे पास अब एक साइन्ड और वेरीफाइड बंडल है जो भेजे जाने के लिए तैयार है। हमें पक्का पता है कि Uniswap कोड सही से काम करेगा और वॉलेट में सारा खर्चा उठाने के लिए काफी बैलेंस है।
अगले (और आखिरी) भाग में: हम ब्लॉक का इंतजार करने वाला लूप लिखेंगे, बंडल को असली में भेजने का काम करेंगे और अपने टूल के लिए एक बढ़िया CLI इंटरफ़ेस बनाएंगे।