HESTIAdocs

Protocol overview

How the packages fit together — common, circuits, contracts, route, sdk — and the two-repo split.


The Hestia protocol is a small set of packages with one rule between them: the cryptographic encodings must be byte-identical across JavaScript, the circuit, and Solidity. A commitment computed by the SDK has to match the one the circuit constrains and the one the contract recomputes. Everything else follows from that discipline.

The packages

PackageLayerResponsibility
@hestia/commoncrypto spineField math, Poseidon, notes, keys, encryption, meta-addresses, the JS Merkle tree. The source of truth all others conform to.
@hestia/circuitsprovingThe Circom join-split circuits and a browser-safe Groth16 prover.
contractssettlementHestiaPool, MerkleTreeWithHistory, AssociationSetRegistry, generated verifiers.
@hestia/routeconvenienceIndexer, store, relayer, and framework-agnostic API handlers.
@hestia/sdkagent surfaceKeys, discovery, coin selection, proving, submission behind four verbs.

How a transaction flows through them

text
@hestia/sdk                @hestia/circuits        contracts            @hestia/route
─────────────              ────────────────        ─────────            ─────────────
select note ─┐
build outputs│
encrypt blobs│
             └─ build witness ─► Groth16 prove ─► proof + signals
                                                       │
                                  submit (self or relayer) ─► HestiaPool.transact1x2
                                                                 verify · nullify · insert
                                                       ◄── events ──┘
                                  rebuild tree / nullifiers / ASP roots ◄── Indexer.sync()

The SDK never trusts the route for anything secret: it proves locally and only asks the route for public data (Merkle paths, ciphertexts, ASP status) and, optionally, for gas-paying relay.

Conformance: one encoding, three implementations

The golden test fixtures in @hestia/common are the conformance suite. The circuit and the contract must reproduce them exactly:

  • Poseidon uses the same parameters everywhere. On-chain it is circomlib-generated bytecode (the T2/T3/T6 permutations) deployed via CREATE, so the contract hashes a note to the same value the circuit and the SDK do.
  • The commitment is poseidon([value, token, owner, label, randomness]) in all three.
  • The Merkle tree uses the same depth (32), zero value (0), and Poseidon(2) ordering.

If any layer drifted, a proof generated by the SDK would fail to verify on-chain. The fixtures exist so it can't drift silently.

Versions

ts
import { HESTIA_PROTOCOL_VERSION } from "@hestia/common"; // "0.1.0"
import { SDK_VERSION, PROTOCOL_VERSION } from "@hestia/sdk"; // "0.1.0", "0.1.0"

The two-repo split

Hestia is developed as two repositories with a clean boundary:

  • hestia-build — the open-source protocol: contracts, circuits, and the @hestia/* packages (common, circuits, route, sdk). This is what's audited, published, and built against.
  • hestia — this product app: the UI and the necessary backend. It holds no protocol source; it consumes the @hestia/* packages.

That separation is why the SDK is engineered to be browser-safe: the same package that powers a Node service also bundles into a Next.js client for in-browser proving.

Continue to Zero-knowledge circuits for the proving layer, or Smart contracts for settlement.