├── .npmignore ├── .env.example ├── upload ├── img.png └── metadata.json ├── src ├── IDL │ ├── index.ts │ ├── pump-fun.ts │ └── pump-fun.json ├── index.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 ├── metadata.ts ├── tsconfig.base.json ├── rollup.config.js ├── LICENSE ├── README.md ├── package.json ├── utils.ts └── index.ts /.npmignore: -------------------------------------------------------------------------------- 1 | example/ 2 | script/ -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | PRIVATE_KEY= 2 | HELIUS_RPC_URL= -------------------------------------------------------------------------------- /upload/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Immutal0/pumpfun-raydium-bundler/HEAD/upload/img.png -------------------------------------------------------------------------------- /src/IDL/index.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | export { default as IDL } from "./pump-fun.json"; 5 | export { PumpFun } from "./pump-fun"; 6 | 7 | -------------------------------------------------------------------------------- /.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 | .env.copy 16 | refs/ -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | export * from './pumpfun' 5 | export * from './util' 6 | export * from './types' 7 | export * from './events' 8 | export * from './globalAccount' 9 | export * from './bondingCurveAccount' 10 | export * from './amm' 11 | -------------------------------------------------------------------------------- /upload/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Immutal0 Token", 3 | "symbol": "IMMUTAL0", 4 | "description": "Pump Fun Immutal0 Token", 5 | "image": "https://amber-giant-dormouse-64.mypinata.cloud/ipfs/bafybeihprwlepqebysbaks6pi7w2b7vwgss4mqfo4uvs4meix2ncljjqfu", 6 | "showName": true, 7 | "createdOn": "https://pump.fun", 8 | "twitter": "https://x.com/Immutal0_", 9 | "telegram": "https://t.me/Immutal0", 10 | "website": "" 11 | } -------------------------------------------------------------------------------- /metadata.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | const metadata = { 5 | "name": "Immutal0 Token", 6 | "symbol": "IMMUTAL0", 7 | "description": "Pump Fun Immutal0 Token", 8 | "image": "./upload/img.png", 9 | "showName": true, 10 | "createdOn": "https://pump.fun", 11 | "twitter": "https://x.com/Immutal0_", 12 | "telegram": "https://t.me/Immutal0", 13 | "website": "https://github.com/Immutal0" 14 | } 15 | 16 | export default metadata; -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { Commitment, PublicKey } from "@solana/web3.js"; 5 | import { Connection, Keypair } from "@solana/web3.js"; 6 | import * as bs58 from "bs58"; 7 | 8 | export const rpc_https_url = 9 | "https://white-aged-glitter.solana-mainnet.quiknode.pro/743d4e1e3949c3127beb7f7815cf2ca9743b43a6/"; 10 | 11 | export const blockEngineUrl = "tokyo.mainnet.block-engine.jito.wtf"; 12 | export const connection = new Connection(rpc_https_url, "confirmed"); 13 | 14 | -------------------------------------------------------------------------------- /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 | }; -------------------------------------------------------------------------------- /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. 20 | 21 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | export const RPC_ENDPOINT = 4 | "https://mainnet.helius-rpc.com/?api-key=c7de8383-67ff-4e3b-aba5-c7c915635375/"; 5 | export const RPC_WEBSOCKET_ENDPOINT = 6 | "wss://mainnet.helius-rpc.com/?api-key=c7de8383-67ff-4e3b-aba5-c7c915635375/"; 7 | export const JITO_FEE = 1000000; 8 | export const COMMITMENT_LEVEL = "confirmed"; 9 | export const JITO_KEY = 10 | "66xqL9aFZJ8k9YpjNBexNASfuoDgNE1ZpGRXB28zoTfS4u2czzVBhMNMqgZYFeMN8FnUi6gMzXWgVYRHkTZ6yuLC"; 11 | export const BLOCKENGINE_URL = "tokyo.mainnet.block-engine.jito.wtf"; 12 | export const JITO_AUTH_KEYPAIR = 13 | "66xqL9aFZJ8k9YpjNBexNASfuoDgNE1ZpGRXB28zoTfS4u2czzVBhMNMqgZYFeMN8FnUi6gMzXWgVYRHkTZ6yuLC"; 14 | 15 | export const CHECK_FILTER = true; 16 | export const CHECK_SOCIAL = true; 17 | export const CHECK_NAMEWHITELIST = false; 18 | export const CHECK_NAMEBLACKLIST = false; 19 | export const CHECK_WALLETWHITELIST = false; 20 | export const CHECK_WALLETBLACKLIST = false; 21 | export const CHECK_SOLDBALANCE = true; 22 | export const USE_SNIPE_LIST = false; 23 | export const JITO_MODE = true; 24 | export const JITO_ALL = false; 25 | export const stop_loss = -0.1; 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🤖Pumpfun Bundler 2 | 3 | Pumpfun bundler which allows you bundle create & buy transactions on Pumpfun. 4 | 5 | ## I have upgraded version that can bundle 20 buys. 6 | 7 | https://solscan.io/tx/5MtjdECJtnZ1HVmRViqvVRjy425fPkhdjy5BDmjcGBrbPZK9y6caMkPmfwxycVMAKtdXRF8HXDAoVRkwAqABg3q5 8 | https://solscan.io/tx/4YCPCrhUYEaeKw1qb7JCf24nHJ5c6NNiRpAqyttkmaLuEduvoE6Aqqh8SkHBoN352FTHWCFVVGuavUdPajSKEMZw 9 | https://solscan.io/tx/b9fzcKwvxQN7sxz1wC2aJxUyMgLXGb7XY9YBHZ9kRpzRz5kcfgLNvTv4RAw9jw4c9GFXQYPoP8GbnHEHcCFCiPL 10 | https://solscan.io/tx/2jUs984mYmJBxLqb3RFeHz7tZkLra3Ws4zoXtK46xWsCFBsZ4raJvZEDNdGKgs8BtU1DxMVCoqQGseT6mx7yroDp 11 | 12 |
13 | 14 | ## 💬Contact Me 15 | 16 | If you have any question or something, feel free to reach out me anytime via telegram, discord or twitter. 17 |
18 | #### 🌹You're always welcome🌹 19 | 20 | Telegram: [@frankeindev](https://t.me/frankeindev)
21 | 22 | 23 | ## 👀Usage 24 | 1. Clone the repository 25 | 26 | ``` 27 | git clone https://github.com/Immutal0/pumpfun-bundler.git 28 | cd pumpfun-bundler 29 | ``` 30 | 2. Install dependencies 31 | 32 | ``` 33 | npm install 34 | ``` 35 | 3. Configure the environment variables 36 | 37 | Rename the .env.example file to .env and set RPC, main keypair's secret key. 38 | 39 | 5. Run the bot 40 | 41 | ``` 42 | npm start 43 | ``` 44 | 45 | ## Update metada 46 | 47 | Update metadata.ts, /upload/img.png and /upload/metadata.json. 48 | Then you can create your own token. 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pumpdotfun-v1", 3 | "version": "1.3.2", 4 | "description": "Pumpfun bundler version1 buy tokens with 3 wallets", 5 | "module": "./dist/esm/index.js", 6 | "main": "./dist/cjs/index.js", 7 | "browser": "./dist/browser/index.js", 8 | "types": "dist/cjs/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "start": "npx ts-node ./index.ts" 12 | }, 13 | "files": [ 14 | "dist", 15 | "types" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/Immutal0/pumpfun-bundler.git" 20 | }, 21 | "keywords": [ 22 | "pumpdotfun", 23 | "sdk", 24 | "solana" 25 | ], 26 | "author": "", 27 | "license": "ISC", 28 | "devDependencies": { 29 | "@coral-xyz/borsh": "^0.30.1", 30 | "@rollup/plugin-commonjs": "^26.0.1", 31 | "@rollup/plugin-node-resolve": "^15.2.3", 32 | "@rollup/plugin-replace": "^5.0.7", 33 | "@rollup/plugin-typescript": "^11.1.6", 34 | "@types/bn.js": "^5.1.5", 35 | "@types/node": "^20.14.1", 36 | "dotenv": "^16.4.5", 37 | "js-sha256": "^0.11.0", 38 | "rimraf": "^3.0.2", 39 | "rollup": "^4.18.0", 40 | "ts-node": "^10.9.2" 41 | }, 42 | "dependencies": { 43 | "@coral-xyz/anchor": "^0.30.1", 44 | "@fleekxyz/sdk": "^1.4.2", 45 | "@rollup/plugin-json": "^6.1.0", 46 | "@solana/spl-token": "^0.4.0", 47 | "@solana/web3.js": "^1.89.1", 48 | "axios": "^1.6.8", 49 | "jito-ts": "^4.1.0", 50 | "tsx": "^4.16.2", 51 | "typescript": "^5.3.3", 52 | "undici": "^6.19.2" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/events.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { PublicKey } from "@solana/web3.js"; 5 | import { 6 | CompleteEvent, 7 | CreateEvent, 8 | SetParamsEvent, 9 | TradeEvent, 10 | } from "./types"; 11 | 12 | export function toCreateEvent(event: CreateEvent): CreateEvent { 13 | return { 14 | name: event.name, 15 | symbol: event.symbol, 16 | uri: event.uri, 17 | mint: new PublicKey(event.mint), 18 | bondingCurve: new PublicKey(event.bondingCurve), 19 | user: new PublicKey(event.user), 20 | }; 21 | } 22 | 23 | export function toCompleteEvent(event: CompleteEvent): CompleteEvent { 24 | return { 25 | user: new PublicKey(event.user), 26 | mint: new PublicKey(event.mint), 27 | bondingCurve: new PublicKey(event.bondingCurve), 28 | timestamp: event.timestamp, 29 | }; 30 | } 31 | 32 | export function toTradeEvent(event: TradeEvent): TradeEvent { 33 | return { 34 | mint: new PublicKey(event.mint), 35 | solAmount: BigInt(event.solAmount), 36 | tokenAmount: BigInt(event.tokenAmount), 37 | isBuy: event.isBuy, 38 | user: new PublicKey(event.user), 39 | timestamp: Number(event.timestamp), 40 | virtualSolReserves: BigInt(event.virtualSolReserves), 41 | virtualTokenReserves: BigInt(event.virtualTokenReserves), 42 | realSolReserves: BigInt(event.realSolReserves), 43 | realTokenReserves: BigInt(event.realTokenReserves), 44 | }; 45 | } 46 | 47 | export function toSetParamsEvent(event: SetParamsEvent): SetParamsEvent { 48 | return { 49 | feeRecipient: new PublicKey(event.feeRecipient), 50 | initialVirtualTokenReserves: BigInt(event.initialVirtualTokenReserves), 51 | initialVirtualSolReserves: BigInt(event.initialVirtualSolReserves), 52 | initialRealTokenReserves: BigInt(event.initialRealTokenReserves), 53 | tokenTotalSupply: BigInt(event.tokenTotalSupply), 54 | feeBasisPoints: BigInt(event.feeBasisPoints), 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /utils.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { getAssociatedTokenAddressSync } from "@solana/spl-token"; 5 | import { 6 | Keypair, 7 | PublicKey, 8 | Connection, 9 | LAMPORTS_PER_SOL, 10 | } from "@solana/web3.js"; 11 | import { sha256 } from "js-sha256"; 12 | 13 | import fs from "fs"; 14 | 15 | export const printSOLBalance = async ( 16 | connection: Connection, 17 | pubKey: PublicKey, 18 | info: string = "" 19 | ) => { 20 | const balance = await connection.getBalance(pubKey); 21 | console.log( 22 | `${info ? info + " " : ""}${pubKey.toBase58()}:`, 23 | balance / LAMPORTS_PER_SOL, 24 | `SOL` 25 | ); 26 | }; 27 | 28 | export const getSPLBalance = async ( 29 | connection: Connection, 30 | mintAddress: PublicKey, 31 | pubKey: PublicKey, 32 | allowOffCurve: boolean = false 33 | ) => { 34 | try { 35 | let ata = getAssociatedTokenAddressSync(mintAddress, pubKey, allowOffCurve); 36 | const balance = await connection.getTokenAccountBalance(ata, "processed"); 37 | return balance.value.uiAmount; 38 | } catch (e) {} 39 | return null; 40 | }; 41 | 42 | export const printSPLBalance = async ( 43 | connection: Connection, 44 | mintAddress: PublicKey, 45 | user: PublicKey, 46 | info: string = "" 47 | ) => { 48 | const balance = await getSPLBalance(connection, mintAddress, user); 49 | if (balance === null) { 50 | console.log( 51 | `${info ? info + " " : ""}${user.toBase58()}:`, 52 | "No Account Found" 53 | ); 54 | } else { 55 | console.log(`${info ? info + " " : ""}${user.toBase58()}:`, balance); 56 | } 57 | }; 58 | 59 | export const baseToValue = (base: number, decimals: number): number => { 60 | return base * Math.pow(10, decimals); 61 | }; 62 | 63 | export const valueToBase = (value: number, decimals: number): number => { 64 | return value / Math.pow(10, decimals); 65 | }; 66 | 67 | //i.e. account:BondingCurve 68 | export function getDiscriminator(name: string) { 69 | return sha256.digest(name).slice(0, 8); 70 | } 71 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { PublicKey, VersionedTransactionResponse } from "@solana/web3.js"; 5 | 6 | export type CreateTokenMetadata = { 7 | name: string; 8 | symbol: string; 9 | description: string; 10 | file: Blob; 11 | twitter?: string; 12 | telegram?: string; 13 | website?: string; 14 | }; 15 | 16 | export type TokenMetadata = { 17 | name: string; 18 | symbol: string; 19 | description: string; 20 | image: string; 21 | showName: boolean; 22 | createdOn: string; 23 | twitter: string; 24 | }; 25 | 26 | export type CreateEvent = { 27 | name: string; 28 | symbol: string; 29 | uri: string; 30 | mint: PublicKey; 31 | bondingCurve: PublicKey; 32 | user: PublicKey; 33 | }; 34 | 35 | export type TradeEvent = { 36 | mint: PublicKey; 37 | solAmount: bigint; 38 | tokenAmount: bigint; 39 | isBuy: boolean; 40 | user: PublicKey; 41 | timestamp: number; 42 | virtualSolReserves: bigint; 43 | virtualTokenReserves: bigint; 44 | realSolReserves: bigint; 45 | realTokenReserves: bigint; 46 | }; 47 | 48 | export type CompleteEvent = { 49 | user: PublicKey; 50 | mint: PublicKey; 51 | bondingCurve: PublicKey; 52 | timestamp: number; 53 | }; 54 | 55 | export type SetParamsEvent = { 56 | feeRecipient: PublicKey; 57 | initialVirtualTokenReserves: bigint; 58 | initialVirtualSolReserves: bigint; 59 | initialRealTokenReserves: bigint; 60 | tokenTotalSupply: bigint; 61 | feeBasisPoints: bigint; 62 | }; 63 | 64 | export interface PumpFunEventHandlers { 65 | createEvent: CreateEvent; 66 | tradeEvent: TradeEvent; 67 | completeEvent: CompleteEvent; 68 | setParamsEvent: SetParamsEvent; 69 | } 70 | 71 | export type PumpFunEventType = keyof PumpFunEventHandlers; 72 | 73 | export type PriorityFee = { 74 | unitLimit: number; 75 | unitPrice: number; 76 | }; 77 | 78 | export type TransactionResult = { 79 | signature?: string; 80 | error?: unknown; 81 | results?: VersionedTransactionResponse; 82 | success: boolean; 83 | }; 84 | -------------------------------------------------------------------------------- /src/uploadToIpfs.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import fs from 'fs'; 5 | import dotenv from 'dotenv'; 6 | import { FleekSdk, PersonalAccessTokenService } from '@fleekxyz/sdk'; 7 | import metadata from '../metadata'; 8 | dotenv.config(); 9 | 10 | const pat = process.env.PAT || ''; 11 | const project_id = process.env.PROJECT_ID || ''; 12 | const imageName = "./upload/img.png"; 13 | const metadataName = "./upload/metadata.json"; 14 | 15 | const patService = new PersonalAccessTokenService({ 16 | personalAccessToken: pat, 17 | projectId: project_id, 18 | }) 19 | 20 | const fleekSdk = new FleekSdk({ accessTokenService: patService }) 21 | 22 | async function uploadFileToIPFS(filename: string, content: Buffer) { 23 | const result = await fleekSdk.ipfs().add({ 24 | path: filename, 25 | content: content 26 | }); 27 | return result; 28 | } 29 | 30 | export const getUploadedMetadataURI = async (): Promise => { 31 | const fileContent = fs.readFileSync(imageName); 32 | 33 | try { 34 | const imageUploadResult = await uploadFileToIPFS(imageName, fileContent); 35 | console.log('Image uploaded to IPFS:', imageUploadResult); 36 | console.log('IPFS URL:', `https://cf-ipfs.com/ipfs/${imageUploadResult.cid}`); 37 | 38 | const data = { 39 | "name": metadata.name, 40 | "symbol": metadata.symbol, 41 | "description": metadata.description, 42 | "image": `https://cf-ipfs.com/ipfs/${imageUploadResult.cid}`, 43 | "showName": metadata.showName, 44 | "createdOn": metadata.createdOn, 45 | "twitter": metadata.twitter, 46 | "telegram": metadata.telegram, 47 | "website": metadata.website 48 | } 49 | const metadataString = JSON.stringify(data); 50 | const bufferContent = Buffer.from(metadataString, 'utf-8'); 51 | fs.writeFileSync(metadataName, bufferContent); 52 | const metadataContent = fs.readFileSync(metadataName); 53 | 54 | const metadataUploadResult = await uploadFileToIPFS(metadataName, metadataContent); 55 | console.log('File uploaded to IPFS:', metadataUploadResult); 56 | console.log('IPFS URL:', `https://cf-ipfs.com/ipfs/${metadataUploadResult.cid}`) 57 | return `https://cf-ipfs.com/ipfs/${metadataUploadResult.cid}`; 58 | } catch (error) { 59 | return ""; 60 | } 61 | } -------------------------------------------------------------------------------- /src/globalAccount.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { PublicKey } from "@solana/web3.js"; 5 | import { struct, bool, u64, publicKey, Layout } from "@coral-xyz/borsh"; 6 | 7 | export class GlobalAccount { 8 | public discriminator: bigint; 9 | public initialized: boolean = false; 10 | public authority: PublicKey; 11 | public feeRecipient: PublicKey; 12 | public initialVirtualTokenReserves: bigint; 13 | public initialVirtualSolReserves: bigint; 14 | public initialRealTokenReserves: bigint; 15 | public tokenTotalSupply: bigint; 16 | public feeBasisPoints: bigint; 17 | 18 | constructor( 19 | discriminator: bigint, 20 | initialized: boolean, 21 | authority: PublicKey, 22 | feeRecipient: PublicKey, 23 | initialVirtualTokenReserves: bigint, 24 | initialVirtualSolReserves: bigint, 25 | initialRealTokenReserves: bigint, 26 | tokenTotalSupply: bigint, 27 | feeBasisPoints: bigint 28 | ) { 29 | this.discriminator = discriminator; 30 | this.initialized = initialized; 31 | this.authority = authority; 32 | this.feeRecipient = feeRecipient; 33 | this.initialVirtualTokenReserves = initialVirtualTokenReserves; 34 | this.initialVirtualSolReserves = initialVirtualSolReserves; 35 | this.initialRealTokenReserves = initialRealTokenReserves; 36 | this.tokenTotalSupply = tokenTotalSupply; 37 | this.feeBasisPoints = feeBasisPoints; 38 | } 39 | 40 | getInitialBuyPrice(amount: bigint): bigint { 41 | if (amount <= 0n) { 42 | return 0n; 43 | } 44 | 45 | let n = this.initialVirtualSolReserves * this.initialVirtualTokenReserves; 46 | let i = this.initialVirtualSolReserves + amount; 47 | let r = n / i + 1n; 48 | let s = this.initialVirtualTokenReserves - r; 49 | return s < this.initialRealTokenReserves 50 | ? s 51 | : this.initialRealTokenReserves; 52 | } 53 | 54 | public static fromBuffer(buffer: Buffer): GlobalAccount { 55 | const structure: Layout = struct([ 56 | u64("discriminator"), 57 | bool("initialized"), 58 | publicKey("authority"), 59 | publicKey("feeRecipient"), 60 | u64("initialVirtualTokenReserves"), 61 | u64("initialVirtualSolReserves"), 62 | u64("initialRealTokenReserves"), 63 | u64("tokenTotalSupply"), 64 | u64("feeBasisPoints"), 65 | ]); 66 | 67 | let value = structure.decode(buffer); 68 | return new GlobalAccount( 69 | BigInt(value.discriminator), 70 | value.initialized, 71 | value.authority, 72 | value.feeRecipient, 73 | BigInt(value.initialVirtualTokenReserves), 74 | BigInt(value.initialVirtualSolReserves), 75 | BigInt(value.initialRealTokenReserves), 76 | BigInt(value.tokenTotalSupply), 77 | BigInt(value.feeBasisPoints) 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/amm.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { BondingCurveAccount } from "./bondingCurveAccount"; 5 | import { GlobalAccount } from "./globalAccount"; 6 | 7 | export type BuyResult = { 8 | token_amount: bigint; 9 | sol_amount: bigint; 10 | }; 11 | 12 | export type SellResult = { 13 | token_amount: bigint; 14 | sol_amount: bigint; 15 | }; 16 | 17 | export class AMM { 18 | constructor( 19 | public virtualSolReserves: bigint, 20 | public virtualTokenReserves: bigint, 21 | public realSolReserves: bigint, 22 | public realTokenReserves: bigint, 23 | public initialVirtualTokenReserves: bigint 24 | ) {} 25 | 26 | static fromGlobalAccount(global: GlobalAccount): AMM { 27 | return new AMM( 28 | global.initialVirtualSolReserves, 29 | global.initialVirtualTokenReserves, 30 | 0n, 31 | global.initialRealTokenReserves, 32 | global.initialVirtualTokenReserves 33 | ); 34 | } 35 | 36 | static fromBondingCurveAccount(bonding_curve: BondingCurveAccount, initialVirtualTokenReserves: bigint): AMM { 37 | return new AMM( 38 | bonding_curve.virtualSolReserves, 39 | bonding_curve.virtualTokenReserves, 40 | bonding_curve.realSolReserves, 41 | bonding_curve.realTokenReserves, 42 | initialVirtualTokenReserves 43 | ); 44 | } 45 | 46 | getBuyPrice(tokens: bigint): bigint { 47 | const product_of_reserves = this.virtualSolReserves * this.virtualTokenReserves; 48 | const new_virtual_token_reserves = this.virtualTokenReserves - tokens; 49 | const new_virtual_sol_reserves = product_of_reserves / new_virtual_token_reserves + 1n; 50 | const amount_needed = new_virtual_sol_reserves > this.virtualSolReserves ? new_virtual_sol_reserves - this.virtualSolReserves : 0n; 51 | return amount_needed > 0n ? amount_needed : 0n; 52 | } 53 | 54 | applyBuy(token_amount: bigint): BuyResult { 55 | const final_token_amount = token_amount > this.realTokenReserves ? this.realTokenReserves : token_amount; 56 | const sol_amount = this.getBuyPrice(final_token_amount); 57 | 58 | this.virtualTokenReserves = this.virtualTokenReserves - final_token_amount; 59 | this.realTokenReserves = this.realTokenReserves - final_token_amount; 60 | 61 | this.virtualSolReserves = this.virtualSolReserves + sol_amount; 62 | this.realSolReserves = this.realSolReserves + sol_amount; 63 | 64 | return { 65 | token_amount: final_token_amount, 66 | sol_amount: sol_amount 67 | } 68 | } 69 | 70 | applySell(token_amount: bigint): SellResult { 71 | this.virtualTokenReserves = this.virtualTokenReserves + token_amount; 72 | this.realTokenReserves = this.realTokenReserves + token_amount; 73 | 74 | const sell_price = this.getSellPrice(token_amount); 75 | 76 | this.virtualSolReserves = this.virtualSolReserves - sell_price; 77 | this.realSolReserves = this.realSolReserves - sell_price; 78 | 79 | return { 80 | token_amount: token_amount, 81 | sol_amount: sell_price 82 | } 83 | } 84 | 85 | getSellPrice(tokens: bigint): bigint { 86 | const scaling_factor = this.initialVirtualTokenReserves; 87 | const token_sell_proportion = (tokens * scaling_factor) / this.virtualTokenReserves; 88 | const sol_received = (this.virtualSolReserves * token_sell_proportion) / scaling_factor; 89 | return sol_received < this.realSolReserves ? sol_received : this.realSolReserves; 90 | } 91 | } -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import dotenv from "dotenv"; 5 | import fs, { openAsBlob } from "fs"; 6 | import { 7 | Connection, 8 | Keypair, 9 | LAMPORTS_PER_SOL, 10 | } from "@solana/web3.js"; 11 | import { PumpFunSDK } from "./src"; 12 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 13 | import { AnchorProvider } from "@coral-xyz/anchor"; 14 | import { 15 | printSOLBalance, 16 | printSPLBalance, 17 | } from "./utils"; 18 | import metadata from "./metadata"; 19 | import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; 20 | 21 | const SLIPPAGE_BASIS_POINTS = 100n; 22 | 23 | const main = async () => { 24 | dotenv.config(); 25 | 26 | if (!process.env.HELIUS_RPC_URL) { 27 | console.error("Need HELIUS_RPC_URL in .env file"); 28 | console.error( 29 | "Example: HELIUS_RPC_URL=https://mainnet.helius-rpc.com/?api-key=" 30 | ); 31 | console.error("Get one from Helius Offical Website : https://www.helius.dev"); 32 | return; 33 | } 34 | 35 | let connection = new Connection(process.env.HELIUS_RPC_URL || ""); 36 | 37 | let wallet = new NodeWallet(new Keypair()); //note this is not used 38 | const provider = new AnchorProvider(connection, wallet, { 39 | commitment: "finalized", 40 | }); 41 | 42 | if (!process.env.PRIVATE_KEY) { 43 | console.error("Need your private key in .env file"); 44 | return; 45 | } 46 | 47 | const private_key = process.env.PRIVATE_KEY; 48 | 49 | const buyer = Keypair.fromSecretKey(bs58.decode(private_key)); 50 | const mint = Keypair.generate(); 51 | 52 | await printSOLBalance( 53 | connection, 54 | buyer.publicKey, 55 | "Your Account Pubkey :" 56 | ); 57 | 58 | let sdk = new PumpFunSDK(provider); 59 | 60 | let currentSolBalance = await connection.getBalance(buyer.publicKey); 61 | if (currentSolBalance == 0) { 62 | console.log( 63 | "Need some SOL to the your account:", 64 | buyer.publicKey.toBase58() 65 | ); 66 | return; 67 | } 68 | 69 | //Check if mint already exists 70 | let boundingCurveAccount = await sdk.getBondingCurveAccount(mint.publicKey); 71 | if (!boundingCurveAccount) { 72 | let tokenMetadata = { 73 | name: metadata.name, 74 | symbol: metadata.symbol, 75 | description: metadata.description, 76 | showName: metadata.showName, 77 | createOn: metadata.createdOn, 78 | twitter: metadata.twitter, 79 | telegram: metadata.telegram, 80 | website: metadata.website, 81 | file: await openAsBlob(metadata.image), 82 | }; 83 | 84 | let createResults = await sdk.createAndBuy( 85 | buyer, 86 | mint, 87 | [buyer], // buyers 88 | tokenMetadata, 89 | BigInt(0.0001 * LAMPORTS_PER_SOL), 90 | SLIPPAGE_BASIS_POINTS, 91 | { 92 | unitLimit: 5_000_000, 93 | unitPrice: 200_000, 94 | } 95 | ); 96 | 97 | if (createResults.confirmed) { 98 | console.log("Congratelation:", `https://pump.fun/${mint.publicKey.toBase58()}`); 99 | console.log(createResults.jitoTxsignature); 100 | boundingCurveAccount = await sdk.getBondingCurveAccount(mint.publicKey); 101 | console.log("Bonding curve after create and buy", boundingCurveAccount); 102 | printSPLBalance(connection, mint.publicKey, buyer.publicKey); 103 | } 104 | } else { 105 | console.log("boundingCurveAccount", boundingCurveAccount); 106 | console.log("Success:", `https://pump.fun/${mint.publicKey.toBase58()}`); 107 | printSPLBalance(connection, mint.publicKey, buyer.publicKey); 108 | } 109 | }; 110 | 111 | main(); 112 | -------------------------------------------------------------------------------- /src/jito.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | // Jito Bundling part 5 | 6 | import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, VersionedTransaction } from "@solana/web3.js" 7 | 8 | import base58 from "bs58" 9 | import { SearcherClient, searcherClient } from "jito-ts/dist/sdk/block-engine/searcher" 10 | import { Bundle } from "jito-ts/dist/sdk/block-engine/types" 11 | import { isError } from "jito-ts/dist/sdk/block-engine/utils" 12 | import { BLOCKENGINE_URL, JITO_AUTH_KEYPAIR, JITO_FEE, RPC_ENDPOINT, RPC_WEBSOCKET_ENDPOINT } from "./constants" 13 | const connection = new Connection(RPC_ENDPOINT, { 14 | wsEndpoint: RPC_WEBSOCKET_ENDPOINT, 15 | }) 16 | 17 | export async function bundle(txs: VersionedTransaction[], keypair: Keypair) { 18 | 19 | try { 20 | const txNum = Math.ceil(txs.length / 3) 21 | let successNum = 0 22 | for (let i = 0; i < txNum; i++) { 23 | const upperIndex = (i + 1) * 3 24 | const downIndex = i * 3 25 | const newTxs: VersionedTransaction[] = [] 26 | for (let j = downIndex; j < upperIndex; j++) { 27 | if (txs[j]) newTxs.push(txs[j]) 28 | } 29 | let success = await bull_dozer(newTxs, keypair) 30 | return success 31 | } 32 | if (successNum == txNum) return true 33 | else return false 34 | } catch (error) { 35 | return false 36 | } 37 | } 38 | 39 | 40 | export async function bull_dozer(txs: VersionedTransaction[], keypair: Keypair) { 41 | try { 42 | const bundleTransactionLimit = parseInt('4') 43 | const jitoKey = Keypair.fromSecretKey(base58.decode(JITO_AUTH_KEYPAIR)) 44 | const search = searcherClient(BLOCKENGINE_URL, jitoKey) 45 | 46 | await build_bundle( 47 | search, 48 | bundleTransactionLimit, 49 | txs, 50 | keypair 51 | ) 52 | const bundle_result = await onBundleResult(search) 53 | return bundle_result 54 | } catch (error) { 55 | return 0 56 | } 57 | } 58 | 59 | 60 | async function build_bundle( 61 | search: SearcherClient, 62 | bundleTransactionLimit: number, 63 | txs: VersionedTransaction[], 64 | keypair: Keypair 65 | ) { 66 | const accounts = await search.getTipAccounts() 67 | const _tipAccount = accounts[Math.min(Math.floor(Math.random() * accounts.length), 3)] 68 | const tipAccount = new PublicKey(_tipAccount) 69 | 70 | const bund = new Bundle([], bundleTransactionLimit) 71 | const resp = await connection.getLatestBlockhash("processed") 72 | bund.addTransactions(...txs) 73 | 74 | let maybeBundle = bund.addTipTx( 75 | keypair, 76 | Number(JITO_FEE / LAMPORTS_PER_SOL), 77 | tipAccount, 78 | resp.blockhash 79 | ) 80 | 81 | if (isError(maybeBundle)) { 82 | throw maybeBundle 83 | } 84 | try { 85 | await search.sendBundle(maybeBundle) 86 | } catch (e) { } 87 | return maybeBundle 88 | } 89 | 90 | export const onBundleResult = (c: SearcherClient): Promise => { 91 | let first = 0 92 | let isResolved = false 93 | 94 | return new Promise((resolve) => { 95 | // Set a timeout to reject the promise if no bundle is accepted within 5 seconds 96 | setTimeout(() => { 97 | resolve(first) 98 | isResolved = true 99 | }, 30000) 100 | 101 | c.onBundleResult( 102 | (result: any) => { 103 | if (isResolved) return first 104 | // clearTimeout(timeout) // Clear the timeout if a bundle is accepted 105 | const isAccepted = result.accepted 106 | const isRejected = result.rejected 107 | if (isResolved == false) { 108 | 109 | if (isAccepted) { 110 | // console.log(`bundle accepted, ID: ${result.bundleId} | Slot: ${result.accepted!.slot}`) 111 | first += 1 112 | isResolved = true 113 | resolve(first) // Resolve with 'first' when a bundle is accepted 114 | } 115 | if (isRejected) { 116 | // Do not resolve or reject the promise here 117 | } 118 | } 119 | }, 120 | (e: any) => { 121 | // Do not reject the promise here 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 | 148 | 149 | -------------------------------------------------------------------------------- /src/bondingCurveAccount.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { struct, bool, u64, Layout } from "@coral-xyz/borsh"; 5 | 6 | export class BondingCurveAccount { 7 | public discriminator: bigint; 8 | public virtualTokenReserves: bigint; 9 | public virtualSolReserves: bigint; 10 | public realTokenReserves: bigint; 11 | public realSolReserves: bigint; 12 | public tokenTotalSupply: bigint; 13 | public complete: boolean; 14 | 15 | constructor( 16 | discriminator: bigint, 17 | virtualTokenReserves: bigint, 18 | virtualSolReserves: bigint, 19 | realTokenReserves: bigint, 20 | realSolReserves: bigint, 21 | tokenTotalSupply: bigint, 22 | complete: boolean 23 | ) { 24 | this.discriminator = discriminator; 25 | this.virtualTokenReserves = virtualTokenReserves; 26 | this.virtualSolReserves = virtualSolReserves; 27 | this.realTokenReserves = realTokenReserves; 28 | this.realSolReserves = realSolReserves; 29 | this.tokenTotalSupply = tokenTotalSupply; 30 | this.complete = complete; 31 | } 32 | 33 | getBuyPrice(amount: bigint): bigint { 34 | if (this.complete) { 35 | throw new Error("Curve is complete"); 36 | } 37 | 38 | if (amount <= 0n) { 39 | return 0n; 40 | } 41 | 42 | // Calculate the product of virtual reserves 43 | let n = this.virtualSolReserves * this.virtualTokenReserves; 44 | 45 | // Calculate the new virtual sol reserves after the purchase 46 | let i = this.virtualSolReserves + amount; 47 | 48 | // Calculate the new virtual token reserves after the purchase 49 | let r = n / i + 1n; 50 | 51 | // Calculate the amount of tokens to be purchased 52 | let s = this.virtualTokenReserves - r; 53 | 54 | // Return the minimum of the calculated tokens and real token reserves 55 | return s < this.realTokenReserves ? s : this.realTokenReserves; 56 | } 57 | 58 | getSellPrice(amount: bigint, feeBasisPoints: bigint): bigint { 59 | if (this.complete) { 60 | throw new Error("Curve is complete"); 61 | } 62 | 63 | if (amount <= 0n) { 64 | return 0n; 65 | } 66 | 67 | // Calculate the proportional amount of virtual sol reserves to be received 68 | let n = 69 | (amount * this.virtualSolReserves) / (this.virtualTokenReserves + amount); 70 | 71 | // Calculate the fee amount in the same units 72 | let a = (n * feeBasisPoints) / 10000n; 73 | 74 | // Return the net amount after deducting the fee 75 | return n - a; 76 | } 77 | 78 | getMarketCapSOL(): bigint { 79 | if (this.virtualTokenReserves === 0n) { 80 | return 0n; 81 | } 82 | 83 | return ( 84 | (this.tokenTotalSupply * this.virtualSolReserves) / 85 | this.virtualTokenReserves 86 | ); 87 | } 88 | 89 | getFinalMarketCapSOL(feeBasisPoints: bigint): bigint { 90 | let totalSellValue = this.getBuyOutPrice( 91 | this.realTokenReserves, 92 | feeBasisPoints 93 | ); 94 | let totalVirtualValue = this.virtualSolReserves + totalSellValue; 95 | let totalVirtualTokens = this.virtualTokenReserves - this.realTokenReserves; 96 | 97 | if (totalVirtualTokens === 0n) { 98 | return 0n; 99 | } 100 | 101 | return (this.tokenTotalSupply * totalVirtualValue) / totalVirtualTokens; 102 | } 103 | 104 | getBuyOutPrice(amount: bigint, feeBasisPoints: bigint): bigint { 105 | let solTokens = 106 | amount < this.realSolReserves ? this.realSolReserves : amount; 107 | let totalSellValue = 108 | (solTokens * this.virtualSolReserves) / 109 | (this.virtualTokenReserves - solTokens) + 110 | 1n; 111 | let fee = (totalSellValue * feeBasisPoints) / 10000n; 112 | return totalSellValue + fee; 113 | } 114 | 115 | public static fromBuffer(buffer: Buffer): BondingCurveAccount { 116 | const structure: Layout = struct([ 117 | u64("discriminator"), 118 | u64("virtualTokenReserves"), 119 | u64("virtualSolReserves"), 120 | u64("realTokenReserves"), 121 | u64("realSolReserves"), 122 | u64("tokenTotalSupply"), 123 | bool("complete"), 124 | ]); 125 | 126 | let value = structure.decode(buffer); 127 | return new BondingCurveAccount( 128 | BigInt(value.discriminator), 129 | BigInt(value.virtualTokenReserves), 130 | BigInt(value.virtualSolReserves), 131 | BigInt(value.realTokenReserves), 132 | BigInt(value.realSolReserves), 133 | BigInt(value.tokenTotalSupply), 134 | value.complete 135 | ); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/jitoWithAxios.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { 5 | Connection, 6 | Keypair, 7 | LAMPORTS_PER_SOL, 8 | PublicKey, 9 | SystemProgram, 10 | TransactionMessage, 11 | VersionedTransaction, 12 | } from "@solana/web3.js"; 13 | import dotenv from "dotenv"; 14 | 15 | import base58 from "bs58"; 16 | import axios, { AxiosError } from "axios"; 17 | import { 18 | COMMITMENT_LEVEL, 19 | JITO_FEE, 20 | RPC_ENDPOINT, 21 | RPC_WEBSOCKET_ENDPOINT, 22 | } from "./constants"; 23 | 24 | interface Blockhash { 25 | blockhash: string; 26 | lastValidBlockHeight: number; 27 | } 28 | dotenv.config(); 29 | 30 | 31 | const solanaConnection = new Connection(process.env.HELIUS_RPC_URL || ""); 32 | 33 | export const jitoWithAxios = async ( 34 | transactions: VersionedTransaction[], 35 | payer: Keypair 36 | ) => { 37 | console.log("Starting Jito transaction execution..."); 38 | const tipAccounts = [ 39 | "Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY", 40 | "DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL", 41 | "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5", 42 | "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT", 43 | "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe", 44 | "ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49", 45 | "ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt", 46 | "DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh", 47 | ]; 48 | const jitoFeeWallet = new PublicKey( 49 | tipAccounts[Math.floor(tipAccounts.length * Math.random())] 50 | ); 51 | 52 | console.log(`Selected Jito fee wallet: ${jitoFeeWallet.toBase58()}`); 53 | 54 | try { 55 | console.log(`Calculated fee: ${JITO_FEE / LAMPORTS_PER_SOL} sol`); 56 | console.log(await solanaConnection.getBalance(payer.publicKey)) 57 | let latestBlockhash = await solanaConnection.getLatestBlockhash(); 58 | const jitTipTxFeeMessage = new TransactionMessage({ 59 | payerKey: payer.publicKey, 60 | recentBlockhash: latestBlockhash.blockhash, 61 | instructions: [ 62 | SystemProgram.transfer({ 63 | fromPubkey: payer.publicKey, 64 | toPubkey: jitoFeeWallet, 65 | lamports: JITO_FEE, 66 | }), 67 | ], 68 | }).compileToV0Message(); 69 | 70 | const jitoFeeTx = new VersionedTransaction(jitTipTxFeeMessage); 71 | jitoFeeTx.sign([payer]); 72 | 73 | const jitoTxsignature = base58.encode(jitoFeeTx.signatures[0]); 74 | 75 | // Serialize the transactions once here 76 | const serializedjitoFeeTx = base58.encode(jitoFeeTx.serialize()); 77 | const serializedTransactions = [serializedjitoFeeTx]; 78 | for (let i = 0; i < transactions.length; i++) { 79 | const serializedTransaction = base58.encode(transactions[i].serialize()); 80 | serializedTransactions.push(serializedTransaction); 81 | } 82 | 83 | const endpoints = [ 84 | // 'https://mainnet.block-engine.jito.wtf/api/v1/bundles', 85 | // 'https://amsterdam.mainnet.block-engine.jito.wtf/api/v1/bundles', 86 | 'https://frankfurt.mainnet.block-engine.jito.wtf/api/v1/bundles', 87 | // "https://ny.mainnet.block-engine.jito.wtf/api/v1/bundles", 88 | // "https://tokyo.mainnet.block-engine.jito.wtf/api/v1/bundles", 89 | ]; 90 | 91 | const requests = endpoints.map((url) => 92 | axios.post(url, { 93 | jsonrpc: "2.0", 94 | id: 1, 95 | method: "sendBundle", 96 | params: [serializedTransactions], 97 | }) 98 | ); 99 | 100 | console.log("Sending transactions to endpoints..."); 101 | 102 | const results = await Promise.all(requests.map((p) => p.catch((e) => e))); 103 | 104 | const successfulResults = results.filter( 105 | (result) => !(result instanceof Error) 106 | ); 107 | 108 | if (successfulResults.length > 0) { 109 | console.log(`Successful response`); 110 | // console.log(`Confirming jito transaction...`); 111 | 112 | const confirmation = await solanaConnection.confirmTransaction( 113 | { 114 | signature: jitoTxsignature, 115 | lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, 116 | blockhash: latestBlockhash.blockhash, 117 | }, 118 | COMMITMENT_LEVEL 119 | ); 120 | 121 | console.log(confirmation); 122 | 123 | return { confirmed: !confirmation.value.err, jitoTxsignature }; 124 | } else { 125 | console.log(`No successful responses received for jito`); 126 | } 127 | 128 | return { confirmed: false }; 129 | } catch (error) { 130 | if (error instanceof AxiosError) { 131 | console.log("Failed to execute jito transaction"); 132 | } 133 | console.log("Error during transaction execution", error); 134 | return { confirmed: false }; 135 | } 136 | }; 137 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { 5 | Commitment, 6 | ComputeBudgetProgram, 7 | Connection, 8 | Finality, 9 | Keypair, 10 | PublicKey, 11 | SendTransactionError, 12 | Transaction, 13 | TransactionMessage, 14 | VersionedTransaction, 15 | VersionedTransactionResponse, 16 | } from "@solana/web3.js"; 17 | import { PriorityFee, TransactionResult } from "./types"; 18 | import fs from "fs"; 19 | 20 | export const DEFAULT_COMMITMENT: Commitment = "finalized"; 21 | export const DEFAULT_FINALITY: Finality = "finalized"; 22 | 23 | export const calculateWithSlippageBuy = ( 24 | amount: bigint, 25 | basisPoints: bigint 26 | ) => { 27 | return amount + (amount * basisPoints) / 10000n; 28 | }; 29 | 30 | export const calculateWithSlippageSell = ( 31 | amount: bigint, 32 | basisPoints: bigint 33 | ) => { 34 | return amount - (amount * basisPoints) / 10000n; 35 | }; 36 | 37 | export async function sendTx( 38 | connection: Connection, 39 | tx: Transaction, 40 | payer: PublicKey, 41 | signers: Keypair[], 42 | priorityFees?: PriorityFee, 43 | commitment: Commitment = DEFAULT_COMMITMENT, 44 | finality: Finality = DEFAULT_FINALITY 45 | ): Promise { 46 | let newTx = new Transaction(); 47 | 48 | if (priorityFees) { 49 | const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 50 | units: priorityFees.unitLimit, 51 | }); 52 | 53 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 54 | microLamports: priorityFees.unitPrice, 55 | }); 56 | newTx.add(modifyComputeUnits); 57 | newTx.add(addPriorityFee); 58 | } 59 | newTx.add(tx); 60 | let versionedTx = await buildVersionedTx( 61 | connection, 62 | payer, 63 | newTx, 64 | commitment 65 | ); 66 | versionedTx.sign(signers); 67 | try { 68 | console.log(await connection.simulateTransaction(versionedTx, undefined)); 69 | 70 | const sig = await connection.sendTransaction(versionedTx, { 71 | skipPreflight: false, 72 | }); 73 | console.log("sig:", `https://solscan.io/tx/${sig}`); 74 | 75 | let txResult = await getTxDetails(connection, sig, commitment, finality); 76 | if (!txResult) { 77 | return { 78 | success: false, 79 | error: "Transaction failed", 80 | }; 81 | } 82 | return { 83 | success: true, 84 | signature: sig, 85 | results: txResult, 86 | }; 87 | } catch (e) { 88 | if (e instanceof SendTransactionError) { 89 | let ste = e as SendTransactionError; 90 | } else { 91 | console.error(e); 92 | } 93 | return { 94 | error: e, 95 | success: false, 96 | }; 97 | } 98 | } 99 | 100 | export async function buildTx( 101 | connection: Connection, 102 | tx: Transaction, 103 | payer: PublicKey, 104 | signers: Keypair[], 105 | priorityFees?: PriorityFee, 106 | commitment: Commitment = DEFAULT_COMMITMENT, 107 | finality: Finality = DEFAULT_FINALITY 108 | ): Promise { 109 | let newTx = new Transaction(); 110 | 111 | if (priorityFees) { 112 | const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 113 | units: priorityFees.unitLimit, 114 | }); 115 | 116 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 117 | microLamports: priorityFees.unitPrice, 118 | }); 119 | newTx.add(modifyComputeUnits); 120 | newTx.add(addPriorityFee); 121 | } 122 | newTx.add(tx); 123 | let versionedTx = await buildVersionedTx( 124 | connection, 125 | payer, 126 | newTx, 127 | commitment 128 | ); 129 | versionedTx.sign(signers); 130 | return versionedTx; 131 | } 132 | 133 | export const buildVersionedTx = async ( 134 | connection: Connection, 135 | payer: PublicKey, 136 | tx: Transaction, 137 | commitment: Commitment = DEFAULT_COMMITMENT 138 | ): Promise => { 139 | const blockHash = (await connection.getLatestBlockhash(commitment)).blockhash; 140 | 141 | let messageV0 = new TransactionMessage({ 142 | payerKey: payer, 143 | recentBlockhash: blockHash, 144 | instructions: tx.instructions, 145 | }).compileToV0Message(); 146 | 147 | return new VersionedTransaction(messageV0); 148 | }; 149 | 150 | export const getTxDetails = async ( 151 | connection: Connection, 152 | sig: string, 153 | commitment: Commitment = DEFAULT_COMMITMENT, 154 | finality: Finality = DEFAULT_FINALITY 155 | ): Promise => { 156 | const latestBlockHash = await connection.getLatestBlockhash(); 157 | await connection.confirmTransaction( 158 | { 159 | blockhash: latestBlockHash.blockhash, 160 | lastValidBlockHeight: latestBlockHash.lastValidBlockHeight, 161 | signature: sig, 162 | }, 163 | commitment 164 | ); 165 | 166 | return connection.getTransaction(sig, { 167 | maxSupportedTransactionVersion: 0, 168 | commitment: finality, 169 | }); 170 | }; 171 | 172 | export const getRandomInt = (min: number, max: number): number => { 173 | min = Math.ceil(min); 174 | max = Math.floor(max); 175 | return Math.floor(Math.random() * (max - min + 1)) + min; // The maximum is inclusive, the minimum is inclusive 176 | }; 177 | -------------------------------------------------------------------------------- /src/pumpfun.ts: -------------------------------------------------------------------------------- 1 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | import { 5 | Commitment, 6 | Connection, 7 | Finality, 8 | Keypair, 9 | PublicKey, 10 | Transaction, 11 | VersionedTransaction, 12 | } from "@solana/web3.js"; 13 | import { Program, Provider } from "@coral-xyz/anchor"; 14 | import { setGlobalDispatcher, Agent } from "undici"; 15 | import { GlobalAccount } from "./globalAccount"; 16 | import { 17 | CompleteEvent, 18 | CreateEvent, 19 | CreateTokenMetadata, 20 | PriorityFee, 21 | PumpFunEventHandlers, 22 | PumpFunEventType, 23 | SetParamsEvent, 24 | TradeEvent, 25 | TransactionResult, 26 | } from "./types"; 27 | import { 28 | toCompleteEvent, 29 | toCreateEvent, 30 | toSetParamsEvent, 31 | toTradeEvent, 32 | } from "./events"; 33 | import { 34 | createAssociatedTokenAccountInstruction, 35 | getAccount, 36 | getAssociatedTokenAddress, 37 | } from "@solana/spl-token"; 38 | import { BondingCurveAccount } from "./bondingCurveAccount"; 39 | import { BN } from "bn.js"; 40 | import { 41 | DEFAULT_COMMITMENT, 42 | DEFAULT_FINALITY, 43 | buildTx, 44 | calculateWithSlippageBuy, 45 | calculateWithSlippageSell, 46 | getRandomInt, 47 | sendTx, 48 | } from "./util"; 49 | import { PumpFun, IDL } from "./IDL"; 50 | import { jitoWithAxios } from "./jitoWithAxios"; 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 | if (buyAmountSol > 0) { 105 | for (let i = 0; i < buyers.length; i++) { 106 | const randomPercent = getRandomInt(10, 25); 107 | const buyAmountSolWithRandom = 108 | (buyAmountSol / BigInt(100)) * 109 | BigInt(randomPercent % 2 ? 100 + randomPercent : 100 - randomPercent); 110 | 111 | const globalAccount = await this.getGlobalAccount(commitment); 112 | const buyAmount = globalAccount.getInitialBuyPrice( 113 | buyAmountSolWithRandom 114 | ); 115 | const buyAmountWithSlippage = calculateWithSlippageBuy( 116 | buyAmountSolWithRandom, 117 | slippageBasisPoints * 100n 118 | ); 119 | 120 | const buyTx = await this.getBuyInstructions( 121 | buyers[i].publicKey, 122 | mint.publicKey, 123 | globalAccount.feeRecipient, 124 | buyAmount, 125 | buyAmountWithSlippage 126 | ); 127 | 128 | const buyVersionedTx = await buildTx( 129 | this.connection, 130 | buyTx, 131 | buyers[i].publicKey, 132 | [buyers[i]], 133 | priorityFees, 134 | commitment, 135 | finality 136 | ); 137 | buyTxs.push(buyVersionedTx); 138 | } 139 | } 140 | let result; 141 | while (1) { 142 | result = await jitoWithAxios([createVersionedTx, ...buyTxs], creator); 143 | if (result.confirmed) break; 144 | } 145 | 146 | return result; 147 | } 148 | 149 | async buy( 150 | buyer: Keypair, 151 | mint: PublicKey, 152 | buyAmountSol: bigint, 153 | slippageBasisPoints: bigint = 500n, 154 | priorityFees?: PriorityFee, 155 | commitment: Commitment = DEFAULT_COMMITMENT, 156 | finality: Finality = DEFAULT_FINALITY 157 | ): Promise { 158 | let buyTx = await this.getBuyInstructionsBySolAmount( 159 | buyer.publicKey, 160 | mint, 161 | buyAmountSol, 162 | slippageBasisPoints, 163 | commitment 164 | ); 165 | 166 | let buyResults = await sendTx( 167 | this.connection, 168 | buyTx, 169 | buyer.publicKey, 170 | [buyer], 171 | priorityFees, 172 | commitment, 173 | finality 174 | ); 175 | return buyResults; 176 | } 177 | 178 | async sell( 179 | seller: Keypair, 180 | mint: PublicKey, 181 | sellTokenAmount: bigint, 182 | slippageBasisPoints: bigint = 500n, 183 | priorityFees?: PriorityFee, 184 | commitment: Commitment = DEFAULT_COMMITMENT, 185 | finality: Finality = DEFAULT_FINALITY 186 | ): Promise { 187 | let sellTx = await this.getSellInstructionsByTokenAmount( 188 | seller.publicKey, 189 | mint, 190 | sellTokenAmount, 191 | slippageBasisPoints, 192 | commitment 193 | ); 194 | 195 | let sellResults = await sendTx( 196 | this.connection, 197 | sellTx, 198 | seller.publicKey, 199 | [seller], 200 | priorityFees, 201 | commitment, 202 | finality 203 | ); 204 | return sellResults; 205 | } 206 | 207 | //create token instructions 208 | async getCreateInstructions( 209 | creator: PublicKey, 210 | name: string, 211 | symbol: string, 212 | uri: string, 213 | mint: Keypair 214 | ) { 215 | const mplTokenMetadata = new PublicKey(MPL_TOKEN_METADATA_PROGRAM_ID); 216 | 217 | const [metadataPDA] = PublicKey.findProgramAddressSync( 218 | [ 219 | Buffer.from(METADATA_SEED), 220 | mplTokenMetadata.toBuffer(), 221 | mint.publicKey.toBuffer(), 222 | ], 223 | mplTokenMetadata 224 | ); 225 | 226 | const associatedBondingCurve = await getAssociatedTokenAddress( 227 | mint.publicKey, 228 | this.getBondingCurvePDA(mint.publicKey), 229 | true 230 | ); 231 | 232 | return this.program.methods 233 | .create(name, symbol, uri) 234 | .accounts({ 235 | mint: mint.publicKey, 236 | associatedBondingCurve: associatedBondingCurve, 237 | metadata: metadataPDA, 238 | user: creator, 239 | }) 240 | .signers([mint]) 241 | .transaction(); 242 | } 243 | 244 | async getBuyInstructionsBySolAmount( 245 | buyer: PublicKey, 246 | mint: PublicKey, 247 | buyAmountSol: bigint, 248 | slippageBasisPoints: bigint = 500n, 249 | commitment: Commitment = DEFAULT_COMMITMENT 250 | ) { 251 | let bondingCurveAccount = await this.getBondingCurveAccount( 252 | mint, 253 | commitment 254 | ); 255 | if (!bondingCurveAccount) { 256 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 257 | } 258 | 259 | let buyAmount = bondingCurveAccount.getBuyPrice(buyAmountSol); 260 | let buyAmountWithSlippage = calculateWithSlippageBuy( 261 | buyAmountSol, 262 | slippageBasisPoints 263 | ); 264 | let globalAccount = await this.getGlobalAccount(commitment); 265 | 266 | return await this.getBuyInstructions( 267 | buyer, 268 | mint, 269 | globalAccount.feeRecipient, 270 | buyAmount, 271 | buyAmountWithSlippage 272 | ); 273 | } 274 | 275 | //buy 276 | async getBuyInstructions( 277 | buyer: PublicKey, 278 | mint: PublicKey, 279 | feeRecipient: PublicKey, 280 | amount: bigint, 281 | solAmount: bigint, 282 | commitment: Commitment = DEFAULT_COMMITMENT 283 | ) { 284 | const associatedBondingCurve = await getAssociatedTokenAddress( 285 | mint, 286 | this.getBondingCurvePDA(mint), 287 | true 288 | ); 289 | 290 | const associatedUser = await getAssociatedTokenAddress(mint, buyer, false); 291 | 292 | let transaction = new Transaction(); 293 | 294 | try { 295 | await getAccount(this.connection, associatedUser, commitment); 296 | } catch (e) { 297 | transaction.add( 298 | createAssociatedTokenAccountInstruction( 299 | buyer, 300 | associatedUser, 301 | buyer, 302 | mint 303 | ) 304 | ); 305 | } 306 | 307 | transaction.add( 308 | await this.program.methods 309 | .buy(new BN(amount.toString()), new BN(solAmount.toString())) 310 | .accounts({ 311 | feeRecipient: feeRecipient, 312 | mint: mint, 313 | associatedBondingCurve: associatedBondingCurve, 314 | associatedUser: associatedUser, 315 | user: buyer, 316 | }) 317 | .transaction() 318 | ); 319 | 320 | return transaction; 321 | } 322 | 323 | //sell 324 | async getSellInstructionsByTokenAmount( 325 | seller: PublicKey, 326 | mint: PublicKey, 327 | sellTokenAmount: bigint, 328 | slippageBasisPoints: bigint = 500n, 329 | commitment: Commitment = DEFAULT_COMMITMENT 330 | ) { 331 | let bondingCurveAccount = await this.getBondingCurveAccount( 332 | mint, 333 | commitment 334 | ); 335 | if (!bondingCurveAccount) { 336 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 337 | } 338 | 339 | let globalAccount = await this.getGlobalAccount(commitment); 340 | 341 | let minSolOutput = bondingCurveAccount.getSellPrice( 342 | sellTokenAmount, 343 | globalAccount.feeBasisPoints 344 | ); 345 | 346 | let sellAmountWithSlippage = calculateWithSlippageSell( 347 | minSolOutput, 348 | slippageBasisPoints 349 | ); 350 | 351 | return await this.getSellInstructions( 352 | seller, 353 | mint, 354 | globalAccount.feeRecipient, 355 | sellTokenAmount, 356 | sellAmountWithSlippage 357 | ); 358 | } 359 | 360 | async getSellInstructions( 361 | seller: PublicKey, 362 | mint: PublicKey, 363 | feeRecipient: PublicKey, 364 | amount: bigint, 365 | minSolOutput: bigint 366 | ) { 367 | const associatedBondingCurve = await getAssociatedTokenAddress( 368 | mint, 369 | this.getBondingCurvePDA(mint), 370 | true 371 | ); 372 | 373 | const associatedUser = await getAssociatedTokenAddress(mint, seller, false); 374 | 375 | let transaction = new Transaction(); 376 | 377 | transaction.add( 378 | await this.program.methods 379 | .sell(new BN(amount.toString()), new BN(minSolOutput.toString())) 380 | .accounts({ 381 | feeRecipient: feeRecipient, 382 | mint: mint, 383 | associatedBondingCurve: associatedBondingCurve, 384 | associatedUser: associatedUser, 385 | user: seller, 386 | }) 387 | .transaction() 388 | ); 389 | 390 | return transaction; 391 | } 392 | 393 | async getBondingCurveAccount( 394 | mint: PublicKey, 395 | commitment: Commitment = DEFAULT_COMMITMENT 396 | ) { 397 | const tokenAccount = await this.connection.getAccountInfo( 398 | this.getBondingCurvePDA(mint), 399 | commitment 400 | ); 401 | if (!tokenAccount) { 402 | return null; 403 | } 404 | return BondingCurveAccount.fromBuffer(tokenAccount!.data); 405 | } 406 | 407 | async getGlobalAccount(commitment: Commitment = DEFAULT_COMMITMENT) { 408 | const [globalAccountPDA] = PublicKey.findProgramAddressSync( 409 | [Buffer.from(GLOBAL_ACCOUNT_SEED)], 410 | new PublicKey(PROGRAM_ID) 411 | ); 412 | 413 | const tokenAccount = await this.connection.getAccountInfo( 414 | globalAccountPDA, 415 | commitment 416 | ); 417 | 418 | return GlobalAccount.fromBuffer(tokenAccount!.data); 419 | } 420 | 421 | getBondingCurvePDA(mint: PublicKey) { 422 | return PublicKey.findProgramAddressSync( 423 | [Buffer.from(BONDING_CURVE_SEED), mint.toBuffer()], 424 | this.program.programId 425 | )[0]; 426 | } 427 | 428 | async createTokenMetadata(create: CreateTokenMetadata) { 429 | let formData = new FormData(); 430 | formData.append("file", create.file), 431 | formData.append("name", create.name), 432 | formData.append("symbol", create.symbol), 433 | formData.append("description", create.description), 434 | formData.append("twitter", create.twitter || ""), 435 | formData.append("telegram", create.telegram || ""), 436 | formData.append("website", create.website || ""), 437 | formData.append("showName", "true"); 438 | 439 | setGlobalDispatcher(new Agent({ connect: { timeout: 60_000 } })); 440 | let request = await fetch("https://pump.fun/api/ipfs", { 441 | method: "POST", 442 | headers: { 443 | Host: "www.pump.fun", 444 | "User-Agent": 445 | "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 | // Date: 03/01/2025 2 | // Authour: Immutal0 3 | 4 | export type PumpFun = { 5 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 6 | metadata: { 7 | name: "pump"; 8 | version: "0.1.0"; 9 | spec: "0.1.0"; 10 | }; 11 | instructions: [ 12 | { 13 | name: "initialize"; 14 | discriminator: [175, 175, 109, 31, 13, 152, 155, 237]; 15 | docs: ["Creates the global state."]; 16 | accounts: [ 17 | { 18 | name: "global"; 19 | writable: true; 20 | pda: { 21 | seeds: [ 22 | { 23 | kind: "const"; 24 | value: [103, 108, 111, 98, 97, 108]; 25 | } 26 | ]; 27 | }; 28 | }, 29 | { 30 | name: "user"; 31 | writable: true; 32 | signer: true; 33 | }, 34 | { 35 | name: "systemProgram"; 36 | address: "11111111111111111111111111111111"; 37 | } 38 | ]; 39 | args: []; 40 | }, 41 | { 42 | name: "setParams"; 43 | discriminator: [165, 31, 134, 53, 189, 180, 130, 255]; 44 | docs: ["Sets the global state parameters."]; 45 | accounts: [ 46 | { 47 | name: "global"; 48 | writable: true; 49 | pda: { 50 | seeds: [ 51 | { 52 | kind: "const"; 53 | value: [103, 108, 111, 98, 97, 108]; 54 | } 55 | ]; 56 | }; 57 | }, 58 | { 59 | name: "user"; 60 | writable: true; 61 | signer: true; 62 | }, 63 | { 64 | name: "systemProgram"; 65 | address: "11111111111111111111111111111111"; 66 | }, 67 | { 68 | name: "eventAuthority"; 69 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 70 | }, 71 | { 72 | name: "program"; 73 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 74 | } 75 | ]; 76 | args: [ 77 | { 78 | name: "feeRecipient"; 79 | type: "pubkey"; 80 | }, 81 | { 82 | name: "initialVirtualTokenReserves"; 83 | type: "u64"; 84 | }, 85 | { 86 | name: "initialVirtualSolReserves"; 87 | type: "u64"; 88 | }, 89 | { 90 | name: "initialRealTokenReserves"; 91 | type: "u64"; 92 | }, 93 | { 94 | name: "tokenTotalSupply"; 95 | type: "u64"; 96 | }, 97 | { 98 | name: "feeBasisPoints"; 99 | type: "u64"; 100 | } 101 | ]; 102 | }, 103 | { 104 | name: "create"; 105 | discriminator: [24, 30, 200, 40, 5, 28, 7, 119]; 106 | docs: ["Creates a new coin and bonding curve."]; 107 | accounts: [ 108 | { 109 | name: "mint"; 110 | writable: true; 111 | signer: true; 112 | }, 113 | { 114 | name: "mint_authority"; 115 | pda: { 116 | seeds: [ 117 | { 118 | kind: "const"; 119 | value: [ 120 | 109, 121 | 105, 122 | 110, 123 | 116, 124 | 45, 125 | 97, 126 | 117, 127 | 116, 128 | 104, 129 | 111, 130 | 114, 131 | 105, 132 | 116, 133 | 121 134 | ]; 135 | } 136 | ]; 137 | }; 138 | }, 139 | { 140 | name: "bondingCurve"; 141 | writable: true; 142 | pda: { 143 | seeds: [ 144 | { 145 | kind: "const"; 146 | value: [ 147 | 98, 148 | 111, 149 | 110, 150 | 100, 151 | 105, 152 | 110, 153 | 103, 154 | 45, 155 | 99, 156 | 117, 157 | 114, 158 | 118, 159 | 101 160 | ]; 161 | }, 162 | { 163 | kind: "account"; 164 | path: "mint"; 165 | } 166 | ]; 167 | }; 168 | }, 169 | { 170 | name: "associatedBondingCurve"; 171 | writable: true; 172 | signer: false; 173 | }, 174 | { 175 | name: "global"; 176 | writable: false; 177 | pda: { 178 | seeds: [ 179 | { 180 | kind: "const"; 181 | value: [103, 108, 111, 98, 97, 108]; 182 | } 183 | ]; 184 | }; 185 | }, 186 | { 187 | name: "mplTokenMetadata"; 188 | address: "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"; 189 | }, 190 | { 191 | name: "metadata"; 192 | writable: true; 193 | signer: false; 194 | }, 195 | { 196 | name: "user"; 197 | isMut: true; 198 | isSigner: true; 199 | }, 200 | { 201 | name: "systemProgram"; 202 | address: "11111111111111111111111111111111"; 203 | }, 204 | { 205 | name: "tokenProgram"; 206 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 207 | }, 208 | { 209 | name: "associatedTokenProgram"; 210 | address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"; 211 | }, 212 | { 213 | name: "rent"; 214 | address: "SysvarRent111111111111111111111111111111111"; 215 | }, 216 | { 217 | name: "eventAuthority"; 218 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 219 | }, 220 | { 221 | name: "program"; 222 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 223 | } 224 | ]; 225 | args: [ 226 | { 227 | name: "name"; 228 | type: "string"; 229 | }, 230 | { 231 | name: "symbol"; 232 | type: "string"; 233 | }, 234 | { 235 | name: "uri"; 236 | type: "string"; 237 | } 238 | ]; 239 | }, 240 | { 241 | name: "buy"; 242 | discriminator: [102, 6, 61, 18, 1, 218, 235, 234]; 243 | docs: ["Buys tokens from a bonding curve."]; 244 | accounts: [ 245 | { 246 | name: "global"; 247 | pda: { 248 | seeds: [ 249 | { 250 | kind: "const"; 251 | value: [103, 108, 111, 98, 97, 108]; 252 | } 253 | ]; 254 | }; 255 | }, 256 | { 257 | name: "feeRecipient"; 258 | writable: true; 259 | signer: false; 260 | }, 261 | { 262 | name: "mint"; 263 | writable: false; 264 | signer: false; 265 | }, 266 | { 267 | name: "bondingCurve"; 268 | writable: true; 269 | pda: { 270 | seeds: [ 271 | { 272 | kind: "const"; 273 | value: [ 274 | 98, 275 | 111, 276 | 110, 277 | 100, 278 | 105, 279 | 110, 280 | 103, 281 | 45, 282 | 99, 283 | 117, 284 | 114, 285 | 118, 286 | 101 287 | ]; 288 | }, 289 | { 290 | kind: "account"; 291 | path: "mint"; 292 | } 293 | ]; 294 | }; 295 | }, 296 | { 297 | name: "associatedBondingCurve"; 298 | writable: true; 299 | signer: false; 300 | }, 301 | { 302 | name: "associatedUser"; 303 | writable: true; 304 | signer: false; 305 | }, 306 | { 307 | name: "user"; 308 | writable: true; 309 | signer: true; 310 | }, 311 | { 312 | name: "systemProgram"; 313 | address: "11111111111111111111111111111111"; 314 | }, 315 | { 316 | name: "tokenProgram"; 317 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 318 | }, 319 | { 320 | name: "rent"; 321 | address: "SysvarRent111111111111111111111111111111111"; 322 | }, 323 | { 324 | name: "eventAuthority"; 325 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 326 | }, 327 | { 328 | name: "program"; 329 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 330 | } 331 | ]; 332 | args: [ 333 | { 334 | name: "amount"; 335 | type: "u64"; 336 | }, 337 | { 338 | name: "maxSolCost"; 339 | type: "u64"; 340 | } 341 | ]; 342 | }, 343 | { 344 | name: "sell"; 345 | discriminator: [51, 230, 133, 164, 1, 127, 131, 173]; 346 | docs: ["Sells tokens into a bonding curve."]; 347 | accounts: [ 348 | { 349 | name: "global"; 350 | writable: false; 351 | pda: { 352 | seeds: [ 353 | { 354 | kind: "const"; 355 | value: [103, 108, 111, 98, 97, 108]; 356 | } 357 | ]; 358 | }; 359 | }, 360 | { 361 | name: "feeRecipient"; 362 | writable: true; 363 | signer: false; 364 | }, 365 | { 366 | name: "mint"; 367 | writable: false; 368 | signer: false; 369 | }, 370 | { 371 | name: "bondingCurve"; 372 | writable: true; 373 | pda: { 374 | seeds: [ 375 | { 376 | kind: "const"; 377 | value: [ 378 | 98, 379 | 111, 380 | 110, 381 | 100, 382 | 105, 383 | 110, 384 | 103, 385 | 45, 386 | 99, 387 | 117, 388 | 114, 389 | 118, 390 | 101 391 | ]; 392 | }, 393 | { 394 | kind: "account"; 395 | path: "mint"; 396 | } 397 | ]; 398 | }; 399 | }, 400 | { 401 | name: "associatedBondingCurve"; 402 | writable: true; 403 | signer: false; 404 | }, 405 | { 406 | name: "associatedUser"; 407 | writable: true; 408 | signer: false; 409 | }, 410 | { 411 | name: "user"; 412 | writable: true; 413 | signer: true; 414 | }, 415 | { 416 | name: "systemProgram"; 417 | address: "11111111111111111111111111111111"; 418 | }, 419 | { 420 | name: "associatedTokenProgram"; 421 | address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"; 422 | }, 423 | { 424 | name: "tokenProgram"; 425 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 426 | }, 427 | { 428 | name: "eventAuthority"; 429 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 430 | }, 431 | { 432 | name: "program"; 433 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 434 | } 435 | ]; 436 | args: [ 437 | { 438 | name: "amount"; 439 | type: "u64"; 440 | }, 441 | { 442 | name: "minSolOutput"; 443 | type: "u64"; 444 | } 445 | ]; 446 | }, 447 | { 448 | name: "withdraw"; 449 | discriminator: [183, 18, 70, 156, 148, 109, 161, 34]; 450 | docs: [ 451 | "Allows the admin to withdraw liquidity for a migration once the bonding curve completes" 452 | ]; 453 | accounts: [ 454 | { 455 | name: "global"; 456 | writable: false; 457 | pda: { 458 | seeds: [ 459 | { 460 | kind: "const"; 461 | value: [103, 108, 111, 98, 97, 108]; 462 | } 463 | ]; 464 | }; 465 | }, 466 | { 467 | name: "lastWithdraw"; 468 | writable: true; 469 | signer: false; 470 | }, 471 | { 472 | name: "mint"; 473 | writable: false; 474 | signer: false; 475 | }, 476 | { 477 | name: "bondingCurve"; 478 | writable: true; 479 | pda: { 480 | seeds: [ 481 | { 482 | kind: "const"; 483 | value: [ 484 | 98, 485 | 111, 486 | 110, 487 | 100, 488 | 105, 489 | 110, 490 | 103, 491 | 45, 492 | 99, 493 | 117, 494 | 114, 495 | 118, 496 | 101 497 | ]; 498 | }, 499 | { 500 | kind: "account"; 501 | path: "mint"; 502 | } 503 | ]; 504 | }; 505 | }, 506 | { 507 | name: "associatedBondingCurve"; 508 | writable: true; 509 | signer: false; 510 | }, 511 | { 512 | name: "associatedUser"; 513 | writable: true; 514 | signer: false; 515 | }, 516 | { 517 | name: "user"; 518 | writable: true; 519 | signer: true; 520 | }, 521 | { 522 | name: "system_program"; 523 | address: "11111111111111111111111111111111"; 524 | }, 525 | { 526 | name: "tokenProgram"; 527 | address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; 528 | }, 529 | { 530 | name: "rent"; 531 | address: "SysvarRent111111111111111111111111111111111"; 532 | }, 533 | { 534 | name: "eventAuthority"; 535 | address: "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; 536 | }, 537 | { 538 | name: "program"; 539 | address: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; 540 | } 541 | ]; 542 | args: []; 543 | } 544 | ]; 545 | accounts: [ 546 | { 547 | name: "bondingCurve"; 548 | discriminator: [23, 183, 248, 55, 96, 216, 172, 96]; 549 | }, 550 | { 551 | name: "global"; 552 | discriminator: [167, 232, 232, 177, 200, 108, 114, 127]; 553 | } 554 | ]; 555 | events: [ 556 | { 557 | name: "createEvent"; 558 | discriminator: [27, 114, 169, 77, 222, 235, 99, 118]; 559 | }, 560 | { 561 | name: "tradeEvent"; 562 | discriminator: [189, 219, 127, 211, 78, 230, 97, 238]; 563 | }, 564 | { 565 | name: "completeEvent"; 566 | discriminator: [95, 114, 97, 156, 212, 46, 152, 8]; 567 | }, 568 | { 569 | name: "setParamsEvent"; 570 | discriminator: [223, 195, 159, 246, 62, 48, 143, 131]; 571 | } 572 | ]; 573 | types: [ 574 | { 575 | name: "global"; 576 | type: { 577 | kind: "struct"; 578 | fields: [ 579 | { 580 | name: "initialized"; 581 | type: "bool"; 582 | }, 583 | { 584 | name: "authority"; 585 | type: "pubkey"; 586 | }, 587 | { 588 | name: "feeRecipient"; 589 | type: "pubkey"; 590 | }, 591 | { 592 | name: "initialVirtualTokenReserves"; 593 | type: "u64"; 594 | }, 595 | { 596 | name: "initialVirtualSolReserves"; 597 | type: "u64"; 598 | }, 599 | { 600 | name: "initialRealTokenReserves"; 601 | type: "u64"; 602 | }, 603 | { 604 | name: "tokenTotalSupply"; 605 | type: "u64"; 606 | }, 607 | { 608 | name: "feeBasisPoints"; 609 | type: "u64"; 610 | } 611 | ]; 612 | }; 613 | }, 614 | { 615 | name: "lastWithdraw"; 616 | type: { 617 | kind: "struct"; 618 | fields: [ 619 | { 620 | name: "lastWithdrawTimestamp"; 621 | type: "i64"; 622 | } 623 | ]; 624 | }; 625 | }, 626 | { 627 | name: "bondingCurve"; 628 | type: { 629 | kind: "struct"; 630 | fields: [ 631 | { 632 | name: "virtualTokenReserves"; 633 | type: "u64"; 634 | }, 635 | { 636 | name: "virtualSolReserves"; 637 | type: "u64"; 638 | }, 639 | { 640 | name: "realTokenReserves"; 641 | type: "u64"; 642 | }, 643 | { 644 | name: "realSolReserves"; 645 | type: "u64"; 646 | }, 647 | { 648 | name: "tokenTotalSupply"; 649 | type: "u64"; 650 | }, 651 | { 652 | name: "complete"; 653 | type: "bool"; 654 | } 655 | ]; 656 | }; 657 | }, 658 | { 659 | name: "createEvent"; 660 | type: { 661 | kind: "struct"; 662 | fields: [ 663 | { 664 | name: "name"; 665 | type: "string"; 666 | index: false; 667 | }, 668 | { 669 | name: "symbol"; 670 | type: "string"; 671 | index: false; 672 | }, 673 | { 674 | name: "uri"; 675 | type: "string"; 676 | index: false; 677 | }, 678 | { 679 | name: "mint"; 680 | type: "pubkey"; 681 | index: false; 682 | }, 683 | { 684 | name: "bondingCurve"; 685 | type: "pubkey"; 686 | index: false; 687 | }, 688 | { 689 | name: "user"; 690 | type: "pubkey"; 691 | index: false; 692 | } 693 | ]; 694 | }; 695 | }, 696 | { 697 | name: "tradeEvent"; 698 | type: { 699 | kind: "struct"; 700 | fields: [ 701 | { 702 | name: "mint"; 703 | type: "pubkey"; 704 | index: false; 705 | }, 706 | { 707 | name: "solAmount"; 708 | type: "u64"; 709 | index: false; 710 | }, 711 | { 712 | name: "tokenAmount"; 713 | type: "u64"; 714 | index: false; 715 | }, 716 | { 717 | name: "isBuy"; 718 | type: "bool"; 719 | index: false; 720 | }, 721 | { 722 | name: "user"; 723 | type: "pubkey"; 724 | index: false; 725 | }, 726 | { 727 | name: "timestamp"; 728 | type: "i64"; 729 | index: false; 730 | }, 731 | { 732 | name: "virtualSolReserves"; 733 | type: "u64"; 734 | index: false; 735 | }, 736 | { 737 | name: "virtualTokenReserves"; 738 | type: "u64"; 739 | index: false; 740 | }, 741 | { 742 | name: "realSolReserves"; 743 | type: "u64"; 744 | index: false; 745 | }, 746 | { 747 | name: "realTokenReserves"; 748 | type: "u64"; 749 | index: false; 750 | } 751 | ]; 752 | }; 753 | }, 754 | { 755 | name: "completeEvent"; 756 | type: { 757 | kind: "struct"; 758 | fields: [ 759 | { 760 | name: "user"; 761 | type: "pubkey"; 762 | index: false; 763 | }, 764 | { 765 | name: "mint"; 766 | type: "pubkey"; 767 | index: false; 768 | }, 769 | { 770 | name: "bondingCurve"; 771 | type: "pubkey"; 772 | index: false; 773 | }, 774 | { 775 | name: "timestamp"; 776 | type: "i64"; 777 | index: false; 778 | } 779 | ]; 780 | }; 781 | }, 782 | { 783 | name: "setParamsEvent"; 784 | type: { 785 | kind: "struct"; 786 | fields: [ 787 | { 788 | name: "feeRecipient"; 789 | type: "pubkey"; 790 | index: false; 791 | }, 792 | { 793 | name: "initialVirtualTokenReserves"; 794 | type: "u64"; 795 | index: false; 796 | }, 797 | { 798 | name: "initialVirtualSolReserves"; 799 | type: "u64"; 800 | index: false; 801 | }, 802 | { 803 | name: "initialRealTokenReserves"; 804 | type: "u64"; 805 | index: false; 806 | }, 807 | { 808 | name: "tokenTotalSupply"; 809 | type: "u64"; 810 | index: false; 811 | }, 812 | { 813 | name: "feeBasisPoints"; 814 | type: "u64"; 815 | index: false; 816 | } 817 | ]; 818 | }; 819 | } 820 | ]; 821 | errors: [ 822 | { 823 | code: 6000; 824 | name: "NotAuthorized"; 825 | msg: "The given account is not authorized to execute this instruction."; 826 | }, 827 | { 828 | code: 6001; 829 | name: "AlreadyInitialized"; 830 | msg: "The program is already initialized."; 831 | }, 832 | { 833 | code: 6002; 834 | name: "TooMuchSolRequired"; 835 | msg: "slippage: Too much SOL required to buy the given amount of tokens."; 836 | }, 837 | { 838 | code: 6003; 839 | name: "TooLittleSolReceived"; 840 | msg: "slippage: Too little SOL received to sell the given amount of tokens."; 841 | }, 842 | { 843 | code: 6004; 844 | name: "MintDoesNotMatchBondingCurve"; 845 | msg: "The mint does not match the bonding curve."; 846 | }, 847 | { 848 | code: 6005; 849 | name: "BondingCurveComplete"; 850 | msg: "The bonding curve has completed and liquidity migrated to raydium."; 851 | }, 852 | { 853 | code: 6006; 854 | name: "BondingCurveNotComplete"; 855 | msg: "The bonding curve has not completed."; 856 | }, 857 | { 858 | code: 6007; 859 | name: "NotInitialized"; 860 | msg: "The program is not initialized."; 861 | }, 862 | { 863 | code: 6008; 864 | name: "WithdrawTooFrequent"; 865 | msg: "Withdraw too frequent"; 866 | } 867 | ]; 868 | }; -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------