Skip to main content

XRPL implementation of x402 payments (presigned Payment scheme) with client + FastAPI/Starlette helpers

Project description

x402 XRPL Python SDK

This package provides a small, spec‑aligned SDK for working with x402 payments over XRPL in this repository. It is designed to be reusable by both buyer clients (creating X-PAYMENT headers) and seller/resource servers (verifying and settling via a facilitator).

Note: The XRPL exact flow in this repo is the presigned Payment tx blob scheme. The older escrow-based implementation has been removed; historical docs remain under app/docs/xrpl-exact/escrow/.

For an overview of the scheme and end-to-end flow, see: app/docs/xrpl-exact/presigned-payment/README.md.


Install

pip install x402-xrpl

Modules at a Glance

  • x402_xrpl.types
    • Core x402 types:
      • PaymentRequirements – spec‑aligned requirements (string maxAmountRequired, payTo, asset, etc.).
        • XRPL IOU extension: include extra={"issuer":"r..."} when asset != "XRP".
      • PaymentPayload – outer payment envelope (x402Version, scheme, network, payload).
      • PaymentRequiredResponse{ x402Version, error, accepts: [...] }.
      • FacilitatorSupportedResponse, PaymentVerifyResponse, SettlementResponse (normalized responses from the facilitator).
  • x402_xrpl.facilitator
    • HTTP client for x402 facilitators:
      • FacilitatorClient (sync).
      • AsyncFacilitatorClient (async).
      • FacilitatorClientOptions, FacilitatorWireFormat.
  • x402_xrpl.client
    • Client‑side XRPL helper:
      • Presigned payments: XRPLPresignedPaymentPayer, XRPLPresignedPaymentPayerOptions, XRPLPresignedPreparedPayment.
  • x402_xrpl.clients
    • Buyer-side HTTP helpers (requests-style):
      • x402_requests, X402RequestsSession – auto-handle 402 → build X-PAYMENT → retry.
      • decode_x_payment_response – decode X-PAYMENT-RESPONSE (base64 JSON).
      • x402Client.default_payment_requirements_selector – default requirement selection.
  • x402_xrpl.server
    • Server‑side FastAPI/Starlette middleware:
      • RequireX402Options, InvoiceStore, require_x402(...).

Quickstart: Buyer Client (requests-style)

If you want the UX of x402_requests(...) (auto-handle 402), use x402_xrpl.clients.requests:

import requests
from xrpl.wallet import Wallet

from x402_xrpl.clients.requests import x402_requests
from x402_xrpl.clients.base import decode_x_payment_response

XRPL_RPC = "https://s.altnet.rippletest.net:51234/"
RESOURCE_URL = "http://127.0.0.1:8080/xrpl-demo/resource"

wallet = Wallet.from_seed("…demo seed…")

session: requests.Session = x402_requests(
    wallet,
    rpc_url=XRPL_RPC,
    # Optional filters so most users don't write a custom selector:
    network_filter="xrpl-testnet",
    scheme_filter="exact",
)

resp = session.get(RESOURCE_URL, timeout=180)
print(resp.status_code, resp.text)

if "X-PAYMENT-RESPONSE" in resp.headers:
    settlement = decode_x_payment_response(resp.headers["X-PAYMENT-RESPONSE"])
    print("settled tx:", settlement.get("transaction"))

Quickstart: Building a Payment Header on XRPL (Presigned Payment)

Given a 402 response body from /xrpl-demo/resource, you can construct PaymentRequirements and an X-PAYMENT header like this:

import requests
from xrpl.wallet import Wallet

from x402_xrpl.client import XRPLPresignedPaymentPayer, XRPLPresignedPaymentPayerOptions
from x402_xrpl.types import PaymentRequirements

XRPL_RPC = "https://s.altnet.rippletest.net:51234/"
RESOURCE_URL = "http://127.0.0.1:8080/xrpl-demo/resource"

# 1) Fetch payment requirements via HTTP 402
resp = requests.get(RESOURCE_URL, timeout=60)
if resp.status_code != 402:
    resp.raise_for_status()
body = resp.json()
raw_reqs = body.get("paymentRequirements") or (body.get("accepts") or [])[0]
reqs = PaymentRequirements.from_dict(raw_reqs)

# 2) Configure payer with a funded wallet
wallet = Wallet.from_seed("…demo seed…")
payer = XRPLPresignedPaymentPayer(
    XRPLPresignedPaymentPayerOptions(
        wallet=wallet,
        network=reqs.network,  # "xrpl-testnet"
        rpc_url=XRPL_RPC,
        # Default is "both": bind invoiceId via Memos + InvoiceID.
        # invoice_binding="memos" or "invoice_id" are also supported.
    )
)

# 3) Build the presigned Payment tx + X-PAYMENT header
x_payment_header = payer.create_payment_header(reqs)

# 4) Redeem the resource
redeem = requests.get(RESOURCE_URL, headers={"X-PAYMENT": x_payment_header}, timeout=180)
print(redeem.status_code, redeem.json())

This flow is essentially what tests/test_script_xrpl_presigned_flow.py does end‑to‑end.

IOU notes (non-XRP assets):

  • Set reqs.asset to the currency code (e.g. "RLUSD").
  • Provide the issuer as reqs.extra["issuer"] (classic address).
  • Set reqs.maxAmountRequired to the XRPL issued-currency value string (e.g. "1", "1.25").

Quickstart: Calling a Facilitator Directly

If you already have:

  • An X-PAYMENT header value (payment_header), and
  • A PaymentRequirements instance (reqs)

you can talk to the XRPL facilitator directly:

from x402_xrpl.facilitator import FacilitatorClient, FacilitatorClientOptions

client = FacilitatorClient(
    FacilitatorClientOptions(
        base_url="http://127.0.0.1:8011",
        wire_format="paymentHeader",  # XRPL facilitator expects paymentHeader
    )
)

# Optional: discover supported scheme/network pairs
supported = client.supported()
for kind in supported.kinds:
    print("facilitator supports:", kind.scheme, kind.network)

# Verify
verify_result = client.verify(
    payment_header=payment_header,
    payment_requirements=reqs,
    x402_version=1,
)
if not verify_result.is_valid:
    raise RuntimeError(f"verify failed: {verify_result.invalid_reason}")

# Settle
settle_result = client.settle(
    payment_header=payment_header,
    payment_requirements=reqs,
    x402_version=1,
)
if not settle_result.success:
    raise RuntimeError(f"settle failed: {settle_result.error_reason}")

print("settled on", settle_result.network, "tx:", settle_result.transaction)

For async flows, use AsyncFacilitatorClient instead and await the same methods.


Quickstart: Protecting a FastAPI Route with require_x402

To protect a route (e.g. /xrpl-demo/resource) with x402 XRPL payments:

from fastapi import FastAPI

from x402_xrpl.server import RequireX402Options, require_x402

app = FastAPI()

options = RequireX402Options(
    pay_to="rhaDe3NBxgUSLL12N5Sxpii2xy8vSyXNG6",
    max_amount_required="1000000",
    scheme="exact",
    network="xrpl-testnet",
    asset="XRP",
    # For IOUs (asset != "XRP"), also set:
    # issuer="rISSUER...",
    max_timeout_seconds=600,
    resource="demo:xrpl-resource",
    facilitator_url="http://127.0.0.1:8011",
    path="/xrpl-demo/resource",
)

app.middleware("http")(require_x402(options))

Behavior:

  • First request without X-PAYMENT:
    • Returns 402 with a spec‑style PaymentRequirementsResponse (accepts) plus convenience paymentRequirements and facilitatorBaseUrl.
  • Second request with X-PAYMENT:
    • Middleware verifies/settles via the facilitator.
    • On success:
      • Proceeds to the route handler.
      • Copies X-PAYMENT-RESPONSE from facilitator → client.

The existing /xrpl-demo/resource route in this repo uses this pattern.


Where to Look Next

  • app/docs/xrpl-exact/README.md – index of XRPL exact approaches in this repo.
  • app/docs/xrpl-exact/presigned-payment/README.md – presigned-Payment approach.
  • app/docs/xrpl-exact/presigned-payment/scheme_exact_xrpl_presigned_payment.md – scheme spec.
  • app/docs/xrpl-exact/escrow/ – legacy escrow docs only (implementation removed).
  • tests/test_x402_xrpl_sdk.py – pure unit tests for this package.
  • tests/test_script_xrpl_presigned_flow.py – full XRPL + facilitator + resource server integration using presigned payments.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

x402_xrpl-0.1.0.tar.gz (29.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

x402_xrpl-0.1.0-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file x402_xrpl-0.1.0.tar.gz.

File metadata

  • Download URL: x402_xrpl-0.1.0.tar.gz
  • Upload date:
  • Size: 29.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for x402_xrpl-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a728cbe014c3dab3d3cb3585217884a3490c03a737f39cf48b14d4a5ef9bd321
MD5 1172610414b64a9f14c3c52215f3b2d5
BLAKE2b-256 773990330d5c33294358c31265412b20968b5b7079db1c0f32b99d4e2c74949d

See more details on using hashes here.

File details

Details for the file x402_xrpl-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: x402_xrpl-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for x402_xrpl-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 183824085b728012131bda7784c34fe5146956256ab6c92a8b09359b0191d784
MD5 bf3694462235c7725070546328956cec
BLAKE2b-256 ac8d9a86af52f274e4b9e8ea6d801068a9a0719ef5de56aa00a9f02a850dab0b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page