| Crates.io | x402-rs |
| lib.rs | x402-rs |
| version | 0.7.3 |
| created_at | 2025-05-08 14:36:53.520413+00 |
| updated_at | 2025-09-23 22:44:34.460011+00 |
| description | x402 payments in Rust: verify, settle, and monitor payments over HTTP 402 flows |
| homepage | https://x402.rs |
| repository | https://github.com/x402-rs/x402-rs |
| max_upload_size | |
| id | 1665414 |
| size | 447,279 |
A Rust-based implementation of the x402 protocol.
This repository provides:
x402-rs (current crate):
x402-axum - Axum middleware for accepting x402 payments,x402-reqwest - Wrapper for reqwest for transparent x402 payments,x402-axum-example - an example of x402-axum usage.x402-reqwest-example - an example of x402-reqwest usage.The x402 protocol is a proposed standard for making blockchain payments directly through HTTP using native 402 Payment Required status code.
Servers declare payment requirements for specific routes. Clients send cryptographically signed payment payloads. Facilitators verify and settle payments on-chain.
docker run --env-file .env -p 8080:8080 ukstv/x402-facilitator
Or build locally:
docker build -t x402-rs .
docker run --env-file .env -p 8080:8080 x402-rs
See the Facilitator section below for full usage details
Use x402-axum to gate your routes behind on-chain payments:
let x402 = X402Middleware::try_from("https://x402.org/facilitator/").unwrap();
let usdc = USDCDeployment::by_network(Network::BaseSepolia);
let app = Router::new().route("/paid-content", get(handler).layer(
x402.with_price_tag(usdc.amount("0.025").pay_to("0xYourAddress").unwrap())
),
);
See x402-axum crate docs.
Use x402-reqwest to send payments:
let signer: PrivateKeySigner = "0x...".parse()?; // never hardcode real keys!
let client = reqwest::Client::new()
.with_payments(signer)
.prefer(USDCDeployment::by_network(Network::Base))
.max(USDCDeployment::by_network(Network::Base).amount("1.00")?)
.build();
let res = client
.get("https://example.com/protected")
.send()
.await?;
| Milestone | Description | Status |
|---|---|---|
| Facilitator for Base USDC | Payment verification and settlement service, enabling real-time pay-per-use transactions for Base chain. | ✅ Complete |
| Metrics and Tracing | Expose OpenTelemetry metrics and structured tracing for observability, monitoring, and debugging | ✅ Complete |
| Server Middleware | Provide ready-to-use integration for Rust web frameworks such as axum and tower. | ✅ Complete |
| Client Library | Provide a lightweight Rust library for initiating and managing x402 payment flows from Rust clients. | ✅ Complete |
| Solana Support | Support Solana chain. | ✅ Complete |
| Multiple chains and multiple tokens | Support various tokens and EVM compatible chains. | ⏳ Planned |
| Payment Storage | Persist verified and settled payments for analytics, access control, and auditability. | 🔜 Planned |
| Micropayment Support | Enable fine-grained offchain usage-based payments, including streaming and per-request billing. | 🔜 Planned |
The initial focus is on establishing a stable, production-quality Rust SDK and middleware ecosystem for x402 integration.
The x402-rs crate (this repo) provides a runnable x402 facilitator binary. The Facilitator role simplifies adoption of x402 by handling:
By using a Facilitator, servers (sellers) do not need to:
Instead, they can rely on the Facilitator to perform verification and settlement, reducing operational overhead and accelerating x402 adoption. The Facilitator never holds user funds. It acts solely as a stateless verification and execution layer for signed payment payloads.
For a detailed overview of the x402 payment flow and Facilitator role, see the x402 protocol documentation.
Create a .env file or set environment variables directly. Example .env:
HOST=0.0.0.0
PORT=8080
RPC_URL_BASE_SEPOLIA=https://sepolia.base.org
RPC_URL_BASE=https://mainnet.base.org
SIGNER_TYPE=private-key
EVM_PRIVATE_KEY=0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
SOLANA_PRIVATE_KEY=6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt
RUST_LOG=info
Important: The supported networks are determined by which RPC URLs you provide:
RPC_URL_BASE_SEPOLIA, then only Base Sepolia network is supported.RPC_URL_BASE_SEPOLIA and RPC_URL_BASE, then both Base Sepolia and Base Mainnet are supported.Prebuilt Docker images are available at:
ghcr.io/x402-rs/x402-facilitatorukstv/x402-facilitatorRun the container from Docker Hub:
docker run --env-file .env -p 8080:8080 ukstv/x402-facilitator
To run using GitHub Container Registry:
docker run --env-file .env -p 8080:8080 ghcr.io/x402-rs/x402-facilitator
Or build a Docker image locally:
docker build -t x402-rs .
docker run --env-file .env -p 8080:8080 x402-rs
The container:
8080 (or a port you configure with PORT environment variable).debian:bullseye-slim).If you are building an x402-powered application, update the Facilitator URL to point to your self-hosted instance.
ℹ️ Tip: For production deployments, ensure your Facilitator is reachable via HTTPS and protect it against public abuse.
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { paymentMiddleware } from "x402-hono";
const app = new Hono();
// Configure the payment middleware
app.use(paymentMiddleware(
"0xYourAddress", // Your receiving wallet address
{
"/protected-route": {
price: "$0.10",
network: "base-sepolia",
config: {
description: "Access to premium content",
}
}
},
{
url: "http://your-validator.url/", // 👈 Your self-hosted Facilitator
}
));
// Implement your protected route
app.get("/protected-route", (c) => {
return c.json({ message: "This content is behind a paywall" });
});
serve({
fetch: app.fetch,
port: 3000
});
let x402 = X402Middleware::try_from("http://your-validator.url/").unwrap(); // 👈 Your self-hosted Facilitator
let usdc = USDCDeployment::by_network(Network::BaseSepolia);
let app = Router::new().route("/paid-content", get(handler).layer(
x402.with_price_tag(usdc.amount("0.025").pay_to("0xYourAddress").unwrap())
),
);
The service reads configuration via .env file or directly through environment variables.
Available variables:
RUST_LOG: Logging level (e.g., info, debug, trace),
HOST: HTTP host to bind to (default: 0.0.0.0),
PORT: HTTP server port (default: 8080),
SIGNER_TYPE (required): Type of signer to use. Only private-key is supported now,
EVM_PRIVATE_KEY (required): Private key in hex for EVM networks, like 0xdeadbeef...,
SOLANA_PRIVATE_KEY (required): Private key in hex for Solana networks, like 0xdeadbeef...,
RPC_URL_BASE_SEPOLIA: Ethereum RPC endpoint for Base Sepolia testnet,
RPC_URL_BASE: Ethereum RPC endpoint for Base mainnet,
RPC_URL_AVALANCHE_FUJI: Ethereum RPC endpoint for Avalanche Fuji testnet,
RPC_URL_AVALANCHE: Ethereum RPC endpoint for Avalanche C-Chain mainnet.
RPC_URL_SOLANA: RPC endpoint for Solana mainnet.
RPC_URL_SOLANA_DEVNET: RPC endpoint for Solana devnet.
RPC_URL_POLYGON: RPC endpoint for Polygon mainnet.
RPC_URL_POLYGON_AMOY: RPC endpoint for Polygon Amoy testnet.
The facilitator emits OpenTelemetry-compatible traces and metrics to standard endpoints, making it easy to integrate with tools like Honeycomb, Prometheus, Grafana, and others. Tracing spans are annotated with HTTP method, status code, URI, latency, other request and process metadata.
To enable tracing and metrics export, set the appropriate OTEL_ environment variables:
# For Honeycomb, for example:
# Endpoint URL for sending OpenTelemetry traces and metrics
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443
# Comma-separated list of key=value pairs to add as headers
OTEL_EXPORTER_OTLP_HEADERS=x-honeycomb-team=your_api_key,x-honeycomb-dataset=x402-rs
# Export protocol to use for telemetry. Supported values: `http/protobuf` (default), `grpc`
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
The service automatically detects and initializes exporters if OTEL_EXPORTER_OTLP_* variables are provided.
The Facilitator supports different networks based on the environment variables you configure:
| Network | Environment Variable | Supported if Set | Notes |
|---|---|---|---|
| Base Sepolia Testnet | RPC_URL_BASE_SEPOLIA |
✅ | Testnet, Recommended for testing |
| Base Mainnet | RPC_URL_BASE |
✅ | Mainnet |
| XDC Mainnet | RPC_URL_XDC |
✅ | Mainnet |
| Avalanche Fuji Testnet | RPC_URL_AVALANCHE_FUJI |
✅ | Testnet |
| Avalanche C-Chain Mainnet | RPC_URL_AVALANCHE |
✅ | Mainnet |
| Polygon Amoy Testnet | RPC_URL_POLYGON_AMOY |
✅ | Testnet |
| Polygon Mainnet | RPC_URL_POLYGON |
✅ | Mainnet |
| Solana Mainnet | RPC_URL_SOLANA |
✅ | Mainnet |
| Solana Devnet | RPC_URL_SOLANA_DEVNET |
✅ | Testnet, Recommended for testing |
RPC_URL_BASE_SEPOLIA, only Base Sepolia will be available.RPC_URL_BASE_SEPOLIA, RPC_URL_BASE, and other env variables on the list, then all the specified networks will be supported.ℹ️ Tip: For initial development and testing, you can start with Base Sepolia only.
Prerequisites:
cargo and a working toolchainBuild locally:
cargo build
Run:
cargo run
Feel free to open issues or pull requests to improve x402 support in the Rust ecosystem.