Bundle
Last updated
Last updated
POST
/trade/local/bundle
Create local transactions to execute a jito bundle.
Body
tip
number ≥ 0.00001
No - defaults to 0.001
launch
object
No
swaps
object array (1-5 items, 1-4 if a launch is included)
Yes
Response
{
"transactions": [
{
"base64": "base 64 serialized transaction",
"action": "launch",
"signersNeeded": [
"public key of mint needing to sign",
"public key of dev wallet needing to sign"
]
},
{
"base64": "base 64 serialized transaction",
"action": "swap",
"signersNeeded": [
"public key of wallet needing to sign"
]
},
{
"base64": "base 64 serialized transaction",
"action": "swap",
"signersNeeded": [
"public key of wallet needing to sign"
]
},
{
"base64": "base 64 serialized transaction",
"action": "swap",
"signersNeeded": [
"public key of wallet needing to sign"
]
}
]
}
import { Keypair, VersionedTransaction } from "@solana/web3.js";
import bs58 from "bs58";
import fs from "fs";
import "dotenv/config";
//load wallets
const wallet1 = Keypair.fromSecretKey(bs58.decode("key 1"));
const wallet2 = Keypair.fromSecretKey(bs58.decode("key 2"));
const wallet3 = Keypair.fromSecretKey(bs58.decode("key 3"));
const wallet4 = Keypair.fromSecretKey(bs58.decode("key 4"));
const wallet5 = Keypair.fromSecretKey(bs58.decode("key 5"));
async function localBundle() {
// Create a random CA for the token
const mint = Keypair.generate();
// token metadata
const tokenMetadata = new FormData();
tokenMetadata.append("file", await fs.openAsBlob("./logo.png")); // Load image
tokenMetadata.append("name", "test name"); // Name of the token
tokenMetadata.append("symbol", "ticker"); // Symbol (ticker) of the token
tokenMetadata.append("description", "This is my description"); // Description of the token (optional)
tokenMetadata.append("twitter", "https://x.com/"); // Twitter link (optional)
tokenMetadata.append("telegram", "https://t.me/"); // Telegram link (optional)
tokenMetadata.append("website", "https://x.com"); // Website link (optional)
// Create IPFS metadata storage
const metadataResponse = await fetch("https://pump.fun/api/ipfs", {
method: "POST",
body: tokenMetadata,
});
const metadataResponseJSON = await metadataResponse.json();
const bundleParams = {
tip: 0.001, //essentialy priority fee for the bundle
launch: {
// launch params
publicKey: wallet1.publicKey.toBase58(), //dev wallet public key
mint: mint.publicKey.toBase58(), //ca of the token
tokenMetadata: {
name: metadataResponseJSON.metadata.name, //keep this as is
symbol: metadataResponseJSON.metadata.symbol, //keep this as is
uri: metadataResponseJSON.metadataUri, //keep this as is
},
amount: 0.01, // dev buy
ccy: "sol", // denomination of the amount
},
swaps: [
// trades
{
action: "buy",
publicKey: wallet2.publicKey.toBase58(), //dev wallet public key
mint: mint.publicKey.toBase58(), //ca of the token
amount: 0.01, // amount of the token to swap
ccy: "sol", // denomination of the amount
slippage: 50, // slippage tolerance for the swap, use high slippage for bundles since each buy will increase the price
pool: "pump", // we know the pool is pump since we are launching the coin
},
{
action: "buy",
publicKey: wallet3.publicKey.toBase58(),
mint: mint.publicKey.toBase58(),
amount: 0.01,
ccy: "sol",
slippage: 50,
pool: "pump",
},
{
action: "buy",
publicKey: wallet4.publicKey.toBase58(),
mint: mint.publicKey.toBase58(),
amount: 0.01,
ccy: "sol",
slippage: 50,
pool: "pump",
},
{
action: "buy",
publicKey: wallet5.publicKey.toBase58(),
mint: mint.publicKey.toBase58(),
amount: 0.01,
ccy: "sol",
slippage: 50,
pool: "pump",
},
],
};
//create the transaction
const response = await fetch(`https://api.pumplify.fun/trade/local/bundle`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(bundleParams),
});
// Check if the response succeeded
if (!response.ok) {
// If the response is not ok, print the error
console.error("Bundle failed:", await response.json());
return;
}
// Get the array of transactions
const responseJSON = await response.json();
const rawTransactions = responseJSON.transactions;
if (!rawTransactions) {
console.error("No transactions returned");
return;
}
// Create an array of all the wallets and the mint to use for signing
const signers = [mint, wallet1, wallet2, wallet3, wallet4, wallet5];
// Create an array to store the signatures so we can look at the solscan txs later
let signatures: string[] = [];
const signedTransactions = rawTransactions.map(
(rawTx: { base64: string; signersNeeded: string[]; action: string }) => {
// Deserialize the transaction to interact with it
const txBuffer = Buffer.from(rawTx.base64, "base64");
const tx = VersionedTransaction.deserialize(new Uint8Array(txBuffer));
// Filter signers based on the required signers for this transaction
const requiredSigners = signers.filter((signer) =>
rawTx.signersNeeded.includes(signer.publicKey.toBase58())
);
// Sign the transaction
tx.sign(requiredSigners);
// Add the signature to the array
signatures.push(bs58.encode(tx.signatures[0]));
// Convert the signed transaction back to base64 for sending
return Buffer.from(tx.serialize()).toString("base64");
}
);
// Send the bundle
const bundleResponse = 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: [
signedTransactions,
{
encoding: "base64",
},
],
}),
}
);
// Check if the response succeeded
if (!bundleResponse.ok) {
// If the response is not ok, print the error
console.error("Bundle failed:", await bundleResponse.json());
return;
}
const bundleResponseJSON = await bundleResponse.json();
// Print the txs
signatures.map((signature, i) => {
console.log(`Tx ${i}: https://solscan.io/tx/${signature}`);
});
// Print the bundle explorer link
console.log(
`Bundle explorer (May take a few minutes to update): https://explorer.jito.wtf/bundle/${bundleResponseJSON.result}`
);
// Print the coin link
console.log(`Coin: https://pump.fun/coin/${mint.publicKey.toBase58()}`);
}
localBundle();
Essentially a priority fee. Reference ebst values at
Constructed body of what you would post to without the priority fee.
Array of constructed bodies of what you would post to without the priority fees.
What is a Jito Bundle?
A Jito bundle is a "bundle" of up to 5 transactions that will has the following features:
Sequential: The transactions are always executed in the order provided
Atomic: All transactions land in the same block
All or Nothing: If any of the transactions fail, all the transactions will be failed