Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
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)

Author

Status
Merged
Merged on
Jun 19
Branch
hackathon/kaizen-streaming-payments

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 streaming

Try it

Open PR on GitHubView diff

Checkout locally

git fetch origin pull/21/head:pr-21
git checkout pr-21