@haven_ai/sdk 0.8.0-alpha.0 → 0.9.0-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.
Files changed (39) hide show
  1. package/dist/base64-BZDPJ8M1.d.ts +1344 -0
  2. package/dist/base64-Cyxhsvqd.d.cts +1344 -0
  3. package/dist/{chunk-UXULZ3ZY.js → chunk-424S4QMG.js} +10 -5
  4. package/dist/chunk-424S4QMG.js.map +1 -0
  5. package/dist/{chunk-HX34HOW4.cjs → chunk-4Z6ATE44.cjs} +2 -2
  6. package/dist/chunk-4Z6ATE44.cjs.map +1 -0
  7. package/dist/chunk-7UTWSJC5.cjs +106 -0
  8. package/dist/chunk-7UTWSJC5.cjs.map +1 -0
  9. package/dist/{chunk-H4APV67M.js → chunk-J7N4LUZZ.js} +2 -2
  10. package/dist/chunk-J7N4LUZZ.js.map +1 -0
  11. package/dist/chunk-VRKWNJ7H.js +103 -0
  12. package/dist/chunk-VRKWNJ7H.js.map +1 -0
  13. package/dist/{chunk-WJFDXCYP.cjs → chunk-ZDKNPNI3.cjs} +41 -35
  14. package/dist/chunk-ZDKNPNI3.cjs.map +1 -0
  15. package/dist/edge.cjs +97 -89
  16. package/dist/edge.d.cts +4 -2
  17. package/dist/edge.d.ts +4 -2
  18. package/dist/edge.js +4 -4
  19. package/dist/index.cjs +1033 -490
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +103 -147
  22. package/dist/index.d.ts +103 -147
  23. package/dist/index.js +705 -189
  24. package/dist/index.js.map +1 -1
  25. package/dist/receipt-D4Roey3D.d.cts +130 -0
  26. package/dist/receipt-WkXHZGbu.d.ts +130 -0
  27. package/dist/test-support.cjs +71 -18
  28. package/dist/test-support.cjs.map +1 -1
  29. package/dist/test-support.d.cts +21 -1
  30. package/dist/test-support.d.ts +21 -1
  31. package/dist/test-support.js +53 -3
  32. package/dist/test-support.js.map +1 -1
  33. package/dist/{base64-znjJJQqu.d.cts → types-CrszUJ7Z.d.cts} +208 -1306
  34. package/dist/{base64-znjJJQqu.d.ts → types-CrszUJ7Z.d.ts} +208 -1306
  35. package/package.json +1 -1
  36. package/dist/chunk-H4APV67M.js.map +0 -1
  37. package/dist/chunk-HX34HOW4.cjs.map +0 -1
  38. package/dist/chunk-UXULZ3ZY.js.map +0 -1
  39. package/dist/chunk-WJFDXCYP.cjs.map +0 -1
@@ -1,5 +1,129 @@
1
- import { PaymentRequirements } from 'x402/types';
2
- import { Hex, Address } from 'viem';
1
+ /**
2
+ * #3747: the hosted merchant-egress policy.
3
+ *
4
+ * Hosted Haven sends requests to merchant URLs agents choose. This module is
5
+ * the STRING-LEVEL policy those requests run under when the embedder opts in
6
+ * (`HavenClientConfig.merchantEgress`, set by `createHostedHavenClient`):
7
+ * https only, no IP-literal hosts, no local or internal names, re-checked GET
8
+ * redirects, and per-use budgets (timeouts, a response byte cap enforced
9
+ * WHILE reading — never after buffering).
10
+ *
11
+ * Scope and limits, stated plainly:
12
+ *
13
+ * - The policy is checked before every request and every redirect hop, but
14
+ * it is a string check. A public host name whose DNS ANSWER points at
15
+ * private space is NOT blocked here — that needs the resolution-time
16
+ * checks parked in #3742–#3744 (owner-accepted residual, 2026-10-07).
17
+ * - Without `merchantEgress`, NOTHING in the SDK changes: no `redirect:
18
+ * 'manual'`, no body capping, no extra refusals. SDK, local-MCP and
19
+ * embedder callers keep today's behaviour byte for byte.
20
+ * - The policy is network policy, not spend control. It never gates a
21
+ * payment's authority — the on-chain allowance stays the real control
22
+ * (CASP: off-chain policy is never the spend control).
23
+ */
24
+ /** Which merchant use a budget applies to, so each use's timeout is pinnable. */
25
+ type MerchantEgressUse = 'quote' | 'mcpSession' | 'discovery' | 'delivery';
26
+ interface MerchantEgressTimeouts {
27
+ /** Quote probes (`quoteX402`, resume probes) — short. */
28
+ quote?: number;
29
+ /** MCP session setup (`initialize`) — short. */
30
+ mcpSession?: number;
31
+ /** Discovery fetches — short (the #1271 budget is 5s). */
32
+ discovery?: number;
33
+ /** Paid delivery — finite (today's default is 300s). */
34
+ delivery?: number;
35
+ }
36
+ interface MerchantEgressPolicy {
37
+ /**
38
+ * Refuse a URL before any request (or redirect hop) connects. Throws
39
+ * `MerchantEgressRefusedError` with `beforeRequest: true`; the transport
40
+ * re-marks hop-time refusals as mid-flight.
41
+ */
42
+ assertUrl(url: string): void;
43
+ /**
44
+ * Response byte cap, enforced while the body is being read (the stream
45
+ * errors mid-read) — never by buffering first. `undefined` = no cap.
46
+ */
47
+ maxResponseBytes?: number;
48
+ /**
49
+ * How many GET redirects may be followed; EVERY hop is re-asserted against
50
+ * `assertUrl` before it connects. A redirect on any other method is
51
+ * refused outright. `undefined` = no redirect following.
52
+ */
53
+ maxGetRedirects?: number;
54
+ /** Per-use timeouts (ms). The effective deadline is `min(this, merchantTimeout)`. */
55
+ timeouts?: MerchantEgressTimeouts;
56
+ /**
57
+ * Per-use response byte caps (#3747 spec review), enforced while the body
58
+ * is being read. A use absent here falls back to `maxResponseBytes`.
59
+ */
60
+ responseByteCaps?: Partial<Record<MerchantEgressUse, number>>;
61
+ }
62
+ type MerchantEgressRefusalReason = 'url_not_allowed' | 'redirect_on_non_get' | 'redirect_missing_location' | 'redirect_invalid_location' | 'redirect_budget_exceeded';
63
+ declare const MERCHANT_EGRESS_REFUSED_CODE = "MERCHANT_EGRESS_REFUSED";
64
+ /**
65
+ * The policy refused a merchant request. `beforeRequest` is true when the
66
+ * refusal happened BEFORE any request of that merchant use was sent (nothing
67
+ * is on the wire); false when it happened mid-flight — the initial request
68
+ * was already sent (a redirect answered, a hop refused, a body mid-read),
69
+ * which after a PAID delivery means the payment header may have been
70
+ * delivered and the money is in the verify-then-sweep state (#1300).
71
+ */
72
+ declare class MerchantEgressRefusedError extends HavenError {
73
+ readonly url: string;
74
+ readonly refusal: MerchantEgressRefusalReason;
75
+ readonly beforeRequest: boolean;
76
+ constructor(message: string, url: string, refusal: MerchantEgressRefusalReason, beforeRequest: boolean);
77
+ }
78
+ declare const MERCHANT_EGRESS_RESPONSE_CAP_CODE = "MERCHANT_EGRESS_RESPONSE_CAP";
79
+ /**
80
+ * A response body grew past `maxResponseBytes` WHILE it was being read —
81
+ * the read was aborted mid-stream, never buffered past the cap. Always
82
+ * mid-flight: the request was already sent.
83
+ */
84
+ declare class MerchantEgressResponseCapError extends HavenError {
85
+ readonly url: string | undefined;
86
+ readonly limitBytes: number;
87
+ constructor(message: string, limitBytes: number, url?: string);
88
+ }
89
+ /**
90
+ * The strict hosted string check: https (any port), no IP literals (v4 or
91
+ * v6 — `URL` normalises the exotic spellings to these two shapes before this
92
+ * runs, as #3112 established for the retry-target check), no `localhost`, no
93
+ * single-label host, none of the internal/reserved suffixes. `true` for
94
+ * exactly the URLs a hosted merchant request may connect to.
95
+ */
96
+ declare function isPublicHttpsMerchantUrl(url: string): boolean;
97
+ /** Human-readable reason a URL failed `isPublicHttpsMerchantUrl`. */
98
+ declare function publicHttpsMerchantUrlRefusal(url: string): string;
99
+ /**
100
+ * The `assertUrl` half of the strict hosted policy: throws
101
+ * `MerchantEgressRefusedError` (beforeRequest: true) unless the URL is a
102
+ * public https URL. Message names the offending URL (agent-chosen input —
103
+ * never a RESOLVED address; this policy never resolves DNS).
104
+ */
105
+ declare function assertPublicHttpsMerchantUrl(url: string): void;
106
+ /** #1271's discovery budget, reused as the floor for hosted discovery reads. */
107
+ declare const HOSTED_DISCOVERY_TIMEOUT_MS = 5000;
108
+ /** Hosted per-use timeouts: short probes, finite paid delivery. */
109
+ declare const HOSTED_EGRESS_TIMEOUTS: Required<MerchantEgressTimeouts>;
110
+ /** Hosted per-use byte caps (#3747 spec review, owner-delegated values). */
111
+ declare const HOSTED_RESPONSE_BYTE_CAPS: Required<Record<MerchantEgressUse, number>>;
112
+ /** Hosted GET-redirect budget: every hop re-checked against the URL rules. */
113
+ declare const HOSTED_MAX_GET_REDIRECTS = 3;
114
+ /**
115
+ * The strict hosted policy `createHostedHavenClient` installs. Deliberately
116
+ * exported so the budgets are pinnable in tests and a deployment can build
117
+ * its own variant beside it.
118
+ */
119
+ declare function strictMerchantEgressPolicy(): MerchantEgressPolicy;
120
+ /**
121
+ * Read a response body as text with a byte cap enforced WHILE reading: the
122
+ * moment the stream grows past `maxBytes` the read is cancelled and a
123
+ * `MerchantEgressResponseCapError` is thrown — nothing is buffered past the
124
+ * cap, and a body that never ends cannot hold the read open.
125
+ */
126
+ declare function readBodyCapped(response: Response, maxBytes: number): Promise<string>;
3
127
 
4
128
  interface HavenClientConfig {
5
129
  /** Haven API key (sk_agent_xxx) */
@@ -17,6 +141,16 @@ interface HavenClientConfig {
17
141
  * merchants may settle on-chain synchronously, so the default is
18
142
  * deliberately generous. #1300. */
19
143
  merchantTimeout?: number;
144
+ /**
145
+ * #3747: optional string-level merchant-egress policy. When set, EVERY
146
+ * merchant request (and every redirect hop) is checked against it before
147
+ * connecting; GET redirects are followed `manual` with re-checked hops;
148
+ * response bodies are capped WHILE being read; per-use timeouts apply.
149
+ * Absent — the SDK, local-MCP and embedder default — behaviour is
150
+ * unchanged. This is network policy, never spend control: the on-chain
151
+ * allowance remains the real control. See `merchant-egress.ts`.
152
+ */
153
+ merchantEgress?: MerchantEgressPolicy;
20
154
  /** Timeout in ms when polling for tx confirmation (default: 90000) */
21
155
  confirmationTimeout?: number;
22
156
  /** Polling interval in ms when waiting for confirmation (default: 3000) */
@@ -441,6 +575,13 @@ interface X402McpCallContext {
441
575
  toolName: string;
442
576
  arguments?: Record<string, unknown>;
443
577
  mcpTransport?: X402McpTransport;
578
+ /**
579
+ * #3781: Haven's own catalog row name, when the purchase came from a
580
+ * catalog entry — persisted with the context so a settle can report the
581
+ * catalog row's name as the display product. Optional — omit for a direct
582
+ * `haven_pay_mcp_tool` call. Haven-derived, never merchant content (#1349).
583
+ */
584
+ catalogName?: string;
444
585
  }
445
586
  /**
446
587
  * Response shape of `getX402MerchantCallContext` — the stored merchant call
@@ -452,6 +593,28 @@ interface X402MerchantCallContext {
452
593
  toolName: string;
453
594
  arguments: Record<string, unknown>;
454
595
  mcpTransport?: X402McpTransport;
596
+ /** #3781: the catalog row's name, when the purchase came from a catalog entry. */
597
+ catalogName?: string;
598
+ }
599
+ /**
600
+ * Response shape of `findX402IntentByIdempotencyKey` — the read-only state of
601
+ * the caller's own x402 intent for an idempotency key (#3739).
602
+ */
603
+ interface X402IntentByKey {
604
+ paymentId: string;
605
+ status: string;
606
+ /** `null` when the stored row does not say (never guessed). */
607
+ settlementScheme: 'erc7710' | 'eip3009' | null;
608
+ resourceUrl: string | null;
609
+ expiresAt: string | null;
610
+ /** True only for a `pending_signature` intent whose `expiresAt` is still in the future. */
611
+ windowOpen: boolean;
612
+ taskBudgetId: string | null;
613
+ /** Atomic amount, as a string. */
614
+ amountAtomic: string;
615
+ /** #3739 review: token contract of `amountAtomic`, so a whole-token cap can be converted. */
616
+ asset: string | null;
617
+ network: string;
455
618
  }
456
619
  /** Quote parsed from an HTTP 402 response without creating a Haven payment. */
457
620
  interface X402Quote {
@@ -559,6 +722,19 @@ interface HavenAllowance {
559
722
  tokenSymbol: string;
560
723
  configuredAmount: string;
561
724
  resetPeriodMin: number;
725
+ /**
726
+ * #3731: whether the account's balance can back THIS row's WHOLE remaining
727
+ * period budget. `false` is a heads-up to mention to the user, never a
728
+ * refusal — a budget larger than the balance is a normal setup (an owner
729
+ * may top up weekly) and says nothing certain about the next payment;
730
+ * `null` when unverifiable (the chain read failed, or `remaining` was not
731
+ * read live — `onchain.remainingIsFromChain` false). Always present: any
732
+ * non-boolean wire value, including an absent one, maps to `null` rather
733
+ * than `undefined`. The key is absent on the WIRE when the remaining is 0
734
+ * (`balance >= 0` would be a vacuous true). Rows for one token are each
735
+ * compared alone — they do not add up. Never a balance figure.
736
+ */
737
+ fundsCoverRemaining: boolean | null;
562
738
  /**
563
739
  * #3518: this budget's SCOPE, so an agent holding more than one budget
564
740
  * for a token can name the merchant-locked one before paying. The
@@ -767,9 +943,13 @@ interface HavenBalanceCoverage {
767
943
  * call returns, so it surfaces as an API error rather than `revoked`. `revoked`
768
944
  * is reached when the request authenticates but the agent status is non-active.
769
945
  *
770
- * Wallet token balance is intentionally NOT folded in here: the on-chain
771
- * remaining allowance is the gate Haven enforces, and insufficient wallet
772
- * funding surfaces at pay time as INSUFFICIENT_FUNDS.
946
+ * Wallet token balance is intentionally NOT folded into the readiness value
947
+ * itself — `ready` stays an AUTHORITY signal (installed consumers switch on
948
+ * its value set) — but the account's ability to back it is reported beside
949
+ * it: the allowances rows carry `fundsCoverRemaining` (#3731), null when
950
+ * unverifiable, and an underfunded prepare surfaces at pay time as
951
+ * `PREPARE_REVERTED` with `revert_cause: "insufficient_balance"`, never
952
+ * `INSUFFICIENT_FUNDS`.
773
953
  */
774
954
  type HavenAgentReadiness = 'ready' | 'needs_approval' | 'revoked';
775
955
  /**
@@ -798,6 +978,14 @@ interface HavenAgentAllowanceSummary {
798
978
  configuredAmount: string;
799
979
  resetPeriodMin: number;
800
980
  isResetPending: boolean;
981
+ /**
982
+ * #3731: the {@link HavenAllowance.fundsCoverRemaining} projection —
983
+ * whether the account's balance can back this row's whole remaining
984
+ * period budget. `false` is a heads-up to mention to the user, not a
985
+ * refusal; `null` when unverifiable. Same provenance rule as the detailed
986
+ * read: any non-boolean wire value maps to `null`, never `undefined`.
987
+ */
988
+ fundsCoverRemaining: boolean | null;
801
989
  }
802
990
  /**
803
991
  * One-shot "am I ready?" bootstrap: identity + live spend authority + a
@@ -1811,6 +1999,20 @@ interface HavenCatalogEntry {
1811
1999
  protocol: 'http' | 'mcp';
1812
2000
  toolName: string | null;
1813
2001
  toolArguments: Record<string, unknown> | null;
2002
+ /**
2003
+ * #3769: the row's declared JSON Schema for a per-call MCP tool's caller
2004
+ * arguments — `haven_prepare_catalog_purchase` validates an `arguments`
2005
+ * input against it. NULL/absent on a fixed-SKU row, which refuses caller
2006
+ * arguments. OPTIONAL on purpose: an installed SDK may face a backend
2007
+ * predating #3769.
2008
+ */
2009
+ toolArgumentsSchema?: Record<string, unknown> | null;
2010
+ /** #3769: the HTTP method a plain-HTTP resource needs (null = GET). OPTIONAL like the schema above. */
2011
+ httpMethod?: string | null;
2012
+ /** #3769: the body encoding of `bodyExample` — 'json' today. OPTIONAL like the schema above. */
2013
+ bodyType?: string | null;
2014
+ /** #3769: an example body the row's discovery hint carries. OPTIONAL like the schema above. */
2015
+ bodyExample?: Record<string, unknown> | null;
1814
2016
  priceDisplay: string | null;
1815
2017
  priceAtomic: string | null;
1816
2018
  asset: string | null;
@@ -2094,1304 +2296,4 @@ declare class HavenTimeoutError extends HavenError {
2094
2296
  constructor(paymentId: string);
2095
2297
  }
2096
2298
 
2097
- /**
2098
- * Gasless delegate-sweep primitives — the single source of truth shared by the
2099
- * edge signer (which signs) and the Haven backend (which relays).
2100
- *
2101
- * A stranded delegate EOA holds USDC but no ETH, so a raw ERC-20 transfer can't
2102
- * pay for its own gas. Instead the delegate signs an *off-chain* EIP-3009
2103
- * `TransferWithAuthorization` and the Haven relayer submits it on-chain and pays
2104
- * gas. The relayer is only a gas payer: it holds no allowance and is never a
2105
- * spender, so a relayer compromise cannot move user funds.
2106
- *
2107
- * Framework-neutral on purpose: `buildSweepTypedData` returns a plain
2108
- * `{ domain, types, primaryType, message }` that both viem
2109
- * (`signTypedData`/`recoverTypedDataAddress`) and ethers v6
2110
- * (`signTypedData`/`verifyTypedData`) accept, so the signer (viem) and backend
2111
- * (ethers) stay in lockstep without sharing a crypto library.
2112
- */
2113
- /** Base mainnet. The only chain Haven sweeps today. */
2114
- declare const SWEEP_BASE_CHAIN_ID = 8453;
2115
- /** Base Sepolia testnet — used by the dev environment / QA harness. */
2116
- declare const SWEEP_BASE_SEPOLIA_CHAIN_ID = 84532;
2117
- /** Canonical Circle USDC on Base (FiatTokenV2_2). */
2118
- declare const SWEEP_BASE_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
2119
- /** Circle's canonical Base Sepolia testnet USDC. */
2120
- declare const SWEEP_BASE_SEPOLIA_USDC_ADDRESS = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
2121
- /** True when the gasless sweep supports a chain (its USDC domain + address are known). */
2122
- declare function isSweepableChain(chainId: number): boolean;
2123
- /** EIP-712 `TransferWithAuthorization` struct, per EIP-3009. */
2124
- declare const TRANSFER_WITH_AUTHORIZATION_TYPES: {
2125
- readonly TransferWithAuthorization: readonly [{
2126
- readonly name: "from";
2127
- readonly type: "address";
2128
- }, {
2129
- readonly name: "to";
2130
- readonly type: "address";
2131
- }, {
2132
- readonly name: "value";
2133
- readonly type: "uint256";
2134
- }, {
2135
- readonly name: "validAfter";
2136
- readonly type: "uint256";
2137
- }, {
2138
- readonly name: "validBefore";
2139
- readonly type: "uint256";
2140
- }, {
2141
- readonly name: "nonce";
2142
- readonly type: "bytes32";
2143
- }];
2144
- };
2145
- interface SweepEip712Domain {
2146
- name: string;
2147
- version: string;
2148
- chainId: number;
2149
- verifyingContract: string;
2150
- }
2151
- /**
2152
- * A fully-specified EIP-3009 authorization. All amounts/times are decimal
2153
- * strings (JSON-safe) and `nonce` is a 0x-prefixed 32-byte hex value. `token`
2154
- * and `chainId` are carried explicitly so the signer can assert they are
2155
- * canonical before signing.
2156
- */
2157
- interface SweepAuthorization {
2158
- /** Delegate EOA the funds are swept FROM. */
2159
- from: string;
2160
- /** The agent's Haven account the funds are swept TO. */
2161
- to: string;
2162
- /** Atomic USDC amount (decimal string). */
2163
- value: string;
2164
- /** Unix seconds the authorization becomes valid (decimal string, usually "0"). */
2165
- validAfter: string;
2166
- /** Unix seconds the authorization expires (decimal string). */
2167
- validBefore: string;
2168
- /** Random 0x-prefixed 32-byte hex nonce. */
2169
- nonce: string;
2170
- /** USDC contract address. */
2171
- token: string;
2172
- /** Chain id (8453 today). */
2173
- chainId: number;
2174
- }
2175
- /**
2176
- * Haven's signature over the sweep authorization context, signed with the same
2177
- * binding key the x402 expected-context uses. Lets the edge signer verify the
2178
- * authorization actually came from Haven (and wasn't crafted by a compromised
2179
- * hosted server pointing `to` at an attacker) before it signs.
2180
- */
2181
- interface SweepExpectedAuth {
2182
- /**
2183
- * Currently always 1. Typed as `number` for the same reason as
2184
- * `X402ExpectedAuth.version` (#1143): it is inbound, so a stale signer must be
2185
- * able to *receive* an unknown version in order to report it. The signer's
2186
- * `SUPPORTED_SWEEP_BINDING_VERSIONS` is the authority on what it will sign.
2187
- */
2188
- version: number;
2189
- message: string;
2190
- signature: string;
2191
- signer: string;
2192
- }
2193
- /** What `POST /machine-payments/sweep/prepare` returns when funds are stranded. */
2194
- interface SweepPreparation {
2195
- authorization: SweepAuthorization;
2196
- expectedAuth: SweepExpectedAuth;
2197
- }
2198
- /** Wire response from `POST /machine-payments/sweep/prepare` (snake_case). */
2199
- interface SweepPrepareResponse {
2200
- /** Present and true when the delegate holds nothing to recover. */
2201
- nothing_stranded?: boolean;
2202
- /**
2203
- * Present and true when the stranded balance is below the sweep floor (#700):
2204
- * it is left on the delegate as dust rather than recovered, because the gas to
2205
- * sweep it would exceed its value. `min_usdc` carries the configured floor. No
2206
- * `authorization` is built.
2207
- */
2208
- below_min?: boolean;
2209
- min_usdc?: string;
2210
- /** The authorization to sign — absent when nothing is stranded or below the floor. */
2211
- authorization?: SweepAuthorization;
2212
- /** Haven's binding over the authorization — absent when nothing is stranded. */
2213
- expected_auth?: SweepExpectedAuth;
2214
- asset?: string;
2215
- amount?: string;
2216
- amount_atomic?: string;
2217
- chain_id: number;
2218
- sign_instructions?: string;
2219
- message?: string;
2220
- }
2221
- /** Wire response from `POST /machine-payments/sweep/submit` (snake_case). */
2222
- interface SweepSubmitResponse {
2223
- tx_hash: string;
2224
- asset: string;
2225
- amount: string;
2226
- amount_atomic: string;
2227
- from_address: string;
2228
- to_address: string;
2229
- chain_id: number;
2230
- explorer_url: string;
2231
- idempotent_replay?: boolean;
2232
- }
2233
- /** Result of a submitted gasless sweep. */
2234
- interface SweepSubmitResult {
2235
- txHash: string;
2236
- amount: string;
2237
- amountAtomic: string;
2238
- asset: string;
2239
- fromAddress: string;
2240
- toAddress: string;
2241
- chainId: number;
2242
- explorerUrl: string;
2243
- }
2244
- interface SweepTypedData {
2245
- domain: SweepEip712Domain;
2246
- types: typeof TRANSFER_WITH_AUTHORIZATION_TYPES;
2247
- primaryType: 'TransferWithAuthorization';
2248
- message: {
2249
- from: string;
2250
- to: string;
2251
- value: bigint;
2252
- validAfter: bigint;
2253
- validBefore: bigint;
2254
- nonce: string;
2255
- };
2256
- }
2257
- /** Resolve the canonical USDC contract for a sweepable chain, or throw. */
2258
- declare function sweepUsdcAddress(chainId: number): string;
2259
- /** Resolve the USDC EIP-712 domain for a sweepable chain, or throw. */
2260
- declare function sweepUsdcDomain(chainId: number): SweepEip712Domain;
2261
- /**
2262
- * Build the EIP-712 typed data for an authorization, validating that the token
2263
- * and chain are canonical (the domain's `verifyingContract` must match the
2264
- * authorization's `token`). Returns bigint-valued fields so both viem and
2265
- * ethers v6 sign/recover identically.
2266
- */
2267
- declare function buildSweepTypedData(auth: SweepAuthorization): SweepTypedData;
2268
- /**
2269
- * Canonical, deterministic string the backend signs and the signer re-derives
2270
- * for the authorization binding. The `Haven sweep authorization v1` namespace
2271
- * (and `kind`) is distinct from the x402 expected-context namespace so an x402
2272
- * binding can never be replayed as a sweep authorization even though they share
2273
- * a signing key.
2274
- */
2275
- declare function buildSweepAuthorizationMessage(auth: SweepAuthorization): string;
2276
-
2277
- /**
2278
- * Client identity on Haven API requests (#3303, epic #3302).
2279
- *
2280
- * Every published Haven client names itself with one header,
2281
- * `X-Haven-Client: <package>/<version>`, so the backend can tell an outdated
2282
- * client what to run — a `client_update` hint on its responses, or, only below
2283
- * a minimum the deployment has explicitly set, a 426 `client_outdated` refusal
2284
- * at the payment-initiating routes (the signer: at sign-context). The backend's
2285
- * table and decision live in `@haven_ai/core`'s `client-compat.ts`; this module
2286
- * is the client half and deliberately holds no thresholds.
2287
- *
2288
- * Deliberately free of any other SDK import so `@haven_ai/sdk/edge` (the
2289
- * signer's ethers-free entry) can re-export it.
2290
- */
2291
- /**
2292
- * This SDK's own version. Owned by `scripts/release-bump.mjs`, which rewrites
2293
- * it with the package version on every release — never hand-edit it.
2294
- */
2295
- declare const SDK_VERSION = "0.8.0-alpha.0";
2296
- /** The request header every published Haven client sends. */
2297
- declare const HAVEN_CLIENT_HEADER = "X-Haven-Client";
2298
- /** `<package>/<version>` — the value of {@link HAVEN_CLIENT_HEADER}. */
2299
- declare function havenClientIdentity(pkg: string, version: string): string;
2300
- /** What a bare SDK embedder sends when it names no package of its own. */
2301
- declare const SDK_CLIENT_IDENTITY: string;
2302
- /**
2303
- * The `client_update` object the backend attaches to a response when this
2304
- * client is behind (`required: false`) or below a set minimum
2305
- * (`required: true`). Every field is the backend's; the SDK never computes one.
2306
- */
2307
- interface HavenClientUpdate {
2308
- package: string;
2309
- current: string;
2310
- recommended: string | null;
2311
- min_version: string | null;
2312
- required: boolean;
2313
- upgrade_command: string;
2314
- notes_url: string | null;
2315
- }
2316
- /** Narrow an unknown response field to a {@link HavenClientUpdate}, or undefined. */
2317
- declare function readClientUpdate(value: unknown): HavenClientUpdate | undefined;
2318
-
2319
- /**
2320
- * #3101 (epic #3105, slice 2/5): the typed next-step builder.
2321
- *
2322
- * Every hosted payment tool ends by naming the agent's next tool and its
2323
- * arguments (#1308). Until this module, the tool was a free string and the
2324
- * arguments a `Record<string, unknown>`, so nothing tied the keys to the tool
2325
- * named beside them — three sites handed `{ payment_id: null }` to a tool
2326
- * whose `payment_id` is a required string, and the compiler could not see it.
2327
- *
2328
- * The builder is generic over a TARGET MAP the caller supplies: bare tool
2329
- * name → { role, validate }. It is deliberately schema-library-agnostic (the
2330
- * SDK carries no zod): the hosted server derives each target's argument type
2331
- * from its own zod shape and passes a `validate` closure; this module only
2332
- * needs to know the role (to render `mcp__<server>__<tool>`) and how to say
2333
- * whether arguments parse. Keyed on the bare name + role (decision 1) so the
2334
- * namespaced string is rendered in exactly one place and the runtime-neutral
2335
- * `next_tool_server` / `next_tool_name` / `next_tool_server_role` fields are
2336
- * derived from the same input rather than parsed back out of a literal.
2337
- *
2338
- * Decisions 3 and 8: `nextTool` is REQUIRED on the input and may be `null` —
2339
- * a site that forgets it is a compile error; a site with no next tool says
2340
- * why, and the wire omits `next_tool` and carries `next_tool_omitted_reason`.
2341
- * `next_tool` is never null on the wire.
2342
- */
2343
- type NextToolServerRole = 'hosted' | 'signer';
2344
- /** The DEFAULT server name each role is wired under (#1588, #2550). */
2345
- declare const NEXT_TOOL_SERVER_NAMES: Record<NextToolServerRole, string>;
2346
- /** Default server name → role. An unknown server yields no role rather than a guess (#2550). */
2347
- declare const NEXT_TOOL_SERVER_ROLES: Record<string, NextToolServerRole>;
2348
- /** Renders the Claude-family namespaced tool name — the one string clients have followed since #1308. */
2349
- declare function renderNextTool(role: NextToolServerRole, name: string): string;
2350
- /** Parses a namespaced literal back into its parts; `role` is absent for an unknown server. */
2351
- declare function parseNextTool(literal: string): {
2352
- server: string;
2353
- name: string;
2354
- role?: NextToolServerRole;
2355
- } | null;
2356
- /**
2357
- * One target the builder may hand off to. `TArgs` is the argument type the
2358
- * caller derived from the tool's declared schema; `validate` is the runtime
2359
- * twin of that type and returns `null` when the arguments parse, else why not.
2360
- */
2361
- interface NextStepTarget<TArgs> {
2362
- role: NextToolServerRole;
2363
- validate: (input: unknown) => string | null;
2364
- /** Phantom carrier for the argument type; never read at runtime. */
2365
- readonly _args?: TArgs;
2366
- }
2367
- type NextStepTargets = Record<string, NextStepTarget<unknown>>;
2368
- /** The argument type a target carries. */
2369
- type NextStepArguments<Targets extends NextStepTargets, T extends keyof Targets> = Targets[T] extends NextStepTarget<infer A> ? A : never;
2370
- /**
2371
- * The handoff half of a next step: a registered tool with arguments that
2372
- * tool accepts, or no tool with the reason. A discriminated union over the
2373
- * target map's keys, so a wrong key, a missing required key, an unregistered
2374
- * tool name and an omitted `nextTool` are each a compile error at the site.
2375
- */
2376
- type NextStepHandoff<Targets extends NextStepTargets> = {
2377
- [T in keyof Targets & string]: {
2378
- nextTool: T;
2379
- nextArguments: NextStepArguments<Targets, T>;
2380
- };
2381
- }[keyof Targets & string] | {
2382
- nextTool: null;
2383
- nextToolOmittedReason: string;
2384
- };
2385
- type NextStepInput<Targets extends NextStepTargets> = NextStepHandoff<Targets> & {
2386
- nextAction: AgentPaymentNextAction;
2387
- safeToContinue: boolean;
2388
- reason: string;
2389
- };
2390
- /** The wire shape: `AgentNextStep` (its `next_tool` family) — never a null `next_tool`. */
2391
- type NextStep = AgentNextStep;
2392
- /**
2393
- * Per-`next_action` default tool (decision 9): the tool a site names unless it
2394
- * has a reason to override. Only actions with ONE sensible target are listed;
2395
- * `retry_original_x402_request` is absent because its only live emitter names
2396
- * no tool on purpose (the agent's own HTTP retry); `sign_and_submit_payment`
2397
- * is absent because the signer tool
2398
- * depends on the settlement scheme (`haven_sign` for erc7710 delegations,
2399
- * `haven_sign_x402` for the EIP-3009 bridge) and a wrong default there would be
2400
- * worse than none.
2401
- */
2402
- declare const DEFAULT_NEXT_TOOL_BY_ACTION: {
2403
- readonly check_status_later: "haven_get_payment_status";
2404
- readonly sweep_stranded_funds: "haven_sweep_delegate";
2405
- };
2406
- declare function defaultNextToolFor(action: AgentPaymentNextAction): string | undefined;
2407
- /**
2408
- * Builds a `nextStep` function bound to a target map. The returned function
2409
- * renders the wire fields from the bare name + role, and re-validates the
2410
- * arguments at runtime: on a mismatch it FAILS SAFE — omits the tool and says
2411
- * why in `next_tool_omitted_reason` — rather than throwing out of a handler
2412
- * that has already moved money. The compile-time twin makes that branch
2413
- * unreachable from typed sites; it exists for callers that bypass the types.
2414
- */
2415
- declare function createNextStepBuilder<Targets extends NextStepTargets>(targets: Targets): (input: NextStepInput<Targets>) => NextStep;
2416
-
2417
- /**
2418
- * The npm dist-tag the published Haven packages tell a user to re-run (#2423,
2419
- * slice 3 of epic #2420).
2420
- *
2421
- * ## Why a constant and not a literal
2422
- *
2423
- * Roughly a dozen user- and agent-facing strings across `@haven_ai/sdk`,
2424
- * `@haven_ai/signer`, `@haven_ai/connect` and the hosted MCP server say some
2425
- * form of "re-run `npx @haven_ai/connect@alpha`". Every one of them was a
2426
- * hard-coded literal, which is correct only for a build published under the
2427
- * `alpha` dist-tag. Once `dev`-branch snapshots publish under a `dev` tag
2428
- * (#2421), a snapshot build telling its tester to re-run `@alpha` would hand
2429
- * them the production connector — silently replacing the very build they are
2430
- * testing. So the tag becomes one build-time constant and every hint derives
2431
- * from it.
2432
- *
2433
- * ## Who writes it
2434
- *
2435
- * `scripts/release-bump.mjs` rewrites {@link HAVEN_CONNECTOR_CHANNEL} from the
2436
- * version it is bumping to, using exactly the rule `.github/workflows/publish.yml`
2437
- * uses to pick the `--tag` for that same version:
2438
- *
2439
- * | version | dist-tag / channel |
2440
- * |---|---|
2441
- * | `0.1.34-alpha.0` | `alpha` |
2442
- * | `0.0.0-dev.202609021200.abc1234` | `dev` |
2443
- * | `0.2.0` | `latest` |
2444
- *
2445
- * One rule, two consumers. `scripts/ci/connector-channel-agreement.test.mjs`
2446
- * executes the workflow's own shell and the bump script's own function over the
2447
- * same version table and fails if they ever disagree.
2448
- *
2449
- * ## Build-time here, run-time there
2450
- *
2451
- * A published tarball cannot read a deployment's environment, so for the
2452
- * published packages the channel is baked in at release time. A surface that is
2453
- * *deployed* rather than published has no release at which to bake anything in,
2454
- * so it reads the `HAVEN_CONNECTOR_CHANNEL` environment variable and falls back
2455
- * to this constant. Two surfaces do that: the hosted MCP server
2456
- * (`packages/mcp-server/src/connector-channel.ts`) and, since slice 2 (#2422),
2457
- * the backend's connector handout (`parseConnectorChannel` in
2458
- * `packages/backend/src/config.ts`). All three readers share one variable name,
2459
- * one default and one validation pattern, and that agreement is EXECUTED rather
2460
- * than asserted: `packages/backend/src/__tests__/connector-channel.test.ts`
2461
- * runs this module's `resolveConnectorChannel` and the backend's
2462
- * `parseConnectorChannel` over the same input table and fails if they ever
2463
- * diverge.
2464
- *
2465
- * **This says nothing about how any environment is configured.** Setting the
2466
- * variable anywhere is an operator action (epic #2420, operator step 3); no
2467
- * code here can observe it and none of this comment asserts it has happened.
2468
- */
2469
- /** The published connector package. Never varies; only its tag does. */
2470
- declare const CONNECTOR_PACKAGE_NAME = "@haven_ai/connect";
2471
- /**
2472
- * The npm dist-tag this build's re-run hints name.
2473
- *
2474
- * **Do not hand-edit.** `scripts/release-bump.mjs` owns this literal the same
2475
- * way it owns `CONNECTOR_VERSION` and its siblings, and
2476
- * `scripts/release-bump.test.mjs` fails if the two drift.
2477
- */
2478
- declare const HAVEN_CONNECTOR_CHANNEL = "alpha";
2479
- /** True when `value` is a well-formed dist-tag. */
2480
- declare function isConnectorChannel(value: string): boolean;
2481
- /**
2482
- * Resolve a channel from a deployment's `HAVEN_CONNECTOR_CHANNEL`.
2483
- *
2484
- * - unset, empty or whitespace ⇒ `fallback` (dashboards store a cleared
2485
- * variable as `""`, and that must land on the production-safe value);
2486
- * - well-formed ⇒ itself;
2487
- * - anything else ⇒ **throws**. It does not quietly fall back: a typo such as
2488
- * `dve` would then land on the production channel, and the environment would
2489
- * look fixed while reproducing the exact defect this slice removes.
2490
- *
2491
- * Well-formed-but-wrong (`dve` again) is *not* caught here and cannot be — it
2492
- * fails later at `npx`, where the error names the package. Stated rather than
2493
- * implied.
2494
- */
2495
- declare function resolveConnectorChannel(raw: string | undefined | null, fallback?: string): string;
2496
- /** `@haven_ai/connect@<channel>` — the spec an `npx` invocation names. */
2497
- declare function connectorSpec(channel?: string): string;
2498
- /**
2499
- * The re-run command every hint embeds.
2500
- *
2501
- * `connectorRerunCommand()` → `npx @haven_ai/connect@alpha`
2502
- * `connectorRerunCommand('--doctor')` → `npx @haven_ai/connect@alpha --doctor`
2503
- *
2504
- * `args` is appended verbatim so each call site keeps its own flags and its own
2505
- * surrounding sentence. The wording of those sentences is deliberately NOT
2506
- * moved here: several are inside signer refusal messages that users and agents
2507
- * pattern-match on, and this change is meant to move the channel token and
2508
- * nothing else.
2509
- */
2510
- declare function connectorRerunCommand(args?: string, options?: {
2511
- channel?: string;
2512
- npxFlags?: string;
2513
- }): string;
2514
- /**
2515
- * The command every UPGRADE hint names (#3412): `npx -y @haven_ai/connect@<channel> --doctor`.
2516
- *
2517
- * A bare connector re-run is a SETUP command — on a machine that is already
2518
- * set up it stops at "Missing --setup <hv_setup_...> setup token", so an
2519
- * outdated signer, local MCP or connector told to "re-run the connector" was
2520
- * handed a dead end. The flagless doctor works as pasted on an existing
2521
- * install (#3210: it resolves the runtime from the setup record), diagnoses an
2522
- * outdated signer, and prints the exact `--doctor --repair` line for the agent
2523
- * it describes — with `--credentials-dir` whenever more than one agent lives on
2524
- * the machine, so the repair cannot land on a different agent.
2525
- *
2526
- * `-y` because an upgrade hint is often run by an agent in a non-interactive
2527
- * shell. `@haven_ai/core`'s `upgradeCommandFor` (the backend's
2528
- * `client_update.upgrade_command`) cannot import this package, so it carries a
2529
- * copy; `packages/backend/src/__tests__/connector-upgrade-command-parity.test.ts`
2530
- * fails if the two ever disagree. Setup-time hints (identity restore,
2531
- * mid-setup retry) legitimately stay on {@link connectorRerunCommand}.
2532
- */
2533
- declare function connectorUpgradeCommand(options?: {
2534
- channel?: string;
2535
- }): string;
2536
-
2537
- /**
2538
- * The Node.js floor Haven's published packages support (#1161).
2539
- *
2540
- * ## Why this lives in the SDK
2541
- *
2542
- * Three packages need to enforce the same floor — `connect` (at setup),
2543
- * `signer` and `mcp` (at startup) — and `@haven_ai/sdk` is the only dependency
2544
- * all three already share. A copy per package is how the floor drifted in the
2545
- * first place: `engines` said `>=24` everywhere while connect's runtime manifest
2546
- * enforced `20.0.0`, so a connect run on Node v23 passed the guard, installed
2547
- * the signer, and signed a real payment. Two numbers for one fact is one number
2548
- * too many.
2549
- *
2550
- * Each consumer still owns its own refusal — the error type, the exit code, the
2551
- * wording of "what to do next" — because a library must never terminate its
2552
- * host process. This module only answers *is this version supported* and *what
2553
- * should we tell the user*.
2554
- *
2555
- * ## Why a floor is enforced at all
2556
- *
2557
- * `engines` is advisory: npm emits `EBADENGINE` and installs anyway unless the
2558
- * user happens to have `engine-strict` set. For a normal library that is a
2559
- * reasonable default. For the **signer** it is not — it holds the delegate key
2560
- * and produces every payment signature, so a subtle runtime incompatibility
2561
- * shows up as a wrong or missing signature on a money path. "It seemed to work"
2562
- * is precisely the evidence that cannot be relied on there.
2563
- */
2564
- /**
2565
- * The minimum supported Node.js version, as `major.minor.patch`.
2566
- *
2567
- * MUST equal the `engines.node` floor declared by every published Haven
2568
- * package. A guard test in each package asserts exactly that against its own
2569
- * `package.json`, so the two cannot drift again silently.
2570
- */
2571
- declare const HAVEN_MINIMUM_NODE_VERSION = "22.0.0";
2572
- /**
2573
- * Compare two Node versions. Negative when `left` is older.
2574
- *
2575
- * An unparseable version parses to `0.0.0` and therefore compares as older than
2576
- * any real floor — fail-closed. A version string Haven cannot read is not
2577
- * evidence of a supported runtime, and treating it as one would reopen exactly
2578
- * the hole this module closes.
2579
- */
2580
- declare function compareNodeVersions(left: string, right: string): number;
2581
- declare function isSupportedNodeVersion(nodeVersion?: string, minimumNodeVersion?: string): boolean;
2582
- interface UnsupportedNodeVersionMessageOptions {
2583
- /**
2584
- * What is being refused, in the user's terms — "Haven setup", "The Haven
2585
- * signer". Leads the message so the reader knows what just stopped.
2586
- */
2587
- subject: string;
2588
- nodeVersion?: string;
2589
- minimumNodeVersion?: string;
2590
- /** Appended verbatim as the closing line. Used for the re-run instruction. */
2591
- retryHint?: string;
2592
- }
2593
- /**
2594
- * The refusal text.
2595
- *
2596
- * Names the detected version, the required version, and **how to fix it** — the
2597
- * previous message stopped after the two version numbers, which tells a user
2598
- * they are stuck without telling them how to get unstuck. The version-manager
2599
- * lines are the fix for nearly everyone; the closing caveat is there because the
2600
- * runtime that *spawns* the signer is frequently not the shell that was
2601
- * upgraded, and a desktop app can keep launching the old Node long after
2602
- * `node -v` in a terminal says otherwise.
2603
- */
2604
- declare function unsupportedNodeVersionMessage(options: UnsupportedNodeVersionMessageOptions): string;
2605
-
2606
- /**
2607
- * x402 protocol support for the Haven SDK.
2608
- *
2609
- * Provides:
2610
- * - parsePaymentRequired() — extract payment requirements from a 402 response
2611
- * - parsePaymentRequiredResponse() — async parser with JSON body fallback
2612
- * - encodePaymentProof() — encode a receipt as a PAYMENT-SIGNATURE header
2613
- *
2614
- * The main authorizeX402() and fetchWithPayment() are methods on HavenClient
2615
- * (see client.ts) since they need API access and signing.
2616
- */
2617
-
2618
- /**
2619
- * Persisted, agent-scoped facts used to preflight a signed standard x402
2620
- * payment header. This is an integrity comparison only: it never rebuilds,
2621
- * modifies, persists, or submits the supplied authorization.
2622
- */
2623
- interface X402PaymentHeaderContext {
2624
- merchantTo: string;
2625
- amountAtomic: string;
2626
- asset: string;
2627
- network: string;
2628
- resourceUrl: string;
2629
- payer: string;
2630
- chainId: number;
2631
- }
2632
- /** A deliberately value-free refusal for untrusted payment-header input. */
2633
- declare class X402PaymentHeaderValidationError extends Error {
2634
- constructor();
2635
- }
2636
- /**
2637
- * Upper bound on the MERCHANT-requested part of the EIP-3009 authorization
2638
- * window (#715, epic #713). The x402 library sets
2639
- * `validBefore = now + maxTimeoutSeconds` straight from the MERCHANT's 402
2640
- * challenge — without a cap, a malicious or sloppy merchant can request a
2641
- * year-long window and a leaked signed authorization stays spendable that
2642
- * whole time. 600 s is generous for any facilitator settle (typical is
2643
- * 30–60 s). This cap applies only to the signed authorization, never to the
2644
- * advertised requirements echoed in `accepted`. A merchant requiring more
2645
- * than the bounded lifetime can still reject at verification; preserving its
2646
- * offer does not widen Haven's signing policy.
2647
- */
2648
- declare const X402_MAX_AUTHORIZATION_WINDOW_SECONDS = 600;
2649
- /**
2650
- * Forward margin ADDED on top of the (clamped) merchant timeout when the
2651
- * authorization is actually signed (#1256). The x402 verify rule requires
2652
- * `validBefore ≥ now + maxTimeoutSeconds` AT THE FACILITATOR — but the
2653
- * upstream library computes `validBefore = now + maxTimeoutSeconds` at
2654
- * SIGNING time, leaving zero forward margin. Haven's flow guarantees elapsed
2655
- * time between the two (the funding UserOp confirms before the merchant
2656
- * retry, ~1 min plus latency), so every purchase against a merchant whose
2657
- * `maxTimeoutSeconds` exceeded that latency failed structurally — measured
2658
- * live on Base mainnet: Anchor requires 300 s, and 226 s remained at verify.
2659
- *
2660
- * 300 s covers funding + retry latency with room to spare. The #715 exposure
2661
- * ceiling becomes clamped-timeout + margin ≤ 900 s total forward — a
2662
- * deliberate widening from 600 s, recorded on #1256: an authorization that
2663
- * cannot pass verify protects no one, and 900 s is still bounded by the same
2664
- * clamp discipline.
2665
- */
2666
- declare const X402_SETTLEMENT_FORWARD_MARGIN_SECONDS = 300;
2667
- declare function normalizePaymentRequired(value: unknown): X402PaymentRequired | null;
2668
- /**
2669
- * The x402 wire header names, in one place (#2289).
2670
- *
2671
- * v2 renamed all three; v1's only name was `X-PAYMENT`, used in BOTH
2672
- * directions. Haven had adopted the v2 names for everything it *reads* and
2673
- * kept the v1 name for the one thing it *writes*, which is how a strict v2
2674
- * merchant came to never see a payment header at all.
2675
- *
2676
- * The 2026-08-31 owner decision was to send both outbound names on every
2677
- * retry rather than switch on `x402Version`: a v1 merchant ignores the name it
2678
- * does not know, a v2 merchant ignores the legacy one, and no version
2679
- * heuristic has to be right for a payment to land.
2680
- *
2681
- * **That is no longer unconditional (#2341).** It held while the cost of a
2682
- * spare header was zero, and on the EIP-3009 bridge it still is. On erc7710 it
2683
- * is not: that header carries a whole delegation chain, and duplicating it
2684
- * overflowed the merchant's header limit — HTTP 431, every erc7710 settlement
2685
- * refused. `x402PaymentHeaderNamesFor` below is the live rule; read it rather
2686
- * than this paragraph, which records why the simpler rule was right first.
2687
- */
2688
- /** v2 client→server payment payload. The name a strict v2 merchant reads. */
2689
- declare const X402_PAYMENT_HEADER_NAME = "PAYMENT-SIGNATURE";
2690
- /** v1 client→server payment payload; still accepted by most v2 merchants. */
2691
- declare const X402_LEGACY_PAYMENT_HEADER_NAME = "X-PAYMENT";
2692
- /** v2 server→client payment requirements. */
2693
- declare const X402_PAYMENT_REQUIRED_HEADER_NAME = "PAYMENT-REQUIRED";
2694
- /** v2 server→client settlement receipt. */
2695
- declare const X402_PAYMENT_RESPONSE_HEADER_NAME = "PAYMENT-RESPONSE";
2696
- /**
2697
- * Both wire names, v2 first — the value an EIP-3009 retry actually sends.
2698
- *
2699
- * **Not the general answer any more (#2341), and not what a recorder should
2700
- * reach for.** This was the evidence record's `paymentProofHeaderName` while
2701
- * both names always went on the wire; erc7710 now sends one, so a recorder
2702
- * still reading this constant would log a legacy header that was never sent —
2703
- * exactly the drift the previous wording promised it prevented. Use
2704
- * `x402PaymentHeaderNamesSent(paymentHeader)`. Kept exported because it is a
2705
- * published surface and removing it would break consumers.
2706
- */
2707
- declare const X402_PAYMENT_HEADER_NAMES_SENT = "PAYMENT-SIGNATURE, X-PAYMENT";
2708
- /**
2709
- * The x402 v2 payment envelope: `{x402Version, resource?, accepted, payload,
2710
- * extensions?}` per the spec's PaymentPayload (§5.2.2).
2711
- *
2712
- * The `resource` and `extensions` echoes are the #2361 fix, and they are not
2713
- * optional politeness: the spec makes the extensions echo a MUST ("the client
2714
- * must include at least the info received"), and CoinGecko's facilitator was
2715
- * live-bisected rejecting the echo-less envelope with a bare 400 while
2716
- * accepting the identical signature and `accepted`/`payload` bytes with the
2717
- * echoes added (#2360, Base mainnet, 2026-09-01). Both objects are echoed
2718
- * VERBATIM from the merchant's 402 — never reconstructed — and omitted when
2719
- * the challenge carries none, which keeps the envelope byte-identical to the
2720
- * pre-#2361 shape for echo-less merchants (Ampersend and Soundside settled
2721
- * that shape live, so omission is the proven-compatible default).
2722
- *
2723
- * The `accepted` wrap itself is #303's shape and predates this helper — see
2724
- * the #300/#303 history before "fixing" it: scheme/network live INSIDE
2725
- * `accepted` in v2, never at the top level.
2726
- */
2727
- declare function x402V2PaymentEnvelope(paymentRequired: Pick<X402PaymentRequired, 'x402Version' | 'resource' | 'extensions'>, accepted: X402PaymentOption, payload: unknown): Record<string, unknown>;
2728
- /**
2729
- * Parse an HTTP 402 response into x402 PaymentRequired data.
2730
- *
2731
- * Supports:
2732
- * - v2: PAYMENT-REQUIRED header (base64 JSON)
2733
- * - v1 fallback: X-PAYMENT header or response body
2734
- */
2735
- declare function parsePaymentRequired(response: Response): X402PaymentRequired;
2736
- /**
2737
- * Parse an HTTP 402 response into x402 PaymentRequired data.
2738
- *
2739
- * Soundside and other Bazaar-style MCP endpoints return the PaymentRequired
2740
- * object in the JSON body, while older Haven demos and many x402 examples use
2741
- * base64 headers. This keeps the synchronous header parser intact and adds the
2742
- * body fallback needed for those endpoints.
2743
- */
2744
- declare function parsePaymentRequiredResponse(response: Response): Promise<X402PaymentRequired>;
2745
- /**
2746
- * Select the best payment option from the x402 accepts array.
2747
- *
2748
- * Preference order:
2749
- * 1. Option on a Haven-supported network with a known token
2750
- * 2. Any option on a Haven-supported network
2751
- * 3. null — no compatible option
2752
- */
2753
- declare function selectPaymentOption(accepts: X402PaymentOption[]): X402PaymentOption | null;
2754
- /** The `extra.assetTransferMethod` value that marks an erc7710-settleable entry. */
2755
- declare const ERC7710_ASSET_TRANSFER_METHOD = "erc7710";
2756
- /**
2757
- * Read `extra.assetTransferMethod` defensively. `extra` is the merchant's own
2758
- * object, so it is untrusted shape: anything that is not the exact string is
2759
- * treated as "not erc7710" rather than coerced.
2760
- */
2761
- declare function x402AssetTransferMethod(option: X402PaymentOption): string | null;
2762
- /** True when the merchant advertises this entry as erc7710-settleable. */
2763
- declare function isErc7710Option(option: X402PaymentOption): boolean;
2764
- /**
2765
- * The facilitator addresses a merchant advertises for an erc7710 entry, for
2766
- * the #1058 redeemer pin — or `null` when it pins nothing.
2767
- *
2768
- * **An EMPTY array is `null`, not `[]`.** The backend rejects an empty
2769
- * `redeemers` list with a 400 (`routes/x402.ts`), and the QA scenario already
2770
- * treats empty as absent. Returning `[]` here would hand callers a value that
2771
- * means "pin to nobody" — which is not a narrower pin, it is an unbuildable
2772
- * delegation.
2773
- *
2774
- * Malformed entries are DROPPED rather than failing the whole option, and that
2775
- * asymmetry is deliberate. A pin narrowed by a merchant's typo means the
2776
- * facilitator that actually tries to redeem is not on the list, so redemption
2777
- * reverts — and erc7710 has no funding leg, so nothing moved and nothing is
2778
- * stranded. Refusing the option outright would instead deny a payment the
2779
- * remaining valid facilitators could have settled. Losing the payment is the
2780
- * worse outcome, precisely because the failure this issue closes (#1453) is the
2781
- * one where funds move BEFORE the rejection.
2782
- */
2783
- declare function x402FacilitatorAddresses(option: X402PaymentOption): string[] | null;
2784
- /**
2785
- * Select an option that can be paid with the official x402 EIP-3009 exact
2786
- * scheme. Haven's older tx-hash proof path can describe more networks; the
2787
- * merchant-verified path currently needs Base USDC.
2788
- *
2789
- * **Skips erc7710-tagged entries (#1453).** It used to return the first
2790
- * positional match and never look at `extra.assetTransferMethod`, so a merchant
2791
- * that listed its erc7710 entry first made a Haven client echo that option
2792
- * while signing a standard EIP-3009 authorization. The merchant rejects the
2793
- * mismatch cleanly — but on the two-leg bridge the account→delegate funding
2794
- * transfer has already executed, so the visible result is a stranded delegate
2795
- * balance for the sweep to reclaim. Only our own demo merchant's ordering was
2796
- * holding that shut, and that pin binds our merchant, not the ones we do not
2797
- * control.
2798
- */
2799
- declare function selectStandardPaymentOption(accepts: X402PaymentOption[]): X402PaymentOption | null;
2800
- /**
2801
- * Select the erc7710-settleable option, if the merchant advertises one.
2802
- */
2803
- declare function selectErc7710PaymentOption(accepts: X402PaymentOption[]): X402PaymentOption | null;
2804
- /** What a settlement-scheme decision resolved to. */
2805
- interface X402SchemeSelection {
2806
- scheme: 'erc7710' | 'eip3009';
2807
- option: X402PaymentOption;
2808
- /** Redeemer pin for the settlement child; only ever set on erc7710. */
2809
- facilitatorAddresses: string[] | null;
2810
- }
2811
- /**
2812
- * THE preference rule, in one place (#1450 owner decision, #1453).
2813
- *
2814
- * Prefer erc7710 whenever the account is on the delegation rail and the
2815
- * merchant advertises `extra.assetTransferMethod: "erc7710"`; fall back to
2816
- * the EIP-3009 bridge otherwise.
2817
- *
2818
- * Both halves of that condition are required, and the rail half is the
2819
- * caller's to supply — the SDK cannot see which rail an account is on from a
2820
- * 402 response alone. A legacy AllowanceModule account passing
2821
- * `delegationRail: true` would select a scheme its account cannot settle; the
2822
- * backend refuses that at authorize with the #1986 retired-rail 410 (#2245 —
2823
- * previously a scheme-specific 400 that wrongly implied the legacy rail could
2824
- * still settle via EIP-3009), which is where a rail mismatch SHOULD fail,
2825
- * on-chain-adjacent rather than in a client that could be lying to itself.
2826
- *
2827
- * Returns `null` when neither scheme has a payable entry — the caller decides
2828
- * whether that is an error or a reason to look elsewhere.
2829
- */
2830
- declare function selectX402SettlementScheme(accepts: X402PaymentOption[], opts: {
2831
- delegationRail: boolean;
2832
- }): X402SchemeSelection | null;
2833
- declare function x402AuthorizationAmount(option: X402PaymentOption): string;
2834
- /**
2835
- * Canonical Haven-authenticated x402 expected context, recomputed byte-for-byte
2836
- * by the edge signer before it signs anything.
2837
- *
2838
- * **Two versions, and the version is derived — never passed in (#1138).**
2839
- * `typedDataHash` present ⇒ v2, absent ⇒ v1. A v1 message is byte-identical to
2840
- * what shipped before, so existing signers keep verifying legacy-rail bindings
2841
- * unchanged.
2842
- *
2843
- * The version lives in both the header line and the payload so neither can be
2844
- * reinterpreted as the other: a v2 context cannot be replayed as a v1 one that
2845
- * drops the typed-data commitment, and a v1 context cannot be presented as v2.
2846
- * That downgrade is exactly the attack the digest exists to stop — see
2847
- * `assertExpectedBinding` in `@haven_ai/signer`, which refuses to raw-sign a
2848
- * hash under a v2 binding and refuses to sign typed data without one.
2849
- */
2850
- declare function buildX402ExpectedMessage(context: X402ExpectedContext): string;
2851
- declare function toStandardPaymentRequirements(paymentRequired: X402PaymentRequired, option: X402PaymentOption): PaymentRequirements;
2852
- /**
2853
- * Strictly validate an edge-signed EIP-3009 X-PAYMENT header against the
2854
- * persisted x402 intent context before a hosted relay can submit funding.
2855
- *
2856
- * The merchant/facilitator remains the final protocol verifier. This closes a
2857
- * separate hosted-relay integrity gap: malformed or context-mismatched input
2858
- * must never cause Haven to relay the funding signature first.
2859
- */
2860
- declare function validateStandardX402PaymentHeader(paymentHeader: string, context: X402PaymentHeaderContext): Promise<void>;
2861
- /**
2862
- * Encode a payment receipt as a base64 PAYMENT-SIGNATURE header value.
2863
- *
2864
- * This follows the x402 v2 protocol — the server's facilitator will
2865
- * verify the on-chain transaction referenced by tx_hash.
2866
- */
2867
- declare function encodePaymentProof(receipt: {
2868
- txHash: string;
2869
- paymentId: string;
2870
- token: string;
2871
- amount: string;
2872
- to: string;
2873
- resourceUrl?: string;
2874
- accepted?: X402PaymentOption;
2875
- payer?: string;
2876
- chainId?: number;
2877
- }): string;
2878
- /**
2879
- * Resolve a token symbol from a contract address.
2880
- *
2881
- * Checks all supported chains. For chain-specific resolution,
2882
- * pass the optional `network` CAIP-2 string (e.g. "eip155:8453").
2883
- */
2884
- declare function resolveTokenFromAddress(address: string, network?: string): {
2885
- symbol: string;
2886
- decimals: number;
2887
- } | null;
2888
- /**
2889
- * #3410: token decimals from a SYMBOL + CHAIN — the same registry
2890
- * `resolveTokenFromAddress` reads, keyed the other way. The address-based
2891
- * resolver needs the token's contract address, which the consent seed path
2892
- * (setup-time credential files) does not carry; the symbol and chain it does
2893
- * carry. Null when the symbol is not registered on that chain (unknown or
2894
- * custom tokens) — callers must fall back to an explicit atomic label rather
2895
- * than reading an atomic amount as whole tokens.
2896
- */
2897
- declare function resolveTokenBySymbol(chainId: number, symbol: string): {
2898
- symbol: string;
2899
- decimals: number;
2900
- } | null;
2901
-
2902
- /**
2903
- * #3271: the integrity check every client runs before signing a direct
2904
- * delegation-rail payment's typed data.
2905
- *
2906
- * A direct payment (`POST /payments`, surfaced as `haven_send` / `haven_pay`)
2907
- * is signed as the HybridDeleGator's EIP-712 `PackedUserOperation`, and Haven
2908
- * returns two things for it: that typed data, and `payload_hash` — the
2909
- * ERC-4337 v0.7 UserOperation hash of the same operation. Nothing used to tie
2910
- * the two together at signing time. The typed data is multi-KB and reaches the
2911
- * signer through a language model when it is relayed by hand, so one corrupted
2912
- * character produced a valid-looking signature over the wrong digest, and the
2913
- * first sign of it was `AA24 signature error` from the bundler (#3271,
2914
- * reproduced on dev 2026-09-24).
2915
- *
2916
- * This recomputes the v0.7 hash from the typed data's own message and domain
2917
- * and refuses unless it equals `payload_hash`, and it pins the parts of the
2918
- * typed data the hash does NOT cover (domain name/version/verifyingContract,
2919
- * the field list, the EntryPoint). It is a CORRUPTION check: the caller supplies
2920
- * both values, so it proves they describe the same operation, never that Haven
2921
- * prepared it. Provenance is the byte-free sign context (`payment_id`); what a
2922
- * delegate key will sign at all is `assertBoundDirectPaymentUserOp`
2923
- * (`direct-payment-guard.ts`, #3272 / #3283), which every caller of this check
2924
- * — `HavenClient.signForData` and the signer's `haven_sign` — runs next.
2925
- *
2926
- * Pure viem, no ethers: `@haven_ai/sdk/edge` re-exports it for the edge signer,
2927
- * and `edge-imports.test.ts` pins that graph.
2928
- */
2929
- /** Version of the direct-payment sign context (`GET /payments/:id/sign-context`). */
2930
- declare const DIRECT_SIGN_CONTEXT_VERSION = 1;
2931
- /**
2932
- * #3419: version of the task-budget sign context (`GET
2933
- * /task-budgets/:id/sign-context`), the sign-then-submit envelope every
2934
- * `haven_sign { task_budget_id }` call fetches. The backend emits it
2935
- * (`task-budget-service.ts`, `task_sign_context_version: 1`); the signer
2936
- * derives its enforced set `SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS` from this
2937
- * constant — never a second literal — and the hosted/local task-budget
2938
- * handoffs report it in `signer_compatibility.task_sign_context_version`.
2939
- * The signer could not carry the single source itself (a published package
2940
- * cannot host a constant the backend also serves), so it lives beside the
2941
- * other binding constants here, exactly as `DIRECT_SIGN_CONTEXT_VERSION` does.
2942
- */
2943
- declare const TASK_SIGN_CONTEXT_VERSION = 1;
2944
- /** The ERC-4337 v0.7 EntryPoint — the only one the delegation rail submits to. */
2945
- declare const ENTRY_POINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
2946
- /**
2947
- * The HybridDeleGator EIP-712 domain constants and the `PackedUserOperation`
2948
- * field list, vendored from `@metamask/smart-accounts-kit`
2949
- * (`contracts.HybridDeleGator.constants`, `SIGNABLE_USER_OP_TYPED_DATA`) so the
2950
- * published packages need no runtime dependency on the kit. Pinned equal to the
2951
- * kit's values by `userop-binding.test.ts`.
2952
- */
2953
- declare const HYBRID_DELEGATOR_DOMAIN_NAME = "HybridDeleGator";
2954
- declare const HYBRID_DELEGATOR_DOMAIN_VERSION = "1";
2955
- declare const PACKED_USER_OPERATION_FIELDS: ReadonlyArray<{
2956
- name: string;
2957
- type: string;
2958
- }>;
2959
- /** Refusal raised when UserOperation typed data (a direct payment, or the SDK's x402 funding leg) does not match its `payload_hash`. */
2960
- declare class HavenUserOpBindingError extends HavenError {
2961
- constructor(message: string);
2962
- }
2963
- /** True when the typed data is a `PackedUserOperation` (the direct-payment shape). */
2964
- declare function isPackedUserOperationTypedData(value: unknown): boolean;
2965
- /**
2966
- * Compute the ERC-4337 v0.7 UserOperation hash from a HybridDeleGator
2967
- * `PackedUserOperation` typed-data object — the value Haven returns as
2968
- * `payload_hash` for a direct payment (`getUserOperationHash`, entryPoint 0.7).
2969
- */
2970
- declare function packedUserOperationHash(typedData: unknown): Hex;
2971
- /**
2972
- * Refuse (throw `HavenUserOpBindingError`) unless this `PackedUserOperation`
2973
- * typed data is the operation `payloadHash` names, in the HybridDeleGator
2974
- * domain of its own sender, against the v0.7 EntryPoint. Returns the
2975
- * recomputed hash.
2976
- */
2977
- declare function assertUserOpTypedDataBinding(typedData: unknown, payloadHash: string): Hex;
2978
-
2979
- /**
2980
- * The counterfactual HybridDeleGator account address for an owner EOA (#3272).
2981
- *
2982
- * `haven_sign`'s unbound branch (`@haven_ai/signer`'s `tools.ts`) and, since
2983
- * #3283, `HavenClient.signForData` (`direct-payment-guard.ts`) sign a
2984
- * `PackedUserOperation`
2985
- * only when its `sender` (== `domain.verifyingContract`) is THIS SIGNER'S OWN
2986
- * delegate account — never any other HybridDeleGator, and never a third
2987
- * party's. Haven provisions that account counterfactually at signup (#970):
2988
- * it may have zero on-chain transactions, so the signer must be able to
2989
- * compute its address OFFLINE, from nothing but the delegate key's own
2990
- * address.
2991
- *
2992
- * This is exactly what `@metamask/smart-accounts-kit`'s
2993
- * `getCounterfactualAccountData` computes for
2994
- * `implementation: 'Hybrid'`, `deployParams: [owner, [], [], []]` (no passkey
2995
- * co-owners — the only shape Haven's signup flow provisions), `deploySalt:
2996
- * '0x'`: CREATE2 of an `ERC1967Proxy(HybridDeleGatorImpl, initialize(owner,
2997
- * [], [], []))` behind the `SimpleFactory`.
2998
- *
2999
- * VENDORED, NOT IMPORTED. `@metamask/smart-accounts-kit` is a devDependency
3000
- * only (see `package.json`) — this package installs on users' machines and
3001
- * must not carry it at runtime. The constants below (the factory and
3002
- * implementation addresses, the `ERC1967Proxy` bytecode) are copied from the
3003
- * kit's pinned environment / `@metamask/delegation-abis`' bytecode export,
3004
- * exactly like `settlement-child.ts` vendors the DelegationManager and caveat
3005
- * enforcer addresses for the same reason. Cross-checked against the kit by
3006
- * `packages/signer/src/delegate-account.pins.test.ts`, including against the real, on-chain
3007
- * `direct-payment-userop.json` fixture.
3008
- */
3009
-
3010
- /**
3011
- * SimpleFactory — deterministically deployed, so Base and Base Sepolia share
3012
- * the address (matches `packages/backend/src/rails/delegation-contracts.ts`'s
3013
- * `simpleFactory` pin for both chains).
3014
- */
3015
- declare const SIMPLE_FACTORY_ADDRESS: Address;
3016
- /**
3017
- * HybridDeleGator implementation — matches `delegation-contracts.ts`'s
3018
- * `hybridDeleGatorImpl` pin for both chains.
3019
- */
3020
- declare const HYBRID_DELEGATOR_IMPLEMENTATION: Address;
3021
- /**
3022
- * Derive the counterfactual HybridDeleGator account address for `owner`, with
3023
- * no passkey co-owners — the only shape Haven's signup flow provisions
3024
- * (#970). Pure and offline: no RPC call, no dependency on the account having
3025
- * been deployed. Verified byte-for-byte against
3026
- * `@metamask/smart-accounts-kit`'s `getCounterfactualAccountData` by
3027
- * `packages/signer/src/delegate-account.pins.test.ts`, including against a real Base Sepolia payload served by the dev backend
3028
- * (`direct-payment-userop.json`).
3029
- */
3030
- declare function deriveDelegateAccountAddress(owner: Address): Address;
3031
-
3032
- /**
3033
- * Independent verification of an erc7710 x402 settlement child (#1455).
3034
- *
3035
- * Moved from `@haven_ai/signer` into the SDK by #3283 (epic #3284) so the
3036
- * signer and `HavenClient.signForData` run ONE verifier. The signer checks the
3037
- * child against the Haven-signed expected context; the SDK checks it against
3038
- * the merchant's own 402, which Haven does not produce.
3039
- *
3040
- * WHY THIS EXISTS. `assertExpectedBinding` proves Haven *declared* a payload:
3041
- * the expected context is signed by `HAVEN_X402_BINDING_SIGNER` and commits to
3042
- * the digest of the exact bytes being signed. That is a real property, and it
3043
- * is not this one. It says nothing about what the payload MEANS.
3044
- *
3045
- * A backend that declared `merchantTo = the real merchant` while pinning a
3046
- * different payee in the child's `AllowedCalldata` caveat would produce a
3047
- * perfectly consistent pair: the declaration binds the digest, the digest is
3048
- * the child's, and the child pays someone else. The signature is the authority
3049
- * here — the merchant's facilitator redeems it and pulls from the treasury — so
3050
- * the signer has to re-derive the meaning locally or it is a pass-through with
3051
- * extra steps.
3052
- *
3053
- * ADDRESSES ARE PINNED HERE ON PURPOSE. Reading the enforcer map from Haven
3054
- * would make the check circular: an attacker who can pick which contract counts
3055
- * as "the payee enforcer" can satisfy any comparison. Taking
3056
- * `@metamask/smart-accounts-kit` as a runtime dependency was the other option
3057
- * and was rejected — this package installs on users' machines. The constants
3058
- * below are snapshot-pinned and cross-checked against the kit by a test
3059
- * (`packages/signer/src/settlement-child.pins.test.ts`), the same pattern
3060
- * `packages/core/src/chains.ts` uses against its registry.
3061
- *
3062
- * EXTRA CAVEATS ARE ALLOWED, and that is deliberate — verified, not assumed
3063
- * (#1455 review challenged it directly).
3064
- *
3065
- * `DelegationManager.redeemDelegations` loops every caveat of every delegation
3066
- * and calls `beforeHook` on each, with no break and no try/catch: a single
3067
- * revert aborts the whole redemption, and nothing lets one caveat cause another
3068
- * to be skipped. Top-level caveats are therefore strictly AND-ed, so one this
3069
- * file does not recognise can only add a constraint, never remove one.
3070
- *
3071
- * The specific challenge was `LogicalOrWrapperEnforcer`, whose terms encode
3072
- * several caveat GROUPS and whose own security notice warns that "the redeemer
3073
- * can select the least restrictive group, bypassing stricter requirements in
3074
- * other groups". That warning is about groups INSIDE the wrapper — it binds
3075
- * whoever authors wrapper terms. The wrapper is itself one caveat among the
3076
- * delegation's, so it is AND-ed with the four required below and cannot unlock
3077
- * them.
3078
- *
3079
- * The shape that WOULD be dangerous is the inverse: a required caveat hidden
3080
- * inside a wrapper group instead of sitting at top level, where the redeemer
3081
- * could select a group that omits it. This file scans top-level caveats and
3082
- * refuses on absence, so that child is refused for lacking the caveat — which
3083
- * is the correct outcome and is pinned by a test.
3084
- */
3085
- /** DelegationManager, the EIP-712 `verifyingContract` for a delegation. */
3086
- declare const DELEGATION_MANAGER = "0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3";
3087
- /**
3088
- * Caveat enforcers, by role. Deterministically deployed, so Base and Base
3089
- * Sepolia share addresses — verified for both chains by the pin test.
3090
- */
3091
- declare const CAVEAT_ENFORCERS: {
3092
- readonly erc20TransferAmount: "0xf100b0819427117EcF76Ed94B358B1A5b5C6D2Fc";
3093
- readonly allowedCalldata: "0xc2b0d624c1c4319760C96503BA27C347F3260f55";
3094
- readonly timestamp: "0x1046bb45C8d673d4ea75321280DB34899413c069";
3095
- readonly redeemer: "0xE144b0b2618071B4E56f746313528a669c7E65c5";
3096
- };
3097
- /** The backend's own ceiling (`MAX_SETTLEMENT_WINDOW_SECONDS`), enforced again here. */
3098
- declare const MAX_SETTLEMENT_WINDOW_SECONDS = 600;
3099
- interface SettlementChildTypedData {
3100
- domain: {
3101
- name?: string;
3102
- version?: string;
3103
- chainId?: number | string;
3104
- verifyingContract?: string;
3105
- };
3106
- types: Record<string, unknown>;
3107
- primaryType: string;
3108
- message: Record<string, unknown>;
3109
- }
3110
- /**
3111
- * True when this typed data is a delegation — the shape that must never be
3112
- * signed unbound. Excludes a SELF-delegation (`delegate === delegator`,
3113
- * #3329): that is the shape of a task-budget child
3114
- * (`task-budget-guards.ts`'s `isTaskChildTypedData`), a DIFFERENT typed-data
3115
- * class verified by a different function against a different expectation. A
3116
- * real settlement child's `delegate` is always a facilitator or
3117
- * `ANY_BENEFICIARY` — never this account's own address — so narrowing here
3118
- * costs this verifier nothing and keeps the two classes from ever
3119
- * overlapping.
3120
- */
3121
- declare function isSettlementChildTypedData(value: unknown): value is SettlementChildTypedData;
3122
- /**
3123
- * Map an x402 network string to a chain id. Local on purpose (#1455 review):
3124
- * the chain must come from Haven's SIGNED `network` field, never from the
3125
- * payload under verification — see `verifySettlementChild`.
3126
- */
3127
- declare function chainIdForNetwork(network: string | undefined): number | undefined;
3128
- interface SettlementChildExpectation {
3129
- merchantTo: string;
3130
- amount: string;
3131
- asset: string;
3132
- /**
3133
- * Derived from the expected context's SIGNED `network`, never from
3134
- * `typedData.domain.chainId`. Comparing the payload's own claim against
3135
- * itself is a check that cannot fail — which is exactly what shipped in the
3136
- * first draft of this file's call site, and what the review caught.
3137
- */
3138
- chainId: number;
3139
- /** ISO timestamp; the child must not outlive it. */
3140
- expiresAt?: string;
3141
- /**
3142
- * #3283 / #3281 criterion 8: the signer's OWN derived delegate account.
3143
- * When set, the child's `delegator` must be exactly this account — the
3144
- * child is a re-delegation of this agent's budget, never a grant from some
3145
- * other account the key happens to control.
3146
- */
3147
- delegatorAccount?: string;
3148
- /**
3149
- * #3283: the facilitator addresses the merchant's 402 advertised
3150
- * (`extra.facilitatorAddresses`). When non-empty, the child must carry a
3151
- * `RedeemerEnforcer` caveat pinning exactly this set — otherwise the child
3152
- * is a bearer instrument any party could redeem within its bounds.
3153
- */
3154
- redeemers?: readonly string[];
3155
- }
3156
- /** `@metamask/delegation-core`'s `ROOT_AUTHORITY` — a delegation chained to nothing. */
3157
- declare const ROOT_AUTHORITY: string;
3158
- /**
3159
- * Verify a settlement child implements what the expected context declares.
3160
- * Throws `HavenSigningError` on any disagreement; returns nothing on success.
3161
- *
3162
- * `now` is injectable so the expiry checks are testable without faking clocks.
3163
- */
3164
- declare function verifySettlementChild(typedData: SettlementChildTypedData, expected: SettlementChildExpectation, now?: number): void;
3165
-
3166
- /** Wire code for a typed-data payload outside the signable allowlist. */
3167
- declare const TYPED_DATA_NOT_ALLOWED: "TYPED_DATA_NOT_ALLOWED";
3168
- /**
3169
- * A typed-data payload was refused before signing because it is not a shape
3170
- * a delegate key may sign. Nothing was signed. `@haven_ai/signer` subclasses
3171
- * this to attach its MCP next step; the `code` is the same on both.
3172
- */
3173
- declare class HavenTypedDataRefusedError extends HavenSigningError {
3174
- readonly code: typeof TYPED_DATA_NOT_ALLOWED;
3175
- constructor(message: string);
3176
- }
3177
- /**
3178
- * Chains the delegation rail has PINNED delegation contracts for
3179
- * (`packages/backend/src/rails/delegation-contracts.ts`) — the only chains a
3180
- * direct-payment UserOp may be scoped to. No other chain has a pinned
3181
- * DelegationManager/enforcer set, so every other chain is deliberately
3182
- * excluded even where the delegate account itself could exist.
3183
- */
3184
- declare const DIRECT_PAYMENT_CHAIN_IDS: ReadonlySet<number>;
3185
- /** The DeleGator's single-execution `execute((address,uint256,bytes))` — selector `0x5c1c6dcd`. */
3186
- declare const EXECUTE_ABI: readonly [{
3187
- readonly type: "function";
3188
- readonly name: "execute";
3189
- readonly inputs: readonly [{
3190
- readonly name: "_execution";
3191
- readonly type: "tuple";
3192
- readonly components: readonly [{
3193
- readonly name: "target";
3194
- readonly type: "address";
3195
- }, {
3196
- readonly name: "value";
3197
- readonly type: "uint256";
3198
- }, {
3199
- readonly name: "callData";
3200
- readonly type: "bytes";
3201
- }];
3202
- }];
3203
- readonly outputs: readonly [];
3204
- readonly stateMutability: "payable";
3205
- }];
3206
- /**
3207
- * The content + provenance allowlist (#3272 criteria 1–2). Call ONLY after
3208
- * `assertUserOpTypedDataBinding` has already proven `typedData` is a
3209
- * well-formed `PackedUserOperation` matching its own hash — this function
3210
- * trusts `typedData.domain`/`message` are shaped correctly and checks only
3211
- * what they SAY. Throws `HavenTypedDataRefusedError` (never returns) on any
3212
- * disagreement.
3213
- */
3214
- declare function assertBoundDirectPaymentUserOp(typedData: Record<string, unknown>, delegateAddress: string): void;
3215
-
3216
- /**
3217
- * The settlement-child half of the same surface (#3283): verify an erc7710
3218
- * child against `expectation` (from somewhere Haven did not write — the
3219
- * merchant's 402 in the SDK, the Haven-signed expected context in the
3220
- * signer), AND that it is re-delegated from this key's OWN account. Throws
3221
- * `HavenTypedDataRefusedError` (code `TYPED_DATA_NOT_ALLOWED`) on any
3222
- * disagreement.
3223
- */
3224
- declare function assertOwnSettlementChild(typedData: unknown, expectation: SettlementChildExpectation, delegateAddress: string): void;
3225
- /**
3226
- * #3281 (epic #3284, criterion 5): pin WHERE an x402 EIP-3009 funding leg's
3227
- * redemption sends the money. The funding leg is always
3228
- * `transfer(<delegate EOA>, <amount>)` of the quoted token
3229
- * (`delegation-authorize.ts` → `prepareDelegationPayment(agent, token,
3230
- * payTo = the delegate EOA, amountRaw)`), so the single execution must be
3231
- * exactly `encodePacked(asset, 0, transfer(delegateAddress, amount))`.
3232
- *
3233
- * `delegateAddress` is the signing key's OWN address — local, not from Haven —
3234
- * so even a compromised Haven can at most move budget into the agent's own
3235
- * EOA (the hot-delegate residual the sweep returns), never to an attacker.
3236
- * `asset` and `amount` keep the leg consistent with what is being paid. Two
3237
- * callers, two sources: the signer's x402 arm (#3281) passes the Haven-signed
3238
- * expected context's; `HavenClient.signForData` (#3375) passes the 402 option
3239
- * the SDK is paying, never the `/x402` response.
3240
- *
3241
- * Call ONLY after `assertBoundDirectPaymentUserOp` has passed on the same
3242
- * typed data (it proves the `execute` → `redeemDelegations` shape this reads).
3243
- * Throws `HavenTypedDataRefusedError` on any disagreement.
3244
- */
3245
- declare function assertFundingLegPaysDelegate(typedData: Record<string, unknown>, expected: {
3246
- delegateAddress: string;
3247
- asset: string;
3248
- amount: string;
3249
- }): void;
3250
-
3251
- /**
3252
- * Task budgets (#3329): independent verification of a task child delegation
3253
- * and its close UserOp, mirroring `settlement-child.ts` / `direct-payment-
3254
- * guard.ts` for a DIFFERENT typed-data class.
3255
- *
3256
- * A task budget's child is a SELF-delegation: the agent's own delegate
3257
- * account grants itself a narrower, time-boxed slice of its budget
3258
- * delegation (`delegate === delegator === the agent's own account`), chained
3259
- * under the budget via `authority`. That is what separates it from an x402
3260
- * settlement child, whose `delegate` is a facilitator/ANY_BENEFICIARY — never
3261
- * the agent's own account. `isSettlementChildTypedData` (`settlement-
3262
- * child.ts`) was narrowed to return `false` for a self-delegated payload so
3263
- * the two classes cannot be confused by either verifier; this file is the
3264
- * task-child counterpart, verified against a different expectation
3265
- * (`GET /task-budgets/:id/sign-context`, never a merchant's 402).
3266
- *
3267
- * Two shapes, two functions:
3268
- * - `assertOwnTaskChild` verifies the `Delegation` typed data signed to OPEN
3269
- * a task budget.
3270
- * - `assertOwnTaskBudgetCloseUserOp` verifies the `PackedUserOperation`
3271
- * typed data signed to CLOSE one early (an on-chain
3272
- * `disableDelegation(child)` call from the agent's own account) — an
3273
- * authority-REDUCING action only, never a grant.
3274
- *
3275
- * `hashDelegation` below reproduces `@metamask/smart-accounts-kit/utils`'s
3276
- * struct hash (via `@metamask/delegation-core`) byte-for-byte, WITHOUT taking
3277
- * the kit as a runtime dependency (this package installs on users' machines —
3278
- * same reasoning `delegate-account.ts` and `settlement-child.ts` give for
3279
- * their own vendored constants). `DELEGATION_TYPEHASH` / `CAVEAT_TYPEHASH`
3280
- * are pinned literals, cross-checked against the kit's own `hashDelegation`
3281
- * by a test vector in `task-budget-guards.test.ts` (which imports the kit
3282
- * ONLY in that test file).
3283
- */
3284
-
3285
- /** The backend's own ceiling (`MAX_TASK_BUDGET_TTL_SECONDS`), enforced again here. */
3286
- declare const MAX_TASK_BUDGET_TTL_SECONDS = 86400;
3287
- interface TaskChildTypedData {
3288
- domain: {
3289
- name?: string;
3290
- version?: string;
3291
- chainId?: number | string;
3292
- verifyingContract?: string;
3293
- };
3294
- types: Record<string, unknown>;
3295
- primaryType: string;
3296
- message: Record<string, unknown>;
3297
- }
3298
- /**
3299
- * True when this typed data is a task-budget child: a `Delegation` whose
3300
- * `delegate` equals its own `delegator` (self-delegation). This is the ONLY
3301
- * shape distinguishing it from an x402 settlement child (whose `delegate` is
3302
- * a facilitator or `ANY_BENEFICIARY`) — `isSettlementChildTypedData` is
3303
- * narrowed to return `false` for this same shape so the two verifiers never
3304
- * overlap.
3305
- */
3306
- declare function isTaskChildTypedData(value: unknown): value is TaskChildTypedData;
3307
- interface TaskChildExpectation {
3308
- chainId: number;
3309
- tokenAddress: string;
3310
- maxAmountAtomic: string;
3311
- recipientAddress: string | null;
3312
- /** unix seconds — the `TimestampEnforcer`'s `beforeThreshold`. */
3313
- expiresAt: number;
3314
- parentDelegationHash: string;
3315
- }
3316
- /**
3317
- * Verify a task-budget child delegation is EXACTLY what
3318
- * `GET /task-budgets/:id/sign-context` (purpose `open`) declared, AND that
3319
- * both `delegate` and `delegator` are this signer's OWN account. Throws
3320
- * `HavenTypedDataRefusedError` (never returns) on any disagreement.
3321
- */
3322
- declare function assertOwnTaskChild(typedData: unknown, expected: TaskChildExpectation, delegateAddress: string, now?: number): void;
3323
- interface TaskBudgetCloseExpectation {
3324
- /** The child delegation's own struct hash (`agent_task_budgets.delegation_hash`). */
3325
- delegationHash: string;
3326
- }
3327
- /**
3328
- * Verify a task-budget close UserOp is EXACTLY an on-chain
3329
- * `disableDelegation(child)` call from the agent's own delegate account —
3330
- * authority-REDUCING only, never a grant. Throws `HavenTypedDataRefusedError`
3331
- * (never returns) on any disagreement.
3332
- */
3333
- declare function assertOwnTaskBudgetCloseUserOp(typedData: Record<string, unknown>, expected: TaskBudgetCloseExpectation, delegateAddress: string): void;
3334
- /**
3335
- * `@metamask/delegation-core`'s `DELEGATION_TYPEHASH` — pinned, cross-checked
3336
- * against the kit by a test vector in `task-budget-guards.test.ts`.
3337
- */
3338
- declare const DELEGATION_TYPEHASH: Hex;
3339
- /** `@metamask/delegation-core`'s `CAVEAT_TYPEHASH` — pinned, same cross-check. */
3340
- declare const CAVEAT_TYPEHASH: Hex;
3341
- interface DelegationForHashing {
3342
- delegate: Address;
3343
- delegator: Address;
3344
- authority: Hex;
3345
- caveats: readonly {
3346
- enforcer: Address;
3347
- terms: Hex;
3348
- }[];
3349
- salt: bigint;
3350
- }
3351
- /**
3352
- * Reproduces `@metamask/smart-accounts-kit/utils`'s `hashDelegation`
3353
- * byte-for-byte, WITHOUT the kit at runtime (see the file header). Ignores
3354
- * `signature` — the kit's own `hashDelegation` does the same (it hashes with
3355
- * `signature: '0x'` regardless of what the caller passes).
3356
- */
3357
- declare function hashDelegation(delegation: DelegationForHashing): Hex;
3358
-
3359
- /**
3360
- * Runtime-agnostic base64 helpers — the single source of truth for the wire
3361
- * encoding shared by the SDK and the edge signer (#325).
3362
- *
3363
- * Why this module exists: the SDK used `atob`/`btoa` (Web globals) while the
3364
- * signer used `Buffer` (Node-only). Both worked because both currently run in
3365
- * Node ≥ 16, but the duplication was a latent wire-incompatibility — and the
3366
- * signer is headed for non-Node runtimes (browsers, Cloudflare Workers) where
3367
- * `Buffer` does not exist (#314).
3368
- *
3369
- * Encoding contract:
3370
- * - Output is ALWAYS standard base64 (`+`, `/`, padded). The x402 protocol's
3371
- * reference implementation validates headers against
3372
- * `/^[A-Za-z0-9+/]*={0,2}$/` — URL-safe output would be rejected.
3373
- * - Decoding is tolerant: URL-safe input (`-`, `_`, unpadded) is normalized
3374
- * before decoding, since third-party merchants are not guaranteed to be as
3375
- * strict as the reference implementation.
3376
- * - UTF-8 throughout. Naive `btoa(JSON.stringify(...))` throws on any
3377
- * non-Latin-1 character (e.g. a merchant description with an emoji or
3378
- * non-ASCII name); these helpers route through TextEncoder/TextDecoder on
3379
- * the Web path so multibyte characters round-trip identically on both
3380
- * runtimes.
3381
- */
3382
- /** Encode a UTF-8 string as standard base64. */
3383
- declare function encodeBase64Utf8(value: string): string;
3384
- /** Decode standard or URL-safe base64 to a UTF-8 string. */
3385
- declare function decodeBase64Utf8(value: string): string;
3386
- /** Encode a JSON-serializable value as a standard-base64 string. */
3387
- declare function encodeBase64Json(value: unknown): string;
3388
- /**
3389
- * Decode a base64 JSON payload.
3390
- *
3391
- * Pass a `label` to get a wrapped error message instead of the raw
3392
- * JSON/base64 error — call sites parsing untrusted merchant headers use this
3393
- * to produce actionable failures.
3394
- */
3395
- declare function decodeBase64Json<T>(value: string, label?: string): T;
3396
-
3397
- export { AgentPaymentFailureCodeSchema as $, type AgentPaymentWarning as A, type BudgetPrecheckResult as B, type CloseTaskBudgetResult as C, type X402Erc7710Settlement as D, type X402McpCallContext as E, type SignData as F, type ResumeAuthorizedX402Input as G, type HavenClientConfig as H, type ResumeX402PaymentInput as I, type X402ResumeState as J, type X402McpTransport as K, type X402MerchantCallContext as L, HavenError as M, AGENT_PAYMENT_FAILURE_CODE_VALUES as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, AGENT_PAYMENT_NEXT_ACTION_VALUES as Q, type RawPaymentParties as R, type SweepResult as S, type TaskBudgetSignContext as T, AGENT_PAYMENT_PHASE_VALUES as U, AGENT_PAYMENT_RAIL_VALUES as V, type AgentNextStep as W, type X402PaymentRequired as X, type AgentPaymentEnumSchema as Y, AgentPaymentFailureCode as Z, AgentPaymentFailureCodeDescriptions as _, type HavenClientUpdate as a, SignerRefusalCode as a$, AgentPaymentNextAction as a0, AgentPaymentNextActionDescriptions as a1, AgentPaymentNextActionSchema as a2, AgentPaymentPhase as a3, AgentPaymentPhaseDescriptions as a4, AgentPaymentPhaseSchema as a5, AgentPaymentRail as a6, AgentPaymentRailDescriptions as a7, AgentPaymentRailSchema as a8, type AgentPaymentSummary as a9, HavenZeroSettlementHashError as aA, MAX_TASK_BUDGET_TTL_SECONDS as aB, type MachinePaymentRail as aC, MerchantTimeoutError as aD, NEXT_TOOL_SERVER_NAMES as aE, NEXT_TOOL_SERVER_ROLES as aF, type NextStep as aG, type NextStepArguments as aH, type NextStepHandoff as aI, type NextStepInput as aJ, type NextStepTarget as aK, type NextStepTargets as aL, type NextToolServerRole as aM, PACKED_USER_OPERATION_FIELDS as aN, type PaymentFee as aO, type PaymentNextAction as aP, type PaymentPhase as aQ, type PaymentStatus as aR, ROOT_AUTHORITY as aS, SDK_CLIENT_IDENTITY as aT, SDK_VERSION as aU, SIGNER_UPDATE_FALLBACK as aV, SWEEP_BASE_CHAIN_ID as aW, SWEEP_BASE_SEPOLIA_CHAIN_ID as aX, SWEEP_BASE_SEPOLIA_USDC_ADDRESS as aY, SWEEP_BASE_USDC_ADDRESS as aZ, type SettlementChildExpectation as a_, AgentPaymentWarningCode as aa, type AgentPurchaseSummary as ab, CONNECTOR_PACKAGE_NAME as ac, type CatalogSubmissionAccepted as ad, DEFAULT_CONFIRMATION_TIMEOUT_MS as ae, DEFAULT_NEXT_TOOL_BY_ACTION as af, DIRECT_SIGN_CONTEXT_VERSION as ag, ENTRY_POINT_V07 as ah, ERC7710_ASSET_TRANSFER_METHOD as ai, HAVEN_CLIENT_HEADER as aj, HAVEN_CONNECTOR_CHANNEL as ak, HAVEN_MINIMUM_NODE_VERSION as al, HYBRID_DELEGATOR_DOMAIN_NAME as am, HYBRID_DELEGATOR_DOMAIN_VERSION as an, type HavenAgentAllowanceSummary as ao, type HavenAgentReadiness as ap, type HavenAllowance as aq, HavenApiError as ar, type HavenCatalogMerchant as as, type HavenListScope as at, HavenPaymentStateError as au, HavenSigningError as av, HavenTimeoutError as aw, HavenTypedDataRefusedError as ax, HavenUnsupportedSignerVersionError as ay, HavenUserOpBindingError as az, type PaymentResult as b, parsePaymentRequiredResponse as b$, type SweepConfirmation as b0, type SweepEip712Domain as b1, type SweepEntry as b2, type SweepExpectedAuth as b3, type SweepPreparation as b4, type SweepSubmitResult as b5, type SweepTypedData as b6, TASK_SIGN_CONTEXT_VERSION as b7, TRANSFER_WITH_AUTHORIZATION_TYPES as b8, TYPED_DATA_NOT_ALLOWED as b9, buildSweepAuthorizationMessage as bA, buildSweepTypedData as bB, buildX402ExpectedMessage as bC, compareNodeVersions as bD, connectorRerunCommand as bE, connectorSpec as bF, connectorUpgradeCommand as bG, createNextStepBuilder as bH, decodeBase64Json as bI, decodeBase64Utf8 as bJ, defaultNextToolFor as bK, deriveDelegateAccountAddress as bL, encodeBase64Json as bM, encodeBase64Utf8 as bN, encodePaymentProof as bO, hashDelegation as bP, havenClientIdentity as bQ, isConnectorChannel as bR, isErc7710Option as bS, isPackedUserOperationTypedData as bT, isSupportedNodeVersion as bU, isSweepableChain as bV, isTaskChildTypedData as bW, normalizePaymentRequired as bX, packedUserOperationHash as bY, parseNextTool as bZ, parsePaymentRequired as b_, type TaskBudgetCloseExpectation as ba, type TaskChildExpectation as bb, type TaskChildTypedData as bc, type UnsupportedNodeVersionMessageOptions as bd, X402AlreadySettledError as be, X402Erc7710AlreadySettledError as bf, type X402ExpectedAuth as bg, type X402ExpectedContext as bh, type X402PaymentHeaderContext as bi, X402PaymentHeaderValidationError as bj, type X402PaymentOption as bk, type X402RequestSnapshot as bl, type X402SchemeSelection as bm, X402TaskBudgetMismatchError as bn, X402UnexpectedStatusError as bo, X402_LEGACY_PAYMENT_HEADER_NAME as bp, X402_MAX_AUTHORIZATION_WINDOW_SECONDS as bq, X402_PAYMENT_HEADER_NAME as br, X402_PAYMENT_HEADER_NAMES_SENT as bs, X402_PAYMENT_REQUIRED_HEADER_NAME as bt, X402_PAYMENT_RESPONSE_HEADER_NAME as bu, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS as bv, assertBoundDirectPaymentUserOp as bw, assertOwnTaskBudgetCloseUserOp as bx, assertOwnTaskChild as by, assertUserOpTypedDataBinding as bz, type PaymentIntent as c, readClientUpdate as c0, renderNextTool as c1, resolveConnectorChannel as c2, resolveTokenBySymbol as c3, resolveTokenFromAddress as c4, selectErc7710PaymentOption as c5, selectPaymentOption as c6, selectStandardPaymentOption as c7, selectX402SettlementScheme as c8, signerUpdateFallback as c9, sweepUsdcAddress as ca, sweepUsdcDomain as cb, toStandardPaymentRequirements as cc, unsupportedNodeVersionMessage as cd, validateStandardX402PaymentHeader as ce, verifySettlementChild as cf, x402AssetTransferMethod as cg, x402AuthorizationAmount as ch, x402FacilitatorAddresses as ci, x402V2PaymentEnvelope as cj, type DelegationForHashing as ck, CAVEAT_ENFORCERS as cl, CAVEAT_TYPEHASH as cm, DELEGATION_MANAGER as cn, DELEGATION_TYPEHASH as co, DIRECT_PAYMENT_CHAIN_IDS as cp, EXECUTE_ABI as cq, HYBRID_DELEGATOR_IMPLEMENTATION as cr, MAX_SETTLEMENT_WINDOW_SECONDS as cs, SIMPLE_FACTORY_ADDRESS as ct, type SettlementChildTypedData as cu, assertFundingLegPaysDelegate as cv, assertOwnSettlementChild as cw, chainIdForNetwork as cx, isSettlementChildTypedData as cy, type X402AuthorizationOptions as d, type X402Intent as e, type PaymentStatusResult as f, type HavenAgent as g, type HavenAgentSummary as h, type SweepPrepareResponse as i, type SweepAuthorization as j, type SweepSubmitResponse as k, type HavenAllowanceSummary as l, type HavenBalanceCoverage as m, type PostPurchaseAllowanceSummary as n, type HavenCatalogEntry as o, type HavenCatalogSubmission as p, type HavenPaymentReceipt as q, type HavenPaymentReceiptsPage as r, type HavenTaskBudget as s, type SubmitTaskBudgetResult as t, type SubmitSubBudgetResult as u, type HavenPendingSubBudgetSignature as v, type CloseSubBudgetResult as w, type PaymentResumeState as x, type X402Receipt as y, type X402Quote as z };
2299
+ export { AgentPaymentNextActionSchema as $, type AgentPaymentWarning as A, type BudgetPrecheckResult as B, type CloseTaskBudgetResult as C, type X402ResumeState as D, type X402McpTransport as E, type X402MerchantCallContext as F, type X402IntentByKey as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, type MerchantEgressPolicy as M, AGENT_PAYMENT_RAIL_VALUES as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentNextStep as Q, type ResumeAuthorizedX402Input as R, type SweepResult as S, type TaskBudgetSignContext as T, type AgentPaymentEnumSchema as U, AgentPaymentFailureCode as V, AgentPaymentFailureCodeDescriptions as W, type X402PaymentRequired as X, AgentPaymentFailureCodeSchema as Y, AgentPaymentNextAction as Z, AgentPaymentNextActionDescriptions as _, type PaymentResult as a, AgentPaymentPhase as a0, AgentPaymentPhaseDescriptions as a1, AgentPaymentPhaseSchema as a2, AgentPaymentRail as a3, AgentPaymentRailDescriptions as a4, AgentPaymentRailSchema as a5, type AgentPaymentSummary as a6, AgentPaymentWarningCode as a7, type AgentPurchaseSummary as a8, type CatalogSubmissionAccepted as a9, type PaymentNextAction as aA, type PaymentPhase as aB, type PaymentStatus as aC, SIGNER_UPDATE_FALLBACK as aD, SignerRefusalCode as aE, type SweepConfirmation as aF, type SweepEntry as aG, X402AlreadySettledError as aH, X402Erc7710AlreadySettledError as aI, type X402ExpectedAuth as aJ, type X402ExpectedContext as aK, type X402PaymentOption as aL, type X402RequestSnapshot as aM, X402TaskBudgetMismatchError as aN, X402UnexpectedStatusError as aO, assertPublicHttpsMerchantUrl as aP, isPublicHttpsMerchantUrl as aQ, publicHttpsMerchantUrlRefusal as aR, readBodyCapped as aS, signerUpdateFallback as aT, strictMerchantEgressPolicy as aU, type RawPaymentParties as aV, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, HOSTED_DISCOVERY_TIMEOUT_MS as ab, HOSTED_EGRESS_TIMEOUTS as ac, HOSTED_MAX_GET_REDIRECTS as ad, HOSTED_RESPONSE_BYTE_CAPS as ae, type HavenAgentAllowanceSummary as af, type HavenAgentReadiness as ag, type HavenAllowance as ah, HavenApiError as ai, type HavenCatalogMerchant as aj, type HavenListScope as ak, HavenPaymentStateError as al, HavenSigningError as am, HavenTimeoutError as an, HavenUnsupportedSignerVersionError as ao, HavenZeroSettlementHashError as ap, MERCHANT_EGRESS_REFUSED_CODE as aq, MERCHANT_EGRESS_RESPONSE_CAP_CODE as ar, type MachinePaymentRail as as, type MerchantEgressRefusalReason as at, MerchantEgressRefusedError as au, MerchantEgressResponseCapError as av, type MerchantEgressTimeouts as aw, type MerchantEgressUse as ax, MerchantTimeoutError as ay, type PaymentFee as az, type PaymentIntent as b, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type HavenAllowanceSummary as h, type HavenBalanceCoverage as i, type PostPurchaseAllowanceSummary as j, type HavenCatalogEntry as k, type HavenCatalogSubmission as l, type HavenPaymentReceipt as m, type HavenPaymentReceiptsPage as n, type HavenTaskBudget as o, type SubmitTaskBudgetResult as p, type SubmitSubBudgetResult as q, type HavenPendingSubBudgetSignature as r, type CloseSubBudgetResult as s, type PaymentResumeState as t, type X402Receipt as u, type X402Quote as v, type X402Erc7710Settlement as w, type X402McpCallContext as x, type SignData as y, type ResumeX402PaymentInput as z };