@zbdpay/agent-fetch is the client half of the L402 flow. It accepts a payment hook, handles challenge parsing, enforces guards, and retries with proof.
Install
npm install @zbdpay/agent-fetch
Minimal Integration
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: "<payment-preimage>" ,
paymentId: "<payment-id>" ,
amountPaidSats: challenge . amountSats ,
};
},
});
console . log ( response . status , await response . json ());
API Surface
import {
agentFetch ,
requestChallenge ,
payChallenge ,
fetchWithProof ,
FileTokenCache ,
} from "@zbdpay/agent-fetch" ;
Core Options
Option Required Purpose pay(challenge)Yes Pays parsed challenge and returns preimage or payment ID waitForPayment(paymentId)No Polls async settlement when preimage is not immediate tokenCacheNo Cache for URL-scoped authorization proofs maxPaymentSatsNo Hard cap to reject expensive challenges requestInitNo Base request options forwarded to fetch paymentTimeoutMsNo Async settlement timeout paymentPollIntervalMsNo Poll interval for async settlement
Manual Flow (Advanced)
requestChallenge + payChallenge
fetchWithProof
import { requestChallenge , payChallenge } from "@zbdpay/agent-fetch" ;
const challenge = requestChallenge ({
status: 402 ,
headers: response . headers ,
bodyText: await response . text (),
});
const paid = await pay ( challenge );
const authorization = payChallenge ( challenge , paid );
Behavior Guarantees
Cache lookup first
If a valid token exists for the URL, request is sent with proof immediately.
Pass-through for non-402
Non-paid endpoints are returned untouched.
Challenge parsing
Supports both L402 and LSAT challenge schemes.
Payment and retry
Runs caller-provided payment logic, then retries with authorization proof.
Proof caching
Stores token and optional expiry for reuse.
Runnable Examples
The repository includes maintained scripts under examples/:
examples/zbd-agent-fetch.mjs: end-to-end paid fetch using ZBD API payment hooks
examples/fetch-with-known-proof.mjs: fetch with a precomputed L402 authorization token
From the agents workspace, run:
npm --prefix agent-fetch run build
PROTECTED_URL = "https://api.example.com/protected" ZBD_API_KEY =< your_api_key > npm --prefix agent-fetch run example:zbd
If you already have an authorization token:
PROTECTED_URL = "https://api.example.com/protected" L402_AUTHORIZATION = "L402 <macaroon>:<preimage>" npm --prefix agent-fetch run example:proof
pay is mandatory. agent-fetch does not call ZBD directly unless you implement that behavior in your payment hook.