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 (stringmaxAmountRequired,payTo,asset, etc.).- XRPL IOU extension: include
extra={"issuer":"r..."}whenasset != "XRP".
- XRPL IOU extension: include
PaymentPayload– outer payment envelope (x402Version,scheme,network,payload).PaymentRequiredResponse–{ x402Version, error, accepts: [...] }.FacilitatorSupportedResponse,PaymentVerifyResponse,SettlementResponse(normalized responses from the facilitator).
- Core x402 types:
x402_xrpl.facilitator- HTTP client for x402 facilitators:
FacilitatorClient(sync).AsyncFacilitatorClient(async).FacilitatorClientOptions,FacilitatorWireFormat.
- HTTP client for x402 facilitators:
x402_xrpl.client- Client‑side XRPL helper:
- Presigned payments:
XRPLPresignedPaymentPayer,XRPLPresignedPaymentPayerOptions,XRPLPresignedPreparedPayment.
- Presigned payments:
- Client‑side XRPL helper:
x402_xrpl.clients- Buyer-side HTTP helpers (requests-style):
x402_requests,X402RequestsSession– auto-handle 402 → buildX-PAYMENT→ retry.decode_x_payment_response– decodeX-PAYMENT-RESPONSE(base64 JSON).x402Client.default_payment_requirements_selector– default requirement selection.
- Buyer-side HTTP helpers (requests-style):
x402_xrpl.server- Server‑side FastAPI/Starlette middleware:
RequireX402Options,InvoiceStore,require_x402(...).
- Server‑side FastAPI/Starlette middleware:
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.assetto the currency code (e.g."RLUSD"). - Provide the issuer as
reqs.extra["issuer"](classic address). - Set
reqs.maxAmountRequiredto the XRPL issued-currencyvaluestring (e.g."1","1.25").
Quickstart: Calling a Facilitator Directly
If you already have:
- An
X-PAYMENTheader value (payment_header), and - A
PaymentRequirementsinstance (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 conveniencepaymentRequirementsandfacilitatorBaseUrl.
- Returns 402 with a spec‑style
- Second request with
X-PAYMENT:- Middleware verifies/settles via the facilitator.
- On success:
- Proceeds to the route handler.
- Copies
X-PAYMENT-RESPONSEfrom 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-Paymentapproach.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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a728cbe014c3dab3d3cb3585217884a3490c03a737f39cf48b14d4a5ef9bd321
|
|
| MD5 |
1172610414b64a9f14c3c52215f3b2d5
|
|
| BLAKE2b-256 |
773990330d5c33294358c31265412b20968b5b7079db1c0f32b99d4e2c74949d
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
183824085b728012131bda7784c34fe5146956256ab6c92a8b09359b0191d784
|
|
| MD5 |
bf3694462235c7725070546328956cec
|
|
| BLAKE2b-256 |
ac8d9a86af52f274e4b9e8ea6d801068a9a0719ef5de56aa00a9f02a850dab0b
|