Question it answers
“For a Solana launchpad like pump.fun: which tokens just launched, which are still climbing the bonding curve, and which have graduated to a DEX, and what’s a given token’s bonding-curve status?”Lands one row per launchpad event (
created / traded / migrated) from the decoded launchpadEvents feed, and derives a per-token latest-status projection. The four legacy pump.fun surfaces, new, bonding, graduated, and per-token status, are all reads over this one recipe.
What you get
The recipe reads the master-blocklaunchpadEvents array and lands two surfaces:
- The launchpad event log, keyed by exchange, one row per
created/traded/migratedevent. - A per-token status projection, keyed by token, latest bonding progress, graduated flag, and graduation time.
| Column | Description |
|---|---|
token_address | The launchpad token (SPL mint) |
exchange_address | The launchpad program (the legacy :exchange, e.g. pump.fun 6EF8…F6P) |
launchpad_platform | Friendly name, pumpfun, raydium_launchlab |
event_type | created · traded · migrated (migrated = graduated) |
progress_percentage | Bonding-curve progress 0–100 (sparse, set on trading activity) |
pool_address | The DEX pool a token migrated into, populated on the migrated event (take max(pool_address)) |
token_name, token_symbol, token_uri | Emitted on the created event only |
trade_direction, token_amount, native_amount | On traded events, native price = native_amount / token_amount |
block_number, log_index, event_ts, tx_hash | On-chain ordering + provenance |
Source
The transform reads one per-block array,launchpadEvents, one row per event. event_type distinguishes created (a new token, carries name/symbol/uri), traded (a bonding-curve fill, carries progress_percentage and trade amounts), and migrated (graduation to a DEX pool, carries pool_address). On the Solana feed today the price field (current_price) is not populated, see Fidelity gaps. The exchange_address (launchpad program) is shared by every token on a platform.
Destination
| Destination | Tables | Access |
|---|---|---|
| ClickHouse (first-class) | fact_launchpad_events (by exchange) + fact_token_bonding_status (by token) | prefix scan on (chain_id, exchange_address, block_number) for the event log; per-token aggregate for status |
| Postgres | launchpad_events + token_bonding_status (materialized view) | index on (exchange_address, block_number); unique on token_address |
| MySQL | launchpad_events + token_bonding_status (trigger-maintained) | same shape |
fact_launchpad_events is ordered for the by-exchange event log (bloom skip index on token_address for the by-token log); fact_token_bonding_status is keyed by token for the latest-state read.
Full schema
ClickHouse, fact_launchpad_events
ClickHouse, fact_launchpad_events
ClickHouse, fact_token_bonding_status (per-token)
ClickHouse, fact_token_bonding_status (per-token)
launchpad_events table plus a token_bonding_status current-state projection (a materialized view on Postgres, a trigger-maintained table on MySQL).Run it
Everything runs in your infrastructure: the sink writes into a database you own and you query it with plain SQL, no API and no per-call limits. Prerequisites- Docker and Docker Compose.
- A Data Feeds key, a
cm_live_…key withcontinuum:readscope (this is not your legacy Web3 API key).
Sign up for a Data Feeds key
Log in to the Moralis admin panel to create your account and generate a
cm_live_… key.tokenBondingStatus in the Moralis Admin Panel, choose Solana as the chain (launchpad activity is densest on pump.fun and Raydium LaunchLab) and your destination, then run it with Docker. The quickstart walks through it end to end.
Backfill by use case. The new / bonding / graduated lists are event feeds, run realtime to track launches live, no backfill needed. A per-token status is current state, backfill from the token’s
created event to capture its full curve. See History & backfill.Example reads
New tokens on a launchpad, the token’screated event, newest first:
migrated event, plus the DEX pool they migrated into (max grabs the non-empty pool_address, since a graduation can emit more than one migrated row):
Other ways to consume this data
The sink is the way to get these pre-shaped tables. The same underlying data is also available as the raw decoded feed, if you’d rather shape it yourself:- Your existing message clients: stream
launchpadEventslive with Kafka / AMQP / SQS (great for a real-time launch feed). - REST / Arrow Flight: pull the decoded Solana block stream directly.
- Your warehouse: query it via Iceberg from Snowflake, BigQuery, Spark, or DuckDB.
launchpadEvents array to project yourself, not these tables. All read the one data lake into your infrastructure. See What are Data Feeds?.
Modes
Shipped defaults: ClickHousehybrid (backfill → realtime), Postgres / MySQL historical. For live launch discovery use ClickHouse, see the overview.
Multichain
Launchpad activity is densest on Solana (pump.fun, Raydium LaunchLab) and Base; on Ethereum mainnet thelaunchpadEvents array is effectively empty. Point the recipe at Solana in the Admin Panel wizard for real coverage. On Solana logIndex isn’t row-unique within an instruction, so vendor_event_id widens with (tokenAddress, eventType) to keep rows distinct.
Fidelity gaps
name/symbolride on thecreatedevent; a token seen only viatradedevents carries none until you join Token Metadata (also the source ofdecimals).progress_percentageis sparse:createdevents carry no curve progress (0 is coerced to null), so a freshly-created token has null progress until its first trade.- No price in the feed.
current_pricelands empty on the Solana feed today (0 populated in live sampling). Derive the native price per token fromtradedevents (native_amount / token_amount), and convert to USD with a SOL/USD mark (e.g. wrapped SOL from a Token Prices sync). Liquidity (cumulative curvenative_amount, or post-graduation Pair Reserves) and FDV (token_metadata.total_supply× price) are derive-or-omit. pool_addressarrives on themigratedevent: the DEX pool the token graduated into (verified live). A graduation can emit more than onemigratedrow, so take the non-empty value withmax(pool_address)rather thananyLast.logoand other off-chain metadata aren’t in the feed.
token_address, exchange_address, event_type, progress_percentage, graduation (the migrated event, with pool_address), token name/symbol (on created), trade amounts, and timestamps, are sourced from launchpadEvents.
Migrating from the REST API
The four endpoints share most of their response shape, so the common fields map once:| Legacy field (all four endpoints) | Data Feeds | Fidelity |
|---|---|---|
tokenAddress / mint | token_address | exact |
name, symbol | token_name / token_symbol on the created event, or Token Metadata | exact |
decimals | token_metadata.decimals (join Token Metadata) | exact |
priceNative | derive native_amount / token_amount from traded events, currentPrice is not populated on the Solana feed today | calculated |
priceUsd | priceNative × a SOL/USD mark (wrapped SOL via Token Prices) | calculated |
liquidity | cumulative curve native_amount × price; post-graduation, Pair Reserves × price | calculated |
fullyDilutedValuation | token_metadata.total_supply × price | calculated |
logo | not in the feed, bring your own token list, or omit | add yourself |
:exchange is the launchpad’s onchain program address (pump.fun is 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P); each event carries it as exchange_address plus a friendly launchpad_platform (pumpfun, raydium_launchlab), filter on either. None of the lists have a per-call cap anymore; page with a keyset on the sort column.
New tokens by exchange
created events on a launchpad, newest first, a view over fact_launchpad_events:
createdAt maps to min(event_ts) over the created event (exact).
- Launches are an event list, run the recipe realtime for a live feed, no backfill needed; index back only to list tokens created before you started.
- A brand-new token has no price and no curve progress until its first trade.
Bonding tokens by exchange
bondingCurveProgress maps to the latest non-null progress_percentage per token (exact).
- Progress is carried forward: it updates with each trade, and is null until the first trade (same as the old endpoint, which had nothing to report before curve activity).
- A token leaves the bonding list the moment it emits a
migratedevent; theHAVINGclause excludes those.
Graduated tokens by exchange
migrated event, a token with one has left the curve for a DEX pool:
graduatedAt maps to minIf(event_ts, event_type = 'migrated'), and poolAddress, which the old endpoint didn’t even expose, is max(pool_address) over the token’s migrated events (both exact).
This one is not a 1:1 swap. The legacy response bundled prices, liquidity, and FDV, but a graduated token trades on a normal DEX pool, so price it with Token Prices and read pool liquidity with Pair Reserves, keyed on the migrated
pool_address. Run those recipes alongside this one if you serve those fields.pool_addressis only populated onmigratedevents (verified live), and a graduation can emit more than onemigratedrow, take the non-empty value withmax(pool_address), notanyLast.- Graduations are an event list, run realtime to catch them as they happen.
Token bonding status
mint, bondingProgress, and graduatedAt map to token_address, bonding_progress, and graduated_at (all exact). On Postgres or MySQL it’s a single-row lookup on the maintained status table:
- Status is current state, not an event list, backfill from the token’s
createdevent to capture its full curve and graduation history. graduated/graduated_atcome from themigratedevent; both are empty until the token graduates.
Related
Token Metadata
Names, symbols, and decimals for launchpad tokens.
Token Prices
USD marks to layer onto bonding and graduated tokens.

