Skip to main content

Viewkit

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. is a CLI tool for creating, testing, and deploying viewsView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape.. It does not process or serve data (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. do that). It packages a viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. into a binary bundle on your machine and submits a transaction 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..

What viewkit does and does not do

What it does:

  • Define GraphQL SDL schemas for viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. output.
  • Configure 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 for data mapping.
  • Pre-validate transforms locally using WasmerWasmer A WASM runtime written in Rust. Viewkit uses it to validate lenses locally before deployment. runtime.
  • Package everything into a ViewBundleViewBundle The packaged form of a view: GraphQL query, SDL, lens metadata, and WASM lens binaries. Viewkit produces a ViewBundle and submits it to the View Registry. The wire format is VWL. (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. binary format).
  • Deploy 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..

What it does not do:

  • Process data (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. do this).
  • Store data (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. does this).
  • Serve queries (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. do this).
  • Run as a daemon (it is a CLI tool).

View definition

A viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. has three pieces:

  1. A query that picks which primitive data to select (e.g., "all LogsLog 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 the USDC contract").
  2. An SDL, the GraphQL schema defining the output shape.
  3. A 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. (optional), a WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. moduleModule 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 transforms the data.

The @materialized directive

In the SDL, @materialized(if: true) 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 pre-compute and store the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. data. @materialized(if: false) computes it on query.

@materialized(if: true) is recommended for now. Queries are faster because data is already materialized when the query arrives. The tradeoff is more storage on 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..

Important: the limit parameter should be on the source query (e.g., Log(limit: 100)), not on the materialized viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. collection.

CLI commands

# Initialize a new view
viewkit view create my-usdc-view \
--query 'Ethereum__Mainnet__Log { address topics data transactionHash blockNumber }'

# Add GraphQL schema
viewkit view add sdl \
'type USDCTransfer @materialized(if: true) { from: String to: String amount: String blockNumber: Int }' \
--name my-usdc-view

# Add a WASM lens with arguments
viewkit view add lens \
--label "decode_transfers" \
--url "https://raw.githubusercontent.com/shinzonetwork/wasm-bucket/main/bucket/decode_log/decode_log.wasm" \
--args '{"abi":"[{\"type\":\"event\",\"name\":\"Transfer\",...}]"}' \
--name my-usdc-view

# Remove a lens
viewkit view remove lens --label "decode_transfers" --name my-usdc-view

# Inspect the bundle
viewkit view inspect my-usdc-view

# Generate a wallet for deployments
viewkit wallet generate

# Deploy to devnet
viewkit view deploy my-usdc-view \
--target devnet \
--rpc http://rpc.devnet.shinzo.network:8545

What happens during deploy

When you run viewkit view deploy, the following happens inside core/service/deploy.go:

  1. Tests the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. locally (builds a temporary 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. instance, applies 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., validates output).
  2. Derives an ECDSAECDSA The signature algorithm used by Ethereum and ShinzoHub (secp256k1 curve). Viewkit derives an ECDSA private key from the wallet to sign deploy transactions. private key from the wallet.
  3. 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.: reads the WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. file and base64-encodes it.
  4. Calls viewbundle.NewBundler().BundleView(view) to produce compressed 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. wire bytes.
  5. Computes viewID: keccak256(sender.Bytes(), wireBytes).
  6. ABIABI Describes how to encode and decode function calls, arguments, and event data for an EVM contract. Lenses such as `decode_log` take ABI JSON as input to read raw log data.-encodes the transaction: method selector keccak256("register(bytes)")[:4] + ABIABI Describes how to encode and decode function calls, arguments, and event data for an EVM contract. Lenses such as `decode_log` take ABI JSON as input to read raw log data.-encoded bytes.
  7. Sends EVMEVM The runtime that executes Solidity smart contracts. ShinzoHub embeds an EVM module so its registries are accessible as precompiled contracts at fixed addresses, callable from any EVM tooling. transaction to 0x0000000000000000000000000000000000000210 (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.).
  8. Polls for receipt and checks status.

VWL wire format

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. (ViewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. Wire Language) is the binary format for viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. bundles.

Byte layout

The bundle is a single byte stream written in the order below. Each section is appended directly after the previous one.

#SectionContents
1Header"VWL" magic (3 bytes), version (1 byte, currently 0x01)
2Querylength (u32), GraphQL query string
3SDLlength (u32), GraphQL schema string
4LensLens 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. metadatacount (u16); 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.: ID (u32), args length (u32), JSON args bytes
5LensLens 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. blobcodec byte (0 = none, 1 = zstd), blob length (u32), WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. count (u16); for each WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM.: length (u32) and bytes

WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. binaries can be 70-200+ KB each. zstd compression is applied before the bundle goes on chain. 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. decompresses when applying.

Two implementations of the wire format exist:

ImplementationLanguageSideUsed by
viewbundleViewBundle The packaged form of a view: GraphQL query, SDL, lens metadata, and WASM lens binaries. Viewkit produces a ViewBundle and submits it to the View Registry. The wire format is VWL.-goGoServer-sideviewkitViewkit 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., 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.
viewbundleViewBundle The packaged form of a view: GraphQL query, SDL, lens metadata, and WASM lens binaries. Viewkit produces a ViewBundle and submits it to the View Registry. The wire format is VWL.TypeScriptClient-sideBrowser-based tooling

Key functions:

// Encode a view into wire bytes
wireBytes := viewbundle.BundleView(view)

// Decode just the header (without loading the full WASM body)
header := viewbundle.DecodeHeader(encodedBytes)

// Re-encode a modified header
reEncoded := viewbundle.EncodeHeader(decodedValue)

There is a known issue with v0.6.2 of 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: it uses viewbundle.UnbundleView() with zstd decompression. ViewsView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. registered before v0.6.2 may be stored in uncompressed format. 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. tries to decompress an uncompressed payload, it fails.

View ID computation

ViewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. IDs are deterministic. The same computation runs on the client (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.) and on chain (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.):

viewID = typeName + "_" + keccak256(senderAddress, wireBytes)

Example:

TestView_0xae1bd91e83f5a71ed4c34e18470ea3c12b9ba3d4a69cfd98717e23cf27f4eccb

Because the same computation runs in both places, the client can predict the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. ID before the transaction confirms.

Lens authoring

LensesLens 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. are WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. binaries, typically written in Rust or AssemblyScript, that transform raw primitive data into structured output.

A simplified Rust example:

fn transform(log: Log) -> Option<USDCTransfer> {
if log.address != USDC_ADDRESS { return None; }
if log.topics[0] != TRANSFER_SIG { return None; }
Some(USDCTransfer {
from: decode_address(log.topics[1]),
to: decode_address(log.topics[2]),
amount: decode_uint256(log.data),
})
}

LensesLens 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. must be deterministic. Any 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 the same 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. on the same data should produce identical results.

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. supports bidirectional transforms (the inverse() function in the WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. moduleModule 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.), though most viewsView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. use one-way transforms.

Binary size by language

LanguageTypical WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. sizeNotes
Rust~200 KBPreferred for production
AssemblyScript~73 KBEasier if you know TypeScript, smaller binary

Smaller binaries mean less P2P overhead.

Available lenses

Stored in shinzo-gh/wasm-bucket. Currently available:

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.Purpose
decode_logABIABI Describes how to encode and decode function calls, arguments, and event data for an EVM contract. Lenses such as `decode_log` take ABI JSON as input to read raw log data.-decodes EVMEVM The runtime that executes Solidity smart contracts. ShinzoHub embeds an EVM module so its registries are accessible as precompiled contracts at fixed addresses, callable from any EVM tooling. 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. events. Takes ABIABI Describes how to encode and decode function calls, arguments, and event data for an EVM contract. Lenses such as `decode_log` take ABI JSON as input to read raw log data. JSON as argument.
filter_transactionFilters by contract address

Writing new lenses

  • Rust SDK: source-gh/lens/sdk-rust/.
  • AssemblyScript example: source-gh/lens/tests/modules/as_wasm32_simple/.
  • WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. runtime paths: source-gh/lens/host-go/runtimes/wasmtime/, wasmer/, wazero/.

AssemblyScript lensesLens 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. follow the same interface as Rust lensesLens 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.. 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. runtime does not care what language produced the WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM..

The view lifecycle across repos

Five repos are involved in the lifecycle from creation to query:

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 not involved in the viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. lifecycle. By the time a viewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. is created and applied, 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. have already delivered raw data to 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. over P2P.

Key files

WhatLocation
ViewView A curated, SDL-defined representation of defraDB documents. Views transform raw indexed data into a structured output shape. deploy logicshinzo-gh/shinzo-view-creator/core/service/deploy.go
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. encoding/decodingshinzo-gh/viewbundle-go/
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. bundler (compress/decompress)shinzo-gh/viewbundle-go/bundler.go
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. wire codecshinzo-gh/viewbundle-go/codec.go
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. header-only decodeshinzo-gh/viewbundle-go/header.go
WASMWASM A portable, sandboxed bytecode format. Lens transforms compile to WASM — typically from Rust or AssemblyScript — and hosts run them via LensVM. lensesLens 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.shinzo-gh/wasm-bucket/
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. (decode/validate)shinzohub/app/precompiles/viewregistry/methods.go
Rust 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. SDKsource-gh/lens/sdk-rust/
AssemblyScript 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. examplesource-gh/lens/tests/modules/as_wasm32_simple/