Skip to content

Latest commit

 

History

History
298 lines (222 loc) · 7.63 KB

File metadata and controls

298 lines (222 loc) · 7.63 KB

Server Application

Express backend for the Proxy Endpoints Demo, demonstrating how to protect API endpoints with AnySpend x402 payment requirements.

Overview

This server wraps third-party APIs (TAAPI.io for technical indicators, RapidAPI Twitter for social data) and protects them with x402 payment middleware. Clients must submit valid x402 payments to access these endpoints.

Features

  • x402 Payment Middleware: Automatic payment verification and settlement
  • TAAPI.io Integration: Technical indicators (RSI, MACD, EMA, Bollinger Bands, etc.)
  • Twitter Data Integration: Search and user profile data via RapidAPI
  • Balance Fetching: Multi-chain token balance queries via Sim Dune API
  • CORS Support: Configurable for frontend access
  • Caching: HTTP response caching for improved performance

Tech Stack

  • Express for HTTP server
  • @b3dotfun/anyspend-x402-express for payment middleware
  • Viem for Ethereum interactions
  • TypeScript with NodeNext module resolution

Setup

Prerequisites

  • Node.js 18+
  • pnpm (or npm/yarn)
  • TAAPI.io API key (get from https://taapi.io)
  • RapidAPI key with Twitter API access (get from https://rapidapi.com)
  • Optional: Sim Dune API key for balance queries

Environment Variables

Create .env file in apps/server:

# Server Configuration
NODE_ENV=development
PORT=4021

# AnySpend x402 Configuration
ANYSPEND_FACILITATOR_URL=https://mainnet.anyspend.com/x402
# Supported networks: base, polygon, arbitrum, bsc
ANYSPEND_NETWORK=base
ANYSPEND_RECEIVER_ADDRESS=0x93f6fdB246Da7204d2845230967725256493A0E5
ANYSPEND_PRICE_USD=$0.01

# Optional: Override network per service
# TAAPI_NETWORK=bsc
# TWITTER_NETWORK=base

# Optional: BSC-specific token configuration (Binance-Peg USDC uses 18 decimals)
# TAAPI_PRICE_ASSET=0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d
# TAAPI_PRICE_DECIMALS=18

# TAAPI.io Configuration
TAAPI_BASE_URL=https://api.taapi.io
TAAPI_SECRET_KEY=your_taapi_secret_key_here

# RapidAPI Twitter Configuration
RAPIDAPI_KEY=your_rapidapi_key_here
TWITTER_RAPIDAPI_HOST=twitter-v24.p.rapidapi.com
TWITTER_RAPIDAPI_SEARCH_PATH=/search
TWITTER_RAPIDAPI_PROFILE_PATH=/user/profile

# Balance API (Optional)
SIM_DUNE_API_KEY=your_sim_dune_api_key_here

Installation

From the monorepo root:

# Install dependencies
pnpm install

# Run server only
pnpm dev:server

# Or run all apps
pnpm dev:all

The server will be available at http://localhost:4021

File Structure

apps/server/
├── src/
│   ├── lib/
│   │   ├── cache.ts         # HTTP caching utilities
│   │   └── http.ts          # HTTP client with caching
│   ├── routes/
│   │   ├── index.ts         # Main router + balance endpoint
│   │   ├── taapi.ts         # TAAPI indicator endpoints
│   │   └── twitter.ts       # Twitter data endpoints
│   ├── server/
│   │   └── index.ts         # Express app setup + x402 middleware
│   ├── services/
│   │   ├── taapi.ts         # TAAPI.io client
│   │   └── twitter.ts       # RapidAPI Twitter client
│   └── types/               # TypeScript type definitions
├── dist/                    # Compiled output (gitignored)
└── package.json

API Endpoints

Balance Endpoint

GET /api/balances/:address

Returns token balances across multiple networks for the given address.

Response:

{
  "address": "0x...",
  "balances": [
    {
      "network": "base",
      "chainId": "8453",
      "tokens": [
        {
          "symbol": "USDC",
          "balance": "100.50",
          "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
        }
      ]
    }
  ]
}

TAAPI Endpoints (x402 Protected)

All TAAPI endpoints require x402 payment headers.

GET /api/taapi/rsi?symbol=BTC/USDT&exchange=binance&interval=1h
GET /api/taapi/macd?symbol=BTC/USDT&exchange=binance&interval=1h
GET /api/taapi/ema?symbol=BTC/USDT&exchange=binance&interval=1h&period=20
GET /api/taapi/bbands?symbol=BTC/USDT&exchange=binance&interval=1h
GET /api/taapi/adx?symbol=BTC/USDT&exchange=binance&interval=1h

Query Parameters:

  • symbol: Trading pair (e.g., BTC/USDT)
  • exchange: Exchange name (e.g., binance)
  • interval: Timeframe (e.g., 1h, 4h, 1d)
  • period: Indicator period (for EMA, etc.)

Twitter Endpoints (x402 Protected)

GET /api/twitter/search?query=bitcoin&count=10
GET /api/twitter/profile?username=elonmusk

Search Parameters:

  • query: Search term
  • count: Number of results (default: 10)

Profile Parameters:

  • username: Twitter username (without @)

x402 Integration

Payment Middleware Setup

import { anyspendX402Factory } from '@b3dotfun/anyspend-x402-express';

const anyspendX402 = anyspendX402Factory({
  facilitatorUrl: process.env.ANYSPEND_FACILITATOR_URL,
  receiverAddress: process.env.ANYSPEND_RECEIVER_ADDRESS,
  network: process.env.ANYSPEND_NETWORK,
  price: process.env.ANYSPEND_PRICE_USD,
});

// Apply to protected routes
app.use('/api/taapi', anyspendX402, taapiRouter);
app.use('/api/twitter', anyspendX402, twitterRouter);

How It Works

  1. Client makes request with x402 payment headers
  2. Middleware verifies payment with facilitator
  3. If valid, request proceeds to handler
  4. Payment is settled to ANYSPEND_RECEIVER_ADDRESS
  5. Response returned to client

Development

Scripts

# Development mode with auto-reload
pnpm dev

# Build for production
pnpm build

# Run production build
pnpm start

# Type checking
pnpm typecheck

# Lint code
pnpm lint

# Format code
pnpm format

Adding New Protected Endpoints

  1. Create service in src/services/ to wrap the external API
  2. Create route handler in src/routes/
  3. Apply anyspendX402 middleware to the router
  4. Register router in src/server/index.ts

Example:

// src/services/myapi.ts
export async function fetchData(params: any) {
  // External API call
}

// src/routes/myapi.ts
import { Router } from 'express';
import { fetchData } from '../services/myapi.js';

const router = Router();

router.get('/', async (req, res) => {
  const data = await fetchData(req.query);
  res.json(data);
});

export default router;

// src/server/index.ts
import myApiRouter from '../routes/myapi.js';
app.use('/api/myapi', anyspendX402, myApiRouter);

Caching

The server implements HTTP caching to reduce external API calls:

  • TAAPI responses: Cached based on symbol, interval, indicator
  • Twitter responses: Cached based on query/username
  • Cache entries automatically expire based on Cache-Control headers

Error Handling

The server returns standard HTTP error codes:

  • 400: Bad request (missing parameters)
  • 401: Payment required or invalid
  • 404: Resource not found
  • 500: Internal server error
  • 502: External API error

Troubleshooting

Issue: TAAPI endpoints returning 401 Solution: Check TAAPI_SECRET_KEY is valid and TAAPI account has credits

Issue: Twitter endpoints failing Solution: Verify RAPIDAPI_KEY has access to Twitter API v2

Issue: x402 payment verification failing Solution: Ensure ANYSPEND_FACILITATOR_URL is reachable and configured correctly

Issue: Balance endpoint returns empty Solution: Provide SIM_DUNE_API_KEY in environment variables

Security Considerations

  • Never expose API keys in responses or logs
  • Validate all input parameters before passing to external APIs
  • Rate limit endpoints in production (not included in demo)
  • Use HTTPS in production
  • Rotate API keys regularly

Related