Documentation What is a nest?

A nest is the unit of everything in nuthatch. It’s a content-addressed, reproducible specification of a question about on-chain data - machine-generated at the floor, human- and AI-refinable in meaning and logic, and instantiable like a function rather than copied like a file.

A nest is a spec, never a program. That distinction is load-bearing: because a nest is a declaration of inputs (config + ABIs + authored logic), the same inputs always produce the same decode, the same tables, the same derived state - verifiably, on any machine.

The four layers

  • Sources - generated. nuthatch.toml (the chain, the contracts, the events to decode) plus the vendored ABIs. This is what init scaffolds from an address. See nuthatch.toml.
  • Meaning - semantic.toml, describing what each table and column means, so an agent (or a human) can query the nest without guessing. See The semantic layer.
  • Logic - authored SQL views over the decoded events (the tip ∪ sealed surface), plus recipes. Where a nest computes derived answers. See Authored SQL views.
  • Identity - the content-addressed manifest: a sha256 over the canonical inputs, so a nest is a reproducible blob you can bundle, publish, and pull by hash. See The registry.

The property that ties them together: a nest is a function, not a fork. You instantiate one; you don’t copy it.

On disk

init 0xAddr produces roughly:

my-nest/
  nuthatch.toml        # the [nest] header + [[contracts]] - the sources layer
  abis/                # vendored ABIs (Sourcify → Etherscan), never re-fetched at runtime
  schema.json          # generated: the decoded tables + columns
  views/               # authored SQL derivations (a commented starter to uncomment)
  semantic.toml        # the meaning layer
  llms.txt             # a machine-readable index for coding agents
  nuthatch.redb        # the hot store (runtime, not an input - excluded from the hash)
  segments/            # sealed Parquet past finality (runtime, content-addressed)

Only the authored inputs are part of a nest’s identity - the hot store and sealed segments are derived, so they never enter the content hash.

Decoding

Decode is deterministic Rust, keyed by topic0, with contract-ABI priority and a generic fallback. ABIs are acquired at init (Sourcify first, then an Etherscan-class API) and cached locally - nuthatch never phones home for them at runtime. Every declared event of every contract becomes a table {alias}__{event} with implicit columns (block_number, block_hash, block_timestamp, tx_hash, log_index, address, _seq) alongside the decoded fields. See ABIs, events & tables.

Never retroactively re-decoded. When an ABI improves, nuthatch does not rewrite stored history - decodings are versioned. Old rows keep the decoding they were indexed with; a better ABI applies going forward. Determinism over convenience.

Next