Skip to main content
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>
ParameterTypeRequiredDescription
urlstringYesURL of the paid API endpoint
optionsFetchOptionsNoRequest 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>
ParameterTypeRequiredDescription
urlstringYesURL 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.
getBudget(): BudgetState
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.
resetDailyBudget(): void

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
ParameterTypeRequiredDescription
format"csv" | "json"YesExport 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 };
}
FieldTypeDescription
networkstring"base" or "base-sepolia"
protocolsstring[]["x402"] or ["x402", "l402"]
canPaybooleantrue if Coinbase credentials are configured
canPayLightningbooleantrue if NWC connection string is configured
chainsChainNamespace[]["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[]>
ParameterTypeRequiredDescription
optionsDiscoverOptionsNoFilter 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>
ParameterTypeRequiredDescription
urlstringYesURL of the MPP endpoint
optionsBoltzPaySessionOptionsNoSession 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
ParameterTypeRequiredDescription
clientMcpClientLikeYesMCP 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>
ParameterTypeRequiredDescription
urlstringYesURL 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.
close(): void

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;
}
FieldTypeDefaultDescription
coinbaseApiKeyIdstringCoinbase CDP API key ID
coinbaseApiKeySecretstringCoinbase CDP API key secret
coinbaseWalletSecretstringCoinbase CDP wallet secret
nwcConnectionStringstringNWC connection string (enables L402 protocol)
network"base" | "base-sepolia""base"Blockchain network
preferredChainsChainNamespace[]Preferred chain order for multi-chain endpoints
budgetBudgetConfigSpending limits
persistencePersistenceConfigEnable history and budget persistence to disk
logLevelstring"warn"Logging verbosity
walletsWalletConfig[]Wallet configurations for payments
mppPreferredMethodsstring[]Preferred MPP payment methods
registryUrlstring"https://status.boltzpay.ai"BoltzPay registry URL
sessionMaxDepositstring | numberDefault max deposit for MPP sessions
storage"file" | "memory" | StorageAdapterStorage backend for persistence
logFormat"text" | "json""text"Log output format
maxAmountPerRequeststring | numberGlobal per-request spending cap
allowliststring[]Only allow payments to these URLs
blockliststring[]Block payments to these URLs
retryRetryConfigRetry configuration for failed requests
rateLimitRateLimitConfigRate limiting configuration
timeoutsTimeoutConfigTimeout 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, 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[] };
TypeRequired FieldsDescription
"coinbase"name, coinbaseApiKeyId, coinbaseApiKeySecret, coinbaseWalletSecretCoinbase CDP wallet for x402 payments
"nwc"name, nwcConnectionStringNostr Wallet Connect for L402 payments
"tempo"name, tempoPrivateKeyTempo wallet for MPP sessions
"stripe-mpp"name, stripeSecretKeyStripe MPP wallet
"visa-mpp"name, visaJweVisa 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
}
FieldTypeDescription
maxAmountnumber | stringMaximum 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.
headersRecord<string, string>Additional HTTP headers sent with the request.
methodstringHTTP method. Defaults to "GET".
bodyUint8ArrayRequest body as raw bytes.
chainChainNamespaceOverride chain selection for this request. Takes priority over preferredChains in config.
dryRunbooleanSimulate 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 / MethodTypeDescription
okbooleantrue if status is 200-299
statusnumberHTTP status code
headersRecord<string, string>Response headers
paymentPaymentDetails | undefinedPayment metadata, or undefined for free endpoints
protocolstring | undefinedProtocol used ("x402", "l402", "mpp", or undefined)
json<T>()Promise<T>Parse body as JSON
text()Promise<string>Decode body as UTF-8 string
bodyReadableStream<Uint8Array> | nullRaw body as a ReadableStream

QuoteResult

Returned by quote().
interface QuoteResult {
  amount: Money;
  protocol: string;
  network: string | undefined;
  allAccepts?: readonly AcceptOption[];
  inputHints?: EndpointInputHints;
}
FieldTypeDescription
amountMoneyPrice of the endpoint
protocolstringDetected protocol ("x402" or "l402")
networkstring | undefinedCAIP-2 network identifier (e.g. "eip155:8453")
allAcceptsreadonly AcceptOption[]All available payment options (multi-chain)
inputHintsEndpointInputHintsHints 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;
}
FieldTypeDescription
totalSpentMoneySum of all successful payments
callCountnumberTotal calls (successes + errors)
successCountnumberSuccessful payments
errorCountnumberFailed payment attempts
errorRatenumbererrorCount / callCount (0 if no calls)
avgLatencyMsnumberAverage payment round-trip time in ms
lastPaymentAtDate | undefinedTimestamp 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;
  };
}
FieldTypeDescription
wouldPaybooleantrue if payment would succeed
reasonstringWhy payment would fail (e.g. "budget_exceeded", "not_paid", "no_wallet_for_network")
quoteobjectDetected price and protocol info
budgetCheckobjectBudget validation result
walletobjectWhich wallet would be used
endpointobjectEndpoint 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;
}
FieldTypeDefaultDescription
protocolstringFilter by protocol ("x402", "l402", "mpp")
minScorenumberMinimum score threshold (0-100)
categorystringFilter by category (e.g. "crypto-data", "utilities")
querystringFree-text search
limitnumber200Maximum number of results
offsetnumberPagination offset
signalAbortSignalAbort 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>;
}
MethodDescription
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>;
}

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;
}
FieldTypeDescription
networkstring"base" or "base-sepolia"
isTestnetbooleantrue on "base-sepolia"
protocolsstring[]["x402"] or ["x402", "l402"]
canPaybooleantrue if Coinbase credentials are configured
credentialsobjectCredential configuration status
connectionConnectionStatusCDP connection probe result
accountsobjectEVM and Solana wallet addresses + USDC balances
budgetBudgetStateCurrent spending state
lightningLightningStatusLightning 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];
}
EventPayloadWhen
paymentPaymentRecordAfter every successful payment
budget:warningBudgetWarningEventWhen spending crosses the warning threshold
budget:exceededBudgetExceededEventWhen a transaction is rejected for exceeding a budget limit
errorErrorOn any SDK error (protocol, budget, network)
session:openSessionOpenEventSession opened
session:voucherSessionVoucherEventVoucher received during stream
session:closeSessionCloseEventSession closed
session:errorSessionErrorEventSession error
mcp:paymentMcpPaymentEventMCP tool payment completed
wallet:selectedWalletSelectedEventWallet chosen for payment
retry:attemptRetryAttemptEventRetry attempt started
retry:exhaustedRetryExhaustedEventAll retries exhausted
payment:uncertainPaymentUncertainEventPayment 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';
MethodSignatureDescription
Money.fromDollars(dollars)static fromDollars(dollars: string): MoneyParse from dollar string (e.g. "10.50" or "$10.50")
Money.fromCents(cents)static fromCents(cents: bigint): MoneyCreate from cent amount as bigint
Money.zero()static zero(): MoneyCreate a zero-value Money
money.centsreadonly cents: bigintRaw cent amount
money.currencyreadonly currency: "USD"Always "USD"
money.add(other)add(other: Money): MoneyAddition
money.subtract(other)subtract(other: Money): MoneySubtraction (throws if result would be negative)
money.multiply(factor)multiply(factor: bigint): MoneyMultiply by integer factor
money.isZero()isZero(): booleanCheck if zero
money.greaterThan(other)greaterThan(other: Money): booleanComparison
money.greaterThanOrEqual(other)greaterThanOrEqual(other: Money): booleanComparison
money.equals(other)equals(other: Money): booleanEquality check
money.toDisplayString()toDisplayString(): stringFormat 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

CodeClassWhen thrown
daily_budget_exceededBudgetExceededErrorPayment would exceed daily budget
monthly_budget_exceededBudgetExceededErrorPayment would exceed monthly budget
per_transaction_exceededBudgetExceededErrorPayment exceeds per-transaction or maxAmount limit
missing_coinbase_credentialsConfigurationErrorCoinbase keys required but missing
invalid_configConfigurationErrorConfig fails Zod validation
insufficient_usdcInsufficientFundsErrorNot enough USDC in wallet
insufficient_lightning_balanceInsufficientFundsErrorNot enough Lightning balance
network_timeoutNetworkErrorRequest timed out
endpoint_unreachableNetworkErrorEndpoint unreachable
blockchain_errorNetworkErrorBlockchain RPC or transaction error
protocol_detection_failedProtocolErrorNo payment protocol detected
protocol_not_supportedProtocolErrorRequested protocol adapter not available
payment_failedProtocolErrorPayment not accepted by server (may include diagnosis)
no_compatible_chainProtocolErrorNo chain overlap between endpoint and SDK
x402_payment_failedProtocolErrorx402 payment execution failed
x402_quote_failedProtocolErrorx402 quote extraction failed
l402_payment_failedProtocolErrorL402 payment execution failed
l402_quote_failedProtocolErrorL402 quote extraction failed
l402_detection_failedProtocolErrorL402 protocol detection failed
l402_credentials_missingProtocolErrorL402 detected but no NWC connection string
cdp_provisioning_failedProtocolErrorCDP 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";