├── .npmignore ├── .npmrc ├── src ├── IDL │ ├── index.ts │ └── pump-fun.json ├── pumpEvents │ ├── utils.ts │ ├── pumpEvents.consts.ts │ ├── pumpEvents.types.ts │ └── pumpEvents.ts ├── slippage.ts ├── modules │ ├── utils.ts │ ├── EventModule.ts │ ├── PdaModule.ts │ ├── TokenModule.ts │ ├── JitoModule.ts │ ├── NodeOneModule.ts │ ├── NextBlockModule.ts │ ├── SlotModule.ts │ ├── AstraModule.ts │ └── TradeModule.ts ├── index.ts ├── pumpFun.types.ts ├── pumpFun.consts.ts ├── PumpFunSDK.ts ├── globalAccount.ts ├── tx.ts ├── AgentRegistry.ts ├── FeeConfig.ts └── BondingCurveAccount.ts ├── example ├── images │ └── test.png ├── utils.ts ├── jitoExample.ts ├── providerExample.ts └── index.ts ├── tsconfig.json ├── tsconfig.base.json ├── LICENSE ├── package.json ├── rollup.config.js ├── .gitignore └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | example/ -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /src/IDL/index.ts: -------------------------------------------------------------------------------- 1 | export { default as IDL } from "./pump-fun.json"; 2 | -------------------------------------------------------------------------------- /example/images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D3AD-E/pumpdotfun-sdk-repumped/HEAD/example/images/test.png -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | }, 6 | "include": [ 7 | "./src/**/*", 8 | "./src/**/*.json", 9 | "./example/**/*", 10 | "./example/**/*.json" 11 | ] 12 | } -------------------------------------------------------------------------------- /src/pumpEvents/utils.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey, PublicKeyInitData } from "@solana/web3.js"; 2 | 3 | export const toPubKey = (v: PublicKeyInitData): PublicKey => new PublicKey(v); 4 | export const toBigInt = (v: string | number | bigint | boolean): bigint => 5 | BigInt(v); 6 | -------------------------------------------------------------------------------- /src/slippage.ts: -------------------------------------------------------------------------------- 1 | export const calculateWithSlippageBuy = ( 2 | amount: bigint, 3 | basisPoints: bigint 4 | ) => { 5 | return amount + (amount * basisPoints) / 10000n; 6 | }; 7 | 8 | export function calculateWithSlippageSell( 9 | amount: bigint, 10 | slippageBasisPoints: bigint = 500n 11 | ): bigint { 12 | // Actually use the slippage basis points for calculation 13 | const reduction = Math.max( 14 | 1, 15 | Number((amount * slippageBasisPoints) / 10000n) 16 | ); 17 | return amount - BigInt(reduction); 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node20/tsconfig.json", 3 | "include": ["./src/**/*", "./src/**/*.json"], 4 | "compilerOptions": { 5 | "module": "Node16", 6 | "sourceMap": true, 7 | "declaration": true, 8 | "declarationMap": true, 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true, 11 | "emitDecoratorMetadata": true, 12 | "noImplicitAny": false, 13 | "strictNullChecks": true, 14 | "esModuleInterop": true, 15 | "resolveJsonModule": true, 16 | "skipLibCheck": true 17 | } 18 | } -------------------------------------------------------------------------------- /src/modules/utils.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | 3 | const ACCOUNTS = [ 4 | new PublicKey("96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5"), 5 | new PublicKey("DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh"), 6 | new PublicKey("DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL"), 7 | new PublicKey("ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49"), 8 | new PublicKey("Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY"), 9 | new PublicKey("ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt"), 10 | new PublicKey("HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe"), 11 | new PublicKey("3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT"), 12 | ]; 13 | 14 | export function getRandomJitoTipAccount() { 15 | const randomIndex = Math.floor(Math.random() * ACCOUNTS.length); 16 | return ACCOUNTS[randomIndex]; 17 | } 18 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./PumpFunSDK.js"; 2 | export * from "./modules/TradeModule.js"; 3 | export * from "./modules/TokenModule.js"; 4 | export * from "./modules/EventModule.js"; 5 | export * from "./modules/JitoModule.js"; 6 | export * from "./modules/SlotModule.js"; 7 | export * from "./modules/NodeOneModule.js"; 8 | export * from "./modules/AstraModule.js"; 9 | export * from "./modules/NextBlockModule.js"; 10 | 11 | export * from "./BondingCurveAccount.js"; 12 | export * from "./GlobalAccount.js"; 13 | export * from "./slippage.js"; 14 | export * from "./tx.js"; 15 | 16 | export * from "./pumpFun.consts.js"; 17 | export * from "./pumpFun.types.js"; 18 | export * from "./pumpEvents/pumpEvents.consts.js"; 19 | export * from "./pumpEvents/pumpEvents.types.js"; 20 | 21 | export * from "./pumpEvents/pumpEvents.js"; 22 | -------------------------------------------------------------------------------- /src/pumpEvents/pumpEvents.consts.ts: -------------------------------------------------------------------------------- 1 | import { 2 | toCreateEvent, 3 | toTradeEvent, 4 | toCompleteEvent, 5 | toSetParamsEvent, 6 | toCollectCreatorFeeEvent, 7 | toCompletePumpAmmMigrationEvent, 8 | toExtendAccountEvent, 9 | toSetCreatorEvent, 10 | toSetMetaplexCreatorEvent, 11 | toUpdateGlobalAuthorityEvent, 12 | } from "./pumpEvents.js"; 13 | import { EventConverterMap } from "./pumpEvents.types.js"; 14 | 15 | export const converters: EventConverterMap = { 16 | createEvent: toCreateEvent, 17 | tradeEvent: toTradeEvent, 18 | completeEvent: toCompleteEvent, 19 | setParamsEvent: toSetParamsEvent, 20 | collectCreatorFeeEvent: toCollectCreatorFeeEvent, 21 | completePumpAmmMigrationEvent: toCompletePumpAmmMigrationEvent, 22 | extendAccountEvent: toExtendAccountEvent, 23 | setCreatorEvent: toSetCreatorEvent, 24 | setMetaplexCreatorEvent: toSetMetaplexCreatorEvent, 25 | updateGlobalAuthorityEvent: toUpdateGlobalAuthorityEvent, 26 | }; 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 D3AD 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/modules/EventModule.ts: -------------------------------------------------------------------------------- 1 | import { converters } from "../pumpEvents/pumpEvents.consts.js"; 2 | import { 3 | PumpFunEventType, 4 | PumpFunEventHandlers, 5 | } from "../pumpEvents/pumpEvents.types.js"; 6 | import { PumpFunSDK } from "../PumpFunSDK.js"; 7 | 8 | export class EventModule { 9 | constructor(private sdk: PumpFunSDK) {} 10 | 11 | addEventListener( 12 | eventType: T, 13 | callback: ( 14 | event: PumpFunEventHandlers[T], 15 | slot: number, 16 | signature: string 17 | ) => void 18 | ) { 19 | return this.sdk.program.addEventListener( 20 | eventType, 21 | (event: any, slot: number, signature: string) => { 22 | try { 23 | const convert = converters[eventType]; 24 | if (!convert) 25 | throw new Error(`No converter for event type: ${eventType}`); 26 | callback(convert(event), slot, signature); 27 | } catch (err) { 28 | console.error(`Failed to handle ${eventType}:`, err); 29 | } 30 | } 31 | ); 32 | } 33 | 34 | removeEventListener(id: number) { 35 | this.sdk.program.removeEventListener(id); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pumpFun.types.ts: -------------------------------------------------------------------------------- 1 | import { Keypair, VersionedTransactionResponse } from "@solana/web3.js"; 2 | 3 | export type CreateTokenMetadata = { 4 | name: string; 5 | symbol: string; 6 | description: string; 7 | file: Blob; 8 | twitter?: string; 9 | telegram?: string; 10 | website?: string; 11 | }; 12 | export type PriorityFee = { 13 | unitLimit: number; 14 | unitPrice: number; 15 | }; 16 | 17 | export type TransactionResult = { 18 | signature?: string; 19 | error?: unknown; 20 | results?: VersionedTransactionResponse; 21 | success: boolean; 22 | }; 23 | 24 | export type PumpOptions = { 25 | jitoUrl?: string; 26 | authKeypair?: Keypair; 27 | providerRegion?: Region; 28 | shouldKeepAlive?: boolean; 29 | astraKey?: string; 30 | slotKey?: string; 31 | nextBlockKey?: string; 32 | nodeOneKey?: string; 33 | }; 34 | 35 | export type JitoResult = { 36 | bundleId?: string; 37 | error?: unknown; 38 | success: boolean; 39 | }; 40 | export type HostKey = "slot" | "node" | "nextBlock" | "astra"; 41 | 42 | export enum Region { 43 | Frankfurt = "fra", 44 | NY = "ny", 45 | Tokyo = "tokyo", 46 | Amsterdam = "ams", 47 | LosAngeles = "la", 48 | } 49 | -------------------------------------------------------------------------------- /example/utils.ts: -------------------------------------------------------------------------------- 1 | import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes/index.js"; 2 | import { Connection, Keypair, PublicKey } from "@solana/web3.js"; 3 | function parseSecretKey(v: string | undefined): number[] { 4 | if (!v) throw new Error("WALLET_PRIVATE_KEY missing"); 5 | let parsed: unknown; 6 | try { 7 | parsed = JSON.parse(v); 8 | } catch { 9 | throw new Error('WALLET_PRIVATE_KEY must be valid JSON (e.g. "[1,2,3]")'); 10 | } 11 | if ( 12 | !Array.isArray(parsed) || 13 | !parsed.every((n) => Number.isInteger(n) && n >= 0 && n <= 255) 14 | ) { 15 | throw new Error("WALLET_PRIVATE_KEY must be an array of 0-255 integers"); 16 | } 17 | return parsed as number[]; 18 | } 19 | export const wallet = Keypair.fromSecretKey( 20 | Buffer.from(parseSecretKey(process.env.WALLET_PRIVATE_KEY)) 21 | ); 22 | 23 | export async function getSPL( 24 | conn: Connection, 25 | mint: PublicKey, 26 | owner: PublicKey 27 | ) { 28 | const ata = PublicKey.findProgramAddressSync( 29 | [ 30 | owner.toBuffer(), 31 | new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").toBuffer(), 32 | mint.toBuffer(), 33 | ], 34 | new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL") 35 | )[0]; 36 | 37 | const info = await conn.getTokenAccountBalance(ata).catch(() => null); 38 | return info ? Number(info.value.amount) : 0; 39 | } 40 | -------------------------------------------------------------------------------- /example/jitoExample.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { 3 | Connection, 4 | Keypair, 5 | LAMPORTS_PER_SOL, 6 | PublicKey, 7 | } from "@solana/web3.js"; 8 | import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; 9 | import { DEFAULT_DECIMALS } from "../src/pumpFun.consts.js"; 10 | import { getSPL, wallet } from "./utils.js"; 11 | import fs from "fs"; 12 | import { PumpFunSDK } from "../src/PumpFunSDK.js"; 13 | import { Region } from "../src/pumpFun.types.js"; 14 | 15 | async function printSOL(conn: Connection, pk: PublicKey, label = "") { 16 | const bal = (await conn.getBalance(pk)) / LAMPORTS_PER_SOL; 17 | console.log(`${label} SOL balance:`, bal.toFixed(4)); 18 | } 19 | 20 | const DEVNET_RPC = "https://api.devnet.solana.com"; 21 | const SLIPPAGE_BPS = 100n; 22 | const PRIORITY = { unitLimit: 250_000, unitPrice: 250_000 }; // devnet tip 23 | 24 | async function main() { 25 | const connection = new Connection(DEVNET_RPC, { commitment: "confirmed" }); 26 | const dummyWallet = new Wallet(wallet); 27 | const provider = new AnchorProvider(connection, dummyWallet, { 28 | commitment: "confirmed", 29 | }); 30 | const sdk = new PumpFunSDK(provider, { 31 | jitoUrl: "ny.mainnet.block-engine.jito.wtf", 32 | }); 33 | const mint = Keypair.generate(); 34 | 35 | await printSOL(connection, wallet.publicKey, "User"); 36 | console.log("Buying with jito"); 37 | await sdk.jito!.buyJito( 38 | wallet, 39 | mint.publicKey, 40 | BigInt(0.0002 * LAMPORTS_PER_SOL), 41 | SLIPPAGE_BPS, 42 | 500_000, // 500_000 tip 43 | PRIORITY, 44 | "confirmed" 45 | ); 46 | const splAfterBuy = await getSPL( 47 | connection, 48 | mint.publicKey, 49 | wallet.publicKey 50 | ); 51 | console.log("User now holds", splAfterBuy / 10 ** DEFAULT_DECIMALS, "tokens"); 52 | } 53 | 54 | main().catch((e) => console.error(e)); 55 | -------------------------------------------------------------------------------- /example/providerExample.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { 3 | Connection, 4 | Keypair, 5 | LAMPORTS_PER_SOL, 6 | PublicKey, 7 | } from "@solana/web3.js"; 8 | import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; 9 | import { DEFAULT_DECIMALS } from "../src/pumpFun.consts.js"; 10 | import { getSPL, wallet } from "./utils.js"; 11 | import fs from "fs"; 12 | import { PumpFunSDK } from "../src/PumpFunSDK.js"; 13 | import { Region } from "../src/pumpFun.types.js"; 14 | 15 | async function printSOL(conn: Connection, pk: PublicKey, label = "") { 16 | const bal = (await conn.getBalance(pk)) / LAMPORTS_PER_SOL; 17 | console.log(`${label} SOL balance:`, bal.toFixed(4)); 18 | } 19 | 20 | const DEVNET_RPC = "https://api.devnet.solana.com"; 21 | const SLOT_KEY = "key"; 22 | const SLIPPAGE_BPS = 100n; 23 | const PRIORITY = { unitLimit: 250_000, unitPrice: 250_000 }; // devnet tip 24 | 25 | async function main() { 26 | const connection = new Connection(DEVNET_RPC, { commitment: "confirmed" }); 27 | const dummyWallet = new Wallet(wallet); 28 | const provider = new AnchorProvider(connection, dummyWallet, { 29 | commitment: "confirmed", 30 | }); 31 | const sdk = new PumpFunSDK(provider, { 32 | providerRegion: Region.Frankfurt, 33 | slotKey: SLOT_KEY, 34 | }); 35 | const mint = Keypair.generate(); 36 | 37 | await printSOL(connection, wallet.publicKey, "User"); 38 | console.log("Ping slot provider…"); 39 | const pingRes = await sdk.slot!.ping(); 40 | console.log("Ping response:", pingRes); 41 | console.log("Buying with 0slot"); 42 | await sdk.slot!.buy( 43 | wallet, 44 | mint.publicKey, 45 | BigInt(0.0002 * LAMPORTS_PER_SOL), 46 | SLIPPAGE_BPS, 47 | 500_000, // 500_000 tip 48 | PRIORITY, 49 | "confirmed" 50 | ); 51 | const splAfterBuy = await getSPL( 52 | connection, 53 | mint.publicKey, 54 | wallet.publicKey 55 | ); 56 | console.log("User now holds", splAfterBuy / 10 ** DEFAULT_DECIMALS, "tokens"); 57 | } 58 | 59 | main().catch((e) => console.error(e)); 60 | -------------------------------------------------------------------------------- /src/pumpFun.consts.ts: -------------------------------------------------------------------------------- 1 | import { Commitment, Finality, PublicKey } from "@solana/web3.js"; 2 | import { Region } from "./pumpFun.types.js"; 3 | 4 | export const MPL_TOKEN_METADATA_PROGRAM_ID = 5 | "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"; 6 | 7 | export const GLOBAL_ACCOUNT_SEED = "global"; 8 | export const MINT_AUTHORITY_SEED = "mint-authority"; 9 | export const BONDING_CURVE_SEED = "bonding-curve"; 10 | export const METADATA_SEED = "metadata"; 11 | export const EVENT_AUTHORITY_SEED = "__event_authority"; 12 | export const GLOBAL_VOLUME_SEED = "global_volume_accumulator"; 13 | export const USER_VOLUME_SEED = "user_volume_accumulator"; 14 | export const PUMP_PROGRAM_ID = new PublicKey( 15 | "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 16 | ); 17 | export const PUMP_FEE_PROGRAM_ID = new PublicKey( 18 | "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ" 19 | ); 20 | export const DEFAULT_DECIMALS = 6; 21 | 22 | export const DEFAULT_COMMITMENT: Commitment = "finalized"; 23 | export const DEFAULT_FINALITY: Finality = "finalized"; 24 | 25 | export const SLOT_ENDPOINT_BY_REGION: Record = { 26 | [Region.Frankfurt]: "de1.0slot.trade", 27 | [Region.NY]: "ny1.0slot.trade", 28 | [Region.Tokyo]: "jp.0slot.trade", 29 | [Region.Amsterdam]: "ams1.0slot.trade", 30 | [Region.LosAngeles]: "la1.0slot.trade", 31 | }; 32 | 33 | export const ASTRA_ENDPOINT_BY_REGION: Partial> = { 34 | [Region.Frankfurt]: "fr.gateway.astralane.io", 35 | [Region.NY]: "ny.gateway.astralane.io", 36 | [Region.Tokyo]: "jp.gateway.astralane.io", 37 | [Region.Amsterdam]: "ams.gateway.astralane.io", 38 | }; 39 | 40 | export const NODE1_ENDPOINT_BY_REGION: Partial> = { 41 | [Region.NY]: "ny.node1.me", 42 | [Region.Tokyo]: "ny.node1.me", 43 | [Region.Amsterdam]: "ams.node1.me", 44 | [Region.Frankfurt]: "fra.node1.me", 45 | }; 46 | 47 | export const NEXTBLOCK_ENDPOINT_BY_REGION: Partial> = { 48 | [Region.Tokyo]: "tokyo.nextblock.io", 49 | [Region.Frankfurt]: "fra.nextblock.io", 50 | [Region.NY]: "ny.nextblock.io", 51 | }; 52 | 53 | export const getHealthBody = JSON.stringify({ 54 | jsonrpc: "2.0", 55 | id: 1, 56 | method: "getHealth", 57 | }); 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pumpdotfun-repumped-sdk", 3 | "version": "1.4.2", 4 | "description": "Pumpfun SDK — create, buy, sell tokens with support for Jito bundles and multiple relayer integrations. Rebuilt and fixed pumpdotfun-sdk.", 5 | "author": "D3AD-E ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/D3AD-E/pumpdotfun-sdk-repumped.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/D3AD-E/pumpdotfun-sdk-repumped/issues" 13 | }, 14 | "homepage": "https://github.com/D3AD-E/pumpdotfun-sdk-repumped#readme", 15 | "type": "module", 16 | "main": "dist/cjs/index.js", 17 | "module": "dist/esm/index.mjs", 18 | "types": "dist/index.d.ts", 19 | "exports": { 20 | ".": { 21 | "import": "./dist/esm/index.mjs", 22 | "require": "./dist/cjs/index.cjs", 23 | "types": "./dist/esm/index.d.ts" 24 | } 25 | }, 26 | "files": [ 27 | "dist", 28 | "README.md", 29 | "LICENSE" 30 | ], 31 | "sideEffects": false, 32 | "engines": { 33 | "node": ">=18" 34 | }, 35 | "scripts": { 36 | "build": "rimraf dist && rollup -c --bundleConfigAsCjs", 37 | "prepare": "npm run build", 38 | "example": "npm run build && tsx example/index.ts", 39 | "lint": "tsc -p tsconfig.json --noEmit" 40 | }, 41 | "dependencies": { 42 | "@coral-xyz/anchor": "^0.31.1", 43 | "@solana/spl-token": "^0.4.13", 44 | "@solana/web3.js": "^1.98.2", 45 | "bn.js": "^5.2.2", 46 | "jito-ts": "^4.2.0" 47 | }, 48 | "devDependencies": { 49 | "@coral-xyz/borsh": "^0.31.1", 50 | "@rollup/plugin-commonjs": "^28.0.6", 51 | "@rollup/plugin-json": "^6.1.0", 52 | "@rollup/plugin-node-resolve": "^16.0.1", 53 | "@rollup/plugin-typescript": "^12.1.3", 54 | "@tsconfig/node20": "^20.1.6", 55 | "@types/node": "^20.19.1", 56 | "dotenv": "^16.5.0", 57 | "rimraf": "^6.0.1", 58 | "rollup": "^4.44.0", 59 | "tsx": "^4.20.3", 60 | "typescript": "^5.8.3" 61 | }, 62 | "publishConfig": { 63 | "access": "public" 64 | }, 65 | "keywords": [ 66 | "pump.fun", 67 | "pumpfun", 68 | "pumpdotfun", 69 | "solana", 70 | "pumpdotfunsdk", 71 | "sdk", 72 | "token", 73 | "jito", 74 | "web3", 75 | "create", 76 | "buy", 77 | "sell", 78 | "trading" 79 | ] 80 | } 81 | -------------------------------------------------------------------------------- /src/modules/PdaModule.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { 3 | GLOBAL_ACCOUNT_SEED, 4 | EVENT_AUTHORITY_SEED, 5 | BONDING_CURVE_SEED, 6 | MINT_AUTHORITY_SEED, 7 | MPL_TOKEN_METADATA_PROGRAM_ID, 8 | METADATA_SEED, 9 | GLOBAL_VOLUME_SEED, 10 | USER_VOLUME_SEED, 11 | PUMP_PROGRAM_ID, 12 | PUMP_FEE_PROGRAM_ID, 13 | } from "../pumpFun.consts.js"; 14 | import { PumpFunSDK } from "../PumpFunSDK.js"; 15 | 16 | export class PdaModule { 17 | constructor(private sdk: PumpFunSDK) {} 18 | 19 | getCreatorVaultPda(creator: PublicKey): PublicKey { 20 | return PublicKey.findProgramAddressSync( 21 | [Buffer.from("creator-vault"), creator.toBuffer()], 22 | this.sdk.program.programId 23 | )[0]; 24 | } 25 | 26 | getGlobalAccountPda(): PublicKey { 27 | return PublicKey.findProgramAddressSync( 28 | [Buffer.from(GLOBAL_ACCOUNT_SEED)], 29 | this.sdk.program.programId 30 | )[0]; 31 | } 32 | 33 | getEventAuthorityPda(): PublicKey { 34 | return PublicKey.findProgramAddressSync( 35 | [Buffer.from(EVENT_AUTHORITY_SEED)], 36 | this.sdk.program.programId 37 | )[0]; 38 | } 39 | 40 | getBondingCurvePDA(mint: PublicKey) { 41 | return PublicKey.findProgramAddressSync( 42 | [Buffer.from(BONDING_CURVE_SEED), mint.toBuffer()], 43 | this.sdk.program.programId 44 | )[0]; 45 | } 46 | 47 | getMintAuthorityPDA() { 48 | return PublicKey.findProgramAddressSync( 49 | [Buffer.from(MINT_AUTHORITY_SEED)], 50 | this.sdk.program.programId 51 | )[0]; 52 | } 53 | 54 | getPumpFeeConfigPda(): PublicKey { 55 | return PublicKey.findProgramAddressSync( 56 | [Buffer.from("fee_config"), PUMP_PROGRAM_ID.toBuffer()], 57 | PUMP_FEE_PROGRAM_ID 58 | )[0]; 59 | } 60 | 61 | getMetadataPDA(mint: PublicKey): PublicKey { 62 | const metadataProgram = new PublicKey(MPL_TOKEN_METADATA_PROGRAM_ID); 63 | 64 | const [metadataPDA] = PublicKey.findProgramAddressSync( 65 | [Buffer.from(METADATA_SEED), metadataProgram.toBuffer(), mint.toBuffer()], 66 | metadataProgram 67 | ); 68 | return metadataPDA; 69 | } 70 | 71 | getGlobalVolumeAccumulatorPda(): PublicKey { 72 | return PublicKey.findProgramAddressSync( 73 | [Buffer.from(GLOBAL_VOLUME_SEED)], 74 | this.sdk.program.programId 75 | )[0]; 76 | } 77 | 78 | getUserVolumeAccumulatorPda(user: PublicKey): PublicKey { 79 | return PublicKey.findProgramAddressSync( 80 | [Buffer.from(USER_VOLUME_SEED), user.toBuffer()], 81 | this.sdk.program.programId 82 | )[0]; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /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 | import { builtinModules } from "module"; 6 | 7 | const nodeBuiltins = builtinModules; 8 | const external = (id) => 9 | [ 10 | "@coral-xyz/borsh", 11 | "@solana/web3.js", 12 | "@solana/spl-token", 13 | "@coral-xyz/anchor", 14 | "jito-ts", 15 | ...nodeBuiltins, 16 | ].some((pkg) => id === pkg || id.startsWith(`${pkg}/`)) || 17 | builtinModules.includes(id); 18 | 19 | const plugins = [ 20 | commonjs(), 21 | json(), 22 | nodeResolve({ 23 | extensions: [".js", ".ts"], 24 | preferBuiltins: false, 25 | }), 26 | ]; 27 | 28 | export default [ 29 | // ESM build 30 | { 31 | input: "src/index.ts", 32 | output: { 33 | dir: "dist/esm", 34 | format: "es", 35 | entryFileNames: "[name].mjs", 36 | sourcemap: true, 37 | preserveModules: true, 38 | preserveModulesRoot: "src", 39 | }, 40 | plugins: [ 41 | ...plugins, 42 | typescript({ 43 | tsconfig: "./tsconfig.base.json", 44 | outDir: "./dist/esm", 45 | outputToFilesystem: false, 46 | sourceMap: true, 47 | inlineSources: true, 48 | }), 49 | ], 50 | external, 51 | }, 52 | // CommonJS build 53 | { 54 | input: "src/index.ts", 55 | output: { 56 | dir: "dist/cjs", 57 | format: "cjs", 58 | entryFileNames: "[name].cjs", 59 | sourcemap: true, 60 | preserveModules: true, 61 | preserveModulesRoot: "src", 62 | exports: "named", 63 | }, 64 | plugins: [ 65 | ...plugins, 66 | typescript({ 67 | tsconfig: "./tsconfig.base.json", 68 | outDir: "./dist/cjs", 69 | outputToFilesystem: false, 70 | sourceMap: true, 71 | inlineSources: true, 72 | }), 73 | ], 74 | external, 75 | }, 76 | // Browser build 77 | { 78 | input: "src/index.ts", 79 | output: { 80 | file: "dist/browser/index.js", 81 | format: "es", 82 | sourcemap: true, 83 | }, 84 | plugins: [ 85 | commonjs(), 86 | json(), 87 | nodeResolve({ 88 | browser: true, 89 | extensions: [".js", ".ts"], 90 | preferBuiltins: false, 91 | }), 92 | typescript({ 93 | tsconfig: "./tsconfig.base.json", 94 | outDir: "./dist/browser", 95 | outputToFilesystem: false, 96 | compilerOptions: { 97 | module: "ES2022", 98 | moduleResolution: "bundler", 99 | }, 100 | }), 101 | ], 102 | external, 103 | }, 104 | ]; 105 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # vitepress build output 108 | **/.vitepress/dist 109 | 110 | # vitepress cache directory 111 | **/.vitepress/cache 112 | 113 | # Docusaurus cache and generated files 114 | .docusaurus 115 | 116 | # Serverless directories 117 | .serverless/ 118 | 119 | # FuseBox cache 120 | .fusebox/ 121 | 122 | # DynamoDB Local files 123 | .dynamodb/ 124 | 125 | # TernJS port file 126 | .tern-port 127 | 128 | # Stores VSCode versions used for testing VSCode extensions 129 | .vscode-test 130 | 131 | # yarn v2 132 | .yarn/cache 133 | .yarn/unplugged 134 | .yarn/build-state.yml 135 | .yarn/install-state.gz 136 | .pnp.* 137 | wallet.json -------------------------------------------------------------------------------- /example/index.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { 3 | Connection, 4 | Keypair, 5 | LAMPORTS_PER_SOL, 6 | PublicKey, 7 | } from "@solana/web3.js"; 8 | import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; 9 | import { DEFAULT_DECIMALS } from "../src/pumpFun.consts.js"; 10 | import { getSPL, wallet } from "./utils.js"; 11 | import fs from "fs"; 12 | import { PumpFunSDK } from "../dist/esm/index.mjs"; 13 | 14 | async function printSOL(conn: Connection, pk: PublicKey, label = "") { 15 | const bal = (await conn.getBalance(pk)) / LAMPORTS_PER_SOL; 16 | console.log(`${label} SOL balance:`, bal.toFixed(4)); 17 | } 18 | 19 | const DEVNET_RPC = "https://api.devnet.solana.com"; 20 | const SLIPPAGE_BPS = 1000n; 21 | const PRIORITY = { unitLimit: 250_000, unitPrice: 250_000 }; // devnet tip 22 | 23 | async function main() { 24 | const connection = new Connection(DEVNET_RPC, { commitment: "confirmed" }); 25 | const dummyWallet = new Wallet(wallet); 26 | const provider = new AnchorProvider(connection, dummyWallet, { 27 | commitment: "confirmed", 28 | }); 29 | const sdk = new PumpFunSDK(provider); 30 | const mint = Keypair.generate(); 31 | 32 | await printSOL(connection, wallet.publicKey, "User"); 33 | 34 | console.log("Creating token & first buy…"); 35 | const buffer = await fs.promises.readFile("example/images/test.png"); 36 | const blob = new Blob([buffer], { type: "image/png" }); 37 | const meta = { 38 | name: "TST-7", 39 | symbol: "TST-7", 40 | description: "Test token on devnet", 41 | file: blob, 42 | }; 43 | const res = await sdk.trade.createAndBuy( 44 | wallet, 45 | mint, 46 | meta, 47 | BigInt(0.0001 * LAMPORTS_PER_SOL), 48 | SLIPPAGE_BPS, 49 | PRIORITY 50 | ); 51 | 52 | if (!res.success) throw new Error("createAndBuy failed"); 53 | const curve = await sdk.token.getBondingCurveAccount(mint.publicKey); 54 | console.log( 55 | "Created! Pump link:", 56 | `https://pump.fun/${mint.publicKey.toBase58()}?cluster=devnet` 57 | ); 58 | 59 | /* 4. second buy */ 60 | console.log("Buying again…"); 61 | await sdk.trade.buy( 62 | wallet, 63 | mint.publicKey, 64 | BigInt(0.0002 * LAMPORTS_PER_SOL), 65 | SLIPPAGE_BPS, 66 | PRIORITY 67 | ); 68 | const splAfterBuy = await getSPL( 69 | connection, 70 | mint.publicKey, 71 | wallet.publicKey 72 | ); 73 | console.log("User now holds", splAfterBuy / 10 ** DEFAULT_DECIMALS, "tokens"); 74 | 75 | /* 5. sell everything back */ 76 | console.log("Selling all…"); 77 | await sdk.trade.sell( 78 | wallet, 79 | mint.publicKey, 80 | BigInt(splAfterBuy), 81 | SLIPPAGE_BPS, 82 | PRIORITY 83 | ); 84 | await printSOL(connection, wallet.publicKey, "User after sell"); 85 | 86 | console.log( 87 | "Bonding curve state:", 88 | await sdk.token.getBondingCurveAccount(mint.publicKey) 89 | ); 90 | } 91 | 92 | main().catch((e) => console.error(e)); 93 | -------------------------------------------------------------------------------- /src/PumpFunSDK.ts: -------------------------------------------------------------------------------- 1 | import { Program, Idl, Provider } from "@coral-xyz/anchor"; 2 | import { Connection } from "@solana/web3.js"; 3 | import { IDL } from "./IDL/index.js"; 4 | import { EventModule } from "./modules/EventModule.js"; 5 | import { TokenModule } from "./modules/TokenModule.js"; 6 | import { TradeModule } from "./modules/TradeModule.js"; 7 | import { PdaModule } from "./modules/PdaModule.js"; 8 | import { JitoModule } from "./modules/JitoModule.js"; 9 | import { PumpOptions } from "./pumpFun.types.js"; 10 | import { AstraModule } from "./modules/AstraModule.js"; 11 | import { SlotModule } from "./modules/SlotModule.js"; 12 | import { NextBlockModule } from "./modules/NextBlockModule.js"; 13 | import { NodeOneModule } from "./modules/NodeOneModule.js"; 14 | 15 | export class PumpFunSDK { 16 | public program: Program; 17 | public connection: Connection; 18 | public token: TokenModule; 19 | public trade: TradeModule; 20 | public pda: PdaModule; 21 | public jito?: JitoModule; 22 | public astra?: AstraModule; 23 | public slot?: SlotModule; 24 | public nextBlock?: NextBlockModule; 25 | public nodeOne?: NodeOneModule; 26 | public events: EventModule; 27 | 28 | constructor(provider: Provider, options?: PumpOptions) { 29 | this.program = new Program(IDL as Idl, provider); 30 | this.connection = this.program.provider.connection; 31 | 32 | // Initialize modules 33 | this.token = new TokenModule(this); 34 | this.trade = new TradeModule(this); 35 | this.events = new EventModule(this); 36 | this.pda = new PdaModule(this); 37 | if (options?.jitoUrl) { 38 | this.jito = new JitoModule(this, options.jitoUrl, options.authKeypair); 39 | } 40 | if (options?.astraKey) { 41 | if (!options.providerRegion) { 42 | throw new Error("Provider region is required for Astra module."); 43 | } 44 | this.astra = new AstraModule( 45 | this, 46 | options.providerRegion, 47 | options.astraKey 48 | ); 49 | } 50 | if (options?.slotKey) { 51 | if (!options.providerRegion) { 52 | throw new Error("Provider region is required for 0Slot module."); 53 | } 54 | this.slot = new SlotModule(this, options.providerRegion, options.slotKey); 55 | } 56 | if (options?.nextBlockKey) { 57 | if (!options.providerRegion) { 58 | throw new Error("Provider region is required for NextBlock module."); 59 | } 60 | this.nextBlock = new NextBlockModule( 61 | this, 62 | options.providerRegion, 63 | options.nextBlockKey 64 | ); 65 | } 66 | if (options?.nodeOneKey) { 67 | if (!options.providerRegion) { 68 | throw new Error("Provider region is required for NodeOne module."); 69 | } 70 | this.nodeOne = new NodeOneModule( 71 | this, 72 | options.providerRegion, 73 | options.nodeOneKey 74 | ); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/pumpEvents/pumpEvents.types.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | 3 | export type CollectCreatorFeeEvent = { 4 | timestamp: number; 5 | creator: PublicKey; 6 | creatorFee: bigint; 7 | }; 8 | 9 | export type CompleteEvent = { 10 | user: PublicKey; 11 | mint: PublicKey; 12 | bondingCurve: PublicKey; 13 | timestamp: number; 14 | }; 15 | 16 | export type CompletePumpAmmMigrationEvent = { 17 | user: PublicKey; 18 | mint: PublicKey; 19 | mintAmount: bigint; 20 | solAmount: bigint; 21 | poolMigrationFee: bigint; 22 | bondingCurve: PublicKey; 23 | timestamp: number; 24 | pool: PublicKey; 25 | }; 26 | 27 | export type CreateEvent = { 28 | name: string; 29 | symbol: string; 30 | uri: string; 31 | mint: PublicKey; 32 | bondingCurve: PublicKey; 33 | user: PublicKey; 34 | creator: PublicKey; 35 | timestamp: number; 36 | virtualTokenReserves: bigint; 37 | virtualSolReserves: bigint; 38 | realTokenReserves: bigint; 39 | tokenTotalSupply: bigint; 40 | }; 41 | 42 | export type ExtendAccountEvent = { 43 | account: PublicKey; 44 | user: PublicKey; 45 | currentSize: bigint; 46 | newSize: bigint; 47 | timestamp: number; 48 | }; 49 | 50 | export type SetCreatorEvent = { 51 | timestamp: number; 52 | mint: PublicKey; 53 | bondingCurve: PublicKey; 54 | creator: PublicKey; 55 | }; 56 | 57 | export type SetMetaplexCreatorEvent = { 58 | timestamp: number; 59 | mint: PublicKey; 60 | bondingCurve: PublicKey; 61 | metadata: PublicKey; 62 | creator: PublicKey; 63 | }; 64 | 65 | export type SetParamsEvent = { 66 | initialVirtualTokenReserves: bigint; 67 | initialVirtualSolReserves: bigint; 68 | initialRealTokenReserves: bigint; 69 | finalRealSolReserves: bigint; 70 | tokenTotalSupply: bigint; 71 | feeBasisPoints: bigint; 72 | withdrawAuthority: PublicKey; 73 | enableMigrate: boolean; 74 | poolMigrationFee: bigint; 75 | creatorFeeBasisPoints: bigint; 76 | feeRecipients: PublicKey[]; // length: 8 77 | timestamp: number; 78 | setCreatorAuthority: PublicKey; 79 | }; 80 | 81 | export type TradeEvent = { 82 | mint: PublicKey; 83 | solAmount: bigint; 84 | tokenAmount: bigint; 85 | isBuy: boolean; 86 | user: PublicKey; 87 | timestamp: number; 88 | virtualSolReserves: bigint; 89 | virtualTokenReserves: bigint; 90 | realSolReserves: bigint; 91 | realTokenReserves: bigint; 92 | feeRecipient: PublicKey; 93 | feeBasisPoints: bigint; 94 | fee: bigint; 95 | creator: PublicKey; 96 | creatorFeeBasisPoints: bigint; 97 | creatorFee: bigint; 98 | }; 99 | 100 | export type UpdateGlobalAuthorityEvent = { 101 | global: PublicKey; 102 | authority: PublicKey; 103 | newAuthority: PublicKey; 104 | timestamp: number; 105 | }; 106 | 107 | export interface PumpFunEventHandlers { 108 | collectCreatorFeeEvent: CollectCreatorFeeEvent; 109 | completeEvent: CompleteEvent; 110 | completePumpAmmMigrationEvent: CompletePumpAmmMigrationEvent; 111 | createEvent: CreateEvent; 112 | extendAccountEvent: ExtendAccountEvent; 113 | setCreatorEvent: SetCreatorEvent; 114 | setMetaplexCreatorEvent: SetMetaplexCreatorEvent; 115 | setParamsEvent: SetParamsEvent; 116 | tradeEvent: TradeEvent; 117 | updateGlobalAuthorityEvent: UpdateGlobalAuthorityEvent; 118 | } 119 | 120 | export type PumpFunEventType = keyof PumpFunEventHandlers; 121 | 122 | export type EventConverterMap = { 123 | [K in PumpFunEventType]: (event: any) => PumpFunEventHandlers[K]; 124 | }; 125 | -------------------------------------------------------------------------------- /src/globalAccount.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { struct, bool, u64, publicKey, Layout } from "@coral-xyz/borsh"; 3 | 4 | export class GlobalAccount { 5 | public discriminator: bigint; 6 | public initialized: boolean = false; 7 | public authority: PublicKey; 8 | public feeRecipient: PublicKey; 9 | public initialVirtualTokenReserves: bigint; 10 | public initialVirtualSolReserves: bigint; 11 | public initialRealTokenReserves: bigint; 12 | public tokenTotalSupply: bigint; 13 | public feeBasisPoints: bigint; 14 | public withdrawAuthority: PublicKey; 15 | public enableMigrate: boolean = false; 16 | public poolMigrationFee: bigint; 17 | public creatorFeeBasisPoints: bigint; 18 | 19 | constructor( 20 | discriminator: bigint, 21 | initialized: boolean, 22 | authority: PublicKey, 23 | feeRecipient: PublicKey, 24 | initialVirtualTokenReserves: bigint, 25 | initialVirtualSolReserves: bigint, 26 | initialRealTokenReserves: bigint, 27 | tokenTotalSupply: bigint, 28 | feeBasisPoints: bigint, 29 | withdrawAuthority: PublicKey, 30 | enableMigrate: boolean, 31 | poolMigrationFee: bigint, 32 | creatorFeeBasisPoints: bigint 33 | ) { 34 | this.discriminator = discriminator; 35 | this.initialized = initialized; 36 | this.authority = authority; 37 | this.feeRecipient = feeRecipient; 38 | this.initialVirtualTokenReserves = initialVirtualTokenReserves; 39 | this.initialVirtualSolReserves = initialVirtualSolReserves; 40 | this.initialRealTokenReserves = initialRealTokenReserves; 41 | this.tokenTotalSupply = tokenTotalSupply; 42 | this.feeBasisPoints = feeBasisPoints; 43 | this.withdrawAuthority = withdrawAuthority; 44 | this.enableMigrate = enableMigrate; 45 | this.poolMigrationFee = poolMigrationFee; 46 | this.creatorFeeBasisPoints = creatorFeeBasisPoints; 47 | } 48 | 49 | getInitialBuyPrice(amount: bigint): bigint { 50 | if (amount <= 0n) { 51 | return 0n; 52 | } 53 | 54 | let n = this.initialVirtualSolReserves * this.initialVirtualTokenReserves; 55 | let i = this.initialVirtualSolReserves + amount; 56 | let r = n / i + 1n; 57 | let s = this.initialVirtualTokenReserves - r; 58 | return s < this.initialRealTokenReserves 59 | ? s 60 | : this.initialRealTokenReserves; 61 | } 62 | 63 | public static fromBuffer(buffer: Buffer): GlobalAccount { 64 | const structure: Layout = struct([ 65 | u64("discriminator"), 66 | bool("initialized"), 67 | publicKey("authority"), 68 | publicKey("feeRecipient"), 69 | u64("initialVirtualTokenReserves"), 70 | u64("initialVirtualSolReserves"), 71 | u64("initialRealTokenReserves"), 72 | u64("tokenTotalSupply"), 73 | u64("feeBasisPoints"), 74 | publicKey("withdrawAuthority"), 75 | bool("enableMigrate"), 76 | u64("poolMigrationFee"), 77 | u64("creatorFeeBasisPoints"), 78 | ]); 79 | 80 | let value = structure.decode(buffer); 81 | return new GlobalAccount( 82 | BigInt(value.discriminator), 83 | value.initialized, 84 | value.authority, 85 | value.feeRecipient, 86 | BigInt(value.initialVirtualTokenReserves), 87 | BigInt(value.initialVirtualSolReserves), 88 | BigInt(value.initialRealTokenReserves), 89 | BigInt(value.tokenTotalSupply), 90 | BigInt(value.feeBasisPoints), 91 | value.withdrawAuthority, 92 | value.enableMigrate, 93 | BigInt(value.poolMigrationFee), 94 | BigInt(value.creatorFeeBasisPoints) 95 | ); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/tx.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Connection, 3 | Transaction, 4 | PublicKey, 5 | Keypair, 6 | Commitment, 7 | Finality, 8 | ComputeBudgetProgram, 9 | SendTransactionError, 10 | VersionedTransaction, 11 | TransactionMessage, 12 | VersionedTransactionResponse, 13 | } from "@solana/web3.js"; 14 | import { DEFAULT_COMMITMENT, DEFAULT_FINALITY } from "./pumpFun.consts.js"; 15 | import { PriorityFee, TransactionResult } from "./pumpFun.types.js"; 16 | 17 | export async function sendTx( 18 | connection: Connection, 19 | tx: Transaction, 20 | payer: PublicKey, 21 | signers: Keypair[], 22 | priorityFees?: PriorityFee, 23 | commitment: Commitment = DEFAULT_COMMITMENT, 24 | finality: Finality = DEFAULT_FINALITY 25 | ): Promise { 26 | let versionedTx = await buildSignedTx( 27 | priorityFees, 28 | tx, 29 | connection, 30 | payer, 31 | commitment, 32 | signers 33 | ); 34 | 35 | try { 36 | const sig = await connection.sendTransaction(versionedTx, { 37 | skipPreflight: false, 38 | }); 39 | console.log("sig:", `https://solscan.io/tx/${sig}`); 40 | 41 | let txResult = await getTxDetails(connection, sig, commitment, finality); 42 | if (!txResult) { 43 | return { 44 | success: false, 45 | error: "Transaction failed", 46 | }; 47 | } 48 | return { 49 | success: true, 50 | signature: sig, 51 | results: txResult, 52 | }; 53 | } catch (e) { 54 | if (e instanceof SendTransactionError) { 55 | let ste = e as SendTransactionError; 56 | console.log("SendTransactionError" + ste.logs); 57 | } else { 58 | console.error(e); 59 | } 60 | return { 61 | error: e, 62 | success: false, 63 | }; 64 | } 65 | } 66 | 67 | export const buildVersionedTx = async ( 68 | connection: Connection, 69 | payer: PublicKey, 70 | tx: Transaction, 71 | commitment: Commitment = DEFAULT_COMMITMENT 72 | ): Promise => { 73 | const blockHash = (await connection.getLatestBlockhash(commitment)).blockhash; 74 | 75 | let messageV0 = new TransactionMessage({ 76 | payerKey: payer, 77 | recentBlockhash: blockHash, 78 | instructions: tx.instructions, 79 | }).compileToV0Message(); 80 | 81 | return new VersionedTransaction(messageV0); 82 | }; 83 | 84 | export const getTxDetails = async ( 85 | connection: Connection, 86 | sig: string, 87 | commitment: Commitment = DEFAULT_COMMITMENT, 88 | finality: Finality = DEFAULT_FINALITY 89 | ): Promise => { 90 | const latestBlockHash = await connection.getLatestBlockhash(); 91 | await connection.confirmTransaction( 92 | { 93 | blockhash: latestBlockHash.blockhash, 94 | lastValidBlockHeight: latestBlockHash.lastValidBlockHeight, 95 | signature: sig, 96 | }, 97 | commitment 98 | ); 99 | 100 | return connection.getTransaction(sig, { 101 | maxSupportedTransactionVersion: 0, 102 | commitment: finality, 103 | }); 104 | }; 105 | 106 | export async function buildSignedTx( 107 | priorityFees: PriorityFee | undefined, 108 | tx: Transaction, 109 | connection: Connection, 110 | payer: PublicKey, 111 | commitment: Commitment, 112 | signers: Keypair[] 113 | ) { 114 | let newTx = new Transaction(); 115 | 116 | if (priorityFees) { 117 | const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 118 | units: priorityFees.unitLimit, 119 | }); 120 | 121 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 122 | microLamports: priorityFees.unitPrice, 123 | }); 124 | newTx.add(modifyComputeUnits); 125 | newTx.add(addPriorityFee); 126 | } 127 | 128 | newTx.add(tx); 129 | 130 | let versionedTx = await buildVersionedTx( 131 | connection, 132 | payer, 133 | newTx, 134 | commitment 135 | ); 136 | versionedTx.sign(signers); 137 | return versionedTx; 138 | } 139 | -------------------------------------------------------------------------------- /src/AgentRegistry.ts: -------------------------------------------------------------------------------- 1 | import { HostKey, Region } from "./pumpFun.types.js"; 2 | import http from "http"; 3 | import https from "https"; 4 | import { 5 | ASTRA_ENDPOINT_BY_REGION, 6 | NEXTBLOCK_ENDPOINT_BY_REGION, 7 | NODE1_ENDPOINT_BY_REGION, 8 | SLOT_ENDPOINT_BY_REGION, 9 | } from "./pumpFun.consts.js"; 10 | 11 | class AgentRegistry { 12 | private static agents: Partial> = {}; 13 | private static config: Map = 14 | new Map(); 15 | /** Lazy-create & memoize */ 16 | static get(key: HostKey): http.Agent { 17 | if (!this.agents[key]) { 18 | const config = this.config[key]; 19 | const isHttps = config.port === 443; 20 | 21 | this.agents[key] = isHttps 22 | ? new https.Agent({ 23 | keepAlive: true, 24 | keepAliveMsecs: 60_000, 25 | maxSockets: 6, // tune per host 26 | maxFreeSockets: 6, 27 | }) 28 | : new http.Agent({ 29 | keepAlive: true, 30 | keepAliveMsecs: 60_000, 31 | maxSockets: 6, // tune per host 32 | maxFreeSockets: 6, 33 | }); 34 | // wireAgentDebug(this.agents[key]!, key); 35 | } 36 | return this.agents[key]!; 37 | } 38 | 39 | static registerInConfig(key: HostKey, region: Region) { 40 | if (this.config.has(key)) { 41 | throw new Error(`Host key ${key} is already registered.`); 42 | } 43 | switch (key) { 44 | case "slot": 45 | this.config.set(key, { 46 | host: SLOT_ENDPOINT_BY_REGION[region], 47 | port: 80, 48 | }); 49 | break; 50 | case "node": 51 | this.config.set(key, { 52 | host: NODE1_ENDPOINT_BY_REGION[region]!, 53 | port: 80, 54 | }); 55 | break; 56 | case "nextBlock": 57 | this.config.set(key, { 58 | host: NEXTBLOCK_ENDPOINT_BY_REGION[region]!, 59 | port: 80, 60 | }); 61 | break; 62 | case "astra": 63 | this.config.set(key, { 64 | host: ASTRA_ENDPOINT_BY_REGION[region]!, 65 | port: 80, 66 | }); 67 | break; 68 | default: 69 | throw new Error(`Unknown host key: ${key}`); 70 | } 71 | } 72 | 73 | static deleteFromConfig(key: HostKey) { 74 | if (!this.config.has(key)) { 75 | throw new Error(`Host key ${key} is not registered.`); 76 | } 77 | this.config.delete(key); 78 | delete this.agents[key]; 79 | } 80 | 81 | static target(key: HostKey) { 82 | return this.config[key]; 83 | } 84 | 85 | static callUpstream( 86 | key: HostKey, 87 | path: string, 88 | options: { 89 | method?: string; 90 | headers?: Record; 91 | body?: string; 92 | timeout?: number; 93 | } = {} 94 | ): Promise { 95 | return new Promise((resolve, reject) => { 96 | const { host, port } = this.target(key); 97 | const agent = this.get(key); 98 | const isHttps = port === 443; 99 | const requestOptions: http.RequestOptions = { 100 | hostname: host, 101 | path: path, 102 | port: port, 103 | method: options.method || "GET", 104 | headers: options.headers || {}, 105 | agent: agent, 106 | timeout: options.timeout || 5000, // 5 second timeout 107 | }; 108 | const requestModule = isHttps ? https : http; 109 | const req = requestModule.request(requestOptions, (res) => { 110 | let data = ""; 111 | res.on("data", (chunk) => { 112 | data += chunk; 113 | }); 114 | 115 | res.on("end", () => { 116 | if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { 117 | resolve(data); 118 | } else { 119 | reject(new Error(`HTTP ${res.statusCode}: ${data}`)); 120 | } 121 | }); 122 | }); 123 | req.on("socket", (sock) => { 124 | sock.setNoDelay(true); 125 | }); 126 | 127 | req.on("error", (err) => { 128 | reject(err); 129 | }); 130 | 131 | req.on("timeout", () => { 132 | req.destroy(); 133 | reject(new Error("Request timeout")); 134 | }); 135 | 136 | // Write body if provided 137 | if (options.body) { 138 | req.write(options.body); 139 | } 140 | 141 | req.end(); 142 | }); 143 | } 144 | } 145 | 146 | export default AgentRegistry; 147 | -------------------------------------------------------------------------------- /src/pumpEvents/pumpEvents.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CollectCreatorFeeEvent, 3 | CompleteEvent, 4 | CompletePumpAmmMigrationEvent, 5 | CreateEvent, 6 | ExtendAccountEvent, 7 | SetCreatorEvent, 8 | SetMetaplexCreatorEvent, 9 | SetParamsEvent, 10 | TradeEvent, 11 | UpdateGlobalAuthorityEvent, 12 | } from "./pumpEvents.types.js"; 13 | import { toPubKey, toBigInt } from "./utils.js"; 14 | 15 | export function toCollectCreatorFeeEvent(e: any): CollectCreatorFeeEvent { 16 | return { 17 | timestamp: Number(e.timestamp), 18 | creator: toPubKey(e.creator), 19 | creatorFee: toBigInt(e.creatorFee), 20 | }; 21 | } 22 | 23 | export function toCompleteEvent(e: any): CompleteEvent { 24 | return { 25 | user: toPubKey(e.user), 26 | mint: toPubKey(e.mint), 27 | bondingCurve: toPubKey(e.bondingCurve), 28 | timestamp: Number(e.timestamp), 29 | }; 30 | } 31 | 32 | export function toCompletePumpAmmMigrationEvent( 33 | e: any 34 | ): CompletePumpAmmMigrationEvent { 35 | return { 36 | user: toPubKey(e.user), 37 | mint: toPubKey(e.mint), 38 | mintAmount: toBigInt(e.mintAmount), 39 | solAmount: toBigInt(e.solAmount), 40 | poolMigrationFee: toBigInt(e.poolMigrationFee), 41 | bondingCurve: toPubKey(e.bondingCurve), 42 | timestamp: Number(e.timestamp), 43 | pool: toPubKey(e.pool), 44 | }; 45 | } 46 | 47 | export function toCreateEvent(e: any): CreateEvent { 48 | return { 49 | name: e.name, 50 | symbol: e.symbol, 51 | uri: e.uri, 52 | mint: toPubKey(e.mint), 53 | bondingCurve: toPubKey(e.bondingCurve), 54 | user: toPubKey(e.user), 55 | creator: toPubKey(e.creator), 56 | timestamp: Number(e.timestamp), 57 | virtualTokenReserves: toBigInt(e.virtualTokenReserves), 58 | virtualSolReserves: toBigInt(e.virtualSolReserves), 59 | realTokenReserves: toBigInt(e.realTokenReserves), 60 | tokenTotalSupply: toBigInt(e.tokenTotalSupply), 61 | }; 62 | } 63 | 64 | export function toExtendAccountEvent(e: any): ExtendAccountEvent { 65 | return { 66 | account: toPubKey(e.account), 67 | user: toPubKey(e.user), 68 | currentSize: toBigInt(e.currentSize), 69 | newSize: toBigInt(e.newSize), 70 | timestamp: Number(e.timestamp), 71 | }; 72 | } 73 | 74 | export function toSetCreatorEvent(e: any): SetCreatorEvent { 75 | return { 76 | timestamp: Number(e.timestamp), 77 | mint: toPubKey(e.mint), 78 | bondingCurve: toPubKey(e.bondingCurve), 79 | creator: toPubKey(e.creator), 80 | }; 81 | } 82 | 83 | export function toSetMetaplexCreatorEvent(e: any): SetMetaplexCreatorEvent { 84 | return { 85 | timestamp: Number(e.timestamp), 86 | mint: toPubKey(e.mint), 87 | bondingCurve: toPubKey(e.bondingCurve), 88 | metadata: toPubKey(e.metadata), 89 | creator: toPubKey(e.creator), 90 | }; 91 | } 92 | 93 | export function toSetParamsEvent(e: any): SetParamsEvent { 94 | return { 95 | initialVirtualTokenReserves: toBigInt(e.initialVirtualTokenReserves), 96 | initialVirtualSolReserves: toBigInt(e.initialVirtualSolReserves), 97 | initialRealTokenReserves: toBigInt(e.initialRealTokenReserves), 98 | finalRealSolReserves: toBigInt(e.finalRealSolReserves), 99 | tokenTotalSupply: toBigInt(e.tokenTotalSupply), 100 | feeBasisPoints: toBigInt(e.feeBasisPoints), 101 | withdrawAuthority: toPubKey(e.withdrawAuthority), 102 | enableMigrate: Boolean(e.enableMigrate), 103 | poolMigrationFee: toBigInt(e.poolMigrationFee), 104 | creatorFeeBasisPoints: toBigInt(e.creatorFeeBasisPoints), 105 | feeRecipients: e.feeRecipients.map(toPubKey), 106 | timestamp: Number(e.timestamp), 107 | setCreatorAuthority: toPubKey(e.setCreatorAuthority), 108 | }; 109 | } 110 | 111 | export function toTradeEvent(e: any): TradeEvent { 112 | return { 113 | mint: toPubKey(e.mint), 114 | solAmount: toBigInt(e.solAmount), 115 | tokenAmount: toBigInt(e.tokenAmount), 116 | isBuy: Boolean(e.isBuy), 117 | user: toPubKey(e.user), 118 | timestamp: Number(e.timestamp), 119 | virtualSolReserves: toBigInt(e.virtualSolReserves), 120 | virtualTokenReserves: toBigInt(e.virtualTokenReserves), 121 | realSolReserves: toBigInt(e.realSolReserves), 122 | realTokenReserves: toBigInt(e.realTokenReserves), 123 | feeRecipient: toPubKey(e.feeRecipient), 124 | feeBasisPoints: toBigInt(e.feeBasisPoints), 125 | fee: toBigInt(e.fee), 126 | creator: toPubKey(e.creator), 127 | creatorFeeBasisPoints: toBigInt(e.creatorFeeBasisPoints), 128 | creatorFee: toBigInt(e.creatorFee), 129 | }; 130 | } 131 | 132 | export function toUpdateGlobalAuthorityEvent( 133 | e: any 134 | ): UpdateGlobalAuthorityEvent { 135 | return { 136 | global: toPubKey(e.global), 137 | authority: toPubKey(e.authority), 138 | newAuthority: toPubKey(e.newAuthority), 139 | timestamp: Number(e.timestamp), 140 | }; 141 | } 142 | -------------------------------------------------------------------------------- /src/modules/TokenModule.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createAssociatedTokenAccountInstruction, 3 | getAccount, 4 | getAssociatedTokenAddress, 5 | } from "@solana/spl-token"; 6 | import { PublicKey, Transaction, Commitment } from "@solana/web3.js"; 7 | import { DEFAULT_COMMITMENT } from "../pumpFun.consts.js"; 8 | import { CreateTokenMetadata } from "../pumpFun.types.js"; 9 | import { PumpFunSDK } from "../PumpFunSDK.js"; 10 | import { BondingCurveAccount } from "../BondingCurveAccount.js"; 11 | import { GlobalAccount } from "../GlobalAccount.js"; 12 | import { FeeConfig } from "../FeeConfig.js"; 13 | 14 | export class TokenModule { 15 | constructor(private sdk: PumpFunSDK) {} 16 | 17 | async createTokenMetadata(create: CreateTokenMetadata) { 18 | // Validate file 19 | if (!(create.file instanceof Blob)) { 20 | throw new Error("File must be a Blob or File object"); 21 | } 22 | 23 | let formData = new FormData(); 24 | formData.append("file", create.file, "image.png"); // Add filename 25 | formData.append("name", create.name); 26 | formData.append("symbol", create.symbol); 27 | formData.append("description", create.description); 28 | formData.append("twitter", create.twitter || ""); 29 | formData.append("telegram", create.telegram || ""); 30 | formData.append("website", create.website || ""); 31 | formData.append("showName", "true"); 32 | 33 | try { 34 | const request = await fetch("https://pump.fun/api/ipfs", { 35 | method: "POST", 36 | headers: { 37 | Accept: "application/json", 38 | }, 39 | body: formData, 40 | credentials: "same-origin", 41 | }); 42 | 43 | if (request.status === 500) { 44 | // Try to get more error details 45 | const errorText = await request.text(); 46 | throw new Error( 47 | `Server error (500): ${errorText || "No error details available"}` 48 | ); 49 | } 50 | 51 | if (!request.ok) { 52 | throw new Error(`HTTP error! status: ${request.status}`); 53 | } 54 | 55 | const responseText = await request.text(); 56 | if (!responseText) { 57 | throw new Error("Empty response received from server"); 58 | } 59 | 60 | try { 61 | return JSON.parse(responseText); 62 | } catch (e) { 63 | throw new Error(`Invalid JSON response: ${responseText}`); 64 | } 65 | } catch (error) { 66 | console.error("Error in createTokenMetadata:", error); 67 | throw error; 68 | } 69 | } 70 | 71 | async createAssociatedTokenAccountIfNeeded( 72 | payer: PublicKey, 73 | owner: PublicKey, 74 | mint: PublicKey, 75 | transaction: Transaction, 76 | commitment: Commitment = DEFAULT_COMMITMENT 77 | ): Promise { 78 | const associatedTokenAccount = await getAssociatedTokenAddress( 79 | mint, 80 | owner, 81 | false 82 | ); 83 | 84 | try { 85 | await getAccount(this.sdk.connection, associatedTokenAccount, commitment); 86 | } catch (e) { 87 | transaction.add( 88 | createAssociatedTokenAccountInstruction( 89 | payer, 90 | associatedTokenAccount, 91 | owner, 92 | mint 93 | ) 94 | ); 95 | } 96 | 97 | return associatedTokenAccount; 98 | } 99 | 100 | async getBondingCurveAccount( 101 | mint: PublicKey, 102 | commitment: Commitment = DEFAULT_COMMITMENT 103 | ) { 104 | const tokenAccount = await this.sdk.connection.getAccountInfo( 105 | this.sdk.pda.getBondingCurvePDA(mint), 106 | commitment 107 | ); 108 | if (!tokenAccount) { 109 | return null; 110 | } 111 | return BondingCurveAccount.fromBuffer(tokenAccount!.data); 112 | } 113 | 114 | async getGlobalAccount(commitment: Commitment = DEFAULT_COMMITMENT) { 115 | const globalAccountPDA = this.sdk.pda.getGlobalAccountPda(); 116 | 117 | const tokenAccount = await this.sdk.connection.getAccountInfo( 118 | globalAccountPDA, 119 | commitment 120 | ); 121 | 122 | return GlobalAccount.fromBuffer(tokenAccount!.data); 123 | } 124 | 125 | async getFeeConfig(commitment: Commitment = DEFAULT_COMMITMENT) { 126 | const feePda = this.sdk.pda.getPumpFeeConfigPda(); 127 | // @ts-ignore: feeConfig account is missing in generated Anchor types 128 | const anchorFee = await this.sdk.program.account.feeConfig.fetch(feePda); 129 | return FeeConfig.convert(anchorFee); 130 | } 131 | 132 | async getBondingCurveCreator( 133 | bondingCurvePDA: PublicKey, 134 | commitment: Commitment = DEFAULT_COMMITMENT 135 | ): Promise { 136 | const bondingAccountInfo = await this.sdk.connection.getAccountInfo( 137 | bondingCurvePDA, 138 | commitment 139 | ); 140 | if (!bondingAccountInfo) { 141 | throw new Error("Bonding curve account not found"); 142 | } 143 | 144 | // Creator is at offset 49 (after 8 bytes discriminator, 5 u64 fields, and 1 byte boolean) 145 | const creatorBytes = bondingAccountInfo.data.subarray(49, 49 + 32); 146 | return new PublicKey(creatorBytes); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/FeeConfig.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { BondingCurveAccount } from "./BondingCurveAccount.js"; 3 | import { Layout, struct, u64, bool, publicKey, array } from "@coral-xyz/borsh"; 4 | import { GlobalAccount } from "./GlobalAccount.js"; 5 | import { BN } from "@coral-xyz/anchor"; 6 | 7 | export interface CalculatedFeesBps { 8 | protocolFeeBps: bigint; 9 | creatorFeeBps: bigint; 10 | } 11 | 12 | export interface CalculatedFees { 13 | protocolFee: bigint; 14 | creatorFee: bigint; 15 | } 16 | 17 | export interface FeeTier { 18 | marketCapLamportsThreshold: bigint; 19 | fees: Fees; 20 | } 21 | 22 | export interface Fees { 23 | lpFeeBps: bigint; 24 | protocolFeeBps: bigint; 25 | creatorFeeBps: bigint; 26 | } 27 | 28 | export interface FeeConfigAnchor { 29 | admin: PublicKey; 30 | flatFees: FeesAnchor; 31 | feeTiers: FeeTierAnchor[]; 32 | } 33 | 34 | export interface FeeTierAnchor { 35 | marketCapLamportsThreshold: BN; 36 | fees: FeesAnchor; 37 | } 38 | 39 | export interface FeesAnchor { 40 | lpFeeBps: BN; 41 | protocolFeeBps: BN; 42 | creatorFeeBps: BN; 43 | } 44 | 45 | export class FeeConfig { 46 | public discriminator: bigint; 47 | public admin: PublicKey; 48 | public flatFees: Fees; 49 | public feeTiers: FeeTier[]; 50 | 51 | constructor( 52 | discriminator: bigint, 53 | admin: PublicKey, 54 | flatFees: Fees, 55 | feeTiers: FeeTier[] 56 | ) { 57 | this.discriminator = discriminator; 58 | this.admin = admin; 59 | this.flatFees = flatFees; 60 | this.feeTiers = feeTiers; 61 | } 62 | 63 | getFee({ 64 | global, 65 | bondingCurve, 66 | amount, 67 | isNewBondingCurve, 68 | }: { 69 | global: GlobalAccount; 70 | bondingCurve: BondingCurveAccount; 71 | amount: bigint; 72 | isNewBondingCurve: boolean; 73 | }) { 74 | const { virtualSolReserves, virtualTokenReserves } = bondingCurve; 75 | const { protocolFeeBps, creatorFeeBps } = this.computeFeesBps({ 76 | global, 77 | virtualSolReserves, 78 | virtualTokenReserves, 79 | }); 80 | 81 | return ( 82 | this.fee(amount, protocolFeeBps) + 83 | (isNewBondingCurve || !PublicKey.default.equals(bondingCurve.creator) 84 | ? this.fee(amount, creatorFeeBps) 85 | : 0n) 86 | ); 87 | } 88 | 89 | bondingCurveMarketCap({ 90 | mintSupply, 91 | virtualSolReserves, 92 | virtualTokenReserves, 93 | }: { 94 | mintSupply: bigint; 95 | virtualSolReserves: bigint; 96 | virtualTokenReserves: bigint; 97 | }): bigint { 98 | if (virtualTokenReserves === 0n) { 99 | throw new Error( 100 | "Division by zero: virtual token reserves cannot be zero" 101 | ); 102 | } 103 | return (virtualSolReserves * mintSupply) / virtualTokenReserves; 104 | } 105 | 106 | computeFeesBps({ 107 | global, 108 | virtualSolReserves, 109 | virtualTokenReserves, 110 | }: { 111 | global: GlobalAccount; 112 | virtualSolReserves: bigint; 113 | virtualTokenReserves: bigint; 114 | }): CalculatedFeesBps { 115 | const marketCap = this.bondingCurveMarketCap({ 116 | mintSupply: global.tokenTotalSupply, 117 | virtualSolReserves, 118 | virtualTokenReserves, 119 | }); 120 | 121 | return this.calculateFeeTier({ 122 | feeTiers: this.feeTiers, 123 | marketCap, 124 | }); 125 | } 126 | 127 | calculateFeeTier({ 128 | feeTiers, 129 | marketCap, 130 | }: { 131 | feeTiers: FeeTier[]; 132 | marketCap: bigint; 133 | }): Fees { 134 | const firstTier = feeTiers[0]; 135 | 136 | if (marketCap < firstTier.marketCapLamportsThreshold) { 137 | return firstTier.fees; 138 | } 139 | 140 | for (const tier of feeTiers.slice().reverse()) { 141 | if (marketCap >= tier.marketCapLamportsThreshold) { 142 | return tier.fees; 143 | } 144 | } 145 | 146 | return firstTier.fees; 147 | } 148 | 149 | fee(amount: bigint, feeBasisPoints: bigint): bigint { 150 | return this.ceilDiv(amount * feeBasisPoints, 10000n); 151 | } 152 | 153 | ceilDiv(a: bigint, b: bigint): bigint { 154 | return (a + (b - 1n)) / b; 155 | } 156 | 157 | public static convert(base: FeeConfigAnchor): FeeConfig { 158 | const flatFees: Fees = { 159 | lpFeeBps: BigInt(base.flatFees.lpFeeBps.toString()), 160 | protocolFeeBps: BigInt(base.flatFees.protocolFeeBps.toString()), 161 | creatorFeeBps: BigInt(base.flatFees.creatorFeeBps.toString()), 162 | }; 163 | 164 | const feeTiers: FeeTier[] = base.feeTiers.map((tier) => ({ 165 | marketCapLamportsThreshold: BigInt( 166 | tier.marketCapLamportsThreshold.toString() 167 | ), 168 | fees: { 169 | lpFeeBps: BigInt(tier.fees.lpFeeBps.toString()), 170 | protocolFeeBps: BigInt(tier.fees.protocolFeeBps.toString()), 171 | creatorFeeBps: BigInt(tier.fees.creatorFeeBps.toString()), 172 | }, 173 | })); 174 | 175 | return new FeeConfig( 176 | 0n, // discriminator not available in FeeConfigAnchor 177 | base.admin, 178 | flatFees, 179 | feeTiers 180 | ); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/BondingCurveAccount.ts: -------------------------------------------------------------------------------- 1 | import { struct, bool, u64, Layout, publicKey } from "@coral-xyz/borsh"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | import { FeeConfig } from "./FeeConfig.js"; 4 | import { GlobalAccount } from "./GlobalAccount.js"; 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 | public creator: PublicKey; 15 | 16 | constructor( 17 | discriminator: bigint, 18 | virtualTokenReserves: bigint, 19 | virtualSolReserves: bigint, 20 | realTokenReserves: bigint, 21 | realSolReserves: bigint, 22 | tokenTotalSupply: bigint, 23 | complete: boolean, 24 | creator: PublicKey 25 | ) { 26 | this.discriminator = discriminator; 27 | this.virtualTokenReserves = virtualTokenReserves; 28 | this.virtualSolReserves = virtualSolReserves; 29 | this.realTokenReserves = realTokenReserves; 30 | this.realSolReserves = realSolReserves; 31 | this.tokenTotalSupply = tokenTotalSupply; 32 | this.complete = complete; 33 | this.creator = creator; 34 | } 35 | 36 | getBuyPrice( 37 | globalAccount: GlobalAccount, 38 | feeConfig: FeeConfig, 39 | amount: bigint 40 | ): bigint { 41 | if (this.complete) { 42 | throw new Error("Curve is complete"); 43 | } 44 | 45 | if (amount <= 0n) { 46 | return 0n; 47 | } 48 | if (this.virtualTokenReserves === 0n) { 49 | return 0n; 50 | } 51 | const { protocolFeeBps, creatorFeeBps } = feeConfig.computeFeesBps({ 52 | global: globalAccount, 53 | virtualSolReserves: this.virtualSolReserves, 54 | virtualTokenReserves: this.virtualTokenReserves, 55 | }); 56 | const totalFeeBasisPoints = 57 | protocolFeeBps + 58 | (!PublicKey.default.equals(this.creator) ? creatorFeeBps : 0n); 59 | 60 | const inputAmount = (amount * 10_000n) / (totalFeeBasisPoints + 10_000n); 61 | 62 | const tokensReceived = this.getBuyTokenAmountFromSolAmountQuote({ 63 | inputAmount, 64 | virtualTokenReserves: this.virtualTokenReserves, 65 | virtualSolReserves: this.virtualSolReserves, 66 | }); 67 | 68 | return tokensReceived < this.realTokenReserves 69 | ? tokensReceived 70 | : this.realTokenReserves; 71 | } 72 | 73 | getBuyTokenAmountFromSolAmountQuote({ 74 | inputAmount, 75 | virtualTokenReserves, 76 | virtualSolReserves, 77 | }: { 78 | inputAmount: bigint; 79 | virtualTokenReserves: bigint; 80 | virtualSolReserves: bigint; 81 | }): bigint { 82 | return ( 83 | (inputAmount * virtualTokenReserves) / (virtualSolReserves + inputAmount) 84 | ); 85 | } 86 | 87 | getSellSolAmountFromTokenAmountQuote({ 88 | inputAmount, 89 | virtualTokenReserves, 90 | virtualSolReserves, 91 | }: { 92 | inputAmount: bigint; 93 | virtualTokenReserves: bigint; 94 | virtualSolReserves: bigint; 95 | }): bigint { 96 | return ( 97 | (inputAmount * virtualSolReserves) / (virtualTokenReserves + inputAmount) 98 | ); 99 | } 100 | 101 | getSellPrice( 102 | globalAccount: GlobalAccount, 103 | feeConfig: FeeConfig, 104 | amount: bigint 105 | ): bigint { 106 | if (this.complete) { 107 | throw new Error("Curve is complete"); 108 | } 109 | 110 | if (amount <= 0n) { 111 | return 0n; 112 | } 113 | if (this.virtualTokenReserves === 0n) { 114 | return 0n; 115 | } 116 | const solCost = this.getSellSolAmountFromTokenAmountQuote({ 117 | inputAmount: amount, 118 | virtualTokenReserves: this.virtualTokenReserves, 119 | virtualSolReserves: this.virtualSolReserves, 120 | }); 121 | 122 | const fee = feeConfig.getFee({ 123 | global: globalAccount, 124 | bondingCurve: this, 125 | amount: solCost, 126 | isNewBondingCurve: false, 127 | }); 128 | return solCost - fee; 129 | } 130 | 131 | getMarketCapSOL(): bigint { 132 | if (this.virtualTokenReserves === 0n) { 133 | return 0n; 134 | } 135 | 136 | return ( 137 | (this.tokenTotalSupply * this.virtualSolReserves) / 138 | this.virtualTokenReserves 139 | ); 140 | } 141 | 142 | getFinalMarketCapSOL(mintSupply: bigint): bigint { 143 | return (this.virtualSolReserves * mintSupply) / this.virtualTokenReserves; 144 | } 145 | 146 | public static fromBuffer(buffer: Buffer): BondingCurveAccount { 147 | const structure: Layout = struct([ 148 | u64("discriminator"), 149 | u64("virtualTokenReserves"), 150 | u64("virtualSolReserves"), 151 | u64("realTokenReserves"), 152 | u64("realSolReserves"), 153 | u64("tokenTotalSupply"), 154 | bool("complete"), 155 | publicKey("creator"), 156 | ]); 157 | 158 | let value = structure.decode(buffer); 159 | return new BondingCurveAccount( 160 | BigInt(value.discriminator), 161 | BigInt(value.virtualTokenReserves), 162 | BigInt(value.virtualSolReserves), 163 | BigInt(value.realTokenReserves), 164 | BigInt(value.realSolReserves), 165 | BigInt(value.tokenTotalSupply), 166 | value.complete, 167 | value.creator 168 | ); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/modules/JitoModule.ts: -------------------------------------------------------------------------------- 1 | import { 2 | searcherClient, 3 | SearcherClient, 4 | } from "jito-ts/dist/sdk/block-engine/searcher.js"; 5 | import { PumpFunSDK } from "../PumpFunSDK.js"; 6 | import { 7 | Commitment, 8 | Finality, 9 | Keypair, 10 | PublicKey, 11 | SystemProgram, 12 | Transaction, 13 | VersionedTransaction, 14 | } from "@solana/web3.js"; 15 | import { DEFAULT_COMMITMENT, DEFAULT_FINALITY } from "../pumpFun.consts.js"; 16 | import { 17 | JitoResult, 18 | PriorityFee, 19 | TransactionResult, 20 | } from "../pumpFun.types.js"; 21 | import { 22 | calculateWithSlippageBuy, 23 | calculateWithSlippageSell, 24 | } from "../slippage.js"; 25 | import { buildSignedTx, sendTx } from "../tx.js"; 26 | import { getRandomJitoTipAccount } from "./utils.js"; 27 | import { Bundle } from "jito-ts/dist/sdk/block-engine/types.js"; 28 | 29 | export class JitoModule { 30 | private client: SearcherClient; 31 | constructor( 32 | private sdk: PumpFunSDK, 33 | endpoint?: string, 34 | authKeypair?: Keypair 35 | ) { 36 | if (!endpoint) { 37 | throw new Error("Jito endpoint is required"); 38 | } 39 | this.client = searcherClient(endpoint, authKeypair); 40 | } 41 | 42 | async buyJito( 43 | buyer: Keypair, 44 | mint: PublicKey, 45 | buyAmountSol: bigint, 46 | slippageBasisPoints: bigint = 500n, 47 | jitoTip: number = 500000, 48 | priorityFees?: PriorityFee, 49 | commitment: Commitment = DEFAULT_COMMITMENT 50 | ): Promise { 51 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 52 | mint, 53 | commitment 54 | ); 55 | if (!bondingAccount) { 56 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 57 | } 58 | 59 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 60 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 61 | const buyAmount = bondingAccount.getBuyPrice( 62 | globalAccount, 63 | feeConfig, 64 | buyAmountSol 65 | ); 66 | const buyAmountWithSlippage = calculateWithSlippageBuy( 67 | buyAmountSol, 68 | slippageBasisPoints 69 | ); 70 | 71 | const transaction = new Transaction(); 72 | await this.sdk.trade.buildBuyIx( 73 | buyer.publicKey, 74 | mint, 75 | buyAmount, 76 | buyAmountWithSlippage, 77 | transaction, 78 | commitment, 79 | false 80 | ); 81 | this.addJitoTip(buyer, transaction, jitoTip); 82 | const signedTx = await buildSignedTx( 83 | priorityFees, 84 | transaction, 85 | this.sdk.connection, 86 | buyer.publicKey, 87 | commitment, 88 | [buyer] 89 | ); 90 | return await this.sendJitoTx(signedTx); 91 | } 92 | 93 | async sellJito( 94 | seller: Keypair, 95 | mint: PublicKey, 96 | sellTokenAmount: bigint, 97 | slippageBasisPoints: bigint = 500n, 98 | jitoTip: number = 500000, 99 | priorityFees?: PriorityFee, 100 | commitment: Commitment = DEFAULT_COMMITMENT 101 | ): Promise { 102 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 103 | mint, 104 | commitment 105 | ); 106 | if (!bondingAccount) 107 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 108 | 109 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 110 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 111 | const minSolOutput = bondingAccount.getSellPrice( 112 | globalAccount, 113 | feeConfig, 114 | sellTokenAmount 115 | ); 116 | let sellAmountWithSlippage = calculateWithSlippageSell( 117 | minSolOutput, 118 | slippageBasisPoints 119 | ); 120 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 121 | 122 | const transaction = new Transaction(); 123 | await this.sdk.trade.buildSellIx( 124 | seller.publicKey, 125 | mint, 126 | sellTokenAmount, 127 | sellAmountWithSlippage, 128 | transaction, 129 | commitment 130 | ); 131 | 132 | this.addJitoTip(seller, transaction, jitoTip); 133 | const signedTx = await buildSignedTx( 134 | priorityFees, 135 | transaction, 136 | this.sdk.connection, 137 | seller.publicKey, 138 | commitment, 139 | [seller] 140 | ); 141 | return await this.sendJitoTx(signedTx); 142 | } 143 | 144 | private addJitoTip( 145 | buyer: Keypair, 146 | transaction: Transaction, 147 | jitoTip: number = 500000 148 | ): Transaction { 149 | if (jitoTip <= 0) { 150 | return transaction; 151 | } 152 | const jitoTipAccount = getRandomJitoTipAccount(); 153 | const jitoTipInstruction = SystemProgram.transfer({ 154 | fromPubkey: buyer.publicKey, 155 | toPubkey: jitoTipAccount, 156 | lamports: jitoTip, 157 | }); 158 | transaction.add(jitoTipInstruction); 159 | return transaction; 160 | } 161 | 162 | private async sendJitoTx(tx: VersionedTransaction): Promise { 163 | const b = new Bundle([tx], 1); 164 | 165 | const res = await this.client.sendBundle(b); 166 | if (res.ok) { 167 | return { 168 | success: true, 169 | bundleId: res.value, 170 | }; 171 | } 172 | return { 173 | success: false, 174 | error: res.error, 175 | }; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/modules/NodeOneModule.ts: -------------------------------------------------------------------------------- 1 | import { PumpFunSDK } from "../PumpFunSDK.js"; 2 | import { 3 | Commitment, 4 | Keypair, 5 | PublicKey, 6 | SystemProgram, 7 | Transaction, 8 | VersionedTransaction, 9 | } from "@solana/web3.js"; 10 | import { DEFAULT_COMMITMENT, getHealthBody } from "../pumpFun.consts.js"; 11 | import { PriorityFee, Region } from "../pumpFun.types.js"; 12 | import { 13 | calculateWithSlippageBuy, 14 | calculateWithSlippageSell, 15 | } from "../slippage.js"; 16 | import { buildSignedTx } from "../tx.js"; 17 | import AgentRegistry from "../AgentRegistry.js"; 18 | 19 | export class NodeOneModule { 20 | private key: string; 21 | constructor(private sdk: PumpFunSDK, region: Region, key: string) { 22 | AgentRegistry.registerInConfig("node", region); 23 | this.key = key; 24 | } 25 | 26 | NODE_ONE_ACCOUNTS = [ 27 | new PublicKey("node1PqAa3BWWzUnTHVbw8NJHC874zn9ngAkXjgWEej"), 28 | new PublicKey("node1UzzTxAAeBTpfZkQPJXBAqixsbdth11ba1NXLBG"), 29 | new PublicKey("node1Qm1bV4fwYnCurP8otJ9s5yrkPq7SPZ5uhj3Tsv"), 30 | new PublicKey("node1PUber6SFmSQgvf2ECmXsHP5o3boRSGhvJyPMX1"), 31 | new PublicKey("node1AyMbeqiVN6eoQzEAwCA6Pk826hrdqdAHR7cdJ3"), 32 | new PublicKey("node1YtWCoTwwVYTFLfS19zquRQzYX332hs1HEuRBjC"), 33 | new PublicKey("node1FdMPnJBN7QTuhzNw3VS823nxFuDTizrrbcEqzp"), 34 | ]; 35 | 36 | private getRandomAccount() { 37 | const randomIndex = Math.floor( 38 | Math.random() * this.NODE_ONE_ACCOUNTS.length 39 | ); 40 | return this.NODE_ONE_ACCOUNTS[randomIndex]; 41 | } 42 | 43 | async buy( 44 | buyer: Keypair, 45 | mint: PublicKey, 46 | buyAmountSol: bigint, 47 | slippageBasisPoints: bigint = 500n, 48 | tip: number = 500000, 49 | priorityFees?: PriorityFee, 50 | commitment: Commitment = DEFAULT_COMMITMENT 51 | ): Promise { 52 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 53 | mint, 54 | commitment 55 | ); 56 | if (!bondingAccount) { 57 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 58 | } 59 | 60 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 61 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 62 | const buyAmount = bondingAccount.getBuyPrice( 63 | globalAccount, 64 | feeConfig, 65 | buyAmountSol 66 | ); 67 | const buyAmountWithSlippage = calculateWithSlippageBuy( 68 | buyAmountSol, 69 | slippageBasisPoints 70 | ); 71 | 72 | const transaction = new Transaction(); 73 | await this.sdk.trade.buildBuyIx( 74 | buyer.publicKey, 75 | mint, 76 | buyAmount, 77 | buyAmountWithSlippage, 78 | transaction, 79 | commitment, 80 | false 81 | ); 82 | this.addTip(buyer, transaction, tip); 83 | const signedTx = await buildSignedTx( 84 | priorityFees, 85 | transaction, 86 | this.sdk.connection, 87 | buyer.publicKey, 88 | commitment, 89 | [buyer] 90 | ); 91 | return await this.sendTransaction(signedTx); 92 | } 93 | 94 | async sell( 95 | seller: Keypair, 96 | mint: PublicKey, 97 | sellTokenAmount: bigint, 98 | slippageBasisPoints: bigint = 500n, 99 | tip: number = 500000, 100 | priorityFees?: PriorityFee, 101 | commitment: Commitment = DEFAULT_COMMITMENT 102 | ): Promise { 103 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 104 | mint, 105 | commitment 106 | ); 107 | if (!bondingAccount) 108 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 109 | 110 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 111 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 112 | 113 | const minSolOutput = bondingAccount.getSellPrice( 114 | globalAccount, 115 | feeConfig, 116 | sellTokenAmount 117 | ); 118 | let sellAmountWithSlippage = calculateWithSlippageSell( 119 | minSolOutput, 120 | slippageBasisPoints 121 | ); 122 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 123 | 124 | const transaction = new Transaction(); 125 | await this.sdk.trade.buildSellIx( 126 | seller.publicKey, 127 | mint, 128 | sellTokenAmount, 129 | sellAmountWithSlippage, 130 | transaction, 131 | commitment 132 | ); 133 | 134 | this.addTip(seller, transaction, tip); 135 | const signedTx = await buildSignedTx( 136 | priorityFees, 137 | transaction, 138 | this.sdk.connection, 139 | seller.publicKey, 140 | commitment, 141 | [seller] 142 | ); 143 | 144 | return await this.sendTransaction(signedTx); 145 | } 146 | 147 | private addTip( 148 | buyer: Keypair, 149 | transaction: Transaction, 150 | tip: number = 500000 151 | ): Transaction { 152 | if (tip <= 0) { 153 | return transaction; 154 | } 155 | const tipAccount = this.getRandomAccount(); 156 | const tipInstructions = SystemProgram.transfer({ 157 | fromPubkey: buyer.publicKey, 158 | toPubkey: tipAccount, 159 | lamports: tip, 160 | }); 161 | transaction.add(tipInstructions); 162 | return transaction; 163 | } 164 | 165 | async ping() { 166 | return await AgentRegistry.callUpstream("node", "/ping", { 167 | method: "GET", 168 | }); 169 | } 170 | 171 | async sendTransaction(vertionedTx: VersionedTransaction) { 172 | const serealized = vertionedTx.serialize(); 173 | const tx = Buffer.from(serealized).toString("base64"); 174 | const UUID = crypto.randomUUID(); 175 | const txbody = JSON.stringify({ 176 | jsonrpc: "2.0", 177 | id: UUID, 178 | method: "sendTransaction", 179 | params: [tx, { encoding: "base64", skipPreflight: true, maxRetries: 0 }], 180 | }); 181 | return await AgentRegistry.callUpstream("node", `/`, { 182 | method: "POST", 183 | headers: { 184 | "Content-Type": "application/json", 185 | "Content-Length": Buffer.byteLength(txbody), 186 | "api-key": this.key, 187 | }, 188 | body: txbody, 189 | }); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/modules/NextBlockModule.ts: -------------------------------------------------------------------------------- 1 | import { PumpFunSDK } from "../PumpFunSDK.js"; 2 | import { 3 | Commitment, 4 | Keypair, 5 | PublicKey, 6 | SystemProgram, 7 | Transaction, 8 | VersionedTransaction, 9 | } from "@solana/web3.js"; 10 | import { DEFAULT_COMMITMENT, getHealthBody } from "../pumpFun.consts.js"; 11 | import { PriorityFee, Region } from "../pumpFun.types.js"; 12 | import { 13 | calculateWithSlippageBuy, 14 | calculateWithSlippageSell, 15 | } from "../slippage.js"; 16 | import { buildSignedTx } from "../tx.js"; 17 | import AgentRegistry from "../AgentRegistry.js"; 18 | 19 | export class NextBlockModule { 20 | private key: string; 21 | constructor(private sdk: PumpFunSDK, region: Region, key: string) { 22 | AgentRegistry.registerInConfig("nextBlock", region); 23 | this.key = key; 24 | } 25 | 26 | NEXT_BLOCK_ACCOUNTS = [ 27 | new PublicKey("NextbLoCkVtMGcV47JzewQdvBpLqT9TxQFozQkN98pE"), 28 | new PublicKey("NexTbLoCkWykbLuB1NkjXgFWkX9oAtcoagQegygXXA2"), 29 | new PublicKey("NeXTBLoCKs9F1y5PJS9CKrFNNLU1keHW71rfh7KgA1X"), 30 | new PublicKey("NexTBLockJYZ7QD7p2byrUa6df8ndV2WSd8GkbWqfbb"), 31 | new PublicKey("neXtBLock1LeC67jYd1QdAa32kbVeubsfPNTJC1V5At"), 32 | new PublicKey("nEXTBLockYgngeRmRrjDV31mGSekVPqZoMGhQEZtPVG"), 33 | new PublicKey("NEXTbLoCkB51HpLBLojQfpyVAMorm3zzKg7w9NFdqid"), 34 | new PublicKey("nextBLoCkPMgmG8ZgJtABeScP35qLa2AMCNKntAP7Xc"), 35 | ]; 36 | 37 | private getRandomAccount() { 38 | const randomIndex = Math.floor( 39 | Math.random() * this.NEXT_BLOCK_ACCOUNTS.length 40 | ); 41 | return this.NEXT_BLOCK_ACCOUNTS[randomIndex]; 42 | } 43 | 44 | async buy( 45 | buyer: Keypair, 46 | mint: PublicKey, 47 | buyAmountSol: bigint, 48 | slippageBasisPoints: bigint = 500n, 49 | tip: number = 500000, 50 | priorityFees?: PriorityFee, 51 | commitment: Commitment = DEFAULT_COMMITMENT 52 | ): Promise { 53 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 54 | mint, 55 | commitment 56 | ); 57 | if (!bondingAccount) { 58 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 59 | } 60 | 61 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 62 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 63 | const buyAmount = bondingAccount.getBuyPrice( 64 | globalAccount, 65 | feeConfig, 66 | buyAmountSol 67 | ); 68 | const buyAmountWithSlippage = calculateWithSlippageBuy( 69 | buyAmountSol, 70 | slippageBasisPoints 71 | ); 72 | 73 | const transaction = new Transaction(); 74 | await this.sdk.trade.buildBuyIx( 75 | buyer.publicKey, 76 | mint, 77 | buyAmount, 78 | buyAmountWithSlippage, 79 | transaction, 80 | commitment, 81 | false 82 | ); 83 | this.addTip(buyer, transaction, tip); 84 | const signedTx = await buildSignedTx( 85 | priorityFees, 86 | transaction, 87 | this.sdk.connection, 88 | buyer.publicKey, 89 | commitment, 90 | [buyer] 91 | ); 92 | return await this.sendTransaction(signedTx); 93 | } 94 | 95 | async sell( 96 | seller: Keypair, 97 | mint: PublicKey, 98 | sellTokenAmount: bigint, 99 | slippageBasisPoints: bigint = 500n, 100 | tip: number = 500000, 101 | priorityFees?: PriorityFee, 102 | commitment: Commitment = DEFAULT_COMMITMENT 103 | ): Promise { 104 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 105 | mint, 106 | commitment 107 | ); 108 | if (!bondingAccount) 109 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 110 | 111 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 112 | 113 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 114 | 115 | const minSolOutput = bondingAccount.getSellPrice( 116 | globalAccount, 117 | feeConfig, 118 | sellTokenAmount 119 | ); 120 | let sellAmountWithSlippage = calculateWithSlippageSell( 121 | minSolOutput, 122 | slippageBasisPoints 123 | ); 124 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 125 | 126 | const transaction = new Transaction(); 127 | await this.sdk.trade.buildSellIx( 128 | seller.publicKey, 129 | mint, 130 | sellTokenAmount, 131 | sellAmountWithSlippage, 132 | transaction, 133 | commitment 134 | ); 135 | 136 | this.addTip(seller, transaction, tip); 137 | const signedTx = await buildSignedTx( 138 | priorityFees, 139 | transaction, 140 | this.sdk.connection, 141 | seller.publicKey, 142 | commitment, 143 | [seller] 144 | ); 145 | 146 | return await this.sendTransaction(signedTx); 147 | } 148 | 149 | private addTip( 150 | buyer: Keypair, 151 | transaction: Transaction, 152 | tip: number = 500000 153 | ): Transaction { 154 | if (tip <= 0) { 155 | return transaction; 156 | } 157 | const tipAccount = this.getRandomAccount(); 158 | const tipInstructions = SystemProgram.transfer({ 159 | fromPubkey: buyer.publicKey, 160 | toPubkey: tipAccount, 161 | lamports: tip, 162 | }); 163 | transaction.add(tipInstructions); 164 | return transaction; 165 | } 166 | 167 | async ping() { 168 | return await AgentRegistry.callUpstream("nextBlock", "/api/v2/submit", { 169 | method: "GET", 170 | headers: { 171 | Authorization: this.key, 172 | }, 173 | }); 174 | } 175 | 176 | async sendTransaction(vertionedTx: VersionedTransaction) { 177 | const serealized = vertionedTx.serialize(); 178 | const tx = Buffer.from(serealized).toString("base64"); 179 | const txbody = JSON.stringify({ transaction: { content: tx } }); 180 | return await AgentRegistry.callUpstream("nextBlock", `/api/v2/submit`, { 181 | method: "POST", 182 | headers: { 183 | "Content-Type": "application/json", 184 | "Content-Length": Buffer.byteLength(txbody), 185 | Authorization: this.key, 186 | }, 187 | body: txbody, 188 | }); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/modules/SlotModule.ts: -------------------------------------------------------------------------------- 1 | import { PumpFunSDK } from "../PumpFunSDK.js"; 2 | import { 3 | Commitment, 4 | Keypair, 5 | PublicKey, 6 | SystemProgram, 7 | Transaction, 8 | VersionedTransaction, 9 | } from "@solana/web3.js"; 10 | import { DEFAULT_COMMITMENT, getHealthBody } from "../pumpFun.consts.js"; 11 | import { PriorityFee, Region } from "../pumpFun.types.js"; 12 | import { 13 | calculateWithSlippageBuy, 14 | calculateWithSlippageSell, 15 | } from "../slippage.js"; 16 | import { buildSignedTx } from "../tx.js"; 17 | import AgentRegistry from "../AgentRegistry.js"; 18 | 19 | export class SlotModule { 20 | private key: string; 21 | constructor(private sdk: PumpFunSDK, region: Region, key: string) { 22 | AgentRegistry.registerInConfig("slot", region); 23 | this.key = key; 24 | } 25 | 26 | SLOT_ACCOUNTS = [ 27 | new PublicKey("Eb2KpSC8uMt9GmzyAEm5Eb1AAAgTjRaXWFjKyFXHZxF3"), 28 | new PublicKey("FCjUJZ1qozm1e8romw216qyfQMaaWKxWsuySnumVCCNe"), 29 | new PublicKey("ENxTEjSQ1YabmUpXAdCgevnHQ9MHdLv8tzFiuiYJqa13"), 30 | new PublicKey("6rYLG55Q9RpsPGvqdPNJs4z5WTxJVatMB8zV3WJhs5EK"), 31 | new PublicKey("Cix2bHfqPcKcM233mzxbLk14kSggUUiz2A87fJtGivXr"), 32 | ]; 33 | 34 | private getRandomAccount() { 35 | const randomIndex = Math.floor(Math.random() * this.SLOT_ACCOUNTS.length); 36 | return this.SLOT_ACCOUNTS[randomIndex]; 37 | } 38 | 39 | async buy( 40 | buyer: Keypair, 41 | mint: PublicKey, 42 | buyAmountSol: bigint, 43 | slippageBasisPoints: bigint = 500n, 44 | tip: number = 500000, 45 | priorityFees?: PriorityFee, 46 | commitment: Commitment = DEFAULT_COMMITMENT 47 | ): Promise { 48 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 49 | mint, 50 | commitment 51 | ); 52 | if (!bondingAccount) { 53 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 54 | } 55 | 56 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 57 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 58 | const buyAmount = bondingAccount.getBuyPrice( 59 | globalAccount, 60 | feeConfig, 61 | buyAmountSol 62 | ); 63 | const buyAmountWithSlippage = calculateWithSlippageBuy( 64 | buyAmountSol, 65 | slippageBasisPoints 66 | ); 67 | 68 | const transaction = new Transaction(); 69 | await this.sdk.trade.buildBuyIx( 70 | buyer.publicKey, 71 | mint, 72 | buyAmount, 73 | buyAmountWithSlippage, 74 | transaction, 75 | commitment, 76 | false 77 | ); 78 | this.addTip(buyer, transaction, tip); 79 | const signedTx = await buildSignedTx( 80 | priorityFees, 81 | transaction, 82 | this.sdk.connection, 83 | buyer.publicKey, 84 | commitment, 85 | [buyer] 86 | ); 87 | return await this.sendTransaction(signedTx); 88 | } 89 | 90 | async sell( 91 | seller: Keypair, 92 | mint: PublicKey, 93 | sellTokenAmount: bigint, 94 | slippageBasisPoints: bigint = 500n, 95 | tip: number = 500000, 96 | priorityFees?: PriorityFee, 97 | commitment: Commitment = DEFAULT_COMMITMENT 98 | ): Promise { 99 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 100 | mint, 101 | commitment 102 | ); 103 | if (!bondingAccount) 104 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 105 | 106 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 107 | 108 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 109 | 110 | const minSolOutput = bondingAccount.getSellPrice( 111 | globalAccount, 112 | feeConfig, 113 | sellTokenAmount 114 | ); 115 | let sellAmountWithSlippage = calculateWithSlippageSell( 116 | minSolOutput, 117 | slippageBasisPoints 118 | ); 119 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 120 | 121 | const transaction = new Transaction(); 122 | await this.sdk.trade.buildSellIx( 123 | seller.publicKey, 124 | mint, 125 | sellTokenAmount, 126 | sellAmountWithSlippage, 127 | transaction, 128 | commitment 129 | ); 130 | 131 | this.addTip(seller, transaction, tip); 132 | const signedTx = await buildSignedTx( 133 | priorityFees, 134 | transaction, 135 | this.sdk.connection, 136 | seller.publicKey, 137 | commitment, 138 | [seller] 139 | ); 140 | 141 | return await this.sendTransaction(signedTx); 142 | } 143 | 144 | private addTip( 145 | buyer: Keypair, 146 | transaction: Transaction, 147 | tip: number = 500000 148 | ): Transaction { 149 | if (tip <= 0) { 150 | return transaction; 151 | } 152 | const tipAccount = this.getRandomAccount(); 153 | const tipInstructions = SystemProgram.transfer({ 154 | fromPubkey: buyer.publicKey, 155 | toPubkey: tipAccount, 156 | lamports: tip, 157 | }); 158 | transaction.add(tipInstructions); 159 | return transaction; 160 | } 161 | 162 | async ping() { 163 | return await AgentRegistry.callUpstream("slot", `/?api-key=${this.key}`, { 164 | method: "POST", 165 | headers: { 166 | "Content-Type": "application/json", 167 | "Content-Length": Buffer.byteLength(getHealthBody), 168 | }, 169 | body: getHealthBody, 170 | }); 171 | } 172 | 173 | async sendTransaction(vertionedTx: VersionedTransaction) { 174 | const serealized = vertionedTx.serialize(); 175 | const tx = Buffer.from(serealized).toString("base64"); 176 | const UUID = crypto.randomUUID(); 177 | const txbody = JSON.stringify({ 178 | jsonrpc: "2.0", 179 | id: UUID, 180 | method: "sendTransaction", 181 | params: [tx, { encoding: "base64", skipPreflight: true, maxRetries: 0 }], 182 | }); 183 | return await AgentRegistry.callUpstream("slot", `/?api-key=${this.key}`, { 184 | method: "POST", 185 | headers: { 186 | "Content-Type": "application/json", 187 | "Content-Length": Buffer.byteLength(txbody), 188 | }, 189 | body: txbody, 190 | }); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/modules/AstraModule.ts: -------------------------------------------------------------------------------- 1 | import { PumpFunSDK } from "../PumpFunSDK.js"; 2 | import { 3 | Commitment, 4 | Keypair, 5 | PublicKey, 6 | SystemProgram, 7 | Transaction, 8 | VersionedTransaction, 9 | } from "@solana/web3.js"; 10 | import { DEFAULT_COMMITMENT, getHealthBody } from "../pumpFun.consts.js"; 11 | import { PriorityFee, Region } from "../pumpFun.types.js"; 12 | import { 13 | calculateWithSlippageBuy, 14 | calculateWithSlippageSell, 15 | } from "../slippage.js"; 16 | import { buildSignedTx } from "../tx.js"; 17 | import AgentRegistry from "../AgentRegistry.js"; 18 | 19 | export class AstraModule { 20 | private key: string; 21 | constructor(private sdk: PumpFunSDK, region: Region, key: string) { 22 | AgentRegistry.registerInConfig("astra", region); 23 | this.key = key; 24 | } 25 | 26 | ASTRA_ACCOUNTS = [ 27 | new PublicKey("astrazznxsGUhWShqgNtAdfrzP2G83DzcWVJDxwV9bF"), 28 | new PublicKey("astra4uejePWneqNaJKuFFA8oonqCE1sqF6b45kDMZm"), 29 | new PublicKey("astra9xWY93QyfG6yM8zwsKsRodscjQ2uU2HKNL5prk"), 30 | new PublicKey("astraRVUuTHjpwEVvNBeQEgwYx9w9CFyfxjYoobCZhL"), 31 | ]; 32 | 33 | private getRandomAccount() { 34 | const randomIndex = Math.floor(Math.random() * this.ASTRA_ACCOUNTS.length); 35 | return this.ASTRA_ACCOUNTS[randomIndex]; 36 | } 37 | 38 | async buy( 39 | buyer: Keypair, 40 | mint: PublicKey, 41 | buyAmountSol: bigint, 42 | slippageBasisPoints: bigint = 500n, 43 | tip: number = 500000, 44 | priorityFees?: PriorityFee, 45 | commitment: Commitment = DEFAULT_COMMITMENT 46 | ): Promise { 47 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 48 | mint, 49 | commitment 50 | ); 51 | if (!bondingAccount) { 52 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 53 | } 54 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 55 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 56 | const buyAmount = bondingAccount.getBuyPrice( 57 | globalAccount, 58 | feeConfig, 59 | buyAmountSol 60 | ); 61 | const buyAmountWithSlippage = calculateWithSlippageBuy( 62 | buyAmountSol, 63 | slippageBasisPoints 64 | ); 65 | 66 | const transaction = new Transaction(); 67 | await this.sdk.trade.buildBuyIx( 68 | buyer.publicKey, 69 | mint, 70 | buyAmount, 71 | buyAmountWithSlippage, 72 | transaction, 73 | commitment, 74 | false 75 | ); 76 | this.addTip(buyer, transaction, tip); 77 | const signedTx = await buildSignedTx( 78 | priorityFees, 79 | transaction, 80 | this.sdk.connection, 81 | buyer.publicKey, 82 | commitment, 83 | [buyer] 84 | ); 85 | return await this.sendTransaction(signedTx); 86 | } 87 | 88 | async sell( 89 | seller: Keypair, 90 | mint: PublicKey, 91 | sellTokenAmount: bigint, 92 | slippageBasisPoints: bigint = 500n, 93 | tip: number = 500000, 94 | priorityFees?: PriorityFee, 95 | commitment: Commitment = DEFAULT_COMMITMENT 96 | ): Promise { 97 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 98 | mint, 99 | commitment 100 | ); 101 | if (!bondingAccount) 102 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 103 | 104 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 105 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 106 | 107 | const minSolOutput = bondingAccount.getSellPrice( 108 | globalAccount, 109 | feeConfig, 110 | sellTokenAmount 111 | ); 112 | let sellAmountWithSlippage = calculateWithSlippageSell( 113 | minSolOutput, 114 | slippageBasisPoints 115 | ); 116 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 117 | 118 | const transaction = new Transaction(); 119 | await this.sdk.trade.buildSellIx( 120 | seller.publicKey, 121 | mint, 122 | sellTokenAmount, 123 | sellAmountWithSlippage, 124 | transaction, 125 | commitment 126 | ); 127 | 128 | this.addTip(seller, transaction, tip); 129 | const signedTx = await buildSignedTx( 130 | priorityFees, 131 | transaction, 132 | this.sdk.connection, 133 | seller.publicKey, 134 | commitment, 135 | [seller] 136 | ); 137 | 138 | return await this.sendTransaction(signedTx); 139 | } 140 | 141 | private addTip( 142 | buyer: Keypair, 143 | transaction: Transaction, 144 | tip: number = 500000 145 | ): Transaction { 146 | if (tip <= 0) { 147 | return transaction; 148 | } 149 | const tipAccount = this.getRandomAccount(); 150 | const tipInstructions = SystemProgram.transfer({ 151 | fromPubkey: buyer.publicKey, 152 | toPubkey: tipAccount, 153 | lamports: tip, 154 | }); 155 | transaction.add(tipInstructions); 156 | return transaction; 157 | } 158 | 159 | async ping() { 160 | return await AgentRegistry.callUpstream( 161 | "astra", 162 | `/iris?api-key=${this.key}`, 163 | { 164 | method: "POST", 165 | headers: { 166 | "Content-Type": "application/json", 167 | "Content-Length": Buffer.byteLength(getHealthBody), 168 | }, 169 | body: getHealthBody, 170 | } 171 | ); 172 | } 173 | 174 | async sendTransaction(vertionedTx: VersionedTransaction) { 175 | const serealized = vertionedTx.serialize(); 176 | const tx = Buffer.from(serealized).toString("base64"); 177 | const UUID = crypto.randomUUID(); 178 | const txbody = JSON.stringify({ 179 | jsonrpc: "2.0", 180 | id: UUID, 181 | method: "sendTransaction", 182 | params: [tx, { encoding: "base64", skipPreflight: true, maxRetries: 0 }], 183 | }); 184 | return await AgentRegistry.callUpstream( 185 | "astra", 186 | `/iris?api-key=${this.key}`, 187 | { 188 | method: "POST", 189 | headers: { 190 | "Content-Type": "application/json", 191 | "Content-Length": Buffer.byteLength(txbody), 192 | }, 193 | body: txbody, 194 | } 195 | ); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Pumpdotfun SDK Repumped

2 |

3 | TypeScript SDK for Pump Fun
4 | Create · Buy · Sell · Relay · Jito Bundles 5 |

6 |

7 | npm 8 | MIT 9 | visitors 10 |

11 | 12 | 13 | 14 | > Fixed and reworked version of [rckprtr/pumpdotfun-sdk](https://github.com/rckprtr/pumpdotfun-sdk). 15 | > ✅ Fixed buy/sell/create 16 | > ✅ Added support for new events 17 | > ✅ Added Jito and alternative relay support (Astra, 0Slot, NodeOne, NextBlock) 18 | > ✅ Works on **devnet** and **mainnet-beta** 19 | > ✅ ESM & CJS builds via Rollup in **`dist/`** 20 | 21 | --- 22 | 23 |

24 | ⭐️ If you find this project useful, please star the repo — it helps a lot! ⭐️ 25 |

26 | 27 | --- 28 | 29 | 30 | ## ✨ Features 31 | 32 | | Module | Highlights | 33 | | --------------------- | --------------------------------------------------------------------------------------------------- | 34 | | **`PumpFunSDK`** | Entry point. Wraps Anchor `Program` & `Connection` and initializes all submodules. | 35 | | **`TradeModule`** | `createAndBuy`, `buy`, `sell`, tx builders, slippage helpers | 36 | | **`TokenModule`** | Token metadata, ATA creation, mint helpers | 37 | | **`PdaModule`** | PDA helpers: global, event-authority, bonding-curve, metadata, etc. | 38 | | **`EventModule`** | Typed Anchor event listeners with automatic deserialization | 39 | | **`JitoModule`** | Submit Jito bundles for `buy`/`sell`. Requires `jitoUrl` and `authKeypair` in SDK options | 40 | | **`AstraModule`** | Sends `buy`/`sell` transactions via Astra relays. Adds tip transfers + optional `ping()` keep-alive | 41 | | **`SlotModule`** | Similar to Astra; optimized for 0Slot relays with `buy()` and `ping()` | 42 | | **`NextBlockModule`** | Similar to Astra; optimized for NextBlock relays with `buy()` and `ping()` | 43 | | **`NodeOneModule`** | Similar to Astra; optimized for NodeOne relays with `buy()` and `ping()` | 44 | | **IDL exports** | Full `IDL` JSON and `type PumpFun` helper | 45 | 46 | > **Note:** `ping()` on relay modules (e.g., `sdk.slot.ping()`) should be called periodically to keep upstream relay connection alive. 47 | 48 | --- 49 | 50 | ## 📦 Install 51 | 52 | ```bash 53 | npm install pumpdotfun-repumped-sdk 54 | ``` 55 | 56 | --- 57 | 58 | ## 🔨 Quick Start 59 | 60 | Replace DEVNET_RPC url with mainnet url 61 | 62 | ```ts 63 | const DEVNET_RPC = "https://api.devnet.solana.com"; 64 | const SLIPPAGE_BPS = 100n; 65 | const PRIORITY_FEE = { unitLimit: 250_000, unitPrice: 250_000 }; 66 | 67 | const secret = JSON.parse(process.env.WALLET!); 68 | const wallet = Keypair.fromSecretKey(Uint8Array.from(secret)); 69 | 70 | async function printSOL(conn: Connection, pk: PublicKey, label = "") { 71 | const sol = (await conn.getBalance(pk)) / LAMPORTS_PER_SOL; 72 | console.log(`${label} SOL:`, sol.toFixed(4)); 73 | } 74 | 75 | async function main() { 76 | const connection = new Connection(DEVNET_RPC, "confirmed"); 77 | const provider = new AnchorProvider(connection, new Wallet(wallet), { 78 | commitment: "confirmed", 79 | }); 80 | const sdk = new PumpFunSDK(provider); 81 | const mint = Keypair.generate(); 82 | 83 | await printSOL(connection, wallet.publicKey, "user"); 84 | 85 | const img = await import("node:fs/promises").then((fs) => 86 | fs.readFile("example/images/test.png") 87 | ); 88 | const blob = new Blob([img], { type: "image/png" }); 89 | await sdk.trade.createAndBuy( 90 | wallet, 91 | mint, 92 | { name: "DEV-TEST", symbol: "DVT", description: "Devnet demo", file: blob }, 93 | 0.0001 * LAMPORTS_PER_SOL, 94 | SLIPPAGE_BPS, 95 | PRIORITY_FEE 96 | ); 97 | console.log( 98 | "pump.fun link →", 99 | `https://pump.fun/${mint.publicKey}?cluster=devnet` 100 | ); 101 | 102 | await sdk.trade.buy( 103 | wallet, 104 | mint.publicKey, 105 | 0.0002 * LAMPORTS_PER_SOL, 106 | SLIPPAGE_BPS, 107 | PRIORITY_FEE 108 | ); 109 | 110 | const bal = await getSPLBalance(connection, mint.publicKey, wallet.publicKey); 111 | console.log("Token balance:", bal / 10 ** DEFAULT_DECIMALS); 112 | 113 | await sdk.trade.sell( 114 | wallet, 115 | mint.publicKey, 116 | BigInt(bal), 117 | SLIPPAGE_BPS, 118 | PRIORITY_FEE 119 | ); 120 | await printSOL(connection, wallet.publicKey, "user after sell"); 121 | } 122 | 123 | main().catch(console.error); 124 | ``` 125 | 126 | --- 127 | 128 | ## 🚀 Advanced Examples 129 | 130 | ### 🧠 Buy with **Jito** 131 | 132 | ```ts 133 | const sdk = new PumpFunSDK(provider, { 134 | jitoUrl: "ny.mainnet.block-engine.jito.wtf", 135 | authKeypair: wallet, 136 | }); 137 | 138 | await sdk.jito!.buyJito( 139 | wallet, 140 | mint.publicKey, 141 | BigInt(0.0002 * LAMPORTS_PER_SOL), 142 | SLIPPAGE_BPS, 143 | 500_000, 144 | PRIORITY, 145 | "confirmed" 146 | ); 147 | ``` 148 | 149 | --- 150 | 151 | ### 🛰️ Buy with **0Slot**, **NodeOne**, **Astra**, or **NextBlock** 152 | 153 | > These modules use upstream relayers to speed up TX submission. 154 | > They support periodic `ping()` to keep-alive HTTPS connection and reduce TLS overhead. 155 | 156 | ```ts 157 | const sdk = new PumpFunSDK(provider, { 158 | providerRegion: Region.Frankfurt, 159 | slotKey: "your-api-key", // or astraKey / nextBlockKey / nodeOneKey 160 | }); 161 | 162 | await sdk.slot!.ping(); 163 | 164 | await sdk.slot!.buy( 165 | wallet, 166 | mint.publicKey, 167 | BigInt(0.0002 * LAMPORTS_PER_SOL), 168 | SLIPPAGE_BPS, 169 | 500_000, 170 | PRIORITY, 171 | "confirmed" 172 | ); 173 | ``` 174 | 175 | > `AstraModule`, `NodeOneModule`, `NextBlockModule` follow the same interface: `buy()`, `sell()`, `ping()` 176 | > Transactions are signed locally, and relayed via HTTPS POST (base64-encoded) for speed. Tx are sent over http for extra speed. 177 | 178 | --- 179 | 180 | ## 🧩 Tip: What `ping()` Does 181 | 182 | Relay modules like `SlotModule`, `AstraModule`, `NodeOneModule`, and `NextBlockModule` implement `ping()`. 183 | 184 | Calling `ping()` periodically: 185 | 186 | - Prevents connection idle timeouts 187 | - Keeps the relay ready for low-latency submission 188 | 189 | ```ts 190 | await sdk.astra!.ping(); 191 | await sdk.slot!.ping(); 192 | ``` 193 | 194 | --- 195 | 196 | ## 🌐 Supported Relay Regions 197 | 198 | Each relay provider supports a defined set of regions for optimal latency. Below are the currently supported regions per provider: 199 | 200 | ```text 201 | Slot 📍 Frankfurt • New York • Tokyo • Amsterdam • Los Angeles 202 | Astra 📍 Frankfurt • New York • Tokyo • Amsterdam 203 | NodeOne 📍 New York • Tokyo • Amsterdam • Frankfurt 204 | NextBlock 📍 Tokyo • Frankfurt • New York 205 | ``` 206 | 207 | > You must specify `providerRegion` in `PumpFunSDK` options to select which regional relay to use. 208 | 209 | ## ⚠️ Disclaimer 210 | 211 | This software is provided **“as is,”** without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. 212 | In no event shall the authors or copyright holders be liable for any claim, damages, or other liability—whether in an action of contract, tort, or otherwise—arising from, out of, or in connection with the software or the use or other dealings in the software. 213 | 214 | > Use at your own risk. 215 | > The authors take no responsibility for any harm or damage caused by the use of this software. 216 | > Users are responsible for ensuring the suitability and safety of this software for their specific use cases. 217 | 218 | By using this software, **you acknowledge that you have read, understood, and agree to this disclaimer.** 219 | -------------------------------------------------------------------------------- /src/modules/TradeModule.ts: -------------------------------------------------------------------------------- 1 | import BN from "bn.js"; 2 | import { getAssociatedTokenAddress } from "@solana/spl-token"; 3 | import { 4 | Keypair, 5 | Commitment, 6 | Finality, 7 | Transaction, 8 | PublicKey, 9 | } from "@solana/web3.js"; 10 | import { GlobalAccount } from "../GlobalAccount.js"; 11 | 12 | import { DEFAULT_COMMITMENT, DEFAULT_FINALITY } from "../pumpFun.consts.js"; 13 | import { 14 | CreateTokenMetadata, 15 | PriorityFee, 16 | TransactionResult, 17 | } from "../pumpFun.types.js"; 18 | import { PumpFunSDK } from "../PumpFunSDK.js"; 19 | import { 20 | calculateWithSlippageBuy, 21 | calculateWithSlippageSell, 22 | } from "../slippage.js"; 23 | import { sendTx } from "../tx.js"; 24 | 25 | export class TradeModule { 26 | constructor(private sdk: PumpFunSDK) {} 27 | 28 | async createAndBuy( 29 | creator: Keypair, 30 | mint: Keypair, 31 | metadata: CreateTokenMetadata, 32 | buyAmountSol: bigint, 33 | slippageBasisPoints: bigint = 500n, 34 | priorityFees?: PriorityFee, 35 | commitment: Commitment = DEFAULT_COMMITMENT, 36 | finality: Finality = DEFAULT_FINALITY 37 | ): Promise { 38 | const tokenMetadata = await this.sdk.token.createTokenMetadata(metadata); 39 | 40 | const createIx = await this.getCreateInstructions( 41 | creator.publicKey, 42 | metadata.name, 43 | metadata.symbol, 44 | tokenMetadata.metadataUri, 45 | mint 46 | ); 47 | 48 | const transaction = new Transaction().add(createIx); 49 | 50 | if (buyAmountSol > 0n) { 51 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 52 | const buyAmount = globalAccount.getInitialBuyPrice(buyAmountSol); 53 | const buyAmountWithSlippage = calculateWithSlippageBuy( 54 | buyAmountSol, 55 | slippageBasisPoints 56 | ); 57 | 58 | await this.buildBuyIx( 59 | creator.publicKey, 60 | mint.publicKey, 61 | buyAmount, 62 | buyAmountWithSlippage, 63 | transaction, 64 | commitment, 65 | true 66 | ); 67 | } 68 | 69 | return await sendTx( 70 | this.sdk.connection, 71 | transaction, 72 | creator.publicKey, 73 | [creator, mint], 74 | priorityFees, 75 | commitment, 76 | finality 77 | ); 78 | } 79 | 80 | async buy( 81 | buyer: Keypair, 82 | mint: PublicKey, 83 | buyAmountSol: bigint, 84 | slippageBasisPoints: bigint = 500n, 85 | priorityFees?: PriorityFee, 86 | commitment: Commitment = DEFAULT_COMMITMENT, 87 | finality: Finality = DEFAULT_FINALITY 88 | ): Promise { 89 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 90 | mint, 91 | commitment 92 | ); 93 | if (!bondingAccount) { 94 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 95 | } 96 | 97 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 98 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 99 | const buyAmount = bondingAccount.getBuyPrice( 100 | globalAccount, 101 | feeConfig, 102 | buyAmountSol 103 | ); 104 | const buyAmountWithSlippage = calculateWithSlippageBuy( 105 | buyAmountSol, 106 | slippageBasisPoints 107 | ); 108 | 109 | const transaction = new Transaction(); 110 | await this.buildBuyIx( 111 | buyer.publicKey, 112 | mint, 113 | buyAmount, 114 | buyAmountWithSlippage, 115 | transaction, 116 | commitment, 117 | false 118 | ); 119 | 120 | return await sendTx( 121 | this.sdk.connection, 122 | transaction, 123 | buyer.publicKey, 124 | [buyer], 125 | priorityFees, 126 | commitment, 127 | finality 128 | ); 129 | } 130 | 131 | async getBuyInstructionsBySolAmount( 132 | buyer: PublicKey, 133 | mint: PublicKey, 134 | buyAmountSol: bigint, 135 | slippageBasisPoints: bigint = 500n, 136 | commitment: Commitment = DEFAULT_COMMITMENT 137 | ): Promise { 138 | const bondingCurveAccount = await this.sdk.token.getBondingCurveAccount( 139 | mint, 140 | commitment 141 | ); 142 | if (!bondingCurveAccount) { 143 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 144 | } 145 | 146 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 147 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 148 | const buyAmount = bondingCurveAccount.getBuyPrice( 149 | globalAccount, 150 | feeConfig, 151 | buyAmountSol 152 | ); 153 | const buyAmountWithSlippage = calculateWithSlippageBuy( 154 | buyAmountSol, 155 | slippageBasisPoints 156 | ); 157 | 158 | const transaction = new Transaction(); 159 | await this.buildBuyIx( 160 | buyer, 161 | mint, 162 | buyAmount, 163 | buyAmountWithSlippage, 164 | transaction, 165 | commitment, 166 | false 167 | ); 168 | 169 | return transaction; 170 | } 171 | 172 | async buildBuyIx( 173 | buyer: PublicKey, 174 | mint: PublicKey, 175 | amount: bigint, 176 | maxSolCost: bigint, 177 | tx: Transaction, 178 | commitment: Commitment, 179 | shouldUseBuyerAsBonding: boolean 180 | ): Promise { 181 | const bondingCurve = this.sdk.pda.getBondingCurvePDA(mint); 182 | const associatedBonding = await getAssociatedTokenAddress( 183 | mint, 184 | bondingCurve, 185 | true 186 | ); 187 | 188 | const associatedUser = 189 | await this.sdk.token.createAssociatedTokenAccountIfNeeded( 190 | buyer, 191 | buyer, 192 | mint, 193 | tx, 194 | commitment 195 | ); 196 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 197 | const globalAccountPDA = this.sdk.pda.getGlobalAccountPda(); 198 | const bondingCreator = shouldUseBuyerAsBonding 199 | ? this.sdk.pda.getCreatorVaultPda(buyer) 200 | : await this.sdk.token.getBondingCurveCreator(bondingCurve, commitment); 201 | const creatorVault = shouldUseBuyerAsBonding 202 | ? bondingCreator 203 | : this.sdk.pda.getCreatorVaultPda(bondingCreator); 204 | 205 | const eventAuthority = this.sdk.pda.getEventAuthorityPda(); 206 | 207 | const ix = await this.sdk.program.methods 208 | .buy(new BN(amount.toString()), new BN(maxSolCost.toString())) 209 | .accounts({ 210 | global: globalAccountPDA, 211 | feeRecipient: globalAccount.feeRecipient, 212 | mint, 213 | bondingCurve, 214 | associatedBondingCurve: associatedBonding, 215 | associatedUser, 216 | user: buyer, 217 | creatorVault, 218 | eventAuthority, 219 | globalVolumeAccumulator: this.sdk.pda.getGlobalVolumeAccumulatorPda(), 220 | userVolumeAccumulator: this.sdk.pda.getUserVolumeAccumulatorPda(buyer), 221 | feeConfig: this.sdk.pda.getPumpFeeConfigPda(), 222 | }) 223 | .instruction(); 224 | 225 | tx.add(ix); 226 | } 227 | 228 | //create token instructions 229 | async getCreateInstructions( 230 | creator: PublicKey, 231 | name: string, 232 | symbol: string, 233 | uri: string, 234 | mint: Keypair 235 | ): Promise { 236 | const mintAuthority = this.sdk.pda.getMintAuthorityPDA(); 237 | const bondingCurve = this.sdk.pda.getBondingCurvePDA(mint.publicKey); 238 | const associatedBonding = await getAssociatedTokenAddress( 239 | mint.publicKey, 240 | bondingCurve, 241 | true 242 | ); 243 | const global = this.sdk.pda.getGlobalAccountPda(); 244 | const metadata = this.sdk.pda.getMetadataPDA(mint.publicKey); 245 | const eventAuthority = this.sdk.pda.getEventAuthorityPda(); 246 | 247 | const ix = await this.sdk.program.methods 248 | .create(name, symbol, uri, creator) 249 | .accounts({ 250 | mint: mint.publicKey, 251 | mintAuthority, 252 | bondingCurve, 253 | associatedBondingCurve: associatedBonding, 254 | global, 255 | metadata, 256 | user: creator, 257 | eventAuthority, 258 | }) 259 | .instruction(); 260 | 261 | return new Transaction().add(ix); 262 | } 263 | 264 | async buildSellIx( 265 | seller: PublicKey, 266 | mint: PublicKey, 267 | tokenAmount: bigint, 268 | minSolOutput: bigint, 269 | tx: Transaction, 270 | commitment: Commitment 271 | ): Promise { 272 | const bondingCurve = this.sdk.pda.getBondingCurvePDA(mint); 273 | const associatedBonding = await getAssociatedTokenAddress( 274 | mint, 275 | bondingCurve, 276 | true 277 | ); 278 | 279 | const associatedUser = 280 | await this.sdk.token.createAssociatedTokenAccountIfNeeded( 281 | seller, 282 | seller, 283 | mint, 284 | tx, 285 | commitment 286 | ); 287 | 288 | const globalPda = this.sdk.pda.getGlobalAccountPda(); 289 | const globalBuf = await this.sdk.connection.getAccountInfo( 290 | globalPda, 291 | commitment 292 | ); 293 | const feeRecipient = GlobalAccount.fromBuffer(globalBuf!.data).feeRecipient; 294 | 295 | const bondingCreator = await this.sdk.token.getBondingCurveCreator( 296 | bondingCurve, 297 | commitment 298 | ); 299 | const creatorVault = this.sdk.pda.getCreatorVaultPda(bondingCreator); 300 | 301 | const eventAuthority = this.sdk.pda.getEventAuthorityPda(); 302 | 303 | const ix = await this.sdk.program.methods 304 | .sell(new BN(tokenAmount.toString()), new BN(minSolOutput.toString())) 305 | .accounts({ 306 | global: globalPda, 307 | feeRecipient, 308 | mint, 309 | bondingCurve, 310 | associatedBondingCurve: associatedBonding, 311 | associatedUser, 312 | user: seller, 313 | creatorVault, 314 | eventAuthority, 315 | feeConfig: this.sdk.pda.getPumpFeeConfigPda(), 316 | }) 317 | .instruction(); 318 | 319 | tx.add(ix); 320 | } 321 | 322 | async sell( 323 | seller: Keypair, 324 | mint: PublicKey, 325 | sellTokenAmount: bigint, 326 | slippageBasisPoints: bigint = 500n, 327 | priorityFees?: PriorityFee, 328 | commitment: Commitment = DEFAULT_COMMITMENT, 329 | finality: Finality = DEFAULT_FINALITY 330 | ): Promise { 331 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 332 | mint, 333 | commitment 334 | ); 335 | if (!bondingAccount) 336 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 337 | 338 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 339 | 340 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 341 | 342 | const minSolOutput = bondingAccount.getSellPrice( 343 | globalAccount, 344 | feeConfig, 345 | sellTokenAmount 346 | ); 347 | let sellAmountWithSlippage = calculateWithSlippageSell( 348 | minSolOutput, 349 | slippageBasisPoints 350 | ); 351 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 352 | 353 | const transaction = new Transaction(); 354 | await this.buildSellIx( 355 | seller.publicKey, 356 | mint, 357 | sellTokenAmount, 358 | sellAmountWithSlippage, 359 | transaction, 360 | commitment 361 | ); 362 | 363 | return await sendTx( 364 | this.sdk.connection, 365 | transaction, 366 | seller.publicKey, 367 | [seller], 368 | priorityFees, 369 | commitment, 370 | finality 371 | ); 372 | } 373 | 374 | async getSellInstructionsByTokenAmount( 375 | seller: PublicKey, 376 | mint: PublicKey, 377 | sellTokenAmount: bigint, 378 | slippageBasisPoints: bigint = 500n, 379 | commitment: Commitment = DEFAULT_COMMITMENT 380 | ): Promise { 381 | const bondingAccount = await this.sdk.token.getBondingCurveAccount( 382 | mint, 383 | commitment 384 | ); 385 | if (!bondingAccount) 386 | throw new Error(`Bonding curve account not found: ${mint.toBase58()}`); 387 | 388 | const globalAccount = await this.sdk.token.getGlobalAccount(commitment); 389 | const feeConfig = await this.sdk.token.getFeeConfig(commitment); 390 | 391 | const minSolOutput = bondingAccount.getSellPrice( 392 | globalAccount, 393 | feeConfig, 394 | sellTokenAmount 395 | ); 396 | let sellAmountWithSlippage = calculateWithSlippageSell( 397 | minSolOutput, 398 | slippageBasisPoints 399 | ); 400 | if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n; 401 | 402 | const transaction = new Transaction(); 403 | await this.buildSellIx( 404 | seller, 405 | mint, 406 | sellTokenAmount, 407 | sellAmountWithSlippage, 408 | transaction, 409 | commitment 410 | ); 411 | return transaction; 412 | } 413 | } 414 | -------------------------------------------------------------------------------- /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 | "description": "Created with Anchor" 8 | }, 9 | "instructions": [ 10 | { 11 | "name": "admin_set_creator", 12 | "docs": [ 13 | "Allows Global::admin_set_creator_authority to override the bonding curve creator" 14 | ], 15 | "discriminator": [69, 25, 171, 142, 57, 239, 13, 4], 16 | "accounts": [ 17 | { 18 | "name": "admin_set_creator_authority", 19 | "signer": true, 20 | "relations": ["global"] 21 | }, 22 | { 23 | "name": "global", 24 | "pda": { 25 | "seeds": [ 26 | { 27 | "kind": "const", 28 | "value": [103, 108, 111, 98, 97, 108] 29 | } 30 | ] 31 | } 32 | }, 33 | { 34 | "name": "mint" 35 | }, 36 | { 37 | "name": "bonding_curve", 38 | "writable": true, 39 | "pda": { 40 | "seeds": [ 41 | { 42 | "kind": "const", 43 | "value": [ 44 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 45 | ] 46 | }, 47 | { 48 | "kind": "account", 49 | "path": "mint" 50 | } 51 | ] 52 | } 53 | }, 54 | { 55 | "name": "event_authority", 56 | "pda": { 57 | "seeds": [ 58 | { 59 | "kind": "const", 60 | "value": [ 61 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 62 | 114, 105, 116, 121 63 | ] 64 | } 65 | ] 66 | } 67 | }, 68 | { 69 | "name": "program" 70 | } 71 | ], 72 | "args": [ 73 | { 74 | "name": "creator", 75 | "type": "pubkey" 76 | } 77 | ] 78 | }, 79 | { 80 | "name": "admin_set_idl_authority", 81 | "discriminator": [8, 217, 96, 231, 144, 104, 192, 5], 82 | "accounts": [ 83 | { 84 | "name": "authority", 85 | "signer": true, 86 | "relations": ["global"] 87 | }, 88 | { 89 | "name": "global", 90 | "pda": { 91 | "seeds": [ 92 | { 93 | "kind": "const", 94 | "value": [103, 108, 111, 98, 97, 108] 95 | } 96 | ] 97 | } 98 | }, 99 | { 100 | "name": "idl_account", 101 | "writable": true 102 | }, 103 | { 104 | "name": "system_program", 105 | "address": "11111111111111111111111111111111" 106 | }, 107 | { 108 | "name": "program_signer", 109 | "pda": { 110 | "seeds": [] 111 | } 112 | }, 113 | { 114 | "name": "event_authority", 115 | "pda": { 116 | "seeds": [ 117 | { 118 | "kind": "const", 119 | "value": [ 120 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 121 | 114, 105, 116, 121 122 | ] 123 | } 124 | ] 125 | } 126 | }, 127 | { 128 | "name": "program" 129 | } 130 | ], 131 | "args": [ 132 | { 133 | "name": "idl_authority", 134 | "type": "pubkey" 135 | } 136 | ] 137 | }, 138 | { 139 | "name": "admin_update_token_incentives", 140 | "discriminator": [209, 11, 115, 87, 213, 23, 124, 204], 141 | "accounts": [ 142 | { 143 | "name": "authority", 144 | "writable": true, 145 | "signer": true, 146 | "relations": ["global"] 147 | }, 148 | { 149 | "name": "global", 150 | "pda": { 151 | "seeds": [ 152 | { 153 | "kind": "const", 154 | "value": [103, 108, 111, 98, 97, 108] 155 | } 156 | ] 157 | } 158 | }, 159 | { 160 | "name": "global_volume_accumulator", 161 | "writable": true, 162 | "pda": { 163 | "seeds": [ 164 | { 165 | "kind": "const", 166 | "value": [ 167 | 103, 108, 111, 98, 97, 108, 95, 118, 111, 108, 117, 109, 101, 168 | 95, 97, 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 169 | ] 170 | } 171 | ] 172 | } 173 | }, 174 | { 175 | "name": "mint" 176 | }, 177 | { 178 | "name": "global_incentive_token_account", 179 | "writable": true, 180 | "pda": { 181 | "seeds": [ 182 | { 183 | "kind": "account", 184 | "path": "global_volume_accumulator" 185 | }, 186 | { 187 | "kind": "account", 188 | "path": "token_program" 189 | }, 190 | { 191 | "kind": "account", 192 | "path": "mint" 193 | } 194 | ], 195 | "program": { 196 | "kind": "const", 197 | "value": [ 198 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 199 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 200 | 219, 233, 248, 89 201 | ] 202 | } 203 | } 204 | }, 205 | { 206 | "name": "associated_token_program", 207 | "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" 208 | }, 209 | { 210 | "name": "system_program", 211 | "address": "11111111111111111111111111111111" 212 | }, 213 | { 214 | "name": "token_program" 215 | }, 216 | { 217 | "name": "event_authority", 218 | "pda": { 219 | "seeds": [ 220 | { 221 | "kind": "const", 222 | "value": [ 223 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 224 | 114, 105, 116, 121 225 | ] 226 | } 227 | ] 228 | } 229 | }, 230 | { 231 | "name": "program" 232 | } 233 | ], 234 | "args": [ 235 | { 236 | "name": "start_time", 237 | "type": "i64" 238 | }, 239 | { 240 | "name": "end_time", 241 | "type": "i64" 242 | }, 243 | { 244 | "name": "seconds_in_a_day", 245 | "type": "i64" 246 | }, 247 | { 248 | "name": "day_number", 249 | "type": "u64" 250 | }, 251 | { 252 | "name": "pump_token_supply_per_day", 253 | "type": "u64" 254 | } 255 | ] 256 | }, 257 | { 258 | "name": "buy", 259 | "docs": ["Buys tokens from a bonding curve."], 260 | "discriminator": [102, 6, 61, 18, 1, 218, 235, 234], 261 | "accounts": [ 262 | { 263 | "name": "global", 264 | "pda": { 265 | "seeds": [ 266 | { 267 | "kind": "const", 268 | "value": [103, 108, 111, 98, 97, 108] 269 | } 270 | ] 271 | } 272 | }, 273 | { 274 | "name": "fee_recipient", 275 | "writable": true 276 | }, 277 | { 278 | "name": "mint" 279 | }, 280 | { 281 | "name": "bonding_curve", 282 | "writable": true, 283 | "pda": { 284 | "seeds": [ 285 | { 286 | "kind": "const", 287 | "value": [ 288 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 289 | ] 290 | }, 291 | { 292 | "kind": "account", 293 | "path": "mint" 294 | } 295 | ] 296 | } 297 | }, 298 | { 299 | "name": "associated_bonding_curve", 300 | "writable": true, 301 | "pda": { 302 | "seeds": [ 303 | { 304 | "kind": "account", 305 | "path": "bonding_curve" 306 | }, 307 | { 308 | "kind": "const", 309 | "value": [ 310 | 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, 311 | 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, 312 | 245, 133, 126, 255, 0, 169 313 | ] 314 | }, 315 | { 316 | "kind": "account", 317 | "path": "mint" 318 | } 319 | ], 320 | "program": { 321 | "kind": "const", 322 | "value": [ 323 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 324 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 325 | 219, 233, 248, 89 326 | ] 327 | } 328 | } 329 | }, 330 | { 331 | "name": "associated_user", 332 | "writable": true 333 | }, 334 | { 335 | "name": "user", 336 | "writable": true, 337 | "signer": true 338 | }, 339 | { 340 | "name": "system_program", 341 | "address": "11111111111111111111111111111111" 342 | }, 343 | { 344 | "name": "token_program", 345 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 346 | }, 347 | { 348 | "name": "creator_vault", 349 | "writable": true, 350 | "pda": { 351 | "seeds": [ 352 | { 353 | "kind": "const", 354 | "value": [ 355 | 99, 114, 101, 97, 116, 111, 114, 45, 118, 97, 117, 108, 116 356 | ] 357 | }, 358 | { 359 | "kind": "account", 360 | "path": "bonding_curve.creator", 361 | "account": "BondingCurve" 362 | } 363 | ] 364 | } 365 | }, 366 | { 367 | "name": "event_authority", 368 | "pda": { 369 | "seeds": [ 370 | { 371 | "kind": "const", 372 | "value": [ 373 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 374 | 114, 105, 116, 121 375 | ] 376 | } 377 | ] 378 | } 379 | }, 380 | { 381 | "name": "program" 382 | }, 383 | { 384 | "name": "global_volume_accumulator", 385 | "writable": true, 386 | "pda": { 387 | "seeds": [ 388 | { 389 | "kind": "const", 390 | "value": [ 391 | 103, 108, 111, 98, 97, 108, 95, 118, 111, 108, 117, 109, 101, 392 | 95, 97, 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 393 | ] 394 | } 395 | ] 396 | } 397 | }, 398 | { 399 | "name": "user_volume_accumulator", 400 | "writable": true, 401 | "pda": { 402 | "seeds": [ 403 | { 404 | "kind": "const", 405 | "value": [ 406 | 117, 115, 101, 114, 95, 118, 111, 108, 117, 109, 101, 95, 97, 407 | 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 408 | ] 409 | }, 410 | { 411 | "kind": "account", 412 | "path": "user" 413 | } 414 | ] 415 | } 416 | }, 417 | { 418 | "name": "fee_config", 419 | "pda": { 420 | "seeds": [ 421 | { 422 | "kind": "const", 423 | "value": [102, 101, 101, 95, 99, 111, 110, 102, 105, 103] 424 | }, 425 | { 426 | "kind": "const", 427 | "value": [ 428 | 1, 86, 224, 246, 147, 102, 90, 207, 68, 219, 21, 104, 191, 23, 429 | 91, 170, 81, 137, 203, 151, 245, 210, 255, 59, 101, 93, 43, 430 | 182, 253, 109, 24, 176 431 | ] 432 | } 433 | ], 434 | "program": { 435 | "kind": "account", 436 | "path": "fee_program" 437 | } 438 | } 439 | }, 440 | { 441 | "name": "fee_program", 442 | "address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ" 443 | } 444 | ], 445 | "args": [ 446 | { 447 | "name": "amount", 448 | "type": "u64" 449 | }, 450 | { 451 | "name": "max_sol_cost", 452 | "type": "u64" 453 | } 454 | ] 455 | }, 456 | { 457 | "name": "claim_token_incentives", 458 | "discriminator": [16, 4, 71, 28, 204, 1, 40, 27], 459 | "accounts": [ 460 | { 461 | "name": "user" 462 | }, 463 | { 464 | "name": "user_ata", 465 | "writable": true, 466 | "pda": { 467 | "seeds": [ 468 | { 469 | "kind": "account", 470 | "path": "user" 471 | }, 472 | { 473 | "kind": "account", 474 | "path": "token_program" 475 | }, 476 | { 477 | "kind": "account", 478 | "path": "mint" 479 | } 480 | ], 481 | "program": { 482 | "kind": "const", 483 | "value": [ 484 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 485 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 486 | 219, 233, 248, 89 487 | ] 488 | } 489 | } 490 | }, 491 | { 492 | "name": "global_volume_accumulator", 493 | "pda": { 494 | "seeds": [ 495 | { 496 | "kind": "const", 497 | "value": [ 498 | 103, 108, 111, 98, 97, 108, 95, 118, 111, 108, 117, 109, 101, 499 | 95, 97, 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 500 | ] 501 | } 502 | ] 503 | } 504 | }, 505 | { 506 | "name": "global_incentive_token_account", 507 | "writable": true, 508 | "pda": { 509 | "seeds": [ 510 | { 511 | "kind": "account", 512 | "path": "global_volume_accumulator" 513 | }, 514 | { 515 | "kind": "account", 516 | "path": "token_program" 517 | }, 518 | { 519 | "kind": "account", 520 | "path": "mint" 521 | } 522 | ], 523 | "program": { 524 | "kind": "const", 525 | "value": [ 526 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 527 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 528 | 219, 233, 248, 89 529 | ] 530 | } 531 | } 532 | }, 533 | { 534 | "name": "user_volume_accumulator", 535 | "writable": true, 536 | "pda": { 537 | "seeds": [ 538 | { 539 | "kind": "const", 540 | "value": [ 541 | 117, 115, 101, 114, 95, 118, 111, 108, 117, 109, 101, 95, 97, 542 | 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 543 | ] 544 | }, 545 | { 546 | "kind": "account", 547 | "path": "user" 548 | } 549 | ] 550 | } 551 | }, 552 | { 553 | "name": "mint", 554 | "relations": ["global_volume_accumulator"] 555 | }, 556 | { 557 | "name": "token_program" 558 | }, 559 | { 560 | "name": "system_program", 561 | "address": "11111111111111111111111111111111" 562 | }, 563 | { 564 | "name": "associated_token_program", 565 | "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" 566 | }, 567 | { 568 | "name": "event_authority", 569 | "pda": { 570 | "seeds": [ 571 | { 572 | "kind": "const", 573 | "value": [ 574 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 575 | 114, 105, 116, 121 576 | ] 577 | } 578 | ] 579 | } 580 | }, 581 | { 582 | "name": "program" 583 | }, 584 | { 585 | "name": "payer", 586 | "writable": true, 587 | "signer": true 588 | } 589 | ], 590 | "args": [] 591 | }, 592 | { 593 | "name": "close_user_volume_accumulator", 594 | "discriminator": [249, 69, 164, 218, 150, 103, 84, 138], 595 | "accounts": [ 596 | { 597 | "name": "user", 598 | "writable": true, 599 | "signer": true 600 | }, 601 | { 602 | "name": "user_volume_accumulator", 603 | "writable": true, 604 | "pda": { 605 | "seeds": [ 606 | { 607 | "kind": "const", 608 | "value": [ 609 | 117, 115, 101, 114, 95, 118, 111, 108, 117, 109, 101, 95, 97, 610 | 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 611 | ] 612 | }, 613 | { 614 | "kind": "account", 615 | "path": "user" 616 | } 617 | ] 618 | } 619 | }, 620 | { 621 | "name": "event_authority", 622 | "pda": { 623 | "seeds": [ 624 | { 625 | "kind": "const", 626 | "value": [ 627 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 628 | 114, 105, 116, 121 629 | ] 630 | } 631 | ] 632 | } 633 | }, 634 | { 635 | "name": "program" 636 | } 637 | ], 638 | "args": [] 639 | }, 640 | { 641 | "name": "collect_creator_fee", 642 | "docs": [ 643 | "Collects creator_fee from creator_vault to the coin creator account" 644 | ], 645 | "discriminator": [20, 22, 86, 123, 198, 28, 219, 132], 646 | "accounts": [ 647 | { 648 | "name": "creator", 649 | "writable": true 650 | }, 651 | { 652 | "name": "creator_vault", 653 | "writable": true, 654 | "pda": { 655 | "seeds": [ 656 | { 657 | "kind": "const", 658 | "value": [ 659 | 99, 114, 101, 97, 116, 111, 114, 45, 118, 97, 117, 108, 116 660 | ] 661 | }, 662 | { 663 | "kind": "account", 664 | "path": "creator" 665 | } 666 | ] 667 | } 668 | }, 669 | { 670 | "name": "system_program", 671 | "address": "11111111111111111111111111111111" 672 | }, 673 | { 674 | "name": "event_authority", 675 | "pda": { 676 | "seeds": [ 677 | { 678 | "kind": "const", 679 | "value": [ 680 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 681 | 114, 105, 116, 121 682 | ] 683 | } 684 | ] 685 | } 686 | }, 687 | { 688 | "name": "program" 689 | } 690 | ], 691 | "args": [] 692 | }, 693 | { 694 | "name": "create", 695 | "docs": ["Creates a new coin and bonding curve."], 696 | "discriminator": [24, 30, 200, 40, 5, 28, 7, 119], 697 | "accounts": [ 698 | { 699 | "name": "mint", 700 | "writable": true, 701 | "signer": true 702 | }, 703 | { 704 | "name": "mint_authority", 705 | "pda": { 706 | "seeds": [ 707 | { 708 | "kind": "const", 709 | "value": [ 710 | 109, 105, 110, 116, 45, 97, 117, 116, 104, 111, 114, 105, 116, 711 | 121 712 | ] 713 | } 714 | ] 715 | } 716 | }, 717 | { 718 | "name": "bonding_curve", 719 | "writable": true, 720 | "pda": { 721 | "seeds": [ 722 | { 723 | "kind": "const", 724 | "value": [ 725 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 726 | ] 727 | }, 728 | { 729 | "kind": "account", 730 | "path": "mint" 731 | } 732 | ] 733 | } 734 | }, 735 | { 736 | "name": "associated_bonding_curve", 737 | "writable": true, 738 | "pda": { 739 | "seeds": [ 740 | { 741 | "kind": "account", 742 | "path": "bonding_curve" 743 | }, 744 | { 745 | "kind": "const", 746 | "value": [ 747 | 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, 748 | 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, 749 | 245, 133, 126, 255, 0, 169 750 | ] 751 | }, 752 | { 753 | "kind": "account", 754 | "path": "mint" 755 | } 756 | ], 757 | "program": { 758 | "kind": "const", 759 | "value": [ 760 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 761 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 762 | 219, 233, 248, 89 763 | ] 764 | } 765 | } 766 | }, 767 | { 768 | "name": "global", 769 | "pda": { 770 | "seeds": [ 771 | { 772 | "kind": "const", 773 | "value": [103, 108, 111, 98, 97, 108] 774 | } 775 | ] 776 | } 777 | }, 778 | { 779 | "name": "mpl_token_metadata", 780 | "address": "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" 781 | }, 782 | { 783 | "name": "metadata", 784 | "writable": true, 785 | "pda": { 786 | "seeds": [ 787 | { 788 | "kind": "const", 789 | "value": [109, 101, 116, 97, 100, 97, 116, 97] 790 | }, 791 | { 792 | "kind": "const", 793 | "value": [ 794 | 11, 112, 101, 177, 227, 209, 124, 69, 56, 157, 82, 127, 107, 795 | 4, 195, 205, 88, 184, 108, 115, 26, 160, 253, 181, 73, 182, 796 | 209, 188, 3, 248, 41, 70 797 | ] 798 | }, 799 | { 800 | "kind": "account", 801 | "path": "mint" 802 | } 803 | ], 804 | "program": { 805 | "kind": "account", 806 | "path": "mpl_token_metadata" 807 | } 808 | } 809 | }, 810 | { 811 | "name": "user", 812 | "writable": true, 813 | "signer": true 814 | }, 815 | { 816 | "name": "system_program", 817 | "address": "11111111111111111111111111111111" 818 | }, 819 | { 820 | "name": "token_program", 821 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 822 | }, 823 | { 824 | "name": "associated_token_program", 825 | "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" 826 | }, 827 | { 828 | "name": "rent", 829 | "address": "SysvarRent111111111111111111111111111111111" 830 | }, 831 | { 832 | "name": "event_authority", 833 | "pda": { 834 | "seeds": [ 835 | { 836 | "kind": "const", 837 | "value": [ 838 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 839 | 114, 105, 116, 121 840 | ] 841 | } 842 | ] 843 | } 844 | }, 845 | { 846 | "name": "program" 847 | } 848 | ], 849 | "args": [ 850 | { 851 | "name": "name", 852 | "type": "string" 853 | }, 854 | { 855 | "name": "symbol", 856 | "type": "string" 857 | }, 858 | { 859 | "name": "uri", 860 | "type": "string" 861 | }, 862 | { 863 | "name": "creator", 864 | "type": "pubkey" 865 | } 866 | ] 867 | }, 868 | { 869 | "name": "extend_account", 870 | "docs": ["Extends the size of program-owned accounts"], 871 | "discriminator": [234, 102, 194, 203, 150, 72, 62, 229], 872 | "accounts": [ 873 | { 874 | "name": "account", 875 | "writable": true 876 | }, 877 | { 878 | "name": "user", 879 | "signer": true 880 | }, 881 | { 882 | "name": "system_program", 883 | "address": "11111111111111111111111111111111" 884 | }, 885 | { 886 | "name": "event_authority", 887 | "pda": { 888 | "seeds": [ 889 | { 890 | "kind": "const", 891 | "value": [ 892 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 893 | 114, 105, 116, 121 894 | ] 895 | } 896 | ] 897 | } 898 | }, 899 | { 900 | "name": "program" 901 | } 902 | ], 903 | "args": [] 904 | }, 905 | { 906 | "name": "init_user_volume_accumulator", 907 | "discriminator": [94, 6, 202, 115, 255, 96, 232, 183], 908 | "accounts": [ 909 | { 910 | "name": "payer", 911 | "writable": true, 912 | "signer": true 913 | }, 914 | { 915 | "name": "user" 916 | }, 917 | { 918 | "name": "user_volume_accumulator", 919 | "writable": true, 920 | "pda": { 921 | "seeds": [ 922 | { 923 | "kind": "const", 924 | "value": [ 925 | 117, 115, 101, 114, 95, 118, 111, 108, 117, 109, 101, 95, 97, 926 | 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 927 | ] 928 | }, 929 | { 930 | "kind": "account", 931 | "path": "user" 932 | } 933 | ] 934 | } 935 | }, 936 | { 937 | "name": "system_program", 938 | "address": "11111111111111111111111111111111" 939 | }, 940 | { 941 | "name": "event_authority", 942 | "pda": { 943 | "seeds": [ 944 | { 945 | "kind": "const", 946 | "value": [ 947 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 948 | 114, 105, 116, 121 949 | ] 950 | } 951 | ] 952 | } 953 | }, 954 | { 955 | "name": "program" 956 | } 957 | ], 958 | "args": [] 959 | }, 960 | { 961 | "name": "initialize", 962 | "docs": ["Creates the global state."], 963 | "discriminator": [175, 175, 109, 31, 13, 152, 155, 237], 964 | "accounts": [ 965 | { 966 | "name": "global", 967 | "writable": true, 968 | "pda": { 969 | "seeds": [ 970 | { 971 | "kind": "const", 972 | "value": [103, 108, 111, 98, 97, 108] 973 | } 974 | ] 975 | } 976 | }, 977 | { 978 | "name": "user", 979 | "writable": true, 980 | "signer": true 981 | }, 982 | { 983 | "name": "system_program", 984 | "address": "11111111111111111111111111111111" 985 | } 986 | ], 987 | "args": [] 988 | }, 989 | { 990 | "name": "migrate", 991 | "docs": [ 992 | "Migrates liquidity to pump_amm if the bonding curve is complete" 993 | ], 994 | "discriminator": [155, 234, 231, 146, 236, 158, 162, 30], 995 | "accounts": [ 996 | { 997 | "name": "global", 998 | "pda": { 999 | "seeds": [ 1000 | { 1001 | "kind": "const", 1002 | "value": [103, 108, 111, 98, 97, 108] 1003 | } 1004 | ] 1005 | } 1006 | }, 1007 | { 1008 | "name": "withdraw_authority", 1009 | "writable": true, 1010 | "relations": ["global"] 1011 | }, 1012 | { 1013 | "name": "mint" 1014 | }, 1015 | { 1016 | "name": "bonding_curve", 1017 | "writable": true, 1018 | "pda": { 1019 | "seeds": [ 1020 | { 1021 | "kind": "const", 1022 | "value": [ 1023 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 1024 | ] 1025 | }, 1026 | { 1027 | "kind": "account", 1028 | "path": "mint" 1029 | } 1030 | ] 1031 | } 1032 | }, 1033 | { 1034 | "name": "associated_bonding_curve", 1035 | "writable": true, 1036 | "pda": { 1037 | "seeds": [ 1038 | { 1039 | "kind": "account", 1040 | "path": "bonding_curve" 1041 | }, 1042 | { 1043 | "kind": "const", 1044 | "value": [ 1045 | 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, 1046 | 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, 1047 | 245, 133, 126, 255, 0, 169 1048 | ] 1049 | }, 1050 | { 1051 | "kind": "account", 1052 | "path": "mint" 1053 | } 1054 | ], 1055 | "program": { 1056 | "kind": "const", 1057 | "value": [ 1058 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 1059 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 1060 | 219, 233, 248, 89 1061 | ] 1062 | } 1063 | } 1064 | }, 1065 | { 1066 | "name": "user", 1067 | "signer": true 1068 | }, 1069 | { 1070 | "name": "system_program", 1071 | "address": "11111111111111111111111111111111" 1072 | }, 1073 | { 1074 | "name": "token_program", 1075 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 1076 | }, 1077 | { 1078 | "name": "pump_amm", 1079 | "address": "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA" 1080 | }, 1081 | { 1082 | "name": "pool", 1083 | "writable": true, 1084 | "pda": { 1085 | "seeds": [ 1086 | { 1087 | "kind": "const", 1088 | "value": [112, 111, 111, 108] 1089 | }, 1090 | { 1091 | "kind": "const", 1092 | "value": [0, 0] 1093 | }, 1094 | { 1095 | "kind": "account", 1096 | "path": "pool_authority" 1097 | }, 1098 | { 1099 | "kind": "account", 1100 | "path": "mint" 1101 | }, 1102 | { 1103 | "kind": "account", 1104 | "path": "wsol_mint" 1105 | } 1106 | ], 1107 | "program": { 1108 | "kind": "account", 1109 | "path": "pump_amm" 1110 | } 1111 | } 1112 | }, 1113 | { 1114 | "name": "pool_authority", 1115 | "writable": true, 1116 | "pda": { 1117 | "seeds": [ 1118 | { 1119 | "kind": "const", 1120 | "value": [ 1121 | 112, 111, 111, 108, 45, 97, 117, 116, 104, 111, 114, 105, 116, 1122 | 121 1123 | ] 1124 | }, 1125 | { 1126 | "kind": "account", 1127 | "path": "mint" 1128 | } 1129 | ] 1130 | } 1131 | }, 1132 | { 1133 | "name": "pool_authority_mint_account", 1134 | "writable": true, 1135 | "pda": { 1136 | "seeds": [ 1137 | { 1138 | "kind": "account", 1139 | "path": "pool_authority" 1140 | }, 1141 | { 1142 | "kind": "account", 1143 | "path": "token_program" 1144 | }, 1145 | { 1146 | "kind": "account", 1147 | "path": "mint" 1148 | } 1149 | ], 1150 | "program": { 1151 | "kind": "account", 1152 | "path": "associated_token_program" 1153 | } 1154 | } 1155 | }, 1156 | { 1157 | "name": "pool_authority_wsol_account", 1158 | "writable": true, 1159 | "pda": { 1160 | "seeds": [ 1161 | { 1162 | "kind": "account", 1163 | "path": "pool_authority" 1164 | }, 1165 | { 1166 | "kind": "account", 1167 | "path": "token_program" 1168 | }, 1169 | { 1170 | "kind": "account", 1171 | "path": "wsol_mint" 1172 | } 1173 | ], 1174 | "program": { 1175 | "kind": "account", 1176 | "path": "associated_token_program" 1177 | } 1178 | } 1179 | }, 1180 | { 1181 | "name": "amm_global_config", 1182 | "pda": { 1183 | "seeds": [ 1184 | { 1185 | "kind": "const", 1186 | "value": [ 1187 | 103, 108, 111, 98, 97, 108, 95, 99, 111, 110, 102, 105, 103 1188 | ] 1189 | } 1190 | ], 1191 | "program": { 1192 | "kind": "account", 1193 | "path": "pump_amm" 1194 | } 1195 | } 1196 | }, 1197 | { 1198 | "name": "wsol_mint", 1199 | "address": "So11111111111111111111111111111111111111112" 1200 | }, 1201 | { 1202 | "name": "lp_mint", 1203 | "writable": true, 1204 | "pda": { 1205 | "seeds": [ 1206 | { 1207 | "kind": "const", 1208 | "value": [ 1209 | 112, 111, 111, 108, 95, 108, 112, 95, 109, 105, 110, 116 1210 | ] 1211 | }, 1212 | { 1213 | "kind": "account", 1214 | "path": "pool" 1215 | } 1216 | ], 1217 | "program": { 1218 | "kind": "account", 1219 | "path": "pump_amm" 1220 | } 1221 | } 1222 | }, 1223 | { 1224 | "name": "user_pool_token_account", 1225 | "writable": true, 1226 | "pda": { 1227 | "seeds": [ 1228 | { 1229 | "kind": "account", 1230 | "path": "pool_authority" 1231 | }, 1232 | { 1233 | "kind": "account", 1234 | "path": "token_2022_program" 1235 | }, 1236 | { 1237 | "kind": "account", 1238 | "path": "lp_mint" 1239 | } 1240 | ], 1241 | "program": { 1242 | "kind": "account", 1243 | "path": "associated_token_program" 1244 | } 1245 | } 1246 | }, 1247 | { 1248 | "name": "pool_base_token_account", 1249 | "writable": true, 1250 | "pda": { 1251 | "seeds": [ 1252 | { 1253 | "kind": "account", 1254 | "path": "pool" 1255 | }, 1256 | { 1257 | "kind": "account", 1258 | "path": "token_program" 1259 | }, 1260 | { 1261 | "kind": "account", 1262 | "path": "mint" 1263 | } 1264 | ], 1265 | "program": { 1266 | "kind": "account", 1267 | "path": "associated_token_program" 1268 | } 1269 | } 1270 | }, 1271 | { 1272 | "name": "pool_quote_token_account", 1273 | "writable": true, 1274 | "pda": { 1275 | "seeds": [ 1276 | { 1277 | "kind": "account", 1278 | "path": "pool" 1279 | }, 1280 | { 1281 | "kind": "account", 1282 | "path": "token_program" 1283 | }, 1284 | { 1285 | "kind": "account", 1286 | "path": "wsol_mint" 1287 | } 1288 | ], 1289 | "program": { 1290 | "kind": "account", 1291 | "path": "associated_token_program" 1292 | } 1293 | } 1294 | }, 1295 | { 1296 | "name": "token_2022_program", 1297 | "address": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" 1298 | }, 1299 | { 1300 | "name": "associated_token_program", 1301 | "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" 1302 | }, 1303 | { 1304 | "name": "pump_amm_event_authority", 1305 | "pda": { 1306 | "seeds": [ 1307 | { 1308 | "kind": "const", 1309 | "value": [ 1310 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1311 | 114, 105, 116, 121 1312 | ] 1313 | } 1314 | ], 1315 | "program": { 1316 | "kind": "account", 1317 | "path": "pump_amm" 1318 | } 1319 | } 1320 | }, 1321 | { 1322 | "name": "event_authority", 1323 | "pda": { 1324 | "seeds": [ 1325 | { 1326 | "kind": "const", 1327 | "value": [ 1328 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1329 | 114, 105, 116, 121 1330 | ] 1331 | } 1332 | ] 1333 | } 1334 | }, 1335 | { 1336 | "name": "program" 1337 | } 1338 | ], 1339 | "args": [] 1340 | }, 1341 | { 1342 | "name": "sell", 1343 | "docs": ["Sells tokens into a bonding curve."], 1344 | "discriminator": [51, 230, 133, 164, 1, 127, 131, 173], 1345 | "accounts": [ 1346 | { 1347 | "name": "global", 1348 | "pda": { 1349 | "seeds": [ 1350 | { 1351 | "kind": "const", 1352 | "value": [103, 108, 111, 98, 97, 108] 1353 | } 1354 | ] 1355 | } 1356 | }, 1357 | { 1358 | "name": "fee_recipient", 1359 | "writable": true 1360 | }, 1361 | { 1362 | "name": "mint" 1363 | }, 1364 | { 1365 | "name": "bonding_curve", 1366 | "writable": true, 1367 | "pda": { 1368 | "seeds": [ 1369 | { 1370 | "kind": "const", 1371 | "value": [ 1372 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 1373 | ] 1374 | }, 1375 | { 1376 | "kind": "account", 1377 | "path": "mint" 1378 | } 1379 | ] 1380 | } 1381 | }, 1382 | { 1383 | "name": "associated_bonding_curve", 1384 | "writable": true, 1385 | "pda": { 1386 | "seeds": [ 1387 | { 1388 | "kind": "account", 1389 | "path": "bonding_curve" 1390 | }, 1391 | { 1392 | "kind": "const", 1393 | "value": [ 1394 | 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, 1395 | 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, 1396 | 245, 133, 126, 255, 0, 169 1397 | ] 1398 | }, 1399 | { 1400 | "kind": "account", 1401 | "path": "mint" 1402 | } 1403 | ], 1404 | "program": { 1405 | "kind": "const", 1406 | "value": [ 1407 | 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 1408 | 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, 1409 | 219, 233, 248, 89 1410 | ] 1411 | } 1412 | } 1413 | }, 1414 | { 1415 | "name": "associated_user", 1416 | "writable": true 1417 | }, 1418 | { 1419 | "name": "user", 1420 | "writable": true, 1421 | "signer": true 1422 | }, 1423 | { 1424 | "name": "system_program", 1425 | "address": "11111111111111111111111111111111" 1426 | }, 1427 | { 1428 | "name": "creator_vault", 1429 | "writable": true, 1430 | "pda": { 1431 | "seeds": [ 1432 | { 1433 | "kind": "const", 1434 | "value": [ 1435 | 99, 114, 101, 97, 116, 111, 114, 45, 118, 97, 117, 108, 116 1436 | ] 1437 | }, 1438 | { 1439 | "kind": "account", 1440 | "path": "bonding_curve.creator", 1441 | "account": "BondingCurve" 1442 | } 1443 | ] 1444 | } 1445 | }, 1446 | { 1447 | "name": "token_program", 1448 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 1449 | }, 1450 | { 1451 | "name": "event_authority", 1452 | "pda": { 1453 | "seeds": [ 1454 | { 1455 | "kind": "const", 1456 | "value": [ 1457 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1458 | 114, 105, 116, 121 1459 | ] 1460 | } 1461 | ] 1462 | } 1463 | }, 1464 | { 1465 | "name": "program", 1466 | "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" 1467 | }, 1468 | { 1469 | "name": "fee_config", 1470 | "pda": { 1471 | "seeds": [ 1472 | { 1473 | "kind": "const", 1474 | "value": [102, 101, 101, 95, 99, 111, 110, 102, 105, 103] 1475 | }, 1476 | { 1477 | "kind": "const", 1478 | "value": [ 1479 | 1, 86, 224, 246, 147, 102, 90, 207, 68, 219, 21, 104, 191, 23, 1480 | 91, 170, 81, 137, 203, 151, 245, 210, 255, 59, 101, 93, 43, 1481 | 182, 253, 109, 24, 176 1482 | ] 1483 | } 1484 | ], 1485 | "program": { 1486 | "kind": "account", 1487 | "path": "fee_program" 1488 | } 1489 | } 1490 | }, 1491 | { 1492 | "name": "fee_program", 1493 | "address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ" 1494 | } 1495 | ], 1496 | "args": [ 1497 | { 1498 | "name": "amount", 1499 | "type": "u64" 1500 | }, 1501 | { 1502 | "name": "min_sol_output", 1503 | "type": "u64" 1504 | } 1505 | ] 1506 | }, 1507 | { 1508 | "name": "set_creator", 1509 | "docs": [ 1510 | "Allows Global::set_creator_authority to set the bonding curve creator from Metaplex metadata or input argument" 1511 | ], 1512 | "discriminator": [254, 148, 255, 112, 207, 142, 170, 165], 1513 | "accounts": [ 1514 | { 1515 | "name": "set_creator_authority", 1516 | "signer": true, 1517 | "relations": ["global"] 1518 | }, 1519 | { 1520 | "name": "global", 1521 | "pda": { 1522 | "seeds": [ 1523 | { 1524 | "kind": "const", 1525 | "value": [103, 108, 111, 98, 97, 108] 1526 | } 1527 | ] 1528 | } 1529 | }, 1530 | { 1531 | "name": "mint" 1532 | }, 1533 | { 1534 | "name": "metadata", 1535 | "pda": { 1536 | "seeds": [ 1537 | { 1538 | "kind": "const", 1539 | "value": [109, 101, 116, 97, 100, 97, 116, 97] 1540 | }, 1541 | { 1542 | "kind": "const", 1543 | "value": [ 1544 | 11, 112, 101, 177, 227, 209, 124, 69, 56, 157, 82, 127, 107, 1545 | 4, 195, 205, 88, 184, 108, 115, 26, 160, 253, 181, 73, 182, 1546 | 209, 188, 3, 248, 41, 70 1547 | ] 1548 | }, 1549 | { 1550 | "kind": "account", 1551 | "path": "mint" 1552 | } 1553 | ], 1554 | "program": { 1555 | "kind": "const", 1556 | "value": [ 1557 | 11, 112, 101, 177, 227, 209, 124, 69, 56, 157, 82, 127, 107, 4, 1558 | 195, 205, 88, 184, 108, 115, 26, 160, 253, 181, 73, 182, 209, 1559 | 188, 3, 248, 41, 70 1560 | ] 1561 | } 1562 | } 1563 | }, 1564 | { 1565 | "name": "bonding_curve", 1566 | "writable": true, 1567 | "pda": { 1568 | "seeds": [ 1569 | { 1570 | "kind": "const", 1571 | "value": [ 1572 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 1573 | ] 1574 | }, 1575 | { 1576 | "kind": "account", 1577 | "path": "mint" 1578 | } 1579 | ] 1580 | } 1581 | }, 1582 | { 1583 | "name": "event_authority", 1584 | "pda": { 1585 | "seeds": [ 1586 | { 1587 | "kind": "const", 1588 | "value": [ 1589 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1590 | 114, 105, 116, 121 1591 | ] 1592 | } 1593 | ] 1594 | } 1595 | }, 1596 | { 1597 | "name": "program" 1598 | } 1599 | ], 1600 | "args": [ 1601 | { 1602 | "name": "creator", 1603 | "type": "pubkey" 1604 | } 1605 | ] 1606 | }, 1607 | { 1608 | "name": "set_metaplex_creator", 1609 | "docs": [ 1610 | "Syncs the bonding curve creator with the Metaplex metadata creator if it exists" 1611 | ], 1612 | "discriminator": [138, 96, 174, 217, 48, 85, 197, 246], 1613 | "accounts": [ 1614 | { 1615 | "name": "mint" 1616 | }, 1617 | { 1618 | "name": "metadata", 1619 | "pda": { 1620 | "seeds": [ 1621 | { 1622 | "kind": "const", 1623 | "value": [109, 101, 116, 97, 100, 97, 116, 97] 1624 | }, 1625 | { 1626 | "kind": "const", 1627 | "value": [ 1628 | 11, 112, 101, 177, 227, 209, 124, 69, 56, 157, 82, 127, 107, 1629 | 4, 195, 205, 88, 184, 108, 115, 26, 160, 253, 181, 73, 182, 1630 | 209, 188, 3, 248, 41, 70 1631 | ] 1632 | }, 1633 | { 1634 | "kind": "account", 1635 | "path": "mint" 1636 | } 1637 | ], 1638 | "program": { 1639 | "kind": "const", 1640 | "value": [ 1641 | 11, 112, 101, 177, 227, 209, 124, 69, 56, 157, 82, 127, 107, 4, 1642 | 195, 205, 88, 184, 108, 115, 26, 160, 253, 181, 73, 182, 209, 1643 | 188, 3, 248, 41, 70 1644 | ] 1645 | } 1646 | } 1647 | }, 1648 | { 1649 | "name": "bonding_curve", 1650 | "writable": true, 1651 | "pda": { 1652 | "seeds": [ 1653 | { 1654 | "kind": "const", 1655 | "value": [ 1656 | 98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101 1657 | ] 1658 | }, 1659 | { 1660 | "kind": "account", 1661 | "path": "mint" 1662 | } 1663 | ] 1664 | } 1665 | }, 1666 | { 1667 | "name": "event_authority", 1668 | "pda": { 1669 | "seeds": [ 1670 | { 1671 | "kind": "const", 1672 | "value": [ 1673 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1674 | 114, 105, 116, 121 1675 | ] 1676 | } 1677 | ] 1678 | } 1679 | }, 1680 | { 1681 | "name": "program" 1682 | } 1683 | ], 1684 | "args": [] 1685 | }, 1686 | { 1687 | "name": "set_params", 1688 | "docs": ["Sets the global state parameters."], 1689 | "discriminator": [27, 234, 178, 52, 147, 2, 187, 141], 1690 | "accounts": [ 1691 | { 1692 | "name": "global", 1693 | "writable": true, 1694 | "pda": { 1695 | "seeds": [ 1696 | { 1697 | "kind": "const", 1698 | "value": [103, 108, 111, 98, 97, 108] 1699 | } 1700 | ] 1701 | } 1702 | }, 1703 | { 1704 | "name": "authority", 1705 | "writable": true, 1706 | "signer": true, 1707 | "relations": ["global"] 1708 | }, 1709 | { 1710 | "name": "event_authority", 1711 | "pda": { 1712 | "seeds": [ 1713 | { 1714 | "kind": "const", 1715 | "value": [ 1716 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1717 | 114, 105, 116, 121 1718 | ] 1719 | } 1720 | ] 1721 | } 1722 | }, 1723 | { 1724 | "name": "program" 1725 | } 1726 | ], 1727 | "args": [ 1728 | { 1729 | "name": "initial_virtual_token_reserves", 1730 | "type": "u64" 1731 | }, 1732 | { 1733 | "name": "initial_virtual_sol_reserves", 1734 | "type": "u64" 1735 | }, 1736 | { 1737 | "name": "initial_real_token_reserves", 1738 | "type": "u64" 1739 | }, 1740 | { 1741 | "name": "token_total_supply", 1742 | "type": "u64" 1743 | }, 1744 | { 1745 | "name": "fee_basis_points", 1746 | "type": "u64" 1747 | }, 1748 | { 1749 | "name": "withdraw_authority", 1750 | "type": "pubkey" 1751 | }, 1752 | { 1753 | "name": "enable_migrate", 1754 | "type": "bool" 1755 | }, 1756 | { 1757 | "name": "pool_migration_fee", 1758 | "type": "u64" 1759 | }, 1760 | { 1761 | "name": "creator_fee_basis_points", 1762 | "type": "u64" 1763 | }, 1764 | { 1765 | "name": "set_creator_authority", 1766 | "type": "pubkey" 1767 | }, 1768 | { 1769 | "name": "admin_set_creator_authority", 1770 | "type": "pubkey" 1771 | } 1772 | ] 1773 | }, 1774 | { 1775 | "name": "sync_user_volume_accumulator", 1776 | "discriminator": [86, 31, 192, 87, 163, 87, 79, 238], 1777 | "accounts": [ 1778 | { 1779 | "name": "user" 1780 | }, 1781 | { 1782 | "name": "global_volume_accumulator", 1783 | "pda": { 1784 | "seeds": [ 1785 | { 1786 | "kind": "const", 1787 | "value": [ 1788 | 103, 108, 111, 98, 97, 108, 95, 118, 111, 108, 117, 109, 101, 1789 | 95, 97, 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 1790 | ] 1791 | } 1792 | ] 1793 | } 1794 | }, 1795 | { 1796 | "name": "user_volume_accumulator", 1797 | "writable": true, 1798 | "pda": { 1799 | "seeds": [ 1800 | { 1801 | "kind": "const", 1802 | "value": [ 1803 | 117, 115, 101, 114, 95, 118, 111, 108, 117, 109, 101, 95, 97, 1804 | 99, 99, 117, 109, 117, 108, 97, 116, 111, 114 1805 | ] 1806 | }, 1807 | { 1808 | "kind": "account", 1809 | "path": "user" 1810 | } 1811 | ] 1812 | } 1813 | }, 1814 | { 1815 | "name": "event_authority", 1816 | "pda": { 1817 | "seeds": [ 1818 | { 1819 | "kind": "const", 1820 | "value": [ 1821 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1822 | 114, 105, 116, 121 1823 | ] 1824 | } 1825 | ] 1826 | } 1827 | }, 1828 | { 1829 | "name": "program" 1830 | } 1831 | ], 1832 | "args": [] 1833 | }, 1834 | { 1835 | "name": "update_global_authority", 1836 | "discriminator": [227, 181, 74, 196, 208, 21, 97, 213], 1837 | "accounts": [ 1838 | { 1839 | "name": "global", 1840 | "writable": true, 1841 | "pda": { 1842 | "seeds": [ 1843 | { 1844 | "kind": "const", 1845 | "value": [103, 108, 111, 98, 97, 108] 1846 | } 1847 | ] 1848 | } 1849 | }, 1850 | { 1851 | "name": "authority", 1852 | "signer": true, 1853 | "relations": ["global"] 1854 | }, 1855 | { 1856 | "name": "new_authority" 1857 | }, 1858 | { 1859 | "name": "event_authority", 1860 | "pda": { 1861 | "seeds": [ 1862 | { 1863 | "kind": "const", 1864 | "value": [ 1865 | 95, 95, 101, 118, 101, 110, 116, 95, 97, 117, 116, 104, 111, 1866 | 114, 105, 116, 121 1867 | ] 1868 | } 1869 | ] 1870 | } 1871 | }, 1872 | { 1873 | "name": "program" 1874 | } 1875 | ], 1876 | "args": [] 1877 | } 1878 | ], 1879 | "accounts": [ 1880 | { 1881 | "name": "BondingCurve", 1882 | "discriminator": [23, 183, 248, 55, 96, 216, 172, 96] 1883 | }, 1884 | { 1885 | "name": "FeeConfig", 1886 | "discriminator": [143, 52, 146, 187, 219, 123, 76, 155] 1887 | }, 1888 | { 1889 | "name": "Global", 1890 | "discriminator": [167, 232, 232, 177, 200, 108, 114, 127] 1891 | }, 1892 | { 1893 | "name": "GlobalVolumeAccumulator", 1894 | "discriminator": [202, 42, 246, 43, 142, 190, 30, 255] 1895 | }, 1896 | { 1897 | "name": "UserVolumeAccumulator", 1898 | "discriminator": [86, 255, 112, 14, 102, 53, 154, 250] 1899 | } 1900 | ], 1901 | "events": [ 1902 | { 1903 | "name": "AdminSetCreatorEvent", 1904 | "discriminator": [64, 69, 192, 104, 29, 30, 25, 107] 1905 | }, 1906 | { 1907 | "name": "AdminSetIdlAuthorityEvent", 1908 | "discriminator": [245, 59, 70, 34, 75, 185, 109, 92] 1909 | }, 1910 | { 1911 | "name": "AdminUpdateTokenIncentivesEvent", 1912 | "discriminator": [147, 250, 108, 120, 247, 29, 67, 222] 1913 | }, 1914 | { 1915 | "name": "ClaimTokenIncentivesEvent", 1916 | "discriminator": [79, 172, 246, 49, 205, 91, 206, 232] 1917 | }, 1918 | { 1919 | "name": "CloseUserVolumeAccumulatorEvent", 1920 | "discriminator": [146, 159, 189, 172, 146, 88, 56, 244] 1921 | }, 1922 | { 1923 | "name": "CollectCreatorFeeEvent", 1924 | "discriminator": [122, 2, 127, 1, 14, 191, 12, 175] 1925 | }, 1926 | { 1927 | "name": "CompleteEvent", 1928 | "discriminator": [95, 114, 97, 156, 212, 46, 152, 8] 1929 | }, 1930 | { 1931 | "name": "CompletePumpAmmMigrationEvent", 1932 | "discriminator": [189, 233, 93, 185, 92, 148, 234, 148] 1933 | }, 1934 | { 1935 | "name": "CreateEvent", 1936 | "discriminator": [27, 114, 169, 77, 222, 235, 99, 118] 1937 | }, 1938 | { 1939 | "name": "ExtendAccountEvent", 1940 | "discriminator": [97, 97, 215, 144, 93, 146, 22, 124] 1941 | }, 1942 | { 1943 | "name": "InitUserVolumeAccumulatorEvent", 1944 | "discriminator": [134, 36, 13, 72, 232, 101, 130, 216] 1945 | }, 1946 | { 1947 | "name": "SetCreatorEvent", 1948 | "discriminator": [237, 52, 123, 37, 245, 251, 72, 210] 1949 | }, 1950 | { 1951 | "name": "SetMetaplexCreatorEvent", 1952 | "discriminator": [142, 203, 6, 32, 127, 105, 191, 162] 1953 | }, 1954 | { 1955 | "name": "SetParamsEvent", 1956 | "discriminator": [223, 195, 159, 246, 62, 48, 143, 131] 1957 | }, 1958 | { 1959 | "name": "SyncUserVolumeAccumulatorEvent", 1960 | "discriminator": [197, 122, 167, 124, 116, 81, 91, 255] 1961 | }, 1962 | { 1963 | "name": "TradeEvent", 1964 | "discriminator": [189, 219, 127, 211, 78, 230, 97, 238] 1965 | }, 1966 | { 1967 | "name": "UpdateGlobalAuthorityEvent", 1968 | "discriminator": [182, 195, 137, 42, 35, 206, 207, 247] 1969 | } 1970 | ], 1971 | "errors": [ 1972 | { 1973 | "code": 6000, 1974 | "name": "NotAuthorized", 1975 | "msg": "The given account is not authorized to execute this instruction." 1976 | }, 1977 | { 1978 | "code": 6001, 1979 | "name": "AlreadyInitialized", 1980 | "msg": "The program is already initialized." 1981 | }, 1982 | { 1983 | "code": 6002, 1984 | "name": "TooMuchSolRequired", 1985 | "msg": "slippage: Too much SOL required to buy the given amount of tokens." 1986 | }, 1987 | { 1988 | "code": 6003, 1989 | "name": "TooLittleSolReceived", 1990 | "msg": "slippage: Too little SOL received to sell the given amount of tokens." 1991 | }, 1992 | { 1993 | "code": 6004, 1994 | "name": "MintDoesNotMatchBondingCurve", 1995 | "msg": "The mint does not match the bonding curve." 1996 | }, 1997 | { 1998 | "code": 6005, 1999 | "name": "BondingCurveComplete", 2000 | "msg": "The bonding curve has completed and liquidity migrated to raydium." 2001 | }, 2002 | { 2003 | "code": 6006, 2004 | "name": "BondingCurveNotComplete", 2005 | "msg": "The bonding curve has not completed." 2006 | }, 2007 | { 2008 | "code": 6007, 2009 | "name": "NotInitialized", 2010 | "msg": "The program is not initialized." 2011 | }, 2012 | { 2013 | "code": 6008, 2014 | "name": "WithdrawTooFrequent", 2015 | "msg": "Withdraw too frequent" 2016 | }, 2017 | { 2018 | "code": 6009, 2019 | "name": "NewSizeShouldBeGreaterThanCurrentSize", 2020 | "msg": "new_size should be > current_size" 2021 | }, 2022 | { 2023 | "code": 6010, 2024 | "name": "AccountTypeNotSupported", 2025 | "msg": "Account type not supported" 2026 | }, 2027 | { 2028 | "code": 6011, 2029 | "name": "InitialRealTokenReservesShouldBeLessThanTokenTotalSupply", 2030 | "msg": "initial_real_token_reserves should be less than token_total_supply" 2031 | }, 2032 | { 2033 | "code": 6012, 2034 | "name": "InitialVirtualTokenReservesShouldBeGreaterThanInitialRealTokenReserves", 2035 | "msg": "initial_virtual_token_reserves should be greater than initial_real_token_reserves" 2036 | }, 2037 | { 2038 | "code": 6013, 2039 | "name": "FeeBasisPointsGreaterThanMaximum", 2040 | "msg": "fee_basis_points greater than maximum" 2041 | }, 2042 | { 2043 | "code": 6014, 2044 | "name": "AllZerosWithdrawAuthority", 2045 | "msg": "Withdraw authority cannot be set to System Program ID" 2046 | }, 2047 | { 2048 | "code": 6015, 2049 | "name": "PoolMigrationFeeShouldBeLessThanFinalRealSolReserves", 2050 | "msg": "pool_migration_fee should be less than final_real_sol_reserves" 2051 | }, 2052 | { 2053 | "code": 6016, 2054 | "name": "PoolMigrationFeeShouldBeGreaterThanCreatorFeePlusMaxMigrateFees", 2055 | "msg": "pool_migration_fee should be greater than creator_fee + MAX_MIGRATE_FEES" 2056 | }, 2057 | { 2058 | "code": 6017, 2059 | "name": "DisabledWithdraw", 2060 | "msg": "Migrate instruction is disabled" 2061 | }, 2062 | { 2063 | "code": 6018, 2064 | "name": "DisabledMigrate", 2065 | "msg": "Migrate instruction is disabled" 2066 | }, 2067 | { 2068 | "code": 6019, 2069 | "name": "InvalidCreator", 2070 | "msg": "Invalid creator pubkey" 2071 | }, 2072 | { 2073 | "code": 6020, 2074 | "name": "BuyZeroAmount", 2075 | "msg": "Buy zero amount" 2076 | }, 2077 | { 2078 | "code": 6021, 2079 | "name": "NotEnoughTokensToBuy", 2080 | "msg": "Not enough tokens to buy" 2081 | }, 2082 | { 2083 | "code": 6022, 2084 | "name": "SellZeroAmount", 2085 | "msg": "Sell zero amount" 2086 | }, 2087 | { 2088 | "code": 6023, 2089 | "name": "NotEnoughTokensToSell", 2090 | "msg": "Not enough tokens to sell" 2091 | }, 2092 | { 2093 | "code": 6024, 2094 | "name": "Overflow", 2095 | "msg": "Overflow" 2096 | }, 2097 | { 2098 | "code": 6025, 2099 | "name": "Truncation", 2100 | "msg": "Truncation" 2101 | }, 2102 | { 2103 | "code": 6026, 2104 | "name": "DivisionByZero", 2105 | "msg": "Division by zero" 2106 | }, 2107 | { 2108 | "code": 6027, 2109 | "name": "NotEnoughRemainingAccounts", 2110 | "msg": "Not enough remaining accounts" 2111 | }, 2112 | { 2113 | "code": 6028, 2114 | "name": "AllFeeRecipientsShouldBeNonZero", 2115 | "msg": "All fee recipients should be non-zero" 2116 | }, 2117 | { 2118 | "code": 6029, 2119 | "name": "UnsortedNotUniqueFeeRecipients", 2120 | "msg": "Unsorted or not unique fee recipients" 2121 | }, 2122 | { 2123 | "code": 6030, 2124 | "name": "CreatorShouldNotBeZero", 2125 | "msg": "Creator should not be zero" 2126 | }, 2127 | { 2128 | "code": 6031, 2129 | "name": "StartTimeInThePast" 2130 | }, 2131 | { 2132 | "code": 6032, 2133 | "name": "EndTimeInThePast" 2134 | }, 2135 | { 2136 | "code": 6033, 2137 | "name": "EndTimeBeforeStartTime" 2138 | }, 2139 | { 2140 | "code": 6034, 2141 | "name": "TimeRangeTooLarge" 2142 | }, 2143 | { 2144 | "code": 6035, 2145 | "name": "EndTimeBeforeCurrentDay" 2146 | }, 2147 | { 2148 | "code": 6036, 2149 | "name": "SupplyUpdateForFinishedRange" 2150 | }, 2151 | { 2152 | "code": 6037, 2153 | "name": "DayIndexAfterEndIndex" 2154 | }, 2155 | { 2156 | "code": 6038, 2157 | "name": "DayInActiveRange" 2158 | }, 2159 | { 2160 | "code": 6039, 2161 | "name": "InvalidIncentiveMint" 2162 | } 2163 | ], 2164 | "types": [ 2165 | { 2166 | "name": "AdminSetCreatorEvent", 2167 | "type": { 2168 | "kind": "struct", 2169 | "fields": [ 2170 | { 2171 | "name": "timestamp", 2172 | "type": "i64" 2173 | }, 2174 | { 2175 | "name": "admin_set_creator_authority", 2176 | "type": "pubkey" 2177 | }, 2178 | { 2179 | "name": "mint", 2180 | "type": "pubkey" 2181 | }, 2182 | { 2183 | "name": "bonding_curve", 2184 | "type": "pubkey" 2185 | }, 2186 | { 2187 | "name": "old_creator", 2188 | "type": "pubkey" 2189 | }, 2190 | { 2191 | "name": "new_creator", 2192 | "type": "pubkey" 2193 | } 2194 | ] 2195 | } 2196 | }, 2197 | { 2198 | "name": "AdminSetIdlAuthorityEvent", 2199 | "type": { 2200 | "kind": "struct", 2201 | "fields": [ 2202 | { 2203 | "name": "idl_authority", 2204 | "type": "pubkey" 2205 | } 2206 | ] 2207 | } 2208 | }, 2209 | { 2210 | "name": "AdminUpdateTokenIncentivesEvent", 2211 | "type": { 2212 | "kind": "struct", 2213 | "fields": [ 2214 | { 2215 | "name": "start_time", 2216 | "type": "i64" 2217 | }, 2218 | { 2219 | "name": "end_time", 2220 | "type": "i64" 2221 | }, 2222 | { 2223 | "name": "day_number", 2224 | "type": "u64" 2225 | }, 2226 | { 2227 | "name": "token_supply_per_day", 2228 | "type": "u64" 2229 | }, 2230 | { 2231 | "name": "mint", 2232 | "type": "pubkey" 2233 | }, 2234 | { 2235 | "name": "seconds_in_a_day", 2236 | "type": "i64" 2237 | }, 2238 | { 2239 | "name": "timestamp", 2240 | "type": "i64" 2241 | } 2242 | ] 2243 | } 2244 | }, 2245 | { 2246 | "name": "BondingCurve", 2247 | "type": { 2248 | "kind": "struct", 2249 | "fields": [ 2250 | { 2251 | "name": "virtual_token_reserves", 2252 | "type": "u64" 2253 | }, 2254 | { 2255 | "name": "virtual_sol_reserves", 2256 | "type": "u64" 2257 | }, 2258 | { 2259 | "name": "real_token_reserves", 2260 | "type": "u64" 2261 | }, 2262 | { 2263 | "name": "real_sol_reserves", 2264 | "type": "u64" 2265 | }, 2266 | { 2267 | "name": "token_total_supply", 2268 | "type": "u64" 2269 | }, 2270 | { 2271 | "name": "complete", 2272 | "type": "bool" 2273 | }, 2274 | { 2275 | "name": "creator", 2276 | "type": "pubkey" 2277 | } 2278 | ] 2279 | } 2280 | }, 2281 | { 2282 | "name": "ClaimTokenIncentivesEvent", 2283 | "type": { 2284 | "kind": "struct", 2285 | "fields": [ 2286 | { 2287 | "name": "user", 2288 | "type": "pubkey" 2289 | }, 2290 | { 2291 | "name": "mint", 2292 | "type": "pubkey" 2293 | }, 2294 | { 2295 | "name": "amount", 2296 | "type": "u64" 2297 | }, 2298 | { 2299 | "name": "timestamp", 2300 | "type": "i64" 2301 | } 2302 | ] 2303 | } 2304 | }, 2305 | { 2306 | "name": "CloseUserVolumeAccumulatorEvent", 2307 | "type": { 2308 | "kind": "struct", 2309 | "fields": [ 2310 | { 2311 | "name": "user", 2312 | "type": "pubkey" 2313 | }, 2314 | { 2315 | "name": "timestamp", 2316 | "type": "i64" 2317 | } 2318 | ] 2319 | } 2320 | }, 2321 | { 2322 | "name": "CollectCreatorFeeEvent", 2323 | "type": { 2324 | "kind": "struct", 2325 | "fields": [ 2326 | { 2327 | "name": "timestamp", 2328 | "type": "i64" 2329 | }, 2330 | { 2331 | "name": "creator", 2332 | "type": "pubkey" 2333 | }, 2334 | { 2335 | "name": "creator_fee", 2336 | "type": "u64" 2337 | } 2338 | ] 2339 | } 2340 | }, 2341 | { 2342 | "name": "CompleteEvent", 2343 | "type": { 2344 | "kind": "struct", 2345 | "fields": [ 2346 | { 2347 | "name": "user", 2348 | "type": "pubkey" 2349 | }, 2350 | { 2351 | "name": "mint", 2352 | "type": "pubkey" 2353 | }, 2354 | { 2355 | "name": "bonding_curve", 2356 | "type": "pubkey" 2357 | }, 2358 | { 2359 | "name": "timestamp", 2360 | "type": "i64" 2361 | } 2362 | ] 2363 | } 2364 | }, 2365 | { 2366 | "name": "CompletePumpAmmMigrationEvent", 2367 | "type": { 2368 | "kind": "struct", 2369 | "fields": [ 2370 | { 2371 | "name": "user", 2372 | "type": "pubkey" 2373 | }, 2374 | { 2375 | "name": "mint", 2376 | "type": "pubkey" 2377 | }, 2378 | { 2379 | "name": "mint_amount", 2380 | "type": "u64" 2381 | }, 2382 | { 2383 | "name": "sol_amount", 2384 | "type": "u64" 2385 | }, 2386 | { 2387 | "name": "pool_migration_fee", 2388 | "type": "u64" 2389 | }, 2390 | { 2391 | "name": "bonding_curve", 2392 | "type": "pubkey" 2393 | }, 2394 | { 2395 | "name": "timestamp", 2396 | "type": "i64" 2397 | }, 2398 | { 2399 | "name": "pool", 2400 | "type": "pubkey" 2401 | } 2402 | ] 2403 | } 2404 | }, 2405 | { 2406 | "name": "CreateEvent", 2407 | "type": { 2408 | "kind": "struct", 2409 | "fields": [ 2410 | { 2411 | "name": "name", 2412 | "type": "string" 2413 | }, 2414 | { 2415 | "name": "symbol", 2416 | "type": "string" 2417 | }, 2418 | { 2419 | "name": "uri", 2420 | "type": "string" 2421 | }, 2422 | { 2423 | "name": "mint", 2424 | "type": "pubkey" 2425 | }, 2426 | { 2427 | "name": "bonding_curve", 2428 | "type": "pubkey" 2429 | }, 2430 | { 2431 | "name": "user", 2432 | "type": "pubkey" 2433 | }, 2434 | { 2435 | "name": "creator", 2436 | "type": "pubkey" 2437 | }, 2438 | { 2439 | "name": "timestamp", 2440 | "type": "i64" 2441 | }, 2442 | { 2443 | "name": "virtual_token_reserves", 2444 | "type": "u64" 2445 | }, 2446 | { 2447 | "name": "virtual_sol_reserves", 2448 | "type": "u64" 2449 | }, 2450 | { 2451 | "name": "real_token_reserves", 2452 | "type": "u64" 2453 | }, 2454 | { 2455 | "name": "token_total_supply", 2456 | "type": "u64" 2457 | } 2458 | ] 2459 | } 2460 | }, 2461 | { 2462 | "name": "ExtendAccountEvent", 2463 | "type": { 2464 | "kind": "struct", 2465 | "fields": [ 2466 | { 2467 | "name": "account", 2468 | "type": "pubkey" 2469 | }, 2470 | { 2471 | "name": "user", 2472 | "type": "pubkey" 2473 | }, 2474 | { 2475 | "name": "current_size", 2476 | "type": "u64" 2477 | }, 2478 | { 2479 | "name": "new_size", 2480 | "type": "u64" 2481 | }, 2482 | { 2483 | "name": "timestamp", 2484 | "type": "i64" 2485 | } 2486 | ] 2487 | } 2488 | }, 2489 | { 2490 | "name": "FeeConfig", 2491 | "type": { 2492 | "kind": "struct", 2493 | "fields": [ 2494 | { 2495 | "name": "bump", 2496 | "type": "u8" 2497 | }, 2498 | { 2499 | "name": "admin", 2500 | "type": "pubkey" 2501 | }, 2502 | { 2503 | "name": "flat_fees", 2504 | "type": { 2505 | "defined": { 2506 | "name": "Fees" 2507 | } 2508 | } 2509 | }, 2510 | { 2511 | "name": "fee_tiers", 2512 | "type": { 2513 | "vec": { 2514 | "defined": { 2515 | "name": "FeeTier" 2516 | } 2517 | } 2518 | } 2519 | } 2520 | ] 2521 | } 2522 | }, 2523 | { 2524 | "name": "FeeTier", 2525 | "type": { 2526 | "kind": "struct", 2527 | "fields": [ 2528 | { 2529 | "name": "market_cap_lamports_threshold", 2530 | "type": "u128" 2531 | }, 2532 | { 2533 | "name": "fees", 2534 | "type": { 2535 | "defined": { 2536 | "name": "Fees" 2537 | } 2538 | } 2539 | } 2540 | ] 2541 | } 2542 | }, 2543 | { 2544 | "name": "Fees", 2545 | "type": { 2546 | "kind": "struct", 2547 | "fields": [ 2548 | { 2549 | "name": "lp_fee_bps", 2550 | "type": "u64" 2551 | }, 2552 | { 2553 | "name": "protocol_fee_bps", 2554 | "type": "u64" 2555 | }, 2556 | { 2557 | "name": "creator_fee_bps", 2558 | "type": "u64" 2559 | } 2560 | ] 2561 | } 2562 | }, 2563 | { 2564 | "name": "Global", 2565 | "type": { 2566 | "kind": "struct", 2567 | "fields": [ 2568 | { 2569 | "name": "initialized", 2570 | "docs": ["Unused"], 2571 | "type": "bool" 2572 | }, 2573 | { 2574 | "name": "authority", 2575 | "type": "pubkey" 2576 | }, 2577 | { 2578 | "name": "fee_recipient", 2579 | "type": "pubkey" 2580 | }, 2581 | { 2582 | "name": "initial_virtual_token_reserves", 2583 | "type": "u64" 2584 | }, 2585 | { 2586 | "name": "initial_virtual_sol_reserves", 2587 | "type": "u64" 2588 | }, 2589 | { 2590 | "name": "initial_real_token_reserves", 2591 | "type": "u64" 2592 | }, 2593 | { 2594 | "name": "token_total_supply", 2595 | "type": "u64" 2596 | }, 2597 | { 2598 | "name": "fee_basis_points", 2599 | "type": "u64" 2600 | }, 2601 | { 2602 | "name": "withdraw_authority", 2603 | "type": "pubkey" 2604 | }, 2605 | { 2606 | "name": "enable_migrate", 2607 | "docs": ["Unused"], 2608 | "type": "bool" 2609 | }, 2610 | { 2611 | "name": "pool_migration_fee", 2612 | "type": "u64" 2613 | }, 2614 | { 2615 | "name": "creator_fee_basis_points", 2616 | "type": "u64" 2617 | }, 2618 | { 2619 | "name": "fee_recipients", 2620 | "type": { 2621 | "array": ["pubkey", 7] 2622 | } 2623 | }, 2624 | { 2625 | "name": "set_creator_authority", 2626 | "type": "pubkey" 2627 | }, 2628 | { 2629 | "name": "admin_set_creator_authority", 2630 | "type": "pubkey" 2631 | } 2632 | ] 2633 | } 2634 | }, 2635 | { 2636 | "name": "GlobalVolumeAccumulator", 2637 | "type": { 2638 | "kind": "struct", 2639 | "fields": [ 2640 | { 2641 | "name": "start_time", 2642 | "type": "i64" 2643 | }, 2644 | { 2645 | "name": "end_time", 2646 | "type": "i64" 2647 | }, 2648 | { 2649 | "name": "seconds_in_a_day", 2650 | "type": "i64" 2651 | }, 2652 | { 2653 | "name": "mint", 2654 | "type": "pubkey" 2655 | }, 2656 | { 2657 | "name": "total_token_supply", 2658 | "type": { 2659 | "array": ["u64", 30] 2660 | } 2661 | }, 2662 | { 2663 | "name": "sol_volumes", 2664 | "type": { 2665 | "array": ["u64", 30] 2666 | } 2667 | } 2668 | ] 2669 | } 2670 | }, 2671 | { 2672 | "name": "InitUserVolumeAccumulatorEvent", 2673 | "type": { 2674 | "kind": "struct", 2675 | "fields": [ 2676 | { 2677 | "name": "payer", 2678 | "type": "pubkey" 2679 | }, 2680 | { 2681 | "name": "user", 2682 | "type": "pubkey" 2683 | }, 2684 | { 2685 | "name": "timestamp", 2686 | "type": "i64" 2687 | } 2688 | ] 2689 | } 2690 | }, 2691 | { 2692 | "name": "SetCreatorEvent", 2693 | "type": { 2694 | "kind": "struct", 2695 | "fields": [ 2696 | { 2697 | "name": "timestamp", 2698 | "type": "i64" 2699 | }, 2700 | { 2701 | "name": "mint", 2702 | "type": "pubkey" 2703 | }, 2704 | { 2705 | "name": "bonding_curve", 2706 | "type": "pubkey" 2707 | }, 2708 | { 2709 | "name": "creator", 2710 | "type": "pubkey" 2711 | } 2712 | ] 2713 | } 2714 | }, 2715 | { 2716 | "name": "SetMetaplexCreatorEvent", 2717 | "type": { 2718 | "kind": "struct", 2719 | "fields": [ 2720 | { 2721 | "name": "timestamp", 2722 | "type": "i64" 2723 | }, 2724 | { 2725 | "name": "mint", 2726 | "type": "pubkey" 2727 | }, 2728 | { 2729 | "name": "bonding_curve", 2730 | "type": "pubkey" 2731 | }, 2732 | { 2733 | "name": "metadata", 2734 | "type": "pubkey" 2735 | }, 2736 | { 2737 | "name": "creator", 2738 | "type": "pubkey" 2739 | } 2740 | ] 2741 | } 2742 | }, 2743 | { 2744 | "name": "SetParamsEvent", 2745 | "type": { 2746 | "kind": "struct", 2747 | "fields": [ 2748 | { 2749 | "name": "initial_virtual_token_reserves", 2750 | "type": "u64" 2751 | }, 2752 | { 2753 | "name": "initial_virtual_sol_reserves", 2754 | "type": "u64" 2755 | }, 2756 | { 2757 | "name": "initial_real_token_reserves", 2758 | "type": "u64" 2759 | }, 2760 | { 2761 | "name": "final_real_sol_reserves", 2762 | "type": "u64" 2763 | }, 2764 | { 2765 | "name": "token_total_supply", 2766 | "type": "u64" 2767 | }, 2768 | { 2769 | "name": "fee_basis_points", 2770 | "type": "u64" 2771 | }, 2772 | { 2773 | "name": "withdraw_authority", 2774 | "type": "pubkey" 2775 | }, 2776 | { 2777 | "name": "enable_migrate", 2778 | "type": "bool" 2779 | }, 2780 | { 2781 | "name": "pool_migration_fee", 2782 | "type": "u64" 2783 | }, 2784 | { 2785 | "name": "creator_fee_basis_points", 2786 | "type": "u64" 2787 | }, 2788 | { 2789 | "name": "fee_recipients", 2790 | "type": { 2791 | "array": ["pubkey", 8] 2792 | } 2793 | }, 2794 | { 2795 | "name": "timestamp", 2796 | "type": "i64" 2797 | }, 2798 | { 2799 | "name": "set_creator_authority", 2800 | "type": "pubkey" 2801 | }, 2802 | { 2803 | "name": "admin_set_creator_authority", 2804 | "type": "pubkey" 2805 | } 2806 | ] 2807 | } 2808 | }, 2809 | { 2810 | "name": "SyncUserVolumeAccumulatorEvent", 2811 | "type": { 2812 | "kind": "struct", 2813 | "fields": [ 2814 | { 2815 | "name": "user", 2816 | "type": "pubkey" 2817 | }, 2818 | { 2819 | "name": "total_claimed_tokens_before", 2820 | "type": "u64" 2821 | }, 2822 | { 2823 | "name": "total_claimed_tokens_after", 2824 | "type": "u64" 2825 | }, 2826 | { 2827 | "name": "timestamp", 2828 | "type": "i64" 2829 | } 2830 | ] 2831 | } 2832 | }, 2833 | { 2834 | "name": "TradeEvent", 2835 | "type": { 2836 | "kind": "struct", 2837 | "fields": [ 2838 | { 2839 | "name": "mint", 2840 | "type": "pubkey" 2841 | }, 2842 | { 2843 | "name": "sol_amount", 2844 | "type": "u64" 2845 | }, 2846 | { 2847 | "name": "token_amount", 2848 | "type": "u64" 2849 | }, 2850 | { 2851 | "name": "is_buy", 2852 | "type": "bool" 2853 | }, 2854 | { 2855 | "name": "user", 2856 | "type": "pubkey" 2857 | }, 2858 | { 2859 | "name": "timestamp", 2860 | "type": "i64" 2861 | }, 2862 | { 2863 | "name": "virtual_sol_reserves", 2864 | "type": "u64" 2865 | }, 2866 | { 2867 | "name": "virtual_token_reserves", 2868 | "type": "u64" 2869 | }, 2870 | { 2871 | "name": "real_sol_reserves", 2872 | "type": "u64" 2873 | }, 2874 | { 2875 | "name": "real_token_reserves", 2876 | "type": "u64" 2877 | }, 2878 | { 2879 | "name": "fee_recipient", 2880 | "type": "pubkey" 2881 | }, 2882 | { 2883 | "name": "fee_basis_points", 2884 | "type": "u64" 2885 | }, 2886 | { 2887 | "name": "fee", 2888 | "type": "u64" 2889 | }, 2890 | { 2891 | "name": "creator", 2892 | "type": "pubkey" 2893 | }, 2894 | { 2895 | "name": "creator_fee_basis_points", 2896 | "type": "u64" 2897 | }, 2898 | { 2899 | "name": "creator_fee", 2900 | "type": "u64" 2901 | } 2902 | ] 2903 | } 2904 | }, 2905 | { 2906 | "name": "UpdateGlobalAuthorityEvent", 2907 | "type": { 2908 | "kind": "struct", 2909 | "fields": [ 2910 | { 2911 | "name": "global", 2912 | "type": "pubkey" 2913 | }, 2914 | { 2915 | "name": "authority", 2916 | "type": "pubkey" 2917 | }, 2918 | { 2919 | "name": "new_authority", 2920 | "type": "pubkey" 2921 | }, 2922 | { 2923 | "name": "timestamp", 2924 | "type": "i64" 2925 | } 2926 | ] 2927 | } 2928 | }, 2929 | { 2930 | "name": "UserVolumeAccumulator", 2931 | "type": { 2932 | "kind": "struct", 2933 | "fields": [ 2934 | { 2935 | "name": "user", 2936 | "type": "pubkey" 2937 | }, 2938 | { 2939 | "name": "needs_claim", 2940 | "type": "bool" 2941 | }, 2942 | { 2943 | "name": "total_unclaimed_tokens", 2944 | "type": "u64" 2945 | }, 2946 | { 2947 | "name": "total_claimed_tokens", 2948 | "type": "u64" 2949 | }, 2950 | { 2951 | "name": "current_sol_volume", 2952 | "type": "u64" 2953 | }, 2954 | { 2955 | "name": "last_update_timestamp", 2956 | "type": "i64" 2957 | }, 2958 | { 2959 | "name": "has_total_claimed_tokens", 2960 | "type": "bool" 2961 | } 2962 | ] 2963 | } 2964 | } 2965 | ] 2966 | } 2967 | --------------------------------------------------------------------------------