Lunar Shadow Labs

pump.fun trades and new tokens over WebSocket

By Lunar Shadow Labs · Updated

Every pump.fun token launch, bonding-curve buy and sell arrives on our feed as decoded JSON (launch and swap messages with venue pump). After a token graduates, its trades continue on PumpSwap (venue pumpswap) in the same format, so one subscription follows a token from launch to AMM.

Market data only. Nothing here is a recommendation to buy or sell any token.

Subscribe

Ask for launches and swaps on pump.fun and PumpSwap, and print each new token and its trades:

import asyncio, json, os, websockets   # pip install websockets

URL = "wss://feed.lunarshadowlabs.com/ws?venues=pump,pumpswap&kinds=launch,swap"
HEADERS = {"Authorization": f"Bearer {os.environ['LSL_KEY']}"}
SOL = "So11111111111111111111111111111111111111112"

def handle(m):
    if m["kind"] == "launch":
        print("new token", m["symbol"], m["mint"], "creator", m["creator"],
              "quote", "SOL" if m["quote_mint"] == SOL else m["quote_mint"])
    elif m["kind"] == "swap":
        base = int(m["base_amount"]) / 10 ** m["base_decimals"]
        quote = int(m["quote_amount"]) / 10 ** m["quote_decimals"]
        side = "buy " if m["is_buy"] else "sell"
        print(m["venue"], side, m["base_mint"], f"{base:,.0f} tokens for {quote:.4f}", "price", m["price"])

async def main():
    async with websockets.connect(URL, additional_headers=HEADERS, max_size=None) as ws:
        async for raw in ws:
            m = json.loads(raw)
            if m["kind"] in ("launch", "swap"):   # control messages (gaps, resume) are covered in the docs
                handle(m)

asyncio.run(main())

Amounts are strings of raw integer units; divide by 10 ** *_decimals to get whole tokens. To follow only some tokens, add a watchlist (&watch=<mint>,…); for production use, add the resume and reconnect loop from the docs.

A new token

{
  "v": 1,
  "seq": 15555257,
  "kind": "launch",
  "venue": "pump",
  "keys": [
    "EFsx6FNr4nDcfVeig3CGC57esiiuHGauzHJRGaE2pump",
    "So11111111111111111111111111111111111111112",
    "E9Lkf2gmuAib18mVk2kt6C1QYKDT48sNQM2cvHUspAHH",
    "A62G6hPp3ifiYDQrLLDpUMimhapfZGfSPPU7Msi6ommh"
  ],
  "stage": "executed",
  "source": "geyser",
  "commitment": "processed",
  "slot": 454422525,
  "sig": "34Dzd6jzxS5LBYDz86s3Zva9uRqdtqpF8Gdw8DwyVgAFavXz2bUC7Y1wvQDbyxMFJVZEq4ety7C7gxF6oXpFTbZh",
  "ix": 2,
  "inner": 22,
  "t_ingest_us": 1791429793132019,
  "t_emit_us": 1791429793132044,
  "via": null,
  "mint": "EFsx6FNr4nDcfVeig3CGC57esiiuHGauzHJRGaE2pump",
  "curve": "E9Lkf2gmuAib18mVk2kt6C1QYKDT48sNQM2cvHUspAHH",
  "creator": "A62G6hPp3ifiYDQrLLDpUMimhapfZGfSPPU7Msi6ommh",
  "user": "A62G6hPp3ifiYDQrLLDpUMimhapfZGfSPPU7Msi6ommh",
  "name": "Weird Cat",
  "symbol": "WEIRDCAT",
  "uri": "https://ipfs.io/ipfs/Qmd57ANHxjo1NgPjXEQE1Z2TdiCxLuJTYbNVf5yNFbQju8",
  "quote_mint": "So11111111111111111111111111111111111111112",
  "token_program": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",
  "base_flags": {
    "program": "token2022",
    "decimals": 6,
    "supply": "2000000000000000",
    "mint_authority": null,
    "freeze_authority": null,
    "metadata_pointer": "EFsx6FNr4nDcfVeig3CGC57esiiuHGauzHJRGaE2pump",
    "extensions": [18, 19]
  },
  "quote_flags": {
    "program": "spl",
    "decimals": 9,
    "supply": "0",
    "mint_authority": null,
    "freeze_authority": null,
    "extensions": []
  },
  "x": {
    "virtual_token_reserves": "1073000000000000",
    "virtual_sol_reserves": "30000000000",
    "token_total_supply": "1000000000000000"
  }
}

Captured from our live feed on 2026-10-08.

A buy on the bonding curve

{
  "v": 1,
  "seq": 15545446,
  "kind": "swap",
  "venue": "pump",
  "keys": [
    "3Rw3MR7pSR1dvM92zYDLLGmsMvFDzHDtsKWxUQtRHbod",
    "So11111111111111111111111111111111111111112",
    "8d5dZmzFxmE7RunRvVyWE2tRNuqx2qT3XmAr7gBCfaCH",
    "CQuLrqCTiGU5kxspotsMCkBixRzLziYsdGHQkdM91wzF"
  ],
  "stage": "executed",
  "source": "geyser",
  "commitment": "processed",
  "slot": 454422441,
  "sig": "3xPUVquom7AU54LbVNtonF5BPR6SE48cEkdaBkY8mfSyHGbT2FHudEKrUKARWoQ3xkYkKtieZKi2PUD3bCS8pjP3",
  "ix": 2,
  "inner": 7,
  "t_ingest_us": 1791429771082010,
  "t_emit_us": 1791429771082023,
  "via": "6Vo3245eszAb5wuqEMw8mGdbfRUdKbHhDHP5LcaGuTAB",
  "pool": "8d5dZmzFxmE7RunRvVyWE2tRNuqx2qT3XmAr7gBCfaCH",
  "user": "CQuLrqCTiGU5kxspotsMCkBixRzLziYsdGHQkdM91wzF",
  "base_mint": "3Rw3MR7pSR1dvM92zYDLLGmsMvFDzHDtsKWxUQtRHbod",
  "quote_mint": "So11111111111111111111111111111111111111112",
  "is_buy": true,
  "base_amount": "283311232776",
  "quote_amount": "105811989",
  "base_decimals": 6,
  "quote_decimals": 9,
  "price": 0.00000037348321124867027,
  "fees": {
    "fee": "1005214",
    "creator_fee": "317436",
    "cashback": "0",
    "buyback_fee": "502607",
    "holder_rewards": "0"
  },
  "partial": false,
  "derived": false,
  "base_flags": {"program": "token2022", "decimals": 6, "supply": "1000000000000000", "mint_authority": null, "freeze_authority": null, "metadata_pointer": "3Rw3MR7pSR1dvM92zYDLLGmsMvFDzHDtsKWxUQtRHbod", "extensions": [18, 19]},
  "quote_flags": {"program": "spl", "decimals": 9, "supply": "0", "mint_authority": null, "freeze_authority": null, "extensions": []},
  "x": {
    "virtual_sol_reserves": "109699736263",
    "virtual_token_reserves": "293437354101224",
    "real_sol_reserves": "79699736263",
    "real_token_reserves": "13537354101224",
    "ix_name": "buy_exact_quote_in"
  }
}

Captured from our live feed on 2026-10-08.

After graduation: PumpSwap

When a curve fills, you receive curve_complete and migration messages (see pump.fun → PumpSwap migrations), and from then on the token trades on PumpSwap. The swap message has the same top-level fields; only fees and x change:

"venue": "pumpswap",
"is_buy": true, "base_amount": "331761682541", "quote_amount": "165870004",
"fees": {"lp": "327807", "protocol": "81952", "coin_creator": "1557081",
         "cashback": "0", "buyback": "40976", "holder_rewards": "0"},
"x": {"pool_quote_amount_in": "163903164", "pool_quote_amount_in_with_lp_fee": "164230971",
      "user_quote_amount_in": "165870004", "pool_base_token_reserves": "191748931596308",
      "pool_quote_token_reserves": "77342908953", "virtual_quote_reserves": "17224611782",
      "ix_name": "buy"}

Excerpt of a PumpSwap buy captured from our live feed on 2026-10-08 (seq 15545409).

Why not parse pump.fun yourself?

You can: the program's events are public. What you take on is keeping the decoder current as pump.fun changes its instructions and fee fields (the cashback, buyback and holder-reward fields above are newer additions that older trades don't carry), resolving which side is base and quote, scaling amounts by each mint's decimals, and reading every mint's Token-2022 state. Yellowstone gRPC vs a decoded WebSocket goes through the trade-off.

Try the feed

One WebSocket, 12 Solana venues, one flat price.

Start free trial Read the docs

3-day free trial, then $49/month per license plus applicable tax, charged automatically every month until you cancel. Cancel online any time before the trial ends and you pay nothing. Starting a trial means you agree to the Terms. Market data only, no signals or advice.

← All guides

More guides