Running an observer
How to operate an independent observer node, monitor payments, file claims, and anchor daily scoreboard batches.
Implementation status: The deployed foundation supports provider registration, templates, stake/coverage/exits, and scoreboard storage. Claim filing, challenges, payouts, the observer service and the public SDK are planned; integration steps for them describe the intended protocol, not runnable deployed functionality. See the technical specification for the status breakdown.
Role of an observer
Observers are independent nodes that measure payment performance across Stellar anchors. They provide the offchain ground truth that powers onchain enforcement.
Observer qualifications
- Independence: An observer address cannot be the admin of any registered provider.
vaeltrix_registryrejects provider registrations from observer accounts and rejects observer additions for provider accounts. - Registration: Observers are added through the registry governance timelock:
- The registry admin proposes
ActionKind::AddObserver(address, public_key). - After
timelock_secselapses,execute(action_id)registers the observer. is_active_observer(address)returnstrue.
- The registry admin proposes
Core responsibilities
1. Ingest payment starts (t0_ms)
Monitor the Stellar Horizon or RPC streaming endpoint for payments involving covered provider addresses. Extract:
- Transaction ledger close timestamp (
t0_ms). - Payment amount and currency.
- Provider ID and SEP-31 transaction ID.
2. Ingest completion receipts (t1_ms)
Receive signed completion receipts from the anchor via HTTP webhook or SEP-38/31 status poll:
- Validate that the receipt is 131 bytes.
- Verify the Ed25519 signature against the provider's registered signer keys in
vaeltrix_registry. - Extract
t1_msand any legitimatepause_mscarve-outs.
3. File automated claims
If a payment breaches its target duration plus grace, or if no completion receipt is provided before the claim window closes:
- Verify that the payment was covered by checking
is_covered(commitment_id, t0_ms)onvaeltrix_bond. - Construct the
PaymentRefstruct. - Call
bond.file_claim(...)through an funded observer account. - If the provider challenges within
challenge_window_secs, submit an attestation vote (attest) with the evidence hash.
4. Publish daily scoreboard batches
At 00:10 UTC each day, for each active commitment:
- Select all payments with
t0_mswithin the previous UTC day[period_start, period_start + 86400). - Calculate nearest-rank latency percentiles:
p50_ms: 50th percentile (median) payout latency.p95_ms: 95th percentile payout latency.p99_ms: 99th percentile payout latency.
- Count total
payments,on_time,breaches, andcarved_out. - Construct a Merkle tree of all payment IDs and verdicts for the day.
- Invoke
scoreboard.anchor_batch(...)with the Merkle root andPeriodStats.