From efaa09cdfc79b0a6ff59e7c22139bf14c1ebfdb1 Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Wed, 25 Feb 2026 19:46:52 -0800 Subject: [PATCH 1/7] feat: agents docs --- agents.mdx | 86 ++++++++++++++++++ agents/agent-fetch.mdx | 120 +++++++++++++++++++++++++ agents/agent-pay.mdx | 140 ++++++++++++++++++++++++++++++ agents/agent-wallet-dashboard.mdx | 61 +++++++++++++ agents/agent-wallet.mdx | 115 ++++++++++++++++++++++++ agents/architecture.mdx | 68 +++++++++++++++ agents/quickstart.mdx | 132 ++++++++++++++++++++++++++++ agents/registry.mdx | 73 ++++++++++++++++ agents/repo-map.mdx | 62 +++++++++++++ docs.json | 52 ++++++++++- 10 files changed, 906 insertions(+), 3 deletions(-) create mode 100644 agents.mdx create mode 100644 agents/agent-fetch.mdx create mode 100644 agents/agent-pay.mdx create mode 100644 agents/agent-wallet-dashboard.mdx create mode 100644 agents/agent-wallet.mdx create mode 100644 agents/architecture.mdx create mode 100644 agents/quickstart.mdx create mode 100644 agents/registry.mdx create mode 100644 agents/repo-map.mdx diff --git a/agents.mdx b/agents.mdx new file mode 100644 index 0000000..8cf4601 --- /dev/null +++ b/agents.mdx @@ -0,0 +1,86 @@ +--- +title: "ZBD Agents" +sidebarTitle: "Overview" +description: "Build agent-native Bitcoin flows with zbdw, agent-pay, and agent-fetch." +--- + +The ZBD Agents toolkit gives you an end-to-end stack for agentic payments: a wallet CLI (`zbdw`), an L402 client (`agent-fetch`), an L402 server middleware (`agent-pay`), and supporting apps for identity and operations. + + + + Install one package, run `zbdw init`, and execute your first paid request. + + + Add payment gates to Express, Hono, and Next.js route handlers. + + + Auto-handle L402 challenges with max payment guardrails and token caching. + + + Use the dashboard to inspect balances, payment history, and local wallet state. + + + +## Choose Your Path + + + + **Goal:** launch a working agent payment flow fast. + + 1. Start with the [Quick Start](/agents/quickstart) + 2. Add payment-gated routes with [agent-pay](/agents/agent-pay) + 3. Pay those routes with [agent-fetch](/agents/agent-fetch) or `zbdw fetch` + + + **Goal:** validate monetization and ops fit. + + - Map capabilities in [Architecture](/agents/architecture) + - Review deployment surfaces in [Repo Map](/agents/repo-map) + - Track live wallet activity in [Agent Wallet Dashboard](/agents/agent-wallet-dashboard) + + + **Goal:** standardize identity and payments infrastructure. + + - Set up [zbd.ai Registry](/agents/registry) for stable Lightning addresses + - Standardize env vars and shared file paths + - Adopt workspace verification scripts for CI + + + +## Core Repositories + + + + CLI wallet and command router for ZBD agent payments (`zbdw`). + + + L402-aware fetch client for paid HTTP resources. + + + L402 middleware for Express, Hono, and Next.js. + + + Local dashboard for wallet balances and payments history. + + + + + `zbdw` is the binary shipped by `@zbdpay/agent-wallet`. It is designed for JSON-first CLI interoperability with agent runners. + + +## What You Can Build + + + + Gate premium API routes with `agent-pay`, then let autonomous clients unlock access via `agent-fetch`. + + + Use `zbdw fetch` to allow agents to pay per request and retrieve premium content in one command. + + + Combine wallet send/receive primitives with L402 middleware to create closed-loop service economies. + + + Track local wallet activity in `~/.zbd-wallet` and visualize it with the dashboard. + + diff --git a/agents/agent-fetch.mdx b/agents/agent-fetch.mdx new file mode 100644 index 0000000..caa61bd --- /dev/null +++ b/agents/agent-fetch.mdx @@ -0,0 +1,120 @@ +--- +title: "Agent Fetch" +description: "Use agentFetch to parse 402 challenges, pay invoices, and retry automatically with L402 proof." +--- + +`@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. + + + + Source, tests, and engineering contract. + + + Install and integrate into existing runtimes. + + + +## Install + +```bash +npm install @zbdpay/agent-fetch +``` + +## Minimal Integration + +```typescript +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: "", + paymentId: "", + amountPaidSats: challenge.amountSats, + }; + }, +}); + +console.log(response.status, await response.json()); +``` + +## API Surface + +```typescript +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 | +| `tokenCache` | No | Cache for URL-scoped authorization proofs | +| `maxPaymentSats` | No | Hard cap to reject expensive challenges | +| `requestInit` | No | Base request options forwarded to `fetch` | +| `paymentTimeoutMs` | No | Async settlement timeout | +| `paymentPollIntervalMs` | No | Poll interval for async settlement | + +## Manual Flow (Advanced) + + +```typescript requestChallenge + payChallenge +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); +``` + +```typescript fetchWithProof +import { fetchWithProof } from "@zbdpay/agent-fetch"; + +const res = await fetchWithProof( + "https://example.com/protected", + { method: "GET" }, + authorization, + fetch, +); +``` + + +## Behavior Guarantees + + + + If a valid token exists for the URL, request is sent with proof immediately. + + + Non-paid endpoints are returned untouched. + + + Supports both `L402` and `LSAT` challenge schemes. + + + Runs caller-provided payment logic, then retries with authorization proof. + + + Stores token and optional expiry for reuse. + + + + + `pay` is mandatory. `agent-fetch` does not call ZBD directly unless you implement that behavior in your payment hook. + diff --git a/agents/agent-pay.mdx b/agents/agent-pay.mdx new file mode 100644 index 0000000..89093c0 --- /dev/null +++ b/agents/agent-pay.mdx @@ -0,0 +1,140 @@ +--- +title: "Agent Pay" +description: "Protect HTTP routes with L402 payment challenges in Express, Hono, and Next.js." +--- + +`@zbdpay/agent-pay` is the server half of the L402 protocol. It creates invoice-backed payment challenges and verifies payment proof before allowing access. + + + + Full middleware source and adapter tests. + + + Install and use from Node.js services. + + + +## Install + +```bash +npm install @zbdpay/agent-pay +``` + +## Environment + +| Variable | Required | Default | +|---|---|---| +| `ZBD_API_KEY` | Yes (unless passed in config) | none | +| `ZBD_API_BASE_URL` | No | `https://api.zbdpay.com` | + +## Quickstarts + + + + ```typescript + import express from "express"; + import { createExpressPaymentMiddleware } from "@zbdpay/agent-pay"; + + const app = express(); + + app.get( + "/protected", + createExpressPaymentMiddleware({ + amount: 21, + apiKey: process.env.ZBD_API_KEY, + }), + (_req, res) => { + res.json({ ok: true }); + }, + ); + ``` + + + ```typescript + import { Hono } from "hono"; + import { createHonoPaymentMiddleware } from "@zbdpay/agent-pay"; + + const app = new Hono(); + + app.use( + "/protected", + createHonoPaymentMiddleware({ + amount: 21, + apiKey: process.env.ZBD_API_KEY, + }), + ); + ``` + + + ```typescript + import { withPaymentRequired } from "@zbdpay/agent-pay/next"; + + export const GET = withPaymentRequired( + { + amount: 21, + apiKey: process.env.ZBD_API_KEY, + }, + async () => Response.json({ ok: true }), + ); + ``` + + + +## PaymentConfig + +```typescript +type PaymentConfig = { + amount: number | ((request: RequestLike) => number | Promise); + currency?: "SAT" | "USD"; + apiKey?: string; + tokenStorePath?: string; +}; +``` + + + SAT pricing is the default and the most direct production path. + + +## 402 Response Shape + +```http +WWW-Authenticate: L402 macaroon="", invoice="" +``` + +```json +{ + "error": { + "code": "payment_required", + "message": "Payment required" + }, + "macaroon": "", + "invoice": "", + "paymentHash": "", + "amountSats": 21, + "expiresAt": 1735766400 +} +``` + +## Error Codes + +| HTTP | Code | Meaning | +|---|---|---| +| 402 | `payment_required` | No valid payment proof provided | +| 401 | `invalid_credential` | Macaroon signature invalid | +| 401 | `invalid_payment_proof` | Preimage mismatch | +| 403 | `resource_mismatch` | Proof for different route | +| 403 | `amount_mismatch` | Proof for different price | +| 403 | `token_expired` | Proof expired | +| 500 | `configuration_error` | Missing API key/config | +| 500 | `pricing_error` | Dynamic pricing function failed | +| 502 | `invoice_creation_failed` | Upstream invoice creation failed | + +## Storage + +By default, settled token metadata is persisted at: + +```text +~/.zbd-wallet/server-tokens.json +``` + +Override via `tokenStorePath` when needed for your deployment model. diff --git a/agents/agent-wallet-dashboard.mdx b/agents/agent-wallet-dashboard.mdx new file mode 100644 index 0000000..d68a974 --- /dev/null +++ b/agents/agent-wallet-dashboard.mdx @@ -0,0 +1,61 @@ +--- +title: "Agent Wallet Dashboard" +description: "Run a local Next.js dashboard to inspect wallet config, balances, and payment history." +--- + +The Agent Wallet Dashboard is a read-only UI for operators and developers who want visibility into `zbdw` state. + + + + Source code, setup docs, and sample-data fixtures. + + + Reads `~/.zbd-wallet/config.json` and `~/.zbd-wallet/payments.json` by default. + + + +## Run Locally + +```bash +npm install +npm run dev +``` + +Open `http://localhost:3113`. + +## Environment Variables + +| Variable | Default | +|---|---| +| `ZBD_WALLET_CONFIG` | `~/.zbd-wallet/config.json` | +| `ZBD_WALLET_PAYMENTS` | `~/.zbd-wallet/payments.json` | +| `ZBD_API_BASE_URL` | `https://api.zbdpay.com` | + +## Use Included Sample Data + +```bash +ZBD_WALLET_CONFIG="$PWD/sample-data/config.json" \ +ZBD_WALLET_PAYMENTS="$PWD/sample-data/payments.json" \ +npm run dev +``` + +## Built-in Features + + + + Refreshes wallet data every 15 seconds with manual refresh support. + + + Export filtered payment ledgers (`All`, `Received`, `Sent`). + + + Click rows for detailed payload and copy actions. + + + Persistent light/dark mode with local preference storage. + + + + + The dashboard is intentionally read-only. It does not mutate wallet files. + diff --git a/agents/agent-wallet.mdx b/agents/agent-wallet.mdx new file mode 100644 index 0000000..bc6f3f9 --- /dev/null +++ b/agents/agent-wallet.mdx @@ -0,0 +1,115 @@ +--- +title: "Agent Wallet" +description: "Use zbdw for wallet setup, send/receive operations, withdraw flows, and paid fetch." +--- + +`@zbdpay/agent-wallet` ships the `zbdw` CLI and is the fastest way to operationalize agent payments. + + + + Source code, release history, and examples. + + + Install globally or execute with npx. + + + +## Install + +```bash +npm install -g @zbdpay/agent-wallet +``` + +Or run directly: + +```bash +npx @zbdpay/agent-wallet init --key +``` + +## Environment Variables + +| Variable | Default | Purpose | +|---|---|---| +| `ZBD_API_KEY` | none | API key for wallet and payments requests | +| `ZBD_API_BASE_URL` | `https://api.zbdpay.com` | Override ZBD API host | +| `ZBD_AI_BASE_URL` | `https://zbd.ai` | Registration service host | +| `ZBD_WALLET_CONFIG` | `~/.zbd-wallet/config.json` | Wallet config path | +| `ZBD_WALLET_PAYMENTS` | `~/.zbd-wallet/payments.json` | Local payments log path | +| `ZBD_WALLET_TOKEN_CACHE` | `~/.zbd-wallet/token-cache.json` | L402 token cache path | + +## Command Reference + +```bash +zbdw init [--key ] +zbdw info +zbdw balance + +zbdw receive +zbdw receive --static + +zbdw send +zbdw payments +zbdw payment + +zbdw withdraw create +zbdw withdraw status + +zbdw fetch [--method ] [--data ] [--max-sats ] +``` + +## Destination Types (`send`) + +| Destination | Example | Route | +|---|---|---| +| BOLT11 invoice | `lnbc...` | `/v0/payments` | +| Lightning Address | `name@domain.com` | `/v0/ln-address/send-payment` | +| ZBD Gamertag | `@player` | `/v0/gamertag/send-payment` | +| LNURL | `lnurl...` | `/v0/ln-address/send-payment` | + +## JSON Output Contract + +Success and failure responses are always JSON on stdout. + +```json +{ + "error": "error_code", + "message": "Human-readable message", + "details": {} +} +``` + +Common success examples: + +```json +{"lightningAddress":"name@zbd.ai","status":"ok"} +{"balance_sats":50000} +{"payment_id":"pay_123","fee_sats":1,"status":"completed"} +{"status":200,"body":{},"payment_id":"pay_123","amount_paid_sats":21} +``` + +## Storage Layout + +```text +~/.zbd-wallet/ + config.json + payments.json + token-cache.json +``` + + + `zbdw fetch` uses `@zbdpay/agent-fetch` under the hood, including token caching and max payment guardrails. + + +## Troubleshooting + + + + Build and alias the local binary, or install globally with `npm install -g @zbdpay/agent-wallet`. + + + Confirm `ZBD_AI_BASE_URL` points to a reachable `zbd-ai` service and your API key is valid. + + + Verify your configured API base URL returns wallet balance fields in expected shape. + + diff --git a/agents/architecture.mdx b/agents/architecture.mdx new file mode 100644 index 0000000..c8c37ee --- /dev/null +++ b/agents/architecture.mdx @@ -0,0 +1,68 @@ +--- +title: "Architecture" +description: "How wallet, fetch, pay, and registry components fit together for agent-native payments." +--- + +The ZBD Agents architecture is built around a simple split: `agent-pay` issues payment challenges, and `agent-fetch` or `zbdw fetch` solves them automatically. + +```mermaid +graph LR + A[Agent Runtime] -->|zbdw fetch / agentFetch| B[Paid API] + B -->|402 challenge| A + A -->|Pay invoice via ZBD| C[ZBD API] + A -->|Retry with L402 proof| B + B -->|200 premium response| A + + A --> D[zbd.ai Registry] + D --> E[Lightning Address Resolution] +``` + +## Components + + + + CLI interface (`zbdw`) for wallet operations, payment history, withdraw flows, and paid fetch. + + + Client-side L402 flow manager with cache reuse and max payment guardrails. + + + Server middleware that returns 402 challenges and verifies payment proof. + + + Identity layer for stable Lightning addresses and LNURL resolution. + + + +## Request Lifecycle + + + + A request hits an endpoint wrapped by `agent-pay`. + + + `agent-pay` creates an invoice and returns `WWW-Authenticate: L402 ...` plus challenge JSON. + + + `agent-fetch` (or `zbdw fetch`) pays the invoice and retrieves the preimage. + + + The request is retried with `Authorization: L402 :`. + + + `agent-pay` validates signature, hash, amount, expiry, and settlement state before returning 200. + + + +## Shared Local State + +| Path | Primary Writer | Primary Reader | +|---|---|---| +| `~/.zbd-wallet/config.json` | `zbdw init` | `zbdw`, dashboard | +| `~/.zbd-wallet/payments.json` | `zbdw send/receive` | `zbdw`, dashboard | +| `~/.zbd-wallet/token-cache.json` | `zbdw fetch` | `zbdw fetch` | +| `~/.zbd-wallet/server-tokens.json` | `agent-pay` | `agent-pay` | + + + The toolkit is optimized for Node.js 22+ across all core packages. + diff --git a/agents/quickstart.mdx b/agents/quickstart.mdx new file mode 100644 index 0000000..eb0363a --- /dev/null +++ b/agents/quickstart.mdx @@ -0,0 +1,132 @@ +--- +title: "Quick Start" +description: "Launch your first agent payment workflow with zbdw, L402 middleware, and paid fetch." +--- + +This quickstart gets you from zero to a working paid request flow. + + + Use Node.js 22+ for all packages in this toolkit. + + +## 1) Install Wallet CLI + + +```bash Global install +npm install -g @zbdpay/agent-wallet +``` + +```bash One-shot installless +npx @zbdpay/agent-wallet init --key +``` + + +## 2) Initialize Wallet Identity + +```bash +zbdw init --key +# {"lightningAddress":"your-name@zbd.ai","status":"ok"} +``` + +Then verify balance and metadata: + +```bash +zbdw info +zbdw balance +``` + +## 3) Try Core Wallet Actions + + + + ```bash + zbdw receive 1000 + zbdw receive --static + ``` + + + ```bash + zbdw send andre@zbd.gg 500 + zbdw send @gamertag 500 + ``` + + + ```bash + zbdw payments + zbdw payment + ``` + + + +## 4) Fetch a Paid Endpoint (L402) + +```bash +zbdw fetch https://your-paid-api.com/premium --max-sats 100 +``` + +Run the same command again to reuse the token cache when valid. + +```bash +zbdw fetch https://your-paid-api.com/premium --max-sats 100 +``` + + + If cache is reused, `payment_id` is typically `null` on the second call. + + +## 5) Add a Paid Route with agent-pay + +```typescript +import express from "express"; +import { createExpressPaymentMiddleware } from "@zbdpay/agent-pay"; + +const app = express(); + +app.get( + "/premium", + createExpressPaymentMiddleware({ amount: 21, apiKey: process.env.ZBD_API_KEY }), + (_req, res) => res.json({ premium: true }), +); + +app.listen(3000); +``` + +## 6) Use agent-fetch in App Code + +```typescript +import { agentFetch, FileTokenCache } from "@zbdpay/agent-fetch"; + +const tokenCache = new FileTokenCache(`${process.env.HOME}/.zbd-wallet/token-cache.json`); + +const response = await agentFetch("https://localhost:3000/premium", { + tokenCache, + maxPaymentSats: 100, + pay: async (challenge) => { + // Implement invoice payment with your wallet API call. + return { + preimage: "", + paymentId: "", + amountPaidSats: challenge.amountSats, + }; + }, +}); + +console.log(response.status, await response.json()); +``` + +## Next Guides + + + + CLI command reference, env vars, and JSON output contract. + + + Add L402 to Express, Hono, and Next.js. + + + Full client options, async settlement, and caching. + + + Canonical repositories and package boundaries. + + diff --git a/agents/registry.mdx b/agents/registry.mdx new file mode 100644 index 0000000..2e1a2ba --- /dev/null +++ b/agents/registry.mdx @@ -0,0 +1,73 @@ +--- +title: "zbd.ai Registry" +description: "Register agent identities and resolve Lightning Addresses through LNURL endpoints." +--- + +The registry service powers the identity layer behind `zbdw init`, returning stable Lightning addresses like `@zbd.ai`. + +## What It Does + + + + Calls ZBD wallet endpoint to verify key validity. + + + Creates LNURL-backed payment destination for your identity. + + + Responds with `{ "lightningAddress": "name@zbd.ai" }`. + + + +## API Endpoints + +| Method | Route | Purpose | +|---|---|---| +| `POST` | `/api/register` | Register or refresh agent identity | +| `GET` | `/.well-known/lnurlp/:username` | LNURL metadata resolution | +| `GET` | `/.well-known/lnurlp/:username?amount=` | Invoice generation callback | + +## Request + Response + + +```json Register request +{ "apiKey": "" } +``` + +```json Register success +{ "lightningAddress": "swift-tiger@zbd.ai" } +``` + +```json Error example +{ "error": "invalid_key", "message": "API key rejected" } +``` + + +## Storage Backends + + + + Local development and VPS-friendly. + + - Backend: `file` + - Path: `~/.zbd-ai/agents.json` (default) + + + Serverless persistence path. + + - Backend: `vercel-kv` + - Env vars: `KV_REST_API_URL` / `KV_REST_API_TOKEN` + + + +## Key Environment Variables + +| Variable | Default | +|---|---| +| `ZBD_API_BASE_URL` | `https://api.zbdpay.com` | +| `ZBD_AI_STORE_BACKEND` | auto-select | +| `ZBD_AI_STORE_PATH` | `~/.zbd-ai/agents.json` | + + + In serverless deployments, avoid relying on local filesystem persistence. Use a durable backend such as Vercel KV. + diff --git a/agents/repo-map.mdx b/agents/repo-map.mdx new file mode 100644 index 0000000..27c2d79 --- /dev/null +++ b/agents/repo-map.mdx @@ -0,0 +1,62 @@ +--- +title: "Repo Map" +description: "Canonical repositories, packages, and ownership surfaces for the ZBD Agents stack." +--- + +Use this page to orient engineering and product teams across the agent toolkit. + +## Canonical Repositories + + + + `@zbdpay/agent-wallet` package, `zbdw` binary, CLI workflows. + + + `@zbdpay/agent-fetch` package, L402 client flow and token cache. + + + `@zbdpay/agent-pay` package, middleware adapters for Express, Hono, Next.js. + + + Local read-only dashboard for wallet files and operational checks. + + + + + The `zbd.ai` service underpins registration and Lightning Address resolution. The source repository may be private in some environments. + + +## Package + Runtime Matrix + +| Surface | Type | Runtime | NPM | +|---|---|---|---| +| `@zbdpay/agent-wallet` | CLI | Node.js >= 22 | Yes | +| `@zbdpay/agent-fetch` | Library | Node.js >= 22 | Yes | +| `@zbdpay/agent-pay` | Library | Node.js >= 22 | Yes | +| `agent-wallet-dashboard` | Next.js app | Node.js >= 22 | No | +| `zbd-ai` | Next.js app/service | Node.js >= 22 | No | + +## Workspace Helpers + +At the top-level agents workspace, these scripts are useful for full-suite verification: + +```bash +npm run install:all +npm run build:all +npm run test:all +npm run verify:all +``` + +## Where to Go Next + + + + Start with a first-run path across setup, payment, and fetch. + + + Understand request lifecycle and data boundaries. + + + Command reference and operational patterns. + + diff --git a/docs.json b/docs.json index e74ccc3..fd78fa0 100644 --- a/docs.json +++ b/docs.json @@ -237,11 +237,57 @@ } ] } - ] - }, + ] + }, { - "tab": "Pay", + "tab": "Agents", "anchors": [ + { + "anchor": "Overview", + "icon": "robot", + "pages": [ + { + "group": "Overview", + "pages": [ + "agents", + "agents/architecture", + "agents/repo-map" + ] + }, + { + "group": "Quick Start", + "pages": [ + "agents/quickstart" + ] + } + ] + }, + { + "anchor": "Agent Toolkit", + "icon": "toolbox", + "pages": [ + { + "group": "Core Packages", + "pages": [ + "agents/agent-wallet", + "agents/agent-fetch", + "agents/agent-pay" + ] + }, + { + "group": "Supporting Apps", + "pages": [ + "agents/agent-wallet-dashboard", + "agents/registry" + ] + } + ] + } + ] + }, + { + "tab": "Pay", + "anchors": [ { "anchor": "Overview", "icon": "inbox", From c43f3d78b01e5bad10031c2e4f38289a38f623b5 Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Wed, 25 Feb 2026 20:01:24 -0800 Subject: [PATCH 2/7] feat: add agents skills documentation --- agents.mdx | 3 ++ agents/skills.mdx | 109 ++++++++++++++++++++++++++++++++++++++++++++++ docs.json | 3 +- 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 agents/skills.mdx diff --git a/agents.mdx b/agents.mdx index 8cf4601..38b4078 100644 --- a/agents.mdx +++ b/agents.mdx @@ -19,6 +19,9 @@ The ZBD Agents toolkit gives you an end-to-end stack for agentic payments: a wal Use the dashboard to inspect balances, payment history, and local wallet state. + + Package `zbdw` workflows into reusable skills for IDE agents and OpenClaw-compatible runtimes. + ## Choose Your Path diff --git a/agents/skills.mdx b/agents/skills.mdx new file mode 100644 index 0000000..e843400 --- /dev/null +++ b/agents/skills.mdx @@ -0,0 +1,109 @@ +--- +title: "Agent Skills" +description: "Package zbdw workflows as reusable skills for skills.sh and OpenClaw-compatible agents." +--- + +Skills let agent runners call proven `zbdw` flows with better defaults, safer guardrails, and faster onboarding. + + + + Official skill files, references, and OpenClaw metadata for `zbdw` operations. + + + Discovery and installation index for agent skills. + + + Install, list, and validate skills with `npx skills`. + + + Runtime-compatible format for metadata and install requirements. + + + +## Quick Install + + +```bash From GitHub repository +npx skills add https://github.com/zbdpay/agent-wallet --full-depth --skill zbdw +``` + +```bash From local clone +npx skills add ./agent-wallet/skills/zbdw +``` + + + + Use `npx skills add --list` to verify discovery without installing. + + +## What the Skill Covers + + + + - `zbdw init`, `info`, `balance` + - `zbdw receive`, `send`, `payments`, `payment` + - `zbdw withdraw create|status` + + + - `zbdw fetch --max-sats ` + - payment-cap enforcement + - token-cache reuse behavior + + + - maps JSON errors to recovery actions + - enforces destination and amount validation + - documents API key precedence + + + +## Skill Layout + +```text +skills/zbdw/ + SKILL.md + references/ + command-reference.md + troubleshooting.md +``` + +## Authoring Notes for High Discovery + + + + Include natural language triggers users actually type: `send sats`, `withdraw`, `payment id`, `L402`, `paywall`. + + + Keep examples machine-readable so agents can parse fields like `payment_id`, `amount_paid_sats`, and `error`. + + + Place task mappings and troubleshooting in a local `references/` folder and link them from `SKILL.md`. + + + Add OpenClaw metadata for required binaries and install instructions so runners can self-heal setup. + + + +## OpenClaw Metadata Example + +```yaml +metadata: + openclaw: + emoji: "⚡" + requires: + anyBins: + - zbdw + - npx + install: + - id: node-global + kind: node + package: "@zbdpay/agent-wallet" + bins: + - zbdw +``` + +## Publish Checklist + +- Run package checks in `agent-wallet`: `npm run typecheck && npm run build && npm test` +- Verify skill discovery: `npx skills add --list` +- Ensure `SKILL.md` links resolve and references exist +- Push to GitHub and validate install from a clean machine/user profile diff --git a/docs.json b/docs.json index fd78fa0..f97c5b0 100644 --- a/docs.json +++ b/docs.json @@ -257,7 +257,8 @@ { "group": "Quick Start", "pages": [ - "agents/quickstart" + "agents/quickstart", + "agents/skills" ] } ] From 8caa3da10dd89af613f163519a6b62e68766fdff Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Wed, 25 Feb 2026 20:35:54 -0800 Subject: [PATCH 3/7] docs(agents): add OpenClaw skill install guide --- agents/openclaw-skill-install.mdx | 104 ++++++++++++++++++++++++++++++ agents/skills.mdx | 4 ++ docs.json | 3 +- 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 agents/openclaw-skill-install.mdx diff --git a/agents/openclaw-skill-install.mdx b/agents/openclaw-skill-install.mdx new file mode 100644 index 0000000..bd471bc --- /dev/null +++ b/agents/openclaw-skill-install.mdx @@ -0,0 +1,104 @@ +--- +title: "Install zbdw Skill on OpenClaw" +description: "Step-by-step install and verification for using the zbdw skill on an OpenClaw instance." +--- + +Use this guide when you want an OpenClaw instance to use the `zbdw` wallet skill end to end. + + + Use Node.js 22+ and make sure your OpenClaw workspace is set before installing skills. + + +## Prerequisites + +- A working OpenClaw instance +- `npx` available on your machine +- ZBD API key for wallet initialization +- Agent workspace with a `skills/` folder (or permission to create one) + +## 1) Install the skill into your OpenClaw workspace + +From the root of your OpenClaw workspace: + +```bash +npx skills add https://github.com/zbdpay/agent-wallet --full-depth --skill zbdw +``` + +This installs `zbdw` into your local workspace skills so OpenClaw can discover it. + + + You can preview discovery without installing by adding `--list`. + + +## 2) Confirm OpenClaw can see the skill + +```bash +openclaw skills list +openclaw skills list --eligible +openclaw skills info zbdw +``` + +If `zbdw` is missing from `--eligible`, run: + +```bash +openclaw skills check +``` + +## 3) Ensure `zbdw` binary is available + +The skill is eligible when OpenClaw can find one of the required binaries (`zbdw` or `npx`). + +```bash +zbdw --help +``` + +If `zbdw` is not installed globally yet: + +```bash +npm install -g @zbdpay/agent-wallet +zbdw --help +``` + +## 4) Initialize wallet identity + +```bash +zbdw init --key +zbdw info +zbdw balance +``` + +## 5) Validate the skill in an agent session + +Start a new OpenClaw session and ask for a wallet action, for example: + +- "Use zbdw to show my wallet balance" +- "Use zbdw to create a 1000 sat receive invoice" +- "Use zbdw fetch on this paid endpoint with max 100 sats" + + + OpenClaw snapshots eligible skills at session start. If you just installed the skill, start a new session to pick it up. + + +## Shared install for multiple agents (optional) + +If you want all local agents to reuse the same skill set, install/copy the skill under: + +```text +~/.openclaw/skills/zbdw/SKILL.md +``` + +Workspace skills still take precedence over shared skills when names conflict. + +## Troubleshooting + +- `zbdw` not eligible: run `openclaw skills check` and install `@zbdpay/agent-wallet` globally. +- Skill installed but not used: start a new session so OpenClaw refreshes the skill snapshot. +- API key errors: re-run `zbdw init --key ` and verify with `zbdw info`. +- Command not found in sandboxed runs: ensure required binaries are also available in the sandbox image. + +## Related Docs + +- [Agent Skills](/agents/skills) +- [Agent Wallet CLI](/agents/agent-wallet) +- [OpenClaw Skills reference](https://docs.openclaw.ai/tools/skills) +- [OpenClaw skills CLI reference](https://docs.openclaw.ai/cli/skills) diff --git a/agents/skills.mdx b/agents/skills.mdx index e843400..d7cca52 100644 --- a/agents/skills.mdx +++ b/agents/skills.mdx @@ -20,6 +20,10 @@ Skills let agent runners call proven `zbdw` flows with better defaults, safer gu + + Need a direct OpenClaw walkthrough? Use [Install zbdw Skill on OpenClaw](/agents/openclaw-skill-install). + + ## Quick Install diff --git a/docs.json b/docs.json index f97c5b0..16af032 100644 --- a/docs.json +++ b/docs.json @@ -258,7 +258,8 @@ "group": "Quick Start", "pages": [ "agents/quickstart", - "agents/skills" + "agents/skills", + "agents/openclaw-skill-install" ] } ] From 23553cc97d774b46f3219f876f8ba56490e0dadc Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Wed, 25 Feb 2026 20:53:50 -0800 Subject: [PATCH 4/7] docs(agents): surface runnable examples and quick run paths --- README.md | 10 ++++++++++ agents.mdx | 4 ++++ agents/agent-fetch.mdx | 20 ++++++++++++++++++++ agents/agent-pay.mdx | 23 +++++++++++++++++++++++ agents/agent-wallet.mdx | 7 +++++++ agents/quickstart.mdx | 16 ++++++++++++++++ agents/repo-map.mdx | 10 ++++++++++ 7 files changed, 90 insertions(+) diff --git a/README.md b/README.md index 1702d81..999e293 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,16 @@ We enable businesses and consumers to quickly introduce instantaneous Bitcoin pa With ZBD, it's easy! Anyone can do it. **[What are YOU building?](https://dashboard.zbdpay.com)** +## Agents Docs Fast Path + +If you are documenting or testing the Agents toolkit, start here: + +- Overview: `/agents` +- Quick start: `/agents/quickstart` +- Runnable examples: `/agents/agent-pay` and `/agents/agent-fetch` + +The `agent-pay` and `agent-fetch` repositories include `examples/` scripts that let users run a working paid-request flow in minutes. + ## Contributing ### Development diff --git a/agents.mdx b/agents.mdx index 38b4078..4f9aaf9 100644 --- a/agents.mdx +++ b/agents.mdx @@ -6,6 +6,10 @@ description: "Build agent-native Bitcoin flows with zbdw, agent-pay, and agent-f The ZBD Agents toolkit gives you an end-to-end stack for agentic payments: a wallet CLI (`zbdw`), an L402 client (`agent-fetch`), an L402 server middleware (`agent-pay`), and supporting apps for identity and operations. + + Want the fastest hands-on path? Start with the runnable scripts in `agent-pay/examples/http-server.mjs` and `agent-fetch/examples/zbd-agent-fetch.mjs`. + + Install one package, run `zbdw init`, and execute your first paid request. diff --git a/agents/agent-fetch.mdx b/agents/agent-fetch.mdx index caa61bd..ddf60e5 100644 --- a/agents/agent-fetch.mdx +++ b/agents/agent-fetch.mdx @@ -115,6 +115,26 @@ const res = await fetchWithProof( +## 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: + +```bash +npm --prefix agent-fetch run build +PROTECTED_URL="http://localhost:8787/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd +``` + +If you already have an authorization token: + +```bash +PROTECTED_URL="http://localhost:8787/protected" L402_AUTHORIZATION="L402 :" 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. diff --git a/agents/agent-pay.mdx b/agents/agent-pay.mdx index 89093c0..9362f59 100644 --- a/agents/agent-pay.mdx +++ b/agents/agent-pay.mdx @@ -129,6 +129,29 @@ WWW-Authenticate: L402 macaroon="", invoice="" | 500 | `pricing_error` | Dynamic pricing function failed | | 502 | `invoice_creation_failed` | Upstream invoice creation failed | +## Runnable Example + +The repository includes `examples/http-server.mjs` for a minimal paid route. + +From the agents workspace, run: + +```bash +npm --prefix agent-pay run build +ZBD_API_KEY= npm --prefix agent-pay run example:http-server +``` + +Optional verbose logs: + +```bash +ZBD_PAY_DEBUG=1 ZBD_API_KEY= npm --prefix agent-pay run example:http-server +``` + +Then hit the route with your wallet CLI: + +```bash +zbdw fetch "http://localhost:8787/protected" --max-sats 100 +``` + ## Storage By default, settled token metadata is persisted at: diff --git a/agents/agent-wallet.mdx b/agents/agent-wallet.mdx index bc6f3f9..fd54df3 100644 --- a/agents/agent-wallet.mdx +++ b/agents/agent-wallet.mdx @@ -100,6 +100,13 @@ Common success examples: `zbdw fetch` uses `@zbdpay/agent-fetch` under the hood, including token caching and max payment guardrails. +## Companion Runnable Examples + +`agent-wallet` does not currently ship its own `examples/` directory. For a full runnable flow, pair it with: + +- `agent-pay/examples/http-server.mjs` +- `agent-fetch/examples/zbd-agent-fetch.mjs` + ## Troubleshooting diff --git a/agents/quickstart.mdx b/agents/quickstart.mdx index eb0363a..977425f 100644 --- a/agents/quickstart.mdx +++ b/agents/quickstart.mdx @@ -74,6 +74,22 @@ zbdw fetch https://your-paid-api.com/premium --max-sats 100 If cache is reused, `payment_id` is typically `null` on the second call. +## 4b) Zero-to-Demo with Included Examples + +If you want to see the full paid-route flow with minimal setup, run the maintained examples directly from the monorepo workspace: + +```bash +npm --prefix agent-pay run build +ZBD_API_KEY= npm --prefix agent-pay run example:http-server +``` + +Then in another terminal: + +```bash +npm --prefix agent-fetch run build +PROTECTED_URL="http://localhost:8787/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd +``` + ## 5) Add a Paid Route with agent-pay ```typescript diff --git a/agents/repo-map.mdx b/agents/repo-map.mdx index 27c2d79..476502f 100644 --- a/agents/repo-map.mdx +++ b/agents/repo-map.mdx @@ -36,6 +36,16 @@ Use this page to orient engineering and product teams across the agent toolkit. | `agent-wallet-dashboard` | Next.js app | Node.js >= 22 | No | | `zbd-ai` | Next.js app/service | Node.js >= 22 | No | +## Runnable Examples Coverage + +| Repository | `examples/` directory | Fastest demo script | +|---|---|---| +| `agent-fetch` | Yes | `examples/zbd-agent-fetch.mjs` | +| `agent-pay` | Yes | `examples/http-server.mjs` | +| `agent-wallet` | No | Use `zbdw fetch` against `agent-pay` example | +| `agent-wallet-dashboard` | No | Use `sample-data/` quick demo | +| `zbd-ai` | No | Use `POST /api/register` smoke test | + ## Workspace Helpers At the top-level agents workspace, these scripts are useful for full-suite verification: From 803c5d72a2a124cc8eab58a12d4ec5997eb41ae1 Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Thu, 26 Feb 2026 08:07:53 -0800 Subject: [PATCH 5/7] docs(agents): remove localhost-specific example endpoints --- agents/agent-fetch.mdx | 4 ++-- agents/agent-pay.mdx | 2 +- agents/agent-wallet-dashboard.mdx | 2 +- agents/quickstart.mdx | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/agents/agent-fetch.mdx b/agents/agent-fetch.mdx index ddf60e5..9eb7244 100644 --- a/agents/agent-fetch.mdx +++ b/agents/agent-fetch.mdx @@ -126,13 +126,13 @@ From the agents workspace, run: ```bash npm --prefix agent-fetch run build -PROTECTED_URL="http://localhost:8787/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd +PROTECTED_URL="https://api.example.com/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd ``` If you already have an authorization token: ```bash -PROTECTED_URL="http://localhost:8787/protected" L402_AUTHORIZATION="L402 :" npm --prefix agent-fetch run example:proof +PROTECTED_URL="https://api.example.com/protected" L402_AUTHORIZATION="L402 :" npm --prefix agent-fetch run example:proof ``` diff --git a/agents/agent-pay.mdx b/agents/agent-pay.mdx index 9362f59..52b11ed 100644 --- a/agents/agent-pay.mdx +++ b/agents/agent-pay.mdx @@ -149,7 +149,7 @@ ZBD_PAY_DEBUG=1 ZBD_API_KEY= npm --prefix agent-pay run example:ht Then hit the route with your wallet CLI: ```bash -zbdw fetch "http://localhost:8787/protected" --max-sats 100 +zbdw fetch "https://api.example.com/protected" --max-sats 100 ``` ## Storage diff --git a/agents/agent-wallet-dashboard.mdx b/agents/agent-wallet-dashboard.mdx index d68a974..d6cae98 100644 --- a/agents/agent-wallet-dashboard.mdx +++ b/agents/agent-wallet-dashboard.mdx @@ -21,7 +21,7 @@ npm install npm run dev ``` -Open `http://localhost:3113`. +Open the URL printed by the Next.js dev server. ## Environment Variables diff --git a/agents/quickstart.mdx b/agents/quickstart.mdx index 977425f..effe1e2 100644 --- a/agents/quickstart.mdx +++ b/agents/quickstart.mdx @@ -87,7 +87,7 @@ Then in another terminal: ```bash npm --prefix agent-fetch run build -PROTECTED_URL="http://localhost:8787/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd +PROTECTED_URL="https://api.example.com/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd ``` ## 5) Add a Paid Route with agent-pay @@ -114,7 +114,7 @@ import { agentFetch, FileTokenCache } from "@zbdpay/agent-fetch"; const tokenCache = new FileTokenCache(`${process.env.HOME}/.zbd-wallet/token-cache.json`); -const response = await agentFetch("https://localhost:3000/premium", { +const response = await agentFetch("https://api.example.com/premium", { tokenCache, maxPaymentSats: 100, pay: async (challenge) => { From 112d1601f08b9a1d3f4b5cdc0e5c3377a7dee977 Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Thu, 26 Feb 2026 08:07:53 -0800 Subject: [PATCH 6/7] docs(agents): add paylink commands to wallet docs --- agents/agent-wallet.mdx | 14 +++++++++++++- agents/skills.mdx | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/agents/agent-wallet.mdx b/agents/agent-wallet.mdx index fd54df3..c6da70e 100644 --- a/agents/agent-wallet.mdx +++ b/agents/agent-wallet.mdx @@ -51,6 +51,11 @@ zbdw send zbdw payments zbdw payment +zbdw paylink create +zbdw paylink get +zbdw paylink list +zbdw paylink cancel + zbdw withdraw create zbdw withdraw status @@ -85,14 +90,21 @@ Common success examples: {"balance_sats":50000} {"payment_id":"pay_123","fee_sats":1,"status":"completed"} {"status":200,"body":{},"payment_id":"pay_123","amount_paid_sats":21} +{"id":"pl_001","url":"https://zbd.ai/paylinks/pl_001","status":"active","lifecycle":"active","amount_sats":250} ``` + + Paylink lifecycle values: `created | active | paid | expired | dead`. Terminal states (`paid`, `expired`, `dead`) are permanent. + `zbdw paylink get` also syncs the latest payment attempt to local `payments.json`. + + ## Storage Layout ```text ~/.zbd-wallet/ config.json - payments.json + payments.json # includes paylink settlement records with paylink_id, paylink_lifecycle + paylinks.json # local paylink index (ZBD_WALLET_PAYLINKS to override) token-cache.json ``` diff --git a/agents/skills.mdx b/agents/skills.mdx index d7cca52..3594fa4 100644 --- a/agents/skills.mdx +++ b/agents/skills.mdx @@ -46,6 +46,7 @@ npx skills add ./agent-wallet/skills/zbdw - `zbdw init`, `info`, `balance` - `zbdw receive`, `send`, `payments`, `payment` + - `zbdw paylink create|get|list|cancel` - `zbdw withdraw create|status` From 70fcd1ee04bd4e0347a8c7f3c0c5f017e710fff4 Mon Sep 17 00:00:00 2001 From: Andre Neves Date: Fri, 27 Feb 2026 16:34:34 -0800 Subject: [PATCH 7/7] docs(agents): add L402 pay-per-call documentation section --- agents.mdx | 3 + agents/l402-client.mdx | 108 +++++++++++++++++++++++++++++ agents/l402-errors.mdx | 58 ++++++++++++++++ agents/l402-server.mdx | 150 +++++++++++++++++++++++++++++++++++++++++ agents/l402-setup.mdx | 83 +++++++++++++++++++++++ agents/l402.mdx | 82 ++++++++++++++++++++++ docs.json | 26 +++++++ 7 files changed, 510 insertions(+) create mode 100644 agents/l402-client.mdx create mode 100644 agents/l402-errors.mdx create mode 100644 agents/l402-server.mdx create mode 100644 agents/l402-setup.mdx create mode 100644 agents/l402.mdx diff --git a/agents.mdx b/agents.mdx index 4f9aaf9..891bc48 100644 --- a/agents.mdx +++ b/agents.mdx @@ -20,6 +20,9 @@ The ZBD Agents toolkit gives you an end-to-end stack for agentic payments: a wal Auto-handle L402 challenges with max payment guardrails and token caching. + + Follow the complete server + client pattern for Lightning-gated API calls. + Use the dashboard to inspect balances, payment history, and local wallet state. diff --git a/agents/l402-client.mdx b/agents/l402-client.mdx new file mode 100644 index 0000000..31d9286 --- /dev/null +++ b/agents/l402-client.mdx @@ -0,0 +1,108 @@ +--- +title: "Call Paid APIs" +description: "Handle 402 challenges and pay invoices automatically with agent-fetch or zbdw fetch." +--- + +Any HTTP client can call an L402-protected endpoint. In practice, `@zbdpay/agent-fetch` gives you the full challenge-pay-retry loop in one function. + +## Programmatic Flow (Node.js) + +```typescript +import { agentFetch, FileTokenCache } from "@zbdpay/agent-fetch"; + +const tokenCache = new FileTokenCache(`${process.env.HOME}/.zbd-wallet/token-cache.json`); + +const response = await agentFetch("https://api.example.com/premium", { + tokenCache, + maxPaymentSats: 100, + pay: async (challenge) => { + const payment = await fetch("https://api.zbdpay.com/v0/payments", { + method: "POST", + headers: { + apikey: process.env.ZBD_API_KEY!, + "content-type": "application/json", + }, + body: JSON.stringify({ + invoice: challenge.invoice, + amount: challenge.amountSats, + }), + }); + + const body = await payment.json(); + + return { + preimage: body?.preimage ?? body?.data?.preimage, + paymentId: body?.id ?? body?.data?.id, + amountPaidSats: challenge.amountSats, + }; + }, +}); + +console.log(response.status, await response.text()); +``` + +## What agentFetch Handles + + + + If a valid token exists for the URL, it retries immediately with authorization proof. + + + Normal endpoints return untouched. + + + Accepts both `L402` and `LSAT`, and both `macaroon` or `token` challenge keys. + + + Builds `Authorization: <scheme> <macaroon>:<preimage>`. + + + Reuses proof until it expires or the server rejects it. + + + +## Manual Primitives (Advanced) + +```typescript +import { requestChallenge, payChallenge, fetchWithProof } from "@zbdpay/agent-fetch"; + +const challenge = requestChallenge({ + status: res.status, + headers: res.headers, + bodyText: await res.text(), +}); + +const paid = await pay(challenge); +const authorization = payChallenge(challenge, paid); + +const retried = await fetchWithProof( + "https://api.example.com/premium", + { method: "GET" }, + authorization, + fetch, +); +``` + +## CLI Flow with zbdw + +`zbdw fetch` uses `agent-fetch` internally: + +```bash +zbdw fetch "https://api.example.com/premium" --max-sats 100 +``` + +Call it a second time to confirm cache reuse: + +```bash +zbdw fetch "https://api.example.com/premium" --max-sats 100 +``` + +When cache is reused, `payment_id` is typically `null` on the second call. + +## Authorization Format + +```http +Authorization: L402 : +``` + +`LSAT` is also accepted as a legacy scheme. diff --git a/agents/l402-errors.mdx b/agents/l402-errors.mdx new file mode 100644 index 0000000..73c7443 --- /dev/null +++ b/agents/l402-errors.mdx @@ -0,0 +1,58 @@ +--- +title: "L402 Error Codes" +description: "Reference for HTTP status and error codes returned by agent-pay middleware." +--- + +All middleware denials return JSON in this shape: + +```json +{ + "error": { + "code": "error_code", + "message": "Human-readable message" + } +} +``` + +## Server Error Reference (`@zbdpay/agent-pay`) + +| HTTP | `error.code` | Meaning | +| --- | --- | --- | +| 402 | `payment_required` | No valid credential provided. Client must pay invoice and retry. | +| 401 | `invalid_credential` | Token signature is invalid or malformed. | +| 401 | `invalid_payment_proof` | Preimage does not match the payment hash. | +| 403 | `resource_mismatch` | Token was issued for a different route. | +| 403 | `amount_mismatch` | Token was issued for a different price. | +| 403 | `token_expired` | Token is past `expiresAt`. | +| 500 | `configuration_error` | Missing middleware configuration (for example `ZBD_API_KEY`). | +| 500 | `pricing_error` | Dynamic pricing function failed. | +| 502 | `invoice_creation_failed` | Upstream invoice creation failed. | + +## Common Client-Side Failures (`@zbdpay/agent-fetch`) + +These are thrown as runtime errors (not structured HTTP middleware errors): + +- `requestChallenge expects a 402 response` +- `Invalid payment challenge` +- `Payment required: sats exceeds limit of sats` +- `Payment response missing preimage and no settlement poller is configured` +- `Payment failed: ` +- `Payment did not settle within ms` + + + For robust clients, catch these errors and map them to retries, budget policies, or user-visible payment actions. + + +## Related Pages + + + + Understand the full L402 protocol flow in the ZBD stack. + + + Implement server-side route protection and challenge issuance. + + + Build clients that solve 402 challenges automatically. + + diff --git a/agents/l402-server.mdx b/agents/l402-server.mdx new file mode 100644 index 0000000..713901b --- /dev/null +++ b/agents/l402-server.mdx @@ -0,0 +1,150 @@ +--- +title: "Protect Routes with agent-pay" +description: "Require Lightning payment on HTTP routes using Express, Hono, or Next.js adapters." +--- + +`@zbdpay/agent-pay` is the server side of the L402 flow. It returns a `402` challenge when proof is missing, then verifies the retry proof before allowing your handler. + +## Basic Usage + + + + ```typescript + import express from "express"; + import { createExpressPaymentMiddleware } from "@zbdpay/agent-pay"; + + const app = express(); + + app.get( + "/premium", + createExpressPaymentMiddleware({ + amount: 100, + apiKey: process.env.ZBD_API_KEY, + }), + (_req, res) => { + res.json({ content: "Premium data" }); + }, + ); + ``` + + + ```typescript + import { Hono } from "hono"; + import { createHonoPaymentMiddleware } from "@zbdpay/agent-pay"; + + const app = new Hono(); + + app.use( + "/premium", + createHonoPaymentMiddleware({ + amount: 100, + apiKey: process.env.ZBD_API_KEY, + }), + ); + ``` + + + ```typescript + import { withPaymentRequired } from "@zbdpay/agent-pay/next"; + + export const GET = withPaymentRequired( + { + amount: 100, + apiKey: process.env.ZBD_API_KEY, + }, + async () => Response.json({ content: "Premium data" }), + ); + ``` + + + +## PaymentConfig + +```typescript +type PaymentConfig = { + amount: number | ((request: RequestLike) => number | Promise); + currency?: "SAT" | "USD"; + apiKey?: string; + tokenStorePath?: string; +}; +``` + +| Field | Description | +| --- | --- | +| `amount` | Fixed sats/cents amount, or a function that computes price from request context | +| `currency` | Pricing unit: `SAT` (default) or `USD` | +| `apiKey` | Optional override for `ZBD_API_KEY` | +| `tokenStorePath` | File path for settled-token cache on server | + +## Dynamic Pricing + +Use a function for request-based pricing: + +```typescript +app.get( + "/premium", + createExpressPaymentMiddleware({ + amount: (req) => { + const url = new URL(req.url, `http://${req.headers.host}`); + const tier = url.searchParams.get("tier"); + return tier === "pro" ? 500 : 100; + }, + currency: "SAT", + apiKey: process.env.ZBD_API_KEY, + }), + (_req, res) => res.json({ premium: true }), +); +``` + +`agent-pay` evaluates pricing at challenge time and verification time. If the token amount no longer matches current route price, it returns `amount_mismatch`. + +## Fiat Pricing + +If you prefer cent-based pricing: + +```typescript +createExpressPaymentMiddleware({ + amount: 50, + currency: "USD", + apiKey: process.env.ZBD_API_KEY, +}); +``` + +`50` with `USD` means $0.50 (50 cents). The upstream charge is still settled over Lightning. + +## Token Lifetime + +Challenge responses include `expiresAt`. This value is tied to charge expiry from the payment provider. + + + Unlike some SDKs, `agent-pay` does not currently expose an explicit `expirySeconds` field in `PaymentConfig`. + + +## 402 Challenge Shape + +```http +WWW-Authenticate: L402 macaroon="", invoice="" +``` + +```json +{ + "error": { + "code": "payment_required", + "message": "Payment required" + }, + "macaroon": "", + "invoice": "", + "paymentHash": "", + "amountSats": 100, + "expiresAt": 1735766400 +} +``` + + + + Use agent-fetch or zbdw to solve challenges and retry automatically. + + + Review all status codes and middleware error semantics. + + diff --git a/agents/l402-setup.mdx b/agents/l402-setup.mdx new file mode 100644 index 0000000..9ff7a50 --- /dev/null +++ b/agents/l402-setup.mdx @@ -0,0 +1,83 @@ +--- +title: "L402 Setup" +description: "Install and configure the ZBD pay-per-call stack with agent-pay, agent-fetch, and agent-wallet." +--- + +Use this page to stand up the full pay-per-call flow quickly. + +## 1) Install Packages + + + + ```bash + npm install @zbdpay/agent-pay + ``` + + + ```bash + npm install @zbdpay/agent-fetch + ``` + + + ```bash + npm install -g @zbdpay/agent-wallet + ``` + + + +## 2) Configure Environment + +| Variable | Required | Default | Used By | +| --- | --- | --- | --- | +| `ZBD_API_KEY` | Yes | none | `agent-pay`, `agent-fetch` example, `zbdw` | +| `ZBD_API_BASE_URL` | No | `https://api.zbdpay.com` | `agent-pay`, `agent-wallet` | +| `ZBD_WALLET_TOKEN_CACHE` | No | `~/.zbd-wallet/token-cache.json` | `zbdw fetch` | + + + `agent-pay` can also take `apiKey` directly in `PaymentConfig`. If omitted, it falls back to `ZBD_API_KEY`. + + +## 3) Initialize Wallet Identity (Optional but Recommended) + +```bash +zbdw init --key +zbdw info +zbdw balance +``` + +## 4) Run the End-to-End Local Demo + +From `/Users/andreneves/Code/zbd/agents`: + +```bash +npm --prefix agent-pay run build +ZBD_API_KEY= npm --prefix agent-pay run example:http-server +``` + +In a second terminal: + +```bash +npm --prefix agent-fetch run build +PROTECTED_URL="http://localhost:8787/protected" ZBD_API_KEY= npm --prefix agent-fetch run example:zbd +``` + +Or use wallet CLI directly: + +```bash +zbdw fetch "http://localhost:8787/protected" --max-sats 100 +``` + +## 5) Understand Package Roles + +- `@zbdpay/agent-pay`: generates invoice challenge + verifies payment proof on incoming requests. +- `@zbdpay/agent-fetch`: handles `402` parsing, invoice payment hook, retry with proof, and token caching. +- `@zbdpay/agent-wallet`: CLI workflows (`zbdw`) including `zbdw fetch` powered by `agent-fetch`. + + + + Add L402 middleware in Express, Hono, and Next.js. + + + Implement automatic challenge payment and retry. + + diff --git a/agents/l402.mdx b/agents/l402.mdx new file mode 100644 index 0000000..0562902 --- /dev/null +++ b/agents/l402.mdx @@ -0,0 +1,82 @@ +--- +title: "Pay Per Call (L402)" +description: "Monetize any HTTP route with Lightning payments using the L402 challenge and proof flow." +--- + +Gate any API route behind a Lightning payment. Clients request a resource, receive a `402` challenge, pay the invoice, then retry with an `Authorization` proof. + +This section documents the ZBD implementation using: + +- `@zbdpay/agent-pay` (server-side route protection) +- `@zbdpay/agent-fetch` (client-side challenge payment and retry) +- `@zbdpay/agent-wallet` (`zbdw fetch` for CLI-based paid requests) + + + The canonical scheme is `L402`. Legacy `LSAT` is still accepted for backwards compatibility. + + +## How It Works + +```mermaid +sequenceDiagram + participant C as Client + participant S as Protected API + participant L as Lightning + + C->>S: GET /premium + S-->>C: 402 + invoice + macaroon + C->>L: pay invoice + L-->>C: preimage + C->>S: GET /premium
Authorization: L402 macaroon:preimage + S->>S: verify token, path, amount, expiry, settlement + S-->>C: 200 OK + data +``` + + + + + + + + + +## Wire Format + +`agent-pay` returns a challenge header like: + +```http +WWW-Authenticate: L402 macaroon="", invoice="" +``` + +And a JSON body with these fields: + +```json +{ + "error": { + "code": "payment_required", + "message": "Payment required" + }, + "macaroon": "", + "invoice": "", + "paymentHash": "", + "amountSats": 21, + "expiresAt": 1735766400 +} +``` + +## What To Read Next + + + + Install packages, configure environment variables, and run a local paid-route demo. + + + Add payment gates to Express, Hono, and Next.js with `@zbdpay/agent-pay`. + + + Use `agentFetch` or `zbdw fetch` to solve 402 challenges automatically. + + + Understand every L402-related error code returned by the middleware. + + diff --git a/docs.json b/docs.json index 16af032..e3e97a5 100644 --- a/docs.json +++ b/docs.json @@ -284,6 +284,32 @@ ] } ] + }, + { + "anchor": "Pay Per Call (L402)", + "icon": "lock", + "pages": [ + { + "group": "Overview", + "pages": [ + "agents/l402", + "agents/l402-setup" + ] + }, + { + "group": "Server Integration", + "pages": [ + "agents/l402-server", + "agents/l402-errors" + ] + }, + { + "group": "Client Integration", + "pages": [ + "agents/l402-client" + ] + } + ] } ] },