A high performance, multi chain payment gateway built with Rust and Axum, implementing x402 to monetize HTTP APIs using USDC across EVM and Solana networks, with integrated Oyster CVM TEE signature verification for secure, enclave backed request verification.
x402-gateway is an early-stage Rust project in the AI payments / x402 ecosystem. It currently has 0 GitHub stars and 0 forks.
A high performance, multi chain payment gateway built with Rust and Axum, implementing x402 (V2) to monetize HTTP APIs using USDC across EVM and Solana networks, with integrated Oyster CVM TEE signature verification for secure, enclave backed request validation.
payment-required header.The service is configured via a config.json file. You can set the path using the CONFIG_PATH environment variable (defaults to config.json).
config.json{
"gateway_port": 3000,
"facilitator_url": "https://www.x402.org/facilitator",
"target_api_url": "http://127.0.0.1:11434",
"networks": [
{
"type": "evm",
"network": "base-sepolia",
"payment_address": "0xYOUR_EVM_ADDRESS"
},
{
"type": "solana",
"network": "solana-devnet",
"payment_address": "YOUR_SOLANA_PUBKEY"
}
],
"protected_routes": [
{
"path": "/api/chat",
"usdc_amount": 1
}
]
}
gateway_port: The port the gateway listens on (default: 3000).facilitator_url: The x402 facilitator service URL.target_api_url: The backend API URL to proxy requests to.networks: Array of supported blockchain networks.type: "evm" or "solana".network: Network identifier (e.g., "base-sepolia", "solana-devnet").payment_address: Your wallet address for receiving payments.protected_routes: List of routes requiring payment. All other routes are proxied freely by default.path: The URL path.usdc_amount: Cost in USDC microunits (e.g., 1000 = 0.001 USDC).| Variable | Description | Default |
|---|---|---|
CONFIG_PATH |
Path to config.json |
config.json |
SIGNING_PRIVATE_KEY_HEX |
Hex-encoded 32-byte secp256k1 private key for signing responses | — |
SIGNING_KEY_DERIVE_URL |
URL to derive signing key from KMS | http://127.0.0.1:1100/derive/secp256k1?path=signing-server |
If
SIGNING_PRIVATE_KEY_HEXis set, it takes priority. Otherwise the gateway fetches the key from the KMS derive URL (used in Oyster CVM deployments).
config.example.json to config.json and update with your details.export SIGNING_PRIVATE_KEY_HEX="your_64_char_hex_private_key"
cargo run
Or with custom config path:CONFIG_PATH=production.json cargo run --release
This setup demonstrates monetizing an Ollama LLM behind the x402 gateway.
ollama serve
ollama pull qwen3:0.6b
config.json to point to Ollama:{
"target_api_url": "http://127.0.0.1:11434",
"protected_routes": [
{ "path": "/api/chat", "usdc_amount": 1 }
]
}
SIGNING_PRIVATE_KEY_HEX="your_key" cargo run
curl http://localhost:3000/api/version
curl -v http://localhost:3000/api/chat
The docker-compose.yml bundles the gateway with Ollama and auto-pulls the qwen3:0.6b model:
services:
x402-gateway:
image: sagarparker/x402-gateway:latest
network_mode: host
environment:
- CONFIG_PATH=/init-params/config.json
volumes:
- /init-params:/init-params:ro
ollama_server:
image: alpine/ollama:0.10.1
network_mode: host
ollama_model:
image: alpine/ollama:0.10.1
command: pull qwen3:0.6b
network_mode: host
depends_on:
ollama_server:
condition: service_healthy
You can deploy the gateway to an Oyster CVM enclave. The config file is provided externally via init-params.
Simulate locally (for testing):
oyster-cvm simulate --docker-compose docker-compose.yml --init-params "config.json:1:0:file:./config.json"
Deploy to Oyster CVM:
oyster-cvm deploy \
--wallet-private-key <key> \
--duration-in-minutes 30 \
--arch amd64 \
--docker-compose docker-compose.yml \
--init-params "config.json:1:0:file:./config.json"
The --init-params flag follows the format: <enclave_path>:<attest>:<encrypt>:<type>:<value>
config.json — placed at /init-params/config.json inside the enclave1 — included in attestation0 — not encrypted (use 1 if your config contains secrets)file — read from a local file./config.json — path to the local config fileAccess protected routes directly. The gateway returns 402 Payment Required with payment details in the payment-required header if no valid payment is present.
curl -v http://localhost:3000/api/chat
EVM Mainnets: Base, Polygon, Avalanche, Sei, XDC, XRPL EVM, Peaq, IoTeX, Celo
EVM Testnets: Base Sepolia, Polygon Amoy, Avalanche Fuji, Sei Testnet, Celo Sepolia
Solana: Mainnet, Devnet
Note: Set
SIGNING_PRIVATE_KEY_HEX(for local) or deploy on Oyster CVM (for KMS-derived keys).
Recover the public key from a signed response:
cargo run --bin verifier -- http://<ENCLAVE_IP>:8888/your-endpoint
Get the expected public key directly from the KMS:
oyster-cvm kms-derive \
--image-id <IMAGE_ID> \
--path signing-server \
--key-type secp256k1/public
The public key from the verifier should match the public key from kms-derive. This confirms that:
image-id)signing-server pathThe X-Signature header contains a 65-byte hex-encoded signature:
The signed message is the Keccak256 hash of:
"oyster-signature-v2\0" ||
u32be(len(request_method)) || request_method ||
u32be(len(request_path_and_query)) || request_path_and_query ||
u64be(len(request_body)) || request_body ||
u64be(len(response_body)) || response_body
Agent behavior that compiles
An open SDK for agentic payments. Let AI agents make payments, hold funds, and move money across chains with policy enforcement and human approval built in.
x402 payments in Rust: verify, settle, and monitor payments over HTTP 402 flows
Context-aware agentic LLM gateway & router that optimize your agentic workflows with every runs, works with any harnesses, any models, any workflows.
Production-ready x402 facilitator server.
Rust SDK for the x402 payment protocol.