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

@agentchurch/l402

v0.1.1

Published

L402 (Lightning HTTP 402) payment protocol for TypeScript — HMAC-SHA256 macaroons, challenge/verify, and an LND REST invoice client. Edge-safe core.

Readme

@agentchurch/l402

Charge for HTTP requests with Bitcoin Lightning. This library implements L402, the protocol that turns HTTP's 402 Payment Required status into a real payment flow: your server quotes a price, the client pays a Lightning invoice, and the retry carries cryptographic proof of payment. No accounts, no API keys, no payment processor.

It was extracted from Agent Church, where it runs in production letting AI agents pay for services autonomously. Machine-to-machine payments are L402's sweet spot — an agent can read the challenge, pay, and retry without a human in the loop.

What's in the box:

  • The full server side: mint challenges, parse Authorization headers, verify payments.
  • An LND REST client for creating invoices (works with Umbrel and other self-signed-cert nodes).
  • The core is Edge-safe — verification is pure crypto (@noble/hashes), so it runs in Next.js middleware, Cloudflare Workers, and Deno. The LND client is Node-only and lives on a separate subpath so it never enters your Edge bundle.

How the protocol works

  1. Client requests a paid endpoint → server responds 402 with a macaroon (a signed token) and a Lightning invoice.
  2. Client pays the invoice and receives the preimage — a secret that only exists once payment settles.
  3. Client retries with Authorization: L402 <macaroon>:<preimage>.
  4. Server checks the macaroon's signature and that the preimage hashes to the invoice's payment hash. Payment proven, no database lookup.

Install

npm install @agentchurch/l402

Usage

Quote a price (Node — needs your LND node to mint the invoice):

import { buildL402Challenge, formatWWWAuthenticate, rootKeyFromEnv } from "@agentchurch/l402";
import { createLndClient } from "@agentchurch/l402/lnd";

const lnd = createLndClient({ restUrl: "https://your-node:8080", macaroonHex: process.env.LND_MACAROON_HEX! });
const { paymentHash, invoice } = await lnd.createInvoice(5000, "premium_api access");

const challenge = buildL402Challenge(rootKeyFromEnv(), {
  paymentHash, invoice,
  service: "premium_api",
  amountSats: 5000,
  location: "api.example.com",
});

// 402 response with: WWW-Authenticate: formatWWWAuthenticate(challenge)

Verify the payment (anywhere, including Edge):

import { parseL402Authorization, verifyL402Token, l402CaveatsMatch } from "@agentchurch/l402";

const token = parseL402Authorization(request.headers.get("Authorization"));
const result = token && verifyL402Token(rootKey, token);

if (result?.valid && l402CaveatsMatch(result, "premium_api", 5000)) {
  // Paid. Serve the request.
}

l402CaveatsMatch matters: it stops a token bought for a cheap service being replayed against an expensive one.

One payment, one use? That part is yours — verification proves the payment is real, not that it's unused. If your endpoint is pay-per-call, store consumed preimages (a unique-constrained table works) and reject repeats. If one payment should grant a session, skip this; the token's expiry caveat bounds its lifetime.

Reference

  • Root key: 32-byte hex (openssl rand -hex 32), kept secret; it signs and verifies every macaroon.
  • Macaroon primitives (createMacaroon, verifyMacaroonSignature, serialization) are exported if you need lower-level control.
  • Serialization is base64(JSON) — simple and debuggable. Clients treat the macaroon as an opaque string, which is all L402 requires, so standard L402 clients interoperate.
  • Full types are shipped; the .d.ts files document every export.

License

MIT © Hypno Labs