Skip to main content

Dynamic Schema Generation

The ChainStream GraphQL schema is dynamically generated at startup by activecube-rs, a Rust library that compiles Cube definitions into a fully-typed async-graphql schema. Each Cube maps to an analytical data model backed by an OLAP table, and activecube-rs automatically produces:
  • A top-level Query field for the Cube (nested under its Chain Group)
  • A Record type ({Cube}Record) representing the selectable dimensions
  • A Filter input ({Cube}Filter) matching the dimension hierarchy
  • An OrderBy enum ({Cube}OrderBy) with ASC/DESC variants for every dimension path
This means the schema is always in sync with the underlying data models — no handwritten SDL files to maintain.
Because the schema is generated from Cube definitions, any new data model added in Rust is automatically reflected in the GraphQL endpoint after deployment.

Root Query Structure

The root query type is named ChainStream. Cubes are organized into three Chain Groups, each exposed as a top-level field:
type ChainStream {
  EVM(network: Network!, dataset: Dataset, aggregates: Aggregates) {
    DEXTrades(...): [DEXTradesRecord!]!
    Transfers(...): [TransfersRecord!]!
    BalanceUpdates(...): [BalanceUpdatesRecord!]!
    Blocks(...): [BlocksRecord!]!
    Transactions(...): [TransactionsRecord!]!
    Events(...): [EventsRecord!]!
    Calls(...): [CallsRecord!]!
    # ... more EVM Cubes
  }

  Solana(dataset: Dataset, aggregates: Aggregates) {
    DEXTrades(...): [DEXTradesRecord!]!
    Instructions(...): [InstructionsRecord!]!
    DEXOrders(...): [DEXOrdersRecord!]!
    # ... more Solana Cubes
  }

  Trading(dataset: Dataset, aggregates: Aggregates) {
    Pairs(...): [PairsRecord!]!
    Tokens(...): [TokensRecord!]!
  }
}
There are no Mutation or Subscription types — the GraphQL API is read-only analytical queries.

Chain Groups

Cubes are organized into three groups based on the blockchain ecosystem they target:
Chain Groupnetwork ArgumentAvailable NetworksDescription
EVMRequiredeth, bsc, polygonShared Cubes for all EVM-compatible chains
SolanaNot neededsol (implicit)Cubes for Solana including chain-specific ones (Instructions, DEXOrders)
TradingNot neededCross-chain (sol, eth, bsc)Pre-aggregated trading analytics (OHLC candles, token statistics) with a chain dimension
The EVM group requires a network argument to select which chain to query. Solana and Trading do not need a network argument — Solana is implicit, and Trading includes a chain dimension within the data.
See Chain Groups for the full breakdown of which Cubes belong to each group.

Chain Group Parameters

Every Chain Group accepts two optional parameters that control data source behavior:

Dataset

The dataset parameter controls the time scope of data queried:
ValueDescription
combinedFull range — queries both recent and historical data (default)
realtimeRecent data only (approximately the last 24 hours)
archiveHistorical data up to the retention TTL
query {
  Solana(dataset: realtime) {
    DEXTrades(limit: {count: 10}, orderBy: Block_Time_DESC) {
      Block { Time }
      Trade { Buy { Amount } }
    }
  }
}

Aggregates

The aggregates parameter controls whether pre-aggregated (DWM/DWS) tables are used:
ValueDescription
yesPrefer pre-aggregated tables when available (default for applicable Cubes)
noUse raw detail tables only
onlyOnly use pre-aggregated tables (faster but limited fields)
query {
  Trading(aggregates: only) {
    Pairs(
      where: { Token: { Address: { is: "0x..." } } }
      limit: {count: 100}
    ) {
      Interval { Time }
      Price { Ohlc { Open High Low Close } }
      Volume { Usd }
    }
  }
}
See Dataset & Aggregates for detailed usage, supported tables, and performance guidance.

Common Argument Pattern

Within a Chain Group, every Cube field accepts the same set of standard arguments, plus optional Cube-specific selectors:
ArgumentTypeRequiredDescription
where{Cube}FilterNoNested filter object matching the dimension hierarchy
limitLimitInputNoPagination: {count: Int, offset: Int}
orderBy{Cube}OrderByNoSort order enum ({Path}_ASC / {Path}_DESC)
selectorsFilter inputNoShortcut filters (e.g., tokenAddress: {is: "..."})
query {
  Solana {
    DEXTrades(
      tokenAddress: {is: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"}
      where: { Block: { Time: { after: "2026-01-01T00:00:00Z" } } }
      limit: { count: 50, offset: 0 }
      orderBy: Block_Time_DESC
    ) {
      Block { Time }
      Trade { Buy { Amount PriceInUSD } }
    }
  }
}

LimitInput

input LimitInput {
  count: Int   # Number of rows to return
  offset: Int  # Number of rows to skip (for pagination)
}
Default count varies by Cube (typically 25). Maximum is 10,000 for most Cubes.

Generated Types per Cube

For each Cube, activecube-rs generates three companion types:

Record Type

{Cube}Record — The return type containing all selectable dimensions and metrics. Field structure mirrors the Cube’s dimension hierarchy.

Filter Input

{Cube}Filter — A nested input object where each dimension maps to a filter primitive (StringFilter, IntFilter, DateTimeFilter, etc.).

OrderBy Enum

{Cube}OrderBy — Enum variants for every dimension path in both ASC and DESC directions (e.g., Block_Time_ASC, Trade_Buy_Amount_DESC).
Example for DEXTrades:
# Record type (return shape)
type DEXTradesRecord {
  Block: DEXTradesBlockRecord
  Transaction: DEXTradesTransactionRecord
  Trade: DEXTradesTradeRecord
  Pool: DEXTradesPoolRecord
  IsSuspect: Boolean
  count: Int
  sum(of: DEXTradesSumOf!): Float
}

# Filter input
input DEXTradesFilter {
  Block: DEXTradesBlockFilter
  Transaction: DEXTradesTransactionFilter
  Trade: DEXTradesTradeFilter
  Pool: DEXTradesPoolFilter
  IsSuspect: BoolFilter
  any: [DEXTradesFilter!]  # OR logic
}

# OrderBy enum (partial)
enum DEXTradesOrderBy {
  Block_Time_ASC
  Block_Time_DESC
  Trade_Buy_Amount_ASC
  Trade_Buy_Amount_DESC
  # ...
}

Introspection

The schema supports standard GraphQL introspection. You can explore types, fields, and arguments using __schema and __type queries:
query {
  __schema {
    queryType {
      fields {
        name
        description
        args { name type { name } }
      }
    }
  }
}
The GraphQL IDE auto-fetches the introspection schema to power auto-complete and inline documentation. You can explore the full schema interactively without writing introspection queries manually.

Next Steps

Data Cubes

Explore all 25 Cubes — their fields, selectors, and data warehouse layers.

Chain Groups

Understand the EVM, Solana, and Trading Chain Groups and their available Cubes.

Dataset & Aggregates

Control data source scope and pre-aggregation behavior with dataset and aggregates.

Filtering

Learn how to use where filters and selector shortcuts to narrow your queries.

Ordering & Pagination

Sort results and paginate through large datasets with orderBy and limit.

Metrics & Aggregation

Use count, sum, avg, min, max, and uniq to aggregate data in your queries.