Skip to content

feat: IETF Payment session intent#5

Merged
TheCryptoDonkey merged 6 commits intomainfrom
feat/session-intent
Mar 24, 2026
Merged

feat: IETF Payment session intent#5
TheCryptoDonkey merged 6 commits intomainfrom
feat/session-intent

Conversation

@TheCryptoDonkey
Copy link
Collaborator

Summary

Implements the IETF Payment session intent (deposit/bearer/top-up/close lifecycle) per the forgesworn/payment-methods session specification. This enables streaming payment sessions for use cases like LLM token streaming, ridesharing metering, and real-time data feeds.

5 commits:

  • PaymentSender interfacesendPayment(bolt11) on all 5 Lightning backends (Phoenixd, LND, CLN, LNbits, NWC) for outbound refund payments
  • Session storage — SQLite table with migration, indexes, atomic deduct/topUp transactions + memory implementation
  • Session railcreateIETFSessionRail() factory with full lifecycle (challenge, open, bearer, top-up, close)
  • Engine integration'session' mode in TollBoothEngine, deductSession, X-Session-Balance headers, Cache-Control: private, no-store
  • Security audit fixes — 2 CRITICAL + 3 HIGH + 5 MEDIUM addressed

Compliance guardrails built in:

  • maxSessionDurationMs (default 24h) — prevents indefinite custody
  • maxDepositSats (default 100k sats) — limits value held
  • Auto-close sweep for expired sessions with refund
  • Refund-to-originator enforcement (no close-time invoice override)
  • BOLT11 amount validation before refund payment
  • TOCTOU double-refund protection (close-before-pay)
  • Cumulative deposit cap on top-ups

New files:

  • src/core/ietf-session.ts — session rail implementation
  • src/core/ietf-session.test.ts — 26 tests (lifecycle, compliance, security, adversarial)
  • COMPLIANCE.md — regulatory posture documentation

Test plan

  • 852 tests pass (26 new session-specific, 826 existing)
  • TypeScript typecheck clean
  • Security audit: 2 CRITICAL, 3 HIGH, 5 MEDIUM fixed
  • Full session lifecycle: open -> bearer auth -> deduct -> close -> refund
  • Compliance guardrails: max deposit, max duration, auto-close, cap enforcement
  • Adversarial: replay, expired challenge, expired session, close replay, sendPayment failure, malformed auth
  • Integration test with live Lightning backend (post-merge)
  • satgate integration (separate PR)

🤖 Generated with Claude Code

- Add optional sendPayment(bolt11) to LightningBackend for outbound
  payments (session refunds). Implemented in all 5 backends: Phoenixd,
  LND, CLN, LNbits, NWC.
- Add SessionConfig type and ietfSession config to BoothConfig.
- Add sessions table to SQLite storage with migration, indexes, and
  atomic deduct/topUp transactions.
- Add session methods to StorageBackend interface and both SQLite and
  memory implementations.
- 826 tests pass, zero regressions.
- satgate repo is TheCryptoDonkey/satgate, not forgesworn/satgate
- blog post: update year (25 -> 27) and replace dead routing.trotters.cc
  with current live demos (jokes.trotters.dev, satgate.trotters.dev)
- New createIETFSessionRail() factory implementing deposit/bearer/
  top-up/close lifecycle per forgesworn/payment-methods session spec.
- Compliance guardrails: maxSessionDurationMs (24h default),
  maxDepositSats (100k default), auto-close sweep for expired sessions,
  refund-to-originator enforcement.
- Session events: open, close, expire, topup, deduct callbacks.
- Bearer token auth for subsequent requests after session open.
- 18 new tests covering full lifecycle, compliance caps, security
  (HMAC tamper, invalid preimage, unknown bearer, token uniqueness).
- COMPLIANCE.md documenting regulatory posture, data handling, custody
  considerations, and operator responsibilities.
- Public API exports in index.ts.
- 844 tests pass, zero regressions.
CRITICAL fixes:
- Remove close-time return invoice override — refund-to-originator
  enforcement prevents refund redirect attacks.
- Add BOLT11 amount validation before refund payment — prevents
  operator fund drain from amount-mismatched return invoices.

HIGH fixes:
- TOCTOU double-refund: close session before attempting payment in
  sweepExpired, preventing concurrent close + sweep double-spend.
- LND streaming JSON parse: wrap in try/catch per line to handle
  malformed/truncated responses gracefully.
- sweepExpired: emit events on failure for operator visibility.

MEDIUM fixes:
- Session open replay: check for existing session before creating,
  preventing memory storage overwrite and SQLite unhandled throw.
- Fail-fast at rail construction if backend lacks sendPayment().
- Add 'session' mode to RailVerifyResult for session bearer auth.
- Engine uses storage.deductSession() for session-mode requests
  instead of credits table debit.
- Session-specific response headers: X-Session-Balance, Cache-Control
  private/no-store.
- Auth hint for session rail in 402 challenge bodies.
- Public API exports for session rail and types.
- 844 tests pass, zero regressions.
Security fixes:
- Bearer token timing-safe comparison in memory storage (timingSafeEqual)
- NWC sendPayment timeout via Promise.race (prevents hanging sweep)
- Top-up cap now uses cumulative depositSats, not current balanceSats

New adversarial tests (8):
- Duplicate session open (replay prevention)
- Expired challenge rejection
- Bearer auth on expired session
- Close replay on already-closed session
- Missing returnInvoice graceful handling
- sendPayment failure during close (session still closes)
- Malformed base64url in Authorization header
- Top-up with fresh challenge succeeds

852 tests pass, zero regressions.
@TheCryptoDonkey TheCryptoDonkey merged commit 8d770fa into main Mar 24, 2026
8 checks passed
@TheCryptoDonkey TheCryptoDonkey deleted the feat/session-intent branch March 24, 2026 03:13
github-actions bot pushed a commit that referenced this pull request Mar 24, 2026
# [4.4.0](v4.3.0...v4.4.0) (2026-03-24)

### Bug Fixes

* address security audit findings (CRITICAL + HIGH + MEDIUM) ([bc94c21](bc94c21))
* remaining MEDIUM security fixes + adversarial test coverage ([c45792e](c45792e))

### Features

* add IETF Payment session rail with compliance guardrails ([73f3597](73f3597))
* add PaymentSender interface and session storage ([e1fa026](e1fa026))
* IETF Payment session intent ([#5](#5)) ([8d770fa](8d770fa))
* integrate session rail into TollBoothEngine ([ab65a6d](ab65a6d))
@github-actions
Copy link

🎉 This PR is included in version 4.4.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant