2

I am trying to get the information of a pump.fun token, and I want to get the bonding curve progress percentage. but I don't know how to calculate it, is there any API to get the bonding curve progress information? I got the address of the bonding curve, can I use it to get the percentage using it? or anyone know what is the math behind calculating it?

1 Answer 1

1

To get bonding curve percentage you can use bitquery api url

According to the above link, we can calculate progress as follows

//We get totalReserves, realTokenReserves from bonding curve data
reservedTokens=206900000 // (without decimals)
initialRealTokenReserves = totalReserves - reservedTokens
leftTokens = realTokenReserves - reservedTokens
BondingCurveProgress = 100 - ((leftTokens*100)/(initialRealTokenReserves))

We can get same data from blockchain as well. To parse bonding curve account data, we need pump.fun idl. Here is link for the idl file. Posting it below as well

{
"version": "0.1.0",
"name": "pump",
"instructions": [
  {
    "name": "initialize",
    "docs": [
      "Creates the global state."
    ],
    "accounts": [
      {
        "name": "global",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "user",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "systemProgram",
        "isMut": false,
        "isSigner": false
      }
    ],
    "args": []
  },
  {
    "name": "setParams",
    "docs": [
      "Sets the global state parameters."
    ],
    "accounts": [
      {
        "name": "global",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "user",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "systemProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "eventAuthority",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "program",
        "isMut": false,
        "isSigner": false
      }
    ],
    "args": [
      {
        "name": "feeRecipient",
        "type": "publicKey"
      },
      {
        "name": "initialVirtualTokenReserves",
        "type": "u64"
      },
      {
        "name": "initialVirtualSolReserves",
        "type": "u64"
      },
      {
        "name": "initialRealTokenReserves",
        "type": "u64"
      },
      {
        "name": "tokenTotalSupply",
        "type": "u64"
      },
      {
        "name": "feeBasisPoints",
        "type": "u64"
      }
    ]
  },
  {
    "name": "create",
    "docs": [
      "Creates a new coin and bonding curve."
    ],
    "accounts": [
      {
        "name": "mint",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "mintAuthority",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "bondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedBondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "global",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "mplTokenMetadata",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "metadata",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "user",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "systemProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "tokenProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "associatedTokenProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "rent",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "eventAuthority",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "program",
        "isMut": false,
        "isSigner": false
      }
    ],
    "args": [
      {
        "name": "name",
        "type": "string"
      },
      {
        "name": "symbol",
        "type": "string"
      },
      {
        "name": "uri",
        "type": "string"
      }
    ]
  },
  {
    "name": "buy",
    "docs": [
      "Buys tokens from a bonding curve."
    ],
    "accounts": [
      {
        "name": "global",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "feeRecipient",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "mint",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "bondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedBondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedUser",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "user",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "systemProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "tokenProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "rent",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "eventAuthority",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "program",
        "isMut": false,
        "isSigner": false
      }
    ],
    "args": [
      {
        "name": "amount",
        "type": "u64"
      },
      {
        "name": "maxSolCost",
        "type": "u64"
      }
    ]
  },
  {
    "name": "sell",
    "docs": [
      "Sells tokens into a bonding curve."
    ],
    "accounts": [
      {
        "name": "global",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "feeRecipient",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "mint",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "bondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedBondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedUser",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "user",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "systemProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "associatedTokenProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "tokenProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "eventAuthority",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "program",
        "isMut": false,
        "isSigner": false
      }
    ],
    "args": [
      {
        "name": "amount",
        "type": "u64"
      },
      {
        "name": "minSolOutput",
        "type": "u64"
      }
    ]
  },
  {
    "name": "withdraw",
    "docs": [
      "Allows the admin to withdraw liquidity for a migration once the bonding curve completes"
    ],
    "accounts": [
      {
        "name": "global",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "mint",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "bondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedBondingCurve",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "associatedUser",
        "isMut": true,
        "isSigner": false
      },
      {
        "name": "user",
        "isMut": true,
        "isSigner": true
      },
      {
        "name": "systemProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "tokenProgram",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "rent",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "eventAuthority",
        "isMut": false,
        "isSigner": false
      },
      {
        "name": "program",
        "isMut": false,
        "isSigner": false
      }
    ],
    "args": []
  }
],
"accounts": [
  {
    "name": "Global",
    "type": {
      "kind": "struct",
      "fields": [
        {
          "name": "initialized",
          "type": "bool"
        },
        {
          "name": "authority",
          "type": "publicKey"
        },
        {
          "name": "feeRecipient",
          "type": "publicKey"
        },
        {
          "name": "initialVirtualTokenReserves",
          "type": "u64"
        },
        {
          "name": "initialVirtualSolReserves",
          "type": "u64"
        },
        {
          "name": "initialRealTokenReserves",
          "type": "u64"
        },
        {
          "name": "tokenTotalSupply",
          "type": "u64"
        },
        {
          "name": "feeBasisPoints",
          "type": "u64"
        }
      ]
    }
  },
  {
    "name": "BondingCurve",
    "type": {
      "kind": "struct",
      "fields": [
        {
          "name": "virtualTokenReserves",
          "type": "u64"
        },
        {
          "name": "virtualSolReserves",
          "type": "u64"
        },
        {
          "name": "realTokenReserves",
          "type": "u64"
        },
        {
          "name": "realSolReserves",
          "type": "u64"
        },
        {
          "name": "tokenTotalSupply",
          "type": "u64"
        },
        {
          "name": "complete",
          "type": "bool"
        }
      ]
    }
  }
],
"events": [
  {
    "name": "CreateEvent",
    "fields": [
      {
        "name": "name",
        "type": "string",
        "index": false
      },
      {
        "name": "symbol",
        "type": "string",
        "index": false
      },
      {
        "name": "uri",
        "type": "string",
        "index": false
      },
      {
        "name": "mint",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "bondingCurve",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "user",
        "type": "publicKey",
        "index": false
      }
    ]
  },
  {
    "name": "TradeEvent",
    "fields": [
      {
        "name": "mint",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "solAmount",
        "type": "u64",
        "index": false
      },
      {
        "name": "tokenAmount",
        "type": "u64",
        "index": false
      },
      {
        "name": "isBuy",
        "type": "bool",
        "index": false
      },
      {
        "name": "user",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "timestamp",
        "type": "i64",
        "index": false
      },
      {
        "name": "virtualSolReserves",
        "type": "u64",
        "index": false
      },
      {
        "name": "virtualTokenReserves",
        "type": "u64",
        "index": false
      }
    ]
  },
  {
    "name": "CompleteEvent",
    "fields": [
      {
        "name": "user",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "mint",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "bondingCurve",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "timestamp",
        "type": "i64",
        "index": false
      }
    ]
  },
  {
    "name": "SetParamsEvent",
    "fields": [
      {
        "name": "feeRecipient",
        "type": "publicKey",
        "index": false
      },
      {
        "name": "initialVirtualTokenReserves",
        "type": "u64",
        "index": false
      },
      {
        "name": "initialVirtualSolReserves",
        "type": "u64",
        "index": false
      },
      {
        "name": "initialRealTokenReserves",
        "type": "u64",
        "index": false
      },
      {
        "name": "tokenTotalSupply",
        "type": "u64",
        "index": false
      },
      {
        "name": "feeBasisPoints",
        "type": "u64",
        "index": false
      }
    ]
  }
],
"errors": [
  {
    "code": 6000,
    "name": "NotAuthorized",
    "msg": "The given account is not authorized to execute this instruction."
  },
  {
    "code": 6001,
    "name": "AlreadyInitialized",
    "msg": "The program is already initialized."
  },
  {
    "code": 6002,
    "name": "TooMuchSolRequired",
    "msg": "slippage: Too much SOL required to buy the given amount of tokens."
  },
  {
    "code": 6003,
    "name": "TooLittleSolReceived",
    "msg": "slippage: Too little SOL received to sell the given amount of tokens."
  },
  {
    "code": 6004,
    "name": "MintDoesNotMatchBondingCurve",
    "msg": "The mint does not match the bonding curve."
  },
  {
    "code": 6005,
    "name": "BondingCurveComplete",
    "msg": "The bonding curve has completed and liquidity migrated to raydium."
  },
  {
    "code": 6006,
    "name": "BondingCurveNotComplete",
    "msg": "The bonding curve has not completed."
  },
  {
    "code": 6007,
    "name": "NotInitialized",
    "msg": "The program is not initialized."
  }
],
"metadata": {
  "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
}

}

The idl file will help us decode bonding curve data Below is typescript code to get bonding curve progress

import {Program,Wallet,AnchorProvider} from "@coral-xyz/anchor";
import * as web3 from '@solana/web3.js';
import bs58 from 'bs58';
import IDL from "./pump_idl.json" assert { type: "json" };
import Buffer from 'Buffer';
import  BN from 'bn.js';

const bondingurveProgress=async (mintAddress, userPrivateKey)=>{

   const pumpSwapPID=new web3.PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");

   const userWallet= new Wallet(web3.Keypair.fromSecretKey(bs58.decode(userPrivateKey)));

   const conn = new web3.Connection("https://api.mainnet-beta.solana.com",{commitment: "finalized"});
   const provider=new AnchorProvider(conn, userWallet, {commitment: "processed",});
   const program=new Program(IDL, pumpSwapPID, provider);

   const [bondingCurve] = web3.PublicKey.findProgramAddressSync([Buffer.from("bonding-curve"), new web3.PublicKey(mintAddress).toBytes()],pumpSwapPID); 
   const data= await program.account.bondingCurve.fetch(bondingCurve);
   //We multiply by 1000_000 as coin have value in 6 decimals
   const reservedTokens=new BN(206900000).mul(new BN(1000_000));
   const initialRealTokenReserves=data.tokenTotalSupply.sub(reservedTokens);
   const bondingCurveProgress= new BN(100).sub(data.realTokenReserves.mul(new BN(100)).div(initialRealTokenReserves))
   return bondingCurveProgress.toString(10)
}
//Run this by passing mint address & an account keypair to feed in anchor program object
bondingurveProgress(mintKey, userPrivateKey)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.