Introduction
Architecture

Architecture

Preimage Research uses a stateless proxy-to-gateway pattern that keeps provider SDKs simple while centralizing payment logic in the Gateway.

System Overview

┌──────────────────────────────────────────────────────────────┐
│                     Ecosystem Layer                          │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────┐            ┌──────────────────────────┐     │
│  │   Buyers    │            │   API Providers          │     │
│  │             │            │                          │     │
│  │ - Web apps  │            │ - Express APIs           │     │
│  │ - Mobile    │            │ - FastAPI services       │     │
│  │ - CLI tools │            │ - Django apps            │     │
│  │ - Scripts   │            │ - Gin servers            │     │
│  └──────┬──────┘            │ - Axum services          │     │
│         │                   └────────┬─────────────────┘     │
│         │                            │                       │
└─────────┼────────────────────────────┼────────────────────── ┘
          │                            │
          │                            │
┌─────────┼────────────────────────────┼──────────────────────┐
│         │       SDK Layer            │                      │
├─────────┼────────────────────────────┼──────────────────────┤
│         │                            │                      │
│  ┌──────▼────────┐          ┌────────▼───────────┐          │
│  │ @preimage/    │          │ Provider SDK       │          │
│  │   client      │          │ Middleware         │          │
│  │               │          │                    │          │
│  │ - Auto 402    │          │ - Forward requests │          │
│  │ - Sign USDC   │          │ - Proxy to Gateway │          │
│  │ - Retry       │          │ - Attach receipts  │          │
│  └───────┬───────┘          └─────────┬──────────┘          │
│          │                            │                     │
└──────────┼────────────────────────────┼─────────────────────┘
           │                            │
           │       HTTP/HTTPS           │
           │                            │
┌──────────┼────────────────────────────┼─────────────────────┐
│          │     Core Infrastructure    │                     │
├──────────┼────────────────────────────┼─────────────────────┤
│          │                            │                     │
│          └────────────┬───────────────┘                     │
│                       │                                     │
│              ┌────────▼─────────────┐                       │
│              │ Preimage Research Gateway │                  │
│              │                      │                       │
│              │ - Generate challenges│                       │
│              │ - Verify macaroons   │                       │
│              │ - Verify payments    │                       │
│              │ - Sign receipts      │                       │
│              │ - Manage providers   │                       │
│              └─────────┬────────────┘                       │
│                        │                                    │
│                        │                                    │
│              ┌─────────▼────────────┐                       │
│              │ x402 Facilitator     │                       │
│              │                      │                       │
│              │ - Submit USDC txs    │                       │
│              │ - Verify on-chain    │                       │
│              │ - Gas management     │                       │
│              └─────────┬────────────┘                       │
│                        │                                    │
└────────────────────────┼────────────────────────────────────┘


┌────────────────────────┼────────────────────────────────────┐
│                        │   Blockchain Layer                 │
├────────────────────────┼────────────────────────────────────┤
│                        │                                    │
│              ┌─────────▼────────────┐                       │
│              │ Base / Ethereum /    │                       │
│              │ Polygon              │                       │
│              │                      │                       │
│              │ - USDC smart contract│                       │
│              │ - EIP-3009 transfers │                       │
│              │ - Settlement         │                       │
│              └──────────────────────┘                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Stateless Proxy Pattern

Why Proxy-to-Gateway?

Traditional payment systems require each API to:

  • 🗄️ Maintain a database
  • 🔐 Manage user accounts
  • 💳 Process payments
  • 📊 Track usage
  • 🧾 Generate invoices

Preimage Research simplifies this: Provider SDKs are thin proxies that forward auth requests to the Gateway.

Benefits

AspectTraditionalPreimage Research
DatabaseRequiredNot needed
StateStatefulStateless
SDK Complexity1000+ LOC50-100 LOC
Payment LogicPer-providerCentralized
UpdatesManual deployAutomatic
ConsistencyVariesIdentical

Stateless = Scalable. Your API can scale horizontally without worrying about session state or payment verification logic.

Component Breakdown

1. Client SDK (@preimage/client)

Purpose: Automatically handle 402 challenges for API consumers

Responsibilities:

  • Detect 402 Payment Required responses
  • Parse x402 challenges
  • Sign USDC payments (EIP-3009)
  • Retry requests with authorization
  • Extract and return receipts

Example Flow:

const client = createClient({ ... });
 
// 1. Initial request → 402 response (handled internally)
// 2. Sign USDC payments (handled internally)
// 3. Retry with auth (handled internally)
// 4. Return data + receipt
const response = await client.request('/api/data');

2. Provider SDKs

Purpose: Protect API endpoints with minimal code

Available SDKs:

  • Express (Node.js)
  • FastAPI (Python)
  • Django (Python)
  • Gin (Go)
  • Axum (Rust)

Responsibilities:

  • Intercept incoming requests
  • Check for Authorization: x402 header
  • If missing → Forward to Gateway for challenge
  • If present → Forward to Gateway for verification
  • Attach receipt to response
  • Pass request to API handler

Example (Express):

app.use('/api', createX402Middleware({
  gatewayUrl: 'https://gateway.preimage.io',
  providerId: 'prov_abc123',
  pricing: { usdcPerUnit: 0.001 }
}));
 
app.get('/api/data', (req, res) => {
  // Only called if payment verified!
  res.json({ data: 'success' });
});

3. Preimage Research Gateway

Purpose: Centralized payment logic and verification for Preimage Research

Responsibilities:

  • Provider Management - Register providers, endpoints, wallets
  • Challenge Generation - Create macaroons with pricing info
  • Payment Verification - Validate signatures and amounts
  • Facilitator Integration - Submit USDC transfers to blockchain
  • Receipt Signing - Generate JWS receipts
  • Rate Limiting - Prevent abuse
  • Analytics - Track usage and revenue

API Endpoints:

POST   /providers                     # Register provider
POST   /providers/:id/endpoints       # Add endpoint
POST   /providers/:id/wallets         # Add wallet
GET    /challenge                     # Generate challenge
POST   /verify                        # Verify payment
GET    /receipts/:id                  # Get receipt
💡

The Gateway is operated by Preimage Research. You don't need to deploy or maintain it.

4. x402 Facilitator

Purpose: Non-custodial blockchain transaction submission

Responsibilities:

  • Receive signed USDC transfers
  • Verify signatures
  • Submit to blockchain
  • Pay gas fees
  • Return transaction hash
  • Handle failures/retries

Supported Networks:

  • Base (mainnet + sepolia)
  • Ethereum (mainnet + sepolia)
  • Polygon (mainnet + amoy)
⚠️

Facilitators are non-custodial. They never hold funds - they only submit pre-signed transactions to the blockchain.

Request Flow (Detailed)

Challenge Phase

1. Client → Provider SDK
   GET /api/data

2. Provider SDK → Gateway
   POST /challenge
   {
     "providerId": "prov_abc",
     "endpointId": "ep_xyz",
     "pricing": { "usdcPerUnit": 0.001 }
   }

3. Gateway → Provider SDK
   200 OK
   {
     "macaroon": "...",
     "accepts": [ ... ],
     "requestId": "..."
   }

4. Provider SDK → Client
   402 Payment Required
   { x402 challenge }

Payment Phase

5. Client (local)
   - Parse challenge
   - Sign USDC payment #1 (provider)
   - Sign USDC payment #2 (platform)
   - Build Authorization header

Verification Phase

6. Client → Provider SDK
   GET /api/data
   Authorization: x402 <macaroon>:<payload1>:<payload2>

7. Provider SDK → Gateway
   POST /verify
   {
     "macaroon": "...",
     "payloads": [ ... ],
     "providerId": "...",
     "endpointId": "..."
   }

8. Gateway → Facilitator
   POST /submit
   { signed USDC transfers }

9. Facilitator → Blockchain
   transferWithAuthorization(...)

10. Blockchain → Facilitator
    Transaction hash: 0x789...

11. Facilitator → Gateway
    { txHash: "0x789..." }

12. Gateway → Provider SDK
    200 OK
    {
      "verified": true,
      "receipt": "eyJ...",  // JWS receipt
      "paymentId": "pay_123"
    }

13. Provider SDK → API Handler
    req.x402 = { receipt, verified: true }

14. API Handler → Provider SDK
    { data: "response" }

15. Provider SDK → Client
    200 OK
    Preimage-Receipt: eyJ...
    { data: "response" }

Data Flow

Macaroon Flow

Gateway

  ├─ Generate macaroon
  │  ├─ Add caveat: provider-id
  │  ├─ Add caveat: endpoint-id
  │  ├─ Add caveat: expiry (5 min)
  │  └─ Sign with Gateway secret


Client

  ├─ Receive macaroon in 402 response
  ├─ Store temporarily
  └─ Include in retry Authorization header


Gateway

  ├─ Verify signature
  ├─ Check expiry caveat
  ├─ Check provider-id caveat
  └─ Check endpoint-id caveat

Payment Flow

Client Wallet

  ├─ Sign USDC transfer #1 (provider)
  │  └─ EIP-712 signature

  ├─ Sign USDC transfer #2 (platform)
  │  └─ EIP-712 signature


Gateway

  ├─ Verify signatures
  ├─ Check amounts
  └─ Submit to facilitator


Facilitator

  ├─ Call USDC.transferWithAuthorization(...)
  ├─ Payment #1 → Provider wallet (98%)
  └─ Payment #2 → Platform wallet (2%)


Blockchain

  ├─ Verify signatures
  ├─ Check balances
  ├─ Execute transfers
  └─ Emit events

Security Model

Trust Boundaries

ComponentTrusted ByTrust Level
Client SDKBuyerFull (open source)
Provider SDKProviderFull (open source)
GatewayBothVerifiable (signed receipts)
FacilitatorBothNon-custodial (can't steal funds)
BlockchainEveryoneTrustless (EVM)

What If Gateway Is Malicious?

Cannot:

  • ❌ Steal USDC (non-custodial, signed transfers only)
  • ❌ Forge receipts (public key verification)
  • ❌ Charge wrong amount (client signs specific amounts)

Can (but detectable):

  • ⚠️ Refuse to process payments (provider loses money)
  • ⚠️ Return fake verification (receipt verification catches this)

Receipts provide accountability. Every payment has a cryptographically signed proof that can be independently verified.

What If Provider SDK Is Malicious?

Cannot:

  • ❌ Steal USDC (never has access to private keys)
  • ❌ Forge receipts (Gateway signature required)

Can:

  • ⚠️ Not honor API requests (buyer wasted money - reputation damage)

Scalability

Gateway Scalability

  • Horizontal scaling with load balancer
  • Stateless (no session management)
  • Cached macaroon secrets (fast verification)
  • Async receipt signing (non-blocking)

Provider SDK Scalability

  • Completely stateless
  • No database required
  • No session storage
  • CDN-friendly (cache static responses)

Blockchain Scalability

NetworkTPSBlock TimeFinality
Base~10002s2s
Ethereum~1512s12min
Polygon~70002s2s
💡

We recommend Base for production. It offers the best balance of speed, cost, and security for x402 payments.

Next Steps