mergedhumanPR #21Payments
feat(payments): streaming per-tick payments with mid-stream cancellation
Problem #3: [Streaming pay-per-second payments with mid-stream cancellation](https://github.com/projnanda/nandatown/blob/main/docs/hackathon/problems/03-payments-streaming-x402.md)
Description
The pitch.
## Problem
Problem #3: [Streaming pay-per-second payments with mid-stream cancellation](https://github.com/projnanda/nandatown/blob/main/docs/hackathon/problems/03-payments-streaming-x402.md)
## What this does
Adds a `StreamingPayments` plugin at `("payments", "streaming")` that extends prepaid credits with per-tick billing. Either party can cancel mid-stream; unused remainder is never spent. Backward-compatible with the existing `Payments` protocol.
## Key APIs
| Method | Returns | Notes |
|---|---|---|
| `open_stream(to, rate_per_tick, max_total, ref)` | `StreamHandle` | Drains first tick immediately |
| `tick_stream(ref, current_tick)` | `bool` | Per-round billing, enforces max & balance |
| `close_stream(ref)` | `Receipt` | Unused remainder never spent |
| `verify_payment(ref)` | `PaymentStatus` | `STREAMING` / `CONFIRMED` / `FAILED` |
| `pay()` / `refund()` | `Receipt` / `None` | Backward-compatible one-shot |
## Three adversarial validators
1. **Conservation** — `sum(debited) == sum(credited)` across the full trace
2. **No drain-after-close** — no `payment_debited` events after `stream_closed`
3. **No over-bill on partition** — no debits after payer/payee are network-partitioned
## Files changed (7)
- `packages/nest-plugins-reference/nest_plugins_reference/payments/streaming.py` — plugin (~340 lines)
- `packages/nest-plugins-reference/tests/test_streaming_payments.py` — 18 tests (~300 lines)
- `packages/nest-core/nest_core/validators.py` — 3 validators (~190 lines)
- `packages/nest-core/tests/test_validators.py` — 7 validator tests
- `packages/nest-core/nest_core/plugins.py` — registry entry
- `packages/nest-core/nest_core/types.py` — `PaymentStatus.STREAMING` enum
- `scenarios/streaming_payments.yaml` + `streaming_payments_partition.yaml`
## CI
All green: `uv sync` · `ruff check` · `ruff format` · `pyright` · `pytest` (366 passed)
## Verify
```bash
uv run pytest packages/nest-plugins-reference/tests/test_streaming_payments.py -v
uv run pytest packages/nest-core/tests/test_validators.py -v -k streamingTry it
Open PR on GitHubView diffCheckout locally
git fetch origin pull/21/head:pr-21
git checkout pr-21