Skip to content

Feat/cep8 explicit gating#75

Open
1amKhush wants to merge 5 commits into
ContextVM:masterfrom
1amKhush:feat/cep8-explicit-gating
Open

Feat/cep8 explicit gating#75
1amKhush wants to merge 5 commits into
ContextVM:masterfrom
1amKhush:feat/cep8-explicit-gating

Conversation

@1amKhush

Copy link
Copy Markdown
Contributor

Feat: CEP-8 Explicit Gating Lifecycle

Resolves: #74
Reference Spec: ContextVM/contextvm-docs#44

Description

This PR introduces full support for the Explicit Gating payment lifecycle (explicit_gating mode) in the ContextVM TypeScript SDK, as mandated by the latest CEP-8 specification updates.

Previously, the SDK only supported the default transparent notification-based payment flow. With this update, servers can now strictly gate priced capabilities by returning JSON-RPC error responses (-32042 Payment Required and -32043 Payment Pending), effectively blocking execution until a verifiable payment is made.

Key Changes & Architecture

  • Types & Constants:
    • Introduced standard error codes -32042 and -32043.
    • Added payment_interaction to negotiation tags.
    • Implemented CanonicalInvocationIdentity utilizing RFC-8785 JSON canonicalization (JCS) and SHA-256 to ensure idempotent matching between paid authorizations and retried executions.
  • Server Middleware (createExplicitGatingMiddleware):
    • Tracks paid executions using a new TTL-bounded AuthorizationStore with strict check-and-set atomicity.
    • Emits -32043 with a precise mathematically computed retry_after if a request races against an active payment verification.
  • Transport Negotiation:
    • Added capabilities to ClientSession to track both requestedPaymentInteraction and effectivePaymentInteraction.
    • Transports automatically validate the payment_interaction mode and safely fallback to transparent mode to prevent injection of untyped interactions.
  • Client Handling (withClientPayments):
    • Intercepts explicit gating error responses upstream, completely shielding the main MCP caller.
    • Delegates resolution strictly to the user's onPaymentRequired handler hook.
    • Supports completely autonomous auto-retry of the exact original request upon successful payment.
    • Includes resilient exponential backoff for -32043 errors capped at 5 MAX_RETRIES, alongside robust memory management (timer cancellation on transport termination).

Testing

  • Unit Tests: Full coverage for AuthorizationStore concurrency, JCS hashing, and edge cases. (Timings have been buffered to prevent CI flakiness).
  • Integration/E2E Tests: A complete end-to-end flow (payments-flow.test.ts) that runs a client request → intercepts -32042 → delegates to user payment logic → auto-retries → consumes authorization → and successfully returns the result.

Notes-

  • The atomicity inside AuthorizationStore.trySetPending relies on in-memory Maps and is therefore strictly single-process. Extensive doc comments have been added noting that distributed environments should implement an external Redis Redlock using the CanonicalInvocationIdentity.
  • Backward compatibility is 100% maintained. Legacy clients not advertising the new mode will continue running through the default transparent capability.

1amKhush added 2 commits June 11, 2026 16:43
Resolves ContextVM#74 by adding full support for the explicit gating payment lifecycle in the ContextVM TypeScript SDK. Includes server middleware for tracking authorization states, client support for auto-retrying intercepted -32042/-32043 errors, and transport modifications to negotiate payment modes.
Copilot AI review requested due to automatic review settings June 11, 2026 11:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds CEP-8 “explicit_gating” payment interaction mode support across Nostr client/server transports, including negotiation tags, server-side authorization gating, and client-side auto-retry behavior for -32042/-32043.

Changes:

  • Introduces explicit-gating server middleware with canonical invocation hashing + authorization store.
  • Adds client negotiation/disclosure plumbing (payment_interaction tags) and client auto-retry handling for -32042/-32043.
  • Refactors shared server payment utilities and adds unit + transport-level tests.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/transport/payments-flow.test.ts Adds a transport-level test for explicit-gating behavior and retry flow.
src/transport/nostr-server/session-store.ts Stores requested/effective payment interaction on server sessions.
src/transport/nostr-server/outbound-response-router.ts Discloses effective payment_interaction on first response (CEP-8).
src/transport/nostr-server/inbound-coordinator.ts Parses client payment_interaction request and sets per-request context.
src/transport/nostr-server-transport.ts Exposes API to configure supported payment interaction mode.
src/transport/nostr-client/server-metadata-store.ts Persists server-disclosed effective payment interaction mode.
src/transport/nostr-client/outbound-sender.ts Stores raw JSON-RPC request into correlation metadata for retries.
src/transport/nostr-client/inbound-coordinator.ts Captures server-disclosed payment_interaction tag and passes event id to response handler.
src/transport/nostr-client/correlation-store.ts Extends pending request state to include the raw JSON-RPC request.
src/transport/nostr-client-transport.ts Exposes get/set API for payment interaction negotiation and forwards response context.
src/transport/middleware.ts Extends inbound middleware context with paymentInteraction.
src/transport/capability-negotiator.ts Advertises requested payment_interaction tag from the client.
src/payments/types.ts Adds explicit-gating types: interaction mode, error data shapes, canonical identity.
src/payments/server-transport-payments.ts Wires explicit-gating middleware + discovery tags into server transport.
src/payments/server-payments.ts Refactors shared helpers into a new utils module; adds paymentInteraction option.
src/payments/server-payments-utils.ts New module for timeout/capability matching and resolvePrice type guards.
src/payments/server-explicit-gating.ts Implements explicit-gating server middleware returning -32042/-32043.
src/payments/server-explicit-gating.test.ts Unit tests for explicit-gating server middleware.
src/payments/constants.ts Adds explicit-gating error codes and negotiation error code constant.
src/payments/client-payments.ts Adds client-side explicit-gating handling, auto-retry, and pending backoff.
src/payments/client-payments.test.ts Adds tests for -32042/-32043 handling and retry behavior.
src/payments/canonical-identity.ts Computes canonical invocation hash/identity using JSON canonicalization + SHA-256.
src/payments/canonical-identity.test.ts Unit tests for canonical hashing determinism and identity composition.
src/payments/authorization-store.ts Adds LRU+TTL store for pending/granted paid authorizations.
src/payments/authorization-store.test.ts Unit tests for authorization store behavior (TTL, pending, eviction).
src/core/constants.ts Adds PAYMENT_INTERACTION to Nostr tag constants.
package.json Adds json-canonicalize dependency.
bun.lock Locks json-canonicalize dependency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/payments/client-payments.ts Outdated
Comment thread src/payments/client-payments.ts Outdated
Comment thread src/payments/client-payments.ts
Comment thread src/payments/server-explicit-gating.ts
Comment thread src/payments/server-explicit-gating.ts Outdated
Comment thread src/payments/server-transport-payments.ts
Comment thread src/payments/canonical-identity.ts Outdated
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