@piprail/sdk 1.23.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -5204,6 +5204,22 @@ interface RegisterOptions {
5204
5204
  */
5205
5205
  attribution?: boolean;
5206
5206
  }
5207
+ /**
5208
+ * The read-+-pay surface an agent toolkit needs — the methods {@link paymentTools}
5209
+ * calls. BOTH {@link PipRailClient} (one chain) and {@link MultiChainPayer} (many
5210
+ * chains, one per wallet) satisfy it, so `paymentTools` wraps either unchanged:
5211
+ * point an MCP/LLM at one wallet or at a whole bundle without touching the tools.
5212
+ */
5213
+ interface PayingClient {
5214
+ discover(opts?: DiscoverOptions): Promise<DiscoveredResource[]>;
5215
+ quote(url: string, init?: RequestInit): Promise<PipRailQuote | null>;
5216
+ planPayment(url: string, init?: RequestInit): Promise<PaymentPlan | null>;
5217
+ get(url: string, init?: RequestInit): Promise<Response>;
5218
+ fetch(url: string, init?: RequestInit): Promise<Response>;
5219
+ register(url: string, opts?: RegisterOptions): Promise<RegisterOutcome[]>;
5220
+ spent(): SpendSummary;
5221
+ budget(): SessionBudget;
5222
+ }
5207
5223
  declare class PipRailClient {
5208
5224
  private readonly opts;
5209
5225
  private readonly maxRetries;
@@ -5453,11 +5469,188 @@ declare class PipRailClient {
5453
5469
  * A {@link PipRailClient} is bound to one chain (its wallet); give this one client
5454
5470
  * per chain the agent funds and it runs each client's {@link PipRailClient.planPayment}
5455
5471
  * in parallel and merges the rails into one plan, ranked payable-first. `best` is a
5456
- * payable rail; across different native coins there's no oracle to pick the
5457
- * fiat-cheapest, so the tiebreak is the order `clients` were given (the agent's own
5458
- * chain preference). Returns `null` only if the URL isn't gated for any client.
5472
+ * payable rail. Across different native coins there's no oracle to compare gas costs,
5473
+ * so it does NOT rank chains by fee against each other: `best` is the FIRST chain you
5474
+ * pass in `clients` that can settle (your preference order); within a single chain it
5475
+ * still prefers the cheapest-gas rail. Returns `null` only if the URL isn't gated for
5476
+ * any client. Throws only if EVERY client fails to reach the resource (a total outage),
5477
+ * mirroring a single client — a single chain being down just drops that chain.
5459
5478
  */
5460
5479
  declare function planAcross(clients: PipRailClient[], url: string, init?: RequestInit): Promise<PaymentPlan | null>;
5480
+ /**
5481
+ * PAY across several single-chain clients — the EXECUTION counterpart to
5482
+ * {@link planAcross}. Plans the URL on every client in parallel (keeping which
5483
+ * client owns which rail), picks the rail `planAcross` names as `best` (the first
5484
+ * funded chain you listed that can settle RIGHT NOW), and pays it on its owning
5485
+ * client. So an agent that holds one wallet
5486
+ * per chain pays whichever chain/token the merchant's 402 asks for — with no
5487
+ * manual routing — while every payment still goes through that client's own
5488
+ * spend policy, `onBeforePay` hook, retries, and replay-protection (this just
5489
+ * calls the chosen client's {@link PipRailClient.fetch}).
5490
+ *
5491
+ * - A URL that needs no payment (no 402) is returned straight through.
5492
+ * - When NO funded chain can settle it, throws {@link PaymentDeclinedError} with a
5493
+ * merged, per-chain funding hint — BEFORE any on-chain send.
5494
+ *
5495
+ * Selection matches {@link planAcross}: payable-first, and across different native
5496
+ * coins (no price oracle) the FIRST chain you pass in `clients` that can settle wins
5497
+ * (your preference); within a chain, the cheapest-gas rail. It normally pays the rail
5498
+ * `planAcross` reports as `best`, but on a BEST-EFFORT basis — the owning client
5499
+ * re-reads its balances/gas at pay time, so a change between planning and paying (a
5500
+ * concurrent payment, RPC drift, the merchant returning a different 402) can make it
5501
+ * pick another settleable rail ON THE SAME CHAIN, or decline; its spend policy +
5502
+ * `onBeforePay` still gate whatever is actually paid. For the ergonomic object form,
5503
+ * see {@link MultiChainPayer}.
5504
+ *
5505
+ * NOTE: this PROBES the URL with the caller's `init` (method + body) on each client to
5506
+ * read the 402, so prefer it for GET / idempotent requests — a non-idempotent POST is
5507
+ * sent once per client before the pay leg (the x402 gate returns 402 without acting,
5508
+ * but the body is re-sent).
5509
+ */
5510
+ declare function fetchAcross(clients: PipRailClient[], url: string, init?: RequestInit): Promise<Response>;
5511
+
5512
+ /**
5513
+ * MultiChainPayer — one buyer, many wallets, pay whatever the merchant asks.
5514
+ *
5515
+ * A {@link PipRailClient} is bound to exactly ONE chain and ONE wallet (an EVM key
5516
+ * can't sign a Solana tx, and vice-versa — that's enforced at bind time). So a
5517
+ * buyer who wants to pay a 402 *whatever chain/token it demands* holds one key per
5518
+ * chain. This is the ergonomic object that carries that bundle: give it a
5519
+ * `{ chain → wallet }` map and it builds one client per chain, then exposes a single
5520
+ * `fetch`/`get`/`post`/`plan`/`quote` that auto-routes to the first funded chain that
5521
+ * can settle — no manual "which client owns this rail?" plumbing.
5522
+ *
5523
+ * It is a thin, chain-agnostic composition over the existing primitives — it adds
5524
+ * NO new payment logic:
5525
+ * - `planPayment` → {@link planAcross} (merge every chain's plan, payable-first)
5526
+ * - `fetch`/`get`/`post` → {@link fetchAcross} (pay on the first chain that can settle)
5527
+ * Every payment still runs through its owning client's own spend policy,
5528
+ * `onBeforePay` hook, retries, and replay-protection. There is no cross-chain
5529
+ * custody, no price oracle, and no backend: across chains it pays the FIRST one you
5530
+ * list that can settle (your preference order — gas isn't comparable across coins);
5531
+ * within a chain it picks the cheapest-gas rail.
5532
+ *
5533
+ * Because it implements {@link PayingClient}, the agent toolkit ({@link paymentTools})
5534
+ * and the MCP server wrap it byte-identically to a single client.
5535
+ */
5536
+
5537
+ /**
5538
+ * One wallet per chain you fund, keyed by chain selector. The KEY is a chain
5539
+ * string (an EVM preset like `'base'`/`'bnb'`, or a non-EVM family
5540
+ * `'solana'|'ton'|'tron'|'near'|'sui'|'aptos'|'algorand'|'stellar'|'xrpl'`); the
5541
+ * VALUE is that family's {@link WalletInput}:
5542
+ *
5543
+ * base/bnb/… → { privateKey } solana → { secretKey } ton/algorand → { mnemonic }
5544
+ * stellar → { secret } xrpl → { seed } near → { accountId, privateKey }
5545
+ *
5546
+ * One key per family — this map is how a single buyer carries the keys for every
5547
+ * chain it's willing to pay on. (For a CUSTOM EVM chain configured by a viem
5548
+ * `Chain` object, build the {@link PipRailClient} yourself and use
5549
+ * `new MultiChainPayer([...clients])`.)
5550
+ */
5551
+ interface MultiChainPayerOptions {
5552
+ /** `{ chain → wallet }`. Iteration order is your chain PREFERENCE: across chains the
5553
+ * first one that can settle wins (there's no oracle to compare gas across coins). */
5554
+ wallets: Record<string, WalletInput>;
5555
+ /** Spend policy applied to EVERY chain's client. Each client still keeps its own
5556
+ * per-(network,asset) ledger — there is no cross-token sum (no price oracle). */
5557
+ policy?: PaymentPolicy;
5558
+ /** Per-chain RPC overrides, keyed by the same chain selector as `wallets`. */
5559
+ rpcUrls?: Record<string, string>;
5560
+ /** Which schemes every client may settle. Default `['onchain-proof']` (unchanged). */
5561
+ schemes?: PaymentScheme[];
5562
+ /** Final approval hook applied to every chain's client (fires before any send). */
5563
+ onBeforePay?: (quote: PipRailQuote) => boolean | Promise<boolean>;
5564
+ /** Observability hook applied to every chain's client. */
5565
+ onEvent?: (event: PipRailEvent) => void;
5566
+ /** Retry budget for the post-broadcast leg, per client. Default 3. */
5567
+ maxPaymentRetries?: number;
5568
+ /** Timeout (ms) for the retry leg, per client. Default 30_000. */
5569
+ retryTimeoutMs?: number;
5570
+ }
5571
+ declare class MultiChainPayer implements PayingClient {
5572
+ private readonly _clients;
5573
+ /**
5574
+ * Wrap an explicit, ordered set of single-chain clients — use this when a client
5575
+ * needs full control (e.g. a custom EVM chain configured by a viem `Chain`). The
5576
+ * ORDER is your chain preference: across chains the first that can settle wins. Pass
5577
+ * at MOST one client per chain — two clients on the SAME network would double-count in
5578
+ * `spent()`/`budget()` and waste a plan round-trip (`fromWallets` can't produce this).
5579
+ * For the common case, prefer {@link MultiChainPayer.fromWallets}.
5580
+ */
5581
+ constructor(clients: PipRailClient[]);
5582
+ /**
5583
+ * Build one client per funded chain from a `{ chain → wallet }` map — the
5584
+ * ergonomic path. The shared `policy`/`schemes`/`onBeforePay`/`onEvent` apply to
5585
+ * every client; `rpcUrls` are matched per chain. Iteration order of `wallets` is
5586
+ * the chain preference.
5587
+ *
5588
+ * ```ts
5589
+ * const payer = MultiChainPayer.fromWallets({
5590
+ * wallets: {
5591
+ * base: { privateKey: process.env.EVM_KEY! },
5592
+ * solana: { secretKey: process.env.SOLANA_SECRET! },
5593
+ * xrpl: { seed: process.env.XRPL_SEED! },
5594
+ * },
5595
+ * policy: { maxAmount: '1.00', maxTotal: '20.00', tokens: ['USDC', 'USDT'] },
5596
+ * })
5597
+ * const res = await payer.get('https://api.example.com/paid') // pays on the first funded chain that can settle
5598
+ * ```
5599
+ */
5600
+ static fromWallets(opts: MultiChainPayerOptions): MultiChainPayer;
5601
+ /** The underlying single-chain clients, in preference order. Reach for one of
5602
+ * these for chain-specific reads (`estimateCost`, `discoverySigner`, per-chain
5603
+ * `budget()`) that don't make sense merged. */
5604
+ get clients(): readonly PipRailClient[];
5605
+ /** Plan a 402 across every funded chain — merged + ranked payable-first. `null`
5606
+ * when the URL needs no payment. (Delegates to {@link planAcross}.) */
5607
+ planPayment(url: string, init?: RequestInit): Promise<PaymentPlan | null>;
5608
+ /** Can ANY funded chain settle this URL right now? (A free resource is trivially
5609
+ * "affordable".) No funds move. */
5610
+ canAfford(url: string, init?: RequestInit): Promise<boolean>;
5611
+ /** Price a gated URL across funded chains — the chosen rail's quote (the first
5612
+ * funded chain that can settle), else the first offered rail's. `null` when the URL
5613
+ * needs no payment. When it IS
5614
+ * gated but none of your chains are offered, surfaces the same informative
5615
+ * `NoCompatibleAcceptError` a single client would (it names the chains the 402 is
5616
+ * payable on) rather than a misleading `null`. No funds move. */
5617
+ quote(url: string, init?: RequestInit): Promise<PipRailQuote | null>;
5618
+ /** Pay the first funded chain (in your listed order) that can settle this URL.
5619
+ * Delegates to {@link fetchAcross} — full policy / approval / retry / replay path on
5620
+ * the owning client. The owner re-reads balances at pay time, so the rail paid is the
5621
+ * surfaced `best` on a best-effort basis (it can pick another rail on the SAME chain,
5622
+ * or decline, if balances shift between plan and pay). PROBES the URL with `init`
5623
+ * (method + body) per client — prefer GET / idempotent requests. */
5624
+ fetch(url: string, init?: RequestInit): Promise<Response>;
5625
+ /** GET that auto-pays across chains. */
5626
+ get(url: string, init?: RequestInit): Promise<Response>;
5627
+ /**
5628
+ * POST that auto-pays across chains. `body` is a string/FormData/URLSearchParams/
5629
+ * ArrayBuffer/Blob (sent as-is) or a plain object (serialised as JSON) — mirrors
5630
+ * {@link PipRailClient.post}.
5631
+ */
5632
+ post(url: string, body?: BodyInit | object | undefined, init?: RequestInit): Promise<Response>;
5633
+ /**
5634
+ * Find payable resources across every funded chain. With the default
5635
+ * `network: 'self'`, each chain's own results are merged + deduped by URL (so
5636
+ * "self" means "any chain I can pay"). A network-scoped query (a CAIP-2 id or
5637
+ * `'any'`) is chain-independent, so one client answers it. Never throws for a
5638
+ * read problem; moves no funds.
5639
+ */
5640
+ discover(opts?: DiscoverOptions): Promise<DiscoveredResource[]>;
5641
+ /** List a resource YOU run on the open indexes. Registration is a merchant action
5642
+ * independent of which chain you pay FROM, so it goes through your first chain's
5643
+ * client; pass `opts.network` to advertise a specific chain. Moves no funds. */
5644
+ register(url: string, opts?: RegisterOptions): Promise<RegisterOutcome[]>;
5645
+ /** Aggregate spend across every chain — counts summed; per-(network,asset) rows
5646
+ * and records concatenated (no cross-chain collisions, never a cross-token sum). */
5647
+ spent(): SpendSummary;
5648
+ /** A merged budget view: every chain's per-(network,asset) remaining rows, plus the
5649
+ * MOST-RESTRICTIVE session time envelope across chains (the soonest deadline wins).
5650
+ * Mirrors {@link PipRailClient.budget}'s shape so the agent toolkit reads it
5651
+ * unchanged; per-chain session detail is on each `clients[i].budget()`. */
5652
+ budget(): SessionBudget;
5653
+ }
5461
5654
 
5462
5655
  /**
5463
5656
  * MCP-style tool annotations — optional, advisory hints that let an MCP client or
@@ -5514,7 +5707,7 @@ interface AgentTool {
5514
5707
  * declined? }`) — never a thrown error — so the model reasons about it (and never
5515
5708
  * re-pays a broadcast-but-unconfirmed payment) instead of crashing.
5516
5709
  */
5517
- declare function paymentTools(client: PipRailClient): AgentTool[];
5710
+ declare function paymentTools(client: PayingClient): AgentTool[];
5518
5711
 
5519
5712
  /**
5520
5713
  * One line summarising a {@link PaymentPlan} for a model: what's payable, on which
@@ -7031,4 +7224,4 @@ declare const PERMIT2_WITNESS_TYPES: {
7031
7224
  */
7032
7225
  declare function renderLandingPage(sd: SelfDescription): string;
7033
7226
 
7034
- export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, BRAND, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeRail, type SelfDescription, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSelfDescription, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, firstKeylessFacilitator, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, knownFacilitatorsFor, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseFacilitatorSupported, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
7227
+ export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, BRAND, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, MultiChainPayer, type MultiChainPayerOptions, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, type PayingClient, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeRail, type SelfDescription, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSelfDescription, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, fetchAcross, firstKeylessFacilitator, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, knownFacilitatorsFor, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseFacilitatorSupported, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
package/dist/index.d.ts CHANGED
@@ -5204,6 +5204,22 @@ interface RegisterOptions {
5204
5204
  */
5205
5205
  attribution?: boolean;
5206
5206
  }
5207
+ /**
5208
+ * The read-+-pay surface an agent toolkit needs — the methods {@link paymentTools}
5209
+ * calls. BOTH {@link PipRailClient} (one chain) and {@link MultiChainPayer} (many
5210
+ * chains, one per wallet) satisfy it, so `paymentTools` wraps either unchanged:
5211
+ * point an MCP/LLM at one wallet or at a whole bundle without touching the tools.
5212
+ */
5213
+ interface PayingClient {
5214
+ discover(opts?: DiscoverOptions): Promise<DiscoveredResource[]>;
5215
+ quote(url: string, init?: RequestInit): Promise<PipRailQuote | null>;
5216
+ planPayment(url: string, init?: RequestInit): Promise<PaymentPlan | null>;
5217
+ get(url: string, init?: RequestInit): Promise<Response>;
5218
+ fetch(url: string, init?: RequestInit): Promise<Response>;
5219
+ register(url: string, opts?: RegisterOptions): Promise<RegisterOutcome[]>;
5220
+ spent(): SpendSummary;
5221
+ budget(): SessionBudget;
5222
+ }
5207
5223
  declare class PipRailClient {
5208
5224
  private readonly opts;
5209
5225
  private readonly maxRetries;
@@ -5453,11 +5469,188 @@ declare class PipRailClient {
5453
5469
  * A {@link PipRailClient} is bound to one chain (its wallet); give this one client
5454
5470
  * per chain the agent funds and it runs each client's {@link PipRailClient.planPayment}
5455
5471
  * in parallel and merges the rails into one plan, ranked payable-first. `best` is a
5456
- * payable rail; across different native coins there's no oracle to pick the
5457
- * fiat-cheapest, so the tiebreak is the order `clients` were given (the agent's own
5458
- * chain preference). Returns `null` only if the URL isn't gated for any client.
5472
+ * payable rail. Across different native coins there's no oracle to compare gas costs,
5473
+ * so it does NOT rank chains by fee against each other: `best` is the FIRST chain you
5474
+ * pass in `clients` that can settle (your preference order); within a single chain it
5475
+ * still prefers the cheapest-gas rail. Returns `null` only if the URL isn't gated for
5476
+ * any client. Throws only if EVERY client fails to reach the resource (a total outage),
5477
+ * mirroring a single client — a single chain being down just drops that chain.
5459
5478
  */
5460
5479
  declare function planAcross(clients: PipRailClient[], url: string, init?: RequestInit): Promise<PaymentPlan | null>;
5480
+ /**
5481
+ * PAY across several single-chain clients — the EXECUTION counterpart to
5482
+ * {@link planAcross}. Plans the URL on every client in parallel (keeping which
5483
+ * client owns which rail), picks the rail `planAcross` names as `best` (the first
5484
+ * funded chain you listed that can settle RIGHT NOW), and pays it on its owning
5485
+ * client. So an agent that holds one wallet
5486
+ * per chain pays whichever chain/token the merchant's 402 asks for — with no
5487
+ * manual routing — while every payment still goes through that client's own
5488
+ * spend policy, `onBeforePay` hook, retries, and replay-protection (this just
5489
+ * calls the chosen client's {@link PipRailClient.fetch}).
5490
+ *
5491
+ * - A URL that needs no payment (no 402) is returned straight through.
5492
+ * - When NO funded chain can settle it, throws {@link PaymentDeclinedError} with a
5493
+ * merged, per-chain funding hint — BEFORE any on-chain send.
5494
+ *
5495
+ * Selection matches {@link planAcross}: payable-first, and across different native
5496
+ * coins (no price oracle) the FIRST chain you pass in `clients` that can settle wins
5497
+ * (your preference); within a chain, the cheapest-gas rail. It normally pays the rail
5498
+ * `planAcross` reports as `best`, but on a BEST-EFFORT basis — the owning client
5499
+ * re-reads its balances/gas at pay time, so a change between planning and paying (a
5500
+ * concurrent payment, RPC drift, the merchant returning a different 402) can make it
5501
+ * pick another settleable rail ON THE SAME CHAIN, or decline; its spend policy +
5502
+ * `onBeforePay` still gate whatever is actually paid. For the ergonomic object form,
5503
+ * see {@link MultiChainPayer}.
5504
+ *
5505
+ * NOTE: this PROBES the URL with the caller's `init` (method + body) on each client to
5506
+ * read the 402, so prefer it for GET / idempotent requests — a non-idempotent POST is
5507
+ * sent once per client before the pay leg (the x402 gate returns 402 without acting,
5508
+ * but the body is re-sent).
5509
+ */
5510
+ declare function fetchAcross(clients: PipRailClient[], url: string, init?: RequestInit): Promise<Response>;
5511
+
5512
+ /**
5513
+ * MultiChainPayer — one buyer, many wallets, pay whatever the merchant asks.
5514
+ *
5515
+ * A {@link PipRailClient} is bound to exactly ONE chain and ONE wallet (an EVM key
5516
+ * can't sign a Solana tx, and vice-versa — that's enforced at bind time). So a
5517
+ * buyer who wants to pay a 402 *whatever chain/token it demands* holds one key per
5518
+ * chain. This is the ergonomic object that carries that bundle: give it a
5519
+ * `{ chain → wallet }` map and it builds one client per chain, then exposes a single
5520
+ * `fetch`/`get`/`post`/`plan`/`quote` that auto-routes to the first funded chain that
5521
+ * can settle — no manual "which client owns this rail?" plumbing.
5522
+ *
5523
+ * It is a thin, chain-agnostic composition over the existing primitives — it adds
5524
+ * NO new payment logic:
5525
+ * - `planPayment` → {@link planAcross} (merge every chain's plan, payable-first)
5526
+ * - `fetch`/`get`/`post` → {@link fetchAcross} (pay on the first chain that can settle)
5527
+ * Every payment still runs through its owning client's own spend policy,
5528
+ * `onBeforePay` hook, retries, and replay-protection. There is no cross-chain
5529
+ * custody, no price oracle, and no backend: across chains it pays the FIRST one you
5530
+ * list that can settle (your preference order — gas isn't comparable across coins);
5531
+ * within a chain it picks the cheapest-gas rail.
5532
+ *
5533
+ * Because it implements {@link PayingClient}, the agent toolkit ({@link paymentTools})
5534
+ * and the MCP server wrap it byte-identically to a single client.
5535
+ */
5536
+
5537
+ /**
5538
+ * One wallet per chain you fund, keyed by chain selector. The KEY is a chain
5539
+ * string (an EVM preset like `'base'`/`'bnb'`, or a non-EVM family
5540
+ * `'solana'|'ton'|'tron'|'near'|'sui'|'aptos'|'algorand'|'stellar'|'xrpl'`); the
5541
+ * VALUE is that family's {@link WalletInput}:
5542
+ *
5543
+ * base/bnb/… → { privateKey } solana → { secretKey } ton/algorand → { mnemonic }
5544
+ * stellar → { secret } xrpl → { seed } near → { accountId, privateKey }
5545
+ *
5546
+ * One key per family — this map is how a single buyer carries the keys for every
5547
+ * chain it's willing to pay on. (For a CUSTOM EVM chain configured by a viem
5548
+ * `Chain` object, build the {@link PipRailClient} yourself and use
5549
+ * `new MultiChainPayer([...clients])`.)
5550
+ */
5551
+ interface MultiChainPayerOptions {
5552
+ /** `{ chain → wallet }`. Iteration order is your chain PREFERENCE: across chains the
5553
+ * first one that can settle wins (there's no oracle to compare gas across coins). */
5554
+ wallets: Record<string, WalletInput>;
5555
+ /** Spend policy applied to EVERY chain's client. Each client still keeps its own
5556
+ * per-(network,asset) ledger — there is no cross-token sum (no price oracle). */
5557
+ policy?: PaymentPolicy;
5558
+ /** Per-chain RPC overrides, keyed by the same chain selector as `wallets`. */
5559
+ rpcUrls?: Record<string, string>;
5560
+ /** Which schemes every client may settle. Default `['onchain-proof']` (unchanged). */
5561
+ schemes?: PaymentScheme[];
5562
+ /** Final approval hook applied to every chain's client (fires before any send). */
5563
+ onBeforePay?: (quote: PipRailQuote) => boolean | Promise<boolean>;
5564
+ /** Observability hook applied to every chain's client. */
5565
+ onEvent?: (event: PipRailEvent) => void;
5566
+ /** Retry budget for the post-broadcast leg, per client. Default 3. */
5567
+ maxPaymentRetries?: number;
5568
+ /** Timeout (ms) for the retry leg, per client. Default 30_000. */
5569
+ retryTimeoutMs?: number;
5570
+ }
5571
+ declare class MultiChainPayer implements PayingClient {
5572
+ private readonly _clients;
5573
+ /**
5574
+ * Wrap an explicit, ordered set of single-chain clients — use this when a client
5575
+ * needs full control (e.g. a custom EVM chain configured by a viem `Chain`). The
5576
+ * ORDER is your chain preference: across chains the first that can settle wins. Pass
5577
+ * at MOST one client per chain — two clients on the SAME network would double-count in
5578
+ * `spent()`/`budget()` and waste a plan round-trip (`fromWallets` can't produce this).
5579
+ * For the common case, prefer {@link MultiChainPayer.fromWallets}.
5580
+ */
5581
+ constructor(clients: PipRailClient[]);
5582
+ /**
5583
+ * Build one client per funded chain from a `{ chain → wallet }` map — the
5584
+ * ergonomic path. The shared `policy`/`schemes`/`onBeforePay`/`onEvent` apply to
5585
+ * every client; `rpcUrls` are matched per chain. Iteration order of `wallets` is
5586
+ * the chain preference.
5587
+ *
5588
+ * ```ts
5589
+ * const payer = MultiChainPayer.fromWallets({
5590
+ * wallets: {
5591
+ * base: { privateKey: process.env.EVM_KEY! },
5592
+ * solana: { secretKey: process.env.SOLANA_SECRET! },
5593
+ * xrpl: { seed: process.env.XRPL_SEED! },
5594
+ * },
5595
+ * policy: { maxAmount: '1.00', maxTotal: '20.00', tokens: ['USDC', 'USDT'] },
5596
+ * })
5597
+ * const res = await payer.get('https://api.example.com/paid') // pays on the first funded chain that can settle
5598
+ * ```
5599
+ */
5600
+ static fromWallets(opts: MultiChainPayerOptions): MultiChainPayer;
5601
+ /** The underlying single-chain clients, in preference order. Reach for one of
5602
+ * these for chain-specific reads (`estimateCost`, `discoverySigner`, per-chain
5603
+ * `budget()`) that don't make sense merged. */
5604
+ get clients(): readonly PipRailClient[];
5605
+ /** Plan a 402 across every funded chain — merged + ranked payable-first. `null`
5606
+ * when the URL needs no payment. (Delegates to {@link planAcross}.) */
5607
+ planPayment(url: string, init?: RequestInit): Promise<PaymentPlan | null>;
5608
+ /** Can ANY funded chain settle this URL right now? (A free resource is trivially
5609
+ * "affordable".) No funds move. */
5610
+ canAfford(url: string, init?: RequestInit): Promise<boolean>;
5611
+ /** Price a gated URL across funded chains — the chosen rail's quote (the first
5612
+ * funded chain that can settle), else the first offered rail's. `null` when the URL
5613
+ * needs no payment. When it IS
5614
+ * gated but none of your chains are offered, surfaces the same informative
5615
+ * `NoCompatibleAcceptError` a single client would (it names the chains the 402 is
5616
+ * payable on) rather than a misleading `null`. No funds move. */
5617
+ quote(url: string, init?: RequestInit): Promise<PipRailQuote | null>;
5618
+ /** Pay the first funded chain (in your listed order) that can settle this URL.
5619
+ * Delegates to {@link fetchAcross} — full policy / approval / retry / replay path on
5620
+ * the owning client. The owner re-reads balances at pay time, so the rail paid is the
5621
+ * surfaced `best` on a best-effort basis (it can pick another rail on the SAME chain,
5622
+ * or decline, if balances shift between plan and pay). PROBES the URL with `init`
5623
+ * (method + body) per client — prefer GET / idempotent requests. */
5624
+ fetch(url: string, init?: RequestInit): Promise<Response>;
5625
+ /** GET that auto-pays across chains. */
5626
+ get(url: string, init?: RequestInit): Promise<Response>;
5627
+ /**
5628
+ * POST that auto-pays across chains. `body` is a string/FormData/URLSearchParams/
5629
+ * ArrayBuffer/Blob (sent as-is) or a plain object (serialised as JSON) — mirrors
5630
+ * {@link PipRailClient.post}.
5631
+ */
5632
+ post(url: string, body?: BodyInit | object | undefined, init?: RequestInit): Promise<Response>;
5633
+ /**
5634
+ * Find payable resources across every funded chain. With the default
5635
+ * `network: 'self'`, each chain's own results are merged + deduped by URL (so
5636
+ * "self" means "any chain I can pay"). A network-scoped query (a CAIP-2 id or
5637
+ * `'any'`) is chain-independent, so one client answers it. Never throws for a
5638
+ * read problem; moves no funds.
5639
+ */
5640
+ discover(opts?: DiscoverOptions): Promise<DiscoveredResource[]>;
5641
+ /** List a resource YOU run on the open indexes. Registration is a merchant action
5642
+ * independent of which chain you pay FROM, so it goes through your first chain's
5643
+ * client; pass `opts.network` to advertise a specific chain. Moves no funds. */
5644
+ register(url: string, opts?: RegisterOptions): Promise<RegisterOutcome[]>;
5645
+ /** Aggregate spend across every chain — counts summed; per-(network,asset) rows
5646
+ * and records concatenated (no cross-chain collisions, never a cross-token sum). */
5647
+ spent(): SpendSummary;
5648
+ /** A merged budget view: every chain's per-(network,asset) remaining rows, plus the
5649
+ * MOST-RESTRICTIVE session time envelope across chains (the soonest deadline wins).
5650
+ * Mirrors {@link PipRailClient.budget}'s shape so the agent toolkit reads it
5651
+ * unchanged; per-chain session detail is on each `clients[i].budget()`. */
5652
+ budget(): SessionBudget;
5653
+ }
5461
5654
 
5462
5655
  /**
5463
5656
  * MCP-style tool annotations — optional, advisory hints that let an MCP client or
@@ -5514,7 +5707,7 @@ interface AgentTool {
5514
5707
  * declined? }`) — never a thrown error — so the model reasons about it (and never
5515
5708
  * re-pays a broadcast-but-unconfirmed payment) instead of crashing.
5516
5709
  */
5517
- declare function paymentTools(client: PipRailClient): AgentTool[];
5710
+ declare function paymentTools(client: PayingClient): AgentTool[];
5518
5711
 
5519
5712
  /**
5520
5713
  * One line summarising a {@link PaymentPlan} for a model: what's payable, on which
@@ -7031,4 +7224,4 @@ declare const PERMIT2_WITNESS_TYPES: {
7031
7224
  */
7032
7225
  declare function renderLandingPage(sd: SelfDescription): string;
7033
7226
 
7034
- export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, BRAND, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeRail, type SelfDescription, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSelfDescription, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, firstKeylessFacilitator, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, knownFacilitatorsFor, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseFacilitatorSupported, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
7227
+ export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, BRAND, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, type FacilitatorSupportedKind, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, KNOWN_FACILITATORS, type KnownFacilitator, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, MultiChainPayer, type MultiChainPayerOptions, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_PROXY_CHAIN_IDS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, POWERED_BY, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, type PayingClient, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, REGISTER_ATTRIBUTION, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SelfDescribeRail, type SelfDescription, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, WalletRequiredError, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, appendAttribution, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSelfDescription, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, describeChallenge, discoveryHeaders, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, facilitatorCoverage, fetchAcross, firstKeylessFacilitator, formatSpendReport, getDirectoryInfo, isPermit2ProxyChain, knownFacilitatorsFor, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseFacilitatorSupported, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, renderLandingPage, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };