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

@alghanima/x402-lint

v0.1.1

Published

Checks an x402 seller's own payment-required (402) response against the REAL client-side schema from @x402/core, catching the exact class of bug where a response looks fine to its own author but silently fails every real buyer's own validation (found live

Readme

x402-lint

Checks whether an x402 seller's payment-required response will actually be accepted by a real buyer, before a real buyer finds out the hard way.

It exists because of a bug we shipped ourselves. On 2026-10-22 our own capacity-attest server answered every payment-required request with a perfectly normal-looking JSON object — and every real x402 client silently refused to pay, with no error surfaced anywhere. The cause: @x402/core's own client-side schema caps resource.serviceName at 32 characters, and two of our tools declared a 53- and a 71-character name. The response passed every manual look at it. It failed the one check that actually mattered: the real buyer library's own parsePaymentRequired().

x402-lint runs that exact, real schema — imported directly from @x402/core, never reimplemented by hand — against a seller's own response, so that thirty-second check catches what an hour of "why isn't the payment going through" debugging otherwise finds.

Use it from the terminal

npx @alghanima/x402-lint https://your-service.example/some-route
npx @alghanima/x402-lint https://your-service.example/mcp --tool your_paid_tool_name

(installs a check-x402 command — npm install -g @alghanima/x402-lint then run check-x402 <url> directly)

OK  https://capacity-attest.tokenizen.nl/mcp  (mcp transport, HTTP 200)
schema: valid against @x402/core's PaymentRequiredSchema
  no issues found

Add --json for the full machine-readable report, --args '{"...":"..."}' to send specific arguments with the MCP probe. Exit code is 0 for ok, 1 for a failed check, 2 for a usage error — safe to drop straight into CI.

Use it as an MCP tool

A free, public, read-only check_x402_conformance tool is hosted at https://x402-lint.tokenizen.nl/mcp (StreamableHTTPClientTransport). No payment, no API key. Point any MCP client at it directly, or run the same server yourself:

npm install
npm run build
npm run start:http

Two transports, because our own bug lived in the second one

Plain x402 (one URL, one priced action): send a bare request, the 402 status itself is the payment-required signal, and the response body is the PaymentRequired object directly. Just pass the URL.

MCP (one URL serves several named paid tools, e.g. anything built with @x402/mcp's createPaymentWrapper — this is exactly where both of our own serviceName bugs lived): the HTTP layer answers 200 either way, and the payment-required object is nested inside a JSON-RPC tool result's content[0].text, only visible when isError:true. An MCP endpoint cannot answer "what does this cost" without being told which tool you mean, so --tool/mcpToolName is required to get any signal from one at all.

What it checks

  • Where it reads the requirements from — the Payment-Required header first, then the body. An x402 v2 seller keeps its requirements in that header and often answers with a body of {}; the report says which one it used (source).
  • Schema validity — the real, unmodified parsePaymentRequired() from @x402/core. If this fails, no spec-compliant client will ever pay, regardless of how reasonable the response looks.
  • Address shape (warning, not a schema violation) — accepts[].asset and accepts[].payTo should look like a real 0x-prefixed 20-byte address.
  • Resource URL match (warning) — a v2 response's resource.url should match the URL actually tested, or a careful client may refuse it as resource-mismatched.

Erratum (found 2026-10-24)

Up to and including 0.1.0 this tool read only the response body. Measured against our own live paid route, which is a v2 seller with its requirements in the header and a body of {}, it reported x402Version: Invalid discriminator value: a working endpoint called broken. The hosted tool at x402-lint.tokenizen.nl did the same until it was updated. If you were told your v2 endpoint failed the schema by an earlier version, run it again; a result that names the body as its source was not affected. Fixed in 0.1.1, with tests that fail on the old code.

Honest limits

This only sees the HTTP/MCP-level response. It cannot see whether the seller's own signer can actually broadcast once a real payment settles — that was the other bug we found the same night: a signer built with no provider attached, which only throws once a real payment has already been taken. No anonymous, read-only check can see that from the outside without spending real money against someone else's live endpoint, which this tool deliberately never does.

Every outbound request this tool makes goes through tokenizen-net-guard's guardedFetch, because resourceUrl is, by design, whatever the caller gives it — the same SSRF threat model net-guard was already built for.

MIT licensed. Part of the tokenizen monorepo.