├── .npmignore ├── .env.example ├── upload ├── bolt.jpg ├── logo-light.png └── metadata.json ├── src ├── IDL │ ├── index.ts │ ├── pump-fun.ts │ └── pump-fun.json ├── index.ts ├── metadata.ts ├── config.ts ├── constants.ts ├── events.ts ├── types.ts ├── uploadToIpfs.ts ├── globalAccount.ts ├── amm.ts ├── jito.ts ├── bondingCurveAccount.ts ├── jitoWithAxios.ts ├── util.ts └── pumpfun.ts ├── .gitignore ├── tsconfig.cjs.json ├── tsconfig.json ├── example ├── basic │ ├── burnToken.ts │ ├── gen-keypair.ts │ └── index.ts ├── events │ └── index.ts └── util.ts ├── tsconfig.base.json ├── rollup.config.js ├── LICENSE ├── package.json └── Readme.md /.npmignore: -------------------------------------------------------------------------------- 1 | example/ -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | HELIUS_RPC_URL='' -------------------------------------------------------------------------------- /upload/bolt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-bundler-bot/HEAD/upload/bolt.jpg -------------------------------------------------------------------------------- /src/IDL/index.ts: -------------------------------------------------------------------------------- 1 | export { default as IDL } from "./pump-fun.json"; 2 | export { PumpFun } from "./pump-fun"; -------------------------------------------------------------------------------- /upload/logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-bundler-bot/HEAD/upload/logo-light.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .anchor 2 | .DS_Store 3 | target 4 | **/*.rs.bk 5 | node_modules 6 | test-ledger 7 | .yarn 8 | 9 | dist/ 10 | 11 | .keys*/ 12 | .keys*/** 13 | 14 | .env 15 | refs/ -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './pumpfun' 2 | export * from './util' 3 | export * from './types' 4 | export * from './events' 5 | export * from './globalAccount' 6 | export * from './bondingCurveAccount' 7 | export * from './amm' 8 | -------------------------------------------------------------------------------- /tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "es2022", 6 | "outDir": "dist/cjs/", 7 | "rootDir": "./src", 8 | } 9 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "moduleResolution": "node", 5 | "module": "es2022", 6 | "target": "es2022", 7 | "outDir": "dist/esm/", 8 | "rootDir": "./src", 9 | } 10 | } -------------------------------------------------------------------------------- /upload/metadata.json: -------------------------------------------------------------------------------- 1 | {"name":"LB Token","symbol":"LBtoken","description":"Lendon Bracewell","image":"https://cf-ipfs.com/ipfs/bafkreie7pjegykwmpduhmnqh4joe6dqlcqy6w2bwkykvnzh7qknmhswcee","showName":true,"createdOn":"https://pump.fun","twitter":"https://x.com/pepa_inu","telegram":"https://t.me/pepaonsols","website":"https://www.pepa-inu.com"} -------------------------------------------------------------------------------- /src/metadata.ts: -------------------------------------------------------------------------------- 1 | const metadata = { 2 | "name": "Bolt token", 3 | "symbol": "Bolt2", 4 | "description": "Brave Veer & Bolt", 5 | "image": "", 6 | "showName": true, 7 | "createdOn": "https://pump.fun", 8 | "twitter": "https://x.com/pepa_inu", 9 | "telegram": "https://t.me/pepaonsols", 10 | "website": "https://www.pepa-inu.com" 11 | } 12 | 13 | export default metadata; -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import { Commitment, PublicKey } from '@solana/web3.js'; 2 | import { Connection, Keypair } from '@solana/web3.js'; 3 | import * as bs58 from 'bs58'; 4 | 5 | export const rpc_https_url = "https://white-aged-glitter.solana-mainnet.quiknode.pro/743d4e1e3949c3127beb7f7815cf2ca9743b43a6/"; 6 | 7 | export const blockEngineUrl = 'tokyo.mainnet.block-engine.jito.wtf'; 8 | export const connection = new Connection(rpc_https_url, "confirmed"); 9 | export const global_mint = new PublicKey("p89evAyzjd9fphjJx7G3RFA48sbZdpGEppRcfRNpump") -------------------------------------------------------------------------------- /example/basic/burnToken.ts: -------------------------------------------------------------------------------- 1 | const requestBody = { 2 | mint: 'FP5SwaQvsJRMEqAjYbwMqhGwRDKE6RznXaSjwPof61k3', 3 | priorityFee: 0.001, 4 | userPrivateKey: '3qesJ12P92MTNfY3C4Sa8BKWEwRexASEx1RtNnaSZsQaUksVUuiHhvhsBx87SzJpxz3rs3ogu4ytsjSgNLKM7HiU' 5 | }; 6 | 7 | fetch('https://pumpapi.fun/api/burn_tokens', { 8 | method: 'POST', 9 | headers: { 'Content-Type': 'application/json' }, 10 | body: JSON.stringify(requestBody) 11 | }) 12 | .then(response => response.json()) 13 | .then(data => console.log(data)) 14 | .catch(error => console.error(error)); -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./src/**/*", "./src/**/*.json"], 3 | "compilerOptions": { 4 | "sourceMap": true, 5 | "declaration": true, 6 | "declarationMap": true, 7 | "allowSyntheticDefaultImports": true, 8 | "experimentalDecorators": true, 9 | "emitDecoratorMetadata": true, 10 | "noImplicitAny": false, 11 | "strictNullChecks": true, 12 | "esModuleInterop": true, 13 | "resolveJsonModule": true, 14 | "skipLibCheck": true 15 | }, 16 | "ts-node": { 17 | "compilerOptions": { 18 | "module": "commonjs" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from "@rollup/plugin-node-resolve"; 2 | import typescript from "@rollup/plugin-typescript"; 3 | import commonjs from "@rollup/plugin-commonjs"; 4 | import json from "@rollup/plugin-json"; 5 | 6 | export default { 7 | input: "src/index.ts", 8 | plugins: [ 9 | commonjs(), 10 | json(), 11 | nodeResolve({ 12 | browser: true, 13 | extensions: [".js", ".ts"], 14 | preferBuiltins: false, 15 | }), 16 | typescript({ 17 | tsconfig: "./tsconfig.base.json", 18 | moduleResolution: "node", 19 | outDir: "types", 20 | target: "es2022", 21 | outputToFilesystem: false, 22 | }), 23 | ], 24 | external: [ 25 | "@coral-xyz/borsh", 26 | "@solana/web3.js", 27 | "@solana/spl-token" 28 | ], 29 | output: { 30 | file: "dist/browser/index.js", 31 | format: "es", 32 | sourcemap: true, 33 | }, 34 | }; -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const RPC_ENDPOINT = "https://white-aged-glitter.solana-mainnet.quiknode.pro/743d4e1e3949c3127beb7f7815cf2ca9743b43a6/" 2 | export const RPC_WEBSOCKET_ENDPOINT = "wss://white-aged-glitter.solana-mainnet.quiknode.pro/743d4e1e3949c3127beb7f7815cf2ca9743b43a6/" 3 | export const JITO_FEE = 5000000 4 | export const COMMITMENT_LEVEL = "confirmed" 5 | export const JITO_KEY="66xqL9aFZJ8k9YpjNBexNASfuoDgNE1ZpGRXB28zoTfS4u2czzVBhMNMqgZYFeMN8FnUi6gMzXWgVYRHkTZ6yuLC" 6 | export const BLOCKENGINE_URL="tokyo.mainnet.block-engine.jito.wtf" 7 | export const JITO_AUTH_KEYPAIR = "66xqL9aFZJ8k9YpjNBexNASfuoDgNE1ZpGRXB28zoTfS4u2czzVBhMNMqgZYFeMN8FnUi6gMzXWgVYRHkTZ6yuLC" 8 | export const CHECK_FILTER=true 9 | export const CHECK_SOCIAL=true 10 | export const CHECK_NAMEWHITELIST=false 11 | export const CHECK_NAMEBLACKLIST=false 12 | export const CHECK_WALLETWHITELIST=false 13 | export const CHECK_WALLETBLACKLIST=false 14 | export const CHECK_SOLDBALANCE=true 15 | export const USE_SNIPE_LIST=false 16 | export const JITO_MODE = true 17 | export const JITO_ALL = false 18 | export const stop_loss=-0.1 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /example/basic/gen-keypair.ts: -------------------------------------------------------------------------------- 1 | import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes'; 2 | import * as web3 from '@solana/web3.js'; 3 | import fs from "fs"; 4 | 5 | async function createKeypair() { 6 | // Generate a new keypair 7 | const keypair = web3.Keypair.generate(); 8 | 9 | // Extract the public key and secret key 10 | const publicKey = keypair.publicKey; 11 | const secretKey = keypair.secretKey; 12 | 13 | // Convert keys to base58 strings (for display or storage) 14 | const publicKeyBase58 = publicKey.toBase58(); 15 | const secretKeyBase58 = bs58.encode(secretKey); 16 | 17 | // Print out the keys (for demonstration purposes) 18 | console.log('Public Key:', publicKeyBase58); 19 | console.log('Secret Key:', secretKeyBase58); 20 | 21 | const data = { 22 | "publicKey": publicKeyBase58, 23 | "secretKey": secretKeyBase58 24 | } 25 | const metadataString = JSON.stringify(data); 26 | const bufferContent = Buffer.from(metadataString, 'utf-8'); 27 | fs.writeFileSync("./example/basic/.keys/mint.json", bufferContent); 28 | return keypair; // Return the keypair object if needed 29 | } 30 | 31 | createKeypair() -------------------------------------------------------------------------------- /example/events/index.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import { Connection, Keypair } from "@solana/web3.js"; 3 | import { PumpFunSDK } from "../../src"; 4 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 5 | import { AnchorProvider } from "@coral-xyz/anchor"; 6 | 7 | const main = async () => { 8 | dotenv.config(); 9 | 10 | if (!process.env.HELIUS_RPC_URL) { 11 | console.error("Please set HELIUS_RPC_URL in .env file"); 12 | console.error( 13 | "Example: HELIUS_RPC_URL=https://mainnet.helius-rpc.com/?api-key=" 14 | ); 15 | console.error("Get one at: https://www.helius.dev"); 16 | return; 17 | } 18 | 19 | let connection = new Connection(process.env.HELIUS_RPC_URL || ""); 20 | 21 | let wallet = new NodeWallet(new Keypair()); //note this is not used 22 | const provider = new AnchorProvider(connection, wallet, { 23 | commitment: "finalized", 24 | }); 25 | 26 | let sdk = new PumpFunSDK(provider); 27 | 28 | let createEvent = sdk.addEventListener("createEvent", (event) => { 29 | console.log("createEvent", event); 30 | }); 31 | console.log("createEvent", createEvent); 32 | 33 | let tradeEvent = sdk.addEventListener("tradeEvent", (event) => { 34 | console.log("tradeEvent", event); 35 | }); 36 | console.log("tradeEvent", tradeEvent); 37 | 38 | let completeEvent = sdk.addEventListener("completeEvent", (event) => { 39 | console.log("completeEvent", event); 40 | }); 41 | console.log("completeEvent", completeEvent); 42 | }; 43 | 44 | main(); 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pumpdotfun-bundler", 3 | "author": "topsecretagent007", 4 | "scripts": { 5 | "test": "echo \"Error: no test specified\" && exit 1", 6 | "build": "rimraf dist/ && npm run build:node && npm run build:browser", 7 | "build:node": "tsc && tsc -p tsconfig.cjs.json", 8 | "build:browser": "rollup -c rollup.config.js --bundleConfigAsCjs", 9 | "start": "npx ts-node ./example/basic/index.ts" 10 | }, 11 | "files": [ 12 | "dist", 13 | "types" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/topsecretagent007/pumpfun-bundler-bot.git" 18 | }, 19 | "keywords": [ 20 | "pumpdotfun", 21 | "sdk", 22 | "solana" 23 | ], 24 | "license": "ISC", 25 | "devDependencies": { 26 | "@coral-xyz/borsh": "^0.30.1", 27 | "@rollup/plugin-commonjs": "^26.0.1", 28 | "@rollup/plugin-node-resolve": "^15.2.3", 29 | "@rollup/plugin-replace": "^5.0.7", 30 | "@rollup/plugin-typescript": "^11.1.6", 31 | "@types/bn.js": "^5.1.5", 32 | "@types/node": "^20.14.1", 33 | "dotenv": "^16.4.5", 34 | "js-sha256": "^0.11.0", 35 | "rimraf": "^3.0.2", 36 | "rollup": "^4.18.0", 37 | "ts-node": "^10.9.2" 38 | }, 39 | "dependencies": { 40 | "@coral-xyz/anchor": "^0.30.1", 41 | "@fleekxyz/sdk": "^1.4.2", 42 | "@rollup/plugin-json": "^6.1.0", 43 | "@solana/spl-token": "^0.4.0", 44 | "@solana/web3.js": "^1.89.1", 45 | "axios": "^1.6.8", 46 | "jito-ts": "^4.1.0", 47 | "tsx": "^4.16.2", 48 | "typescript": "^5.3.3", 49 | "undici": "^6.19.2" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/events.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { 3 | CompleteEvent, 4 | CreateEvent, 5 | SetParamsEvent, 6 | TradeEvent, 7 | } from "./types"; 8 | 9 | export function toCreateEvent(event: CreateEvent): CreateEvent { 10 | return { 11 | name: event.name, 12 | symbol: event.symbol, 13 | uri: event.uri, 14 | mint: new PublicKey(event.mint), 15 | bondingCurve: new PublicKey(event.bondingCurve), 16 | user: new PublicKey(event.user), 17 | }; 18 | } 19 | 20 | export function toCompleteEvent(event: CompleteEvent): CompleteEvent { 21 | return { 22 | user: new PublicKey(event.user), 23 | mint: new PublicKey(event.mint), 24 | bondingCurve: new PublicKey(event.bondingCurve), 25 | timestamp: event.timestamp, 26 | }; 27 | } 28 | 29 | export function toTradeEvent(event: TradeEvent): TradeEvent { 30 | return { 31 | mint: new PublicKey(event.mint), 32 | solAmount: BigInt(event.solAmount), 33 | tokenAmount: BigInt(event.tokenAmount), 34 | isBuy: event.isBuy, 35 | user: new PublicKey(event.user), 36 | timestamp: Number(event.timestamp), 37 | virtualSolReserves: BigInt(event.virtualSolReserves), 38 | virtualTokenReserves: BigInt(event.virtualTokenReserves), 39 | realSolReserves: BigInt(event.realSolReserves), 40 | realTokenReserves: BigInt(event.realTokenReserves), 41 | }; 42 | } 43 | 44 | export function toSetParamsEvent(event: SetParamsEvent): SetParamsEvent { 45 | return { 46 | feeRecipient: new PublicKey(event.feeRecipient), 47 | initialVirtualTokenReserves: BigInt(event.initialVirtualTokenReserves), 48 | initialVirtualSolReserves: BigInt(event.initialVirtualSolReserves), 49 | initialRealTokenReserves: BigInt(event.initialRealTokenReserves), 50 | tokenTotalSupply: BigInt(event.tokenTotalSupply), 51 | feeBasisPoints: BigInt(event.feeBasisPoints), 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey, VersionedTransactionResponse } from "@solana/web3.js"; 2 | 3 | export type CreateTokenMetadata = { 4 | name: string; 5 | symbol: string; 6 | description: string; 7 | file: Blob; 8 | twitter?: string; 9 | telegram?: string; 10 | website?: string; 11 | }; 12 | 13 | export type TokenMetadata = { 14 | name: string; 15 | symbol: string; 16 | description: string; 17 | image: string; 18 | showName: boolean; 19 | createdOn: string; 20 | twitter: string; 21 | }; 22 | 23 | export type CreateEvent = { 24 | name: string; 25 | symbol: string; 26 | uri: string; 27 | mint: PublicKey; 28 | bondingCurve: PublicKey; 29 | user: PublicKey; 30 | }; 31 | 32 | export type TradeEvent = { 33 | mint: PublicKey; 34 | solAmount: bigint; 35 | tokenAmount: bigint; 36 | isBuy: boolean; 37 | user: PublicKey; 38 | timestamp: number; 39 | virtualSolReserves: bigint; 40 | virtualTokenReserves: bigint; 41 | realSolReserves: bigint; 42 | realTokenReserves: bigint; 43 | }; 44 | 45 | export type CompleteEvent = { 46 | user: PublicKey; 47 | mint: PublicKey; 48 | bondingCurve: PublicKey; 49 | timestamp: number; 50 | }; 51 | 52 | export type SetParamsEvent = { 53 | feeRecipient: PublicKey; 54 | initialVirtualTokenReserves: bigint; 55 | initialVirtualSolReserves: bigint; 56 | initialRealTokenReserves: bigint; 57 | tokenTotalSupply: bigint; 58 | feeBasisPoints: bigint; 59 | }; 60 | 61 | export interface PumpFunEventHandlers { 62 | createEvent: CreateEvent; 63 | tradeEvent: TradeEvent; 64 | completeEvent: CompleteEvent; 65 | setParamsEvent: SetParamsEvent; 66 | } 67 | 68 | export type PumpFunEventType = keyof PumpFunEventHandlers; 69 | 70 | export type PriorityFee = { 71 | unitLimit: number; 72 | unitPrice: number; 73 | }; 74 | 75 | export type TransactionResult = { 76 | signature?: string; 77 | error?: unknown; 78 | results?: VersionedTransactionResponse; 79 | success: boolean; 80 | }; 81 | -------------------------------------------------------------------------------- /src/uploadToIpfs.ts: -------------------------------------------------------------------------------- 1 | 2 | import fs from 'fs'; 3 | import { FleekSdk, PersonalAccessTokenService } from '@fleekxyz/sdk'; 4 | import dotenv from 'dotenv'; 5 | import metadata from './metadata'; 6 | dotenv.config(); 7 | 8 | const pat = process.env.PAT || ''; 9 | const project_id = process.env.PROJECT_ID || ''; 10 | const imageName = "./upload/bolt.jpg"; 11 | const metadataName = "./upload/metadata.json"; 12 | 13 | const patService = new PersonalAccessTokenService({ 14 | personalAccessToken: pat, 15 | projectId: project_id, 16 | }) 17 | 18 | const fleekSdk = new FleekSdk({ accessTokenService: patService }) 19 | 20 | async function uploadFileToIPFS(filename: string, content: Buffer) { 21 | const result = await fleekSdk.ipfs().add({ 22 | path: filename, 23 | content: content 24 | }); 25 | return result; 26 | } 27 | 28 | export const getUploadedMetadataURI = async (): Promise => { 29 | const fileContent = fs.readFileSync(imageName); 30 | 31 | try { 32 | const imageUploadResult = await uploadFileToIPFS(imageName, fileContent); 33 | console.log('Image uploaded to IPFS:', imageUploadResult); 34 | console.log('IPFS URL:', `https://cf-ipfs.com/ipfs/${imageUploadResult.cid}`); 35 | 36 | const data = { 37 | "name": metadata.name, 38 | "symbol": metadata.symbol, 39 | "description": metadata.description, 40 | "image": `https://cf-ipfs.com/ipfs/${imageUploadResult.cid}`, 41 | "showName": metadata.showName, 42 | "createdOn": metadata.createdOn, 43 | "twitter": metadata.twitter, 44 | "telegram": metadata.telegram, 45 | "website": metadata.website 46 | } 47 | const metadataString = JSON.stringify(data); 48 | const bufferContent = Buffer.from(metadataString, 'utf-8'); 49 | fs.writeFileSync(metadataName, bufferContent); 50 | const metadataContent = fs.readFileSync(metadataName); 51 | 52 | const metadataUploadResult = await uploadFileToIPFS(metadataName, metadataContent); 53 | console.log('File uploaded to IPFS:', metadataUploadResult); 54 | console.log('IPFS URL:', `https://cf-ipfs.com/ipfs/${metadataUploadResult.cid}`) 55 | return `https://cf-ipfs.com/ipfs/${metadataUploadResult.cid}`; 56 | } catch (error) { 57 | return ""; 58 | } 59 | } -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # **Pumpfun Bundler Bot V2.0.4** 2 | 3 | ## **Overview** 4 | This bot automates **multi-wallet token purchases** on Pump.fun. It: 5 | 6 | ✅ **Creates 20 wallets** dynamically 7 | ✅ **Airdrops SOL** from the **main wallet** to cover fees 8 | ✅ **Uses Jito for MEV protection** 9 | ✅ **Buys tokens with each wallet** using the specified `SWAP_AMOUNT` 10 | 11 | ## **Configuration** 12 | Set the following **environment variables** in your `.env` file: 13 | 14 | ```ini 15 | # Main Wallet (Used for airdrops & funding) 16 | PRIVATE_KEY=your_main_wallet_private_key 17 | 18 | # RPC Configuration 19 | RPC_ENDPOINT=https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY 20 | RPC_WEBSOCKET_ENDPOINT=wss://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY 21 | 22 | # Bot Settings 23 | SWAP_AMOUNT=0.001 # Token buy amount per wallet 24 | DISTRIBUTION_WALLETNUM=20 # Number of wallets (max: 20) 25 | JITO_FEE=0.001 # MEV protection fee 26 | ``` 27 | 28 | ### **How It Works** 29 | 1. The bot **generates 20 wallets**. 30 | 2. The **main wallet** airdrops SOL to these wallets for gas fees. 31 | 3. Each wallet **buys tokens** using `SWAP_AMOUNT`. 32 | 4. **Jito priority fees** are included in transactions. 33 | 34 | ## **Token Data** 35 | Customize the token details: 36 | 37 | ```ini 38 | TOKEN_NAME="Verify Pump" 39 | TOKEN_SYMBOL="VEPP" 40 | DESCRIPTION="I will give you" 41 | TOKEN_SHOW_NAME="Desk" 42 | TOKEN_CREATE_ON="yesterday" 43 | TWITTER="https://x.com/rrr" 44 | TELEGRAM="https://t.me/www" 45 | WEBSITE="https://sisi.com" 46 | FILE="./image/1.jpg" 47 | ``` 48 | 49 | - **TOKEN_NAME** → The name of the token. 50 | - **TOKEN_SYMBOL** → Token's ticker symbol. 51 | - **DESCRIPTION** → Short description. 52 | - **TOKEN_SHOW_NAME** → Display name for UI. 53 | - **TOKEN_CREATE_ON** → Creation date. 54 | - **TWITTER** → Token’s official Twitter/X link. 55 | - **TELEGRAM** → Telegram group link. 56 | - **WEBSITE** → Official project website. 57 | - **FILE** → Path to token logo/image. 58 | 59 | --- 60 | 61 | ## **Running the Bot** 62 | 1️⃣ Install dependencies: 63 | ```bash 64 | yarn install 65 | ``` 66 | 2️⃣ Create a `.env` file and configure it. 67 | 3️⃣ Run the bot: 68 | ```bash 69 | yarn start 70 | ``` 71 | 72 | ## **Notes** 73 | - **Make sure your main wallet has enough SOL** to fund all 20 wallets. 74 | - **Jito fees are deducted** per transaction for priority execution. 75 | - **Max wallets: 20** (change `DISTRIBUTION_WALLETNUM` if needed). 76 | 77 | ## **Contact me** 78 | Telegram: topsecretagent007[https://t.me/topsecretagent_007] 79 | -------------------------------------------------------------------------------- /src/globalAccount.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { struct, bool, u64, publicKey, Layout } from "@coral-xyz/borsh"; 3 | 4 | export class GlobalAccount { 5 | public discriminator: bigint; 6 | public initialized: boolean = false; 7 | public authority: PublicKey; 8 | public feeRecipient: PublicKey; 9 | public initialVirtualTokenReserves: bigint; 10 | public initialVirtualSolReserves: bigint; 11 | public initialRealTokenReserves: bigint; 12 | public tokenTotalSupply: bigint; 13 | public feeBasisPoints: bigint; 14 | 15 | constructor( 16 | discriminator: bigint, 17 | initialized: boolean, 18 | authority: PublicKey, 19 | feeRecipient: PublicKey, 20 | initialVirtualTokenReserves: bigint, 21 | initialVirtualSolReserves: bigint, 22 | initialRealTokenReserves: bigint, 23 | tokenTotalSupply: bigint, 24 | feeBasisPoints: bigint 25 | ) { 26 | this.discriminator = discriminator; 27 | this.initialized = initialized; 28 | this.authority = authority; 29 | this.feeRecipient = feeRecipient; 30 | this.initialVirtualTokenReserves = initialVirtualTokenReserves; 31 | this.initialVirtualSolReserves = initialVirtualSolReserves; 32 | this.initialRealTokenReserves = initialRealTokenReserves; 33 | this.tokenTotalSupply = tokenTotalSupply; 34 | this.feeBasisPoints = feeBasisPoints; 35 | } 36 | 37 | getInitialBuyPrice(amount: bigint): bigint { 38 | if (amount <= 0n) { 39 | return 0n; 40 | } 41 | 42 | let n = this.initialVirtualSolReserves * this.initialVirtualTokenReserves; 43 | let i = this.initialVirtualSolReserves + amount; 44 | let r = n / i + 1n; 45 | let s = this.initialVirtualTokenReserves - r; 46 | return s < this.initialRealTokenReserves 47 | ? s 48 | : this.initialRealTokenReserves; 49 | } 50 | 51 | public static fromBuffer(buffer: Buffer): GlobalAccount { 52 | const structure: Layout = struct([ 53 | u64("discriminator"), 54 | bool("initialized"), 55 | publicKey("authority"), 56 | publicKey("feeRecipient"), 57 | u64("initialVirtualTokenReserves"), 58 | u64("initialVirtualSolReserves"), 59 | u64("initialRealTokenReserves"), 60 | u64("tokenTotalSupply"), 61 | u64("feeBasisPoints"), 62 | ]); 63 | 64 | let value = structure.decode(buffer); 65 | return new GlobalAccount( 66 | BigInt(value.discriminator), 67 | value.initialized, 68 | value.authority, 69 | value.feeRecipient, 70 | BigInt(value.initialVirtualTokenReserves), 71 | BigInt(value.initialVirtualSolReserves), 72 | BigInt(value.initialRealTokenReserves), 73 | BigInt(value.tokenTotalSupply), 74 | BigInt(value.feeBasisPoints) 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /example/util.ts: -------------------------------------------------------------------------------- 1 | import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; 2 | import { getAssociatedTokenAddressSync } from "@solana/spl-token"; 3 | import { 4 | Keypair, 5 | PublicKey, 6 | Connection, 7 | LAMPORTS_PER_SOL, 8 | } from "@solana/web3.js"; 9 | import { sha256 } from "js-sha256"; 10 | 11 | import fs from "fs"; 12 | 13 | export function getOrCreateKeypair(dir: string, keyName: string): Keypair { 14 | if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); 15 | const authorityKey = dir + "/" + keyName + ".json"; 16 | if (fs.existsSync(authorityKey)) { 17 | const data: { 18 | secretKey: string; 19 | publicKey: string; 20 | } = JSON.parse(fs.readFileSync(authorityKey, "utf-8")); 21 | return Keypair.fromSecretKey(bs58.decode(data.secretKey)); 22 | } else { 23 | const keypair = Keypair.generate(); 24 | keypair.secretKey; 25 | fs.writeFileSync( 26 | authorityKey, 27 | JSON.stringify({ 28 | secretKey: bs58.encode(keypair.secretKey), 29 | publicKey: keypair.publicKey.toBase58(), 30 | }) 31 | ); 32 | return keypair; 33 | } 34 | } 35 | 36 | export const printSOLBalance = async ( 37 | connection: Connection, 38 | pubKey: PublicKey, 39 | info: string = "" 40 | ) => { 41 | const balance = await connection.getBalance(pubKey); 42 | console.log( 43 | `${info ? info + " " : ""}${pubKey.toBase58()}:`, 44 | balance / LAMPORTS_PER_SOL, 45 | `SOL` 46 | ); 47 | }; 48 | 49 | export const getSPLBalance = async ( 50 | connection: Connection, 51 | mintAddress: PublicKey, 52 | pubKey: PublicKey, 53 | allowOffCurve: boolean = false 54 | ) => { 55 | try { 56 | let ata = getAssociatedTokenAddressSync(mintAddress, pubKey, allowOffCurve); 57 | const balance = await connection.getTokenAccountBalance(ata, "processed"); 58 | return balance.value.uiAmount; 59 | } catch (e) {} 60 | return null; 61 | }; 62 | 63 | export const printSPLBalance = async ( 64 | connection: Connection, 65 | mintAddress: PublicKey, 66 | user: PublicKey, 67 | info: string = "" 68 | ) => { 69 | const balance = await getSPLBalance(connection, mintAddress, user); 70 | if (balance === null) { 71 | console.log( 72 | `${info ? info + " " : ""}${user.toBase58()}:`, 73 | "No Account Found" 74 | ); 75 | } else { 76 | console.log(`${info ? info + " " : ""}${user.toBase58()}:`, balance); 77 | } 78 | }; 79 | 80 | export const baseToValue = (base: number, decimals: number): number => { 81 | return base * Math.pow(10, decimals); 82 | }; 83 | 84 | export const valueToBase = (value: number, decimals: number): number => { 85 | return value / Math.pow(10, decimals); 86 | }; 87 | 88 | //i.e. account:BondingCurve 89 | export function getDiscriminator(name: string) { 90 | return sha256.digest(name).slice(0, 8); 91 | } 92 | -------------------------------------------------------------------------------- /src/amm.ts: -------------------------------------------------------------------------------- 1 | import { BondingCurveAccount } from "./bondingCurveAccount"; 2 | import { GlobalAccount } from "./globalAccount"; 3 | 4 | export type BuyResult = { 5 | token_amount: bigint; 6 | sol_amount: bigint; 7 | }; 8 | 9 | export type SellResult = { 10 | token_amount: bigint; 11 | sol_amount: bigint; 12 | }; 13 | 14 | export class AMM { 15 | constructor( 16 | public virtualSolReserves: bigint, 17 | public virtualTokenReserves: bigint, 18 | public realSolReserves: bigint, 19 | public realTokenReserves: bigint, 20 | public initialVirtualTokenReserves: bigint 21 | ) {} 22 | 23 | static fromGlobalAccount(global: GlobalAccount): AMM { 24 | return new AMM( 25 | global.initialVirtualSolReserves, 26 | global.initialVirtualTokenReserves, 27 | 0n, 28 | global.initialRealTokenReserves, 29 | global.initialVirtualTokenReserves 30 | ); 31 | } 32 | 33 | static fromBondingCurveAccount(bonding_curve: BondingCurveAccount, initialVirtualTokenReserves: bigint): AMM { 34 | return new AMM( 35 | bonding_curve.virtualSolReserves, 36 | bonding_curve.virtualTokenReserves, 37 | bonding_curve.realSolReserves, 38 | bonding_curve.realTokenReserves, 39 | initialVirtualTokenReserves 40 | ); 41 | } 42 | 43 | getBuyPrice(tokens: bigint): bigint { 44 | const product_of_reserves = this.virtualSolReserves * this.virtualTokenReserves; 45 | const new_virtual_token_reserves = this.virtualTokenReserves - tokens; 46 | const new_virtual_sol_reserves = product_of_reserves / new_virtual_token_reserves + 1n; 47 | const amount_needed = new_virtual_sol_reserves > this.virtualSolReserves ? new_virtual_sol_reserves - this.virtualSolReserves : 0n; 48 | return amount_needed > 0n ? amount_needed : 0n; 49 | } 50 | 51 | applyBuy(token_amount: bigint): BuyResult { 52 | const final_token_amount = token_amount > this.realTokenReserves ? this.realTokenReserves : token_amount; 53 | const sol_amount = this.getBuyPrice(final_token_amount); 54 | 55 | this.virtualTokenReserves = this.virtualTokenReserves - final_token_amount; 56 | this.realTokenReserves = this.realTokenReserves - final_token_amount; 57 | 58 | this.virtualSolReserves = this.virtualSolReserves + sol_amount; 59 | this.realSolReserves = this.realSolReserves + sol_amount; 60 | 61 | return { 62 | token_amount: final_token_amount, 63 | sol_amount: sol_amount 64 | } 65 | } 66 | 67 | applySell(token_amount: bigint): SellResult { 68 | this.virtualTokenReserves = this.virtualTokenReserves + token_amount; 69 | this.realTokenReserves = this.realTokenReserves + token_amount; 70 | 71 | const sell_price = this.getSellPrice(token_amount); 72 | 73 | this.virtualSolReserves = this.virtualSolReserves - sell_price; 74 | this.realSolReserves = this.realSolReserves - sell_price; 75 | 76 | return { 77 | token_amount: token_amount, 78 | sol_amount: sell_price 79 | } 80 | } 81 | 82 | getSellPrice(tokens: bigint): bigint { 83 | const scaling_factor = this.initialVirtualTokenReserves; 84 | const token_sell_proportion = (tokens * scaling_factor) / this.virtualTokenReserves; 85 | const sol_received = (this.virtualSolReserves * token_sell_proportion) / scaling_factor; 86 | return sol_received < this.realSolReserves ? sol_received : this.realSolReserves; 87 | } 88 | } -------------------------------------------------------------------------------- /src/jito.ts: -------------------------------------------------------------------------------- 1 | 2 | // Jito Bundling part 3 | 4 | import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, VersionedTransaction } from "@solana/web3.js" 5 | 6 | import base58 from "bs58" 7 | import { SearcherClient, searcherClient } from "jito-ts/dist/sdk/block-engine/searcher" 8 | import { Bundle } from "jito-ts/dist/sdk/block-engine/types" 9 | import { isError } from "jito-ts/dist/sdk/block-engine/utils" 10 | import { BLOCKENGINE_URL, JITO_AUTH_KEYPAIR, JITO_FEE, RPC_ENDPOINT, RPC_WEBSOCKET_ENDPOINT } from "./constants" 11 | const connection = new Connection(RPC_ENDPOINT, { 12 | wsEndpoint: RPC_WEBSOCKET_ENDPOINT, 13 | }) 14 | 15 | export async function bundle(txs: VersionedTransaction[], keypair: Keypair) { 16 | 17 | try { 18 | const txNum = Math.ceil(txs.length / 3) 19 | let successNum = 0 20 | for (let i = 0; i < txNum; i++) { 21 | const upperIndex = (i + 1) * 3 22 | const downIndex = i * 3 23 | const newTxs: VersionedTransaction[] = [] 24 | for (let j = downIndex; j < upperIndex; j++) { 25 | if (txs[j]) newTxs.push(txs[j]) 26 | } 27 | let success = await bull_dozer(newTxs, keypair) 28 | return success 29 | } 30 | if (successNum == txNum) return true 31 | else return false 32 | } catch (error) { 33 | return false 34 | } 35 | } 36 | 37 | 38 | export async function bull_dozer(txs: VersionedTransaction[], keypair: Keypair) { 39 | try { 40 | const bundleTransactionLimit = parseInt('4') 41 | const jitoKey = Keypair.fromSecretKey(base58.decode(JITO_AUTH_KEYPAIR)) 42 | const search = searcherClient(BLOCKENGINE_URL, jitoKey) 43 | 44 | await build_bundle( 45 | search, 46 | bundleTransactionLimit, 47 | txs, 48 | keypair 49 | ) 50 | const bundle_result = await onBundleResult(search) 51 | return bundle_result 52 | } catch (error) { 53 | return 0 54 | } 55 | } 56 | 57 | 58 | async function build_bundle( 59 | search: SearcherClient, 60 | bundleTransactionLimit: number, 61 | txs: VersionedTransaction[], 62 | keypair: Keypair 63 | ) { 64 | const accounts = await search.getTipAccounts() 65 | const _tipAccount = accounts[Math.min(Math.floor(Math.random() * accounts.length), 3)] 66 | const tipAccount = new PublicKey(_tipAccount) 67 | 68 | const bund = new Bundle([], bundleTransactionLimit) 69 | const resp = await connection.getLatestBlockhash("processed") 70 | bund.addTransactions(...txs) 71 | 72 | let maybeBundle = bund.addTipTx( 73 | keypair, 74 | Number(JITO_FEE / LAMPORTS_PER_SOL), 75 | tipAccount, 76 | resp.blockhash 77 | ) 78 | 79 | if (isError(maybeBundle)) { 80 | throw maybeBundle 81 | } 82 | try { 83 | await search.sendBundle(maybeBundle) 84 | } catch (e) { } 85 | return maybeBundle 86 | } 87 | 88 | export const onBundleResult = (c: SearcherClient): Promise => { 89 | let first = 0 90 | let isResolved = false 91 | 92 | return new Promise((resolve) => { 93 | // Set a timeout to reject the promise if no bundle is accepted within 5 seconds 94 | setTimeout(() => { 95 | resolve(first) 96 | isResolved = true 97 | }, 30000) 98 | 99 | c.onBundleResult( 100 | (result: any) => { 101 | if (isResolved) return first 102 | // clearTimeout(timeout) // Clear the timeout if a bundle is accepted 103 | const isAccepted = result.accepted 104 | const isRejected = result.rejected 105 | if (isResolved == false) { 106 | 107 | if (isAccepted) { 108 | // console.log(`bundle accepted, ID: ${result.bundleId} | Slot: ${result.accepted!.slot}`) 109 | first += 1 110 | isResolved = true 111 | resolve(first) // Resolve with 'first' when a bundle is accepted 112 | } 113 | if (isRejected) { 114 | // Do not resolve or reject the promise here 115 | } 116 | } 117 | }, 118 | (e: any) => { 119 | // Do not reject the promise here 120 | } 121 | ) 122 | }) 123 | } 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /src/bondingCurveAccount.ts: -------------------------------------------------------------------------------- 1 | import { struct, bool, u64, Layout } from "@coral-xyz/borsh"; 2 | 3 | export class BondingCurveAccount { 4 | public discriminator: bigint; 5 | public virtualTokenReserves: bigint; 6 | public virtualSolReserves: bigint; 7 | public realTokenReserves: bigint; 8 | public realSolReserves: bigint; 9 | public tokenTotalSupply: bigint; 10 | public complete: boolean; 11 | 12 | constructor( 13 | discriminator: bigint, 14 | virtualTokenReserves: bigint, 15 | virtualSolReserves: bigint, 16 | realTokenReserves: bigint, 17 | realSolReserves: bigint, 18 | tokenTotalSupply: bigint, 19 | complete: boolean 20 | ) { 21 | this.discriminator = discriminator; 22 | this.virtualTokenReserves = virtualTokenReserves; 23 | this.virtualSolReserves = virtualSolReserves; 24 | this.realTokenReserves = realTokenReserves; 25 | this.realSolReserves = realSolReserves; 26 | this.tokenTotalSupply = tokenTotalSupply; 27 | this.complete = complete; 28 | } 29 | 30 | getBuyPrice(amount: bigint): bigint { 31 | if (this.complete) { 32 | throw new Error("Curve is complete"); 33 | } 34 | 35 | if (amount <= 0n) { 36 | return 0n; 37 | } 38 | 39 | // Calculate the product of virtual reserves 40 | let n = this.virtualSolReserves * this.virtualTokenReserves; 41 | 42 | // Calculate the new virtual sol reserves after the purchase 43 | let i = this.virtualSolReserves + amount; 44 | 45 | // Calculate the new virtual token reserves after the purchase 46 | let r = n / i + 1n; 47 | 48 | // Calculate the amount of tokens to be purchased 49 | let s = this.virtualTokenReserves - r; 50 | 51 | // Return the minimum of the calculated tokens and real token reserves 52 | return s < this.realTokenReserves ? s : this.realTokenReserves; 53 | } 54 | 55 | getSellPrice(amount: bigint, feeBasisPoints: bigint): bigint { 56 | if (this.complete) { 57 | throw new Error("Curve is complete"); 58 | } 59 | 60 | if (amount <= 0n) { 61 | return 0n; 62 | } 63 | 64 | // Calculate the proportional amount of virtual sol reserves to be received 65 | let n = 66 | (amount * this.virtualSolReserves) / (this.virtualTokenReserves + amount); 67 | 68 | // Calculate the fee amount in the same units 69 | let a = (n * feeBasisPoints) / 10000n; 70 | 71 | // Return the net amount after deducting the fee 72 | return n - a; 73 | } 74 | 75 | getMarketCapSOL(): bigint { 76 | if (this.virtualTokenReserves === 0n) { 77 | return 0n; 78 | } 79 | 80 | return ( 81 | (this.tokenTotalSupply * this.virtualSolReserves) / 82 | this.virtualTokenReserves 83 | ); 84 | } 85 | 86 | getFinalMarketCapSOL(feeBasisPoints: bigint): bigint { 87 | let totalSellValue = this.getBuyOutPrice( 88 | this.realTokenReserves, 89 | feeBasisPoints 90 | ); 91 | let totalVirtualValue = this.virtualSolReserves + totalSellValue; 92 | let totalVirtualTokens = this.virtualTokenReserves - this.realTokenReserves; 93 | 94 | if (totalVirtualTokens === 0n) { 95 | return 0n; 96 | } 97 | 98 | return (this.tokenTotalSupply * totalVirtualValue) / totalVirtualTokens; 99 | } 100 | 101 | getBuyOutPrice(amount: bigint, feeBasisPoints: bigint): bigint { 102 | let solTokens = 103 | amount < this.realSolReserves ? this.realSolReserves : amount; 104 | let totalSellValue = 105 | (solTokens * this.virtualSolReserves) / 106 | (this.virtualTokenReserves - solTokens) + 107 | 1n; 108 | let fee = (totalSellValue * feeBasisPoints) / 10000n; 109 | return totalSellValue + fee; 110 | } 111 | 112 | public static fromBuffer(buffer: Buffer): BondingCurveAccount { 113 | const structure: Layout = struct([ 114 | u64("discriminator"), 115 | u64("virtualTokenReserves"), 116 | u64("virtualSolReserves"), 117 | u64("realTokenReserves"), 118 | u64("realSolReserves"), 119 | u64("tokenTotalSupply"), 120 | bool("complete"), 121 | ]); 122 | 123 | let value = structure.decode(buffer); 124 | return new BondingCurveAccount( 125 | BigInt(value.discriminator), 126 | BigInt(value.virtualTokenReserves), 127 | BigInt(value.virtualSolReserves), 128 | BigInt(value.realTokenReserves), 129 | BigInt(value.realSolReserves), 130 | BigInt(value.tokenTotalSupply), 131 | value.complete 132 | ); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/jitoWithAxios.ts: -------------------------------------------------------------------------------- 1 | import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; 2 | import base58 from "bs58"; 3 | import axios, { AxiosError } from "axios"; 4 | import { COMMITMENT_LEVEL, JITO_FEE, RPC_ENDPOINT, RPC_WEBSOCKET_ENDPOINT } from "./constants"; 5 | 6 | 7 | interface Blockhash { 8 | blockhash: string; 9 | lastValidBlockHeight: number; 10 | } 11 | 12 | const solanaConnection = new Connection(RPC_ENDPOINT, { 13 | wsEndpoint: RPC_WEBSOCKET_ENDPOINT, 14 | }) 15 | 16 | 17 | export const jitoWithAxios = async (transactions: VersionedTransaction[], payer: Keypair) => { 18 | 19 | console.log('Starting Jito transaction execution...'); 20 | const tipAccounts = [ 21 | 'Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY', 22 | 'DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL', 23 | '96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5', 24 | '3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT', 25 | 'HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe', 26 | 'ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49', 27 | 'ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt', 28 | 'DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh', 29 | ]; 30 | const jitoFeeWallet = new PublicKey(tipAccounts[Math.floor(tipAccounts.length * Math.random())]) 31 | 32 | console.log(`Selected Jito fee wallet: ${jitoFeeWallet.toBase58()}`); 33 | 34 | try { 35 | console.log(`Calculated fee: ${JITO_FEE / LAMPORTS_PER_SOL} sol`); 36 | let latestBlockhash = await solanaConnection.getLatestBlockhash(); 37 | const jitTipTxFeeMessage = new TransactionMessage({ 38 | payerKey: payer.publicKey, 39 | recentBlockhash: latestBlockhash.blockhash, 40 | instructions: [ 41 | SystemProgram.transfer({ 42 | fromPubkey: payer.publicKey, 43 | toPubkey: jitoFeeWallet, 44 | lamports: JITO_FEE, 45 | }), 46 | ], 47 | }).compileToV0Message(); 48 | 49 | const jitoFeeTx = new VersionedTransaction(jitTipTxFeeMessage); 50 | jitoFeeTx.sign([payer]); 51 | 52 | 53 | const jitoTxsignature = base58.encode(jitoFeeTx.signatures[0]); 54 | 55 | // Serialize the transactions once here 56 | const serializedjitoFeeTx = base58.encode(jitoFeeTx.serialize()); 57 | const serializedTransactions = [serializedjitoFeeTx]; 58 | for (let i = 0; i < transactions.length; i++) { 59 | const serializedTransaction = base58.encode(transactions[i].serialize()); 60 | serializedTransactions.push(serializedTransaction); 61 | } 62 | 63 | 64 | const endpoints = [ 65 | // 'https://mainnet.block-engine.jito.wtf/api/v1/bundles', 66 | // 'https://amsterdam.mainnet.block-engine.jito.wtf/api/v1/bundles', 67 | // 'https://frankfurt.mainnet.block-engine.jito.wtf/api/v1/bundles', 68 | // 'https://ny.mainnet.block-engine.jito.wtf/api/v1/bundles', 69 | 'https://tokyo.mainnet.block-engine.jito.wtf/api/v1/bundles', 70 | ]; 71 | 72 | const requests = endpoints.map((url) => 73 | axios.post(url, { 74 | jsonrpc: '2.0', 75 | id: 1, 76 | method: 'sendBundle', 77 | params: [serializedTransactions], 78 | }) 79 | ); 80 | 81 | console.log('Sending transactions to endpoints...'); 82 | 83 | const results = await Promise.all(requests.map((p) => p.catch((e) => e))); 84 | 85 | 86 | const successfulResults = results.filter((result) => !(result instanceof Error)); 87 | 88 | if (successfulResults.length > 0) { 89 | console.log(`Successful response`); 90 | // console.log(`Confirming jito transaction...`); 91 | 92 | const confirmation = await solanaConnection.confirmTransaction( 93 | { 94 | signature: jitoTxsignature, 95 | lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, 96 | blockhash: latestBlockhash.blockhash, 97 | }, 98 | COMMITMENT_LEVEL, 99 | ); 100 | 101 | console.log(confirmation) 102 | 103 | return { confirmed: !confirmation.value.err, jitoTxsignature }; 104 | } else { 105 | console.log(`No successful responses received for jito`); 106 | } 107 | 108 | return { confirmed: false }; 109 | } catch (error) { 110 | 111 | if (error instanceof AxiosError) { 112 | console.log('Failed to execute jito transaction'); 113 | } 114 | console.log('Error during transaction execution', error); 115 | return { confirmed: false }; 116 | } 117 | } 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Commitment, 3 | ComputeBudgetProgram, 4 | Connection, 5 | Finality, 6 | Keypair, 7 | PublicKey, 8 | SendTransactionError, 9 | Transaction, 10 | TransactionMessage, 11 | VersionedTransaction, 12 | VersionedTransactionResponse, 13 | } from "@solana/web3.js"; 14 | import { PriorityFee, TransactionResult } from "./types"; 15 | import fs from "fs" 16 | 17 | export const DEFAULT_COMMITMENT: Commitment = "finalized"; 18 | export const DEFAULT_FINALITY: Finality = "finalized"; 19 | 20 | export const calculateWithSlippageBuy = ( 21 | amount: bigint, 22 | basisPoints: bigint 23 | ) => { 24 | return amount + (amount * basisPoints) / 10000n; 25 | }; 26 | 27 | export const calculateWithSlippageSell = ( 28 | amount: bigint, 29 | basisPoints: bigint 30 | ) => { 31 | return amount - (amount * basisPoints) / 10000n; 32 | }; 33 | 34 | export async function sendTx( 35 | connection: Connection, 36 | tx: Transaction, 37 | payer: PublicKey, 38 | signers: Keypair[], 39 | priorityFees?: PriorityFee, 40 | commitment: Commitment = DEFAULT_COMMITMENT, 41 | finality: Finality = DEFAULT_FINALITY 42 | ): Promise { 43 | let newTx = new Transaction(); 44 | 45 | if (priorityFees) { 46 | const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 47 | units: priorityFees.unitLimit, 48 | }); 49 | 50 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 51 | microLamports: priorityFees.unitPrice, 52 | }); 53 | newTx.add(modifyComputeUnits); 54 | newTx.add(addPriorityFee); 55 | } 56 | newTx.add(tx); 57 | let versionedTx = await buildVersionedTx(connection, payer, newTx, commitment); 58 | versionedTx.sign(signers); 59 | try { 60 | console.log((await connection.simulateTransaction(versionedTx, undefined))) 61 | 62 | const sig = await connection.sendTransaction(versionedTx, { 63 | skipPreflight: false, 64 | }); 65 | console.log("sig:", `https://solscan.io/tx/${sig}`); 66 | 67 | let txResult = await getTxDetails(connection, sig, commitment, finality); 68 | if (!txResult) { 69 | return { 70 | success: false, 71 | error: "Transaction failed", 72 | }; 73 | } 74 | return { 75 | success: true, 76 | signature: sig, 77 | results: txResult, 78 | }; 79 | } catch (e) { 80 | if (e instanceof SendTransactionError) { 81 | let ste = e as SendTransactionError; 82 | } else { 83 | console.error(e); 84 | } 85 | return { 86 | error: e, 87 | success: false, 88 | }; 89 | } 90 | } 91 | 92 | export async function buildTx( 93 | connection: Connection, 94 | tx: Transaction, 95 | payer: PublicKey, 96 | signers: Keypair[], 97 | priorityFees?: PriorityFee, 98 | commitment: Commitment = DEFAULT_COMMITMENT, 99 | finality: Finality = DEFAULT_FINALITY 100 | ): Promise { 101 | let newTx = new Transaction(); 102 | 103 | if (priorityFees) { 104 | const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 105 | units: priorityFees.unitLimit, 106 | }); 107 | 108 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 109 | microLamports: priorityFees.unitPrice, 110 | }); 111 | newTx.add(modifyComputeUnits); 112 | newTx.add(addPriorityFee); 113 | } 114 | newTx.add(tx); 115 | let versionedTx = await buildVersionedTx(connection, payer, newTx, commitment); 116 | versionedTx.sign(signers); 117 | return versionedTx; 118 | } 119 | 120 | export const buildVersionedTx = async ( 121 | connection: Connection, 122 | payer: PublicKey, 123 | tx: Transaction, 124 | commitment: Commitment = DEFAULT_COMMITMENT 125 | ): Promise => { 126 | const blockHash = (await connection.getLatestBlockhash(commitment)) 127 | .blockhash; 128 | 129 | let messageV0 = new TransactionMessage({ 130 | payerKey: payer, 131 | recentBlockhash: blockHash, 132 | instructions: tx.instructions, 133 | }).compileToV0Message(); 134 | 135 | return new VersionedTransaction(messageV0); 136 | }; 137 | 138 | export const getTxDetails = async ( 139 | connection: Connection, 140 | sig: string, 141 | commitment: Commitment = DEFAULT_COMMITMENT, 142 | finality: Finality = DEFAULT_FINALITY 143 | ): Promise => { 144 | const latestBlockHash = await connection.getLatestBlockhash(); 145 | await connection.confirmTransaction( 146 | { 147 | blockhash: latestBlockHash.blockhash, 148 | lastValidBlockHeight: latestBlockHash.lastValidBlockHeight, 149 | signature: sig, 150 | }, 151 | commitment 152 | ); 153 | 154 | return connection.getTransaction(sig, { 155 | maxSupportedTransactionVersion: 0, 156 | commitment: finality, 157 | }); 158 | }; 159 | 160 | export const getRandomInt = (min: number, max: number): number => { 161 | min = Math.ceil(min); 162 | max = Math.floor(max); 163 | return Math.floor(Math.random() * (max - min + 1)) + min; // The maximum is inclusive, the minimum is inclusive 164 | } 165 | -------------------------------------------------------------------------------- /example/basic/index.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import fs, { openAsBlob } from "fs"; 3 | import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; 4 | import { DEFAULT_DECIMALS, PumpFunSDK } from "../../src"; 5 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 6 | import { AnchorProvider } from "@coral-xyz/anchor"; 7 | import { 8 | getOrCreateKeypair, 9 | getSPLBalance, 10 | printSOLBalance, 11 | printSPLBalance, 12 | } from "../util"; 13 | import metadata from "../../src/metadata"; 14 | import { getUploadedMetadataURI } from "../../src/uploadToIpfs"; 15 | import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; 16 | 17 | const KEYS_FOLDER = __dirname + "/.keys"; 18 | const SLIPPAGE_BASIS_POINTS = 100n; 19 | 20 | async function createKeypair() { 21 | // Generate a new keypair 22 | const keypair = Keypair.generate(); 23 | 24 | // Extract the public key and secret key 25 | const publicKey = keypair.publicKey; 26 | const secretKey = keypair.secretKey; 27 | 28 | // Convert keys to base58 strings (for display or storage) 29 | const publicKeyBase58 = publicKey.toBase58(); 30 | const secretKeyBase58 = bs58.encode(secretKey); 31 | 32 | const data = { 33 | "publicKey": publicKeyBase58, 34 | "secretKey": secretKeyBase58 35 | } 36 | const metadataString = JSON.stringify(data); 37 | const bufferContent = Buffer.from(metadataString, 'utf-8'); 38 | fs.writeFileSync("./example/basic/.keys/mint.json", bufferContent); 39 | 40 | return keypair; // Return the keypair object if needed 41 | } 42 | 43 | const main = async () => { 44 | dotenv.config(); 45 | 46 | if (!process.env.HELIUS_RPC_URL) { 47 | console.error("Please set HELIUS_RPC_URL in .env file"); 48 | console.error( 49 | "Example: HELIUS_RPC_URL=https://mainnet.helius-rpc.com/?api-key=" 50 | ); 51 | console.error("Get one at: https://www.helius.dev"); 52 | return; 53 | } 54 | 55 | let connection = new Connection(process.env.HELIUS_RPC_URL || ""); 56 | 57 | let wallet = new NodeWallet(new Keypair()); //note this is not used 58 | const provider = new AnchorProvider(connection, wallet, { 59 | commitment: "finalized", 60 | }); 61 | 62 | await createKeypair(); 63 | 64 | const testAccount = getOrCreateKeypair(KEYS_FOLDER, "test-account"); 65 | const buyer = getOrCreateKeypair(KEYS_FOLDER, "buyer"); 66 | const mint = getOrCreateKeypair(KEYS_FOLDER, "mint"); 67 | 68 | await printSOLBalance( 69 | connection, 70 | testAccount.publicKey, 71 | "Test Account keypair" 72 | ); 73 | 74 | let sdk = new PumpFunSDK(provider); 75 | 76 | let globalAccount = await sdk.getGlobalAccount(); 77 | console.log(globalAccount); 78 | 79 | let currentSolBalance = await connection.getBalance(testAccount.publicKey); 80 | if (currentSolBalance == 0) { 81 | console.log( 82 | "Please send some SOL to the test-account:", 83 | testAccount.publicKey.toBase58() 84 | ); 85 | return; 86 | } 87 | 88 | //Check if mint already exists 89 | let boundingCurveAccount = await sdk.getBondingCurveAccount(mint.publicKey); 90 | if (!boundingCurveAccount) { 91 | let tokenMetadata = { 92 | name: metadata.name, 93 | symbol: metadata.symbol, 94 | description: metadata.description, 95 | showName: metadata.showName, 96 | createOn: metadata.createdOn, 97 | twitter: metadata.twitter, 98 | telegram: metadata.telegram, 99 | website: metadata.website, 100 | file: await openAsBlob("./upload/bolt.jpg"), 101 | }; 102 | 103 | let createResults = await sdk.createAndBuy( 104 | testAccount, 105 | mint, 106 | [testAccount, buyer], // buyers 107 | tokenMetadata, 108 | BigInt(0.0001 * LAMPORTS_PER_SOL), 109 | SLIPPAGE_BASIS_POINTS, 110 | { 111 | unitLimit: 5_000_000, 112 | unitPrice: 200_000, 113 | }, 114 | ); 115 | 116 | if (createResults.confirmed) { 117 | console.log("Success:", `https://pump.fun/${mint.publicKey.toBase58()}`); 118 | console.log(createResults.jitoTxsignature); 119 | boundingCurveAccount = await sdk.getBondingCurveAccount(mint.publicKey); 120 | console.log("Bonding curve after create and buy", boundingCurveAccount); 121 | printSPLBalance(connection, mint.publicKey, testAccount.publicKey); 122 | } 123 | } else { 124 | console.log("boundingCurveAccount", boundingCurveAccount); 125 | console.log("Success:", `https://pump.fun/${mint.publicKey.toBase58()}`); 126 | printSPLBalance(connection, mint.publicKey, testAccount.publicKey); 127 | } 128 | 129 | // Buy and sell 130 | // if (boundingCurveAccount) { 131 | // // buy 0.0001 SOL worth of tokens 132 | // let buyResults = await sdk.buy( 133 | // testAccount, 134 | // // mint.publicKey, 135 | // new PublicKey("3ZQuEN9gE14TXxYnMvWq86RBvh6wTdvtSaM1hhdXb2xQ"), 136 | // BigInt(0.0001 * LAMPORTS_PER_SOL), 137 | // SLIPPAGE_BASIS_POINTS, 138 | // { 139 | // unitLimit: 5_000_000, 140 | // unitPrice: 200_000, 141 | // }, 142 | // ); 143 | // if (buyResults.success) { 144 | // printSPLBalance(connection, mint.publicKey, testAccount.publicKey); 145 | // console.log("Bonding curve after buy", await sdk.getBondingCurveAccount(mint.publicKey)); 146 | // } else { 147 | // console.log("Buy failed"); 148 | // } 149 | 150 | // // buy 0.0001 SOL worth of tokens 151 | // let buyResultsByBuyer = await sdk.buy( 152 | // buyer, 153 | // // mint.publicKey, 154 | // new PublicKey("p89evAyzjd9fphjJx7G3RFA48sbZdpGEppRcfRNpump"), 155 | // BigInt(0.0001 * LAMPORTS_PER_SOL), 156 | // SLIPPAGE_BASIS_POINTS, 157 | // { 158 | // unitLimit: 5_000_000, 159 | // unitPrice: 200_000, 160 | // }, 161 | // ); 162 | 163 | // if (buyResultsByBuyer.success) { 164 | // printSPLBalance(connection, mint.publicKey, buyer.publicKey); 165 | // console.log("Bonding curve after buy ", await sdk.getBondingCurveAccount(mint.publicKey)); 166 | // } else { 167 | // console.log("Buy failed"); 168 | // } 169 | 170 | // // sell all tokens 171 | // let currentSPLBalance = await getSPLBalance( 172 | // connection, 173 | // mint.publicKey, 174 | // testAccount.publicKey 175 | // ); 176 | // console.log("currentSPLBalance ", currentSPLBalance); 177 | // if (currentSPLBalance) { 178 | // let sellResults = await sdk.sell( 179 | // testAccount, 180 | // mint.publicKey, 181 | // BigInt(currentSPLBalance * Math.pow(10, DEFAULT_DECIMALS)), 182 | // SLIPPAGE_BASIS_POINTS, 183 | // { 184 | // unitLimit: 5_000_000, 185 | // unitPrice: 200_000, 186 | // }, 187 | // ); 188 | // if (sellResults.success) { 189 | // await printSOLBalance( 190 | // connection, 191 | // testAccount.publicKey, 192 | // "Test Account keypair" 193 | // ); 194 | 195 | // printSPLBalance(connection, mint.publicKey, testAccount.publicKey, "After SPL sell all"); 196 | // console.log("Bonding curve after sell", await sdk.getBondingCurveAccount(mint.publicKey)); 197 | // } else { 198 | // console.log("Sell failed"); 199 | // } 200 | // } 201 | // } 202 | }; 203 | 204 | main(); 205 | -------------------------------------------------------------------------------- /src/pumpfun.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Commitment, 3 | Connection, 4 | Finality, 5 | Keypair, 6 | PublicKey, 7 | Transaction, 8 | VersionedTransaction, 9 | } from "@solana/web3.js"; 10 | import { Program, Provider } from "@coral-xyz/anchor"; 11 | import { setGlobalDispatcher, Agent } from 'undici' 12 | import { GlobalAccount } from "./globalAccount"; 13 | import { 14 | CompleteEvent, 15 | CreateEvent, 16 | CreateTokenMetadata, 17 | PriorityFee, 18 | PumpFunEventHandlers, 19 | PumpFunEventType, 20 | SetParamsEvent, 21 | TradeEvent, 22 | TransactionResult, 23 | } from "./types"; 24 | import { 25 | toCompleteEvent, 26 | toCreateEvent, 27 | toSetParamsEvent, 28 | toTradeEvent, 29 | } from "./events"; 30 | import { 31 | createAssociatedTokenAccountInstruction, 32 | getAccount, 33 | getAssociatedTokenAddress, 34 | } from "@solana/spl-token"; 35 | import { BondingCurveAccount } from "./bondingCurveAccount"; 36 | import { BN } from "bn.js"; 37 | import { 38 | DEFAULT_COMMITMENT, 39 | DEFAULT_FINALITY, 40 | buildTx, 41 | calculateWithSlippageBuy, 42 | calculateWithSlippageSell, 43 | getRandomInt, 44 | sendTx, 45 | } from "./util"; 46 | import { PumpFun, IDL } from "./IDL"; 47 | import { getUploadedMetadataURI } from "./uploadToIpfs"; 48 | import { jitoWithAxios } from "./jitoWithAxios"; 49 | import { RPC_ENDPOINT, RPC_WEBSOCKET_ENDPOINT } from "./constants"; 50 | import { global_mint } from "./config"; 51 | 52 | const PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 53 | const MPL_TOKEN_METADATA_PROGRAM_ID = 54 | "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"; 55 | 56 | export const GLOBAL_ACCOUNT_SEED = "global"; 57 | export const MINT_AUTHORITY_SEED = "mint-authority"; 58 | export const BONDING_CURVE_SEED = "bonding-curve"; 59 | export const METADATA_SEED = "metadata"; 60 | 61 | export const DEFAULT_DECIMALS = 6; 62 | 63 | export class PumpFunSDK { 64 | public program: Program; 65 | public connection: Connection; 66 | constructor(provider?: Provider) { 67 | this.program = new Program(IDL as PumpFun, provider); 68 | this.connection = this.program.provider.connection; 69 | } 70 | 71 | async createAndBuy( 72 | creator: Keypair, 73 | mint: Keypair, 74 | buyers: Keypair[], 75 | createTokenMetadata: CreateTokenMetadata, 76 | buyAmountSol: bigint, 77 | slippageBasisPoints: bigint = 300n, 78 | priorityFees?: PriorityFee, 79 | commitment: Commitment = DEFAULT_COMMITMENT, 80 | finality: Finality = DEFAULT_FINALITY 81 | ) { 82 | let tokenMetadata = await this.createTokenMetadata(createTokenMetadata); 83 | 84 | let createTx = await this.getCreateInstructions( 85 | creator.publicKey, 86 | createTokenMetadata.name, 87 | createTokenMetadata.symbol, 88 | tokenMetadata.metadataUri, 89 | mint 90 | ); 91 | 92 | let newTx = new Transaction().add(createTx); 93 | let buyTxs: VersionedTransaction[] = []; 94 | 95 | let createVersionedTx = await buildTx( 96 | this.connection, 97 | newTx, 98 | creator.publicKey, 99 | [creator, mint], 100 | priorityFees, 101 | commitment, 102 | finality 103 | ); 104 | 105 | if (buyAmountSol > 0) { 106 | for(let i = 0; i < buyers.length; i++) 107 | { 108 | const randomPercent = getRandomInt(10,25); 109 | const buyAmountSolWithRandom = buyAmountSol / BigInt(100) * BigInt(randomPercent % 2 ? (100 + randomPercent) : (100 - randomPercent)) 110 | 111 | let buyTx = await this.getBuyInstructionsBySolAmount( 112 | buyers[i].publicKey, 113 | mint.publicKey, 114 | buyAmountSolWithRandom, 115 | slippageBasisPoints, 116 | commitment 117 | ); 118 | 119 | const buyVersionedTx = await buildTx( 120 | this.connection, 121 | buyTx, 122 | buyers[i].publicKey, 123 | [buyers[i]], 124 | priorityFees, 125 | commitment, 126 | finality 127 | ); 128 | buyTxs.push(buyVersionedTx); 129 | } 130 | } 131 | 132 | await sendTx( 133 | this.connection, 134 | newTx, 135 | creator.publicKey, 136 | [creator, mint], 137 | priorityFees, 138 | commitment, 139 | finality 140 | ); 141 | let result; 142 | while(1) { 143 | result = await jitoWithAxios([createVersionedTx, ...buyTxs], creator); 144 | if (result.confirmed) break; 145 | } 146 | 147 | return result; 148 | } 149 | 150 | async buy( 151 | buyer: Keypair, 152 | mint: PublicKey, 153 | buyAmountSol: bigint, 154 | slippageBasisPoints: bigint = 500n, 155 | priorityFees?: PriorityFee, 156 | commitment: Commitment = DEFAULT_COMMITMENT, 157 | finality: Finality = DEFAULT_FINALITY 158 | ): Promise { 159 | let buyTx = await this.getBuyInstructionsBySolAmount( 160 | buyer.publicKey, 161 | mint, 162 | buyAmountSol, 163 | slippageBasisPoints, 164 | commitment 165 | ); 166 | 167 | let buyResults = await sendTx( 168 | this.connection, 169 | buyTx, 170 | buyer.publicKey, 171 | [buyer], 172 | priorityFees, 173 | commitment, 174 | finality 175 | ); 176 | return buyResults; 177 | } 178 | 179 | async sell( 180 | seller: Keypair, 181 | mint: PublicKey, 182 | sellTokenAmount: bigint, 183 | slippageBasisPoints: bigint = 500n, 184 | priorityFees?: PriorityFee, 185 | commitment: Commitment = DEFAULT_COMMITMENT, 186 | finality: Finality = DEFAULT_FINALITY 187 | ): Promise { 188 | let sellTx = await this.getSellInstructionsByTokenAmount( 189 | seller.publicKey, 190 | mint, 191 | sellTokenAmount, 192 | slippageBasisPoints, 193 | commitment 194 | ); 195 | 196 | let sellResults = await sendTx( 197 | this.connection, 198 | sellTx, 199 | seller.publicKey, 200 | [seller], 201 | priorityFees, 202 | commitment, 203 | finality 204 | ); 205 | return sellResults; 206 | } 207 | 208 | //create token instructions 209 | async getCreateInstructions( 210 | creator: PublicKey, 211 | name: string, 212 | symbol: string, 213 | uri: string, 214 | mint: Keypair 215 | ) { 216 | const mplTokenMetadata = new PublicKey(MPL_TOKEN_METADATA_PROGRAM_ID); 217 | 218 | const [metadataPDA] = PublicKey.findProgramAddressSync( 219 | [ 220 | Buffer.from(METADATA_SEED), 221 | mplTokenMetadata.toBuffer(), 222 | mint.publicKey.toBuffer(), 223 | ], 224 | mplTokenMetadata 225 | ); 226 | 227 | const associatedBondingCurve = await getAssociatedTokenAddress( 228 | mint.publicKey, 229 | this.getBondingCurvePDA(mint.publicKey), 230 | true 231 | ); 232 | 233 | return this.program.methods 234 | .create(name, symbol, uri) 235 | .accounts({ 236 | mint: mint.publicKey, 237 | associatedBondingCurve: associatedBondingCurve, 238 | metadata: metadataPDA, 239 | user: creator, 240 | }) 241 | .signers([mint]) 242 | .transaction(); 243 | } 244 | 245 | async getBuyInstructionsBySolAmount( 246 | buyer: PublicKey, 247 | mint: PublicKey, 248 | buyAmountSol: bigint, 249 | slippageBasisPoints: bigint = 500n, 250 | commitment: Commitment = DEFAULT_COMMITMENT 251 | ) { 252 | let bondingCurveAccount = await this.getBondingCurveAccount( 253 | global_mint, 254 | commitment 255 | ); 256 | if (!bondingCurveAccount) { 257 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 258 | } 259 | 260 | let buyAmount = bondingCurveAccount.getBuyPrice(buyAmountSol); 261 | let buyAmountWithSlippage = calculateWithSlippageBuy( 262 | buyAmountSol, 263 | slippageBasisPoints 264 | ); 265 | let globalAccount = await this.getGlobalAccount(commitment); 266 | 267 | return await this.getBuyInstructions( 268 | buyer, 269 | mint, 270 | globalAccount.feeRecipient, 271 | buyAmount, 272 | buyAmountWithSlippage, 273 | ); 274 | } 275 | 276 | //buy 277 | async getBuyInstructions( 278 | buyer: PublicKey, 279 | mint: PublicKey, 280 | feeRecipient: PublicKey, 281 | amount: bigint, 282 | solAmount: bigint, 283 | commitment: Commitment = DEFAULT_COMMITMENT, 284 | ) { 285 | const associatedBondingCurve = await getAssociatedTokenAddress( 286 | mint, 287 | this.getBondingCurvePDA(mint), 288 | true 289 | ); 290 | 291 | const associatedUser = await getAssociatedTokenAddress(mint, buyer, false); 292 | 293 | let transaction = new Transaction(); 294 | 295 | try { 296 | await getAccount(this.connection, associatedUser, commitment); 297 | } catch (e) { 298 | transaction.add( 299 | createAssociatedTokenAccountInstruction( 300 | buyer, 301 | associatedUser, 302 | buyer, 303 | mint 304 | ) 305 | ); 306 | } 307 | 308 | transaction.add( 309 | await this.program.methods 310 | .buy(new BN(amount.toString()), new BN(solAmount.toString())) 311 | .accounts({ 312 | feeRecipient: feeRecipient, 313 | mint: mint, 314 | associatedBondingCurve: associatedBondingCurve, 315 | associatedUser: associatedUser, 316 | user: buyer, 317 | }) 318 | .transaction() 319 | ); 320 | 321 | return transaction; 322 | } 323 | 324 | //sell 325 | async getSellInstructionsByTokenAmount( 326 | seller: PublicKey, 327 | mint: PublicKey, 328 | sellTokenAmount: bigint, 329 | slippageBasisPoints: bigint = 500n, 330 | commitment: Commitment = DEFAULT_COMMITMENT 331 | ) { 332 | let bondingCurveAccount = await this.getBondingCurveAccount( 333 | mint, 334 | commitment 335 | ); 336 | if (!bondingCurveAccount) { 337 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 338 | } 339 | 340 | let globalAccount = await this.getGlobalAccount(commitment); 341 | 342 | let minSolOutput = bondingCurveAccount.getSellPrice( 343 | sellTokenAmount, 344 | globalAccount.feeBasisPoints 345 | ); 346 | 347 | let sellAmountWithSlippage = calculateWithSlippageSell( 348 | minSolOutput, 349 | slippageBasisPoints 350 | ); 351 | 352 | return await this.getSellInstructions( 353 | seller, 354 | mint, 355 | globalAccount.feeRecipient, 356 | sellTokenAmount, 357 | sellAmountWithSlippage 358 | ); 359 | } 360 | 361 | async getSellInstructions( 362 | seller: PublicKey, 363 | mint: PublicKey, 364 | feeRecipient: PublicKey, 365 | amount: bigint, 366 | minSolOutput: bigint 367 | ) { 368 | const associatedBondingCurve = await getAssociatedTokenAddress( 369 | mint, 370 | this.getBondingCurvePDA(mint), 371 | true 372 | ); 373 | 374 | const associatedUser = await getAssociatedTokenAddress(mint, seller, false); 375 | 376 | let transaction = new Transaction(); 377 | 378 | transaction.add( 379 | await this.program.methods 380 | .sell(new BN(amount.toString()), new BN(minSolOutput.toString())) 381 | .accounts({ 382 | feeRecipient: feeRecipient, 383 | mint: mint, 384 | associatedBondingCurve: associatedBondingCurve, 385 | associatedUser: associatedUser, 386 | user: seller, 387 | }) 388 | .transaction() 389 | ); 390 | 391 | return transaction; 392 | } 393 | 394 | async getBondingCurveAccount( 395 | mint: PublicKey, 396 | commitment: Commitment = DEFAULT_COMMITMENT 397 | ) { 398 | const tokenAccount = await this.connection.getAccountInfo( 399 | this.getBondingCurvePDA(mint), 400 | commitment 401 | ); 402 | if (!tokenAccount) { 403 | return null; 404 | } 405 | return BondingCurveAccount.fromBuffer(tokenAccount!.data); 406 | } 407 | 408 | async getGlobalAccount(commitment: Commitment = DEFAULT_COMMITMENT) { 409 | const [globalAccountPDA] = PublicKey.findProgramAddressSync( 410 | [Buffer.from(GLOBAL_ACCOUNT_SEED)], 411 | new PublicKey(PROGRAM_ID) 412 | ); 413 | 414 | const tokenAccount = await this.connection.getAccountInfo( 415 | globalAccountPDA, 416 | commitment 417 | ); 418 | 419 | return GlobalAccount.fromBuffer(tokenAccount!.data); 420 | } 421 | 422 | getBondingCurvePDA(mint: PublicKey) { 423 | return PublicKey.findProgramAddressSync( 424 | [Buffer.from(BONDING_CURVE_SEED), mint.toBuffer()], 425 | this.program.programId 426 | )[0]; 427 | } 428 | 429 | async createTokenMetadata(create: CreateTokenMetadata) { 430 | let formData = new FormData(); 431 | formData.append("file", create.file), 432 | formData.append("name", create.name), 433 | formData.append("symbol", create.symbol), 434 | formData.append("description", create.description), 435 | formData.append("twitter", create.twitter || ""), 436 | formData.append("telegram", create.telegram || ""), 437 | formData.append("website", create.website || ""), 438 | formData.append("showName", "true"); 439 | 440 | setGlobalDispatcher(new Agent({ connect: { timeout: 60_000 } })) 441 | let request = await fetch("https://pump.fun/api/ipfs", { 442 | method: "POST", 443 | headers: { 444 | "Host": "www.pump.fun", 445 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0", 446 | "Accept": "*/*", 447 | "Accept-Language": "en-US,en;q=0.5", 448 | "Accept-Encoding": "gzip, deflate, br, zstd", 449 | "Referer": "https://www.pump.fun/create", 450 | "Origin": "https://www.pump.fun", 451 | "Connection": "keep-alive", 452 | "Sec-Fetch-Dest": "empty", 453 | "Sec-Fetch-Mode": "cors", 454 | "Sec-Fetch-Site": "same-origin", 455 | "Priority": "u=1", 456 | "TE": "trailers" 457 | }, 458 | body: formData, 459 | }); 460 | return request.json(); 461 | } 462 | 463 | //EVENTS 464 | addEventListener( 465 | eventType: T, 466 | callback: ( 467 | event: PumpFunEventHandlers[T], 468 | slot: number, 469 | signature: string 470 | ) => void 471 | ) { 472 | return this.program.addEventListener( 473 | eventType, 474 | (event: any, slot: number, signature: string) => { 475 | let processedEvent; 476 | switch (eventType) { 477 | case "createEvent": 478 | processedEvent = toCreateEvent(event as CreateEvent); 479 | callback( 480 | processedEvent as PumpFunEventHandlers[T], 481 | slot, 482 | signature 483 | ); 484 | break; 485 | case "tradeEvent": 486 | processedEvent = toTradeEvent(event as TradeEvent); 487 | callback( 488 | processedEvent as PumpFunEventHandlers[T], 489 | slot, 490 | signature 491 | ); 492 | break; 493 | case "completeEvent": 494 | processedEvent = toCompleteEvent(event as CompleteEvent); 495 | callback( 496 | processedEvent as PumpFunEventHandlers[T], 497 | slot, 498 | signature 499 | ); 500 | console.log("completeEvent", event, slot, signature); 501 | break; 502 | case "setParamsEvent": 503 | processedEvent = toSetParamsEvent(event as SetParamsEvent); 504 | callback( 505 | processedEvent as PumpFunEventHandlers[T], 506 | slot, 507 | signature 508 | ); 509 | break; 510 | default: 511 | console.error("Unhandled event type:", eventType); 512 | } 513 | } 514 | ); 515 | } 516 | 517 | removeEventListener(eventId: number) { 518 | this.program.removeEventListener(eventId); 519 | } 520 | } 521 | -------------------------------------------------------------------------------- /src/IDL/pump-fun.ts: -------------------------------------------------------------------------------- 1 | export type PumpFun = { 2 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 3 | metadata: { 4 | name: "pump"; 5 | version: "0.1.0"; 6 | spec: "0.1.0"; 7 | }; 8 | instructions: [ 9 | { 10 | name: "initialize"; 11 | discriminator: [175, 175, 109, 31, 13, 152, 155, 237]; 12 | docs: ["Creates the global state."]; 13 | accounts: [ 14 | { 15 | name: "global"; 16 | writable: true; 17 | pda: { 18 | seeds: [ 19 | { 20 | kind: "const"; 21 | value: [103, 108, 111, 98, 97, 108]; 22 | } 23 | ]; 24 | }; 25 | }, 26 | { 27 | name: "user"; 28 | writable: true; 29 | signer: true; 30 | }, 31 | { 32 | name: "systemProgram"; 33 | address: "11111111111111111111111111111111"; 34 | } 35 | ]; 36 | args: []; 37 | }, 38 | { 39 | name: "setParams"; 40 | discriminator: [165, 31, 134, 53, 189, 180, 130, 255]; 41 | docs: ["Sets the global state parameters."]; 42 | accounts: [ 43 | { 44 | name: "global"; 45 | writable: true; 46 | pda: { 47 | seeds: [ 48 | { 49 | kind: "const"; 50 | value: [103, 108, 111, 98, 97, 108]; 51 | } 52 | ]; 53 | }; 54 | }, 55 | { 56 | name: "user"; 57 | writable: true; 58 | signer: true; 59 | }, 60 | { 61 | name: "systemProgram"; 62 | address: "11111111111111111111111111111111"; 63 | }, 64 | { 65 | name: "eventAuthority"; 66 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 67 | }, 68 | { 69 | name: "program"; 70 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 71 | } 72 | ]; 73 | args: [ 74 | { 75 | name: "feeRecipient"; 76 | type: "pubkey"; 77 | }, 78 | { 79 | name: "initialVirtualTokenReserves"; 80 | type: "u64"; 81 | }, 82 | { 83 | name: "initialVirtualSolReserves"; 84 | type: "u64"; 85 | }, 86 | { 87 | name: "initialRealTokenReserves"; 88 | type: "u64"; 89 | }, 90 | { 91 | name: "tokenTotalSupply"; 92 | type: "u64"; 93 | }, 94 | { 95 | name: "feeBasisPoints"; 96 | type: "u64"; 97 | } 98 | ]; 99 | }, 100 | { 101 | name: "create"; 102 | discriminator: [24, 30, 200, 40, 5, 28, 7, 119]; 103 | docs: ["Creates a new coin and bonding curve."]; 104 | accounts: [ 105 | { 106 | name: "mint"; 107 | writable: true; 108 | signer: true; 109 | }, 110 | { 111 | name: "mint_authority"; 112 | pda: { 113 | seeds: [ 114 | { 115 | kind: "const"; 116 | value: [ 117 | 109, 118 | 105, 119 | 110, 120 | 116, 121 | 45, 122 | 97, 123 | 117, 124 | 116, 125 | 104, 126 | 111, 127 | 114, 128 | 105, 129 | 116, 130 | 121 131 | ]; 132 | } 133 | ]; 134 | }; 135 | }, 136 | { 137 | name: "bondingCurve"; 138 | writable: true; 139 | pda: { 140 | seeds: [ 141 | { 142 | kind: "const"; 143 | value: [ 144 | 98, 145 | 111, 146 | 110, 147 | 100, 148 | 105, 149 | 110, 150 | 103, 151 | 45, 152 | 99, 153 | 117, 154 | 114, 155 | 118, 156 | 101 157 | ]; 158 | }, 159 | { 160 | kind: "account"; 161 | path: "mint"; 162 | } 163 | ]; 164 | }; 165 | }, 166 | { 167 | name: "associatedBondingCurve"; 168 | writable: true; 169 | signer: false; 170 | }, 171 | { 172 | name: "global"; 173 | writable: false; 174 | pda: { 175 | seeds: [ 176 | { 177 | kind: "const"; 178 | value: [103, 108, 111, 98, 97, 108]; 179 | } 180 | ]; 181 | }; 182 | }, 183 | { 184 | name: "mplTokenMetadata"; 185 | address: "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"; 186 | }, 187 | { 188 | name: "metadata"; 189 | writable: true; 190 | signer: false; 191 | }, 192 | { 193 | name: "user"; 194 | isMut: true; 195 | isSigner: true; 196 | }, 197 | { 198 | name: "systemProgram"; 199 | address: "11111111111111111111111111111111"; 200 | }, 201 | { 202 | name: "tokenProgram"; 203 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 204 | }, 205 | { 206 | name: "associatedTokenProgram"; 207 | address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"; 208 | }, 209 | { 210 | name: "rent"; 211 | address: "SysvarRent111111111111111111111111111111111"; 212 | }, 213 | { 214 | name: "eventAuthority"; 215 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 216 | }, 217 | { 218 | name: "program"; 219 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 220 | } 221 | ]; 222 | args: [ 223 | { 224 | name: "name"; 225 | type: "string"; 226 | }, 227 | { 228 | name: "symbol"; 229 | type: "string"; 230 | }, 231 | { 232 | name: "uri"; 233 | type: "string"; 234 | } 235 | ]; 236 | }, 237 | { 238 | name: "buy"; 239 | discriminator: [102, 6, 61, 18, 1, 218, 235, 234]; 240 | docs: ["Buys tokens from a bonding curve."]; 241 | accounts: [ 242 | { 243 | name: "global"; 244 | pda: { 245 | seeds: [ 246 | { 247 | kind: "const"; 248 | value: [103, 108, 111, 98, 97, 108]; 249 | } 250 | ]; 251 | }; 252 | }, 253 | { 254 | name: "feeRecipient"; 255 | writable: true; 256 | signer: false; 257 | }, 258 | { 259 | name: "mint"; 260 | writable: false; 261 | signer: false; 262 | }, 263 | { 264 | name: "bondingCurve"; 265 | writable: true; 266 | pda: { 267 | seeds: [ 268 | { 269 | kind: "const"; 270 | value: [ 271 | 98, 272 | 111, 273 | 110, 274 | 100, 275 | 105, 276 | 110, 277 | 103, 278 | 45, 279 | 99, 280 | 117, 281 | 114, 282 | 118, 283 | 101 284 | ]; 285 | }, 286 | { 287 | kind: "account"; 288 | path: "mint"; 289 | } 290 | ]; 291 | }; 292 | }, 293 | { 294 | name: "associatedBondingCurve"; 295 | writable: true; 296 | signer: false; 297 | }, 298 | { 299 | name: "associatedUser"; 300 | writable: true; 301 | signer: false; 302 | }, 303 | { 304 | name: "user"; 305 | writable: true; 306 | signer: true; 307 | }, 308 | { 309 | name: "systemProgram"; 310 | address: "11111111111111111111111111111111"; 311 | }, 312 | { 313 | name: "tokenProgram"; 314 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 315 | }, 316 | { 317 | name: "rent"; 318 | address: "SysvarRent111111111111111111111111111111111"; 319 | }, 320 | { 321 | name: "eventAuthority"; 322 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 323 | }, 324 | { 325 | name: "program"; 326 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 327 | } 328 | ]; 329 | args: [ 330 | { 331 | name: "amount"; 332 | type: "u64"; 333 | }, 334 | { 335 | name: "maxSolCost"; 336 | type: "u64"; 337 | } 338 | ]; 339 | }, 340 | { 341 | name: "sell"; 342 | discriminator: [51, 230, 133, 164, 1, 127, 131, 173]; 343 | docs: ["Sells tokens into a bonding curve."]; 344 | accounts: [ 345 | { 346 | name: "global"; 347 | writable: false; 348 | pda: { 349 | seeds: [ 350 | { 351 | kind: "const"; 352 | value: [103, 108, 111, 98, 97, 108]; 353 | } 354 | ]; 355 | }; 356 | }, 357 | { 358 | name: "feeRecipient"; 359 | writable: true; 360 | signer: false; 361 | }, 362 | { 363 | name: "mint"; 364 | writable: false; 365 | signer: false; 366 | }, 367 | { 368 | name: "bondingCurve"; 369 | writable: true; 370 | pda: { 371 | seeds: [ 372 | { 373 | kind: "const"; 374 | value: [ 375 | 98, 376 | 111, 377 | 110, 378 | 100, 379 | 105, 380 | 110, 381 | 103, 382 | 45, 383 | 99, 384 | 117, 385 | 114, 386 | 118, 387 | 101 388 | ]; 389 | }, 390 | { 391 | kind: "account"; 392 | path: "mint"; 393 | } 394 | ]; 395 | }; 396 | }, 397 | { 398 | name: "associatedBondingCurve"; 399 | writable: true; 400 | signer: false; 401 | }, 402 | { 403 | name: "associatedUser"; 404 | writable: true; 405 | signer: false; 406 | }, 407 | { 408 | name: "user"; 409 | writable: true; 410 | signer: true; 411 | }, 412 | { 413 | name: "systemProgram"; 414 | address: "11111111111111111111111111111111"; 415 | }, 416 | { 417 | name: "associatedTokenProgram"; 418 | address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"; 419 | }, 420 | { 421 | name: "tokenProgram"; 422 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 423 | }, 424 | { 425 | name: "eventAuthority"; 426 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 427 | }, 428 | { 429 | name: "program"; 430 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 431 | } 432 | ]; 433 | args: [ 434 | { 435 | name: "amount"; 436 | type: "u64"; 437 | }, 438 | { 439 | name: "minSolOutput"; 440 | type: "u64"; 441 | } 442 | ]; 443 | }, 444 | { 445 | name: "withdraw"; 446 | discriminator: [183, 18, 70, 156, 148, 109, 161, 34]; 447 | docs: [ 448 | "Allows the admin to withdraw liquidity for a migration once the bonding curve completes" 449 | ]; 450 | accounts: [ 451 | { 452 | name: "global"; 453 | writable: false; 454 | pda: { 455 | seeds: [ 456 | { 457 | kind: "const"; 458 | value: [103, 108, 111, 98, 97, 108]; 459 | } 460 | ]; 461 | }; 462 | }, 463 | { 464 | name: "lastWithdraw"; 465 | writable: true; 466 | signer: false; 467 | }, 468 | { 469 | name: "mint"; 470 | writable: false; 471 | signer: false; 472 | }, 473 | { 474 | name: "bondingCurve"; 475 | writable: true; 476 | pda: { 477 | seeds: [ 478 | { 479 | kind: "const"; 480 | value: [ 481 | 98, 482 | 111, 483 | 110, 484 | 100, 485 | 105, 486 | 110, 487 | 103, 488 | 45, 489 | 99, 490 | 117, 491 | 114, 492 | 118, 493 | 101 494 | ]; 495 | }, 496 | { 497 | kind: "account"; 498 | path: "mint"; 499 | } 500 | ]; 501 | }; 502 | }, 503 | { 504 | name: "associatedBondingCurve"; 505 | writable: true; 506 | signer: false; 507 | }, 508 | { 509 | name: "associatedUser"; 510 | writable: true; 511 | signer: false; 512 | }, 513 | { 514 | name: "user"; 515 | writable: true; 516 | signer: true; 517 | }, 518 | { 519 | name: "system_program"; 520 | address: "11111111111111111111111111111111"; 521 | }, 522 | { 523 | name: "tokenProgram"; 524 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 525 | }, 526 | { 527 | name: "rent"; 528 | address: "SysvarRent111111111111111111111111111111111"; 529 | }, 530 | { 531 | name: "eventAuthority"; 532 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 533 | }, 534 | { 535 | name: "program"; 536 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 537 | } 538 | ]; 539 | args: []; 540 | } 541 | ]; 542 | accounts: [ 543 | { 544 | name: "bondingCurve"; 545 | discriminator: [23, 183, 248, 55, 96, 216, 172, 96]; 546 | }, 547 | { 548 | name: "global"; 549 | discriminator: [167, 232, 232, 177, 200, 108, 114, 127]; 550 | } 551 | ]; 552 | events: [ 553 | { 554 | name: "createEvent"; 555 | discriminator: [27, 114, 169, 77, 222, 235, 99, 118]; 556 | }, 557 | { 558 | name: "tradeEvent"; 559 | discriminator: [189, 219, 127, 211, 78, 230, 97, 238]; 560 | }, 561 | { 562 | name: "completeEvent"; 563 | discriminator: [95, 114, 97, 156, 212, 46, 152, 8]; 564 | }, 565 | { 566 | name: "setParamsEvent"; 567 | discriminator: [223, 195, 159, 246, 62, 48, 143, 131]; 568 | } 569 | ]; 570 | types: [ 571 | { 572 | name: "global"; 573 | type: { 574 | kind: "struct"; 575 | fields: [ 576 | { 577 | name: "initialized"; 578 | type: "bool"; 579 | }, 580 | { 581 | name: "authority"; 582 | type: "pubkey"; 583 | }, 584 | { 585 | name: "feeRecipient"; 586 | type: "pubkey"; 587 | }, 588 | { 589 | name: "initialVirtualTokenReserves"; 590 | type: "u64"; 591 | }, 592 | { 593 | name: "initialVirtualSolReserves"; 594 | type: "u64"; 595 | }, 596 | { 597 | name: "initialRealTokenReserves"; 598 | type: "u64"; 599 | }, 600 | { 601 | name: "tokenTotalSupply"; 602 | type: "u64"; 603 | }, 604 | { 605 | name: "feeBasisPoints"; 606 | type: "u64"; 607 | } 608 | ]; 609 | }; 610 | }, 611 | { 612 | name: "lastWithdraw"; 613 | type: { 614 | kind: "struct"; 615 | fields: [ 616 | { 617 | name: "lastWithdrawTimestamp"; 618 | type: "i64"; 619 | } 620 | ]; 621 | }; 622 | }, 623 | { 624 | name: "bondingCurve"; 625 | type: { 626 | kind: "struct"; 627 | fields: [ 628 | { 629 | name: "virtualTokenReserves"; 630 | type: "u64"; 631 | }, 632 | { 633 | name: "virtualSolReserves"; 634 | type: "u64"; 635 | }, 636 | { 637 | name: "realTokenReserves"; 638 | type: "u64"; 639 | }, 640 | { 641 | name: "realSolReserves"; 642 | type: "u64"; 643 | }, 644 | { 645 | name: "tokenTotalSupply"; 646 | type: "u64"; 647 | }, 648 | { 649 | name: "complete"; 650 | type: "bool"; 651 | } 652 | ]; 653 | }; 654 | }, 655 | { 656 | name: "createEvent"; 657 | type: { 658 | kind: "struct"; 659 | fields: [ 660 | { 661 | name: "name"; 662 | type: "string"; 663 | index: false; 664 | }, 665 | { 666 | name: "symbol"; 667 | type: "string"; 668 | index: false; 669 | }, 670 | { 671 | name: "uri"; 672 | type: "string"; 673 | index: false; 674 | }, 675 | { 676 | name: "mint"; 677 | type: "pubkey"; 678 | index: false; 679 | }, 680 | { 681 | name: "bondingCurve"; 682 | type: "pubkey"; 683 | index: false; 684 | }, 685 | { 686 | name: "user"; 687 | type: "pubkey"; 688 | index: false; 689 | } 690 | ]; 691 | }; 692 | }, 693 | { 694 | name: "tradeEvent"; 695 | type: { 696 | kind: "struct"; 697 | fields: [ 698 | { 699 | name: "mint"; 700 | type: "pubkey"; 701 | index: false; 702 | }, 703 | { 704 | name: "solAmount"; 705 | type: "u64"; 706 | index: false; 707 | }, 708 | { 709 | name: "tokenAmount"; 710 | type: "u64"; 711 | index: false; 712 | }, 713 | { 714 | name: "isBuy"; 715 | type: "bool"; 716 | index: false; 717 | }, 718 | { 719 | name: "user"; 720 | type: "pubkey"; 721 | index: false; 722 | }, 723 | { 724 | name: "timestamp"; 725 | type: "i64"; 726 | index: false; 727 | }, 728 | { 729 | name: "virtualSolReserves"; 730 | type: "u64"; 731 | index: false; 732 | }, 733 | { 734 | name: "virtualTokenReserves"; 735 | type: "u64"; 736 | index: false; 737 | }, 738 | { 739 | name: "realSolReserves"; 740 | type: "u64"; 741 | index: false; 742 | }, 743 | { 744 | name: "realTokenReserves"; 745 | type: "u64"; 746 | index: false; 747 | } 748 | ]; 749 | }; 750 | }, 751 | { 752 | name: "completeEvent"; 753 | type: { 754 | kind: "struct"; 755 | fields: [ 756 | { 757 | name: "user"; 758 | type: "pubkey"; 759 | index: false; 760 | }, 761 | { 762 | name: "mint"; 763 | type: "pubkey"; 764 | index: false; 765 | }, 766 | { 767 | name: "bondingCurve"; 768 | type: "pubkey"; 769 | index: false; 770 | }, 771 | { 772 | name: "timestamp"; 773 | type: "i64"; 774 | index: false; 775 | } 776 | ]; 777 | }; 778 | }, 779 | { 780 | name: "setParamsEvent"; 781 | type: { 782 | kind: "struct"; 783 | fields: [ 784 | { 785 | name: "feeRecipient"; 786 | type: "pubkey"; 787 | index: false; 788 | }, 789 | { 790 | name: "initialVirtualTokenReserves"; 791 | type: "u64"; 792 | index: false; 793 | }, 794 | { 795 | name: "initialVirtualSolReserves"; 796 | type: "u64"; 797 | index: false; 798 | }, 799 | { 800 | name: "initialRealTokenReserves"; 801 | type: "u64"; 802 | index: false; 803 | }, 804 | { 805 | name: "tokenTotalSupply"; 806 | type: "u64"; 807 | index: false; 808 | }, 809 | { 810 | name: "feeBasisPoints"; 811 | type: "u64"; 812 | index: false; 813 | } 814 | ]; 815 | }; 816 | } 817 | ]; 818 | errors: [ 819 | { 820 | code: 6000; 821 | name: "NotAuthorized"; 822 | msg: "The given account is not authorized to execute this instruction."; 823 | }, 824 | { 825 | code: 6001; 826 | name: "AlreadyInitialized"; 827 | msg: "The program is already initialized."; 828 | }, 829 | { 830 | code: 6002; 831 | name: "TooMuchSolRequired"; 832 | msg: "slippage: Too much SOL required to buy the given amount of tokens."; 833 | }, 834 | { 835 | code: 6003; 836 | name: "TooLittleSolReceived"; 837 | msg: "slippage: Too little SOL received to sell the given amount of tokens."; 838 | }, 839 | { 840 | code: 6004; 841 | name: "MintDoesNotMatchBondingCurve"; 842 | msg: "The mint does not match the bonding curve."; 843 | }, 844 | { 845 | code: 6005; 846 | name: "BondingCurveComplete"; 847 | msg: "The bonding curve has completed and liquidity migrated to raydium."; 848 | }, 849 | { 850 | code: 6006; 851 | name: "BondingCurveNotComplete"; 852 | msg: "The bonding curve has not completed."; 853 | }, 854 | { 855 | code: 6007; 856 | name: "NotInitialized"; 857 | msg: "The program is not initialized."; 858 | }, 859 | { 860 | code: 6008; 861 | name: "WithdrawTooFrequent"; 862 | msg: "Withdraw too frequent"; 863 | } 864 | ]; 865 | }; -------------------------------------------------------------------------------- /src/IDL/pump-fun.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P", 3 | "metadata": { 4 | "name": "pump", 5 | "version": "0.1.0", 6 | "spec": "0.1.0" 7 | }, 8 | "instructions": [ 9 | { 10 | "name": "initialize", 11 | "discriminator": [175, 175, 109, 31, 13, 152, 155, 237], 12 | "docs": ["Creates the global state."], 13 | "accounts": [ 14 | { 15 | "name": "global", 16 | "writable": true, 17 | "pda": { 18 | "seeds": [ 19 | { 20 | "kind": "const", 21 | "value": [ 22 | 103, 23 | 108, 24 | 111, 25 | 98, 26 | 97, 27 | 108 28 | ] 29 | } 30 | ] 31 | } 32 | }, 33 | { 34 | "name": "user", 35 | "writable": true, 36 | "signer": true 37 | }, 38 | { 39 | "name": "system_program", 40 | "address": "11111111111111111111111111111111" 41 | } 42 | ], 43 | "args": [] 44 | }, 45 | { 46 | "name": "setParams", 47 | "discriminator": [165, 31, 134, 53, 189, 180, 130, 255], 48 | "docs": ["Sets the global state parameters."], 49 | "accounts": [ 50 | { 51 | "name": "global", 52 | "writable": true, 53 | "pda": { 54 | "seeds": [ 55 | { 56 | "kind": "const", 57 | "value": [ 58 | 103, 59 | 108, 60 | 111, 61 | 98, 62 | 97, 63 | 108 64 | ] 65 | } 66 | ] 67 | } 68 | }, 69 | { 70 | "name": "user", 71 | "writable": true, 72 | "signer": true 73 | }, 74 | { 75 | "name": "system_program", 76 | "address": "11111111111111111111111111111111" 77 | }, 78 | { 79 | "name": "event_authority", 80 | "address": "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" 81 | }, 82 | { 83 | "name": "program", 84 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 85 | } 86 | ], 87 | "args": [ 88 | { 89 | "name": "feeRecipient", 90 | "type": "pubkey" 91 | }, 92 | { 93 | "name": "initialVirtualTokenReserves", 94 | "type": "u64" 95 | }, 96 | { 97 | "name": "initialVirtualSolReserves", 98 | "type": "u64" 99 | }, 100 | { 101 | "name": "initialRealTokenReserves", 102 | "type": "u64" 103 | }, 104 | { 105 | "name": "tokenTotalSupply", 106 | "type": "u64" 107 | }, 108 | { 109 | "name": "feeBasisPoints", 110 | "type": "u64" 111 | } 112 | ] 113 | }, 114 | { 115 | "name": "create", 116 | "discriminator": [24, 30, 200, 40, 5, 28, 7, 119], 117 | "docs": ["Creates a new coin and bonding curve."], 118 | "accounts": [ 119 | { 120 | "name": "mint", 121 | "writable": true, 122 | "signer": true 123 | }, 124 | { 125 | "name": "mint_authority", 126 | "pda": { 127 | "seeds": [ 128 | { 129 | "kind": "const", 130 | "value": [ 131 | 109, 132 | 105, 133 | 110, 134 | 116, 135 | 45, 136 | 97, 137 | 117, 138 | 116, 139 | 104, 140 | 111, 141 | 114, 142 | 105, 143 | 116, 144 | 121 145 | ] 146 | } 147 | ] 148 | } 149 | }, 150 | { 151 | "name": "bonding_curve", 152 | "writable": true, 153 | "pda": { 154 | "seeds": [ 155 | { 156 | "kind": "const", 157 | "value": [ 158 | 98, 159 | 111, 160 | 110, 161 | 100, 162 | 105, 163 | 110, 164 | 103, 165 | 45, 166 | 99, 167 | 117, 168 | 114, 169 | 118, 170 | 101 171 | ] 172 | }, 173 | { 174 | "kind": "account", 175 | "path": "mint" 176 | } 177 | ] 178 | } 179 | }, 180 | { 181 | "name": "associated_bonding_curve", 182 | "writable": true, 183 | "signer": false 184 | }, 185 | { 186 | "name": "global", 187 | "writable": false, 188 | "pda": { 189 | "seeds": [ 190 | { 191 | "kind": "const", 192 | "value": [ 193 | 103, 194 | 108, 195 | 111, 196 | 98, 197 | 97, 198 | 108 199 | ] 200 | } 201 | ] 202 | } 203 | }, 204 | { 205 | "name": "mpl_token_metadata", 206 | "address": "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" 207 | }, 208 | { 209 | "name": "metadata", 210 | "writable": true, 211 | "signer": false 212 | }, 213 | { 214 | "name": "user", 215 | "isMut": true, 216 | "isSigner": true 217 | }, 218 | { 219 | "name": "system_program", 220 | "address": "11111111111111111111111111111111" 221 | }, 222 | { 223 | "name": "token_program", 224 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 225 | }, 226 | { 227 | "name": "associated_token_program", 228 | "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" 229 | }, 230 | { 231 | "name": "rent", 232 | "address": "SysvarRent111111111111111111111111111111111" 233 | }, 234 | { 235 | "name": "event_authority", 236 | "address": "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" 237 | }, 238 | { 239 | "name": "program", 240 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 241 | } 242 | ], 243 | "args": [ 244 | { 245 | "name": "name", 246 | "type": "string" 247 | }, 248 | { 249 | "name": "symbol", 250 | "type": "string" 251 | }, 252 | { 253 | "name": "uri", 254 | "type": "string" 255 | } 256 | ] 257 | }, 258 | { 259 | "name": "buy", 260 | "discriminator": [102, 6, 61, 18, 1, 218, 235, 234], 261 | "docs": ["Buys tokens from a bonding curve."], 262 | "accounts": [ 263 | { 264 | "name": "global", 265 | "pda": { 266 | "seeds": [ 267 | { 268 | "kind": "const", 269 | "value": [ 270 | 103, 271 | 108, 272 | 111, 273 | 98, 274 | 97, 275 | 108 276 | ] 277 | } 278 | ] 279 | } 280 | }, 281 | { 282 | "name": "fee_recipient", 283 | "writable": true, 284 | "signer": false 285 | }, 286 | { 287 | "name": "mint", 288 | "writable": false, 289 | "signer": false 290 | }, 291 | { 292 | "name": "bonding_curve", 293 | "writable": true, 294 | "pda": { 295 | "seeds": [ 296 | { 297 | "kind": "const", 298 | "value": [ 299 | 98, 300 | 111, 301 | 110, 302 | 100, 303 | 105, 304 | 110, 305 | 103, 306 | 45, 307 | 99, 308 | 117, 309 | 114, 310 | 118, 311 | 101 312 | ] 313 | }, 314 | { 315 | "kind": "account", 316 | "path": "mint" 317 | } 318 | ] 319 | } 320 | }, 321 | { 322 | "name": "associated_bonding_curve", 323 | "writable": true, 324 | "signer": false 325 | }, 326 | { 327 | "name": "associated_user", 328 | "writable": true, 329 | "signer": false 330 | }, 331 | { 332 | "name": "user", 333 | "writable": true, 334 | "signer": true 335 | }, 336 | { 337 | "name": "system_program", 338 | "address": "11111111111111111111111111111111" 339 | }, 340 | { 341 | "name": "token_program", 342 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 343 | }, 344 | { 345 | "name": "rent", 346 | "address": "SysvarRent111111111111111111111111111111111" 347 | }, 348 | { 349 | "name": "event_authority", 350 | "address": "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" 351 | }, 352 | { 353 | "name": "program", 354 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 355 | } 356 | ], 357 | "args": [ 358 | { 359 | "name": "amount", 360 | "type": "u64" 361 | }, 362 | { 363 | "name": "maxSolCost", 364 | "type": "u64" 365 | } 366 | ] 367 | }, 368 | { 369 | "name": "sell", 370 | "discriminator": [51, 230, 133, 164, 1, 127, 131, 173], 371 | "docs": ["Sells tokens into a bonding curve."], 372 | "accounts": [ 373 | { 374 | "name": "global", 375 | "writable": false, 376 | "pda": { 377 | "seeds": [ 378 | { 379 | "kind": "const", 380 | "value": [ 381 | 103, 382 | 108, 383 | 111, 384 | 98, 385 | 97, 386 | 108 387 | ] 388 | } 389 | ] 390 | } 391 | }, 392 | { 393 | "name": "feeRecipient", 394 | "writable": true, 395 | "signer": false 396 | }, 397 | { 398 | "name": "mint", 399 | "writable": false, 400 | "signer": false 401 | }, 402 | { 403 | "name": "bonding_curve", 404 | "writable": true, 405 | "pda": { 406 | "seeds": [ 407 | { 408 | "kind": "const", 409 | "value": [ 410 | 98, 411 | 111, 412 | 110, 413 | 100, 414 | 105, 415 | 110, 416 | 103, 417 | 45, 418 | 99, 419 | 117, 420 | 114, 421 | 118, 422 | 101 423 | ] 424 | }, 425 | { 426 | "kind": "account", 427 | "path": "mint" 428 | } 429 | ] 430 | } 431 | }, 432 | { 433 | "name": "associatedBondingCurve", 434 | "writable": true, 435 | "signer": false 436 | }, 437 | { 438 | "name": "associatedUser", 439 | "writable": true, 440 | "signer": false 441 | }, 442 | { 443 | "name": "user", 444 | "writable": true, 445 | "signer": true 446 | }, 447 | { 448 | "name": "system_program", 449 | "address": "11111111111111111111111111111111" 450 | }, 451 | { 452 | "name": "associated_token_program", 453 | "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" 454 | }, 455 | { 456 | "name": "token_program", 457 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 458 | }, 459 | { 460 | "name": "event_authority", 461 | "address": "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" 462 | }, 463 | { 464 | "name": "program", 465 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 466 | } 467 | ], 468 | "args": [ 469 | { 470 | "name": "amount", 471 | "type": "u64" 472 | }, 473 | { 474 | "name": "minSolOutput", 475 | "type": "u64" 476 | } 477 | ] 478 | }, 479 | { 480 | "name": "withdraw", 481 | "discriminator": [183, 18, 70, 156, 148, 109, 161, 34], 482 | "docs": [ 483 | "Allows the admin to withdraw liquidity for a migration once the bonding curve completes" 484 | ], 485 | "accounts": [ 486 | { 487 | "name": "global", 488 | "writable": false, 489 | "pda": { 490 | "seeds": [ 491 | { 492 | "kind": "const", 493 | "value": [ 494 | 103, 495 | 108, 496 | 111, 497 | 98, 498 | 97, 499 | 108 500 | ] 501 | } 502 | ] 503 | } 504 | }, 505 | { 506 | "name": "lastWithdraw", 507 | "writable": true, 508 | "signer": false 509 | }, 510 | { 511 | "name": "mint", 512 | "writable": false, 513 | "signer": false 514 | }, 515 | { 516 | "name": "bonding_curve", 517 | "writable": true, 518 | "pda": { 519 | "seeds": [ 520 | { 521 | "kind": "const", 522 | "value": [ 523 | 98, 524 | 111, 525 | 110, 526 | 100, 527 | 105, 528 | 110, 529 | 103, 530 | 45, 531 | 99, 532 | 117, 533 | 114, 534 | 118, 535 | 101 536 | ] 537 | }, 538 | { 539 | "kind": "account", 540 | "path": "mint" 541 | } 542 | ] 543 | } 544 | }, 545 | { 546 | "name": "associatedBondingCurve", 547 | "writable": true, 548 | "signer": false 549 | }, 550 | { 551 | "name": "associatedUser", 552 | "writable": true, 553 | "signer": false 554 | }, 555 | { 556 | "name": "user", 557 | "writable": true, 558 | "signer": true 559 | }, 560 | { 561 | "name": "system_program", 562 | "address": "11111111111111111111111111111111" 563 | }, 564 | { 565 | "name": "token_program", 566 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 567 | }, 568 | { 569 | "name": "rent", 570 | "address": "SysvarRent111111111111111111111111111111111" 571 | }, 572 | { 573 | "name": "event_authority", 574 | "address": "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" 575 | }, 576 | { 577 | "name": "program", 578 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 579 | } 580 | ], 581 | "args": [] 582 | } 583 | ], 584 | "accounts": [ 585 | { 586 | "name": "BondingCurve", 587 | "discriminator": [ 588 | 23, 589 | 183, 590 | 248, 591 | 55, 592 | 96, 593 | 216, 594 | 172, 595 | 96 596 | ] 597 | }, 598 | { 599 | "name": "Global", 600 | "discriminator": [ 601 | 167, 602 | 232, 603 | 232, 604 | 177, 605 | 200, 606 | 108, 607 | 114, 608 | 127 609 | ] 610 | } 611 | ], 612 | "events": [ 613 | { 614 | "name": "CreateEvent", 615 | "discriminator": [27, 114, 169, 77, 222, 235, 99, 118] 616 | }, 617 | { 618 | "name": "TradeEvent", 619 | "discriminator": [189, 219, 127, 211, 78, 230, 97, 238] 620 | }, 621 | { 622 | "name": "CompleteEvent", 623 | "discriminator": [95, 114, 97, 156, 212, 46, 152, 8] 624 | }, 625 | { 626 | "name": "SetParamsEvent", 627 | "discriminator": [223, 195, 159, 246, 62, 48, 143, 131] 628 | } 629 | ], 630 | "types": [ 631 | { 632 | "name": "Global", 633 | "type": { 634 | "kind": "struct", 635 | "fields": [ 636 | { 637 | "name": "initialized", 638 | "type": "bool" 639 | }, 640 | { 641 | "name": "authority", 642 | "type": "pubkey" 643 | }, 644 | { 645 | "name": "feeRecipient", 646 | "type": "pubkey" 647 | }, 648 | { 649 | "name": "initialVirtualTokenReserves", 650 | "type": "u64" 651 | }, 652 | { 653 | "name": "initialVirtualSolReserves", 654 | "type": "u64" 655 | }, 656 | { 657 | "name": "initialRealTokenReserves", 658 | "type": "u64" 659 | }, 660 | { 661 | "name": "tokenTotalSupply", 662 | "type": "u64" 663 | }, 664 | { 665 | "name": "feeBasisPoints", 666 | "type": "u64" 667 | } 668 | ] 669 | } 670 | }, 671 | { 672 | "name": "LastWithdraw", 673 | "type": { 674 | "kind": "struct", 675 | "fields": [ 676 | { 677 | "name": "lastWithdrawTimestamp", 678 | "type": "i64" 679 | } 680 | ] 681 | } 682 | }, 683 | { 684 | "name": "BondingCurve", 685 | "type": { 686 | "kind": "struct", 687 | "fields": [ 688 | { 689 | "name": "virtualTokenReserves", 690 | "type": "u64" 691 | }, 692 | { 693 | "name": "virtualSolReserves", 694 | "type": "u64" 695 | }, 696 | { 697 | "name": "realTokenReserves", 698 | "type": "u64" 699 | }, 700 | { 701 | "name": "realSolReserves", 702 | "type": "u64" 703 | }, 704 | { 705 | "name": "tokenTotalSupply", 706 | "type": "u64" 707 | }, 708 | { 709 | "name": "complete", 710 | "type": "bool" 711 | } 712 | ] 713 | } 714 | }, 715 | { 716 | "name": "CreateEvent", 717 | "type": { 718 | "kind": "struct", 719 | "fields": [ 720 | { 721 | "name": "name", 722 | "type": "string", 723 | "index": false 724 | }, 725 | { 726 | "name": "symbol", 727 | "type": "string", 728 | "index": false 729 | }, 730 | { 731 | "name": "uri", 732 | "type": "string", 733 | "index": false 734 | }, 735 | { 736 | "name": "mint", 737 | "type": "pubkey", 738 | "index": false 739 | }, 740 | { 741 | "name": "bondingCurve", 742 | "type": "pubkey", 743 | "index": false 744 | }, 745 | { 746 | "name": "user", 747 | "type": "pubkey", 748 | "index": false 749 | } 750 | ] 751 | } 752 | }, 753 | { 754 | "name": "TradeEvent", 755 | "type": { 756 | "kind": "struct", 757 | "fields": [ 758 | { 759 | "name": "mint", 760 | "type": "pubkey", 761 | "index": false 762 | }, 763 | { 764 | "name": "solAmount", 765 | "type": "u64", 766 | "index": false 767 | }, 768 | { 769 | "name": "tokenAmount", 770 | "type": "u64", 771 | "index": false 772 | }, 773 | { 774 | "name": "isBuy", 775 | "type": "bool", 776 | "index": false 777 | }, 778 | { 779 | "name": "user", 780 | "type": "pubkey", 781 | "index": false 782 | }, 783 | { 784 | "name": "timestamp", 785 | "type": "i64", 786 | "index": false 787 | }, 788 | { 789 | "name": "virtualSolReserves", 790 | "type": "u64", 791 | "index": false 792 | }, 793 | { 794 | "name": "virtualTokenReserves", 795 | "type": "u64", 796 | "index": false 797 | }, 798 | { 799 | "name": "realSolReserves", 800 | "type": "u64", 801 | "index": false 802 | }, 803 | { 804 | "name": "realTokenReserves", 805 | "type": "u64", 806 | "index": false 807 | } 808 | ] 809 | } 810 | }, 811 | { 812 | "name": "CompleteEvent", 813 | "type": { 814 | "kind": "struct", 815 | "fields": [ 816 | { 817 | "name": "user", 818 | "type": "pubkey", 819 | "index": false 820 | }, 821 | { 822 | "name": "mint", 823 | "type": "pubkey", 824 | "index": false 825 | }, 826 | { 827 | "name": "bondingCurve", 828 | "type": "pubkey", 829 | "index": false 830 | }, 831 | { 832 | "name": "timestamp", 833 | "type": "i64", 834 | "index": false 835 | } 836 | ] 837 | } 838 | }, 839 | { 840 | "name": "SetParamsEvent", 841 | "type": { 842 | "kind": "struct", 843 | "fields": [ 844 | { 845 | "name": "feeRecipient", 846 | "type": "pubkey", 847 | "index": false 848 | }, 849 | { 850 | "name": "initialVirtualTokenReserves", 851 | "type": "u64", 852 | "index": false 853 | }, 854 | { 855 | "name": "initialVirtualSolReserves", 856 | "type": "u64", 857 | "index": false 858 | }, 859 | { 860 | "name": "initialRealTokenReserves", 861 | "type": "u64", 862 | "index": false 863 | }, 864 | { 865 | "name": "tokenTotalSupply", 866 | "type": "u64", 867 | "index": false 868 | }, 869 | { 870 | "name": "feeBasisPoints", 871 | "type": "u64", 872 | "index": false 873 | } 874 | ] 875 | } 876 | } 877 | ], 878 | "errors": [ 879 | { 880 | "code": 6000, 881 | "name": "NotAuthorized", 882 | "msg": "The given account is not authorized to execute this instruction." 883 | }, 884 | { 885 | "code": 6001, 886 | "name": "AlreadyInitialized", 887 | "msg": "The program is already initialized." 888 | }, 889 | { 890 | "code": 6002, 891 | "name": "TooMuchSolRequired", 892 | "msg": "slippage: Too much SOL required to buy the given amount of tokens." 893 | }, 894 | { 895 | "code": 6003, 896 | "name": "TooLittleSolReceived", 897 | "msg": "slippage: Too little SOL received to sell the given amount of tokens." 898 | }, 899 | { 900 | "code": 6004, 901 | "name": "MintDoesNotMatchBondingCurve", 902 | "msg": "The mint does not match the bonding curve." 903 | }, 904 | { 905 | "code": 6005, 906 | "name": "BondingCurveComplete", 907 | "msg": "The bonding curve has completed and liquidity migrated to raydium." 908 | }, 909 | { 910 | "code": 6006, 911 | "name": "BondingCurveNotComplete", 912 | "msg": "The bonding curve has not completed." 913 | }, 914 | { 915 | "code": 6007, 916 | "name": "NotInitialized", 917 | "msg": "The program is not initialized." 918 | }, 919 | { 920 | "code": 6008, 921 | "name": "WithdrawTooFrequent", 922 | "msg": "Withdraw too frequent" 923 | } 924 | ] 925 | } 926 | --------------------------------------------------------------------------------