Pura's on-chain logic is organized into four planes. Each plane owns one concern, has its own contracts and adapters, and communicates with adjacent planes through the five standard objects.
┌─────────────────────────────────────┐
│ Settlement plane │ ← pays
├─────────────────────────────────────┤
│ Pricing plane │ ← prices
├─────────────────────────────────────┤
│ Verification plane │ ← proves
├─────────────────────────────────────┤
│ Capacity plane │ ← measures
└─────────────────────────────────────┘Data flows upward: capacity measurements feed verification, verified completions feed pricing, and pricing feeds settlement.
The capacity plane answers one question: how much throughput does each sink have right now?
Contracts:
| Contract | Role |
|---|---|
| CapacityRegistry | Register sinks, store raw and EWMA-smoothed capacity per task type |
| CapacityStaking | Stake tokens to back capacity claims; √stake cap prevents whale dominance |
| DVMCapacityAdapter | Reads NIP-90 kind capacity (kinds 5000–5999), applies EWMA |
The EWMA smoothing prevents gaming. A sink can't flash-report high capacity for one epoch and then disappear. The smoothing formula ():
This means it takes roughly 7 epochs for a new sink's smoothed capacity to reach 90% of its raw capacity. Quick upward jumps get dampened; sustained performance gets rewarded.
The capacity plane emits CapacityAttestation objects. These flow into the verification plane (to check that completed work matches claimed capacity) and into the pricing plane (as a denominator in the congestion formula).
The verification plane answers: did this sink actually complete the work?
Contracts:
| Contract | Role |
|---|---|
| CompletionTracker | Record verified completions per sink per epoch |
| DVMCompletionVerifier | Validate dual-signed DVM results, forward to CompletionTracker |
Every completion requires two EIP-712 signatures:
Both signatures must recover to the expected addresses on-chain. If either is missing or invalid, the completion is rejected. This prevents sinks from self-certifying work they didn't do.
The verifier emits VerificationReceipt objects. Verified completions per epoch feed into the pricing plane (as the numerator measuring actual load) and into the settlement plane (as the trigger for payment).
The pricing plane answers: what should this job cost right now?
Contracts:
| Contract | Role |
|---|---|
| PricingCurve | Base fee + congestion multiplier per task type |
| DVMPricingCurve | Kind-specific weight overlays for NIP-90 task types |
| TemperatureOracle | System-wide Boltzmann temperature τ for allocation |
The congestion pricing formula:
When completions per epoch approach smoothed capacity, the congestion multiplier rises. This creates a feedback signal: sources see prices rise on congested sinks and shift to cheaper alternatives. The Boltzmann allocation mechanism uses these prices to distribute jobs:
Higher temperature τ means more exploration (spreading load across sinks). Lower temperature means more exploitation (concentrating on the highest-capacity sinks). The TemperatureOracle adjusts τ based on system-wide utilization.
The pricing plane emits PriceSignal objects. These are broadcast as Kind 1090 Nostr events so every relay and client in the network sees current pricing.
The settlement plane answers: how does the money move?
Contracts:
| Contract | Role |
|---|---|
| PaymentPool | Epoch-based pool that distributes revenue proportional to verified completions |
| ISettlementAdapter | Abstract interface for settlement rails |
| SuperfluidSettlementAdapter | GDA streaming payments (linear accrual per second) |
| LightningSettlementAdapter | HTLC-based Lightning payments (sha256 preimage, 86400s timeout) |
| DirectSettlementAdapter | ERC-20 transfers from escrow |
Three settlement rails, chosen per sink preference:
| Rail | Mechanism |
|---|---|
| Lightning | HTLC with sha256 preimage and 24-hour timeout. The sink reveals the preimage to claim payment. If the preimage isn't revealed in time, the escrow returns to the pool. |
| Superfluid streaming | GDA (General Distribution Agreement) stream with linear accrual per second, withdrawable at any time. |
| Direct ERC-20 | Simple token transfer. The adapter locks tokens in escrow on job acceptance and releases them on verified completion. |
The settlement plane emits SettlementReceipt objects, closing the loop.
A request moves through all four planes:
The circuit breaker (in EpochController) monitors this flow. If a sink's completion rate drops below 50% for three consecutive epochs, it's automatically deregistered. The SystemStateEmitter broadcasts a Kind 1090 event so the network responds immediately.
35 contracts in total across the four planes, with 319+ passing tests. See the contracts README for the full list and deployment addresses.