Add session mode for pre-funded request processing

Implement session-based API endpoints for creating, managing, and interacting with pre-funded sessions, including deposit and top-up invoice generation, macaroon authentication, and per-request debiting of compute costs.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2dc3847e-7186-4a22-9c7e-16cd31bca8d9
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9f85e954-647c-46a5-90a7-396e495a805a/418bf6f8-212b-4bb0-a7a5-8231a061da4e/sPDHkg8
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
alexpaynex
2026-03-18 20:00:24 +00:00
parent dfc9ecdc7b
commit ab2cc06a79
29 changed files with 1075 additions and 978 deletions

View File

@@ -246,10 +246,53 @@ Only available in development (`NODE_ENV !== 'production'`).
Utility scripts package. Each script is a `.ts` file in `src/` with a corresponding npm script in `package.json`. Run scripts via `pnpm --filter @workspace/scripts run <script>`. Scripts can import any workspace package (e.g., `@workspace/db`) by adding it as a dependency in `scripts/package.json`.
## Roadmap
### Pre-funded session mode (Mode 2)
### Mode 2 — Pre-funded session (v2)
Token-based cost debits against a pre-funded balance. Spec in `TIMMY_TEST_PLAN.md` (Tests 1116 as SKIP stubs).
Pay once, run many requests. Balance is debited at actual cost per request — no per-job invoices.
```bash
BASE="http://localhost:8080"
# 1. Create a session (returns deposit invoice)
curl -s -X POST "$BASE/api/sessions" \
-H "Content-Type: application/json" \
-d '{"amount_sats": 500}'
# → {"sessionId":"…","state":"awaiting_payment","invoice":{"paymentRequest":"…","amountSats":500,"paymentHash":"…"}}
# 2. (Stub mode only) Pay deposit
curl -s -X POST "$BASE/api/dev/stub/pay/<paymentHash>"
# 3. Poll session — auto-advances to active, issues macaroon
curl -s "$BASE/api/sessions/<sessionId>"
# → {"sessionId":"…","state":"active","balanceSats":500,"macaroon":"…","minimumBalanceSats":50}
# 4. Submit requests (use macaroon as Bearer token)
curl -s -X POST "$BASE/api/sessions/<sessionId>/request" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <macaroon>" \
-d '{"request":"What is a satoshi?"}'
# → {"requestId":"…","state":"complete","result":"…","debitedSats":178,"balanceRemaining":322}
# 5. Top up when balance is low (session auto-pauses below 50 sats)
curl -s -X POST "$BASE/api/sessions/<sessionId>/topup" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <macaroon>" \
-d '{"amount_sats": 500}'
```
Session states: `awaiting_payment``active``paused` (low balance) → `expired` (24h TTL, refreshed on each request)
Key properties:
- **No per-job invoices** — balance is debited at actual compute cost (eval + work tokens + DO infra + margin)
- **Rejected requests** still incur a small eval fee (Haiku model only)
- **Macaroon auth** — 32-byte hex token issued on activation; required as `Authorization: Bearer` header
- **Pause on low balance** — session auto-pauses when balance < 50 sats; pay topup invoice to resume
- **TTL** — sessions expire 24 hours after last successful request
- **Deposit limits** — 10010,000 sats; env vars: `SESSION_MIN_DEPOSIT_SATS`, `SESSION_MAX_DEPOSIT_SATS`, `SESSION_MIN_BALANCE_SATS`, `SESSION_EXPIRY_HOURS`
DB tables: `sessions` (state machine, balance, macaroon), `session_requests` (per-request token + cost accounting)
## Roadmap
### Nostr integration
Nostr (NIP-04/NIP-44 encrypted DMs) is planned as the delivery layer for the bootstrap flow and beyond: