1 unstable release
| 0.1.0 | Mar 10, 2026 |
|---|
#13 in #coinbase
31KB
460 lines
x402-cdp
Unofficial, community-contributed CDP (Coinbase Developer Platform) facilitator client for x402 payments in Rust.
Not affiliated with or endorsed by Coinbase. This crate is maintained by independent contributors who needed CDP facilitator auth in their own Rust x402 servers.
Why this crate exists
This crate helps you integrate x402 payments facilitated by CDP into your Rust project. It handles per-request Ed25519 JWT authentication with the CDP hosted facilitator in the required header and payload format.
Quickstart
1. Get CDP API keys from the Coinbase Developer Platform.
2. Set environment variables:
export CDP_API_KEY_ID="your-key-id"
export CDP_API_KEY_SECRET="your-base64-ed25519-secret"
3. Add to your Cargo.toml:
[dependencies]
x402-cdp = "0.1"
x402-axum = "1.4"
4. Mount the proxy and apply x402 middleware:
use x402_axum::X402Middleware;
use x402_cdp::{CdpConfig, cdp_proxy_router};
let port = 3000;
let cdp_config = CdpConfig::from_env()?;
let cdp_router = cdp_proxy_router(cdp_config)?;
let x402 = X402Middleware::new(&format!("http://127.0.0.1:{port}/_cdp"));
let app = Router::new()
.nest("/_cdp", cdp_router)
.route("/paid", get(handler).layer(x402.with_price_tag(price_tag)));
That's it. The proxy signs each facilitator request, normalizes the payment schema, and forwards errors with full CDP response bodies for debugging.
How it works
The crate provides an axum router with three endpoints (/verify, /settle, /supported) that proxy requests to the CDP facilitator. On each request, it:
- Constructs an Ed25519 JWT with the claims CDP expects (
kid,nonce,uri,sub,iss,aud,nbf,exp) - Adds both
amountandmaxAmountRequiredfields to the payment payload (CDP requiresamount, x402-axum v1 sendsmaxAmountRequired) - Forwards the request with the signed JWT in the
Authorizationheader - Returns the CDP response, logging non-success responses at warn level
Facilitator trait impl
CdpFacilitator also implements x402_types::facilitator::Facilitator directly. This is available for non-axum use cases or for when X402Middleware adds a generic constructor that accepts impl Facilitator.
use x402_cdp::{CdpConfig, CdpFacilitator};
use x402_types::facilitator::Facilitator;
let facilitator = CdpFacilitator::new(CdpConfig::from_env()?)?;
let response = facilitator.verify(&request).await?;
Environment variables
| Variable | Required | Default |
|---|---|---|
CDP_API_KEY_ID |
yes | |
CDP_API_KEY_SECRET |
yes | |
CDP_FACILITATOR_URL |
no | https://api.cdp.coinbase.com/platform/v2/x402 |
CDP_REQUEST_TIMEOUT_SECS |
no | 30 |
Features
| Feature | Default | Description |
|---|---|---|
axum-router |
yes | Enables cdp_proxy_router() and the axum dependency |
To use only the Facilitator trait impl without axum:
[dependencies]
x402-cdp = { version = "0.1", default-features = false }
Status
This crate is in active use in production. It is not part of the official x402 or CDP ecosystems.
Bug reports and contributions welcome on GitHub.
License
MIT
Made with <3 at Bitcoin.com
Dependencies
~20–31MB
~466K SLoC