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

@zbdpay/agent-fetch

v1.1.0

Published

L402-capable fetch client with ZBD payment integration hooks

Readme

@zbdpay/agent-fetch

L402-aware fetch client for paid HTTP resources.

This package handles the full payment challenge flow:

  • parse 402 Payment Required responses
  • support both L402 and LSAT schemes
  • pay using caller-provided hooks
  • retry with Authorization proof
  • cache proofs locally to avoid duplicate payments

Want to run this immediately? See Examples (Fastest Way to Run).

Requirements

  • Node.js >=22
  • npm

Install

npm install @zbdpay/agent-fetch

Quick Start

import { agentFetch, FileTokenCache } from "@zbdpay/agent-fetch";

const tokenCache = new FileTokenCache(`${process.env.HOME}/.zbd-wallet/token-cache.json`);

const response = await agentFetch("https://example.com/protected", {
  tokenCache,
  maxPaymentSats: 100,
  pay: async (challenge) => {
    // Pay challenge.invoice with your wallet implementation.
    // Return preimage, plus optional paymentId/amountPaidSats.
    return {
      preimage: "<payment-preimage>",
      paymentId: "<payment-id>",
      amountPaidSats: challenge.amountSats,
    };
  },
  waitForPayment: async (paymentId) => {
    // Optional poller for async settlement.
    // Return pending/completed/failed.
    return {
      status: "completed",
      paymentId,
      preimage: "<payment-preimage>",
      amountPaidSats: 21,
    };
  },
});

const body = await response.json();
console.log(response.status, body);

Behavior

  • If cached auth exists and is not expired, request is sent immediately with proof.
  • If response is not 402, original response is returned untouched.
  • If response is 402, challenge is parsed from WWW-Authenticate and/or JSON body.
  • If payment succeeds, proof is generated as <SCHEME> <macaroon-or-token>:<preimage> and request is retried.
  • If maxPaymentSats is set and challenge exceeds it, call fails before payment.
  • If async settlement is used and times out, call fails with a timeout error.

Public API

Exports from src/index.ts:

  • agentFetch
  • requestChallenge
  • payChallenge
  • fetchWithProof
  • FileTokenCache
  • types: AgentFetchOptions, PaymentChallenge, PaidChallenge, PaymentSettlement, TokenCache, TokenRecord, ChallengeScheme

Options (AgentFetchOptions)

  • pay (required): function to pay a parsed challenge
  • waitForPayment (optional): poller for async settlement
  • tokenCache (optional): token cache backend
  • requestInit (optional): forwarded fetch options
  • fetchImpl (optional): custom fetch implementation
  • maxPaymentSats (optional): payment guardrail
  • paymentTimeoutMs (optional, default 30000)
  • paymentPollIntervalMs (optional, default 300)
  • now, sleep (optional testability hooks)

Token Cache

FileTokenCache stores per-URL tokens as JSON and writes atomically.

  • no expiresAt: token is reused until overwritten/deleted
  • with expiresAt: expired token is evicted on read

Default cache location is chosen by the caller. In this suite, agent-wallet uses ~/.zbd-wallet/token-cache.json.

Examples (Fastest Way to Run)

If you want a working paid-request flow in minutes, start with these scripts before wiring your own app code.

  • examples/zbd-agent-fetch.mjs: end-to-end paid fetch using ZBD API for invoice payment
  • examples/fetch-with-known-proof.mjs: call a protected endpoint with a precomputed L402 token

Run from this repo:

npm run build
PROTECTED_URL="http://localhost:8787/protected" ZBD_API_KEY=<your_api_key> npm run example:zbd

If you already have an authorization token:

PROTECTED_URL="http://localhost:8787/protected" L402_AUTHORIZATION="L402 <macaroon>:<preimage>" npm run example:proof

Scripts

npm run build
npm run test
npm run lint
npm run typecheck
npm run smoke:imports
npm run example:zbd
npm run example:proof
npm run release:dry-run

Related Packages

  • @zbdpay/agent-wallet uses this package for zbdw fetch
  • @zbdpay/agent-pay provides middleware that emits L402 challenges this client can consume