Jito Bundles
The Trading API 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
- Python
- JavaScript
import requests
import base58
from solders.transaction import VersionedTransaction
from solders.keypair import Keypair
signerKeypairs = [
Keypair.from_base58_string("Wallet A base 58 private key here"),
Keypair.from_base58_string("Wallet B base 58 private key here")
# use up to 5 wallets
]
response = requests.post(
"https://pumpportal.fun/api/trade-local",
headers={"Content-Type": "application/json"},
json=[
{
"publicKey": str(signerKeypairs[0].pubkey()),
"action": "buy", # "buy", "sell", or "create"
"mint": "2xHkesAQteG9yz48SDaVAtKdFU6Bvdo9sXS3uQCbpump",
"denominatedInSol": "false",
"amount": 1000,
"slippage": 50,
"priorityFee": 0.0001, # priority fee on the first tx is used for jito tip
"pool": "pump"
},
{
"publicKey": str(signerKeypairs[1].pubkey()),
"action": "buy", # "buy", "sell", or "create"
"mint": "2xHkesAQteG9yz48SDaVAtKdFU6Bvdo9sXS3uQCbpump",
"denominatedInSol": "false",
"amount": 1000,
"slippage": 50,
"priorityFee": 0.0001, # priority fee after first tx is ignored
"pool": "pump"
}
# use up to 5 transactions
]
)
if response.status_code != 200:
print("Failed to generate transactions.")
print(response.reason)
else:
encodedTransactions = response.json()
encodedSignedTransactions = []
txSignatures = []
for index, encodedTransaction in enumerate(encodedTransactions):
signedTx = VersionedTransaction(VersionedTransaction.from_bytes(base58.b58decode(encodedTransaction)).message, [signerKeypairs[index]])
encodedSignedTransactions.append(base58.b58encode(bytes(signedTx)).decode())
txSignatures.append(str(signedTx.signatures[0]))
jito_response = requests.post(
"https://mainnet.block-engine.jito.wtf/api/v1/bundles",
headers={"Content-Type": "application/json"},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "sendBundle",
"params": [
encodedSignedTransactions
]
}
)
for i, signature in enumerate(txSignatures):
print(f'Transaction {i}: https://solscan.io/tx/{signature}')
import { VersionedTransaction, Connection, Keypair, sendAndConfirmTransaction} from '@solana/web3.js';
import bs58 from "bs58";
async function sendTransactionBundle(){
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
}
}
sendTransactionBundle();