Lunar Shadow Labs

One feed across 12 Solana venues

Our feed decodes 12 Solana DEX and launchpad programs into one JSON shape. This page lists each venue, its id in the feed, and the event kinds it produces.

Venue and event matrix

venue idprogramswaplaunchcurve_completemigrationpool_createliquidity
pumppump.fun bonding curve✓✓✓✓ → pumpswap
launchlabRaydium LaunchLab (bonk.fun, StonkFun, …)✓✓✓ → raydium_cpmm / raydium_v4
meteora_dbcMeteora Dynamic Bonding Curve✓✓✓✓ → meteora_damm_v1 / v2
pumpswapPumpSwap AMM✓✓✓
raydium_v4Raydium AMM v4✓✓✓
raydium_cpmmRaydium CPMM✓✓✓
raydium_clmmRaydium CLMM✓✓✓
pancake_v3PancakeSwap v3 (Solana)✓✓✓
orcaOrca Whirlpool✓✓✓
meteora_dlmmMeteora DLMM✓✓✓
meteora_damm_v1Meteora Dynamic AMM✓✓✓
meteora_damm_v2Meteora DAMM v2✓✓✓

One more id, token2022, is not a venue: it is the source of mint_update messages when a Token-2022 mint changes (see Token-2022 risk flags).

Pick venues and kinds

Filters run on our side. Ask only for what you need:

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

URL = "wss://feed.lunarshadowlabs.com/ws?venues=raydium_clmm,orca,meteora_dlmm&kinds=swap,pool_create"
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"] in ("swap", "pool_create"):
                print(m["venue"], m["kind"], m["pool"], m["base_mint"], m["quote_mint"])

asyncio.run(main())

You can also watch specific mints, pools or wallets with ?watch=, or change the filter at any time by sending a subscribe message (docs).

The same shape on every venue

A swap on Orca looks like a swap on PumpSwap: the same core fields, with venue-specific extras in x. Here is a real Orca Whirlpool swap:

{
  "v": 1,
  "seq": 185956,
  "kind": "swap",
  "venue": "orca",
  "keys": [
    "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn",
    "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "HyA4ct7i4XvZsVrLyb5VJhcTP1EZVDZoF9fFGym16zcj",
    "ESTNga8KiDRrVhZoP1sU6pdNWWxoi77t1tNm3zRpc5W9"
  ],
  "stage": "executed",
  "source": "geyser",
  "commitment": "processed",
  "slot": 454292864,
  "sig": "4n2EMHCWVNz1rQiwTZj14RaYrg2RgmJCcHYfrDshXUBEzVk5Q1WaadcE5fnc6iZ9Sf2qc79ZrQ1V7dmrWAaBChCu",
  "ix": 3,
  "inner": 9,
  "t_ingest_us": 1791394901881453,
  "t_emit_us": 1791394901881565,
  "via": "6Vo3245eszAb5wuqEMw8mGdbfRUdKbHhDHP5LcaGuTAB",
  "pool": "HyA4ct7i4XvZsVrLyb5VJhcTP1EZVDZoF9fFGym16zcj",
  "user": "ESTNga8KiDRrVhZoP1sU6pdNWWxoi77t1tNm3zRpc5W9",
  "base_mint": "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn",
  "quote_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "is_buy": false,
  "base_amount": "165681306",
  "quote_amount": "1023390",
  "base_decimals": 6,
  "quote_decimals": 6,
  "price": 0.006176858601054243,
  "fees": {
    "lp": "80634",
    "protocol": "12048"
  },
  "partial": false,
  "derived": false,
  "base_flags": {
    "program": "token2022",
    "decimals": 6,
    "supply": "829378323769471768",
    "mint_authority": null,
    "freeze_authority": null,
    "metadata_pointer": "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn",
    "extensions": [
      14,
      18,
      19
    ]
  },
  "quote_flags": null,
  "x": {
    "input_transfer_fee": "0",
    "output_transfer_fee": "0",
    "post_sqrt_price": "1450064766146880936",
    "quote_rule": "priority"
  }
}

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

A pool's tokens are oriented the same way everywhere: the first of USDC, USDT, SOL present is the quote, so is_buy (the user received the base token) and price (quote per whole base token) are comparable across venues. On liquidity events, lp_amount (LP tokens minted or burned) is reported for Raydium AMM v4, PumpSwap and Meteora Dynamic AMM, and is null on the other venues.

Guides by venue

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