Skip to main content
DB
Back homeUse case

Blockchain & on-chain analytics

Turn decoded chain events into typed, versioned entity state inside the engine, with each writer owning its own slice of the row.

The problem

Where the usual stack breaks

  1. 01

    On-chain data is the messiest input in the industry: events arrive out of order, come back on a reorganization, and mean nothing until they are folded into the entity state your product actually queries.

  2. 02

    You bolt that together from an indexer, a queue, a transform layer and a warehouse, and then a holder count or a balance differs depending on which copy answered, because each copy applied the events in a different order.

  3. 03

    What you want is ordering that does not depend on arrival, per-entity rows that several producers can extend independently, and point-in-time reads, inside the database rather than beside it.

Architecture

How NYXDB does it

Decoded events land in one table and a transformation folds them into one slice of a versioned entity table; other producers write their own slices of the same row, and the engine settles which version wins, so late and shuffled writes converge to the same state.

  1. 01

    Ingest events

    Decoded events land in an append-only table, one row at a time through SQL or in bulk through write batches and native bulk frames.

  2. 02

    Fold (transformation)

    Entity state stays current on its own: CREATE TRANSFORMATION folds events per entity into one ATTRIBUTE GROUP, with MAX and COUNT lanes.

  3. 03

    Extend the row

    Add a new slice to the row while everything keeps running, with ALTER TABLE … ADD ATTRIBUTE GROUP, and let another producer write it.

  4. 04

    Read at a commit

    Reread the winners exactly as they stood at a commit, with AS OF COMMIT and the sequence from a write receipt.

Examples

In practice

Activity per balance, kept current by a transformation
CREATE TRANSFORMATION balance_activity INTO balances ATTRIBUTE GROUP activity AS
SELECT
chain_id,
recipient AS address,
token,
COUNT(*) AS transfer_count,
MAX(transferred_at) AS last_transfer_at,
MAX(_index) AS activity_index
FROM transfers
GROUP BY chain_id, recipient, token;
Current balances of one address
SELECT address, token, amount, updated_at
FROM balances
WHERE chain_id = 1 AND address = '0x9c2e4f1a';
Balances exactly as they were at a commit
SELECT address, token, amount
FROM balances AS OF COMMIT 42
WHERE chain_id = 1;

The examples use the same two tables on every page. See the SQL reference for full syntax.

Capabilities

What you get out of the box

Bulk ingest routes

Move decoded rows in bulk with write batches and native bulk frames, or one row per statement in plain SQL.

In-database folds

Entity state stays current from the event table, with no indexer state layer to run, with CREATE TRANSFORMATION.

Attribute groups

Several producers each own a slice of one keyed row, and no group ever overwrites another.

Arrival-order independent

In-order, shuffled and late writes all converge to the same state, with VALID BY and REVISION BY.

Point-in-time reads

Read the winners as they stood at any commit sequence, with AS OF COMMIT.

Live schema growth

Add a group or a column while running transformations keep running.

Learn more

From raw events to entity state you can query

Fold a stream of events into one slice of a row, then read it as it was at any commit.