Scope: the reference host server in
src/. Other implementations can structure their state machine differently — this is not a wire spec. The wire-format specs (Nostr DVM kinds inspecs/messaging.md, oracle discovery inspecs/oracle-registry.md, conditional swap primitive inspecs/conditional-swap.md) are the cross-implementation contracts.
A query represents a request for verified data. This document defines the
host's query state machine, valid transitions, and expiry behavior — as
implemented in src/domain/query-store.ts + query-transitions.ts.
| State | Description |
|---|---|
awaiting_quotes |
Query posted, waiting for Worker quotes |
worker_selected |
Requester selected a Worker, escrow bound, awaiting Worker acknowledgment |
processing |
Worker acknowledged, proof production in progress |
verifying |
Proof submitted, Oracle verification in progress |
approved |
Verification passed, payment released (terminal) |
rejected |
Verification failed (terminal) |
expired |
Locktime reached without resolution (terminal) |
For simple (non-escrow) queries, an additional pending state exists
with direct transitions to approved, rejected, or expired.
awaiting_quotes --> worker_selected --> processing --> verifying --> approved
| | | |
v v v v
expired expired expired rejected
|
v
expired
| From | To | Trigger |
|---|---|---|
awaiting_quotes |
worker_selected |
Requester selects a Worker, binds escrow |
awaiting_quotes |
expired |
Locktime reached |
worker_selected |
processing |
Worker acknowledges selection and begins work |
worker_selected |
expired |
Locktime reached |
processing |
verifying |
Worker submits proof |
processing |
expired |
Locktime reached |
verifying |
approved |
Oracle verification passes |
verifying |
rejected |
Oracle verification fails |
verifying |
expired |
Locktime reached |
| From | To | Trigger |
|---|---|---|
pending |
approved |
Verification passes |
pending |
rejected |
Verification fails |
pending |
expired |
TTL reached |
approved, rejected, and expired are terminal. No further transitions
are allowed.
A query may be cancelled by the Requester in the following states:
pending, awaiting_quotes, worker_selected, processing.
Cancellation triggers escrow refund if escrow was locked.
Queries carry an expires_at timestamp (derived from escrow locktime or
a default TTL). When the current time exceeds expires_at, any
non-terminal query transitions to expired.
For HTLC queries, expiry triggers automatic escrow refund to the Requester via the Cashu mint's locktime mechanism.
A Requester creates a query with:
| Field | Required | Description |
|---|---|---|
description |
yes | Human-readable description of what is needed |
verification_requirements |
no | Factors to verify: tlsn, gps, nonce, timestamp, oracle, ai_check |
tlsn_requirements |
conditional | Target URL, HTTP method, conditions (required when tlsn is in requirements) |
expected_gps |
no | Expected GPS coordinates for proximity check |
max_gps_distance_km |
no | Maximum allowed distance from expected GPS (default: 50) |
visibility |
conditional | public or requester_only (required when tlsn_requirements is set) |
bounty |
no | Payment amount in sats |
oracle_ids |
no | Acceptable Oracle IDs (default: built-in) |
quorum |
no | Multi-Oracle quorum config (see packages/cashu-frost-oracle/SPEC.md) |