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

@x402-solana/server

v0.2.1

Published

Server-side framework integrations for x402 payment verification on Solana

Readme

@x402-solana/server

Server-side framework integrations for x402 payment verification on Solana.

npm version License: MIT x402

Overview

@x402-solana/server makes it trivial to add USDC micropayments to any HTTP API on Solana. Add one line of middleware and your endpoints instantly support the official x402 payment protocol.

Turn any endpoint into a paid API in under 5 lines of code.

🏆 x402 v1 Compliant: Supports Express, NestJS, and Fastify with full x402 protocol compliance. See X402_COMPLIANCE.md for details.

Installation

npm install @x402-solana/server @solana/web3.js

Quick Start

Express

import express from 'express';
import { X402Middleware } from '@x402-solana/server';

const app = express();
const x402 = new X402Middleware({
  solanaRpcUrl: 'https://api.devnet.solana.com',
  recipientWallet: 'YOUR_WALLET_ADDRESS',
  network: 'devnet',
});

// Free endpoint
app.get('/api/data', (req, res) => {
  res.json({ data: 'This is free!' });
});

// Paid endpoint - just add one line!
app.get('/api/premium',
  x402.requirePayment(0.01),  // $0.01 USDC
  (req, res) => {
    res.json({
      data: 'Premium data!',
      paidBy: req.payment?.payer,
      amount: req.payment?.amount,
    });
  }
);

app.listen(3000);

Features

  • Framework Support - Express, NestJS, Fastify
  • One-Line Integration - Add payments with single middleware call
  • Automatic Verification - Validates USDC transfers on-chain
  • Replay Protection - Prevents payment reuse
  • Webhook System - Async payment notifications with retry logic (NEW in v0.2.1)
  • TypeScript - Fully typed with excellent DX
  • Redis Support - Scales across multiple servers
  • Dynamic Pricing - Set different prices per endpoint
  • Error Handling - Clear 402 responses for clients

Framework Integration

Express

import { X402Middleware } from '@x402-solana/server';

const x402 = new X402Middleware({
  solanaRpcUrl: process.env.SOLANA_RPC_URL!,
  recipientWallet: process.env.RECIPIENT_WALLET!,
  network: 'mainnet-beta',
});

// Single endpoint
app.get('/api/data', x402.requirePayment(0.01), handler);

// Multiple endpoints
app.use('/api/premium', x402.requirePayment(0.05));
app.get('/api/premium/analytics', analyticsHandler);
app.post('/api/premium/execute', executeHandler);

NestJS

import { X402Guard, X402Module, X402Payment } from '@x402-solana/server/nestjs';

@Module({
  imports: [
    X402Module.forRoot({
      solanaRpcUrl: process.env.SOLANA_RPC_URL!,
      recipientWallet: process.env.RECIPIENT_WALLET!,
      network: 'mainnet-beta',
    }),
  ],
})
export class AppModule {}

@Controller('api')
export class ApiController {
  @Get('premium')
  @UseGuards(X402Guard)
  @X402Payment(0.01)  // $0.01 USDC
  getPremiumData(@Request() req) {
    return {
      data: 'Premium data',
      payment: req.payment,
    };
  }
}

Fastify

import x402Plugin from '@x402-solana/server/fastify';

const fastify = Fastify();

await fastify.register(x402Plugin, {
  solanaRpcUrl: process.env.SOLANA_RPC_URL!,
  recipientWallet: process.env.RECIPIENT_WALLET!,
  network: 'mainnet-beta',
});

fastify.get('/api/premium', {
  x402: { priceUSD: 0.01 }
}, async (request, reply) => {
  return {
    data: 'Premium data',
    payment: request.payment,
  };
});

Configuration

Basic Configuration

const x402 = new X402Middleware({
  /** Solana RPC endpoint */
  solanaRpcUrl: string;
  
  /** Your wallet to receive payments */
  recipientWallet: string;
  
  /** Network: 'devnet' or 'mainnet-beta' */
  network: 'devnet' | 'mainnet-beta';
});

Advanced Configuration

const x402 = new X402Middleware({
  solanaRpcUrl: process.env.SOLANA_RPC_URL!,
  recipientWallet: process.env.RECIPIENT_WALLET!,
  network: 'mainnet-beta',
  
  /** Maximum transaction age (default: 5 minutes) */
  maxAgeMs: 300000,
  
  /** Transaction commitment level (default: 'confirmed') */
  commitment: 'finalized',
  
  /** Redis for replay protection across servers */
  cacheConfig: {
    redisUrl: process.env.REDIS_URL!,
    keyPrefix: 'x402:',
    ttlSeconds: 600,
  },
  
  /** Enable debug logging */
  debug: true,
});

Usage Patterns

Fixed Pricing

// Always costs $0.01
app.get('/api/search', x402.requirePayment(0.01), handler);

Dynamic Pricing

// Price varies based on request
app.post('/api/execute', async (req, res, next) => {
  const betAmount = req.body.betAmount;
  const price = 0.10 + (betAmount * 0.02); // $0.10 + 2%
  
  await x402.requirePayment(price)(req, res, next);
}, executeHandler);

Tiered Pricing

app.get('/api/basic', x402.requirePayment(0.001), basicHandler);
app.get('/api/standard', x402.requirePayment(0.01), standardHandler);
app.get('/api/premium', x402.requirePayment(0.10), premiumHandler);

Free + Paid Mix

// Free public endpoint
app.get('/api/markets', (req, res) => {
  res.json({ markets: getAllMarkets() });
});

// Paid analysis endpoint
app.post('/api/analyze', x402.requirePayment(0.05), (req, res) => {
  res.json({ analysis: analyzeMarket(req.body.marketId) });
});

Payment Information

Access payment details in your handlers:

app.get('/api/data', x402.requirePayment(0.01), (req, res) => {
  console.log('Payment verified!');
  console.log('Signature:', req.payment.signature);
  console.log('Payer:', req.payment.payer);
  console.log('Amount:', req.payment.amount, 'USDC');
  console.log('Timestamp:', new Date(req.payment.timestamp * 1000));
  
  res.json({ data: 'your data' });
});

Error Handling

402 Response Format

When payment is required or invalid:

{
  "error": "Payment Required",
  "paymentDetails": {
    "amount": 0.01,
    "currency": "USDC",
    "network": "solana",
    "recipient": "YourUSDCTokenAccount...",
    "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
  }
}

Custom Error Messages

app.get('/api/premium',
  x402.requirePayment(0.01, {
    errorMessage: 'Premium content requires $0.01 USDC payment',
    resource: '/api/premium',
    description: 'Access to premium analytics',
  }),
  handler
);

Redis Setup (Production)

For multi-instance deployments, use Redis to prevent replay attacks:

import Redis from 'ioredis';

const x402 = new X402Middleware({
  solanaRpcUrl: process.env.SOLANA_RPC_URL!,
  recipientWallet: process.env.RECIPIENT_WALLET!,
  network: 'mainnet-beta',
  cacheConfig: {
    redisUrl: process.env.REDIS_URL!,
    keyPrefix: 'x402:',
    ttlSeconds: 600,  // Cache signatures for 10 minutes
  },
});

Wallet Setup

Get Your Recipient Wallet

# Your main wallet address
RECIPIENT_WALLET=YourWalletPublicKey...

# The middleware automatically derives your USDC token account
# Payments go to: deriveUSDCTokenAccount(RECIPIENT_WALLET)

Check Payment Revenue

import { Connection, PublicKey } from '@solana/web3.js';
import { getAssociatedTokenAddressSync } from '@solana/spl-token';

const connection = new Connection(process.env.SOLANA_RPC_URL!);
const wallet = new PublicKey(process.env.RECIPIENT_WALLET!);
const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');

const usdcAccount = getAssociatedTokenAddressSync(usdcMint, wallet);
const balance = await connection.getTokenAccountBalance(usdcAccount);

console.log(`Revenue: ${balance.value.uiAmount} USDC`);

Examples

Weather API with Tiered Pricing

const app = express();
const x402 = new X402Middleware({ ... });

// FREE: Current weather
app.get('/api/weather/current', (req, res) => {
  res.json(getCurrentWeather(req.query.city));
});

// $0.001: 7-day forecast
app.get('/api/weather/forecast',
  x402.requirePayment(0.001),
  (req, res) => {
    res.json(get7DayForecast(req.query.city));
  }
);

// $0.01: Historical data
app.get('/api/weather/historical',
  x402.requirePayment(0.01),
  (req, res) => {
    res.json(getHistoricalData(req.query.city, req.query.date));
  }
);

AI API with Dynamic Pricing

app.post('/api/analyze',
  async (req, res, next) => {
    const complexity = estimateComplexity(req.body.query);
    const price = 0.01 * complexity; // Scale with complexity
    
    await x402.requirePayment(price)(req, res, next);
  },
  async (req, res) => {
    const result = await runAIAnalysis(req.body.query);
    res.json(result);
  }
);

Monitoring & Logging

const x402 = new X402Middleware({
  solanaRpcUrl: process.env.SOLANA_RPC_URL!,
  recipientWallet: process.env.RECIPIENT_WALLET!,
  network: 'mainnet-beta',
  debug: true,  // Enable debug logging
});

// Log all successful payments
app.use((req, res, next) => {
  if (req.payment) {
    console.log(`💰 Payment received: ${req.payment.amount} USDC from ${req.payment.payer}`);
  }
  next();
});

Testing

Development/Testing Mode

// Use devnet for testing
const x402 = new X402Middleware({
  solanaRpcUrl: 'https://api.devnet.solana.com',
  recipientWallet: process.env.TEST_WALLET!,
  network: 'devnet',
  debug: true,
});

Integration Tests

import request from 'supertest';
import { X402Client } from '@x402-solana/client';

const client = new X402Client({
  solanaRpcUrl: 'https://api.devnet.solana.com',
  walletPrivateKey: process.env.TEST_PRIVATE_KEY!,
  network: 'devnet',
});

// Test paid endpoint
const response = await client.fetch('http://localhost:3000/api/premium');
expect(response.ok).toBe(true);

Webhooks (NEW in v0.2.1)

Get notified asynchronously when payments are confirmed, making your API 8-16x faster!

Why Webhooks?

Before (Synchronous):

Client → Server → Wait 400-800ms for blockchain → Response

After (Async with Webhooks):

Client → Server → 202 Accepted (<50ms)
        ↓
Server → Verify async → Webhook fires → Client gets notification

Quick Start

import { requirePayment } from '@x402-solana/server';

app.post('/api/data',
  requirePayment(0.001, {
    webhookUrl: 'https://my-app.com/hooks/payment',
    webhookSecret: process.env.WEBHOOK_SECRET,
    webhookRetry: {
      maxAttempts: 3,
      backoff: 'exponential'
    }
  }),
  handler
);

Webhook Payload

{
  "event": "payment.confirmed",
  "payment": {
    "signature": "5xyz...abc",
    "amount": 1000,
    "payer": "9xQe...7yL",
    "timestamp": 1699564800000,
    "resource": "/api/data"
  },
  "signature": "hmac-sha256..." // For verification
}

Receiving Webhooks

import { createWebhookReceiverEndpoint } from '@x402-solana/server';

app.post('/webhooks/payment',
  createWebhookReceiverEndpoint(
    process.env.WEBHOOK_SECRET,
    (payload) => {
      console.log('Payment confirmed:', payload);
      // Send data to client, update database, etc.
    }
  )
);

Features

  • HMAC-SHA256 Signatures - Cryptographically secure
  • Exponential Backoff - Retry failed deliveries (100ms → 200ms → 400ms)
  • Redis Support - Production-grade queue
  • Delivery Tracking - Logs and metrics
  • Mock Server - Testing utilities included

📚 Full Webhook Documentation

Related Packages

Documentation

License

MIT © 2025