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