Numia Docs

Cosmos SDK

We work with different teams to index their data so institutions, devs, or users can access it. One of the advantages of the Cosmos SDK ecosystem is that every chain built on top of it inherits the same underlying data model — blocks, transactions, messages, and events are emitted with a consistent shape across the entire ecosystem. That means we can expose the same three tables for every Cosmos SDK chain we index, and the queries you write against one chain work, with minimal changes, against any of the others.

Here’s a list of the chains currently supported under Numia SQL.

Onboarding new chains

We onboard new Cosmos SDK chains continuously. If the chain you need isn’t listed below — or if you need to index your own chain or protocol — reach out at support@numia.xyz or through our website and we’ll scope the integration with you.

Available chains

Cosmos Hub

Cosmos Hub

cosmoshub_4

Osmosis

Osmosis

osmosis_1

Stride

Stride

stride_1

Injective

Injective

injective_1

Sei

Sei

pacific_1

dYdX

dYdX

dydx_mainnet_1

Celestia

Celestia

celestia

Noble

Noble

noble_1

Secret Network

Secret Network

secret_4

Akash

Akash

akashnet_2

Xion

Xion

xion_mainnet_1

Mantra

Mantra

mantra_1

Interwoven (Initia)

Interwoven

interwoven_1

Zigchain

Zigchain

zigchain_1

Babylon

Babylon

bbn_1

Echelon

Echelon

echelon_1

Y

Yominet

yominet_1

What’s in each chain’s database

Inside every database above, we expose the same three tables. One raw table is fed directly by the ingestion pipeline; two source tables are derived from it through ClickHouse materialized views and stay within seconds of chain tip.

Rawraw_block_results

One row per block — the raw payload returned by the chain’s RPC.

Derivedsrc_events

One row per event — begin-block, transaction, end-block, and finalize-block events normalized into a single shape.

Derivedsrc_messages

One row per message inside every transaction, with the full message body kept as JSON.

Parsed tables on request

The three tables above keep payloads as raw JSON so they cover every message and event type a chain emits — including ones we’ve never seen. If you need decoded, column-per-field tables for specific message types or modules (e.g. bank.MsgSend, staking.MsgDelegate, IBC transfers, DEX trades), reach out at support@numia.xyz and we’ll build them for you.

What’s in a Cosmos SDK block?

Before diving into columns, it helps to have a mental model of what each row in these tables actually represents. A Cosmos SDK block is a small hierarchy:

Blocks

A block is the unit of consensus. Cosmos chains use the CometBFT (formerly Tendermint BFT) consensus algorithm to commit blocks, each containing a header, a set of transactions, and the side-effects produced by executing them. Every block has a unique, monotonically increasing block_height per chain, and a block_timestamp derived from the consensus round that produced it. In our schema, raw_block_results stores one row per block — the unmodified payload returned by the chain’s RPC, including header, transactions, and execution results.

Transactions

A transaction is a signed user instruction that asks the chain to perform one or more actions. A block contains zero or more transactions, ordered by their position inside the block (transaction_index). Each transaction has a hash, a list of messages, gas accounting, and an execution result (success or failure with a code/log). Transactions don’t get their own dedicated table — they’re embedded inside raw_block_results.transactions (decoded) and raw_block_results.tx_results (execution outcomes), and are surfaced one-row-per-message in src_messages.

Messages

Messages (Msgs) are the actual actions inside a transaction. A MsgSend transfers tokens; a MsgDelegate stakes with a validator; a custom module message might mint an NFT or open a CLOB position. A single transaction can carry multiple messages, executed atomically. src_messages stores one row per message, with the message body kept as JSON in the message column and the protobuf type URL (e.g. /cosmos.bank.v1beta1.MsgSend) in message_type, so the same table holds every message type a chain emits without per-module schema work.

Events

Events are the granular, machine-readable side-effects emitted while a block is being processed. They have a type (e.g. transfer, withdraw_rewards, ibc_transfer) and a list of attributes — key/value pairs that describe the action in detail. Events come from three places in the block lifecycle:

  • Begin-block events — emitted before any transactions run (e.g. epoch rollovers, reward distributions).
  • Per-transaction events — emitted while executing each message inside a transaction.
  • End-block / finalize-block events — emitted after transactions run (e.g. validator set changes, slashing).

src_events stores one row per event across all three sources, normalized onto a single block_section_index axis (see Section indexing) so you can query begin/tx/end events with the same shape.

How it all fits together

Sourceraw_block_results

One row per block. Fields that feed the derived tables:

  • transactions
  • begin_block_events
  • tx_results[*].events
  • end_block_events
  • finalize_block_events
Derivedsrc_messages

Fed by transactions — one row per message inside every tx.

Derivedsrc_events

Fed by the four event arrays — one row per event, normalized across begin / tx / end / finalize.

The rest of this page is the column-level reference for those three tables.

raw_block_results

The unparsed block payload as returned by the chain’s RPC. This is the source of truth — everything else is derived from it.

Column Type Notes
chain_id
String e.g. cosmoshub-4
block_height PK
UInt64 Unique per chain
block_timestamp
DateTime64(9) Nanosecond precision
hash
String Block hash
header
String Raw JSON header
data
String Raw JSON data field (contains txs)
last_commit
String Raw JSON last-commit payload
tx_results
String Raw JSON array of per-tx results
begin_block_events
String Raw JSON events (legacy BeginBlock)
end_block_events
String Raw JSON events (legacy EndBlock)
finalize_block_events
String Raw JSON events (ABCI 2.x FinalizeBlock)
validator_updates
String? Raw JSON
consensus_param_updates
String? Raw JSON
transactions
String Decoded transactions, JSON array (default '[]')
ingestion_timestamp
DateTime64 Used by ReplacingMergeTree to dedupe re-ingestions

src_events

One row per event emitted in the block, regardless of where it came from (begin-block, transaction, end-block, finalize-block). Built from raw_block_results via a materialized view that flattens each event section with ARRAY JOIN.

Column Type Notes
chain_id
String
block_height PK
UInt64
block_timestamp
DateTime
block_section_index PK
UInt8 0 = block_begin, 1 = transactions_results, 2 = block_end, 3 = block_finalize
block_section
String Human-readable section name (matches the index above)
transaction_index PK
String Zero-based tx index; empty for non-tx events
transaction_hash
String Hex hash; for non-tx events: 'This event was not emitted due to a transaction'
message_index PK
String From the msg_index event attribute when present
event_raw_index PK
String Position of the event inside its source array
event_msg_index
String Per-message ordinal of the event
event_type_index
String Per-(message, event_type) ordinal — useful for picking the Nth transfer, etc.
event_type
String e.g. transfer, withdraw_rewards, ibc_transfer
event_attributes
String Raw JSON array of {key, value, index?}
processed_at
DateTime Used by ReplacingMergeTree
ingestion_timestamp
DateTime64 Inherited from the raw row

Section indexing

ABCI 1.x chains emit events through begin_block_events / end_block_events, while ABCI 2.x chains emit through finalize_block_events. We normalize both worlds onto the same block_section_index axis:

block_section_indexblock_sectionSource
0block_beginbegin_block_events, or finalize_block_events with mode = 'BeginBlock'
1transactions_resultsPer-tx events inside tx_results[*].events
2block_endend_block_events, or finalize_block_events with mode = 'EndBlock'
3block_finalizefinalize_block_events not tagged as Begin/End

src_messages

One row per message inside every transaction in the block. Built from raw_block_results.transactions via a materialized view.

Column Type Notes
chain_id
String
block_height PK
UInt64
block_timestamp
DateTime
transaction_index PK
String Zero-based tx index within the block
transaction_hash
String
message_index PK
String Zero-based message index within the tx
message_type
String e.g. /cosmos.bank.v1beta1.MsgSend
message
String Raw JSON body of the message
processed_at
DateTime Used by ReplacingMergeTree
ingestion_timestamp
DateTime64 Inherited from the raw row

Querying tips

  • Always include a block_height predicate (or block_timestamp resolved through it) to take advantage of the partition key.
  • For tables with ReplacingMergeTree, append FINAL only when you need the deduplicated view at query time — otherwise let background merges handle it.
  • Use JSON_VALUE(message, '$.from_address') or JSONExtractString(message, 'from_address') to drill into src_messages.message without re-materializing columns.