← Back to Docs

Technical Overview

Deep dive into the authentication and payment architecture.

Architecture Overview


┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│   Browser   │────▶│   x402 Proxy     │────▶│  Video CDN  │
│  (HLS.js)   │◀────│   (Express)      │◀────│   (Mux)     │
└─────────────┘     └──────────────────┘     └─────────────┘
       │                     │
       │                     ▼
       │            ┌──────────────────┐
       │            │  x402 Facilitator│
       │            │   (Payment)      │
       │            └──────────────────┘
       │                     │
       ▼                     ▼
┌─────────────┐     ┌──────────────────┐
│   Wallet    │     │   Base Network   │
│ (MetaMask)  │     │   (USDC)         │
└─────────────┘     └──────────────────┘
              

JWT Token Structure

After successful payment, we issue a JWT containing the playbackId and expiration time:

Token Payload
{
  "playbackId": "ABC123...",
  "iat": 1733400000,      // Issued at (Unix timestamp)
  "exp": 1733486400       // Expires at (24 hours later)
}

The token is signed with a server-side secret using HS256. Tokens cannot be forged without the secret key.

Cookie Strategy

We use per-video cookies to allow access to multiple videos:

Cookie Names
x402-ABC123=eyJhbGc...  // Token for video ABC123
x402-XYZ789=eyJhbGc...  // Token for video XYZ789
x402-viewing=token...   // Current viewing session
HttpOnly: Prevents XSS attacks from stealing tokens
SameSite=Lax: Prevents CSRF attacks
24h MaxAge: Automatic cleanup of expired tokens

Middleware Chain

Each segment request goes through this middleware chain:

1. validateJwtMiddleware
Checks for valid JWT cookie. If valid, skips payment.
2. x402Middleware
Validates x402 payment with facilitator. Returns 402 if no payment.
3. createJwtMiddleware
Issues JWT after successful payment. Sets cookie.
4. proxy
Forwards request to video CDN. Returns segment data.

x402 Payment Protocol

The x402 protocol uses EIP-3009 (TransferWithAuthorization) for gasless USDC transfers:

Payment Authorization
{
  "domain": {
    "name": "USDC",
    "version": "2",
    "chainId": 84532,           // Base Sepolia
    "verifyingContract": "0x..." // USDC contract
  },
  "message": {
    "from": "0x...",            // Viewer wallet
    "to": "0x...",              // Creator wallet
    "value": "50000",           // $0.05 (6 decimals)
    "validAfter": "...",
    "validBefore": "...",
    "nonce": "0x..."
  },
  "primaryType": "TransferWithAuthorization"
}

The facilitator receives this signed message and executes the actual USDC transfer on-chain.

Security Considerations

🔐 JWT Secret

Store JWT_SECRET in environment variables. Never commit to source control.

🔄 Token Replay

Tokens are bound to playbackId. Cannot use one video token to access another video.

⏰ Expiration

24-hour expiry limits damage from token theft. Can be configured shorter.

🌐 HTTPS

In production, use HTTPS and set secure: trueon cookies.

Environment Variables

Server Configuration
# Required
ORIGIN_BASE_URL=https://stream.mux.com
WALLET_ADDRESS=0x...        # Fallback wallet
MUX_TOKEN_ID=...            # Video CDN credentials
MUX_TOKEN_SECRET=...

# Optional
JWT_SECRET=...              # Random 32+ char string
NETWORK=base-sepolia        # or base-mainnet
ASSET_PRICE=$0.01           # Per-segment price
FACILITATOR_URL=https://x402.org/facilitator
PORT=4000