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

@com-kotobalabs/x402

v0.1.0

Published

x402 client: read the 402, pay, retry. Holds no key — the signer is injected.

Readme

x402-sdk

x402 clients for AI agents: read the 402, pay, retry. One wire contract, one library per language, no key ever held here.

x402 is HTTP's own payment step: ask for a resource, get 402 with the terms, pay, ask again with the proof. It is small enough that an SDK's job is not to hide it but to get the four details right that are easy to get wrong.

| package | install | tests | |---|---|---| | packages/go | go get github.com/kotoba-lang/x402-sdk/packages/go | go test ./... — 12 | | packages/typescript — @com-kotobalabs/x402 | npm i @com-kotobalabs/x402 | | npm test — 13 | | packages/python — com-kotobalabs-x402 | pip install com-kotobalabs-x402 once published | | python -m unittest discover -s tests — 16 | | packages/rust — com-kotobalabs-x402 | cargo add com-kotobalabs-x402 once published | cargo test — 11 |

Published under the com-kotobalabs organisation. x402-sdk, x402 and x402-client were already taken across crates.io, npm and PyPI — checked before publishing rather than after a rejected upload — and the reverse-DNS form says whose it is, which is more useful than a generic name anyway. npm carries it as a scope; PyPI and crates.io have none, so they carry it as a prefix.

Go and Rust install by name today. Go modules are fetched from the repository, so a tag publishes them; npm and PyPI need a token created through a web login, and saying npm i works before anyone has pushed would be a claim about a registry rather than about this code.

The contract both implement is spec/wire.md, transcribed from the facilitator that actually runs rather than from a document it might have drifted from.

The safe first call

from x402_sdk import challenge
c = challenge("https://x402.nexus/gateway/hanmoto/x402/counts")
import { challenge } from "@com-kotobalabs/x402";
const c = await challenge("https://x402.nexus/gateway/hanmoto/x402/counts");

No key, no payment, no side effect. c.accepts states every acceptable payment completely — price, token, network, recipient, and the EIP-712 domain to sign under.

import x402 "github.com/kotoba-lang/x402-sdk/packages/go"
c, _ := (&x402.Client{}).Challenge("https://x402.nexus/gateway/hanmoto/x402/counts")

Paying

const res = await fetchWithPayment(url, undefined, {
  policy: { networks: ["base-sepolia"],
            assets: ["0x036CbD53842c5426634e7929541eC2318f3dCF7e"],
            maxAmount: "5000" },
  signer,                       // yours. See below.
});

You do not need ETH. The exact scheme has the facilitator submit the authorization and pay the gas, so a buyer holding only USDC can pay.

Four things these libraries insist on

The signer is injected (and in Rust, the HTTP transport too). These packages hold no key, sign nothing, and have no cryptography dependency. Your wallet stays wherever you put it — viem, ethers, eth-account, a hardware device, a remote signer. A payment library that wants your key is a place your key can leak from.

A policy is required. selectOffer with no policy refuses with no-policy rather than paying. There is no default ceiling, because a default ceiling is a limit nobody chose.

The cheapest allowed offer wins, never the first. Sellers list the same resource on mainnet and on a testnet in their own order. Taking accepts[0] is how a buyer pays real money to rehearse.

The EIP-712 domain comes from the offer. Base mainnet USDC calls itself USD Coin; Base Sepolia USDC calls itself USDC. Signing under the wrong one produces a signature that recovers a different address, and the payment is rejected as a bad signature — which reads like your fault. These libraries refuse an offer that carries no domain rather than guessing one, and they refuse an unknown network rather than defaulting its chain id.

Refusals are named

Every refusal says which check failed, and all of them, not just the first: an offer on the wrong network usually names that network's token too, and a caller told only network-not-allowed will fix the network and be refused again.

no-policy · scheme-not-allowed · network-not-allowed · asset-not-allowed
over-budget · unparseable-amount · not-a-challenge · no-offers

What they do not do

They do not settle, do not hold funds, and do not implement the transaction scheme's transfer — an offer asking for it is refused by name. They are the protocol, not the wallet.

Measured against a live facilitator

challenge: parsed | offers: 2
  testnet         -> base-sepolia 1000 units domain=USDC/2     chainId=84532
  mainnet-only    -> base         1000 units domain=USD Coin/2 chainId=8453
  1-unit ceiling  REFUSED asset-not-allowed+network-not-allowed+over-budget
catalog: 25 SKUs

MIT.