Di part pertama, kita udah berhasil nge-setup "jalur komunikasi aman" kita. Di bagian ini, kita bakal masuk ke penulisan logika swap. Tugas kita adalah membuat transaksi untuk Uniswap V3 supaya nggak cuma jadi privat, tapi juga dijamin bakal tereksekusi.
1. Persiapan Transaksi Swap
Sebagai contoh, kita bakal jalanin swap ETH ke USDC. Biar transaksi ini valid buat masuk ke bundle, kita harus siapin objek transaksinya dari awal tanpa mengirimnya langsung ke jaringan.
Yang kita butuhin antara lain:
- Alamat Router Uniswap V3.
- ABI (paling nggak yang minimal) buat fungsi
exactInputSingle. - Perhitungan gas dengan mempertimbangkan prioritas.
Aturan Main: Dalam bundle Flashbots,
gasPricediganti samamaxFeePerGasdanmaxPriorityFeePerGas. Justru priorityFee (alias "uang kopi" buat validator) inilah yang nentuin apakah bundle kamu bakal masuk ke blok atau nggak.
2. Kode: Perakitan dan Simulasi
Kita tambahin file swap.ts ke project kita. Fokus utama di sini ada di method .simulate(). Ini adalah "fitur maut" dari Flashbots yang ngebolehin kita ngecek eksekusi transaksi di kondisi blockchain saat ini tanpa perlu bakar duit buat gas beneran.
import { ethers } from "ethers";
import { FlashbotsBundleRawTransaction } from "@flashbots/ethers-provider-bundle";
// ABI minimal buat interaksi sama Router Uniswap V3
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. Bentuk interface dan data transaksi
const iface = new ethers.Interface(ROUTER_ABI);
const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 menit
const amountIn = ethers.parseEther("0.1"); // Swap 0.1 ETH
const params = {
tokenIn: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
fee: 3000, // 0.3%
recipient: wallet.address,
deadline: deadline,
amountIn: amountIn,
amountOutMinimum: 0, // Di production, selalu hitung slippage!
sqrtPriceLimitX96: 0
};
const data = iface.encodeFunctionData("exactInputSingle", [params]);
// 2. Struktur transaksi
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"), // "Sogokan" buat validator
nonce: await wallet.getNonce()
};
// 3. Buat bundle yang sudah ditandatangani
const signedBundle = await flashbotsProvider.signBundle([
{
signer: wallet,
transaction: transaction
}
]);
// 4. SIMULASI (Tahap paling krusial)
console.log("Menjalankan simulasi bundle...");
const simulation = await flashbotsProvider.simulate(signedBundle, nextBlockNumber);
if ("error" in simulation) {
console.error(`Gagal simulasi: ${simulation.error.message}`);
return;
}
console.log("Simulasi aman jaya!", JSON.stringify(simulation, null, 2));
return signedBundle;
}
3. Sisi Teknis: Kenapa simulasi itu wajib?
Di mempool "publik", kalau transaksi kamu gagal (misalnya karena gas limit nggak cukup atau harga berubah), transaksi itu tetep bakal masuk blok dan kamu tetep bayar gas.
Di dunia Flashbots:
- Kalau simulasi nunjukkin error — kamu tinggal nggak usah kirim bundle-nya. Beres.
- Kalau bundle sudah dikirim tapi kondisi di blok berubah dan transaksi jadi nggak menguntungkan — validator bakal nyuekin gitu aja.
Intinya: Kamu cuma bayar gas kalau Stealth Swap kamu bener-bener tereksekusi.
4. Cara nentuin "Sogokan" (Priority Fee)
Validator bakal masukin bundle berdasarkan seberapa cuan bundle itu buat mereka. Keuntungan bundle (Gas Price Score) dihitung kayak gini:

Kalau kamu cuma swap biasa, maxPriorityFeePerGas sebesar 1-2 gwei biasanya udah cukup. Tapi pas volatilitas lagi tinggi, persaingan buat dapet jatah di blok bakal makin ketat, bahkan di jalur privat sekalipun.
Sampai mana kita sekarang?
Kita udah punya bundle yang sudah ditandatangani dan diverifikasi, siap buat gaspol. Kita tahu pasti kalau kode Uniswap bakal jalan bener, dan saldo dompet cukup buat nutupin semua biayanya.
Di bagian berikutnya (dan terakhir): kita bakal bikin loop buat nunggu blok, eksekusi pengiriman bundle beneran, dan bikin interface CLI yang simpel buat tool kita ini.