← 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