Lunar Shadow Labs

pump.fun → PumpSwap migrations in real time

When a pump.fun bonding curve fills, two things happen on chain: the curve completes, then its liquidity migrates into a new PumpSwap pool. Our feed turns those into two decoded messages, curve_complete and migration, so you don't have to parse the program's events yourself.

Market data only. A migration is an on-chain fact, not a signal to buy or sell.

Subscribe

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

URL = "wss://feed.lunarshadowlabs.com/ws?kinds=curve_complete,migration&venues=pump,launchlab,meteora_dbc"
HEADERS = {"Authorization": f"Bearer {os.environ['LSL_KEY']}"}

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"] == "curve_complete":
                print("curve complete", m["venue"], m["mint"])
            elif m["kind"] == "migration":
                print("migrated", m["mint"], m["venue"], "->", m["to_venue"], m["to_pool"])

asyncio.run(main())

For production use, add the resume and reconnect loop from the docs.

The curve completes

{
  "v": 1,
  "seq": 39388,
  "kind": "curve_complete",
  "venue": "pump",
  "keys": [
    "32NtSoRKFXupR75EM3mPJZ2CLgdRwem37ChcnogRpump",
    "So11111111111111111111111111111111111111112",
    "AYuNPrKAvAPr7hxhddYkxFp1cwh2n7wkbL56p25nFw5C",
    "BwWK17cbHxwWBKZkUYvzxLcNQ1YVyaFezduWbtm2de6s"
  ],
  "stage": "executed",
  "source": "geyser",
  "commitment": "processed",
  "slot": 454291875,
  "sig": "E7SRPj62nRg7xnB5FmhnseaweMJsHo9j2HNqojJ9HXKY7jVxnhRob43hLaEk2FoeKoa4VYSipniKkUgesx5KJhj",
  "ix": 2,
  "inner": 5,
  "t_ingest_us": 1791394632043530,
  "t_emit_us": 1791394632043578,
  "via": "MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e",
  "mint": "32NtSoRKFXupR75EM3mPJZ2CLgdRwem37ChcnogRpump",
  "curve": "AYuNPrKAvAPr7hxhddYkxFp1cwh2n7wkbL56p25nFw5C",
  "user": "BwWK17cbHxwWBKZkUYvzxLcNQ1YVyaFezduWbtm2de6s",
  "quote_mint": "So11111111111111111111111111111111111111112"
}

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

curve is the bonding curve account and user the wallet whose trade completed it.

The migration

{
  "v": 1,
  "seq": 39860,
  "kind": "migration",
  "venue": "pump",
  "keys": [
    "32NtSoRKFXupR75EM3mPJZ2CLgdRwem37ChcnogRpump",
    "So11111111111111111111111111111111111111112",
    "7xWVbWAa6rZ18eDdqJPJa4RMLYUq55bH5kURKZHpGd6w",
    null
  ],
  "stage": "executed",
  "source": "geyser",
  "commitment": "processed",
  "slot": 454291879,
  "sig": "BUfoYNxSd272g2R1uwguuhswcapPsqUfRDFeMUYSNMnjNGsEBxqRcVrsocGdnS1cUhxwA9g2d5S2AmTtf649Cud",
  "ix": 2,
  "inner": 40,
  "t_ingest_us": 1791394632951407,
  "t_emit_us": 1791394632951434,
  "via": null,
  "mint": "32NtSoRKFXupR75EM3mPJZ2CLgdRwem37ChcnogRpump",
  "from_curve": "AYuNPrKAvAPr7hxhddYkxFp1cwh2n7wkbL56p25nFw5C",
  "to_venue": "pumpswap",
  "to_pool": "7xWVbWAa6rZ18eDdqJPJa4RMLYUq55bH5kURKZHpGd6w",
  "base_amount": "206900000000000",
  "quote_amount": "1104806152",
  "quote_mint": "So11111111111111111111111111111111111111112",
  "fee": "15000001"
}

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

Raydium migrations come from LaunchLab

Tokens graduating from Raydium LaunchLab (the launchpad behind bonk.fun, StonkFun and others) migrate to raydium_cpmm or raydium_v4. There is no separate curve-complete message for LaunchLab, so the migration is the message to watch:

{
  "v": 1,
  "seq": 143993,
  "kind": "migration",
  "venue": "launchlab",
  "keys": [
    "3XFyVaZMFcA5qht3STXyKPJ4fUAqHEDCM52okDveWqih",
    "Xs3oZwbHvqis4NYcf4YKWmEia2eC84wSiVrcYcTqpH8",
    "6hGrxWm6xXjDbf5WPT3QgTkvMxZi4o2jsUUtpTexTpWo",
    null
  ],
  "stage": "executed",
  "source": "geyser",
  "commitment": "processed",
  "slot": 454292601,
  "sig": "5DmGV8LaXoA4SARR4a3MiaEnDuji9dYSB96Do7Z7HS1oTH4UJP2z4jM4fm81hVjw5rckhU868HGqExpgiEWERsRV",
  "ix": 2,
  "inner": null,
  "t_ingest_us": 1791394829450596,
  "t_emit_us": 1791394829450688,
  "via": null,
  "mint": "3XFyVaZMFcA5qht3STXyKPJ4fUAqHEDCM52okDveWqih",
  "from_curve": "GTBhLTEQpioBDt5uh3w5uH9uhHfY3drxYuHKVkVJPUgB",
  "to_venue": "raydium_cpmm",
  "to_pool": "6hGrxWm6xXjDbf5WPT3QgTkvMxZi4o2jsUUtpTexTpWo",
  "base_amount": "204831000000000",
  "quote_amount": "5922030322",
  "quote_mint": "Xs3oZwbHvqis4NYcf4YKWmEia2eC84wSiVrcYcTqpH8",
  "fee": null
}

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

The quote mint isn't always SOL: LaunchLab platforms can configure other quote tokens, so read quote_mint rather than assuming.

Meteora Dynamic Bonding Curve

Meteora DBC launchpads (meteora_dbc) produce both curve_complete and migration; their migrations go to meteora_damm_v1 or meteora_damm_v2.

Things to know

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