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

x402-paycheck

v0.3.0

Published

Check every x402 payment with Lumière PayCheck before your agent pays: trust grade, price, payout-wallet hijack and OFAC checks, team spend limits enforced by the SDK, and agent credentials sellers can verify.

Readme

x402-paycheck

Check every x402 payment with Lumière PayCheck before your agent pays it. One line on top of the standard @x402/fetch client.

Before your agent signs a payment, PayCheck checks:

  • Trust grade: uptime, response time, price and payout-wallet stability, and real paid delivery tests across 38,000+ monitored x402 endpoints
  • Price: the quote isn't higher than the price PayCheck has been monitoring
  • Payout wallet: the wallet hasn't been swapped (a common sign of a hijacked endpoint)
  • Sanctions: the wallet isn't on the U.S. Treasury OFAC sanctions list
  • Real buyers (optional): with minOrganicShare, enough of the seller's volume comes from independent buyers, not wallets one operator created. We count customers, not wallets.

If PayCheck says no, the payment is never created.

Install

npm i x402-paycheck @x402/fetch

Use

import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { withPayCheck } from "x402-paycheck";

const client = withPayCheck(
  new x402Client().register("eip155:8453", new ExactEvmScheme(signer)),
);
const fetchWithPay = wrapFetchWithPayment(fetch, client);

const res = await fetchWithPay("https://api.example.com/paid-endpoint");

A blocked payment throws from fetchWithPay with the reason, for example:

Payment creation aborted: Lumière PayCheck: deny: payTo differs from the monitored payout wallet (possible hijack)

client.lastPayCheckDecision holds the most recent decision for logging.

Servers on the older x402 v1 format

v1 price quotes don't include the endpoint URL, so use the wrapper, which passes the request URL to PayCheck:

import { wrapFetchWithPayCheck } from "x402-paycheck";

const fetchWithPay = wrapFetchWithPayCheck(fetch, client, wrapFetchWithPayment);

Options

withPayCheck(client, {
  apiKey: "pc_free_...",        // free API key for a higher rate limit: lumierepaycheck.org/#free-key
  rules: { maxAmount: "50000", allowCaution: false, requireVerified: true },
  failOpen: false,           // if PayCheck can't be reached: block (default) or allow
  onDecision: (d) => console.log(d.outcome, d.reasons),
});

| Rule | Default | Meaning | |---|---|---| | maxAmount | none | Hard cap per payment, atomic units (USDC: 1000000 = $1) | | allowCaution | true | Allow "caution" endpoints. Caution includes healthy endpoints not yet paid-tested, so false limits payments to endpoints a real paid test confirmed | | requireVerified | false | Only pay endpoints that passed a real paid delivery test | | requireMonitored | true | Block endpoints PayCheck doesn't monitor | | pinPayTo | true | The payout wallet must match the monitored one | | allowUnconfirmedWallet | false | Allow a recent wallet change nobody could confirm | | minOrganicShare | off | Only pay sellers where at least this share (0-1) of 30-day volume comes from independent buyers |

Teams: spend limits and signed receipts

With a PayCheck plan, give each agent its own key. Payments then go through /v1/authorize: per-agent daily and monthly limits, allowed sellers, human review for unusual payments, a full audit trail, and a signed receipt for every allowed payment.

const client = withPayCheck(baseClient, { agentKey: process.env.PAYCHECK_AGENT_KEY });
// client.lastPayCheckDecision.receipt -> signed receipt for the allowed payment

A decision sent to human review counts as "not allowed" until someone approves it. To wait for the approval instead, pass reviewWaitMs (for example 120_000).

Enforced by the SDK

With an agent key, a payment PayCheck denies can't be signed, and the agent shows Enforced by SDK on your account page.

  • Fail closed: if PayCheck can't be reached (network error, 5xx, 429), the payment is blocked, except payments under the amount your workspace allows without a check (Policies → "If PayCheck can't be reached"; remembered from the last decision). failOpenUnder: "0" always blocks. A bad or revoked key never fails open.
  • Single-use receipts: wallet code that requires a receipt can call consumeReceipt(receipt); a receipt approves one payment, so a second use fails.
  • Re-quotes: if a seller asks for more after approval, the new amount is checked again before anything is signed.

Agent credentials (opt-in)

If your workspace's Owner turned on agent credentials, the agent can prove to sellers that it belongs to a verified company:

const fetchWithPay = wrapFetchWithPayCheck(fetch, client, wrapFetchWithPayment, { agentKey, agentCredential: true });
// each paid request carries an X-PayCheck-Agent header (15 minutes, bound to the agent's registered wallet)

Or get one yourself: await getAgentCredential("api.seller.example", { agentKey }).

For sellers: recognize PayCheck-verified agents

import { verifyAgentCredential } from "x402-paycheck";

const v = await verifyAgentCredential(req.headers["x-paycheck-agent"], { audience: "api.yourservice.com", payer: paidFromWallet });
if (v.valid) {
  // v.level: "workspace" | "domain" | "business"; v.org (named credentials): { name, domains }; v.agent: an ID only you see
}

It checks the Ed25519 signature against PayCheck's published keys (/.well-known/jwks.json), the expiry, that it was issued for your host, that the wallet that paid you is the agent's, and (unless online: false) that the company hasn't turned credentials off. Free, no account needed.

Sellers that need their own sign-in

Some endpoints need the seller's own account, API key or wallet signature on top of x402. PayCheck marks them authRequired (no money is taken when they refuse). If you have access, say so and strict rules (allowCaution: false, requireVerified) won't block them:

const client = withPayCheck(baseClient, { hasAccess: ["api.myseller.com"], rules: { requireVerified: true } });

Use hasAccess: true to mean every seller. On a team plan, listing a seller in an agent's allowed sellers counts as access too.

Just the check

import { checkPayment } from "x402-paycheck";

const d = await checkPayment({ url, amount: "10000", payTo: "0x...", network: "eip155:8453" });
if (!d.allow) console.log(d.reasons);
console.log(d.buyers); // { reviewed, independentBuyers30d, buyerWallets30d, organicShare, flags }

After paying: report how it went

One line after a paid call tells PayCheck whether you got what you paid for. It's free and optional, and no account is needed: the payment's transaction is read from the paid response and checked on-chain.

import { reportOutcome } from "x402-paycheck";

const res = await fetchWithPay(url, init);
await reportOutcome({ url, response: res, answers: { matchedListing: "yes", dataUsable: "yes", charged: "as_quoted", wouldPayAgain: true } });
// -> { accepted: true, outcome: "delivered", ourTestQueued: true, verifiedOnChain: true }

gotResponse and the HTTP status are filled in from response. On a team plan, pass receipt: client.lastPayCheckDecision?.receipt instead. Confirmations from independent buyers move the endpoint up PayCheck's own paid-test queue; serious problems (nothing came back, charged more or twice) trigger a re-test. Reports never change a grade by themselves. reportOutcome never throws: if PayCheck can't be reached, it returns { accepted: false, reason }.

Links

  • Docs and API reference: https://github.com/Book0fEli/lumiere-paycheck
  • MCP server: https://lumierepaycheck.org/mcp
  • Questions: [email protected]

Lumière PayCheck is operated by Lumière LLC. Scores are automated assessments, not guarantees or financial advice.