import {
Connection,
Keypair,
PublicKey,
SystemProgram,
TransactionMessage,
VersionedTransaction,
TransactionInstruction,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
import bs58 from "bs58";
import "dotenv/config";
// Use your Chainstack endpoint for reads
const connection = new Connection(process.env.SOLANA_RPC!);
const payer = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY!));
// Jito block engine for sends
const JITO_ENDPOINT =
"https://mainnet.block-engine.jito.wtf/api/v1/transactions";
// Any valid pubkey starting with "jitodontfront". Does not need to exist on-chain.
const DONT_FRONT = new PublicKey(
"jitodontfront111111111111111111111111111111"
);
// Jito tip accounts — pick one at random to reduce contention
const TIP_ACCOUNTS = [
"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe",
"Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY",
"ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49",
"DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh",
"ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt",
"DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL",
"3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT",
];
function addDontFront(instruction: TransactionInstruction): TransactionInstruction {
return new TransactionInstruction({
...instruction,
keys: [
...instruction.keys,
{ pubkey: DONT_FRONT, isSigner: false, isWritable: false },
],
});
}
function randomTipAccount(): PublicKey {
const idx = Math.floor(Math.random() * TIP_ACCOUNTS.length);
return new PublicKey(TIP_ACCOUNTS[idx]);
}
async function sendWithMEVProtection() {
const latestBlockhash = await connection.getLatestBlockhash();
// Your actual instruction — add dontfront to it
const transferIx = addDontFront(
SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: payer.publicKey,
lamports: 0.001 * LAMPORTS_PER_SOL,
})
);
// Jito tip — minimum 1000 lamports
const tipIx = SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: randomTipAccount(),
lamports: 1000,
});
const message = new TransactionMessage({
payerKey: payer.publicKey,
recentBlockhash: latestBlockhash.blockhash,
instructions: [transferIx, tipIx],
}).compileToV0Message();
const transaction = new VersionedTransaction(message);
transaction.sign([payer]);
// Send through Jito block engine, NOT standard RPC
const serialized = Buffer.from(transaction.serialize()).toString("base64");
const response = await fetch(JITO_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "sendTransaction",
params: [serialized, { encoding: "base64" }],
}),
});
const result = await response.json();
console.log("Sent with dontfront protection:", result.result);
}
sendWithMEVProtection();