How to stream new token launches on Pump.fun in real-time

A step-by-step guide to streaming newly minted Pump.fun tokens on Solana
in real-time using Shyft's Yellowstone gRPC — with mint address detection
and token info fetching via Shyft APIs

A step-by-step guide to detect and stream newly minted Pump.fun tokens on Solana in real-time using Shyft’s Yellowstone gRPC

Stream new token launches on pump cover

Pump.fun launches hundreds of new tokens every hour on Solana. For trading bots, snipers, and analytics tools, detecting these launches the moment they hit the blockchain is critical. Once a token graduates to PumpSwap, you’ll also want to stream and parse PumpSwap AMM transactions to track live trading activity.

In this guide, you’ll learn how to:

  • Subscribe to the Pump.fun program ID (6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P) using Shyft’s Yellowstone gRPC
  • Filter transactions to detect only new token mints using MintTo log messages
  • Fetch token name, symbol, supply and mint address using Shyft’s Token API

All examples use TypeScript with the @triton-one/yellowstone-grpc client

What You Need Before Getting Started

Get Your Shyft API Key, gRPC endpoint and gRPC token

    Signup and get all the above details in Shyft Dashboard. This also includes a free Shyft API key and RPC URL.

    A server-side backend (like NodeJS) to receive gRPC data

      In this example, we used NodeJS, but other backend languages such as C#, Go, Java, Kotlin, Python, or PHP can also be used.

      How This Token Launch Detector Works

      1. Solana blockchain data is streamed through Shyft’s gRPC service.
      2. The received data is then decoded, filtered by log messages to identify new token mints
      3. The data is enriched with token metadata, and then stored in a database.
      Stream → Decode → Filter → Enrich → Store

      How to Connect to Shyft’s Yellowstone gRPC

      To begin streaming, we need to establish the client service. This requires: the gRPC URL and the gRPC Access Token.

      const client = new Client(
          'Your Region specific Shyft gRPC URL',
          'Shyft gRPC Access Token',
          undefined,
        );

      Now, let’s dive in and grab that data from the blockchain!

      For production token snipers, make sure your stream never drops — pair this with gRPC reconnect and slot replay to resume from the exact slot where you left off.

      How to Subscribe to Pump.fun Transactions by Program ID

      The Pump.fun Program Id

      The Pump.fun program ID is 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.

      Requesting the Stream and getting Live data

      The following code demonstrates how to establish a subscription to a live data stream from the gRPC service. Specifically, we subscribe to transactions associated with the Pump.fun program ID.

      const req = {
      accounts: {},
      slots: {},
      transactions: {
      bondingCurve: {
      vote: false,
      failed: false,
      signature: undefined,
      accountInclude: ['6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'], //Address 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P
      accountExclude: [],
      accountRequired: [],
      },
      },
      transactionsStatus: {},
      entry: {},
      blocks: {},
      blocksMeta: {},
      accountsDataSlice: [],
      ping: undefined,
      commitment: CommitmentLevel.CONFIRMED, //for receiving confirmed txn updates
      };
      subscribeCommand(client, req);

      Output will look like:

      filters: [ 'Pumpfun' ],
      account: undefined,
      slot: undefined,
      transaction: {
      transaction: {
      signature: <Buffer 48 e8 a9 27 ba af 8d a7 34 10 83 b8 57 6f 9c d0 e2 31 67 fe 33 c7 94 44 64 de 88 67 d1 9a ff 69 77 e6 6b f4 0b ec e0 48 19 5d a0 0f ef 7e aa b9 c4 af ... 14 more bytes>,
      isVote: false,
      transaction: [Object],
      meta: [Object],
      index: '1690'
      },
      slot: '288764368'
      },
      block: undefined,
      ping: undefined,
      pong: undefined,
      blockMeta: undefined,
      entry: undefined
      }

      To get new token launch Tx, we need to decode and streamline our stream output. In the utils folder, you will find the transactionOutput.ts file. The following code illustrates how to modify the output to meet our needs:

      //from transactionOutput.ts
      import { decodeTransact } from "./decodeTransaction";

      export function tOutPut(data){
      const dataTx = data?.transaction?.transaction
      const signature = data != undefined?decodeTransact(dataTx?.signature):"";
      const message = dataTx?.transaction?.message
      const header = message?.header;
      const accountKeys = data != undefined?message?.accountKeys?.map((t)=>{
      return decodeTransact(t)
      }):"";
      const recentBlockhash = decodeTransact(message?.recentBlockhash);
      const instructions = message?.instructions
      const meta = dataTx?.meta
      const logs : any[] = meta?.logMessages;
      const logFilter = logs?.some(instruction =>
      instruction.match(instruction.match(/MintTo/i)));
      return {
      signature,
      message:{
      header,
      accountKeys,
      recentBlockhash,
      instructions
      },
      meta,
      logFilter
      }
      }

      Output will look like:

      {
      signature: '2mHnosZrcuDPB7PoB5CLS69qW4AA5SfZWkrn4ZPyGpQyQjQG2fZPGAnb28RmTwLeAW4wq4ZMj4oLgrgsWvW4zQbc',
      message: {
      header: {
      numRequiredSignatures: 2,
      numReadonlySignedAccounts: 0,
      numReadonlyUnsignedAccounts: 10
      },
      accountKeys: [
      '89qbZTVyGqpfeu5btKubFqYjV9mh4w3zWDGacKkFpMPj',
      '8MqEGUhijWXbDuzoJR4Zax37HLTpJQZXNfcH81CWpump',
      'HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe',
      ],
      recentBlockhash: '5upunMbFnmYLm2dq8tEDgHoW3yMBqsLQg7UwTBjWFysa',
      instructions: [ [Object], [Object], [Object], [Object], [Object], [Object] ]
      },
      meta: {
      err: undefined,
      fee: '90719',
      preBalances: [
      '6868763480', '0',
      '1432215', '0',
      '0', '0',
      '0', '320032236232075',
      '1', '1',
      '1141440', '323296939',
      '5530000', '1141440',
      '934087680', '731913600',
      '1009200', '0'
      ],
      postBalances: [
      '5832283961', '1461600',
      '5432215', '1001231920',
      '2039280', '15616720',
      '2039280', '320032246232075',
      '1', '1',
      '1141440', '323296939',
      '5530000', '1141440',
      '934087680', '731913600',
      '1009200', '0'
      ],
      innerInstructions: [ [Object], [Object], [Object] ],
      innerInstructionsNone: false,
      logMessages: [
      'Program ComputeBudget111111111111111111111111111111 invoke [1]',
      'Program ComputeBudget111111111111111111111111111111 success',
      'Program 11111111111111111111111111111111 invoke [1]',
      'Program 11111111111111111111111111111111 success',
      'Program ComputeBudget111111111111111111111111111111 invoke [1]',
      'Program ComputeBudget111111111111111111111111111111 success',
      'Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [1]',
      'Program log: Instruction: Create',
      'Program 11111111111111111111111111111111 invoke [2]',
      'Program 11111111111111111111111111111111 success',
      'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]',
      'Program log: Instruction: InitializeMint2',
      'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2780 of 238053 compute units',
      'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',
      'Program 11111111111111111111111111111111 invoke [2]',
      'Program 11111111111111111111111111111111 success',
      'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [2]',

      ],
      logMessagesNone: false,
      preTokenBalances: [],
      postTokenBalances: [ [Object], [Object] ],
      rewards: [],
      loadedWritableAddresses: [],
      loadedReadonlyAddresses: [],
      returnData: undefined,
      returnDataNone: true,
      computeUnitsConsumed: '173923'
      },
      logFilter: true
      }

      To get new token launches, we filter the log messages to find transactions that include the term "MintTo" in their logs. This helps us identify and return only the transactions related to token minting.

      How to Fetch Token Name, Symbol and Mint Address

      Before getting the result, we need basic info about the token, like its name, symbol, description, decimals, and supply. The code below shows how to fetch this using Shyft’s getInfo API.

      var myHeaders = new Headers();
      const api = 'Your api key'
      myHeaders.append("x-api-key", api);
      var requestOptions:any = {
      method: 'GET',
      headers: myHeaders,
      redirect: 'follow'
      };
      export async function getTokenInfo(token){
      const info = await fetch(`https://api.shyft.to/sol/v1/token/get_info?network=mainnet-beta&token_address=${token}`, requestOptions)
      const infoJson = await info.json();
      const name = infoJson.result.name;
      const symbol = infoJson.result.symbol;
      const desc = infoJson.result.description;
      const decimal = infoJson.result.decimals;
      const supply = infoJson.result.current_supply;
      return{
      name,
      symbol,
      desc,
      supply,
      decimal
      }
      }

      We return the token information as an object and then export our function so that it can be called by other functions.

      Code Breakdown

      • const result = await tOutPut(data);: Passes the incoming data to the tOutPut function, which processes the data and returns a promise. The result of this promise is awaited and stored in the result variable.
      • result?.logFilter == true: Checks if result is not null or undefined and if its logFilter property is true. This indicates that the log message matches the criteria (e.g., contains "MintTo").
      • const tokenStream = result?.meta?.postTokenBalances[0];: Retrieves the first token balance entry from the postTokenBalances array in the meta property of result.
      • const mint = tokenStream?.mint;: Extracts the mint address of the token from tokenStream.
      • const tokenInfo = await getTokenInfo(mint);: Calls the getTokenInfo function with the mint address to fetch detailed information about the token. This function returns a promise that is awaited, with the resulting token information stored in tokenInfo.
      stream.on("data", async (data) => {
      try{
      const result = await tOutPut(data);
      if(result?.logFilter == true){
      const tokenStream = result?.meta?.postTokenBalances[0];
      const mint = tokenStream?.mint
      const tokenInfo = await getTokenInfo(mint);
      console.log(`
      CA| ${mint}
      Name| ${tokenInfo?.name}
      Symbol| ${tokenInfo?.symbol}
      Desc| ${tokenInfo?.desc}
      Decimal| ${tokenInfo?.decimal}
      Supply| ${tokenInfo?.supply}
      <https://solscan/tx/${result.signature}>
      `)
      }
      }catch(error){
      if(error){
      console.log(error)
      }
      }

      Logging Token Information

      • CA: The mint address of the token.
      • Name: The name of the token.
      • Symbol: The symbol of the token.
      • Desc: The description of the token.
      • Decimal: The number of decimal places the token supports.
      • Supply: The current supply of the token.
      • Transaction Link: A URL to view the transaction on Solscan, with the transaction signature included.
      console.log(`
      CA| ${mint}
      Name| ${tokenInfo?.name}
      Symbol| ${tokenInfo?.symbol}
      Desc| ${tokenInfo?.desc}
      Decimal| ${tokenInfo?.decimal}
      Supply| ${tokenInfo?.supply}
      <https://solscan/tx/${result.signature}>
      `);

      Our Result should look like this

       CA| 4hhRRFQ4MS8jmzjeVdvAk66zxKU3ARTaherKwYfkpump
      Name| FLOSS
      Symbol| FLOSS
      Desc| Don't forget to FLOSS.
      Decimal| 6
      Supply| 1000000000
      https://solscan/tx/2pbXSouh76bS4aAwXfrCSYtGdDuKcCTcRmuvKDJWrR9UkibUNjRooSFE9qS1jvtpHxpp3EZj8itK9G59VTMjgGUT


      CA| CEfDZRT4X7sX5Q1BqeK7KeqvLtCZc1Jmr1GdTQ6Kpump
      Name| Bro said he knew a spot
      Symbol| SPOT
      Desc| Bro said he knew a spot
      Decimal| 6
      Supply| 1000000000
      https://solscan/tx/3ncnJNsApRX21hbT9rSN7qtty5bj3czBj63bFkJsCg1Wa4Bu7wJ4PUryZREFvqvPPD1PXGboHyRFXNvUz4tzttF2

      Building a Real-Time Pump.fun Token Launch Detector

      In this article, you’ve learned to set up a real-time stream for tracking newly launched tokens on Pumpfun using gRPC. By leveraging gRPC, you’ve overcome the limitations of on-chain data tracking and can now receive live transaction data with milliseconds latency.

      This setup allows you to stay ahead of token launches and access detailed token information using Shyft’s gRPC

      For additional support, join our Discord Server or follow us on Twitter for the latest updates. Our team is here to assist you in utilizing this innovative technology.

      You can find all the code related to this article on our GitHub repository. You can clone it and use it to build innovative solutions.

      Need to detect token launches even before they’re confirmed? RabbitStream streams directly from Solana shreds — giving you 15–100ms earlier detection than standard Yellowstone gRPC.

      Resources