Skip to content

Add x402 1-hour access pass with in-memory receipt cache #495

Description

@DenisCarriere

Detailed description

Add a tracked implementation design for a time-boxed x402 access pass for Token API.

Instead of charging every API query as a separate x402 settlement, Token API should support a $0.10 x402 payment that grants 1 hour of Pro-like access. This is intended to make x402 economically practical for very low-cost Token API requests where per-request facilitator fees/gas economics could exceed the endpoint price.

This issue is a follow-up/sub-scope of:

Proposed behavior

First paid request / pass creation

  1. Client requests a paid Token API route without an existing valid x402 pass.
  2. Token API returns 402 Payment Required for a $0.10 / 1 hour Token API access pass.
  3. Client pays via x402 using one of the accepted rails from Implement x402 Bazaar V2 support for Token API #494:
    • EVM pay-to: 0x49D581486438aAD93f4114084Ac5B09A8b7C9685
    • SVM pay-to: EpRR35QnB5PfTczy3j5rp9bCw4NKzHkd8S1ubdza4my9
  4. Token API verifies/settles through the CDP facilitator:
    • https://api.cdp.coinbase.com/platform/v2/x402
  5. If settlement succeeds, Token API stores an in-process memory record for the payment receipt/pass.
  6. Token API executes the requested route with Pro-like limits.

Subsequent requests within 1 hour

The agent/client should keep sending the same payment completion/proof/receipt reference with each request.

Token API should:

  1. Extract a stable payment/receipt/authorization id from the x402 payload.
  2. Look up that id in in-process memory.
  3. If found and unexpired, allow the request with Pro-like limits without calling the facilitator again.
  4. If missing locally, fall back to the facilitator to revalidate/refetch the settled payment if CDP supports that flow.
  5. If facilitator confirms that the payment was settled and is still within the 1-hour window, cache it locally and allow the request.
  6. If it cannot be confirmed, return 402 Payment Required.

In-memory state model

For v1, use in-process memory only. Do not introduce Redis or another shared datastore yet.

Suggested record shape:

interface X402AccessPass {
  receiptId: string;
  payer: string;
  network: string;
  payTo: string;
  amountUsd: "0.10";
  resource: "token-api-pro-1h";
  settledAt: string;
  expiresAt: string;
  plan: "pro";
}

The exact fields should follow what the x402/CDP libraries expose, but the important properties are:

  • stable receipt/cache key
  • payer identity
  • network/rail
  • payment amount
  • resource/pass type
  • facilitator-confirmed settled timestamp
  • expiry timestamp
  • plan/limit tier

Multi-container / restart behavior

In-memory state is only a cache, not the long-term authority.

If the container restarts or a different container handles the next request:

  1. The local cache may not contain the receipt.
  2. Token API should attempt to refetch/revalidate the payment from the facilitator.
  3. If CDP supports already-settled receipt lookup or replay-safe verification, Token API should rebuild the memory cache and continue access.
  4. If CDP does not support this, the first implementation may require sticky sessions or a future shared-state layer such as Redis.

This needs to be validated during implementation because replaying an already-settled x402 payment through the normal settle path may be rejected or may not be the intended API flow.

Security requirements

  • Do not trust client-provided timestamps.
  • Expiry must be based on facilitator-confirmed settlement time or a server-confirmed first-seen settlement time.
  • Do not key access only by timestamp or wallet address.
  • Bind the receipt to the resource/pass type: token-api-pro-1h.
  • Bind the receipt to payer/network/pay-to/amount where possible.
  • Do not call settle again for known valid in-memory receipts.
  • Ensure a receipt for another resource cannot unlock Token API.
  • Ensure a receipt under $0.10 cannot unlock the pass.
  • Continue applying Pro-like limits/rate limits per request.
  • Prevent public cache leakage for x402-paid responses.

Implementation notes

Likely modules/files:

  • src/config.ts
    • x402 enablement and pass configuration
    • X402_PASS_PRICE_USD=0.10
    • X402_PASS_DURATION_SECONDS=3600
  • src/x402/accessPass.ts
    • memory cache
    • receipt parsing/keying
    • expiry checks
  • src/x402/facilitator.ts
    • CDP verify/settle/refetch wrapper
  • src/middleware/x402AccessPass.ts
    • enforce pass on paid routes
    • set trusted internal plan marker for Pro-like validation
  • src/x402/routes.ts

Testing targets:

  • missing payment returns 402
  • valid first payment stores in-memory pass
  • repeated request with same receipt uses memory cache
  • expired receipt returns 402
  • cache miss calls facilitator fallback
  • underpaid/wrong-resource receipts are rejected
  • free routes bypass x402
  • x402 pass applies Pro-like limits

Open implementation question

Confirm CDP facilitator behavior for an already-settled payment proof:

  • Is there a receipt/status lookup endpoint or SDK method?
  • Can the same payment completion be replayed for verification without settling again?
  • If replayed after settlement, does the facilitator return a useful settled receipt or reject it as already used?

The answer determines whether in-memory cache plus facilitator fallback is enough for multi-container/restart behavior, or whether sticky sessions/shared state are required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions