Skip to main content

Jito Bundles

Local trading can be used to construct Jito bundles. Build trades as you otherwise would, except the JSON body in your request to PumpPortal should be an array of objects, as shown in the example below.

Denominating trade amounts in tokens, not SOL, is strongly recommended to prevent slippage from affecting bundled transactions.

See Token Creation for more advanced examples creating tokens with bundles.

Examples

import { VersionedTransaction, Connection, Keypair, sendAndConfirmTransaction} from '@solana/web3.js';
import bs58 from "bs58";

async function sendPortalLocalTransactionBundle(){
const signerKeyPairs = [
Keypair.fromSecretKey(bs58.decode("Wallet A base 58 private key here")),
Keypair.fromSecretKey(bs58.decode("Wallet B base 58 private key here")),
// use up to 5 wallets
];
const bundledTxArgs = [
{
publicKey: signerKeyPairs[0].publicKey.toBase58(),
"action": "buy", // "buy", "sell", or "create"
"mint": "2xHkesAQteG9yz48SDaVAtKdFU6Bvdo9sXS3uQCbpump",
"denominatedInSol": "false",
"amount": 1000000,
"slippage": 50,
"priorityFee": 0.00005, //priority fee on the first tx is used for jito tip
"pool": "pump"
},
{
publicKey: signerKeyPairs[1].publicKey.toBase58(),
"action": "buy", // "buy", "sell", or "create"
"mint": "2xHkesAQteG9yz48SDaVAtKdFU6Bvdo9sXS3uQCbpump",
"denominatedInSol": "false",
"amount": 1000000,
"slippage": 50,
"priorityFee": 0.0, //priority fee after first tx is ignored
"pool": "pump"
},
// use up to 5 transactions
];
const response = await fetch(`https://pumpportal.fun/api/trade-local`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(bundledTxArgs)
});
if(response.status === 200){ // successfully generated transaction
const transactions = await response.json();
console.log(transactions);
let encodedSignedTransactions = [];
let signatures = [];
for(let i = 0; i < bundledTxArgs.length; i++){ //decode and sign each tx
const tx = VersionedTransaction.deserialize(new Uint8Array(bs58.decode(transactions[i])));
tx.sign([signerKeyPairs[i]]);
encodedSignedTransactions.push(bs58.encode(tx.serialize()));
signatures.push(bs58.encode(tx.signatures[0]));
}

try{
const jitoResponse = await fetch(`https://mainnet.block-engine.jito.wtf/api/v1/bundles`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"jsonrpc": "2.0",
"id": 1,
"method": "sendBundle",
"params": [
encodedSignedTransactions
]
})
});
console.log(jitoResponse);
} catch(e){
console.error(e.message);
}
for(let i = 0; i < signatures.length; i++){
console.log(`Transaction ${i}: https://solscan.io/tx/${signatures[i]}`);
}
} else {
console.log(response.statusText); // log error
}
}
sendPortalLocalTransactionBundle();