A proof-of-concept implementation of the x402 payment protocol on the Casper blockchain. Enables HTTP 402-based micropayments using EIP-3009-style transfer_with_authorization on CEP-18 tokens, with EIP-712 typed structured data hashing for authorization messages.
The x402 protocol brings the long-dormant HTTP 402 ("Payment Required") status code to life. It defines a standard flow for machine-to-machine payments on the web:
- A client requests a paid resource.
- The server responds with 402 and a payment requirement header describing how to pay.
- The client signs a payment authorization off-chain and retries the request with a payment header.
- The server verifies the payment (optionally settling on-chain) and returns the resource.
This project adapts the protocol for the Casper network by implementing gasless, signature-based token transfers — similar to EIP-3009 (transferWithAuthorization) — on top of the CEP-18 token standard. Authorization messages use EIP-712 typed structured data hashing for secure, unambiguous off-chain signing.
┌──────────┐ GET /resource ┌──────────────────┐ POST /settle ┌──────────────┐
│ │ ────────────────▶ │ │ ───────────────▶ │ │
│ Client │ ◀──── 402 ──── │ Resource Server │ ◀── 200 ────── │ Facilitator │
│ │ │ │ │ │
│ │ GET + X-PAYMENT │ │ │ │
│ │ ────────────────▶ │ │ │ │
│ │ ◀──── 200 ───── │ │ │ │
└──────────┘ └──────────────────┘ └──────┬───────┘
│
on-chain settle
│
┌──────▼───────┐
│ Casper │
│ Network │
│ (CEP-18 │
│ + x402) │
└──────────────┘
The project consists of five crates:
A CEP-18 token contract extended with transfer_with_authorization — gasless, off-chain-signed transfers. Built with the Odra smart contract framework.
- EIP-712 authorization: messages are hashed using a domain separator (
chain_name,contract_package_hash) and aTransferAuthorizationstruct (from,to,value,valid_after,valid_before,nonce) - On-chain verification: replay protection (nonce mapping), time-window checks, Ed25519 signature verification
- Standard CEP-18 interface
Defines the EIP-712 domain separator and TransferAuthorization struct used across the contract, facilitator, and demo. Implements casper_eip_712::Eip712Struct for typed structured data hashing. This is the single source of truth for the authorization message format.
Common request/response types used by both the facilitator and demo crates: PaymentRequired, CasperAuthorization, PaymentPayload, VerifyRequest, SettleRequest, and related structs. Re-exports TransferAuthorization from x402-eip712.
An HTTP service (Axum) that verifies payment authorizations and settles them on-chain.
| Endpoint | Description |
|---|---|
GET /supported |
Returns x402 protocol metadata (network, asset, version) |
POST /verify |
Off-chain signature and authorization validation |
POST /settle |
Verify + submit on-chain transfer_with_authorization |
Settles payments against a local Casper network (nctl).
A self-contained binary that runs a resource server, a web UI, and a client, demonstrating the full x402 payment flow. The resource server exposes a paid endpoint at /api/data, and the UI at / provides a browser-based interface to trigger the payment flow via /api/run-flow.
- Rust nightly (
nightly-2025-01-01, pinned inrust-toolchain) - Docker & Docker Compose (for running a local Casper network)
- just command runner (optional, but convenient)
git clone https://github.com/odradev/casper-x402-poc.git
cd casper-x402-poc
cp .env.example .envThe WASM binary must be built before starting the Docker stack, as the wasm/ directory is mounted as a volume:
just build-contractSpin up a local Casper network, deploy the contract, and start the facilitator:
just docker-up
# Follow logs
just docker-logs {{service}}
# Check service status
just docker-psThis starts:
- nctl — local Casper test network
- deployer — deploys the CEP-18 x402 contract (one-shot)
- facilitator — settlement service on port 3001
Once the facilitator is running:
just run-demoThe demo uses keys from the local nctl network, starts a resource server, and runs through the complete payment flow against the local Casper node.
Copy .env.example to .env and adjust as needed:
| Variable | Description | Default |
|---|---|---|
PORT |
Facilitator listen port | 3001 |
RESOURCE_SERVER_PORT |
Demo resource server port | 3002 |
RESOURCE_SERVER_URL |
URL the demo client uses to reach the resource server | http://127.0.0.1:3002 |
FACILITATOR_URL |
URL the resource server uses to reach the facilitator | http://127.0.0.1:3001 |
CONTRACT_PACKAGE_HASH |
Deployed contract address (set automatically by the deployer) | — |
PAY_TO |
Recipient account hash | — |
PAYMENT_AMOUNT |
Payment amount in token units | 1000000 |
SECRET_KEY_PATH |
Path to the Ed25519 secret key for the demo client | .node_keys/secret_key.pem |
ODRA_CASPER_LIVENET_* |
Casper node connection settings | — |
# Run contract tests
just test
# Run a specific test
just test-one transfer_with_authorization_succeeds
# Build contract WASM
just build-contract
# Run facilitator + demo together
just run-all
# Docker helpers
just docker-up
just docker-down
just docker-logs facilitator- x402 Protocol Specification — the payment protocol this project implements
- EIP-3009: Transfer With Authorization — the Ethereum standard that inspired the
transfer_with_authorizationpattern - EIP-712: Typed Structured Data Hashing — the standard used for authorization message hashing
- casper-eip-712 — Casper-native EIP-712 implementation used for typed data hashing
- Casper Network — the L1 blockchain
- CEP-18 Token Standard — Casper's fungible token standard (analogous to ERC-20)
- Odra Framework — smart contract framework used to build the contract
- Odra Documentation — Odra guides and API reference
See LICENSE for details.