Skip to main content

Overview

solana.dex_swaps is a Turbo-only curated dataset that emits one normalized row per DEX swap across the major Solana AMMs and bonding-curve programs. Each row is a fully decoded swap event with the bought/sold token, amounts (both raw and decimal-scaled), the underlying program, and the transaction context needed to trace the swap back on-chain.
This dataset is exclusive to Turbo and is not available in Mirror.
Use it when you want to:
  • Track swap volume, prices, or flows across multiple Solana DEXes without decoding each program’s instructions yourself.
  • Attribute swaps to routers/aggregators (for example, Jupiter) versus direct DEX interactions.
  • Join raw and decimal-scaled amounts alongside the on-chain transaction signature and slot.

Quick start

Scope the source to the DEXes you care about with filter.program_ids (program IDs) and options.dex (human-readable labels). Both accept a comma-separated string.
sources:
  dex_swaps:
    type: dataset
    dataset_name: solana.dex_swaps
    version: 1.0.0
    start_block: 426725306
    filter:
      program_ids: whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc,CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
    options:
      dex: raydium_clmm,orca_whirlpool
See Solana Sources for general Solana source configuration (start_block, block_ranges, filters, checkpoints).

Supported DEXes and program IDs

The dataset currently decodes swap events from the following programs. The project column is the human-readable label (use in options.dex); project_main_id carries the raw on-chain program ID (use in filter.program_ids).
DEX (project)Program ID (project_main_id)
meteora_damm_v1Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
meteora_damm_v2cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
raydium_clmmCAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
raydium_cpmmCPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C
orca_whirlpoolwhirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
pump_ammpAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA
pumpfun6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P

Schema

All amounts describe a single side of the trade: the bought token is what the trader received, the sold token is what they gave up.
ColumnTypeNullableDescription
idstringnoUnique swap id.
projectstringyesHuman-readable DEX label (for example, raydium_clmm, pump_amm).
versionuint8yesDEX/event schema version.
block_timestampuint64noUnix timestamp (seconds) of the block.
block_slotuint64noSolana slot the transaction landed in.
trade_sourcestringnodirect when the swap is a top-level instruction; otherwise the program ID of the router/aggregator (for example, Jupiter) that invoked it.
token_bought_amountfloat64noAmount received, scaled by token_bought_decimals (human units).
token_sold_amountfloat64noAmount paid, scaled by token_sold_decimals (human units).
token_bought_amount_rawuint64noAmount received in raw base units (unscaled integer).
token_sold_amount_rawuint64noAmount paid in raw base units (unscaled integer).
token_bought_mint_addressstringnoSPL mint address of the token received.
token_sold_mint_addressstringnoSPL mint address of the token paid.
token_bought_decimalsuint8noDecimals of the bought mint.
token_sold_decimalsuint8noDecimals of the sold mint.
project_main_idstringnoThe DEX program ID (raw, on-chain).
trader_idstringnoThe swap instruction’s own payer/owner account. See field notes.
tx_idstringnoTransaction signature.
instruction_indexint64noIndex of the swap instruction within the flattened instruction list.
parent_instruction_indexint64yesParent instruction index when invoked by a router (inner instruction); null for a top-level swap.

Field notes

  • token_bought_* vs token_sold_* — direction is from the trader’s perspective. A row always has both sides populated; token_bought_amount and token_sold_amount are the decimal-scaled versions of the _raw integer amounts.
  • trade_source — distinguishes direct DEX interactions from router-routed ones. When a swap is an inner instruction of an aggregator, this holds the parent (router) program ID rather than direct.
  • trader_id — the payer/owner account attached to the swap instruction itself. For router-routed swaps this is typically the router-owned account that signed the inner instruction, not necessarily the end user that submitted the transaction. Use tx_id plus the outer transaction’s fee payer if you need the originating wallet.
  • project vs project_main_id — use project for human-readable filters and grouping; use project_main_id when you need the exact on-chain program ID.

Guide: Stream swaps from selected DEXes to Postgres

This pipeline streams Raydium CLMM and Orca Whirlpool swaps. filter.program_ids narrows the source at scan time; options.dex tells the decoder which DEX projects to emit.
name: solana-dex-swaps
resource_size: m

sources:
  dex_swaps:
    type: dataset
    dataset_name: solana.dex_swaps
    version: 1.0.0
    start_block: 426725306
    filter:
      program_ids: whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc,CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
    options:
      dex: raydium_clmm,orca_whirlpool

sinks:
  postgres_swaps:
    type: postgres
    from: dex_swaps
    schema: public
    table: solana_dex_swaps
    secret_name: MY_POSTGRES
    primary_key: id

Guide: Filter to a single DEX

Narrow both the source filter and the decoder options to a single DEX — here, Raydium CLMM:
name: raydium-clmm-swaps
resource_size: s

sources:
  dex_swaps:
    type: dataset
    dataset_name: solana.dex_swaps
    version: 1.0.0
    start_block: 426725306
    filter:
      program_ids: CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
    options:
      dex: raydium_clmm

transforms:
  raydium_clmm:
    type: sql
    primary_key: id
    sql: |
      SELECT
        id,
        block_slot,
        block_timestamp,
        trader_id,
        tx_id,
        token_bought_mint_address,
        token_sold_mint_address,
        token_bought_amount,
        token_sold_amount,
        trade_source
      FROM dex_swaps

sinks:
  postgres_raydium:
    type: postgres
    from: raydium_clmm
    schema: public
    table: raydium_clmm_swaps
    secret_name: MY_POSTGRES
    primary_key: id

Guide: Separate direct swaps from router-routed swaps

Aggregators like Jupiter invoke DEX programs as inner instructions. Use trade_source to split direct swaps from aggregator flow:
name: dex-swaps-by-source
resource_size: m

sources:
  dex_swaps:
    type: dataset
    dataset_name: solana.dex_swaps
    version: 1.0.0
    start_block: 426725306
    filter:
      program_ids: whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc,CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
    options:
      dex: raydium_clmm,orca_whirlpool

transforms:
  categorized_swaps:
    type: sql
    primary_key: id
    sql: |
      SELECT
        id,
        project,
        tx_id,
        trader_id,
        token_bought_mint_address,
        token_sold_mint_address,
        token_bought_amount,
        token_sold_amount,
        CASE
          WHEN trade_source = 'direct' THEN 'direct'
          ELSE 'router'
        END AS swap_kind,
        trade_source AS router_program_id,
        block_slot,
        block_timestamp
      FROM dex_swaps

sinks:
  postgres_categorized:
    type: postgres
    from: categorized_swaps
    schema: public
    table: solana_dex_swaps_categorized
    secret_name: MY_POSTGRES
    primary_key: id

Guide: Track swaps involving a specific token

Filter by mint on either side of the trade — for example, all Raydium CLMM and Orca Whirlpool swaps involving USDC:
name: usdc-dex-swaps
resource_size: s

sources:
  dex_swaps:
    type: dataset
    dataset_name: solana.dex_swaps
    version: 1.0.0
    start_block: 426725306
    filter:
      program_ids: whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc,CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
    options:
      dex: raydium_clmm,orca_whirlpool

transforms:
  usdc_swaps:
    type: sql
    primary_key: id
    sql: |
      SELECT
        id,
        project,
        tx_id,
        trader_id,
        token_bought_mint_address,
        token_sold_mint_address,
        token_bought_amount,
        token_sold_amount,
        block_slot,
        block_timestamp
      FROM dex_swaps
      WHERE token_bought_mint_address = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
         OR token_sold_mint_address   = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'

sinks:
  postgres_usdc_swaps:
    type: postgres
    from: usdc_swaps
    schema: public
    table: usdc_dex_swaps
    secret_name: MY_POSTGRES
    primary_key: id
Keep filter.program_ids and options.dex in sync — filter.program_ids scopes which slots are scanned during backfills (see Filtering by Account or Program), and options.dex controls which decoded DEX projects are emitted. Listing a DEX in one but not the other will either scan more slots than needed or drop rows you expected.