Complete API reference for the @boltzpay/sdk package. Every public class, method, type, and error is documented here with exact TypeScript signatures.
Installation
npm install @boltzpay/sdk
BoltzPay class
The main entry point. Instantiate once and reuse across requests.
Constructor
import { BoltzPay } from '@boltzpay/sdk';
const sdk = new BoltzPay(config: BoltzPayConfig);
See BoltzPayConfig for the full configuration type.
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.
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.
async fetch(url: string, options?: FetchOptions): Promise<BoltzPayResponse>
| Parameter | Type | Required | Description |
|---|
url | string | Yes | URL of the paid API endpoint |
options | FetchOptions | No | Request options (method, headers, body, maxAmount, chain) |
Returns: BoltzPayResponse
Throws: ProtocolError, BudgetExceededError, NetworkError
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.
async quote(url: string): Promise<QuoteResult>
| Parameter | Type | Required | Description |
|---|
url | string | Yes | URL of the paid endpoint |
Returns: QuoteResult
Throws: ProtocolError with code protocol_detection_failed if the endpoint is free.
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.
Returns: BudgetState
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.
getHistory()
Get all payment records. When persistence is enabled, history survives restarts (stored as history.jsonl, last 500 entries by default).
getHistory(): readonly PaymentRecord[]
Returns: Array of PaymentRecord, ordered chronologically.
getMetrics()
Compute aggregate metrics from payment history.
getMetrics(): PaymentMetrics
Returns: PaymentMetrics
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.
exportHistory(format: "csv" | "json"): string
| Parameter | Type | Required | Description |
|---|
format | "csv" | "json" | Yes | Export format |
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.
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.
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.
async getWalletStatus(): Promise<WalletStatus>
Returns: WalletStatus
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.
async discover(options?: DiscoverOptions): Promise<readonly DiscoveredEntry[]>
| Parameter | Type | Required | Description |
|---|
options | DiscoverOptions | No | Filter by protocol, score, category, query. See DiscoverOptions. |
openSession(url, options?)
Opens a streaming MPP session with a payment channel. Requires a Tempo wallet.
async openSession(url: string, options?: BoltzPaySessionOptions): Promise<BoltzPaySession>
| Parameter | Type | Required | Description |
|---|
url | string | Yes | URL of the MPP endpoint |
options | BoltzPaySessionOptions | No | Session options |
Returns: BoltzPaySession
Throws: ProtocolError, MppSessionBudgetError, ConfigurationError
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).
wrapMcpClient(client: McpClientLike): WrappedMcpClient
| Parameter | Type | Required | Description |
|---|
client | McpClientLike | Yes | MCP Client with callTool() method |
Returns: WrappedMcpClient
Throws: ConfigurationError if no MPP wallet is configured
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.
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.
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.
on(event, callback)
Subscribe to SDK events. Returns this for chaining.
on<E extends EventName>(event: E, listener: EventListener<E>): this
See BoltzPayEvents for the complete event map.
off(event, callback)
Unsubscribe from SDK events. Returns this for chaining.
off<E extends EventName>(event: E, listener: EventListener<E>): this
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.
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[] | — | 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
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
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
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 instead of BoltzPayResponse. |
BoltzPayResponse
Returned by fetch(). Wraps the HTTP response with payment metadata.
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().
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.
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.
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().
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.
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 |
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().
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
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
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
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
type SessionEvent =
| { type: "data"; payload: string }
| { type: "payment"; voucher: VoucherInfo };
VoucherInfo
interface VoucherInfo {
channelId: string;
cumulativeAmount: bigint;
index: number;
}
SessionReceipt
interface SessionReceipt {
channelId: string;
totalSpent: bigint;
refunded: bigint;
voucherCount: number;
}
BoltzPaySessionOptions
interface BoltzPaySessionOptions {
maxDeposit?: number | string; // Max deposit in USD
signal?: AbortSignal;
}
WrappedMcpClient
interface WrappedMcpClient {
callTool(
params: { name: string; arguments?: Record<string, unknown> },
options?: unknown,
): Promise<WrappedCallToolResult>;
}
interface WrappedCallToolResult {
content: unknown;
isError?: boolean;
_meta?: Record<string, unknown>;
receipt?: McpPaymentReceipt;
}
McpPaymentReceipt
interface McpPaymentReceipt {
method: string;
status: string;
reference: string;
timestamp: string;
}
WalletStatus
Returned by getWalletStatus().
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:
type ConnectionStatus =
| { status: "connected"; latencyMs: number }
| { status: "error"; error: string; latencyMs?: number }
| { status: "skipped"; reason: string };
And LightningStatus is:
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.
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 | After every successful payment |
budget:warning | BudgetWarningEvent | When spending crosses the warning threshold |
budget:exceeded | 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
interface BudgetWarningEvent {
readonly spent: Money;
readonly limit: Money;
readonly period: "daily" | "monthly";
readonly usage: number; // 0..1 ratio
}
BudgetExceededEvent
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.
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
type ChainNamespace = "evm" | "svm";
AcceptOption
A single payment option from a multi-chain endpoint.
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
export type { ProtocolType, WalletInfo } from '@boltzpay/core';
Errors
import {
BoltzPayError,
BudgetExceededError,
ConfigurationError,
InsufficientFundsError,
NetworkError,
ProtocolError,
} from '@boltzpay/sdk';
The SDK wraps all internal errors. You only need to catch BoltzPayError subclasses.
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
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)
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)
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
export const VERSION = "0.3.0";