#coinbase #cdp #x402 #payment

x402-cdp

Unofficial CDP (Coinbase Developer Platform) facilitator client for x402 pay-per-request payments in Rust

1 unstable release

0.1.0 Mar 10, 2026

#13 in #coinbase

MIT license

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:

  1. Constructs an Ed25519 JWT with the claims CDP expects (kid, nonce, uri, sub, iss, aud, nbf, exp)
  2. Adds both amount and maxAmountRequired fields to the payment payload (CDP requires amount, x402-axum v1 sends maxAmountRequired)
  3. Forwards the request with the signed JWT in the Authorization header
  4. 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