Menu

Explorer & Settings

Tempo Explorer Submit Project
Back to all projects

x402-tyk-middleware

by emfidev · Updated 8 months ago

Blockchain micropayment middleware for Tyk API Gateway implementing the X402 Payment Protocol

In the AI payments ecosystem

x402-tyk-middleware is an early-stage TypeScript project in the AI payments / x402 ecosystem. It currently has 0 GitHub stars and 0 forks.

README.md View on GitHub →

X402 Tyk Middleware

Blockchain micropayment middleware for Tyk API Gateway implementing the X402 Payment Protocol

License: MIT Tyk Compatible Solana

Overview

This middleware adds native blockchain payment support to Tyk API Gateway using the HTTP 402 Payment Required standard. It enables pay-per-use pricing models with automatic payment verification and on-chain settlement.

Key Features

  • Pre-request payment verification - Validate payments before proxying to upstream
  • Post-request settlement - Settle transactions on-chain after content delivery
  • Multi-endpoint support - Different pricing per API endpoint
  • Non-blocking settlement - Async on-chain settlement doesn't delay responses
  • 🔐 Facilitator integration - Secure payment verification with X402 Facilitator
  • 🌐 Solana blockchain - Native SPL token support (more chains coming)
  • 📊 Comprehensive logging - Detailed payment flow tracking
  • 🚀 Production ready - Battle-tested, optimized for performance

Quick Start

Prerequisites

  • Tyk Gateway v5.0+ (with JSVM plugin support)
  • X402 Facilitator service (or run your own)
  • Solana wallet for receiving payments

Installation

  1. Copy middleware file to Tyk:

    cp middleware/x402_payment.js /opt/tyk-gateway/middleware/
    
  2. Configure API definition:

    {
      "name": "My Protected API",
      "api_id": "protected-api",
      "listen_path": "/api/",
      "target_url": "http://upstream-service:8000",
      "custom_middleware": {
        "driver": "otto",
        "pre": [{
          "name": "x402_payment",
          "path": "/opt/tyk-gateway/middleware/x402_payment.js",
          "require_session": false,
          "raw_body_only": true
        }],
        "post": [{
          "name": "x402_payment",
          "path": "/opt/tyk-gateway/middleware/x402_payment.js",
          "require_session": false
        }]
      },
      "config_data": {
        "x402": {
          "network": "solana-devnet",
          "payTo": "YOUR_WALLET_ADDRESS",
          "asset": "TOKEN_MINT_ADDRESS",
          "maxAmountRequired": "100",
          "feePayer": "FEE_PAYER_ADDRESS"
        }
      }
    }
    
  3. Set environment variables:

    export FACILITATOR_URL="https://facilitator.emfi.dev"
    export FACILITATOR_TIMEOUT="5000"
    
  4. Reload Tyk Gateway:

    docker compose restart tyk-gateway
    # or
    systemctl restart tyk-gateway
    

Test It

# Step 1: Request without payment (get requirements)
curl -i http://localhost:8080/api/data

# Response: 402 Payment Required
# {
#   "error": "Payment Required",
#   "paymentRequirements": {
#     "network": "solana-devnet",
#     "recipient": "YOUR_WALLET_ADDRESS",
#     ...
#   }
# }

# Step 2: Request with payment (using X402 client SDK)
curl -i http://localhost:8080/api/data \
  -H "X-Payment: {\"network\":\"solana-devnet\",\"transaction\":\"...\"}"

# Response: 200 OK with content

Architecture

Payment Flow

┌─────────┐                ┌──────────────┐              ┌──────────┐
│ Client  │                │ Tyk Gateway  │              │ Upstream │
│         │                │ + Middleware │              │          │
└────┬────┘                └──────┬───────┘              └────┬─────┘
     │                            │                           │
     │  1. GET /api/data          │                           │
     ├───────────────────────────>│                           │
     │                            │                           │
     │  2. 402 Payment Required   │                           │
     │<───────────────────────────┤                           │
     │   (payment requirements)   │                           │
     │                            │                           │
     │  3. GET /api/data          │                           │
     │     X-Payment: {...}       │                           │
     ├───────────────────────────>│                           │
     │                            │                           │
     │                            │  4. Verify with           │
     │                            │     Facilitator           │
     │                            │  ┌──────────────┐         │
     │                            ├─>│ Facilitator  │         │
     │                            │<─┤              │         │
     │                            │  └──────────────┘         │
     │                            │                           │
     │                            │  5. Proxy request         │
     │                            ├──────────────────────────>│
     │                            │                           │
     │                            │  6. Response              │
     │                            │<──────────────────────────┤
     │                            │                           │
     │  7. 200 OK + Content       │                           │
     │<───────────────────────────┤                           │
     │                            │                           │
     │                            │  8. Settle (async)        │
     │                            │  ┌──────────────┐         │
     │                            ├─>│ Blockchain   │         │
     │                            │  └──────────────┘         │
     │                            │                           │

Middleware Phases

Pre-Request Phase (Verification)

  1. Extract X-Payment header from request
  2. If no payment → return 402 with payment requirements
  3. If payment present → verify with facilitator
  4. If valid → add payment metadata headers and proxy to upstream
  5. If invalid → return 402 with error message

Post-Request Phase (Settlement)

  1. Check if payment was validated (via X-Payment-Valid header)
  2. Extract payment metadata from headers
  3. Submit settlement request to facilitator (async)
  4. Log settlement result
  5. Never block or modify client response

Configuration

API Definition Config

{
  "config_data": {
    "x402": {
      "network": "solana-devnet",           // Blockchain network
      "payTo": "8xKzG4...",                  // Your wallet address
      "asset": "4zMMC9...",                  // Token mint address
      "maxAmountRequired": "100",            // Cost in token base units
      "feePayer": "4ALzei...",               // Optional fee payer
      "scheme": "exact",                     // Optional: exact|max|dynamic
      "description": "Access to API"         // Optional description
    }
  }
}

Environment Variables

Variable Required Default Description
FACILITATOR_URL Yes https://facilitator.emfi.dev X402 Facilitator service URL
FACILITATOR_TIMEOUT No 5000 Timeout for facilitator calls (ms)

Payment Requirements

Each protected route can have custom payment requirements:

Field Type Description Example
network string Blockchain network "solana-devnet"
scheme string Payment scheme "exact"
payTo string Recipient address "4ALzeix..."
feePayer string Fee payer address "4ALzeix..."
asset string Token mint address "4zMMC9s..."
maxAmountRequired string Payment amount "100"
description string Human-readable description "Premium API access"

Per-Endpoint Pricing

Each API definition can have different pricing:

// API 1: Bitcoin endpoint - 100 tokens
{
  "api_id": "bitcoin-api",
  "listen_path": "/market/crypto/bitcoin",
  "config_data": {
    "x402": {
      "maxAmountRequired": "100"
    }
  }
}

// API 2: Stocks endpoint - 200 tokens
{
  "api_id": "stocks-api",
  "listen_path": "/market/stocks",
  "config_data": {
    "x402": {
      "maxAmountRequired": "200"
    }
  }
}

API Definition Examples

See the examples/ directory for complete API definitions:

Client Integration

Clients need to include the X402 payment proof in the request header:

const response = await axios.get('/protected/resource', {
  headers: {
    'X-Payment-x402': JSON.stringify({
      network: 'solana-devnet',
      transaction: 'BASE64_ENCODED_TRANSACTION',
      signature: 'SIGNATURE',
      payer: 'PAYER_ADDRESS',
      // ... other payment fields
    })
  }
});

For automatic payment handling, use the X402 Client SDK.

API Response Codes

Code Status Description
200 Success Payment valid, content delivered
402 Payment Required No payment or invalid payment
500 Internal Server Error Middleware error (check logs)

402 Response Format

When payment is required:

{
  "error": "Payment Required",
  "message": "This resource requires a valid X402 payment",
  "x402Version": 1,
  "paymentRequirements": {
    "scheme": "exact",
    "network": "solana-devnet",
    "description": "Access to /market/crypto/bitcoin",
    "payTo": "4ALzeix...",
    "asset": "4zMMC9s...",
    "maxAmountRequired": "100",
    "maxTimeoutSeconds": 60
  },
  "instructions": {
    "step1": "Sign a transaction with your wallet",
    "step2": "Include the signed payment object in the X-Payment-x402 header",
    "headerExample": "X-Payment-x402: { x402PaymentObject }"
  }
}

Development

Project Structure

x402-tyk-middleware/
├── middleware/
│   ├── x402_payment.js          # Main middleware
├── examples/
│   ├── bitcoin-price-api.json   # Example API definitions
│   ├── stocks-api.json
│   └── posts-api.json
├── tests/
│   ├── integration/             # Integration tests
│   ├── unit/                    # Unit tests
│   └── README.md
└── README.md

Testing

# Install dependencies
cd tests
npm install

# Run all tests
npm test

# Run specific test suite
npm run test:unit
npm run test:integration
npm run test:blockchain

# With coverage
npm run test:coverage

See tests/README.md for detailed testing documentation.

Local Development

# Start Tyk Gateway with Docker
docker compose -f docker-compose.gateway.yml up -d

# Mount middleware directory
docker compose -f docker-compose.gateway.yml \
  -v $(pwd)/middleware:/opt/tyk-gateway/middleware \
  up -d

# View logs
docker compose logs -f tyk-gateway

# Test endpoint
curl -i http://localhost:8080/market/crypto/bitcoin

Deployment

Docker

# docker-compose.yml
services:
  tyk-gateway:
    image: tykio/tyk-gateway:v5.2
    volumes:
      - ./middleware:/opt/tyk-gateway/middleware
      - ./apps:/opt/tyk-gateway/apps
    environment:
      - TYK_GW_LOGLEVEL=info
      - FACILITATOR_URL=https://facilitator.emfi.dev
    ports:
      - "8080:8080"

Kubernetes

apiVersion: v1
kind: ConfigMap
metadata:
  name: x402-middleware
data:
  x402_payment.js: |
    # Middleware content here
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tyk-gateway
spec:
  template:
    spec:
      containers:
      - name: tyk-gateway
        image: tykio/tyk-gateway:v5.2
        volumeMounts:
        - name: middleware
          mountPath: /opt/tyk-gateway/middleware
      volumes:
      - name: middleware
        configMap:
          name: x402-middleware

See docs/DEPLOYMENT.md for detailed deployment instructions.

Monitoring

Logs

The middleware logs all operations with the [x402] prefix:

[x402] No payment header found for /market/crypto/bitcoin
[x402] Payment proof parsed successfully
[x402] Verifying payment with facilitator: https://facilitator.emfi.dev
[x402] Payment verified successfully for /market/crypto/bitcoin
[x402] Settling payment for transaction: ABC123...
[x402] Settlement successful: {"signature": "DEF456..."}

Monitor these logs to track:

  • Payment verification rates
  • Settlement success/failure
  • Facilitator response times
  • Error patterns

Health Checks

# Check Tyk Gateway
curl http://localhost:8080/hello

# Check Facilitator connectivity
curl https://facilitator.emfi.dev/health

Troubleshooting

Common Issues

1. Always Getting 402 Responses

Symptoms: Even with valid payment header, receiving 402

Causes:

  • Facilitator URL not configured
  • Facilitator service down
  • Network mismatch (devnet vs mainnet)

Solution:

# Check facilitator
curl https://facilitator.emfi.dev/health

# Check logs
docker compose logs tyk-gateway | grep x402

# Verify network in API config matches payment

2. Settlement Failures

Symptoms: Payment accepted but settlement fails

Causes:

  • Fee payer address invalid
  • Insufficient SOL for fees
  • Network congestion

Solution:

  • Check fee payer has sufficient SOL
  • Monitor settlement logs
  • Settlement failures don't affect client (async)

3. Performance Issues

Symptoms: Slow response times

Causes:

  • Facilitator timeout too high
  • Not caching payment validations
  • Network latency

Solution:

# Reduce timeout
export FACILITATOR_TIMEOUT="3000"

# Use load balancer for facilitator
# Implement caching layer

Debug Mode

Enable verbose logging:

# Set log level
export TYK_GW_LOGLEVEL=debug

# Restart gateway
docker compose restart tyk-gateway

# Watch logs
docker compose logs -f tyk-gateway | grep x402

Performance

Benchmarks

Tested on: 2 CPU cores, 4GB RAM

Metric Value
Verification latency ~150ms
Settlement latency ~2s (async)
Throughput 500 req/s
Memory overhead ~50MB

Optimization Tips

  1. Use connection pooling for facilitator
  2. Cache payment validations (short TTL)
  3. Use dedicated facilitator instance
  4. Monitor and tune timeouts
  5. Use CDN for static content

Security

Best Practices

  • ✅ Always use HTTPS in production
  • ✅ Validate payment amounts match requirements
  • ✅ Check recipient address matches your wallet
  • ✅ Use nonces to prevent replay attacks
  • ✅ Set reasonable timeouts
  • ✅ Monitor for suspicious patterns
  • ✅ Keep middleware updated

Threat Model

  • Replay attacks: Mitigated by tracking transaction signatures
  • Amount manipulation: Validated against on-chain data
  • Recipient swapping: Verified by facilitator
  • DoS via invalid payments: Rate limiting recommended

Roadmap

  • Payment caching layer
  • Multiple blockchain support (Ethereum, Bitcoin Lightning)
  • WebSocket support for streaming APIs
  • Built-in rate limiting
  • Payment analytics dashboard
  • Automatic refunds on upstream failures

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Submit a pull request

License

MIT License - see LICENSE for details

Support

Related Projects

Acknowledgments

Built with:


Made with ❤️ for micropayment-powered APIs

All SDKs & Clients SDKs →