Host client
The hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. client receives indexed blockchain data from multiple indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication. over P2P. It verifies the data using attestation records, runs WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. lensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. transforms to produce viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. documents, and serves those documents over GraphQL.
If indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication. are data producers, hostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. are consumers and servers. The separation lets you scale serving independently from indexingIndexing The process of parsing blockchain data and storing it as structured, schema-compliant documents in defraDB..
Architecture
Components
| Component | What it does |
|---|---|
| ShinzoHubShinzoHub Shinzo's coordination chain: a Cosmos SDK chain (v0.53.4) with an integrated EVM, running CometBFT consensus. It holds the view, host, and indexer registries and the economic layer (staking, pricing, payments). It does not store or serve indexed blockchain data. Listener | Subscribes to ShinzoHubShinzoHub Shinzo's coordination chain: a Cosmos SDK chain (v0.53.4) with an integrated EVM, running CometBFT consensus. It holds the view, host, and indexer registries and the economic layer (staking, pricing, payments). It does not store or serve indexed blockchain data. events over a CometBFTCometBFT The BFT consensus engine used by Cosmos SDK chains. ShinzoHub runs CometBFT for block production. Hosts connect to ShinzoHub's CometBFT RPC over WebSocket to receive real-time event notifications. WebSocket. Watches for Registered (new viewsView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape.) and EntityRegistered (new indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication./hostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL.). |
| DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p. | Embedded database. Handles storage, P2P replication, content addressing, CRDTCRDT A data structure that multiple nodes can update independently and then merge without coordination, always reaching the same result. defraDB uses CRDTs — specifically MerkleCRDTs — to merge document updates from peers. merging, and query serving. |
| Attestation Handler | Listens to DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p.'s event bus for new BlockSignatureBlockSignature A document the indexer writes after it finishes processing a block. It contains a Merkle root over all document CIDs for that block, signed with the indexer's identity key. Hosts check it to verify the batch came from a known indexer. documents. Verifies signatures and creates AttestationRecordsAttestationRecord A document a host creates to track how many independent indexers produced the same data for a given block. The `vote_count` field is a P-counter CRDT, so counts converge across hosts without any coordination step. with P-counterP-counter A CRDT that only increments. Each node tracks its own count separately; merging just takes the max per node and sums them. `AttestationRecord.vote_count` uses a P-counter so all hosts converge on the same indexer count without coordinating. vote counts. |
| ViewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. Processor | Downloads WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. lensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. binaries, runs LensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. transforms on primitives, writes viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. documents. |
| NetworkHandler | Manages P2P peer connections through DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p.'s node abstraction. |
Key source files
| Component | File |
|---|---|
| Main hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. logic | pkg/host/host.go |
| ShinzoHubShinzoHub Shinzo's coordination chain: a Cosmos SDK chain (v0.53.4) with an integrated EVM, running CometBFT consensus. It holds the view, host, and indexer registries and the economic layer (staking, pricing, payments). It does not store or serve indexed blockchain data. event subscription | pkg/shinzohub/events.go |
| Attestation processing | pkg/attestation/attestationRecordService.go |
| ViewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. management | pkg/view/viewManager.go |
| Network handler | shinzo-app-sdk/pkg/defra/network_handler.go |
ShinzoHub event subscription
No webhooks. The hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. opens a persistent WebSocket connection to ShinzoHubShinzoHub Shinzo's coordination chain: a Cosmos SDK chain (v0.53.4) with an integrated EVM, running CometBFT consensus. It holds the view, host, and indexer registries and the economic layer (staking, pricing, payments). It does not store or serve indexed blockchain data.'s CometBFTCometBFT The BFT consensus engine used by Cosmos SDK chains. ShinzoHub runs CometBFT for block production. Hosts connect to ShinzoHub's CometBFT RPC over WebSocket to receive real-time event notifications. node and subscribes to transaction events:
cancel, channel, err := shinzohub.StartEventSubscription(wsURL)
This subscribes to two query filters:
"tm.event='Tx' AND Registered.key EXISTS": viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. registration events."tm.event='Tx' AND EntityRegistered.key EXISTS": new indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication. or hostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. joining.
Events arrive on the returned channel. The hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL.'s main loop reads from this channel and dispatches to the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. processor or network handler as appropriate.
Attestation system
When a hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. receives data from multiple indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication. for the same block, it creates an AttestationRecord using a P-counterP-counter A CRDT that only increments. Each node tracks its own count separately; merging just takes the max per node and sums them. `AttestationRecord.vote_count` uses a P-counter so all hosts converge on the same indexer count without coordinating. CRDTCRDT A data structure that multiple nodes can update independently and then merge without coordination, always reaching the same result. defraDB uses CRDTs — specifically MerkleCRDTs — to merge document updates from peers..
AttestationRecord schema
type Ethereum__Mainnet__AttestationRecord {
attested_doc: String @index
source_doc: String
CIDs: [String]
doc_type: String @index
vote_count: Int @crdt(type: pcounter)
}
The @crdt(type: pcounter) annotation tells DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p. to use a Positive Counter merge strategy. Each node tracks its own increments separately, and merges are deterministic:
Host A: {A: 1, B: 0} (saw 1 indexer)
Host B: {A: 0, B: 1} (saw 1 indexer)
Merge: {A: 1, B: 1} -> total = 2
Attestation flow
The upsert pattern in GraphQL:
mutation {
upsert_AttestationRecord(
create: { vote_count: 1 },
update: { vote_count: 1 },
filter: { attested_doc: { _eq: "block_1000" } }
) { _docID }
}
View-specific attestation collections
The hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. creates separate attestation collections per viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape.:
collectionName := fmt.Sprintf("Ethereum__Mainnet__AttestationRecord_%s", viewName)
So you get AttestationRecord_Block for primitive attestations and AttestationRecord_TokenTransfer for a specific viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape..
CID array merging doesn't work right
When multiple hostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. create AttestationRecordsAttestationRecord A document a host creates to track how many independent indexers produced the same data for a given block. The `vote_count` field is a P-counter CRDT, so counts converge across hosts without any coordination step. for the same document but with different CID sets, they may create separate documents instead of merging. The P-counterP-counter A CRDT that only increments. Each node tracks its own count separately; merging just takes the max per node and sums them. `AttestationRecord.vote_count` uses a P-counter so all hosts converge on the same indexer count without coordinating. for vote_count merges correctly, but the CID array ([]string) has no CRDTCRDT A data structure that multiple nodes can update independently and then merge without coordination, always reaching the same result. defraDB uses CRDTs — specifically MerkleCRDTs — to merge document updates from peers. merge strategy. Documented in the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL.-client ADR-03.
Re-org handling
When a blockchain re-orgRe-org Short for chain reorganization: the canonical block at a given height changes. When this happens, different indexers may briefly hold different versions of the same block. Hosts store each version as a separate document; applications pick the one with more attestation votes. happens, different indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication. may briefly have different versions of the same block:
Indexer A: Block #1000 with hash 0xaaa (pre-reorg)
Indexer B: Block #1000 with hash 0xbbb (post-reorg)
These produce separate documents (different CIDs), each with its own AttestationRecordAttestationRecord A document a host creates to track how many independent indexers produced the same data for a given block. The `vote_count` field is a P-counter CRDT, so counts converge across hosts without any coordination step.. The post-reorg version accumulates more votes as indexersIndexer A node that reads blockchain data from a source chain, parses it into structured documents, and writes them to defraDB. Indexers are write-only: they push data out over P2P and reject all incoming replication. converge, and applications pick the one with higher consensus.
View discovery
HostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. watch for viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. registrations through two paths.
At startup, the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. calls FetchAllRegisteredViews(), which queries CometBFTCometBFT The BFT consensus engine used by Cosmos SDK chains. ShinzoHub runs CometBFT for block production. Hosts connect to ShinzoHub's CometBFT RPC over WebSocket to receive real-time event notifications. with tx_search?query="Registered.key EXISTS", paginates through all historical registration transactions, and processes each viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. bundle.
At runtime, the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. subscribes to tm.event='Tx' AND Registered.key EXISTS over WebSocket. When a new event arrives, it extracts the key, creator, and view attributes and processes the bundle.
There is a known bug here: the View RegistryView Registry The ShinzoHub EVM precompile at `0x0210`. When `register(bytes)` is called, it decodes the VWL bundle, registers the view in SourceHub via ICA, and deploys an SVS-1 contract for the new view. precompilePrecompile A contract at a fixed EVM address implemented in native Go rather than Solidity bytecode. ShinzoHub's three registries (View `0x0210`, Host `0x0211`, Indexer `0x0212`) are precompiles so they can call Cosmos SDK keepers directly and trigger ICA packets. emits "ViewRegistered" with attributes view_address/view_name/creator/data, but the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. subscribes to "Registered" and expects attributes key/creator/view. Neither event type nor attribute names match. Fixed in ShinzoHubShinzoHub Shinzo's coordination chain: a Cosmos SDK chain (v0.53.4) with an integrated EVM, running CometBFT consensus. It holds the view, host, and indexer registries and the economic layer (staking, pricing, payments). It does not store or serve indexed blockchain data. v2.
View processing pipeline
When the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. receives a viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. bundle (from either discovery path):
ProcessViewFromWireFormat(): base64-decodes the wire bytes, parses VWLVWL The binary format for view bundles. It is a single byte stream: a `"VWL"` magic header and version byte, then the GraphQL query, SDL, lens metadata, and a lens blob (optionally zstd-compressed) containing the WASM binaries. format, extracts the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. name from SDL via regex.PostWasmToFile(): for each lensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM., base64-decodes the WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. bytes, validates the WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. magic number (0x00 0x61 0x73 0x6D), and writes to disk with a sha256-derived filename.SetupLensInDefraDB(): builds a LensConfig (source collection, destination, lensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. path, arguments) and callsdefraNode.DB.AddLens()to register with LensVMLensVM The WASM execution environment inside a host that runs lens transforms. It supports Wasmtime, Wasmer, and Wazero runtimes, and can run lenses in both directions if the WASM module exposes an `inverse()` function..ConfigureLens(): callsdefraNode.DB.AddView()with or without a transform CID, auto-corrects field names for schema compatibility.SubscribeTo(): enables P2P replication for the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape.'s collection viaCreateP2PCollections().SaveViewToRegistry(): persists viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. metadata toviews.jsonin the lensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. registry directory so the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. can recover on restart.
Lens transforms
The hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. runs LensVMLensVM The WASM execution environment inside a host that runs lens transforms. It supports Wasmtime, Wasmer, and Wazero runtimes, and can run lenses in both directions if the WASM module exposes an `inverse()` function. (source-gh/lens) to execute WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. modulesModule A Cosmos SDK building block that owns a slice of chain state, handles messages, and emits events. ShinzoHub adds five custom modules (`x/admin`, `x/sourcehub`, `x/host`, `x/indexer`, `x/view`) on top of the standard Cosmos set. that transform primitives into viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. documents.
WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. runtimes in use:
| Runtime | Language | Where |
|---|---|---|
| WasmtimeWasmtime A WASM runtime written in Rust. The primary runtime used to execute lenses in production hosts. | Rust | Primary runtime in production hostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. |
| WasmerWasmer A WASM runtime written in Rust. Viewkit uses it to validate lenses locally before deployment. | Rust | viewkitViewkit A CLI tool for creating, testing, and deploying views. It defines the SDL, attaches lenses, runs local validation using the Wasmer runtime, packages everything into a ViewBundle, and submits a deploy transaction to the View Registry. local testing |
| WazeroWazero A pure-Go WASM runtime with no CGo dependency. An alternative lens runtime in LensVM, useful when avoiding CGo is a requirement. | Go | Pure Go alternative, no CGo dependency |
LensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. binary size varies by source language. AssemblyScript produces ~73 KB WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM.. Rust produces ~200 KB.
GraphQL serving
| Port | Purpose |
|---|---|
| 444 | GraphQL Playground (interactive query UI) |
| 9181 | Internal DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p. API |
| 8080 | Health endpoint, Prometheus metrics |
Example query:
{
USDCTransfer(filter: { blockNumber: { _gte: 19540000 } }) {
from
to
amount
blockNumber
}
}
Earnings
HostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. receive the Compute Factor component of viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. pricing. There is an immediate payment per query served, plus a potential bonus at epochEpoch A fixed number of blocks treated as one unit of time. On Ethereum, an epoch is 32 blocks. end if the hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL.'s coverage (uptime and data availability) exceeds the network average.
Document filtering
HostsHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. can filter incoming documents by contract address, event type, or function signature. A hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. running only ERC-20 transfer viewsView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. does not need to store every logLog A document type the indexer produces for event logs emitted during transaction execution. `topics` holds the indexed parameters and `data` holds the non-indexed ones, both as raw hex. ABI decoding happens later, in a lens. from every contract.
Metrics
Port 8080 exposes Prometheus metrics: block processing rates, attestation counts, viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. status (active, syncing, errored), and P2P peer counts.
Resource requirements
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4 cores |
| RAM | 4 GB | 8 GB |
| Storage | 100 GB | 500 GB (depends on number of viewsView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape.) |
| Network | 100 Mbps | 1 Gbps |
Key files
| Path | Purpose |
|---|---|
cmd/main.go | Entry point |
pkg/host/ | Core hostHost A Shinzo node that receives indexed data from indexers over P2P, verifies it, runs lens transforms to produce view documents, and serves those documents over GraphQL. logic |
pkg/shinzohub/ | WebSocket watcher for ShinzoHubShinzoHub Shinzo's coordination chain: a Cosmos SDK chain (v0.53.4) with an integrated EVM, running CometBFT consensus. It holds the view, host, and indexer registries and the economic layer (staking, pricing, payments). It does not store or serve indexed blockchain data. events |
pkg/attestation/ | Attestation record creation and management |
pkg/view/ | ViewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. lifecycle (discovery, loading, execution) |
pkg/graphql/ | GraphQL serving configuration |
pkg/playground/ | GraphQL Playground UI |
pkg/schema/ | DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p. collection schemas |
LensLens A WASM module that transforms primitive documents (e.g., raw `Log` records) into view documents (e.g., `USDCTransfer`). Lenses must be deterministic: the same input always produces the same output. Hosts run them via LensVM. integration is imported from source-gh/lens. DefraDBdefraDB A peer-to-peer, document-oriented database embedded in every indexer and host. It handles storage, content addressing, CRDT merging, query serving, and P2P replication via libp2p. configuration comes from shinzo-gh/shinzo-app-sdk.