Skip to content

Add x402 session settlement timing configuration#126

Open
adambalogh wants to merge 4 commits into
mainfrom
claude/x402-settlement-drops-c02vyy
Open

Add x402 session settlement timing configuration#126
adambalogh wants to merge 4 commits into
mainfrom
claude/x402-settlement-drops-c02vyy

Conversation

@adambalogh

Copy link
Copy Markdown
Contributor

Summary

Adds configuration constants and middleware setup for x402 "upto" session settlement timing, ensuring that accumulated payment tabs are settled safely within the signed Permit2 authorization deadline.

Key Changes

  • New configuration constants in definitions.py:

    • UPTO_SESSION_MAX_TIMEOUT_SECONDS (900s): Validity window signed into the Permit2 authorization
    • UPTO_SETTLEMENT_SAFETY_MARGIN_SECONDS (180s): Force-settle buffer before authorization deadline
    • UPTO_SESSION_IDLE_TIMEOUT_SECONDS (100s): Idle timeout for session settlement
    • SETTLEMENT_POLL_INTERVAL_SECONDS (2.0s): Poll interval for deferred settlement status
    • SETTLEMENT_POLL_TIMEOUT_SECONDS (120.0s): Timeout for settlement confirmation polling
  • Updated __main__.py:

    • Imports new settlement timing constants
    • Configures HTTPFacilitatorClientSync with wait_for_settlement=True and polling parameters to handle asynchronous settlement (202 + job id responses)
    • Passes max_timeout_seconds to all three x402 session configurations (OPG, Completions, Chat)
    • Replaces hardcoded session_idle_timeout value (100) with UPTO_SESSION_IDLE_TIMEOUT_SECONDS constant
    • Adds settlement_safety_margin parameter to x402 middleware initialization

Implementation Details

The changes enforce the critical invariant documented in definitions.py:

UPTO_SESSION_IDLE_TIMEOUT_SECONDS
  < UPTO_SETTLEMENT_SAFETY_MARGIN_SECONDS
  < UPTO_SESSION_MAX_TIMEOUT_SECONDS

This ensures that:

  1. Sessions settle before their authorization deadline expires
  2. On-chain settlement confirmation has time to complete before the deadline
  3. Payment tabs are never silently lost due to expired authorizations

The facilitator client now polls for settlement job completion rather than assuming immediate success, providing visibility into on-chain settlement results.

https://claude.ai/code/session_01HdeaNhmieATKBRgpVtPG89

…eadline

The chat/completions/ohttp routes use the x402 "upto" draw-down scheme, where a
single signed Permit2 authorization backs many requests. The routes did not set
maxTimeoutSeconds (server default 300s), while the reaper settled sessions only
after 100s of idle — so a session busy for more than ~200s was settled after its
authorization deadline and the on-chain settle reverted, silently dropping the
tab.

- Advertise an explicit 900s authorization window (max_timeout_seconds) on all
  three upto routes.
- Enable wait_for_settlement on the facilitator client so the reaper confirms
  the on-chain result before marking a session settled instead of trusting the
  202 enqueue acknowledgement.
- Force-settle sessions 180s before their deadline (settlement_safety_margin),
  leaving room for on-chain confirmation.

New timing knobs and the invariant
(idle < safety_margin < max_timeout, safety_margin > poll_timeout) live in
definitions.py so the relationship can't silently regress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdeaNhmieATKBRgpVtPG89
@adambalogh adambalogh marked this pull request as ready for review July 9, 2026 00:50

Copy link
Copy Markdown
Contributor Author

The mypy check is expected to stay red until the companion og-x402 change is released.

This PR uses new og-x402 API — FacilitatorConfig(wait_for_settlement=, settlement_poll_interval=, settlement_poll_timeout=) and payment_middleware(..., settlement_safety_margin=) — which lives in OpenGradient/x402#1 and is not in the pinned og-x402==0.0.2.dev7. (max_timeout_seconds on the routes already exists in dev7 and type-checks fine.)

TODO before merge: once OpenGradient/x402#1 is merged and released as a new og-x402, bump the og-x402 pin in pyproject.toml + regenerate uv.lock (note: this affects the enclave PCR). mypy will go green then, and the polling / safety-margin behavior only takes effect with that bump — the current changes are inert against dev7.


Generated by Claude Code

adambalogh and others added 3 commits July 8, 2026 21:03
Locks in the ordering between the settlement timing knobs so a future edit to
definitions.py can't silently reintroduce the "tab settled after its Permit2
deadline" drop:

    poll_timeout < safety_margin < max_timeout
    idle_timeout < safety_margin

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdeaNhmieATKBRgpVtPG89
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants