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

x402station-middleware

v0.1.0

Published

Drop-in fetch wrapper that calls x402station.io /preflight before every paid x402 request and refuses ok=false. One-line auto-shielding for any agent that already wraps fetch with @x402/fetch.

Readme

x402station-middleware

Drop-in fetch wrapper that calls x402station.io /preflight before every paid x402 request your agent makes, and refuses (throws) when the endpoint is flagged dangerous.

If your agent already wraps fetch with @x402/fetch, this is one line of code:

import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
import { wrapWithPreflight } from "x402station-middleware";

const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);

const x402Fetch = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
});

// One-line shielding: preflight runs automatically before every call.
// Second arg is options (all optional); the wallet binding lives inside
// `x402Fetch`, the middleware itself doesn't need an account.
const safeFetch = wrapWithPreflight(x402Fetch);

// Use exactly like fetch.
const r = await safeFetch("https://api.example.com/x402-endpoint", {
  method: "POST",
  body: JSON.stringify({ ... }),
});
// ↑ throws PreflightBlockedError if the endpoint is decoy / zombie / dead.

Why

x402 lets agents pay HTTP endpoints, but the network has shape problems:

  • ~161 endpoints listed at ≥ $1000 USDC (decoy / honeypot — most are anti-scraper "swarm" routes)
  • ~10 services 100 % erroring in the last hour but still listed (zombies)
  • Catalog concentration (one provider can be > 40 % of the catalog)

x402station independently probes every endpoint on agentic.market every 10 minutes and flags these. This middleware makes those signals automatic — your agent code doesn't have to remember to preflight, the wrapper does it.

Install

npm install x402station-middleware
# or
pnpm add x402station-middleware
# or
bun add x402station-middleware

Peer deps (must already be installed in your agent project): @x402/fetch, @x402/evm, viem.

API

wrapWithPreflight(paidFetch, options?)

Returns a fetch-shaped function that calls /api/v1/preflight on every URL before forwarding.

| Option | Type | Default | Description | |---|---|---|---| | refuseOn | string[] | ["dead", "zombie", "decoy_price_extreme"] | Warnings that cause refusal. Pass [] to disable refusal (preflight still runs, but pass-through). | | cacheTtlMs | number | 300_000 (5 min) | Per-URL preflight cache. Matches x402station's internal probe cadence (10 min) — same window, identical data. Set 0 to disable. | | creditId | string (uuid) | — | Bulk-credit id from POST /api/v1/credits ($0.50 = 1000 prepaid preflights). When set, preflight calls go via X-Credit-Id header instead of paying $0.001 each → effective $0.0005/preflight. | | failOpen | boolean | false | Forward the request when preflight itself fails (network / 503 / timeout). Default fail-closed. | | preflightTimeoutMs | number | 10_000 | Per-call preflight timeout. Clamped to [1_000, 30_000]. | | baseUrl | string | https://x402station.io | Override (testing). Only canonical x402station.io or localhost / 127.0.0.1 / [::1] accepted; any other host throws at wrap time. |

Error classes

import { PreflightBlockedError, PreflightUnavailableError } from "x402station-middleware";

try {
  await safeFetch(url);
} catch (e) {
  if (e instanceof PreflightBlockedError) {
    console.log("blocked:", e.warnings, e.metadata);
    // → e.warnings: ["zombie", "decoy_price_extreme", ...]
    // → e.metadata: { url, service, provider, price_usdc, ... }
  }
  if (e instanceof PreflightUnavailableError) {
    console.log("preflight down:", e.cause);
  }
}

Cost

  • Per call: $0.001 USDC (the standard x402station preflight tier).
  • With creditId: $0.0005 USDC effective ($0.50 / 1000 calls). Buy via POST /api/v1/credits.
  • Cached calls: free.

For an agent making 100 paid x402 calls per day, that's ~$0.10/day in preflights, often offset by the very first decoy you avoid (a single $1000 honeypot would have wiped your wallet).

Networks

Base mainnet (eip155:8453) — the network x402 lives on. Base Sepolia (eip155:84532) for testing. The wallet you pass into wrapFetchWithPaymentFromConfig must hold USDC; preflight settles the same way every other paid x402 call does.

Caveats / design choices

  1. Default fail-closed. If preflight is unreachable (network blip, 503, timeout), the call throws PreflightUnavailableError. Override with failOpen: true only if availability matters more than safety.
  2. Refusal is on warnings, not just ok. We throw if any warning in refuseOn is in the response, OR if the server flipped ok to false. This is intentional belt-and-suspenders — keeps you safe even if the server's ok calculation changes.
  3. Self-requests skip. Calls TO x402station.io itself (preflight, forensics, credits, etc.) are forwarded directly without recursing.
  4. Cache is per-instance. Re-instantiating wrapWithPreflight gives you a fresh cache. There's no global cache; if you want one, share the wrapped fetch.
  5. Bearer-token allow-list on baseUrl. Only https://x402station.io or local-dev hosts pass. Mirrors the canonical-host check in x402station-mcp — a misconfigured agent can't be tricked into routing preflight payments off-target. CodeRabbit findings (mastra-ai/mastra#15804).

Companion

Same family as the official MCP adapter x402station-mcp, the AgentKit x402station action provider, the @lucid-agents/x402station client, and the upcoming standalone Mastra package. All share signals + canonical host allow-list + Greptile/CodeRabbit security fixes.

License

MIT.