npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

solana402-express

v0.1.0

Published

Express middleware for pay-per-request APIs using Solana payments

Downloads

99

Readme

@555x402/solana402-express

Express middleware for pay-per-request APIs using Solana payments

npm version License: MIT

Overview

Turn any Express API into a paid API with one line of code. Users pay in USDC/SOL per request—no subscriptions, no accounts, instant settlement.

Based on the x402 protocol (HTTP 402 "Payment Required") adapted for Solana.

Features

  • One-Line Integration: Add middleware, done
  • Pay-Per-Request: Charge per API call, not monthly subscriptions
  • Instant Settlement: Funds arrive in ~2 seconds
  • Low Fees: 0.5-1% + minimal gas
  • No User Accounts: Anonymous payments via Solana wallets
  • Username Support: Accept payments to @username or wallet address
  • Automatic Verification: Middleware handles all crypto complexity
  • TypeScript: Full type safety

Installation

npm install @555x402/solana402-express @solana/web3.js

Quick Start

Basic Usage

import express from 'express';
import { solana402Middleware } from '@555x402/solana402-express';
import { PublicKey } from '@solana/web3.js';

const app = express();

// Protect specific routes
app.use('/api/premium', solana402Middleware({
  apiKey: process.env.AGG_API_KEY!,
  recipientAddress: 'your_wallet_or_@username',
  endpoints: {
    'GET /api/premium/data': { 
      price: '0.10',  // $0.10 per request
      mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
    },
    'POST /api/premium/generate': { 
      price: '0.50' 
    }
  }
}));

// Your protected endpoints
app.get('/api/premium/data', (req, res) => {
  // Payment already verified by middleware
  res.json({ data: 'premium content' });
});

app.post('/api/premium/generate', (req, res) => {
  // Payment verified
  const result = expensiveComputation();
  res.json(result);
});

app.listen(3000);

With Route-Specific Pricing

app.use(solana402Middleware({
  apiKey: API_KEY,
  recipientAddress: TREASURY,
  endpoints: {
    'GET /api/basic': { price: '0.01' },        // $0.01
    'GET /api/premium': { price: '0.10' },      // $0.10
    'POST /api/ai/generate': { price: '1.00' }, // $1.00
    'GET /api/data/realtime': { 
      price: '0.05',
      mint: 'So11111111111111111111111111111111111111112' // SOL
    }
  }
}));

API Reference

solana402Middleware(options): RequestHandler

Express middleware that enforces payment for API access.

Options:

interface Solana402Options {
  apiKey: string;                    // 555x402 AGG API key
  apiBase?: string;                  // API base URL (optional)
  recipientAddress: string;          // Your wallet or @username
  endpoints: Record<string, EndpointConfig>;
}

interface EndpointConfig {
  price: string;                     // USD amount as string
  mint?: string;                     // Token mint (defaults to USDC)
}

Behavior:

  1. If request has valid X-Payment header → verify and proceed
  2. If no header → return 402 Payment Required with price info
  3. If invalid payment → return 402 with error

Response Format (402):

{
  "error": "X-Payment required",
  "price": {
    "amount": "0.10",
    "asset": "USDC"
  },
  "recipient": "555Tm1cfV52SrBQmnxXiHMUMrpci8miW3CkLP1Qbmtd7"
}

Examples

1. AI API with Token-Based Pricing

import express from 'express';
import { solana402Middleware } from '@555x402/solana402-express';

const app = express();
app.use(express.json());

// Different prices for different AI models
app.use('/api/ai', solana402Middleware({
  apiKey: process.env.AGG_API_KEY!,
  recipientAddress: process.env.TREASURY_WALLET!,
  endpoints: {
    'POST /api/ai/gpt4': { price: '0.50' },      // $0.50 per request
    'POST /api/ai/claude': { price: '0.40' },    // $0.40 per request
    'POST /api/ai/llama': { price: '0.10' },     // $0.10 per request
  }
}));

app.post('/api/ai/gpt4', async (req, res) => {
  // Payment verified - call OpenAI
  const response = await openai.chat.completions.create({
    model: 'gpt-4',
    messages: req.body.messages
  });
  
  res.json(response);
});

app.post('/api/ai/claude', async (req, res) => {
  // Payment verified
  const response = await anthropic.messages.create(...);
  res.json(response);
});

2. Data API with Rate Limiting

import rateLimit from 'express-rate-limit';

// Free tier: 10 req/min
const freeLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 10
});

// Paid tier: no limit (enforced by payment)
app.get('/api/data/free', freeLimiter, (req, res) => {
  res.json({ data: 'basic data' });
});

app.get('/api/data/premium', 
  solana402Middleware({
    apiKey: API_KEY,
    recipientAddress: TREASURY,
    endpoints: {
      'GET /api/data/premium': { price: '0.05' }
    }
  }),
  (req, res) => {
    // No rate limit for paying users
    res.json({ data: 'premium real-time data' });
  }
);

3. Webhook Notifications

import { solana402Middleware } from '@555x402/solana402-express';

app.use('/api/webhooks', solana402Middleware({
  apiKey: API_KEY,
  recipientAddress: TREASURY,
  endpoints: {
    'POST /api/webhooks/register': { price: '0.01' }
  }
}));

app.post('/api/webhooks/register', (req, res) => {
  // User paid $0.01 to register webhook
  const { url, events } = req.body;
  
  // Store webhook configuration
  await db.webhooks.create({
    url,
    events,
    userId: req.payment.sender // Available after middleware
  });
  
  res.json({ status: 'registered' });
});

4. Username-Based Recipients

// Accept payments to username instead of wallet
app.use(solana402Middleware({
  apiKey: API_KEY,
  recipientAddress: '@your_username', // ← Resolved to wallet automatically
  endpoints: {
    'GET /api/data': { price: '0.10' }
  }
}));

Configuration

Environment Variables

# Required
AGG_API_KEY=pk_live_your_api_key

# Your recipient wallet or username
TREASURY_WALLET=your_solana_wallet
# or
TREASURY_USERNAME=@your_username

# Optional
AGG_API_BASE=https://agg.rendernet.work/pub/v1

USDC Mint Addresses

const USDC = {
  mainnet: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
  devnet: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'
};

// Use in endpoint config
endpoints: {
  'GET /api/data': { 
    price: '0.10',
    mint: USDC.mainnet 
  }
}

Advanced Usage

Custom Error Handling

app.use(solana402Middleware({
  apiKey: API_KEY,
  recipientAddress: TREASURY,
  endpoints: { ... },
  onPaymentError: (error, req, res) => {
    // Custom error response
    res.status(402).json({
      error: 'Payment failed',
      details: error.message,
      retryAfter: 5
    });
  }
}));

Access Payment Details

app.get('/api/data', (req, res) => {
  // Middleware adds payment info to request
  console.log('Paid by:', req.payment.sender);
  console.log('Amount:', req.payment.amount);
  console.log('Tx:', req.payment.txSignature);
  
  res.json({ data: '...' });
});

Dynamic Pricing

app.use((req, res, next) => {
  // Set price based on user tier, time of day, etc.
  req.customPrice = isPremiumUser(req) ? '0.05' : '0.10';
  next();
});

app.use(solana402Middleware({
  apiKey: API_KEY,
  recipientAddress: TREASURY,
  endpoints: {
    'GET /api/data': { 
      price: (req) => req.customPrice  // Dynamic pricing
    }
  }
}));

Client-Side Integration

Users make requests with the X-Payment header:

// Client-side (browser)
import { buildPaymentHeader } from '@555x402/client'; // Hypothetical client package

const paymentHeader = await buildPaymentHeader({
  amount: 0.10,
  recipient: 'recipient_wallet',
  wallet: userWallet
});

const response = await fetch('https://api.example.com/api/premium', {
  headers: {
    'X-Payment': paymentHeader
  }
});

if (response.status === 402) {
  const { price } = await response.json();
  console.log(`Payment required: $${price.amount}`);
} else {
  const data = await response.json();
  console.log('Success:', data);
}

Error Handling

app.use((err, req, res, next) => {
  if (err.name === 'PaymentError') {
    return res.status(402).json({
      error: err.message,
      code: err.code
    });
  }
  next(err);
});

Best Practices

1. Price Optimization

// Too cheap: not worth tx fees
❌ { price: '0.001' }  // $0.001 (less than minimal transaction fees)

// Good: covers fees + provides value
✅ { price: '0.01' }   // $0.01 (minimum recommended)
✅ { price: '0.10' }   // $0.10 (good for data APIs)
✅ { price: '1.00' }   // $1.00 (good for AI/compute)

2. Route Organization

// Group paid routes under /api/premium
app.use('/api/premium', solana402Middleware({...}));
app.use('/api/premium', premiumRouter);

// Keep free routes separate
app.use('/api/public', publicRouter);

3. Logging

app.use(solana402Middleware({
  apiKey: API_KEY,
  recipientAddress: TREASURY,
  endpoints: {...},
  onPaymentSuccess: (payment, req) => {
    logger.info('Payment received', {
      sender: payment.sender,
      amount: payment.amount,
      endpoint: req.path
    });
  }
}));

Troubleshooting

"Payment required" on every request

  • Ensure client is sending X-Payment header
  • Verify payment amount matches endpoint price
  • Check payment signature is valid

"Invalid API key"

  • Verify AGG_API_KEY is set correctly
  • Check you're using the right environment (test vs live)

Slow response times

  • Payment verification adds ~200ms latency
  • Cache verified payments if same user makes multiple requests
  • Consider webhooks for async settlement

Comparison with Traditional APIs

| Feature | Traditional Subscription | solana402-express | |---------|-------------------------|-------------------| | Setup Time | Days (Stripe integration, user accounts, billing) | Minutes (one middleware) | | User Onboarding | Sign up, card info, email verification | None (just wallet) | | Pricing Model | Monthly tiers | Pay-per-use | | Settlement Time | 7-30 days | 2 seconds | | Geographic Restrictions | Many (card processors) | None (crypto-native) | | Chargebacks | Yes (fraud risk) | No (instant finality) | | Privacy | Requires PII | Anonymous (wallet only) |

Changelog

v0.1.0 (2025-11-11)

  • Initial release
  • Express middleware
  • Route-based pricing
  • Username support

License

MIT © 555x402

Support

  • Docs: https://docs.rendernet.work/solana402-express
  • Issues: https://github.com/Render-Network-OS/555x402-solana-express/issues

Related


Monetize your API in 5 minutes