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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fastxyz/x402-server

v1.0.1

Published

Server SDK for the x402 HTTP Payment Protocol — Express middleware for paywall and payment verification

Readme

@fastxyz/x402-server

Server SDK for the x402 HTTP Payment Protocol. Protect API routes with payment requirements using Express middleware.

Use Cases

  • Protect API routes with payment requirements (HTTP 402)
  • Add payment middleware to an Express app
  • Create payment requirements for specific routes
  • Verify or settle payments via a facilitator

Out of scope: Paying for 402-protected content → @fastxyz/x402-client · Running a facilitator service → @fastxyz/x402-facilitator

Installation

pnpm add @fastxyz/x402-server

Quick Start

Protect a Single Route with paywall

Use paywall to protect a single route with one price and network config:

import express from 'express';
import { paywall } from '@fastxyz/x402-server';

const app = express();

app.use(
  paywall(
    { fast: 'fast1merchant...' },
    {
      price: '$0.10',
      network: 'fast-testnet',
      networkConfig: {
        asset: '0x...',
        decimals: 6,
      },
    },
    { url: 'https://facilitator.example.com' }, // facilitator endpoint
  ),
);

app.get('/premium', (req, res) => {
  res.json({ content: 'exclusive data' });
});

app.listen(3000);

Protect Multiple Routes with paymentMiddleware

Use paymentMiddleware to define different price configs per route:

import express from 'express';
import { paymentMiddleware } from '@fastxyz/x402-server';

const app = express();

app.use(
  paymentMiddleware(
    { evm: '0x123...' }, // payTo: EVM address for all payments
    {
      // RoutesConfig: pattern → RouteConfig
      '/basic': {
        price: '$0.01',
        network: 'arbitrum-sepolia',
        // NOTE: In production, use environment variables or a config service for asset addresses
        networkConfig: { asset: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d', decimals: 6 },
      },
      '/premium': {
        price: '$0.10',
        network: 'arbitrum-sepolia',
        // NOTE: In production, use environment variables or a config service for asset addresses
        networkConfig: { asset: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d', decimals: 6 },
        config: { description: 'Premium tier content' },
      },
    },
    { url: 'https://facilitator.example.com' },
  ),
);

app.get('/basic', (req, res) => res.json({ tier: 'basic' }));
app.get('/premium', (req, res) => res.json({ tier: 'premium' }));

app.listen(3000);

Payment Flow

Client                    Server                    Facilitator
  │                         │                           │
  ├── GET /premium ────────►│                           │
  │◄── 402 + PaymentReq ───┤                           │
  │                         │                           │
  ├── GET /premium ────────►│                           │
  │   (X-PAYMENT header)    ├── POST /verify ──────────►│
  │                         │◄── { isValid: true } ─────┤
  │                         │                           │
  │◄── 200 + content ──────┤                           │
  │                         ├── POST /settle ──────────►│
  │                         │◄── { success: true } ─────┤

API

paywall(payTo, config, facilitator, options?)

Express middleware that protects all requests matched at the mount point with a single payment requirement.

Parameters:

| Param | Type | Description | | ------------- | ------------------- | --------------------------------------- | | payTo | PayToConfig | Recipient address config | | config | RouteConfig | Payment config for the mounted route(s) | | facilitator | FacilitatorConfig | Facilitator endpoint ({ url }) | | options | MiddlewareOptions | Optional middleware config |

paymentMiddleware(payTo, routes, facilitator, options?)

Express middleware for multiple route patterns.

RouteConfig

interface RouteConfig {
  price: string; // "$0.10", "0.1 USDC"
  network: string; // "fast-testnet", "arbitrum-sepolia"
  networkConfig: NetworkConfig;
  config?: {
    description?: string;
    mimeType?: string;
    asset?: string; // Override networkConfig.asset
  };
}

interface NetworkConfig {
  asset: string; // USDC contract/token address
  decimals: number; // Token decimals (typically 6)
  extra?: Record<string, unknown>;
}

FacilitatorConfig

interface FacilitatorConfig {
  /** Facilitator URL (e.g., "http://localhost:3002") */
  url: string;
  /** Optional factory for auth headers on verify/settle calls to the facilitator */
  createAuthHeaders?: () => Promise<{
    verify?: Record<string, string>;
    settle?: Record<string, string>;
  }>;
}

Low-Level Functions

  • createPaymentRequirement(payTo, routeConfig, resource) — create a PaymentRequirement
  • createPaymentRequired(payTo, routeConfig, resource) — format a 402 response body
  • verifyPayment(payload, requirement, facilitator) — verify via facilitator
  • settlePayment(payload, requirement, facilitator) — settle via facilitator
  • verifyAndSettle(payload, requirement, facilitator) — verify then settle

Re-exported Express Types

The middleware module re-exports minimal Express-compatible types for use in type annotations:

import type { Request, Response, NextFunction } from '@fastxyz/x402-server';

These are framework-compatible (Express, Koa, etc.) as long as they follow the same method, path, header(), status(), json(), setHeader() signature.

Common Pitfalls

  1. DO NOT omit networkConfig in RouteConfig — there are no hardcoded network defaults.
  2. DO NOT forget the facilitator.url — the server needs a facilitator endpoint to verify/settle payments.
  3. DO NOT use raw token amounts in price — use human-readable formats like "$0.10" or "0.1 USDC".
  4. DO NOT hardcode asset addresses across environments — pass them via networkConfig per route.

Design

  • No hardcoded network configs — all asset info provided via RouteConfig.networkConfig
  • Facilitator-agnostic — pass any facilitator URL; no embedded chain logic
  • Framework-compatible — works with Express and compatible frameworks (req/res/next signature)