@haven_ai/sdk 0.1.8 → 0.1.10-alpha.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.cjs +552 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +225 -3
- package/dist/index.d.ts +225 -3
- package/dist/index.js +547 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -24,6 +24,21 @@ interface HavenClientConfig {
|
|
|
24
24
|
* standard HTTP and never carry Haven-internal headers.
|
|
25
25
|
*/
|
|
26
26
|
defaultHeaders?: Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* JSON-RPC RPC URLs keyed by EIP-155 chain ID.
|
|
29
|
+
*
|
|
30
|
+
* When provided for a chain, the SDK waits for ≥1 on-chain confirmation of
|
|
31
|
+
* the AllowanceModule funding tx before retrying the merchant. This prevents
|
|
32
|
+
* the race where the merchant's `balanceOf(delegate)` call runs before the
|
|
33
|
+
* funding block has propagated to the merchant's RPC node.
|
|
34
|
+
*
|
|
35
|
+
* Without this option the SDK proceeds as soon as Haven's backend confirms
|
|
36
|
+
* submission (backward-compatible default). Set it to a reliable RPC
|
|
37
|
+
* endpoint (e.g. Alchemy / Infura) for production usage.
|
|
38
|
+
*
|
|
39
|
+
* @example { 8453: 'https://mainnet.base.org' }
|
|
40
|
+
*/
|
|
41
|
+
chainRpcs?: Record<number, string>;
|
|
27
42
|
}
|
|
28
43
|
interface PaymentRequest {
|
|
29
44
|
/** Token symbol: "EURe", "USDC.e", or "xDAI" */
|
|
@@ -419,6 +434,30 @@ interface HavenPaymentReceipt {
|
|
|
419
434
|
createdAt: string;
|
|
420
435
|
updatedAt: string;
|
|
421
436
|
}
|
|
437
|
+
/** One transferred asset in a delegate sweep. */
|
|
438
|
+
interface SweepEntry {
|
|
439
|
+
/** 'USDC' or 'ETH' */
|
|
440
|
+
asset: string;
|
|
441
|
+
/** Human-readable amount swept (e.g. "0.12") */
|
|
442
|
+
amount: string;
|
|
443
|
+
/** Atomic amount swept */
|
|
444
|
+
amountAtomic: string;
|
|
445
|
+
/** Transaction hash of the sweep transfer */
|
|
446
|
+
txHash: string;
|
|
447
|
+
/** Block explorer URL for the tx */
|
|
448
|
+
explorerUrl: string;
|
|
449
|
+
}
|
|
450
|
+
/** Result of a `sweepDelegate()` call. */
|
|
451
|
+
interface SweepResult {
|
|
452
|
+
/** Address funds were swept FROM */
|
|
453
|
+
fromAddress: string;
|
|
454
|
+
/** Address funds were swept TO (always the originating Safe) */
|
|
455
|
+
toAddress: string;
|
|
456
|
+
/** Chain the sweep occurred on */
|
|
457
|
+
chainId: number;
|
|
458
|
+
/** One entry per transferred asset. Empty when nothing was stranded. */
|
|
459
|
+
transfers: SweepEntry[];
|
|
460
|
+
}
|
|
422
461
|
type PaymentStateKind = 'payment_intent' | 'approval_request';
|
|
423
462
|
interface AgentPaymentEnumSchema {
|
|
424
463
|
type: 'string';
|
|
@@ -455,6 +494,13 @@ declare const AgentPaymentPhase: {
|
|
|
455
494
|
* funds or the agent's per-token allowance needs to be raised first.
|
|
456
495
|
*/
|
|
457
496
|
readonly InsufficientFunds: "insufficient_funds";
|
|
497
|
+
/**
|
|
498
|
+
* Haven's funding leg (Safe → delegate) confirmed on-chain, but the
|
|
499
|
+
* merchant rejected the x402 retry. The delegate wallet may hold stranded
|
|
500
|
+
* USDC that was never settled to the merchant. The agent should stop, tell
|
|
501
|
+
* the user, and wait for the sweep flow to reclaim the funds.
|
|
502
|
+
*/
|
|
503
|
+
readonly FundedButUnsettled: "funded_but_unsettled";
|
|
458
504
|
};
|
|
459
505
|
type AgentPaymentPhase = (typeof AgentPaymentPhase)[keyof typeof AgentPaymentPhase];
|
|
460
506
|
declare const AgentPaymentNextAction: {
|
|
@@ -480,6 +526,12 @@ declare const AgentPaymentNextAction: {
|
|
|
480
526
|
* can succeed. A user approval will not fix this state on its own.
|
|
481
527
|
*/
|
|
482
528
|
readonly FundSafeOrRaiseAllowance: "fund_safe_or_raise_allowance";
|
|
529
|
+
/**
|
|
530
|
+
* The delegate wallet may hold funds that were sent from the Safe but never
|
|
531
|
+
* settled to the merchant. The wallet owner should initiate a sweep to
|
|
532
|
+
* return those funds to the originating Safe.
|
|
533
|
+
*/
|
|
534
|
+
readonly SweepStrandedFunds: "sweep_stranded_funds";
|
|
483
535
|
};
|
|
484
536
|
type AgentPaymentNextAction = (typeof AgentPaymentNextAction)[keyof typeof AgentPaymentNextAction];
|
|
485
537
|
/**
|
|
@@ -519,8 +571,8 @@ declare const AgentPaymentRail: {
|
|
|
519
571
|
type AgentPaymentRail = (typeof AgentPaymentRail)[keyof typeof AgentPaymentRail];
|
|
520
572
|
type PaymentPhase = AgentPaymentPhase;
|
|
521
573
|
type PaymentNextAction = AgentPaymentNextAction;
|
|
522
|
-
declare const AGENT_PAYMENT_PHASE_VALUES: ("rejected" | "expired" | "failed" | "agent_signature_required" | "payment_submitted" | "payment_confirmed" | "user_approval_required" | "user_execution_required" | "waiting_for_additional_approvals" | "funding_sent" | "insufficient_funds")[];
|
|
523
|
-
declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "fund_safe_or_raise_allowance")[];
|
|
574
|
+
declare const AGENT_PAYMENT_PHASE_VALUES: ("rejected" | "expired" | "failed" | "agent_signature_required" | "payment_submitted" | "payment_confirmed" | "user_approval_required" | "user_execution_required" | "waiting_for_additional_approvals" | "funding_sent" | "insufficient_funds" | "funded_but_unsettled")[];
|
|
575
|
+
declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "fund_safe_or_raise_allowance" | "sweep_stranded_funds")[];
|
|
524
576
|
declare const AGENT_PAYMENT_RAIL_VALUES: ("x402" | "mpp" | "mpp_demo" | "mpp_crypto" | "stripe_deposit" | "spt" | "direct")[];
|
|
525
577
|
declare const AgentPaymentPhaseDescriptions: Record<AgentPaymentPhase, string>;
|
|
526
578
|
declare const AgentPaymentNextActionDescriptions: Record<AgentPaymentNextAction, string>;
|
|
@@ -576,6 +628,24 @@ interface PendingApproval extends PaymentStatusResult {
|
|
|
576
628
|
requested?: string;
|
|
577
629
|
remaining?: string | null;
|
|
578
630
|
}
|
|
631
|
+
/** @internal */
|
|
632
|
+
/** One payable service in Haven's curated merchant catalog. */
|
|
633
|
+
interface HavenCatalogEntry {
|
|
634
|
+
id: string;
|
|
635
|
+
name: string;
|
|
636
|
+
description: string;
|
|
637
|
+
category: string;
|
|
638
|
+
resourceUrl: string;
|
|
639
|
+
rail: 'x402' | 'mpp';
|
|
640
|
+
protocol: 'http' | 'mcp';
|
|
641
|
+
toolName: string | null;
|
|
642
|
+
priceDisplay: string | null;
|
|
643
|
+
priceAtomic: string | null;
|
|
644
|
+
asset: string | null;
|
|
645
|
+
network: string | null;
|
|
646
|
+
status: 'active' | 'degraded' | 'delisted';
|
|
647
|
+
verifiedAt: string | null;
|
|
648
|
+
}
|
|
579
649
|
declare class HavenError extends Error {
|
|
580
650
|
readonly code: string;
|
|
581
651
|
readonly statusCode?: number | undefined;
|
|
@@ -609,6 +679,7 @@ declare class HavenClient {
|
|
|
609
679
|
private readonly requestTimeout;
|
|
610
680
|
private readonly confirmationTimeout;
|
|
611
681
|
private readonly pollingInterval;
|
|
682
|
+
private readonly chainRpcs;
|
|
612
683
|
private readonly inFlightX402;
|
|
613
684
|
private readonly x402ReceiptCache;
|
|
614
685
|
private readonly inFlightMachinePayments;
|
|
@@ -625,6 +696,8 @@ declare class HavenClient {
|
|
|
625
696
|
* the same time — see their own headers without stepping on each other.
|
|
626
697
|
*/
|
|
627
698
|
private readonly requestContext;
|
|
699
|
+
/** Monotonic JSON-RPC id source for the MCP `initialize` handshake. */
|
|
700
|
+
private mcpRequestId;
|
|
628
701
|
/** Delegate address derived from the private key (if provided) */
|
|
629
702
|
readonly delegateAddress: string | undefined;
|
|
630
703
|
constructor(config: HavenClientConfig);
|
|
@@ -707,10 +780,31 @@ declare class HavenClient {
|
|
|
707
780
|
* Get the agent identity tied to this API key.
|
|
708
781
|
*/
|
|
709
782
|
getAgent(): Promise<HavenAgent>;
|
|
783
|
+
/**
|
|
784
|
+
* Sweep stranded USDC and ETH from the delegate EOA back to the originating Safe.
|
|
785
|
+
*
|
|
786
|
+
* The delegate key held by this client signs and submits the transfer transactions
|
|
787
|
+
* directly — Haven's backend never handles the key or constructs signed txs
|
|
788
|
+
* (CASP/MiCA Red Line #2). Funds always go to the Safe linked to this agent.
|
|
789
|
+
*
|
|
790
|
+
* Requires `chainRpcs` to be set for the agent's chain in `HavenClientConfig`.
|
|
791
|
+
*/
|
|
792
|
+
sweepDelegate(): Promise<SweepResult>;
|
|
710
793
|
/**
|
|
711
794
|
* Get configured and on-chain allowances for the authenticated agent.
|
|
712
795
|
*/
|
|
713
796
|
getAllowances(): Promise<HavenAllowanceSummary>;
|
|
797
|
+
/**
|
|
798
|
+
* Discover payable services from Haven's curated merchant catalog.
|
|
799
|
+
*
|
|
800
|
+
* Read-only: returns catalog entries (price, rail, protocol) so an agent
|
|
801
|
+
* can choose a service and pay it with the regular payment tools in the
|
|
802
|
+
* same session. Never creates payments or signatures.
|
|
803
|
+
*/
|
|
804
|
+
discoverTools(options?: {
|
|
805
|
+
category?: string;
|
|
806
|
+
rail?: 'x402' | 'mpp';
|
|
807
|
+
}): Promise<HavenCatalogEntry[]>;
|
|
714
808
|
/**
|
|
715
809
|
* List recent machine-payment receipts/evidence for bookkeeping.
|
|
716
810
|
*/
|
|
@@ -761,9 +855,44 @@ declare class HavenClient {
|
|
|
761
855
|
* const data = await response.json()
|
|
762
856
|
* ```
|
|
763
857
|
*
|
|
858
|
+
* **MCP-over-x402 auto-handshake (issue #315):** when the endpoint is
|
|
859
|
+
* MCP-shaped — the URL path ends in `/mcp`, or the 402 body carries a
|
|
860
|
+
* Coinbase Bazaar `extensions.bazaar` block — the SDK runs the MCP
|
|
861
|
+
* `initialize` handshake, threads the resulting `mcp-session-id`,
|
|
862
|
+
* `Accept: application/json, text/event-stream`, and `x402-wallet` headers
|
|
863
|
+
* through every request, and collapses SSE responses to the JSON-RPC
|
|
864
|
+
* `result`. The caller just passes `(url, { body })` and never sees the
|
|
865
|
+
* protocol plumbing. A non-MCP server (handshake error / no session id)
|
|
866
|
+
* falls back to standard x402 behaviour.
|
|
867
|
+
*
|
|
764
868
|
* Requires `delegateKey` to be set in the client config.
|
|
765
869
|
*/
|
|
766
870
|
fetch(url: string, init?: RequestInit, options?: X402AuthorizationOptions): Promise<Response>;
|
|
871
|
+
/**
|
|
872
|
+
* Run the MCP `initialize` handshake against a Streamable-HTTP endpoint and
|
|
873
|
+
* return the `mcp-session-id` the server assigns.
|
|
874
|
+
*
|
|
875
|
+
* Returns `undefined` whenever the endpoint is not actually an MCP server —
|
|
876
|
+
* a transport/HTTP error, a missing session id, or a JSON-RPC error in the
|
|
877
|
+
* handshake response — so the caller can fall back to plain x402.
|
|
878
|
+
*/
|
|
879
|
+
private mcpInitialize;
|
|
880
|
+
/**
|
|
881
|
+
* Send the MCP `notifications/initialized` notification that completes the
|
|
882
|
+
* lifecycle handshake. Best-effort: the session is already established, so a
|
|
883
|
+
* failed notification must not abort the payment.
|
|
884
|
+
*/
|
|
885
|
+
private mcpNotifyInitialized;
|
|
886
|
+
/** Read a single JSON-RPC message from an MCP response (JSON or SSE body). */
|
|
887
|
+
private readMcpMessage;
|
|
888
|
+
/** Add the MCP transport headers (session id + SSE Accept) to a request. */
|
|
889
|
+
private withMcpHeaders;
|
|
890
|
+
/**
|
|
891
|
+
* Collapse an MCP SSE response into a plain JSON response carrying the
|
|
892
|
+
* JSON-RPC `result`, so callers of `fetch()` never see raw SSE framing.
|
|
893
|
+
* Non-SSE responses pass through untouched.
|
|
894
|
+
*/
|
|
895
|
+
private surfaceMcpResult;
|
|
767
896
|
/**
|
|
768
897
|
* Probe a paid MPP endpoint or inspect an existing challenge without creating
|
|
769
898
|
* a Haven payment or approval request.
|
|
@@ -791,6 +920,16 @@ declare class HavenClient {
|
|
|
791
920
|
private mapMachinePaymentReceiptFromStatus;
|
|
792
921
|
private recordMerchantRetryRejected;
|
|
793
922
|
private reportMachinePaymentEvidence;
|
|
923
|
+
/**
|
|
924
|
+
* Wait for a funding tx to be mined with ≥1 confirmation before the
|
|
925
|
+
* merchant retry, eliminating the race where the merchant's
|
|
926
|
+
* `balanceOf(delegate)` runs before the funding block propagates.
|
|
927
|
+
*
|
|
928
|
+
* Skipped when `chainRpcs` does not include the chain; in that case Haven's
|
|
929
|
+
* backend has already confirmed on-chain submission and callers accept the
|
|
930
|
+
* small propagation window as a trade-off for not configuring an RPC URL.
|
|
931
|
+
*/
|
|
932
|
+
private waitForFundingTx;
|
|
794
933
|
private throwIfNonSignableAuthorizationState;
|
|
795
934
|
private throwPaymentStateError;
|
|
796
935
|
private paymentStateFromRaw;
|
|
@@ -1005,9 +1144,54 @@ declare const toolDescriptions: {
|
|
|
1005
1144
|
readonly behavior: "Returns the agent's recent machine-payment receipts ordered by recency. Proof header values are not returned.";
|
|
1006
1145
|
readonly nextActionGuidance: "";
|
|
1007
1146
|
};
|
|
1147
|
+
readonly payMcpTool: {
|
|
1148
|
+
readonly summary: "Call a named tool on an MCP merchant that requires an x402 payment, handling the full initialize → pay → retry round trip.";
|
|
1149
|
+
readonly selectionGuidance: string;
|
|
1150
|
+
readonly behavior: string;
|
|
1151
|
+
readonly nextActionGuidance: string;
|
|
1152
|
+
};
|
|
1153
|
+
readonly discoverTools: {
|
|
1154
|
+
readonly summary: "Discover payable services from Haven's curated merchant catalog — names, prices, and which pay tool to use.";
|
|
1155
|
+
readonly selectionGuidance: string;
|
|
1156
|
+
readonly behavior: string;
|
|
1157
|
+
readonly nextActionGuidance: "Pick an entry, confirm the price with the user if it is non-trivial, and pay it with the tool named in suggested_tool, passing the entry's resource_url (and tool_name for MCP merchants).";
|
|
1158
|
+
};
|
|
1159
|
+
readonly sweep_delegate: {
|
|
1160
|
+
readonly summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating Safe.";
|
|
1161
|
+
readonly selectionGuidance: string;
|
|
1162
|
+
readonly behavior: string;
|
|
1163
|
+
readonly nextActionGuidance: "If transfers is non-empty, confirm the amounts with the user. No further action required — funds are on their way back to the Safe.";
|
|
1164
|
+
};
|
|
1165
|
+
readonly send: {
|
|
1166
|
+
readonly summary: "Send ETH or USDC directly from the agent's Haven wallet to a recipient address.";
|
|
1167
|
+
readonly selectionGuidance: string;
|
|
1168
|
+
readonly behavior: string;
|
|
1169
|
+
readonly nextActionGuidance: string;
|
|
1170
|
+
};
|
|
1008
1171
|
};
|
|
1009
1172
|
type SharedToolKey = keyof typeof toolDescriptions;
|
|
1010
1173
|
|
|
1174
|
+
/**
|
|
1175
|
+
* The generic Haven payment skill — canonical copy.
|
|
1176
|
+
*
|
|
1177
|
+
* This SDK file is the single source of truth for the generic, secret-free
|
|
1178
|
+
* skill content: no wallet address, no budget numbers, no per-agent values.
|
|
1179
|
+
* The agent learns its identity and live budget at runtime via the
|
|
1180
|
+
* `haven_get_agent` / `haven_get_allowances` MCP tools, so the same file works
|
|
1181
|
+
* for every user. `packages/connect` imports this directly to auto-install the
|
|
1182
|
+
* skill into runtime skills folders.
|
|
1183
|
+
*
|
|
1184
|
+
* `packages/frontend/src/lib/agent-skill-bundle.ts` keeps a deliberately
|
|
1185
|
+
* decoupled inline copy (the download fallback): frontend has zero
|
|
1186
|
+
* `@haven_ai/*` dependencies so it can deploy standalone on Vercel without an
|
|
1187
|
+
* unpublished SDK export. A parity test in that package's test suite imports
|
|
1188
|
+
* this canonical string and asserts byte-for-byte equality, so the two copies
|
|
1189
|
+
* cannot drift.
|
|
1190
|
+
*/
|
|
1191
|
+
declare const HAVEN_SKILL_MD = "---\nname: haven-pay\ndescription: Pay for things from the user's Haven wallet within their agent rules. Use when the user asks to send, pay, tip, or transfer crypto \u2014 or when a request hits an HTTP 402 (x402) paywall.\n---\n\n# Haven: pay from a Haven wallet\n\nThis skill lets the agent make payments from the user's Haven wallet through\nthe Haven MCP tools. Every payment is checked against the agent's on-chain\nbudget before money moves; payments above the remaining budget wait for the\nuser's approval in Haven.\n\n## When to use this skill\n\n- The user asks to send money, pay someone, tip, donate, or transfer tokens.\n- A request returns HTTP 402 (x402): use the Haven pay tools to settle it,\n then retry the original request.\n\n## Identity and budget come from the tools \u2014 never assume them\n\nDo not guess the wallet address, network, or budget. Read them live:\n\n- `haven_get_agent` \u2014 agent identity, Haven wallet address, network.\n- `haven_get_allowances` \u2014 current per-token budgets and what remains.\n\nBudgets reset on a period the user chose. If a payment exceeds the remaining\nbudget it is queued for the user to approve in the Haven dashboard \u2014 this is\nnormal, not an error.\n\n## Paying\n\n- **Direct transfer:** `haven_pay` with recipient, amount, and token.\n- **x402 paywall:** `haven_quote_x402` to get a quote, then\n `haven_pay_x402_quote`. In the hosted setup the signing step happens in\n the local Haven signer; follow the tool results \u2014 they tell you the next\n action at every step. Retry the original request only when the result says\n `retry_original_x402_request`.\n- **Status:** `haven_get_payment_status` with a `payment_id` to check on\n queued or in-flight payments. Do not poll in a tight loop.\n\n## Approval semantics\n\n- A result with `pending_approval` means the payment exceeded the remaining\n budget and is waiting for the user in Haven. Tell the user, then check\n status later.\n- Never ask the user for private keys and never try to sign anything\n yourself \u2014 Haven signs. If a tool reports a missing or invalid credential,\n tell the user to re-run the Haven setup command.\n\n## Failure handling\n\nHaven errors are shaped `{ error, status, details? }` and written for\nhumans \u2014 surface the message verbatim. Common cases:\n\n- `pending_approval`: queued for the user's approval (see above).\n- `insufficient_funds`: the Haven wallet doesn't hold enough of that token.\n Suggest the user add funds in the Haven dashboard.\n- Budget exceeded: tell the user how much remains (from\n `haven_get_allowances`) and that they can raise the budget in Haven.\n\n## Revoke\n\nIf this agent's credential may have leaked, tell the user to pause or revoke\nthe agent in the Haven dashboard under Agents. New requests stop immediately\nfor that credential.\n";
|
|
1192
|
+
/** Directory name for the installed skill folder. */
|
|
1193
|
+
declare const SKILL_FOLDER_NAME = "haven-pay";
|
|
1194
|
+
|
|
1011
1195
|
/**
|
|
1012
1196
|
* x402 protocol support for the Haven SDK.
|
|
1013
1197
|
*
|
|
@@ -1078,4 +1262,42 @@ declare function parseMachinePaymentChallengeResponse(response: Response): Promi
|
|
|
1078
1262
|
declare function buildMachinePaymentIdempotencyKey(challenge: MachinePaymentChallenge): string;
|
|
1079
1263
|
declare function encodeMachinePaymentProof(receipt: Omit<MachinePaymentReceipt, 'proofHeader'>): string;
|
|
1080
1264
|
|
|
1081
|
-
|
|
1265
|
+
/**
|
|
1266
|
+
* Runtime-agnostic base64 helpers — the single source of truth for the wire
|
|
1267
|
+
* encoding shared by the SDK and the edge signer (#325).
|
|
1268
|
+
*
|
|
1269
|
+
* Why this module exists: the SDK used `atob`/`btoa` (Web globals) while the
|
|
1270
|
+
* signer used `Buffer` (Node-only). Both worked because both currently run in
|
|
1271
|
+
* Node ≥ 16, but the duplication was a latent wire-incompatibility — and the
|
|
1272
|
+
* signer is headed for non-Node runtimes (browsers, Cloudflare Workers) where
|
|
1273
|
+
* `Buffer` does not exist (#314).
|
|
1274
|
+
*
|
|
1275
|
+
* Encoding contract:
|
|
1276
|
+
* - Output is ALWAYS standard base64 (`+`, `/`, padded). The x402 protocol's
|
|
1277
|
+
* reference implementation validates headers against
|
|
1278
|
+
* `/^[A-Za-z0-9+/]*={0,2}$/` — URL-safe output would be rejected.
|
|
1279
|
+
* - Decoding is tolerant: URL-safe input (`-`, `_`, unpadded) is normalized
|
|
1280
|
+
* before decoding, since third-party merchants are not guaranteed to be as
|
|
1281
|
+
* strict as the reference implementation.
|
|
1282
|
+
* - UTF-8 throughout. Naive `btoa(JSON.stringify(...))` throws on any
|
|
1283
|
+
* non-Latin-1 character (e.g. a merchant description with an emoji or
|
|
1284
|
+
* non-ASCII name); these helpers route through TextEncoder/TextDecoder on
|
|
1285
|
+
* the Web path so multibyte characters round-trip identically on both
|
|
1286
|
+
* runtimes.
|
|
1287
|
+
*/
|
|
1288
|
+
/** Encode a UTF-8 string as standard base64. */
|
|
1289
|
+
declare function encodeBase64Utf8(value: string): string;
|
|
1290
|
+
/** Decode standard or URL-safe base64 to a UTF-8 string. */
|
|
1291
|
+
declare function decodeBase64Utf8(value: string): string;
|
|
1292
|
+
/** Encode a JSON-serializable value as a standard-base64 string. */
|
|
1293
|
+
declare function encodeBase64Json(value: unknown): string;
|
|
1294
|
+
/**
|
|
1295
|
+
* Decode a base64 JSON payload.
|
|
1296
|
+
*
|
|
1297
|
+
* Pass a `label` to get a wrapped error message instead of the raw
|
|
1298
|
+
* JSON/base64 error — call sites parsing untrusted merchant headers use this
|
|
1299
|
+
* to produce actionable failures.
|
|
1300
|
+
*/
|
|
1301
|
+
declare function decodeBase64Json<T>(value: string, label?: string): T;
|
|
1302
|
+
|
|
1303
|
+
export { AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, type AgentPaymentEnumSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, type ClaudeTool, HAVEN_SKILL_MD, type HavenAgent, type HavenAllowance, type HavenAllowanceSummary, HavenApiError, type HavenCatalogEntry, HavenClient, type HavenClientConfig, HavenError, type HavenPaymentReceipt, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, type MachinePaymentChallenge, type MachinePaymentRail, type MachinePaymentReceipt, type MppAuthorizationOptions, type MppQuote, type MppResumeState, type OpenAITool, type PaymentIntent, type PaymentNextAction, type PaymentPhase, type PaymentRequest, type PaymentResult, type PaymentResumeState, type PaymentStatus, type PaymentStatusResult, type PendingApproval, type ResumeAuthorizedMppInput, type ResumeAuthorizedX402Input, type ResumeMppPaymentInput, type ResumeX402PaymentInput, SKILL_FOLDER_NAME, type SharedToolKey, type SignData, type SweepEntry, type SweepResult, type ToolDescription, type X402AuthorizationOptions, type X402ExpectedAuth, type X402ExpectedContext, type X402Intent, type X402PaymentOption, type X402PaymentRequired, type X402Quote, type X402Receipt, type X402RequestSnapshot, type X402ResumeState, addressFromKey, buildMachinePaymentIdempotencyKey, buildX402ExpectedMessage, composeDescription, decodeBase64Json, decodeBase64Utf8, encodeBase64Json, encodeBase64Utf8, encodeMachinePaymentProof, encodePaymentProof, havenTools, parseMachinePaymentChallenge, parseMachinePaymentChallengeResponse, parsePaymentRequired, parsePaymentRequiredResponse, selectPaymentOption, selectStandardPaymentOption, signHash, toStandardPaymentRequirements, toolDescriptions, verifySignature, x402AuthorizationAmount };
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,21 @@ interface HavenClientConfig {
|
|
|
24
24
|
* standard HTTP and never carry Haven-internal headers.
|
|
25
25
|
*/
|
|
26
26
|
defaultHeaders?: Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* JSON-RPC RPC URLs keyed by EIP-155 chain ID.
|
|
29
|
+
*
|
|
30
|
+
* When provided for a chain, the SDK waits for ≥1 on-chain confirmation of
|
|
31
|
+
* the AllowanceModule funding tx before retrying the merchant. This prevents
|
|
32
|
+
* the race where the merchant's `balanceOf(delegate)` call runs before the
|
|
33
|
+
* funding block has propagated to the merchant's RPC node.
|
|
34
|
+
*
|
|
35
|
+
* Without this option the SDK proceeds as soon as Haven's backend confirms
|
|
36
|
+
* submission (backward-compatible default). Set it to a reliable RPC
|
|
37
|
+
* endpoint (e.g. Alchemy / Infura) for production usage.
|
|
38
|
+
*
|
|
39
|
+
* @example { 8453: 'https://mainnet.base.org' }
|
|
40
|
+
*/
|
|
41
|
+
chainRpcs?: Record<number, string>;
|
|
27
42
|
}
|
|
28
43
|
interface PaymentRequest {
|
|
29
44
|
/** Token symbol: "EURe", "USDC.e", or "xDAI" */
|
|
@@ -419,6 +434,30 @@ interface HavenPaymentReceipt {
|
|
|
419
434
|
createdAt: string;
|
|
420
435
|
updatedAt: string;
|
|
421
436
|
}
|
|
437
|
+
/** One transferred asset in a delegate sweep. */
|
|
438
|
+
interface SweepEntry {
|
|
439
|
+
/** 'USDC' or 'ETH' */
|
|
440
|
+
asset: string;
|
|
441
|
+
/** Human-readable amount swept (e.g. "0.12") */
|
|
442
|
+
amount: string;
|
|
443
|
+
/** Atomic amount swept */
|
|
444
|
+
amountAtomic: string;
|
|
445
|
+
/** Transaction hash of the sweep transfer */
|
|
446
|
+
txHash: string;
|
|
447
|
+
/** Block explorer URL for the tx */
|
|
448
|
+
explorerUrl: string;
|
|
449
|
+
}
|
|
450
|
+
/** Result of a `sweepDelegate()` call. */
|
|
451
|
+
interface SweepResult {
|
|
452
|
+
/** Address funds were swept FROM */
|
|
453
|
+
fromAddress: string;
|
|
454
|
+
/** Address funds were swept TO (always the originating Safe) */
|
|
455
|
+
toAddress: string;
|
|
456
|
+
/** Chain the sweep occurred on */
|
|
457
|
+
chainId: number;
|
|
458
|
+
/** One entry per transferred asset. Empty when nothing was stranded. */
|
|
459
|
+
transfers: SweepEntry[];
|
|
460
|
+
}
|
|
422
461
|
type PaymentStateKind = 'payment_intent' | 'approval_request';
|
|
423
462
|
interface AgentPaymentEnumSchema {
|
|
424
463
|
type: 'string';
|
|
@@ -455,6 +494,13 @@ declare const AgentPaymentPhase: {
|
|
|
455
494
|
* funds or the agent's per-token allowance needs to be raised first.
|
|
456
495
|
*/
|
|
457
496
|
readonly InsufficientFunds: "insufficient_funds";
|
|
497
|
+
/**
|
|
498
|
+
* Haven's funding leg (Safe → delegate) confirmed on-chain, but the
|
|
499
|
+
* merchant rejected the x402 retry. The delegate wallet may hold stranded
|
|
500
|
+
* USDC that was never settled to the merchant. The agent should stop, tell
|
|
501
|
+
* the user, and wait for the sweep flow to reclaim the funds.
|
|
502
|
+
*/
|
|
503
|
+
readonly FundedButUnsettled: "funded_but_unsettled";
|
|
458
504
|
};
|
|
459
505
|
type AgentPaymentPhase = (typeof AgentPaymentPhase)[keyof typeof AgentPaymentPhase];
|
|
460
506
|
declare const AgentPaymentNextAction: {
|
|
@@ -480,6 +526,12 @@ declare const AgentPaymentNextAction: {
|
|
|
480
526
|
* can succeed. A user approval will not fix this state on its own.
|
|
481
527
|
*/
|
|
482
528
|
readonly FundSafeOrRaiseAllowance: "fund_safe_or_raise_allowance";
|
|
529
|
+
/**
|
|
530
|
+
* The delegate wallet may hold funds that were sent from the Safe but never
|
|
531
|
+
* settled to the merchant. The wallet owner should initiate a sweep to
|
|
532
|
+
* return those funds to the originating Safe.
|
|
533
|
+
*/
|
|
534
|
+
readonly SweepStrandedFunds: "sweep_stranded_funds";
|
|
483
535
|
};
|
|
484
536
|
type AgentPaymentNextAction = (typeof AgentPaymentNextAction)[keyof typeof AgentPaymentNextAction];
|
|
485
537
|
/**
|
|
@@ -519,8 +571,8 @@ declare const AgentPaymentRail: {
|
|
|
519
571
|
type AgentPaymentRail = (typeof AgentPaymentRail)[keyof typeof AgentPaymentRail];
|
|
520
572
|
type PaymentPhase = AgentPaymentPhase;
|
|
521
573
|
type PaymentNextAction = AgentPaymentNextAction;
|
|
522
|
-
declare const AGENT_PAYMENT_PHASE_VALUES: ("rejected" | "expired" | "failed" | "agent_signature_required" | "payment_submitted" | "payment_confirmed" | "user_approval_required" | "user_execution_required" | "waiting_for_additional_approvals" | "funding_sent" | "insufficient_funds")[];
|
|
523
|
-
declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "fund_safe_or_raise_allowance")[];
|
|
574
|
+
declare const AGENT_PAYMENT_PHASE_VALUES: ("rejected" | "expired" | "failed" | "agent_signature_required" | "payment_submitted" | "payment_confirmed" | "user_approval_required" | "user_execution_required" | "waiting_for_additional_approvals" | "funding_sent" | "insufficient_funds" | "funded_but_unsettled")[];
|
|
575
|
+
declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "fund_safe_or_raise_allowance" | "sweep_stranded_funds")[];
|
|
524
576
|
declare const AGENT_PAYMENT_RAIL_VALUES: ("x402" | "mpp" | "mpp_demo" | "mpp_crypto" | "stripe_deposit" | "spt" | "direct")[];
|
|
525
577
|
declare const AgentPaymentPhaseDescriptions: Record<AgentPaymentPhase, string>;
|
|
526
578
|
declare const AgentPaymentNextActionDescriptions: Record<AgentPaymentNextAction, string>;
|
|
@@ -576,6 +628,24 @@ interface PendingApproval extends PaymentStatusResult {
|
|
|
576
628
|
requested?: string;
|
|
577
629
|
remaining?: string | null;
|
|
578
630
|
}
|
|
631
|
+
/** @internal */
|
|
632
|
+
/** One payable service in Haven's curated merchant catalog. */
|
|
633
|
+
interface HavenCatalogEntry {
|
|
634
|
+
id: string;
|
|
635
|
+
name: string;
|
|
636
|
+
description: string;
|
|
637
|
+
category: string;
|
|
638
|
+
resourceUrl: string;
|
|
639
|
+
rail: 'x402' | 'mpp';
|
|
640
|
+
protocol: 'http' | 'mcp';
|
|
641
|
+
toolName: string | null;
|
|
642
|
+
priceDisplay: string | null;
|
|
643
|
+
priceAtomic: string | null;
|
|
644
|
+
asset: string | null;
|
|
645
|
+
network: string | null;
|
|
646
|
+
status: 'active' | 'degraded' | 'delisted';
|
|
647
|
+
verifiedAt: string | null;
|
|
648
|
+
}
|
|
579
649
|
declare class HavenError extends Error {
|
|
580
650
|
readonly code: string;
|
|
581
651
|
readonly statusCode?: number | undefined;
|
|
@@ -609,6 +679,7 @@ declare class HavenClient {
|
|
|
609
679
|
private readonly requestTimeout;
|
|
610
680
|
private readonly confirmationTimeout;
|
|
611
681
|
private readonly pollingInterval;
|
|
682
|
+
private readonly chainRpcs;
|
|
612
683
|
private readonly inFlightX402;
|
|
613
684
|
private readonly x402ReceiptCache;
|
|
614
685
|
private readonly inFlightMachinePayments;
|
|
@@ -625,6 +696,8 @@ declare class HavenClient {
|
|
|
625
696
|
* the same time — see their own headers without stepping on each other.
|
|
626
697
|
*/
|
|
627
698
|
private readonly requestContext;
|
|
699
|
+
/** Monotonic JSON-RPC id source for the MCP `initialize` handshake. */
|
|
700
|
+
private mcpRequestId;
|
|
628
701
|
/** Delegate address derived from the private key (if provided) */
|
|
629
702
|
readonly delegateAddress: string | undefined;
|
|
630
703
|
constructor(config: HavenClientConfig);
|
|
@@ -707,10 +780,31 @@ declare class HavenClient {
|
|
|
707
780
|
* Get the agent identity tied to this API key.
|
|
708
781
|
*/
|
|
709
782
|
getAgent(): Promise<HavenAgent>;
|
|
783
|
+
/**
|
|
784
|
+
* Sweep stranded USDC and ETH from the delegate EOA back to the originating Safe.
|
|
785
|
+
*
|
|
786
|
+
* The delegate key held by this client signs and submits the transfer transactions
|
|
787
|
+
* directly — Haven's backend never handles the key or constructs signed txs
|
|
788
|
+
* (CASP/MiCA Red Line #2). Funds always go to the Safe linked to this agent.
|
|
789
|
+
*
|
|
790
|
+
* Requires `chainRpcs` to be set for the agent's chain in `HavenClientConfig`.
|
|
791
|
+
*/
|
|
792
|
+
sweepDelegate(): Promise<SweepResult>;
|
|
710
793
|
/**
|
|
711
794
|
* Get configured and on-chain allowances for the authenticated agent.
|
|
712
795
|
*/
|
|
713
796
|
getAllowances(): Promise<HavenAllowanceSummary>;
|
|
797
|
+
/**
|
|
798
|
+
* Discover payable services from Haven's curated merchant catalog.
|
|
799
|
+
*
|
|
800
|
+
* Read-only: returns catalog entries (price, rail, protocol) so an agent
|
|
801
|
+
* can choose a service and pay it with the regular payment tools in the
|
|
802
|
+
* same session. Never creates payments or signatures.
|
|
803
|
+
*/
|
|
804
|
+
discoverTools(options?: {
|
|
805
|
+
category?: string;
|
|
806
|
+
rail?: 'x402' | 'mpp';
|
|
807
|
+
}): Promise<HavenCatalogEntry[]>;
|
|
714
808
|
/**
|
|
715
809
|
* List recent machine-payment receipts/evidence for bookkeeping.
|
|
716
810
|
*/
|
|
@@ -761,9 +855,44 @@ declare class HavenClient {
|
|
|
761
855
|
* const data = await response.json()
|
|
762
856
|
* ```
|
|
763
857
|
*
|
|
858
|
+
* **MCP-over-x402 auto-handshake (issue #315):** when the endpoint is
|
|
859
|
+
* MCP-shaped — the URL path ends in `/mcp`, or the 402 body carries a
|
|
860
|
+
* Coinbase Bazaar `extensions.bazaar` block — the SDK runs the MCP
|
|
861
|
+
* `initialize` handshake, threads the resulting `mcp-session-id`,
|
|
862
|
+
* `Accept: application/json, text/event-stream`, and `x402-wallet` headers
|
|
863
|
+
* through every request, and collapses SSE responses to the JSON-RPC
|
|
864
|
+
* `result`. The caller just passes `(url, { body })` and never sees the
|
|
865
|
+
* protocol plumbing. A non-MCP server (handshake error / no session id)
|
|
866
|
+
* falls back to standard x402 behaviour.
|
|
867
|
+
*
|
|
764
868
|
* Requires `delegateKey` to be set in the client config.
|
|
765
869
|
*/
|
|
766
870
|
fetch(url: string, init?: RequestInit, options?: X402AuthorizationOptions): Promise<Response>;
|
|
871
|
+
/**
|
|
872
|
+
* Run the MCP `initialize` handshake against a Streamable-HTTP endpoint and
|
|
873
|
+
* return the `mcp-session-id` the server assigns.
|
|
874
|
+
*
|
|
875
|
+
* Returns `undefined` whenever the endpoint is not actually an MCP server —
|
|
876
|
+
* a transport/HTTP error, a missing session id, or a JSON-RPC error in the
|
|
877
|
+
* handshake response — so the caller can fall back to plain x402.
|
|
878
|
+
*/
|
|
879
|
+
private mcpInitialize;
|
|
880
|
+
/**
|
|
881
|
+
* Send the MCP `notifications/initialized` notification that completes the
|
|
882
|
+
* lifecycle handshake. Best-effort: the session is already established, so a
|
|
883
|
+
* failed notification must not abort the payment.
|
|
884
|
+
*/
|
|
885
|
+
private mcpNotifyInitialized;
|
|
886
|
+
/** Read a single JSON-RPC message from an MCP response (JSON or SSE body). */
|
|
887
|
+
private readMcpMessage;
|
|
888
|
+
/** Add the MCP transport headers (session id + SSE Accept) to a request. */
|
|
889
|
+
private withMcpHeaders;
|
|
890
|
+
/**
|
|
891
|
+
* Collapse an MCP SSE response into a plain JSON response carrying the
|
|
892
|
+
* JSON-RPC `result`, so callers of `fetch()` never see raw SSE framing.
|
|
893
|
+
* Non-SSE responses pass through untouched.
|
|
894
|
+
*/
|
|
895
|
+
private surfaceMcpResult;
|
|
767
896
|
/**
|
|
768
897
|
* Probe a paid MPP endpoint or inspect an existing challenge without creating
|
|
769
898
|
* a Haven payment or approval request.
|
|
@@ -791,6 +920,16 @@ declare class HavenClient {
|
|
|
791
920
|
private mapMachinePaymentReceiptFromStatus;
|
|
792
921
|
private recordMerchantRetryRejected;
|
|
793
922
|
private reportMachinePaymentEvidence;
|
|
923
|
+
/**
|
|
924
|
+
* Wait for a funding tx to be mined with ≥1 confirmation before the
|
|
925
|
+
* merchant retry, eliminating the race where the merchant's
|
|
926
|
+
* `balanceOf(delegate)` runs before the funding block propagates.
|
|
927
|
+
*
|
|
928
|
+
* Skipped when `chainRpcs` does not include the chain; in that case Haven's
|
|
929
|
+
* backend has already confirmed on-chain submission and callers accept the
|
|
930
|
+
* small propagation window as a trade-off for not configuring an RPC URL.
|
|
931
|
+
*/
|
|
932
|
+
private waitForFundingTx;
|
|
794
933
|
private throwIfNonSignableAuthorizationState;
|
|
795
934
|
private throwPaymentStateError;
|
|
796
935
|
private paymentStateFromRaw;
|
|
@@ -1005,9 +1144,54 @@ declare const toolDescriptions: {
|
|
|
1005
1144
|
readonly behavior: "Returns the agent's recent machine-payment receipts ordered by recency. Proof header values are not returned.";
|
|
1006
1145
|
readonly nextActionGuidance: "";
|
|
1007
1146
|
};
|
|
1147
|
+
readonly payMcpTool: {
|
|
1148
|
+
readonly summary: "Call a named tool on an MCP merchant that requires an x402 payment, handling the full initialize → pay → retry round trip.";
|
|
1149
|
+
readonly selectionGuidance: string;
|
|
1150
|
+
readonly behavior: string;
|
|
1151
|
+
readonly nextActionGuidance: string;
|
|
1152
|
+
};
|
|
1153
|
+
readonly discoverTools: {
|
|
1154
|
+
readonly summary: "Discover payable services from Haven's curated merchant catalog — names, prices, and which pay tool to use.";
|
|
1155
|
+
readonly selectionGuidance: string;
|
|
1156
|
+
readonly behavior: string;
|
|
1157
|
+
readonly nextActionGuidance: "Pick an entry, confirm the price with the user if it is non-trivial, and pay it with the tool named in suggested_tool, passing the entry's resource_url (and tool_name for MCP merchants).";
|
|
1158
|
+
};
|
|
1159
|
+
readonly sweep_delegate: {
|
|
1160
|
+
readonly summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating Safe.";
|
|
1161
|
+
readonly selectionGuidance: string;
|
|
1162
|
+
readonly behavior: string;
|
|
1163
|
+
readonly nextActionGuidance: "If transfers is non-empty, confirm the amounts with the user. No further action required — funds are on their way back to the Safe.";
|
|
1164
|
+
};
|
|
1165
|
+
readonly send: {
|
|
1166
|
+
readonly summary: "Send ETH or USDC directly from the agent's Haven wallet to a recipient address.";
|
|
1167
|
+
readonly selectionGuidance: string;
|
|
1168
|
+
readonly behavior: string;
|
|
1169
|
+
readonly nextActionGuidance: string;
|
|
1170
|
+
};
|
|
1008
1171
|
};
|
|
1009
1172
|
type SharedToolKey = keyof typeof toolDescriptions;
|
|
1010
1173
|
|
|
1174
|
+
/**
|
|
1175
|
+
* The generic Haven payment skill — canonical copy.
|
|
1176
|
+
*
|
|
1177
|
+
* This SDK file is the single source of truth for the generic, secret-free
|
|
1178
|
+
* skill content: no wallet address, no budget numbers, no per-agent values.
|
|
1179
|
+
* The agent learns its identity and live budget at runtime via the
|
|
1180
|
+
* `haven_get_agent` / `haven_get_allowances` MCP tools, so the same file works
|
|
1181
|
+
* for every user. `packages/connect` imports this directly to auto-install the
|
|
1182
|
+
* skill into runtime skills folders.
|
|
1183
|
+
*
|
|
1184
|
+
* `packages/frontend/src/lib/agent-skill-bundle.ts` keeps a deliberately
|
|
1185
|
+
* decoupled inline copy (the download fallback): frontend has zero
|
|
1186
|
+
* `@haven_ai/*` dependencies so it can deploy standalone on Vercel without an
|
|
1187
|
+
* unpublished SDK export. A parity test in that package's test suite imports
|
|
1188
|
+
* this canonical string and asserts byte-for-byte equality, so the two copies
|
|
1189
|
+
* cannot drift.
|
|
1190
|
+
*/
|
|
1191
|
+
declare const HAVEN_SKILL_MD = "---\nname: haven-pay\ndescription: Pay for things from the user's Haven wallet within their agent rules. Use when the user asks to send, pay, tip, or transfer crypto \u2014 or when a request hits an HTTP 402 (x402) paywall.\n---\n\n# Haven: pay from a Haven wallet\n\nThis skill lets the agent make payments from the user's Haven wallet through\nthe Haven MCP tools. Every payment is checked against the agent's on-chain\nbudget before money moves; payments above the remaining budget wait for the\nuser's approval in Haven.\n\n## When to use this skill\n\n- The user asks to send money, pay someone, tip, donate, or transfer tokens.\n- A request returns HTTP 402 (x402): use the Haven pay tools to settle it,\n then retry the original request.\n\n## Identity and budget come from the tools \u2014 never assume them\n\nDo not guess the wallet address, network, or budget. Read them live:\n\n- `haven_get_agent` \u2014 agent identity, Haven wallet address, network.\n- `haven_get_allowances` \u2014 current per-token budgets and what remains.\n\nBudgets reset on a period the user chose. If a payment exceeds the remaining\nbudget it is queued for the user to approve in the Haven dashboard \u2014 this is\nnormal, not an error.\n\n## Paying\n\n- **Direct transfer:** `haven_pay` with recipient, amount, and token.\n- **x402 paywall:** `haven_quote_x402` to get a quote, then\n `haven_pay_x402_quote`. In the hosted setup the signing step happens in\n the local Haven signer; follow the tool results \u2014 they tell you the next\n action at every step. Retry the original request only when the result says\n `retry_original_x402_request`.\n- **Status:** `haven_get_payment_status` with a `payment_id` to check on\n queued or in-flight payments. Do not poll in a tight loop.\n\n## Approval semantics\n\n- A result with `pending_approval` means the payment exceeded the remaining\n budget and is waiting for the user in Haven. Tell the user, then check\n status later.\n- Never ask the user for private keys and never try to sign anything\n yourself \u2014 Haven signs. If a tool reports a missing or invalid credential,\n tell the user to re-run the Haven setup command.\n\n## Failure handling\n\nHaven errors are shaped `{ error, status, details? }` and written for\nhumans \u2014 surface the message verbatim. Common cases:\n\n- `pending_approval`: queued for the user's approval (see above).\n- `insufficient_funds`: the Haven wallet doesn't hold enough of that token.\n Suggest the user add funds in the Haven dashboard.\n- Budget exceeded: tell the user how much remains (from\n `haven_get_allowances`) and that they can raise the budget in Haven.\n\n## Revoke\n\nIf this agent's credential may have leaked, tell the user to pause or revoke\nthe agent in the Haven dashboard under Agents. New requests stop immediately\nfor that credential.\n";
|
|
1192
|
+
/** Directory name for the installed skill folder. */
|
|
1193
|
+
declare const SKILL_FOLDER_NAME = "haven-pay";
|
|
1194
|
+
|
|
1011
1195
|
/**
|
|
1012
1196
|
* x402 protocol support for the Haven SDK.
|
|
1013
1197
|
*
|
|
@@ -1078,4 +1262,42 @@ declare function parseMachinePaymentChallengeResponse(response: Response): Promi
|
|
|
1078
1262
|
declare function buildMachinePaymentIdempotencyKey(challenge: MachinePaymentChallenge): string;
|
|
1079
1263
|
declare function encodeMachinePaymentProof(receipt: Omit<MachinePaymentReceipt, 'proofHeader'>): string;
|
|
1080
1264
|
|
|
1081
|
-
|
|
1265
|
+
/**
|
|
1266
|
+
* Runtime-agnostic base64 helpers — the single source of truth for the wire
|
|
1267
|
+
* encoding shared by the SDK and the edge signer (#325).
|
|
1268
|
+
*
|
|
1269
|
+
* Why this module exists: the SDK used `atob`/`btoa` (Web globals) while the
|
|
1270
|
+
* signer used `Buffer` (Node-only). Both worked because both currently run in
|
|
1271
|
+
* Node ≥ 16, but the duplication was a latent wire-incompatibility — and the
|
|
1272
|
+
* signer is headed for non-Node runtimes (browsers, Cloudflare Workers) where
|
|
1273
|
+
* `Buffer` does not exist (#314).
|
|
1274
|
+
*
|
|
1275
|
+
* Encoding contract:
|
|
1276
|
+
* - Output is ALWAYS standard base64 (`+`, `/`, padded). The x402 protocol's
|
|
1277
|
+
* reference implementation validates headers against
|
|
1278
|
+
* `/^[A-Za-z0-9+/]*={0,2}$/` — URL-safe output would be rejected.
|
|
1279
|
+
* - Decoding is tolerant: URL-safe input (`-`, `_`, unpadded) is normalized
|
|
1280
|
+
* before decoding, since third-party merchants are not guaranteed to be as
|
|
1281
|
+
* strict as the reference implementation.
|
|
1282
|
+
* - UTF-8 throughout. Naive `btoa(JSON.stringify(...))` throws on any
|
|
1283
|
+
* non-Latin-1 character (e.g. a merchant description with an emoji or
|
|
1284
|
+
* non-ASCII name); these helpers route through TextEncoder/TextDecoder on
|
|
1285
|
+
* the Web path so multibyte characters round-trip identically on both
|
|
1286
|
+
* runtimes.
|
|
1287
|
+
*/
|
|
1288
|
+
/** Encode a UTF-8 string as standard base64. */
|
|
1289
|
+
declare function encodeBase64Utf8(value: string): string;
|
|
1290
|
+
/** Decode standard or URL-safe base64 to a UTF-8 string. */
|
|
1291
|
+
declare function decodeBase64Utf8(value: string): string;
|
|
1292
|
+
/** Encode a JSON-serializable value as a standard-base64 string. */
|
|
1293
|
+
declare function encodeBase64Json(value: unknown): string;
|
|
1294
|
+
/**
|
|
1295
|
+
* Decode a base64 JSON payload.
|
|
1296
|
+
*
|
|
1297
|
+
* Pass a `label` to get a wrapped error message instead of the raw
|
|
1298
|
+
* JSON/base64 error — call sites parsing untrusted merchant headers use this
|
|
1299
|
+
* to produce actionable failures.
|
|
1300
|
+
*/
|
|
1301
|
+
declare function decodeBase64Json<T>(value: string, label?: string): T;
|
|
1302
|
+
|
|
1303
|
+
export { AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, type AgentPaymentEnumSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, type ClaudeTool, HAVEN_SKILL_MD, type HavenAgent, type HavenAllowance, type HavenAllowanceSummary, HavenApiError, type HavenCatalogEntry, HavenClient, type HavenClientConfig, HavenError, type HavenPaymentReceipt, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, type MachinePaymentChallenge, type MachinePaymentRail, type MachinePaymentReceipt, type MppAuthorizationOptions, type MppQuote, type MppResumeState, type OpenAITool, type PaymentIntent, type PaymentNextAction, type PaymentPhase, type PaymentRequest, type PaymentResult, type PaymentResumeState, type PaymentStatus, type PaymentStatusResult, type PendingApproval, type ResumeAuthorizedMppInput, type ResumeAuthorizedX402Input, type ResumeMppPaymentInput, type ResumeX402PaymentInput, SKILL_FOLDER_NAME, type SharedToolKey, type SignData, type SweepEntry, type SweepResult, type ToolDescription, type X402AuthorizationOptions, type X402ExpectedAuth, type X402ExpectedContext, type X402Intent, type X402PaymentOption, type X402PaymentRequired, type X402Quote, type X402Receipt, type X402RequestSnapshot, type X402ResumeState, addressFromKey, buildMachinePaymentIdempotencyKey, buildX402ExpectedMessage, composeDescription, decodeBase64Json, decodeBase64Utf8, encodeBase64Json, encodeBase64Utf8, encodeMachinePaymentProof, encodePaymentProof, havenTools, parseMachinePaymentChallenge, parseMachinePaymentChallengeResponse, parsePaymentRequired, parsePaymentRequiredResponse, selectPaymentOption, selectStandardPaymentOption, signHash, toStandardPaymentRequirements, toolDescriptions, verifySignature, x402AuthorizationAmount };
|