dig-chainsource-interface 0.1.0

The DIG Network canonical ChainSource provider interface: the single pure trait + query types every Chia chain-source provider implements and every consumer depends on. Reads-only, no I/O, no keys, no network — chia-* deps only.
Documentation

dig-chainsource-interface

The DIG Network canonical ChainSource provider interface: the single pure trait + query types every Chia chain-source provider implements and every consumer depends on.

There is ONE ChainSource contract for the whole ecosystem — never a per-crate copy that could byte-drift. This crate is a pure leaf: a trait, its typed query/result/error types, an optional in-memory mock, and known-answer tests. It performs no I/O, holds no keys, opens no network, and ships no concrete provider. Providers (coinset.org, a local wallet/full node, DIG peers) implement this trait in their own crates; chia-query is the registry + aggregating canonical source that composes them. Consumers (dig-did, dig-merkle, dig-node, dig-wallet-backend, the lineage middleware) depend on THIS trait.

Reads only — no broadcast, ever

Nothing in this crate can broadcast, push, or submit to the chain — there is no such method, by design. It is a pure reader; write/spend paths (which touch keys and funds) live entirely outside it, so depending on this crate can never move value.

Fail-closed: Ok(None) vs Err

Every read distinguishes two outcomes a consumer MUST treat differently:

Outcome Meaning Consumer action
Ok(None) / empty Vec The source reliably answered; the thing genuinely does not exist. Safe to act on the absence.
Err(_) The source could not reliably answer (transport, timeout, malformed, unsupported). Fail closed — treat as unknown, never as an absence.

Absence is never an error variant; an error is never degraded to a value.

The trait

Method Returns None / empty means
coin_record(coin_id) Option<CoinRecord> coin does not exist
coin_records_by_puzzle_hash(ph, include_spent) Vec<CoinRecord> no matching coins
coin_records_by_parent(parent_id) Vec<CoinRecord> no known children
coin_spend(coin_id) Option<CoinSpend> coin_id is unspent/unknown
parent_spend(coin_id) Option<CoinSpend> parent is unspent/unknown (a walk gap)
resolve_singleton_lineage(launcher_id) Option<SingletonLineage> launcher never existed / fully melted
peak_height() Option<u32> source exposes no peak
block_timestamp(height) Option<u64> no such block / no timestamp index

parent_spend is the money-critical parent-walk primitive: a coin's puzzle hash is attacker-chosen, so a launcher_id == check is spoofable. A consumer authenticates a singleton by walking parent_spend back toward the real launcher — a spoofed curried-puzzle coin has no genuine recreation parent-spend, so the walk fails closed. SingletonLineage follows suit: authority is membership (contains), never tip-equality.

Implementing a provider

Implement ChainSource over your backend, choosing type Error (ChainSourceError is recommended for registry participants). Map your backend's wallet-protocol CoinState with CoinRecord::from(state) (which maps created_height -> confirmed_height). Implement ChainSourceProvider::provider_info to register with the aggregator. Override the default parent_spend if your backend can resolve a creating spend in one call.

Depending on it as a consumer

Depend on the trait, never on a concrete provider, and be generic over S: ChainSource. Handle Ok(None) and Err(_) distinctly (fail closed on Err).

async -> sync bridge. The trait is synchronous and object-safe. An async provider presents a blocking ChainSource facade at chia-query's native aggregator boundary; a blocking consumer runs the walk under spawn_blocking. This keeps the interface a leaf with no async runtime dependency.

The testing feature

Enable features = ["testing"] to get MockChainSource, an in-memory source you load with coins, spends, and lineages (plus a forced-error switch) to exercise your own trust logic — including the fail-closed paths.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.