> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boltzpay.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK API

> Complete API reference for @boltzpay/sdk.

Complete API reference for the `@boltzpay/sdk` package. Every public class, method, type, and error is documented here with exact TypeScript signatures.

## Installation

```bash theme={null}
npm install @boltzpay/sdk
```

***

## BoltzPay class

The main entry point. Instantiate once and reuse across requests.

### Constructor

```ts theme={null}
import { BoltzPay } from '@boltzpay/sdk';

const sdk = new BoltzPay(config: BoltzPayConfig);
```

See [BoltzPayConfig](#boltzpayconfig) for the full configuration type.

<Tip>
  Coinbase credentials are optional at construction time. Read-only methods (`quote`, `getBudget`, `getHistory`, `getCapabilities`, `discover`) work without them. Payment methods (`fetch`) require credentials and will throw at execution time if missing.
</Tip>

### Methods

#### `fetch(url, options?)`

Fetch data from a paid API endpoint. Automatically detects the payment protocol, pays the required amount, and returns the response. If no payment protocol is detected, the request passes through as a normal fetch. Concurrent calls are serialized internally to prevent double-spend.

```ts theme={null}
async fetch(url: string, options?: FetchOptions): Promise<BoltzPayResponse>
```

| Parameter | Type                            | Required | Description                                               |
| --------- | ------------------------------- | -------- | --------------------------------------------------------- |
| `url`     | `string`                        | Yes      | URL of the paid API endpoint                              |
| `options` | [`FetchOptions`](#fetchoptions) | No       | Request options (method, headers, body, maxAmount, chain) |

**Returns:** [`BoltzPayResponse`](#boltzpayresponse)

**Throws:** [`ProtocolError`](#protocolerror), [`BudgetExceededError`](#budgetexceedederror), [`NetworkError`](#networkerror)

```ts theme={null}
const response = await sdk.fetch('https://invy.bot/api');
const data = await response.json();
console.log(data);
console.log(response.payment); // { protocol: 'x402', amount: Money, ... }
```

***

#### `quote(url)`

Check the cost of a paid endpoint without paying. Probes the URL and returns pricing information.

```ts theme={null}
async quote(url: string): Promise<QuoteResult>
```

| Parameter | Type     | Required | Description              |
| --------- | -------- | -------- | ------------------------ |
| `url`     | `string` | Yes      | URL of the paid endpoint |

**Returns:** [`QuoteResult`](#quoteresult)

**Throws:** [`ProtocolError`](#protocolerror) with code `protocol_detection_failed` if the endpoint is free.

```ts theme={null}
const quote = await sdk.quote('https://invy.bot/api');
console.log(quote.amount.toDisplayString()); // "$0.05"
console.log(quote.protocol);                 // "x402"
```

***

#### `getBudget()`

Get the current budget state, including limits, spending, and remaining amounts.

```ts theme={null}
getBudget(): BudgetState
```

**Returns:** [`BudgetState`](#budgetstate)

```ts theme={null}
const budget = sdk.getBudget();
console.log(budget.dailySpent.toDisplayString());     // "$1.25"
console.log(budget.dailyRemaining?.toDisplayString()); // "$8.75"
```

***

#### `resetDailyBudget()`

Reset the daily spending counter to zero. Call this at the start of each day if you manage budget resets manually.

```ts theme={null}
resetDailyBudget(): void
```

***

#### `getHistory()`

Get all payment records. When persistence is enabled, history survives restarts (stored as `history.jsonl`, last 500 entries by default).

```ts theme={null}
getHistory(): readonly PaymentRecord[]
```

**Returns:** Array of [`PaymentRecord`](#paymentrecord), ordered chronologically.

***

#### `getMetrics()`

Compute aggregate metrics from payment history.

```ts theme={null}
getMetrics(): PaymentMetrics
```

**Returns:** [`PaymentMetrics`](#paymentmetrics)

```ts theme={null}
const metrics = sdk.getMetrics();
console.log(metrics.totalSpent.toDisplayString()); // "$4.25"
console.log(metrics.successCount);                  // 12
console.log(metrics.errorRate);                      // 0.08
console.log(metrics.avgLatencyMs);                   // 342
```

***

#### `exportHistory(format)`

Export payment history as CSV or JSON string.

```ts theme={null}
exportHistory(format: "csv" | "json"): string
```

| Parameter | Type              | Required | Description   |
| --------- | ----------------- | -------- | ------------- |
| `format`  | `"csv" \| "json"` | Yes      | Export format |

```ts theme={null}
const csv = sdk.exportHistory("csv");
const json = sdk.exportHistory("json");
```

***

#### `getCapabilities()`

Return the configured network, supported protocols, payment readiness, chain namespaces, and cached wallet addresses.

```ts theme={null}
getCapabilities(): {
  network: string;
  protocols: string[];
  canPay: boolean;
  canPayLightning: boolean;
  chains: ChainNamespace[];
  addresses: { evm?: string; svm?: string };
}
```

| Field             | Type                             | Description                                         |
| ----------------- | -------------------------------- | --------------------------------------------------- |
| `network`         | `string`                         | `"base"` or `"base-sepolia"`                        |
| `protocols`       | `string[]`                       | `["x402"]` or `["x402", "l402"]`                    |
| `canPay`          | `boolean`                        | `true` if Coinbase credentials are configured       |
| `canPayLightning` | `boolean`                        | `true` if NWC connection string is configured       |
| `chains`          | `ChainNamespace[]`               | `["evm", "svm"]`                                    |
| `addresses`       | `{ evm?: string; svm?: string }` | Cached wallet addresses (populated after first use) |

***

#### `getBalances()`

Query USDC balance per chain from the wallet manager. Degrades gracefully: returns an empty object if credentials are missing or the query fails.

```ts theme={null}
async getBalances(): Promise<{
  evm?: { address: string; balance: Money | undefined };
  svm?: { address: string; balance: Money | undefined };
}>
```

***

#### `getWalletStatus()`

Comprehensive wallet health check. Probes Coinbase CDP connectivity, fetches on-chain balances, checks Lightning (NWC) wallet connectivity and balance, and reports credential and budget status. This is the only method that actively tests connections — other methods use cached data.

```ts theme={null}
async getWalletStatus(): Promise<WalletStatus>
```

**Returns:** [`WalletStatus`](#walletstatus-1)

```ts theme={null}
const status = await sdk.getWalletStatus();
console.log(status.connection.status); // "connected"
console.log(status.canPay);           // true
if (status.lightning?.balance) {
  console.log(status.lightning.balance.display); // "4800 sats"
}
```

***

#### `discover(options?)`

Query the BoltzPay registry for paid API endpoints. Returns scored entries with health and protocol metadata. All filtering is server-side.

```ts theme={null}
async discover(options?: DiscoverOptions): Promise<readonly DiscoveredEntry[]>
```

| Parameter | Type                                  | Required | Description                                                                          |
| --------- | ------------------------------------- | -------- | ------------------------------------------------------------------------------------ |
| `options` | [`DiscoverOptions`](#discoveroptions) | No       | Filter by protocol, score, category, query. See [DiscoverOptions](#discoveroptions). |

***

#### `openSession(url, options?)`

Opens a streaming MPP session with a payment channel. Requires a Tempo wallet.

```ts theme={null}
async openSession(url: string, options?: BoltzPaySessionOptions): Promise<BoltzPaySession>
```

| Parameter | Type                                                | Required | Description             |
| --------- | --------------------------------------------------- | -------- | ----------------------- |
| `url`     | `string`                                            | Yes      | URL of the MPP endpoint |
| `options` | [`BoltzPaySessionOptions`](#boltzpaysessionoptions) | No       | Session options         |

**Returns:** [`BoltzPaySession`](#boltzpaysession)

**Throws:** [`ProtocolError`](#protocolerror), `MppSessionBudgetError`, [`ConfigurationError`](#configurationerror)

```ts theme={null}
const session = await sdk.openSession("https://api.example.com/stream", {
  maxDeposit: "2.00",
});

for await (const event of session.stream("https://api.example.com/stream")) {
  if (event.type === "data") console.log(event.payload);
}

const receipt = await session.close();
```

***

#### `wrapMcpClient(client)`

Wraps a standard MCP Client with automatic MPP payment handling for -32042 errors. Requires at least one MPP wallet (tempo or stripe-mpp).

```ts theme={null}
wrapMcpClient(client: McpClientLike): WrappedMcpClient
```

| Parameter | Type            | Required | Description                         |
| --------- | --------------- | -------- | ----------------------------------- |
| `client`  | `McpClientLike` | Yes      | MCP Client with `callTool()` method |

**Returns:** [`WrappedMcpClient`](#wrappedmcpclient)

**Throws:** [`ConfigurationError`](#configurationerror) if no MPP wallet is configured

```ts theme={null}
const wrapped = sdk.wrapMcpClient(mcpClient);
const result = await wrapped.callTool({ name: "tool", arguments: { q: "data" } });
if (result.receipt) {
  console.log(`Paid via ${result.receipt.method}`);
}
```

***

#### `diagnose(url)`

Run a full diagnostic on any API endpoint in under 2 seconds. Checks DNS resolution, HTTP reachability (GET and POST), protocol detection (x402/L402), format version, pricing, and latency. No credentials required.

```ts theme={null}
async diagnose(url: string): Promise<DiagnoseResult>
```

| Parameter | Type     | Required | Description                     |
| --------- | -------- | -------- | ------------------------------- |
| `url`     | `string` | Yes      | URL of the endpoint to diagnose |

**Returns:** `DiagnoseResult` with `url`, `dns`, `get`, `post`, `protocol`, `version`, `price`, `network`, `health` (`"paid"` | `"free_confirmed"` | `"dead"` | `"ambiguous"`), and `totalMs`.

```ts theme={null}
const result = await sdk.diagnose('https://invy.bot/api');
console.log(result.health);   // "paid"
console.log(result.protocol); // "x402"
console.log(result.price);    // "$0.05"
console.log(result.totalMs);  // 257
```

***

#### `close()`

Close open connections (NWC WebSocket, etc.). Call when done using the SDK instance.

```ts theme={null}
close(): void
```

***

#### `on(event, callback)`

Subscribe to SDK events. Returns `this` for chaining.

```ts theme={null}
on<E extends EventName>(event: E, listener: EventListener<E>): this
```

See [BoltzPayEvents](#boltzpayevents) for the complete event map.

***

#### `off(event, callback)`

Unsubscribe from SDK events. Returns `this` for chaining.

```ts theme={null}
off<E extends EventName>(event: E, listener: EventListener<E>): this
```

***

```ts theme={null}
sdk
  .on('payment', (record) => {
    console.log(`Paid ${record.amount.toDisplayString()} via ${record.protocol}`);
  })
  .on('budget:warning', (event) => {
    console.log(`${(event.usage * 100).toFixed(0)}% of ${event.period} budget used`);
  })
  .on('error', (err) => {
    console.error('SDK error:', err.message);
  });
```

***

## Types

### BoltzPayConfig

Configuration object passed to the `BoltzPay` constructor. All fields are optional.

```ts theme={null}
interface BoltzPayConfig {
  coinbaseApiKeyId?: string;
  coinbaseApiKeySecret?: string;
  coinbaseWalletSecret?: string;
  nwcConnectionString?: string;      // Must start with "nostr+walletconnect://"
  network?: "base" | "base-sepolia"; // Default: "base"
  preferredChains?: ChainNamespace[];
  budget?: BudgetConfig;
  persistence?: {
    enabled?: boolean;                // Default: false
    directory?: string;               // Default: "~/.boltzpay/"
    historyMaxRecords?: number;       // Default: 500
  };
  logLevel?: "debug" | "info" | "warn" | "error" | "silent"; // Default: "warn"
  wallets?: WalletConfig[];
  mppPreferredMethods?: string[];
  registryUrl?: string;                // Default: "https://status.boltzpay.ai"
  sessionMaxDeposit?: string | number;
  storage?: "file" | "memory" | StorageAdapter;
  logFormat?: "text" | "json";         // Default: "text"
  maxAmountPerRequest?: string | number;
  allowlist?: string[];
  blocklist?: string[];
  retry?: RetryConfig;
  rateLimit?: RateLimitConfig;
  timeouts?: TimeoutConfig;
}
```

| Field                  | Type                                   | Default                        | Description                                     |
| ---------------------- | -------------------------------------- | ------------------------------ | ----------------------------------------------- |
| `coinbaseApiKeyId`     | `string`                               | —                              | Coinbase CDP API key ID                         |
| `coinbaseApiKeySecret` | `string`                               | —                              | Coinbase CDP API key secret                     |
| `coinbaseWalletSecret` | `string`                               | —                              | Coinbase CDP wallet secret                      |
| `nwcConnectionString`  | `string`                               | —                              | NWC connection string (enables L402 protocol)   |
| `network`              | `"base" \| "base-sepolia"`             | `"base"`                       | Blockchain network                              |
| `preferredChains`      | `ChainNamespace[]`                     | —                              | Preferred chain order for multi-chain endpoints |
| `budget`               | `BudgetConfig`                         | —                              | Spending limits                                 |
| `persistence`          | `PersistenceConfig`                    | —                              | Enable history and budget persistence to disk   |
| `logLevel`             | `string`                               | `"warn"`                       | Logging verbosity                               |
| `wallets`              | [`WalletConfig[]`](#walletconfig)      | —                              | Wallet configurations for payments              |
| `mppPreferredMethods`  | `string[]`                             | —                              | Preferred MPP payment methods                   |
| `registryUrl`          | `string`                               | `"https://status.boltzpay.ai"` | BoltzPay registry URL                           |
| `sessionMaxDeposit`    | `string \| number`                     | —                              | Default max deposit for MPP sessions            |
| `storage`              | `"file" \| "memory" \| StorageAdapter` | —                              | Storage backend for persistence                 |
| `logFormat`            | `"text" \| "json"`                     | `"text"`                       | Log output format                               |
| `maxAmountPerRequest`  | `string \| number`                     | —                              | Global per-request spending cap                 |
| `allowlist`            | `string[]`                             | —                              | Only allow payments to these URLs               |
| `blocklist`            | `string[]`                             | —                              | Block payments to these URLs                    |
| `retry`                | `RetryConfig`                          | —                              | Retry configuration for failed requests         |
| `rateLimit`            | `RateLimitConfig`                      | —                              | Rate limiting configuration                     |
| `timeouts`             | `TimeoutConfig`                        | —                              | Timeout configuration                           |

### BudgetConfig

```ts theme={null}
interface BudgetConfig {
  daily?: string | number;            // e.g. "10.00" or 10
  monthly?: string | number;
  perTransaction?: string | number;
  warningThreshold?: number;          // 0..1, default: 0.8
  satToUsdRate?: number;              // Default: 0.001 (~$100K/BTC)
}
```

Budget amounts accept both string (`"10.50"`) and number (`10.50`) for convenience. Strings must match the pattern `^\d+(\.\d{1,2})?$`. The `warningThreshold` controls when the `budget:warning` event fires (e.g. `0.8` = 80% of the limit).

The `satToUsdRate` converts L402 satoshi payments to USD for budget accounting. At the default rate of `0.001` (1 sat = $0.001, ~$100K/BTC), a 100-sat payment counts as \$0.10 in the budget.

***

### WalletConfig

```ts theme={null}
type WalletConfig =
  | { type: "coinbase"; name: string; coinbaseApiKeyId: string; coinbaseApiKeySecret: string; coinbaseWalletSecret: string; networks?: string[] }
  | { type: "nwc"; name: string; nwcConnectionString: string; networks?: string[] }
  | { type: "tempo"; name: string; tempoPrivateKey: string; networks?: string[] }
  | { type: "stripe-mpp"; name: string; stripeSecretKey: string; networks?: string[] }
  | { type: "visa-mpp"; name: string; visaJwe: string; networks?: string[] };
```

| Type           | Required Fields                                                            | Description                            |
| -------------- | -------------------------------------------------------------------------- | -------------------------------------- |
| `"coinbase"`   | `name`, `coinbaseApiKeyId`, `coinbaseApiKeySecret`, `coinbaseWalletSecret` | Coinbase CDP wallet for x402 payments  |
| `"nwc"`        | `name`, `nwcConnectionString`                                              | Nostr Wallet Connect for L402 payments |
| `"tempo"`      | `name`, `tempoPrivateKey`                                                  | Tempo wallet for MPP sessions          |
| `"stripe-mpp"` | `name`, `stripeSecretKey`                                                  | Stripe MPP wallet                      |
| `"visa-mpp"`   | `name`, `visaJwe`                                                          | Visa MPP wallet                        |

All wallet types accept an optional `networks` array to restrict which networks they can be used on.

***

### FetchOptions

```ts theme={null}
interface FetchOptions {
  maxAmount?: number | string;
  headers?: Record<string, string>;
  method?: string;                    // Default: "GET"
  body?: Uint8Array;
  chain?: ChainNamespace;
  dryRun?: boolean;                   // Default: false
}
```

| Field       | Type                     | Description                                                                                                                                                                            |
| ----------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `maxAmount` | `number \| string`       | Maximum amount in dollars (e.g. `1` or `"1.00"`). Throws `BudgetExceededError` with code `per_transaction_exceeded` if the price exceeds this. Prefer strings to avoid float rounding. |
| `headers`   | `Record<string, string>` | Additional HTTP headers sent with the request.                                                                                                                                         |
| `method`    | `string`                 | HTTP method. Defaults to `"GET"`.                                                                                                                                                      |
| `body`      | `Uint8Array`             | Request body as raw bytes.                                                                                                                                                             |
| `chain`     | `ChainNamespace`         | Override chain selection for this request. Takes priority over `preferredChains` in config.                                                                                            |
| `dryRun`    | `boolean`                | Simulate the payment flow without spending. Returns a [`DryRunResult`](#dryrunresult) instead of `BoltzPayResponse`.                                                                   |

***

### BoltzPayResponse

Returned by `fetch()`. Wraps the HTTP response with payment metadata.

```ts theme={null}
class BoltzPayResponse {
  readonly ok: boolean;
  readonly status: number;
  readonly headers: Record<string, string>;
  readonly payment: PaymentDetails | undefined;
  readonly protocol: string | undefined;

  async json<T = unknown>(): Promise<T>;
  async text(): Promise<string>;
  get body(): ReadableStream<Uint8Array> | null;
}
```

| Field / Method | Type                                 | Description                                                 |
| -------------- | ------------------------------------ | ----------------------------------------------------------- |
| `ok`           | `boolean`                            | `true` if status is 200-299                                 |
| `status`       | `number`                             | HTTP status code                                            |
| `headers`      | `Record<string, string>`             | Response headers                                            |
| `payment`      | `PaymentDetails \| undefined`        | Payment metadata, or `undefined` for free endpoints         |
| `protocol`     | `string \| undefined`                | Protocol used (`"x402"`, `"l402"`, `"mpp"`, or `undefined`) |
| `json<T>()`    | `Promise<T>`                         | Parse body as JSON                                          |
| `text()`       | `Promise<string>`                    | Decode body as UTF-8 string                                 |
| `body`         | `ReadableStream<Uint8Array> \| null` | Raw body as a ReadableStream                                |

***

### QuoteResult

Returned by `quote()`.

```ts theme={null}
interface QuoteResult {
  amount: Money;
  protocol: string;
  network: string | undefined;
  allAccepts?: readonly AcceptOption[];
  inputHints?: EndpointInputHints;
}
```

| Field        | Type                      | Description                                         |
| ------------ | ------------------------- | --------------------------------------------------- |
| `amount`     | `Money`                   | Price of the endpoint                               |
| `protocol`   | `string`                  | Detected protocol (`"x402"` or `"l402"`)            |
| `network`    | `string \| undefined`     | CAIP-2 network identifier (e.g. `"eip155:8453"`)    |
| `allAccepts` | `readonly AcceptOption[]` | All available payment options (multi-chain)         |
| `inputHints` | `EndpointInputHints`      | Hints about expected parameters (from 402 metadata) |

***

### PaymentDetails

Attached to `BoltzPayResponse.payment` after a successful payment.

```ts theme={null}
interface PaymentDetails {
  readonly protocol: string;
  readonly amount: Money;
  readonly url: string;
  readonly timestamp: Date;
  readonly txHash: string | undefined;
}
```

***

### PaymentRecord

Stored in payment history. Extends `PaymentDetails` with additional fields.

```ts theme={null}
interface PaymentRecord {
  readonly id: string;                // UUID
  readonly url: string;
  readonly protocol: string;
  readonly amount: Money;
  readonly timestamp: Date;
  readonly txHash: string | undefined;
  readonly network: string | undefined;
  readonly durationMs?: number;       // Payment round-trip time
  readonly sessionId?: string;        // Session ID for session payments
  readonly sessionStatus?: string;    // "open" | "closed"
  readonly transport?: string;        // "mcp" for MCP transport payments
}
```

***

### PaymentMetrics

Returned by `getMetrics()`.

```ts theme={null}
interface PaymentMetrics {
  readonly totalSpent: Money;
  readonly callCount: number;
  readonly successCount: number;
  readonly errorCount: number;
  readonly errorRate: number;         // 0..1 ratio
  readonly avgLatencyMs: number;
  readonly lastPaymentAt: Date | undefined;
}
```

| Field           | Type                | Description                              |
| --------------- | ------------------- | ---------------------------------------- |
| `totalSpent`    | `Money`             | Sum of all successful payments           |
| `callCount`     | `number`            | Total calls (successes + errors)         |
| `successCount`  | `number`            | Successful payments                      |
| `errorCount`    | `number`            | Failed payment attempts                  |
| `errorRate`     | `number`            | `errorCount / callCount` (0 if no calls) |
| `avgLatencyMs`  | `number`            | Average payment round-trip time in ms    |
| `lastPaymentAt` | `Date \| undefined` | Timestamp of most recent payment         |

***

### DryRunResult

Returned by `fetch()` when `dryRun: true`. Simulates the full payment flow without spending.

```ts theme={null}
interface DryRunResult {
  readonly wouldPay: boolean;
  readonly reason?: DryRunFailureReason;
  readonly quote?: {
    readonly amount: Money;
    readonly protocol: string;
    readonly network: string | undefined;
    readonly scheme: string;
  };
  readonly budgetCheck?: {
    readonly allowed: boolean;
    readonly dailyRemaining: Money | undefined;
    readonly monthlyRemaining: Money | undefined;
    readonly wouldExceed: "daily" | "monthly" | "per_transaction" | null;
  };
  readonly wallet?: {
    readonly name: string;
    readonly type: string;  // "coinbase", "nwc", "tempo", "stripe-mpp", "visa-mpp"
  };
  readonly endpoint?: {
    readonly health: EndpointHealth;
    readonly formatVersion: string;
  };
}
```

| Field         | Type      | Description                                                                                |
| ------------- | --------- | ------------------------------------------------------------------------------------------ |
| `wouldPay`    | `boolean` | `true` if payment would succeed                                                            |
| `reason`      | `string`  | Why payment would fail (e.g. `"budget_exceeded"`, `"not_paid"`, `"no_wallet_for_network"`) |
| `quote`       | `object`  | Detected price and protocol info                                                           |
| `budgetCheck` | `object`  | Budget validation result                                                                   |
| `wallet`      | `object`  | Which wallet would be used                                                                 |
| `endpoint`    | `object`  | Endpoint health and format version                                                         |

```ts theme={null}
const result = await sdk.fetch("https://invy.bot/api", { dryRun: true });
if (result.wouldPay) {
  console.log(result.quote?.amount.toDisplayString()); // "$0.05"
  console.log(result.wallet?.type);                     // "coinbase"
} else {
  console.log(result.reason);                           // "budget_exceeded"
}
```

***

### BudgetState

Returned by `getBudget()`.

```ts theme={null}
interface BudgetState {
  readonly dailySpent: Money;
  readonly monthlySpent: Money;
  readonly dailyLimit: Money | undefined;
  readonly monthlyLimit: Money | undefined;
  readonly perTransactionLimit: Money | undefined;
  readonly dailyRemaining: Money | undefined;
  readonly monthlyRemaining: Money | undefined;
}
```

When no budget is configured, limits and remaining values are `undefined` and spent values are `Money.zero()`.

***

### DiscoverOptions

```ts theme={null}
interface DiscoverOptions {
  readonly protocol?: string;    // "x402", "l402", "mpp"
  readonly minScore?: number;    // 0-100
  readonly category?: string;
  readonly query?: string;       // Free-text search
  readonly limit?: number;       // Default: 200
  readonly offset?: number;      // Pagination offset
  readonly signal?: AbortSignal;
}
```

| Field      | Type          | Default | Description                                              |
| ---------- | ------------- | ------- | -------------------------------------------------------- |
| `protocol` | `string`      | —       | Filter by protocol (`"x402"`, `"l402"`, `"mpp"`)         |
| `minScore` | `number`      | —       | Minimum score threshold (0-100)                          |
| `category` | `string`      | —       | Filter by category (e.g. `"crypto-data"`, `"utilities"`) |
| `query`    | `string`      | —       | Free-text search                                         |
| `limit`    | `number`      | `200`   | Maximum number of results                                |
| `offset`   | `number`      | —       | Pagination offset                                        |
| `signal`   | `AbortSignal` | —       | Abort signal for cancellation                            |

***

### DiscoveredEntry

```ts theme={null}
interface DiscoveredEntry {
  readonly slug: string;
  readonly name: string;
  readonly url: string;
  readonly protocol: string | undefined;
  readonly score: number;       // 0-100
  readonly health: string;      // "healthy", "degraded", "dead"
  readonly category: string;
  readonly isPaid: boolean;
  readonly badge: "new" | "established" | null;
}
```

***

### BoltzPaySession

```ts theme={null}
class BoltzPaySession {
  readonly channelId: string;
  readonly spent: bigint;

  async fetch(url: string, init?: RequestInit): Promise<Response>;
  async *stream(url: string, init?: Record<string, unknown>): AsyncIterable<SessionEvent>;
  async close(): Promise<SessionReceipt>;
}
```

| Method        | Description                                    |
| ------------- | ---------------------------------------------- |
| `fetch(url)`  | Make a single request within the session       |
| `stream(url)` | Stream SSE data with per-voucher micropayments |
| `close()`     | Close the channel and release unused deposit   |

***

### SessionEvent

```ts theme={null}
type SessionEvent =
  | { type: "data"; payload: string }
  | { type: "payment"; voucher: VoucherInfo };
```

***

### VoucherInfo

```ts theme={null}
interface VoucherInfo {
  channelId: string;
  cumulativeAmount: bigint;
  index: number;
}
```

***

### SessionReceipt

```ts theme={null}
interface SessionReceipt {
  channelId: string;
  totalSpent: bigint;
  refunded: bigint;
  voucherCount: number;
}
```

***

### BoltzPaySessionOptions

```ts theme={null}
interface BoltzPaySessionOptions {
  maxDeposit?: number | string;  // Max deposit in USD
  signal?: AbortSignal;
}
```

***

### WrappedMcpClient

```ts theme={null}
interface WrappedMcpClient {
  callTool(
    params: { name: string; arguments?: Record<string, unknown> },
    options?: unknown,
  ): Promise<WrappedCallToolResult>;
}
```

***

### WrappedCallToolResult

```ts theme={null}
interface WrappedCallToolResult {
  content: unknown;
  isError?: boolean;
  _meta?: Record<string, unknown>;
  receipt?: McpPaymentReceipt;
}
```

***

### McpPaymentReceipt

```ts theme={null}
interface McpPaymentReceipt {
  method: string;
  status: string;
  reference: string;
  timestamp: string;
}
```

***

### WalletStatus

Returned by `getWalletStatus()`.

```ts theme={null}
interface WalletStatus {
  readonly network: string;
  readonly isTestnet: boolean;
  readonly protocols: readonly string[];
  readonly canPay: boolean;
  readonly credentials: {
    readonly coinbase: CredentialStatus;
  };
  readonly connection: ConnectionStatus;
  readonly accounts: {
    readonly evm: AccountStatus | undefined;
    readonly svm: AccountStatus | undefined;
  };
  readonly budget: BudgetState;
  readonly lightning?: LightningStatus;
}
```

| Field         | Type               | Description                                              |
| ------------- | ------------------ | -------------------------------------------------------- |
| `network`     | `string`           | `"base"` or `"base-sepolia"`                             |
| `isTestnet`   | `boolean`          | `true` on `"base-sepolia"`                               |
| `protocols`   | `string[]`         | `["x402"]` or `["x402", "l402"]`                         |
| `canPay`      | `boolean`          | `true` if Coinbase credentials are configured            |
| `credentials` | `object`           | Credential configuration status                          |
| `connection`  | `ConnectionStatus` | CDP connection probe result                              |
| `accounts`    | `object`           | EVM and Solana wallet addresses + USDC balances          |
| `budget`      | `BudgetState`      | Current spending state                                   |
| `lightning`   | `LightningStatus`  | Lightning wallet status (only present if NWC configured) |

Where `ConnectionStatus` is:

```ts theme={null}
type ConnectionStatus =
  | { status: "connected"; latencyMs: number }
  | { status: "error"; error: string; latencyMs?: number }
  | { status: "skipped"; reason: string };
```

And `LightningStatus` is:

```ts theme={null}
interface LightningStatus {
  readonly configured: boolean;
  readonly connection: {
    readonly status: "connected" | "error" | "skipped";
    readonly latencyMs?: number;
    readonly error?: string;
  };
  readonly balance?: { readonly sats: bigint; readonly display: string };
}
```

***

### BoltzPayEvents

Event map for the `on()` method.

```ts theme={null}
interface BoltzPayEvents {
  payment: [PaymentRecord];
  "budget:warning": [BudgetWarningEvent];
  "budget:exceeded": [BudgetExceededEvent];
  error: [Error];
  "retry:attempt": [RetryAttemptEvent];
  "retry:exhausted": [RetryExhaustedEvent];
  "payment:uncertain": [PaymentUncertainEvent];
  "protocol:unsupported-scheme": [UnsupportedSchemeEvent];
  "protocol:unsupported-network": [UnsupportedNetworkEvent];
  "wallet:selected": [WalletSelectedEvent];
  "session:open": [SessionOpenEvent];
  "session:voucher": [SessionVoucherEvent];
  "session:close": [SessionCloseEvent];
  "session:error": [SessionErrorEvent];
  "mcp:payment": [McpPaymentEvent];
}
```

| Event               | Payload                                       | When                                                        |
| ------------------- | --------------------------------------------- | ----------------------------------------------------------- |
| `payment`           | [`PaymentRecord`](#paymentrecord)             | After every successful payment                              |
| `budget:warning`    | [`BudgetWarningEvent`](#budgetwarningevent)   | When spending crosses the warning threshold                 |
| `budget:exceeded`   | [`BudgetExceededEvent`](#budgetexceededevent) | When a transaction is rejected for exceeding a budget limit |
| `error`             | `Error`                                       | On any SDK error (protocol, budget, network)                |
| `session:open`      | `SessionOpenEvent`                            | Session opened                                              |
| `session:voucher`   | `SessionVoucherEvent`                         | Voucher received during stream                              |
| `session:close`     | `SessionCloseEvent`                           | Session closed                                              |
| `session:error`     | `SessionErrorEvent`                           | Session error                                               |
| `mcp:payment`       | `McpPaymentEvent`                             | MCP tool payment completed                                  |
| `wallet:selected`   | `WalletSelectedEvent`                         | Wallet chosen for payment                                   |
| `retry:attempt`     | `RetryAttemptEvent`                           | Retry attempt started                                       |
| `retry:exhausted`   | `RetryExhaustedEvent`                         | All retries exhausted                                       |
| `payment:uncertain` | `PaymentUncertainEvent`                       | Payment outcome uncertain                                   |

#### BudgetWarningEvent

```ts theme={null}
interface BudgetWarningEvent {
  readonly spent: Money;
  readonly limit: Money;
  readonly period: "daily" | "monthly";
  readonly usage: number; // 0..1 ratio
}
```

#### BudgetExceededEvent

```ts theme={null}
interface BudgetExceededEvent {
  readonly requested: Money;
  readonly limit: Money;
  readonly period: "daily" | "monthly" | "per_transaction";
}
```

***

## Re-exported types from @boltzpay/core

The SDK re-exports commonly used types so you do not need to install `@boltzpay/core` separately.

### Money

Immutable value object representing a USD amount. Uses `bigint` internally for precision.

```ts theme={null}
import { Money } from '@boltzpay/sdk';
```

| Method                            | Signature                                                        | Description                                                  |
| --------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------ |
| `Money.fromDollars(dollars)`      | `static fromDollars(dollars: string): Money`                     | Parse from dollar string (e.g. `"10.50"` or `"$10.50"`)      |
| `Money.fromCents(cents)`          | `static fromCents(cents: bigint): Money`                         | Create from cent amount as bigint                            |
| `Money.zero()`                    | `static zero(): Money`                                           | Create a zero-value Money                                    |
| `money.cents`                     | `readonly cents: bigint`                                         | Raw cent amount                                              |
| `money.currency`                  | `readonly currency: "USD"`                                       | Always `"USD"`                                               |
| `money.add(other)`                | `add(other: Money): Money`                                       | Addition                                                     |
| `money.subtract(other)`           | `subtract(other: Money): Money`                                  | Subtraction (throws if result would be negative)             |
| `money.multiply(factor)`          | `multiply(factor: bigint): Money`                                | Multiply by integer factor                                   |
| `money.isZero()`                  | `isZero(): boolean`                                              | Check if zero                                                |
| `money.greaterThan(other)`        | `greaterThan(other: Money): boolean`                             | Comparison                                                   |
| `money.greaterThanOrEqual(other)` | `greaterThanOrEqual(other: Money): boolean`                      | Comparison                                                   |
| `money.equals(other)`             | `equals(other: Money): boolean`                                  | Equality check                                               |
| `money.toDisplayString()`         | `toDisplayString(): string`                                      | Format as `"$10.50"`                                         |
| `money.toJSON()`                  | `toJSON(): { cents: string; currency: string; display: string }` | JSON-safe representation (avoids BigInt serialization crash) |

### ChainNamespace

```ts theme={null}
type ChainNamespace = "evm" | "svm";
```

### AcceptOption

A single payment option from a multi-chain endpoint.

```ts theme={null}
interface AcceptOption {
  readonly namespace: ChainNamespace;
  readonly network: string;
  readonly amount: bigint;     // USD cents
  readonly payTo: string;
  readonly asset: string;
  readonly scheme: string;
}
```

### Other re-exports

```ts theme={null}
export type { ProtocolType, WalletInfo } from '@boltzpay/core';
```

***

## Errors

```ts theme={null}
import {
  BoltzPayError,
  BudgetExceededError,
  ConfigurationError,
  InsufficientFundsError,
  NetworkError,
  ProtocolError,
} from '@boltzpay/sdk';
```

<Note>
  The SDK wraps all internal errors. You only need to catch `BoltzPayError` subclasses.
</Note>

### Error hierarchy

All subclasses extend the abstract `BoltzPayError`, which adds `code` and `statusCode` to the native `Error`.

```
BoltzPayError (abstract)
├── BudgetExceededError      429   + requested: Money, limit: Money
├── ConfigurationError       400
├── InsufficientFundsError   402
├── NetworkError             503
└── ProtocolError            502
```

```ts theme={null}
abstract class BoltzPayError extends Error {
  abstract readonly code: string;
  abstract readonly statusCode: number;
}
```

### Error codes

| Code                             | Class                    | When thrown                                              |
| -------------------------------- | ------------------------ | -------------------------------------------------------- |
| `daily_budget_exceeded`          | `BudgetExceededError`    | Payment would exceed daily budget                        |
| `monthly_budget_exceeded`        | `BudgetExceededError`    | Payment would exceed monthly budget                      |
| `per_transaction_exceeded`       | `BudgetExceededError`    | Payment exceeds per-transaction or `maxAmount` limit     |
| `missing_coinbase_credentials`   | `ConfigurationError`     | Coinbase keys required but missing                       |
| `invalid_config`                 | `ConfigurationError`     | Config fails Zod validation                              |
| `insufficient_usdc`              | `InsufficientFundsError` | Not enough USDC in wallet                                |
| `insufficient_lightning_balance` | `InsufficientFundsError` | Not enough Lightning balance                             |
| `network_timeout`                | `NetworkError`           | Request timed out                                        |
| `endpoint_unreachable`           | `NetworkError`           | Endpoint unreachable                                     |
| `blockchain_error`               | `NetworkError`           | Blockchain RPC or transaction error                      |
| `protocol_detection_failed`      | `ProtocolError`          | No payment protocol detected                             |
| `protocol_not_supported`         | `ProtocolError`          | Requested protocol adapter not available                 |
| `payment_failed`                 | `ProtocolError`          | Payment not accepted by server (may include `diagnosis`) |
| `no_compatible_chain`            | `ProtocolError`          | No chain overlap between endpoint and SDK                |
| `x402_payment_failed`            | `ProtocolError`          | x402 payment execution failed                            |
| `x402_quote_failed`              | `ProtocolError`          | x402 quote extraction failed                             |
| `l402_payment_failed`            | `ProtocolError`          | L402 payment execution failed                            |
| `l402_quote_failed`              | `ProtocolError`          | L402 quote extraction failed                             |
| `l402_detection_failed`          | `ProtocolError`          | L402 protocol detection failed                           |
| `l402_credentials_missing`       | `ProtocolError`          | L402 detected but no NWC connection string               |
| `cdp_provisioning_failed`        | `ProtocolError`          | CDP wallet provisioning failed                           |

### Catching errors

#### By class (instanceof)

```ts theme={null}
try {
  const response = await sdk.fetch('https://invy.bot/api');
} catch (error) {
  if (error instanceof BudgetExceededError) {
    console.log(`Budget: ${error.requested.toDisplayString()} exceeds ${error.limit.toDisplayString()}`);
  } else if (error instanceof InsufficientFundsError) {
    console.log('Wallet needs more USDC');
  } else if (error instanceof ConfigurationError) {
    console.log('Check your API keys');
  } else if (error instanceof ProtocolError) {
    console.log(`Protocol error: ${error.code}`);
  } else if (error instanceof NetworkError) {
    console.log('Network issue, retrying...');
  } else if (error instanceof BoltzPayError) {
    console.log(`SDK error [${error.code}]: ${error.message}`);
  } else {
    throw error;
  }
}
```

#### By code (switch)

```ts theme={null}
try {
  await sdk.fetch(url);
} catch (error) {
  if (error instanceof BoltzPayError) {
    switch (error.code) {
      case 'daily_budget_exceeded':
      case 'monthly_budget_exceeded':
        console.log('Budget exhausted — wait for reset');
        break;
      case 'per_transaction_exceeded':
        console.log('This endpoint is too expensive');
        break;
      case 'missing_coinbase_credentials':
        console.log('Configure Coinbase keys to enable payments');
        break;
      case 'insufficient_usdc':
        console.log('Fund your wallet with USDC');
        break;
      default:
        console.log(`${error.code}: ${error.message}`);
    }
  }
}
```

***

## Constants

```ts theme={null}
export const VERSION = "0.3.0";
```
