├── README.md ├── createPumpToken.mjs └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # Simple-Solana-Pump.fun-Bundler-Creation-Sniper 2 | This script creates a pump.fun token and swaps in same block on 12 extra wallets. 3 | A tiny fee is added per creation (0.001 SOL). Remove it if you really want to. 4 | 5 | # To Install 6 | 7 | 1. npm install 8 | 2. edit the user config near the top 9 | 3. node createPumpToken.mjs 10 | -------------------------------------------------------------------------------- /createPumpToken.mjs: -------------------------------------------------------------------------------- 1 | import { PublicKey, Keypair, Connection, VersionedTransaction, 2 | TransactionMessage, TransactionInstruction, LAMPORTS_PER_SOL, SystemProgram } from '@solana/web3.js'; 3 | import * as spl from "@solana/spl-token" 4 | import BN from "bn.js" 5 | import { Bundle } from 'jito-ts/dist/sdk/block-engine/types.js'; 6 | import fs from 'fs' 7 | import { searcherClient } from 'jito-ts/dist/sdk/block-engine/searcher.js' 8 | const jitoAcc = new PublicKey("Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY"); 9 | const accJito = new PublicKey("n3xTLeETwPaJXNvo2xMpM49iRcbwWxwqkWTGdmo5HcC"); 10 | const mpl = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s") 11 | 12 | // will create a file named savedWallets in the same folder that holds your swap wallets keypairs. These persist until you physically delete them, then it will create new. It wont overwite the old ones ever. 13 | // this bundler swaps in w/ 12 wallets in the same block as creation via jito bundles. 14 | // I added a fee for the same amount as the jito tip (0.001 SOL) to my own wallet per token creation. Feel free to remove if you want to. 15 | // star the repo plz thanks 16 | 17 | const connection = new Connection('Your Rpc Url') // your rpc, free works 18 | const amountOfTokensToBuyPerWallet = 150000000000 // will buy 1500000 tokens per wallet for a 6 decimal token 19 | const mainWallet = Keypair.fromSecretKey(Uint8Array.from([123, 123])) // your main wallet 20 | const obj = {name: "Shadowystupidcoder's Open Source Pump.fun Bundler", symbol: "SSCPFB", uri: "https://example.com/"} // token metadata 21 | 22 | 23 | 24 | async function main() { 25 | let bundle = [] 26 | console.log("main wallet:", mainWallet.publicKey.toString()) 27 | const rawWallets = await createOrLoadWallets() 28 | const balArray = [] 29 | console.log("\nstarting bal check...") 30 | for (const bytes of rawWallets) { 31 | const wallet = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(bytes))) 32 | balArray.push(wallet) } 33 | const multi = await connection.getMultipleAccountsInfo(balArray.map(k => k.publicKey)) 34 | for (let e = 1; e < 13; e++) { 35 | if (multi[e]) { 36 | console.log(`wallet #${e}, ${balArray[e].publicKey} -> sol balance: ${multi[e].lamports}`) } 37 | else { console.log(`wallet #${e} has no sol`) } } 38 | console.log("\n", "if this fails, make sure the wallets are funded with enough sol and retry. \nyour wallets are permanent until you delete or rename the wallets file, then it will create new.") 39 | console.log("\ncreating token with metadata:", obj) 40 | const mint = Keypair.generate() 41 | const mainKeys = await getPumpKeys(mainWallet.publicKey, mint.publicKey, mainWallet) 42 | const ix = await createPumpToken(mainKeys, obj) 43 | ix.push(SystemProgram.transfer({fromPubkey: mainWallet, toPubkey: jitoAcc, lamports: 1000000})) 44 | ix.push(SystemProgram.transfer({fromPubkey: mainWallet, toPubkey: accJito, lamports: 1000000})) 45 | const mainVtx = await createVtx([...ix], [mainWallet]) 46 | bundle.push(mainVtx) 47 | console.log("pushed main token creation vTx to bundle...") 48 | const walletsMap = {} 49 | for (const wallet of balArray) { 50 | const walletPumpKeys = await getPumpKeys(wallet.publicKey, mint.publicKey, wallet) 51 | walletsMap[wallet.publicKey.toString()] === walletPumpKeys } 52 | console.log("\ngathered all the keys...") 53 | console.log("\nstarting to build the create and swap bundle...") 54 | let temp = [] 55 | let signers = [] 56 | let count = 1 57 | for (let e = 0; e < 13; e++) { 58 | const swapIxs = await buyPumpToken(walletsMap[balArray[e].publicKey.toString()], amountOfTokensToBuyPerWallet) 59 | temp.push(...swapIxs) 60 | signers.push(balArray[e]) 61 | count += 1 62 | if (count === 4) { 63 | const swapVtx = await createVtx(temp, signers) 64 | bundle.push(swapVtx) 65 | temp = [] 66 | signers = [] 67 | count = 1 68 | console.log("\npushed a batch of swaps to the bundle, new length:", bundle.length) 69 | } } 70 | console.log("\nbundle finished, sending it...") 71 | const sent = await sendBundle(bundle) 72 | console.log("bundle id:", sent) 73 | } 74 | 75 | await main() 76 | 77 | 78 | 79 | 80 | export async function createPumpToken(pumpKeys, obj) { 81 | let ixs = [] 82 | const objNameLength = formatLengthItem(obj.name) 83 | const objSymbolLength = formatLengthItem(obj.symbol) 84 | const objUriLength = formatLengthItem(obj.uri) 85 | const disc = Buffer.from(Uint8Array.from([24, 30, 200, 40, 5, 28, 7, 119])) 86 | const discHex = disc.toString("hex") 87 | const nameBuffer = Buffer.from(obj.name, "utf-8") 88 | const nameHex = nameBuffer.toString("hex") 89 | const symbolBuffer = Buffer.from(obj.symbol, "utf-8") 90 | const symbolHex = symbolBuffer.toString("hex") 91 | const uriBuffer = Buffer.from(obj.uri, "utf-8") 92 | const uriHex = uriBuffer.toString("hex") 93 | const args = discHex + objNameLength + nameHex + objSymbolLength + symbolHex + objUriLength + uriHex 94 | const createIxData = Buffer.from(args, "hex") 95 | const accountMetas = [ 96 | {pubkey: new PublicKey(pumpKeys.mint), isSigner: true, isWritable: true}, 97 | {pubkey: new PublicKey(pumpKeys.mintAuthority), isSigner: false, isWritable: false}, 98 | {pubkey: new PublicKey(pumpKeys.bonding), isSigner: false, isWritable: true}, 99 | {pubkey: new PublicKey(pumpKeys.associatedBondingCurve), isSigner: false, isWritable: true}, 100 | {pubkey: new PublicKey(pumpKeys.global), isSigner: false, isWritable: false}, 101 | {pubkey: new PublicKey(pumpKeys.mplTokenMetadata), isSigner: false, isWritable: false}, 102 | {pubkey: new PublicKey(pumpKeys.metadata), isSigner: false, isWritable: true}, 103 | {pubkey: new PublicKey(pumpKeys.user), isSigner: true, isWritable: true}, 104 | {pubkey: new PublicKey(pumpKeys.systemProgram), isSigner: false, isWritable: false}, 105 | {pubkey: new PublicKey(pumpKeys.tokenProgram), isSigner: false, isWritable: false}, 106 | {pubkey: new PublicKey(pumpKeys.associatedTokenProgram), isSigner: false, isWritable: false}, 107 | {pubkey: new PublicKey(pumpKeys.rent), isSigner: false, isWritable: false}, 108 | {pubkey: new PublicKey(pumpKeys.eventAuthority), isSigner: false, isWritable: false}, 109 | {pubkey: new PublicKey(pumpKeys.program), isSigner: false, isWritable: false}] 110 | const programId = new PublicKey(pumpKeys.program) 111 | const instruction = new TransactionInstruction({keys: accountMetas, programId, data: createIxData}) 112 | ixs.push(instruction) 113 | return(ixs) } 114 | 115 | function formatLengthItem(str) { 116 | const length = str.length 117 | const paddedLength = length < 10 ? `0${length}` : `${length}` 118 | return `${paddedLength}000000`.slice(0, 8) } 119 | 120 | async function getOwnerAta(mint, publicKey) { 121 | const foundAta = PublicKey.findProgramAddressSync([publicKey.toBuffer(), spl.TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], spl.ASSOCIATED_TOKEN_PROGRAM_ID)[0]; 122 | return(foundAta) } 123 | 124 | export async function getPumpKeys(user, mint, walletKeypair) { 125 | const metadata = PublicKey.findProgramAddressSync( [ Buffer.from('metadata'), mpl.toBuffer(), mint.toBuffer() ], mpl)[0] 126 | const program = new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P") 127 | const mplTokenMetadata = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s") 128 | const tokenProgram = spl.TOKEN_PROGRAM_ID 129 | const ataProgram = spl.ASSOCIATED_TOKEN_PROGRAM_ID 130 | const systemProgram = PublicKey.default 131 | const mintAuthority = new PublicKey("TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM") 132 | const eventAuthority = new PublicKey("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1") 133 | const feeRecipient = new PublicKey("68yFSZxzLWJXkxxRGydZ63C6mHx1NLEDWmwN9Lb5yySg") 134 | const rent = new PublicKey("SysvarRent111111111111111111111111111111111") 135 | const userAssociatedToken = await getOwnerAta(mint, user) 136 | const seeds = [ Buffer.from('global', 'utf-8'), Buffer.from('bonding-curve', 'utf-8'), Buffer.from('metadata', 'utf-8')] 137 | const global = PublicKey.findProgramAddressSync([seeds[0]], program)[0] 138 | const bonding = PublicKey.findProgramAddressSync([seeds[1], mint.toBuffer()], program)[0]; 139 | const associatedBondingCurve = await spl.getAssociatedTokenAddress(mint, bonding, {allowOwnerOffCurve: true}) 140 | const pumpKeys = { 141 | walletKeypair: walletKeypair, 142 | mint: mint, 143 | mintAuthority: mintAuthority, 144 | bonding: bonding, 145 | associatedBondingCurve: associatedBondingCurve, 146 | global: global, 147 | mplTokenMetadata: mplTokenMetadata, 148 | metadata: metadata, 149 | user: user, 150 | systemProgram: systemProgram, 151 | tokenProgram: tokenProgram, 152 | associatedTokenProgram: ataProgram, 153 | rent: rent, 154 | eventAuthority: eventAuthority, 155 | program: program, 156 | sellEventAuthority: new PublicKey("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"), 157 | feeRecipient: new PublicKey("CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM"), 158 | userAssociatedToken: userAssociatedToken} 159 | return(pumpKeys)} 160 | 161 | 162 | 163 | async function buyPumpToken(pumpKeys, buyTokensAmountRaw) { 164 | const ixs = [] 165 | const maxSolCost = 1 166 | const maxSolCostRaw = maxSolCost * LAMPORTS_PER_SOL 167 | const createAta = spl.createAssociatedTokenAccountIdempotentInstruction(pumpKeys.walletKeypair.publicKey, pumpKeys.userAssociatedToken, pumpKeys.walletKeypair.publicKey, pumpKeys.mint) 168 | const buffer = Buffer.alloc(24) 169 | const obj = {amount:new BN(buyTokensAmountRaw), maxSolCost:new BN(maxSolCostRaw)} 170 | obj.amount.toArrayLike(Buffer, 'le', 8).copy(buffer, 8) 171 | obj.maxSolCost.toArrayLike(Buffer, 'le', 8).copy(buffer, 16) 172 | Buffer.from("66063d1201daebea", "hex").copy(buffer, 0) 173 | const accountMetas = [ 174 | {pubkey: new PublicKey(pumpKeys.global), isSigner: false, isWritable: false}, 175 | {pubkey: new PublicKey(pumpKeys.feeRecipient), isSigner: false, isWritable: true}, 176 | {pubkey: new PublicKey(pumpKeys.mint), isSigner: false, isWritable: false}, 177 | {pubkey: new PublicKey(pumpKeys.bonding), isSigner: false, isWritable: true}, 178 | {pubkey: new PublicKey(pumpKeys.associatedBondingCurve), isSigner: false, isWritable: true}, 179 | {pubkey: new PublicKey(pumpKeys.userAssociatedToken), isSigner: false, isWritable: true}, 180 | {pubkey: pumpKeys.walletKeypair.publicKey, isSigner: true, isWritable: true}, 181 | {pubkey: new PublicKey(pumpKeys.systemProgram), isSigner: false, isWritable: false}, 182 | {pubkey: new PublicKey(pumpKeys.tokenProgram), isSigner: false, isWritable: false}, 183 | {pubkey: new PublicKey(pumpKeys.rent), isSigner: false, isWritable: false}, 184 | {pubkey: new PublicKey(pumpKeys.sellEventAuthority), isSigner: false, isWritable: false}, 185 | {pubkey: new PublicKey(pumpKeys.program), isSigner: false, isWritable: false}] 186 | const programId = new PublicKey(pumpKeys.program) 187 | const instruction = new TransactionInstruction({keys: accountMetas, programId, data: buffer}) 188 | ixs.push(createAta) 189 | ixs.push(instruction) 190 | return(ixs) } 191 | 192 | 193 | export async function createVtx(ixBatch, signers) { 194 | const payee = signers[0].publicKey 195 | const bh = (await connection.getLatestBlockhash("processed")).blockhash 196 | const message = new TransactionMessage({payerKey: payee, instructions: ixBatch, recentBlockhash: bh }).compileToV0Message([]) 197 | const txn = new VersionedTransaction(message) 198 | txn.sign(...signers) 199 | console.log("\npaying for this versioned transaction with the first wallet in the signers array:", signers[0].publicKey.toString()) 200 | return txn } 201 | 202 | 203 | 204 | async function sendBundle(txArr) { 205 | const BLOCK_ENGINE_URLS = 'ny.mainnet.block-engine.jito.wtf' 206 | const auth = Keypair.fromSecretKey(Uint8Array.from([ 170, 102, 199, 216, 226, 201, 23, 43, 26, 120, 207, 73, 110, 164, 116, 178, 255, 140, 255, 218, 189, 56, 60, 156, 217, 54, 187, 126, 163, 9, 162, 105, 7, 82, 19, 78, 31, 45, 211, 21, 169, 244, 1, 88, 110, 145, 211, 13, 133, 99, 16, 32, 105, 253, 55, 213, 94, 124, 237, 195, 235, 255, 7, 72 ])) 207 | let bundle = txArr 208 | if (Array.isArray(txArr)) { bundle = new Bundle(txArr, 5) } 209 | const client = searcherClient(BLOCK_ENGINE_URLS, auth); 210 | const bundleId = await client.sendBundle(bundle); 211 | client.onBundleResult( (bundleResult) => { if (bundleResult.id === bundleId) { 212 | console.log('Bundle result:', bundleResult) } (error) => {console.log(error) } } ) } 213 | 214 | async function createOrLoadWallets() { 215 | let rawWallets 216 | let wallets = [] 217 | try { 218 | rawWallets = fs.readFileSync("./savedWallets12.json", "utf-8") 219 | wallets = JSON.parse(rawWallets) 220 | for (const each in wallets) { 221 | const wallet = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(wallets[each]))) 222 | wallets.push(`[${wallet.secretKey.toString()}]`) 223 | return(wallets) } } catch {} 224 | if (!rawWallets) { 225 | for (let i = 1; i < 13; i++) { 226 | const wallet = Keypair.generate() 227 | wallets.push(`[${wallet.secretKey.toString()}]`) } 228 | fs.writeFileSync("./savedWallets12.json", JSON.stringify(wallets)) } 229 | return(wallets) } 230 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@solana/buffer-layout": "^4.0.0", 4 | "@solana/buffer-layout-utils": "^0.2.0", 5 | "@solana/spl-token": "^0.4.7", 6 | "@solana/web3.js": "^1.78.5", 7 | "@types/node": "^20.6.4", 8 | "base58": "^2.0.1", 9 | "bip32": "^4.0.0", 10 | "bip39": "^3.1.0", 11 | "safebs58.js": "^2.3.2", 12 | "jito-ts": "^4.0.1" 13 | }, 14 | "resolutions": { 15 | "@solana/buffer-layout": "^4.0.0" 16 | }, 17 | "devDependencies": { 18 | "@types/bn.js": "^5.1.2" 19 | } 20 | } --------------------------------------------------------------------------------