Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Goal: SDK call for market volume over a time period

Abierto
#1,429 3 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@MicBun ya está trabajando en esto.

Desde el 6/10/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

Why this was created

The order book query surface covers the book, depth, and best prices, but not activity. get_order_book, get_market_depth, and get_best_prices all answer "what is resting right now". Nothing answers "how much traded".

The data is already on the node. ob_order_events records every fill with price, amount, outcome, participant, and block timestamp, so volume and unique traders are computable without new state. What is missing is an SDK call.

Outcome

Each SDK exposes get_market_activity(query_id, from_ts, to_ts), returning volume and unique traders for a single order book over a time window, in the same shape and at the same level as get_market_depth.

Current state

The metrics are reachable today only by writing the SQL yourself. Kwil nodes accept ad hoc read-only SQL through the user.query RPC and the mainnet gateway serves it, so the figure can be computed against a production node right now, but every consumer re-derives the rule by hand.

Scope

No node change. The SDKs ship one pinned SQL statement run through the ad hoc query RPC, with $query_id, $from_ts, $to_ts as parameters, returning one row per call. The statement is the definition and the three SDKs carry the same text. It has been run against mainnet and cross-checked per event type; the record is on the sub-issues.

If a get_market_activity node action is added later, each SDK swaps its method body to call it with no signature change. That action is node work tracked separately and is not required for this Goal. The index described under Future improvement below is likewise not required, though every sub-issue notes its absence.

Definition to hold fixed

Volume is filled orders, counted once per trade, in cents of that market's own collateral token.

Event Volume Counts as a trader
direct_buy_fill price * amount yes
direct_sell_fill no, it is the same trade yes
mint_fill, burn_fill 100 * amount, YES row only yes
split_placed no, it is a deposit no
placements, cancels, amends, settled no no
  • Mint and burn are volume. They are two-party matches with agreed complementary prices, settled by creating or destroying a pair rather than transferring shares, and they are the arbitrage boundaries that hold YES + NO near 100.
  • split_placed is not volume. It is unilateral: collateral in, pair out, no counterparty and no agreed price.
  • Use an allowlist over event types, never a denylist, so an event type added later is excluded until someone decides it is volume.
  • Volume is always per bridge and never summed across bridges. Base units differ between collateral tokens by orders of magnitude and this layer holds no price feed. Unique traders are comparable across bridges.
Returned fields

One object, because every field falls out of the same pass over the event rows: bridge, volume_cents, direct_cents, mint_burn_cents, unique_traders, fill_count, direct_fill_count, shares_traded, first_event_ts, last_event_ts, coverage_from_block, coverage_complete. The direct / mint_burn split is diagnostic: two markets with identical volume behave differently if one is counterparty trading and the other is one participant working the mint and burn boundary.

Retention

ob_order_events is trimmed once indexed, so the node holds a rolling window. A naive query returns 0 for a market whose events were trimmed, indistinguishable from a market with no activity. The statement therefore returns coverage_from_block, the earliest retained block, and coverage_complete, which compares it to the market's creation height. A zero with coverage_complete = false is truncation, not inactivity.

Sub-issues

In dependency order. Python wraps Go through its C bindings, so Go ships first and is tagged; JS is independent.

  1. trufnetwork/sdk-go#205 Problem: GetMarketActivity in sdk-go
  2. trufnetwork/sdk-js#180 Problem: getMarketActivity in sdk-js
  3. trufnetwork/sdk-py#139 Problem: get_market_activity in sdk-py

Future improvement: index ob_order_events for per-market time windows

Out of scope for this Goal, but worth recording here because all three sub-issues reference it and the SDK call is the first consumer that will feel its absence.

ob_order_events is indexed on id (for the indexer's sequential sync) and block_height (for trim_order_events), and on nothing else. The activity statement filters on query_id and a block_timestamp range, so every call is a sequential scan of the whole retained table. Measured on a synced mainnet node at ~120k rows, a seven-day windowed aggregate ran in about 35 ms, which is fine on its own. The problem is the shape: cost scales with total retained events, not with the window requested. A one-hour window costs the same as a one-year window, every call gets slower as retention grows, and a consumer charting several markets or polling repeatedly multiplies that scan.

The fix is a node migration adding an index on (query_id, block_timestamp). It turns the per-market read into an index range scan whose cost tracks the number of events in the window, and it also serves the existing per-market event queries in 050-order-book-event-queries.sql. Writes are not a concern: the table is append-only with periodic trims, and the index is small relative to the rows.

One decision to make before choosing the column order. (query_id, block_timestamp) serves the per-market case this Goal defines. If protocol-wide windowed reads are also wanted later, such as "all fills in the last hour across every market", a leading block_timestamp serves those range scans better, and the two access patterns want two indexes rather than a compromise on one. Decide which pattern the index is really for rather than guessing.

Because this is a public read that any caller can invoke and that every node executes, the index should land before the SDK call sees heavy use. It needs no change to the SDKs: the pinned statement is unchanged and simply gets faster.

Out of scope

  • Any node change: action, migration, or the index above.
  • Historical metrics beyond the retained window. That belongs to a service that keeps its own copy.
  • Protocol wide totals across bridges.
  • Charting endpoints and bucketed series.

Deadline

ETA: 19-Oct-2026 (Monday)

Lenguaje dominante
Go
Estrellas
7
Forks
3
Merge medio
13 h 15 min
PR fusionados (30 d)
13

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de trufnetwork/node

Todos los issues de trufnetwork/node

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.