@haven_ai/sdk 0.5.0-alpha.1 → 0.7.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.
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkQSSVOPWA_cjs = require('./chunk-QSSVOPWA.cjs');
4
- var chunkJKUIE45B_cjs = require('./chunk-JKUIE45B.cjs');
3
+ var chunkJ6DQEBK2_cjs = require('./chunk-J6DQEBK2.cjs');
4
+ var chunk3SVPI4LS_cjs = require('./chunk-3SVPI4LS.cjs');
5
5
  var viem = require('viem');
6
6
  var ethers = require('ethers');
7
7
  var async_hooks = require('async_hooks');
@@ -14,7 +14,7 @@ function signHash(privateKey, hash) {
14
14
  const sig = signingKey.sign(hash);
15
15
  return sig.serialized;
16
16
  } catch (err) {
17
- throw new chunkJKUIE45B_cjs.HavenSigningError(
17
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
18
18
  `Failed to sign hash: ${err instanceof Error ? err.message : String(err)}`
19
19
  );
20
20
  }
@@ -30,7 +30,7 @@ async function signTypedDataVerbatim(privateKey, typedData, label) {
30
30
  typedData.message
31
31
  );
32
32
  } catch (err) {
33
- throw new chunkJKUIE45B_cjs.HavenSigningError(
33
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
34
34
  `Failed to sign ${label}: ${err instanceof Error ? err.message : String(err)}`
35
35
  );
36
36
  }
@@ -45,7 +45,7 @@ function addressFromKey(privateKey) {
45
45
  try {
46
46
  return new ethers.ethers.Wallet(privateKey).address;
47
47
  } catch (err) {
48
- throw new chunkJKUIE45B_cjs.HavenSigningError(
48
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
49
49
  `Invalid private key: ${err instanceof Error ? err.message : String(err)}`
50
50
  );
51
51
  }
@@ -61,7 +61,7 @@ function verifySignature(hash, signature, expectedAddress) {
61
61
  var DEFAULT_BASE_URL = "http://localhost:3001";
62
62
  var DEFAULT_REQUEST_TIMEOUT = 3e4;
63
63
  function withoutClientHeader(headers) {
64
- const target = chunkQSSVOPWA_cjs.HAVEN_CLIENT_HEADER.toLowerCase();
64
+ const target = chunkJ6DQEBK2_cjs.HAVEN_CLIENT_HEADER.toLowerCase();
65
65
  return Object.fromEntries(Object.entries(headers).filter(([name]) => name.toLowerCase() !== target));
66
66
  }
67
67
  var HavenApiTransport = class {
@@ -77,7 +77,7 @@ var HavenApiTransport = class {
77
77
  this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
78
78
  this.requestTimeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT;
79
79
  this.defaultHeaders = { ...config.defaultHeaders ?? {} };
80
- this.clientIdentity = config.clientIdentity ?? chunkQSSVOPWA_cjs.SDK_CLIENT_IDENTITY;
80
+ this.clientIdentity = config.clientIdentity ?? chunkJ6DQEBK2_cjs.SDK_CLIENT_IDENTITY;
81
81
  }
82
82
  /**
83
83
  * The newest `client_update` the backend sent (#3303): inside a
@@ -90,7 +90,7 @@ var HavenApiTransport = class {
90
90
  }
91
91
  recordClientUpdate(data) {
92
92
  if (data === null || typeof data !== "object" || Array.isArray(data)) return;
93
- const hint = chunkQSSVOPWA_cjs.readClientUpdate(data.client_update);
93
+ const hint = chunkJ6DQEBK2_cjs.readClientUpdate(data.client_update);
94
94
  if (!hint) return;
95
95
  this.lastClientUpdate = hint;
96
96
  const store = this.requestContext.getStore();
@@ -123,7 +123,7 @@ var HavenApiTransport = class {
123
123
  // JOIN `x-haven-client` and `X-Haven-Client` into one unparseable
124
124
  // value), so neither `defaultHeaders` nor a dispatch context can
125
125
  // misname the client; `clientIdentity` is the one way to set it.
126
- [chunkQSSVOPWA_cjs.HAVEN_CLIENT_HEADER]: this.clientIdentity
126
+ [chunkJ6DQEBK2_cjs.HAVEN_CLIENT_HEADER]: this.clientIdentity
127
127
  },
128
128
  body: body ? JSON.stringify(body) : void 0,
129
129
  signal: controller.signal
@@ -136,15 +136,15 @@ var HavenApiTransport = class {
136
136
  const rawDetails = record.details ?? record.detail;
137
137
  const detailsText = typeof rawDetails === "string" ? rawDetails : rawDetails != null ? JSON.stringify(rawDetails) : void 0;
138
138
  const message = errorText && detailsText ? `${errorText}: ${detailsText}` : errorText ?? detailsText ?? "API request failed";
139
- throw new chunkJKUIE45B_cjs.HavenApiError(message, res.status, data);
139
+ throw new chunk3SVPI4LS_cjs.HavenApiError(message, res.status, data);
140
140
  }
141
141
  return data;
142
142
  } catch (err) {
143
- if (err instanceof chunkJKUIE45B_cjs.HavenApiError) throw err;
143
+ if (err instanceof chunk3SVPI4LS_cjs.HavenApiError) throw err;
144
144
  if (err instanceof Error && err.name === "AbortError") {
145
- throw new chunkJKUIE45B_cjs.HavenApiError(`Request to ${path} timed out`, 408);
145
+ throw new chunk3SVPI4LS_cjs.HavenApiError(`Request to ${path} timed out`, 408);
146
146
  }
147
- throw new chunkJKUIE45B_cjs.HavenApiError(
147
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
148
148
  `Request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,
149
149
  0
150
150
  );
@@ -161,7 +161,18 @@ function mapParties(raw) {
161
161
  treasuryAccount: raw.treasury_account,
162
162
  delegate: raw.delegate,
163
163
  delegateAccount: raw.delegate_account,
164
- merchant: raw.merchant
164
+ merchant: raw.merchant,
165
+ // #3332: additive — absent unless the wire shape carries it.
166
+ ...raw.buyer ? {
167
+ buyer: {
168
+ legalName: raw.buyer.legal_name,
169
+ country: raw.buyer.country,
170
+ orgNumber: raw.buyer.org_number,
171
+ vatNumber: raw.buyer.vat_number,
172
+ viesStatus: raw.buyer.vies_status,
173
+ viesCheckedAt: raw.buyer.vies_checked_at
174
+ }
175
+ } : {}
165
176
  };
166
177
  }
167
178
  function mapPaymentResult(raw, buildExplorerUrl2) {
@@ -205,6 +216,9 @@ function mapPaymentStatusResult(raw) {
205
216
  expiresAt: raw.expires_at,
206
217
  chainId: raw.chain_id,
207
218
  message: raw.message,
219
+ // #3420: the delivered half of the settle vocabulary, additive — absent
220
+ // from the raw payload (older backend) stays absent here.
221
+ ...raw.delivered === true ? { delivered: true } : {},
208
222
  fee: raw.fee ? {
209
223
  amount: raw.fee.amount,
210
224
  token: raw.fee.token,
@@ -232,17 +246,13 @@ function mapPaymentReceipt(raw) {
232
246
  id: raw.id,
233
247
  paymentId: raw.payment_id,
234
248
  source: raw.rail,
235
- rail: raw.rail,
236
249
  paymentProofStatus: raw.proof_status,
237
- proofStatus: raw.proof_status,
238
250
  txHash: raw.tx_hash,
239
251
  fundingTxHash: raw.funding_tx_hash ?? null,
240
252
  settlementTxHash: raw.settlement_tx_hash ?? null,
241
253
  chainId: raw.chain_id,
242
254
  x402ResourceUrl: raw.resource_url,
243
- resourceUrl: raw.resource_url,
244
255
  x402MerchantAddress: raw.merchant_address,
245
- merchantAddress: raw.merchant_address,
246
256
  payerAddress: raw.payer_address,
247
257
  parties: mapParties(raw.parties),
248
258
  settlementAddress: raw.settlement_address,
@@ -291,29 +301,29 @@ function paymentStateStatusCode(status, fallback = 502) {
291
301
  return PAYMENT_STATE_STATUS_CODES[status] ?? fallback;
292
302
  }
293
303
  function phaseForStatus(status) {
294
- if (status === "pending_signature") return chunkJKUIE45B_cjs.AgentPaymentPhase.AgentSignatureRequired;
295
- if (status === "submitted") return chunkJKUIE45B_cjs.AgentPaymentPhase.PaymentSubmitted;
296
- if (status === "confirmed") return chunkJKUIE45B_cjs.AgentPaymentPhase.PaymentConfirmed;
297
- if (status === "pending" || status === "pending_approval") return chunkJKUIE45B_cjs.AgentPaymentPhase.UserApprovalRequired;
298
- if (status === "approved") return chunkJKUIE45B_cjs.AgentPaymentPhase.UserExecutionRequired;
299
- if (status === "proposed") return chunkJKUIE45B_cjs.AgentPaymentPhase.WaitingForAdditionalApprovals;
300
- if (status === "executed") return chunkJKUIE45B_cjs.AgentPaymentPhase.FundingSent;
301
- if (status === "rejected") return chunkJKUIE45B_cjs.AgentPaymentPhase.Rejected;
302
- if (status === "expired") return chunkJKUIE45B_cjs.AgentPaymentPhase.Expired;
303
- if (status === "failed") return chunkJKUIE45B_cjs.AgentPaymentPhase.Failed;
304
+ if (status === "pending_signature") return chunk3SVPI4LS_cjs.AgentPaymentPhase.AgentSignatureRequired;
305
+ if (status === "submitted") return chunk3SVPI4LS_cjs.AgentPaymentPhase.PaymentSubmitted;
306
+ if (status === "confirmed") return chunk3SVPI4LS_cjs.AgentPaymentPhase.PaymentConfirmed;
307
+ if (status === "pending" || status === "pending_approval") return chunk3SVPI4LS_cjs.AgentPaymentPhase.UserApprovalRequired;
308
+ if (status === "approved") return chunk3SVPI4LS_cjs.AgentPaymentPhase.UserExecutionRequired;
309
+ if (status === "proposed") return chunk3SVPI4LS_cjs.AgentPaymentPhase.WaitingForAdditionalApprovals;
310
+ if (status === "executed") return chunk3SVPI4LS_cjs.AgentPaymentPhase.FundingSent;
311
+ if (status === "rejected") return chunk3SVPI4LS_cjs.AgentPaymentPhase.Rejected;
312
+ if (status === "expired") return chunk3SVPI4LS_cjs.AgentPaymentPhase.Expired;
313
+ if (status === "failed") return chunk3SVPI4LS_cjs.AgentPaymentPhase.Failed;
304
314
  return null;
305
315
  }
306
316
  function nextActionForStatus(status) {
307
- if (status === "pending_signature") return chunkJKUIE45B_cjs.AgentPaymentNextAction.SignAndSubmitPayment;
308
- if (status === "submitted") return chunkJKUIE45B_cjs.AgentPaymentNextAction.CheckStatusLater;
309
- if (status === "confirmed") return chunkJKUIE45B_cjs.AgentPaymentNextAction.None;
310
- if (status === "pending" || status === "pending_approval") return chunkJKUIE45B_cjs.AgentPaymentNextAction.StopAndTellUser;
311
- if (status === "approved") return chunkJKUIE45B_cjs.AgentPaymentNextAction.StopAndTellUser;
312
- if (status === "proposed") return chunkJKUIE45B_cjs.AgentPaymentNextAction.StopAndTellUser;
313
- if (status === "executed") return chunkJKUIE45B_cjs.AgentPaymentNextAction.StopAndTellUser;
314
- if (status === "rejected") return chunkJKUIE45B_cjs.AgentPaymentNextAction.StopAndTellUser;
315
- if (status === "expired") return chunkJKUIE45B_cjs.AgentPaymentNextAction.RequestAgainIfUserStillWantsIt;
316
- if (status === "failed") return chunkJKUIE45B_cjs.AgentPaymentNextAction.StopAndTellUser;
317
+ if (status === "pending_signature") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.SignAndSubmitPayment;
318
+ if (status === "submitted") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.CheckStatusLater;
319
+ if (status === "confirmed") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.None;
320
+ if (status === "pending" || status === "pending_approval") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.StopAndTellUser;
321
+ if (status === "approved") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.StopAndTellUser;
322
+ if (status === "proposed") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.StopAndTellUser;
323
+ if (status === "executed") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.StopAndTellUser;
324
+ if (status === "rejected") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.StopAndTellUser;
325
+ if (status === "expired") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.RequestAgainIfUserStillWantsIt;
326
+ if (status === "failed") return chunk3SVPI4LS_cjs.AgentPaymentNextAction.StopAndTellUser;
317
327
  return null;
318
328
  }
319
329
  function messageForState(label, status, paymentId, nextAction) {
@@ -387,17 +397,17 @@ function throwPaymentStateError(label, raw) {
387
397
  const statusCode = paymentStateStatusCode(raw.status);
388
398
  const state = paymentStateFromRaw(label, raw);
389
399
  if (state) {
390
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(state.message, statusCode, state, raw);
400
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(state.message, statusCode, state, raw);
391
401
  }
392
402
  if (raw.status === "pending_approval") {
393
- throw new chunkJKUIE45B_cjs.HavenApiError(
403
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
394
404
  `${label} exceeds the agent's on-chain budget and was declined; no approval is pending and none will arrive (payment_id: ${raw.payment_id}).`,
395
405
  statusCode,
396
406
  raw
397
407
  );
398
408
  }
399
409
  if (raw.status === "expired") {
400
- throw new chunkJKUIE45B_cjs.HavenApiError(
410
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
401
411
  `${label} expired before it could be completed (payment_id: ${raw.payment_id}).`,
402
412
  statusCode,
403
413
  raw
@@ -405,7 +415,7 @@ function throwPaymentStateError(label, raw) {
405
415
  }
406
416
  const paymentId = raw.payment_id ? ` (payment_id: ${raw.payment_id})` : "";
407
417
  const message = raw.error ?? `${label} ${raw.status}${paymentId}`;
408
- throw new chunkJKUIE45B_cjs.HavenApiError(message, statusCode, raw);
418
+ throw new chunk3SVPI4LS_cjs.HavenApiError(message, statusCode, raw);
409
419
  }
410
420
 
411
421
  // src/x402-retry-target.ts
@@ -437,7 +447,7 @@ function isSecureX402RetryTarget(url) {
437
447
  return RESERVED_SUFFIXES.some((suffix) => host.endsWith(suffix));
438
448
  }
439
449
  var INSECURE_RETRY_TARGET_CODE = "INSECURE_RETRY_TARGET";
440
- var HavenInsecureRetryTargetError = class extends chunkJKUIE45B_cjs.HavenError {
450
+ var HavenInsecureRetryTargetError = class extends chunk3SVPI4LS_cjs.HavenError {
441
451
  constructor(url) {
442
452
  super(
443
453
  `Refusing to send a payment header to ${url}: the paid x402 retry must go to an https URL (or a loopback / reserved test host). The merchant's challenge declared this resource URL; retry with the https URL you quoted (pass it as \`url\`), and report a merchant whose challenge downgrades the scheme.`,
@@ -479,7 +489,7 @@ var McpMerchantTransport = class {
479
489
  return await this.fetchImpl(url, { ...init, signal });
480
490
  } catch (err) {
481
491
  if (timeoutSignal.aborted) {
482
- throw new chunkJKUIE45B_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${url}`);
492
+ throw new chunk3SVPI4LS_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${url}`);
483
493
  }
484
494
  throw err;
485
495
  }
@@ -616,8 +626,8 @@ var McpMerchantTransport = class {
616
626
  async deliverPayment(url, init, paymentHeader) {
617
627
  assertSecureX402RetryTarget(url);
618
628
  const headers = new Headers(init?.headers);
619
- const send = chunkQSSVOPWA_cjs.x402PaymentHeaderNamesFor(paymentHeader);
620
- for (const name of chunkQSSVOPWA_cjs.X402_PAYMENT_HEADER_NAMES) {
629
+ const send = chunkJ6DQEBK2_cjs.x402PaymentHeaderNamesFor(paymentHeader);
630
+ for (const name of chunkJ6DQEBK2_cjs.X402_PAYMENT_HEADER_NAMES) {
621
631
  if (send.includes(name)) headers.set(name, paymentHeader);
622
632
  else headers.delete(name);
623
633
  }
@@ -704,7 +714,7 @@ function mcpToolResultOf(value) {
704
714
  function extractMcpPaymentRequired(toolResult) {
705
715
  if (toolResult.isError !== true) return void 0;
706
716
  if (isRecord(toolResult.structuredContent)) {
707
- const parsed = chunkQSSVOPWA_cjs.normalizePaymentRequired(toolResult.structuredContent);
717
+ const parsed = chunkJ6DQEBK2_cjs.normalizePaymentRequired(toolResult.structuredContent);
708
718
  if (parsed) return parsed;
709
719
  }
710
720
  if (Array.isArray(toolResult.content)) {
@@ -716,7 +726,7 @@ function extractMcpPaymentRequired(toolResult) {
716
726
  } catch {
717
727
  continue;
718
728
  }
719
- const parsed = chunkQSSVOPWA_cjs.normalizePaymentRequired(candidate);
729
+ const parsed = chunkJ6DQEBK2_cjs.normalizePaymentRequired(candidate);
720
730
  if (parsed) return parsed;
721
731
  }
722
732
  }
@@ -740,7 +750,7 @@ function withMcpPaymentMeta(init, paymentHeader) {
740
750
  if (!request) return init;
741
751
  let envelope;
742
752
  try {
743
- envelope = chunkQSSVOPWA_cjs.decodeBase64Json(paymentHeader);
753
+ envelope = chunkJ6DQEBK2_cjs.decodeBase64Json(paymentHeader);
744
754
  } catch {
745
755
  return init;
746
756
  }
@@ -756,7 +766,7 @@ function withMcpPaymentMeta(init, paymentHeader) {
756
766
  };
757
767
  }
758
768
  function encodeMcpSettlementReceipt(settlement) {
759
- return chunkQSSVOPWA_cjs.encodeBase64Json(settlement);
769
+ return chunkJ6DQEBK2_cjs.encodeBase64Json(settlement);
760
770
  }
761
771
  function parseJsonRpcToolsCall(body) {
762
772
  if (typeof body !== "string") return void 0;
@@ -842,22 +852,93 @@ function selectJsonRpcResult(messages) {
842
852
  return messages.find((message) => "result" in message || "error" in message) ?? messages.at(-1);
843
853
  }
844
854
  var RECEIPT_VERSION = "haven-receipt-1";
855
+ var DELEGATION_MANAGER_CHAIN_IDS = /* @__PURE__ */ new Set([8453, 84532]);
856
+ var EIP712_DOMAIN_TYPEHASH = viem.keccak256(
857
+ viem.toBytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
858
+ );
859
+ function delegationDomainSeparator(chainId) {
860
+ return viem.keccak256(
861
+ viem.encodeAbiParameters(
862
+ [{ type: "bytes32" }, { type: "bytes32" }, { type: "bytes32" }, { type: "uint256" }, { type: "address" }],
863
+ [
864
+ EIP712_DOMAIN_TYPEHASH,
865
+ viem.keccak256(viem.toBytes("DelegationManager")),
866
+ viem.keccak256(viem.toBytes("1")),
867
+ BigInt(chainId),
868
+ chunk3SVPI4LS_cjs.DELEGATION_MANAGER
869
+ ]
870
+ )
871
+ );
872
+ }
873
+ function delegationDigest(structHash, chainId) {
874
+ return viem.keccak256(viem.concatHex(["0x1901", delegationDomainSeparator(chainId), structHash]));
875
+ }
845
876
  function defaultRecover(hash, signature) {
846
877
  return ethers.ethers.recoverAddress(hash, signature);
847
878
  }
848
- function verifyPaymentReceipt(receipt, recover = defaultRecover) {
849
- const { delegate, signHash: signHash2, signature } = receipt.authorization;
850
- if (!signature) return { verified: false, reason: "missing_signature" };
879
+ var NOT_A_SIGNED_RECEIPT = { verified: false, reason: "not_a_signed_receipt" };
880
+ function match(delegate, hash, signature, recover) {
851
881
  let recovered;
852
882
  try {
853
- recovered = recover(signHash2, signature);
883
+ recovered = recover(hash, signature);
854
884
  } catch {
855
- return { verified: false, reason: "bad_signature" };
885
+ return { ok: false, reason: "bad_signature" };
856
886
  }
857
887
  if (recovered.toLowerCase() !== delegate.toLowerCase()) {
858
- return { verified: false, reason: "signer_mismatch", recoveredSigner: recovered };
888
+ return { ok: false, reason: "signer_mismatch", recoveredSigner: recovered };
889
+ }
890
+ return { ok: true, recoveredSigner: recovered };
891
+ }
892
+ function finish(result, verifiedOver) {
893
+ if (result.ok) {
894
+ return { verified: true, recoveredSigner: result.recoveredSigner, verifiedOver };
895
+ }
896
+ return result.recoveredSigner !== void 0 ? { verified: false, reason: result.reason, recoveredSigner: result.recoveredSigner } : { verified: false, reason: result.reason };
897
+ }
898
+ function verifyPaymentReceipt(receipt, recover = defaultRecover) {
899
+ if (typeof receipt !== "object" || receipt === null) return NOT_A_SIGNED_RECEIPT;
900
+ const source = receipt;
901
+ if (typeof source.authorization !== "object" || source.authorization === null) {
902
+ return NOT_A_SIGNED_RECEIPT;
903
+ }
904
+ const auth = source.authorization;
905
+ const { delegate, signHash: signHash2, signature, signatureScheme } = auth;
906
+ if (typeof delegate !== "string" || delegate === "" || typeof signHash2 !== "string" || signHash2 === "") {
907
+ return NOT_A_SIGNED_RECEIPT;
908
+ }
909
+ if (typeof signature !== "string" || signature === "") {
910
+ return { verified: false, reason: "missing_signature" };
911
+ }
912
+ const chainId = typeof source.onChain?.chainId === "number" ? source.onChain.chainId : void 0;
913
+ const digestVerifiable = chainId !== void 0 && DELEGATION_MANAGER_CHAIN_IDS.has(chainId);
914
+ if (signatureScheme === "eip712_userop") {
915
+ return { verified: false, reason: "not_verifiable_offline" };
916
+ }
917
+ if (signatureScheme === "eip712_delegation") {
918
+ if (!digestVerifiable) {
919
+ return { verified: false, reason: "not_verifiable_offline" };
920
+ }
921
+ let digest;
922
+ try {
923
+ digest = delegationDigest(signHash2, chainId);
924
+ } catch {
925
+ return { verified: false, reason: "bad_signature" };
926
+ }
927
+ return finish(match(delegate, digest, signature, recover), "delegation_digest");
928
+ }
929
+ const raw = match(delegate, signHash2, signature, recover);
930
+ if (raw.ok) return finish(raw, "sign_hash");
931
+ if (digestVerifiable) {
932
+ let digest;
933
+ try {
934
+ digest = delegationDigest(signHash2, chainId);
935
+ } catch {
936
+ return finish(raw, "sign_hash");
937
+ }
938
+ const delegated = match(delegate, digest, signature, recover);
939
+ if (delegated.ok) return finish(delegated, "delegation_digest");
859
940
  }
860
- return { verified: true, recoveredSigner: recovered };
941
+ return finish(raw, "sign_hash");
861
942
  }
862
943
 
863
944
  // src/account-reads.ts
@@ -880,9 +961,57 @@ function deriveReadiness(status, allowances) {
880
961
  return allowances.some((allowance) => safeBigInt(allowance.remainingAtomic) > 0n) ? "ready" : "needs_approval";
881
962
  }
882
963
  function formatRemainingDisplay(tokenAddress, tokenSymbol, remainingAtomic) {
883
- const token = chunkQSSVOPWA_cjs.resolveTokenFromAddress(tokenAddress);
964
+ const token = chunkJ6DQEBK2_cjs.resolveTokenFromAddress(tokenAddress);
884
965
  return token ? `${formatAtomicAmount(safeBigInt(remainingAtomic), token.decimals)} ${tokenSymbol}` : `${remainingAtomic} ${tokenSymbol} (atomic; unknown decimals)`;
885
966
  }
967
+ function formatTokenAmount(atomic, decimals) {
968
+ const value = safeBigInt(atomic);
969
+ if (value < 0n) return "0";
970
+ const digits = value.toString().padStart(decimals + 1, "0");
971
+ const intPart = digits.slice(0, digits.length - decimals) || "0";
972
+ const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, "");
973
+ return fracPart ? `${intPart}.${fracPart}` : intPart;
974
+ }
975
+ function mapTaskBudget(raw) {
976
+ return {
977
+ id: raw.id,
978
+ agentId: raw.agent_id,
979
+ chainId: raw.chain_id,
980
+ tokenAddress: raw.token_address,
981
+ recipientAddress: raw.recipient_address,
982
+ parentDelegationHash: raw.parent_delegation_hash,
983
+ delegationHash: raw.delegation_hash,
984
+ label: raw.label,
985
+ maxAtomic: raw.max_atomic,
986
+ status: raw.status,
987
+ expiresAt: raw.expires_at,
988
+ isExpired: raw.is_expired,
989
+ createdAt: raw.created_at,
990
+ openedAt: raw.opened_at,
991
+ closedAt: raw.closed_at,
992
+ closeTxHash: raw.close_tx_hash
993
+ };
994
+ }
995
+ function summarizeTaskBudget(taskBudget) {
996
+ const token = chunkJ6DQEBK2_cjs.resolveTokenFromAddress(taskBudget.tokenAddress);
997
+ const maxDisplay = token ? `${formatAtomicAmount(safeBigInt(taskBudget.maxAtomic), token.decimals)} ${token.symbol}` : `${taskBudget.maxAtomic} (atomic; unknown decimals)`;
998
+ return {
999
+ id: taskBudget.id,
1000
+ label: taskBudget.label,
1001
+ tokenAddress: taskBudget.tokenAddress,
1002
+ maxAtomic: taskBudget.maxAtomic,
1003
+ maxDisplay,
1004
+ recipientAddress: taskBudget.recipientAddress,
1005
+ expiresAt: taskBudget.expiresAt
1006
+ };
1007
+ }
1008
+ function compactReceipt(receipt) {
1009
+ const row = { ...receipt };
1010
+ delete row.challengePayload;
1011
+ delete row.selectedPayment;
1012
+ delete row.protocolReceiptPayload;
1013
+ return row;
1014
+ }
886
1015
  var AccountReads = class {
887
1016
  transport;
888
1017
  getPaymentStatus;
@@ -902,7 +1031,11 @@ var AccountReads = class {
902
1031
  return request;
903
1032
  }
904
1033
  async getAgentSummary() {
905
- const [agent, allowanceSummary] = await Promise.all([this.getAgent(), this.getAllowances()]);
1034
+ const [agent, allowanceSummary, taskBudgets] = await Promise.all([
1035
+ this.getAgent(),
1036
+ this.getAllowances(),
1037
+ this.listOpenTaskBudgetsSummary()
1038
+ ]);
906
1039
  const allowances = allowanceSummary.allowances.map((allowance) => {
907
1040
  return {
908
1041
  id: allowance.id,
@@ -916,7 +1049,30 @@ var AccountReads = class {
916
1049
  };
917
1050
  });
918
1051
  const readiness = deriveReadiness(agent.status, allowances);
919
- return { ...agent, readiness, spend_authority_readiness: readiness, allowances };
1052
+ return { ...agent, readiness, spend_authority_readiness: readiness, allowances, taskBudgets };
1053
+ }
1054
+ /**
1055
+ * #3329: `GET /task-budgets?status=open`, mapped to the condensed summary
1056
+ * row `getAgentSummary()` carries. Fails SOFT per the #3093 rule (default
1057
+ * every array wire key to `[]` so an absent/malformed key degrades instead
1058
+ * of taking the route down): a 404 (a backend that predates #3329's
1059
+ * route), ANY other transport error, an undefined/null body, or a missing
1060
+ * or non-array `task_budgets` key all return `[]` rather than throwing —
1061
+ * `getAgentSummary`'s identity + readiness + allowances fields are what
1062
+ * callers depend on, and this read must never be why the whole summary
1063
+ * fails.
1064
+ */
1065
+ async listOpenTaskBudgetsSummary() {
1066
+ try {
1067
+ const raw = await this.transport.get(
1068
+ "/task-budgets?status=open"
1069
+ );
1070
+ const rows = raw?.task_budgets;
1071
+ if (!Array.isArray(rows)) return [];
1072
+ return rows.map((row) => summarizeTaskBudget(mapTaskBudget(row)));
1073
+ } catch {
1074
+ return [];
1075
+ }
920
1076
  }
921
1077
  async getAllowances() {
922
1078
  const raw = await this.transport.get("/machine-payments/allowances");
@@ -984,7 +1140,7 @@ var AccountReads = class {
984
1140
  payment: payment2,
985
1141
  allowance: null,
986
1142
  warnings: [{
987
- code: chunkJKUIE45B_cjs.AgentPaymentWarningCode.AllowanceCheckUnavailable,
1143
+ code: chunk3SVPI4LS_cjs.AgentPaymentWarningCode.AllowanceCheckUnavailable,
988
1144
  message: `Could not read the post-purchase allowance/budget for payment ${paymentId} (${detail}). The payment itself succeeded \u2014 the on-chain policy remains the actual spend gate; this only affects the remaining-budget figure reported here.`
989
1145
  }]
990
1146
  });
@@ -1006,22 +1162,22 @@ var AccountReads = class {
1006
1162
  try {
1007
1163
  const tokenAddress = payment.asset ?? payment.x402?.asset ?? null;
1008
1164
  if (!tokenAddress) return unavailable("the settled payment does not carry a resolvable token address", payment);
1009
- const match = allowanceResult.value.allowances.find(
1165
+ const match2 = allowanceResult.value.allowances.find(
1010
1166
  (allowance) => allowance.tokenAddress.toLowerCase() === tokenAddress.toLowerCase()
1011
1167
  );
1012
- if (!match) return unavailable("no allowance/budget row matches the settled token", payment);
1013
- const token = chunkQSSVOPWA_cjs.resolveTokenFromAddress(match.tokenAddress);
1014
- const remainingDisplay = token ? `${formatAtomicAmount(safeBigInt(match.onchain.remaining), token.decimals)} ${match.tokenSymbol}` : void 0;
1168
+ if (!match2) return unavailable("no allowance/budget row matches the settled token", payment);
1169
+ const token = chunkJ6DQEBK2_cjs.resolveTokenFromAddress(match2.tokenAddress);
1170
+ const remainingDisplay = token ? `${formatAtomicAmount(safeBigInt(match2.onchain.remaining), token.decimals)} ${match2.tokenSymbol}` : void 0;
1015
1171
  const rail = agentResult.value.executionRail;
1016
1172
  return {
1017
1173
  payment,
1018
1174
  allowance: {
1019
1175
  rail,
1020
- remaining_atomic: match.onchain.remaining,
1176
+ remaining_atomic: match2.onchain.remaining,
1021
1177
  ...remainingDisplay ? { remaining_display: remainingDisplay } : {},
1022
- token_symbol: match.tokenSymbol,
1023
- token_address: match.tokenAddress,
1024
- reset_period: match.resetPeriodMin,
1178
+ token_symbol: match2.tokenSymbol,
1179
+ token_address: match2.tokenAddress,
1180
+ reset_period: match2.resetPeriodMin,
1025
1181
  source: rail === "delegation" ? "active_delegations" : "allowance_module"
1026
1182
  },
1027
1183
  warnings: []
@@ -1041,8 +1197,13 @@ var AccountReads = class {
1041
1197
  if (options.cursor) params.set("cursor", options.cursor);
1042
1198
  const query = params.size > 0 ? `?${params.toString()}` : "";
1043
1199
  const raw = await this.transport.get(`/machine-payments/receipts${query}`);
1200
+ const receipts = raw.receipts.map(mapPaymentReceipt);
1044
1201
  return {
1045
- receipts: raw.receipts.map(mapPaymentReceipt),
1202
+ // #3423 (owner decision, opt-in): `compact` drops the three bulky
1203
+ // payload echoes (the merchant's full 402 challenge, the selected
1204
+ // option, and the merchant's PAYMENT-RESPONSE) from each row. The keys
1205
+ // are absent, not null, and the default shape is unchanged.
1206
+ receipts: options.compact ? receipts.map(compactReceipt) : receipts,
1046
1207
  total: typeof raw.total === "number" ? raw.total : null,
1047
1208
  hasMore: typeof raw.has_more === "boolean" ? raw.has_more : null,
1048
1209
  nextCursor: typeof raw.next_cursor === "string" ? raw.next_cursor : null
@@ -1085,7 +1246,7 @@ function isWaitTimeout(err) {
1085
1246
  async function waitForSweepTx(tx) {
1086
1247
  let receipt;
1087
1248
  try {
1088
- receipt = await tx.wait(1, chunkJKUIE45B_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS);
1249
+ receipt = await tx.wait(1, chunk3SVPI4LS_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS);
1089
1250
  } catch (err) {
1090
1251
  if (!isWaitTimeout(err)) throw err;
1091
1252
  return { txHash: tx.hash, confirmation: "unconfirmed" };
@@ -1099,16 +1260,16 @@ var DelegateSweepApi = class {
1099
1260
  }
1100
1261
  options;
1101
1262
  async sweepDelegate() {
1102
- if (!this.options.delegateKey) throw new chunkJKUIE45B_cjs.HavenSigningError("delegateKey is required for sweepDelegate.");
1263
+ if (!this.options.delegateKey) throw new chunk3SVPI4LS_cjs.HavenSigningError("delegateKey is required for sweepDelegate.");
1103
1264
  const agent = await this.options.getAgent();
1104
- if (!agent.delegateAddress) throw new chunkJKUIE45B_cjs.HavenApiError("Agent has no delegate address.", 422);
1265
+ if (!agent.delegateAddress) throw new chunk3SVPI4LS_cjs.HavenApiError("Agent has no delegate address.", 422);
1105
1266
  const rpcUrl = this.options.chainRpcs[agent.chainId];
1106
- if (!rpcUrl) throw new chunkJKUIE45B_cjs.HavenApiError(`chainRpcs[${agent.chainId}] must be configured to sweep the delegate wallet.`, 422);
1267
+ if (!rpcUrl) throw new chunk3SVPI4LS_cjs.HavenApiError(`chainRpcs[${agent.chainId}] must be configured to sweep the delegate wallet.`, 422);
1107
1268
  const provider = createJsonRpcProvider(rpcUrl);
1108
1269
  const wallet = createWallet(this.options.delegateKey, provider);
1109
1270
  const transfers = [];
1110
- if (chunkQSSVOPWA_cjs.isSweepableChain(agent.chainId)) {
1111
- const contract = createErc20Contract(chunkQSSVOPWA_cjs.sweepUsdcAddress(agent.chainId), ["function balanceOf(address) view returns (uint256)", "function transfer(address to, uint256 amount) returns (bool)"], wallet);
1271
+ if (chunkJ6DQEBK2_cjs.isSweepableChain(agent.chainId)) {
1272
+ const contract = createErc20Contract(chunkJ6DQEBK2_cjs.sweepUsdcAddress(agent.chainId), ["function balanceOf(address) view returns (uint256)", "function transfer(address to, uint256 amount) returns (bool)"], wallet);
1112
1273
  const balance2 = await contract.balanceOf(agent.delegateAddress);
1113
1274
  if (balance2 > 0n) {
1114
1275
  const tx = await contract.transfer(agent.accountAddress, balance2);
@@ -1196,7 +1357,7 @@ function snapshotRequestBody(body) {
1196
1357
  if (body == null) return void 0;
1197
1358
  if (typeof body === "string") return body;
1198
1359
  if (body instanceof URLSearchParams) return body.toString();
1199
- throw new chunkJKUIE45B_cjs.HavenApiError(
1360
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1200
1361
  "Quote helpers can only capture resumable request bodies that are strings or URLSearchParams. For streams, blobs, or binary bodies, preserve the original request yourself and call the matching resume method with fresh init.",
1201
1362
  400
1202
1363
  );
@@ -1217,25 +1378,25 @@ function requestInitFromSnapshot(request) {
1217
1378
  };
1218
1379
  }
1219
1380
  function noCompatiblePaymentOptionError(accepts) {
1220
- const erc7710Only = chunkQSSVOPWA_cjs.selectErc7710PaymentOption(accepts) !== null;
1381
+ const erc7710Only = chunkJ6DQEBK2_cjs.selectErc7710PaymentOption(accepts) !== null;
1221
1382
  const unsupportedOnly = !erc7710Only && accepts.some(
1222
- (opt) => opt !== null && typeof opt === "object" && !chunkQSSVOPWA_cjs.isErc7710Option(opt) && (chunkQSSVOPWA_cjs.x402AssetTransferMethod(opt) !== null || opt.extra?.paymentFlow !== void 0)
1383
+ (opt) => opt !== null && typeof opt === "object" && !chunkJ6DQEBK2_cjs.isErc7710Option(opt) && (chunkJ6DQEBK2_cjs.x402AssetTransferMethod(opt) !== null || opt.extra?.paymentFlow !== void 0)
1223
1384
  );
1224
- return new chunkJKUIE45B_cjs.HavenApiError(
1385
+ return new chunk3SVPI4LS_cjs.HavenApiError(
1225
1386
  "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC." + (erc7710Only ? " The only Haven-compatible option this merchant advertises is tagged extra.assetTransferMethod: 'erc7710' (direct settlement), which this EIP-3009 payment path cannot settle \u2014 the limitation is the settlement scheme, not the asset. Paying this merchant requires a delegation-rail erc7710 flow (settleX402Erc7710, or the hosted MCP purchase tools)." : unsupportedOnly ? " Every option this merchant advertises asks for a transfer method or payment flow Haven cannot construct (for example extra.assetTransferMethod: 'permit2', or an unrecognized extra.paymentFlow). No payment intent was created and no funds moved." : ""),
1226
1387
  400
1227
1388
  );
1228
1389
  }
1229
1390
  function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport) {
1230
- const standard = chunkQSSVOPWA_cjs.selectStandardPaymentOption(paymentRequired.accepts);
1231
- const option = standard ?? chunkQSSVOPWA_cjs.selectErc7710PaymentOption(paymentRequired.accepts);
1391
+ const standard = chunkJ6DQEBK2_cjs.selectStandardPaymentOption(paymentRequired.accepts);
1392
+ const option = standard ?? chunkJ6DQEBK2_cjs.selectErc7710PaymentOption(paymentRequired.accepts);
1232
1393
  if (!option) {
1233
1394
  throw noCompatiblePaymentOptionError(paymentRequired.accepts);
1234
1395
  }
1235
- const token = chunkQSSVOPWA_cjs.resolveTokenFromAddress(option.asset, option.network);
1396
+ const token = chunkJ6DQEBK2_cjs.resolveTokenFromAddress(option.asset, option.network);
1236
1397
  return {
1237
1398
  rail: "x402",
1238
- idempotencyKey: idempotencyKey ?? chunkQSSVOPWA_cjs.buildX402IdempotencyKey(paymentRequired, option),
1399
+ idempotencyKey: idempotencyKey ?? chunkJ6DQEBK2_cjs.buildX402IdempotencyKey(paymentRequired, option),
1239
1400
  paymentRequired,
1240
1401
  accepted: option,
1241
1402
  acceptedScheme: standard ? "standard" : "erc7710",
@@ -1249,8 +1410,8 @@ function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport)
1249
1410
  resourceUrlDiffersFromRequest: paymentRequired.resource.url !== request.url,
1250
1411
  description: paymentRequired.resource.description ?? option.description ?? null,
1251
1412
  mimeType: paymentRequired.resource.mimeType ?? option.mimeType ?? null,
1252
- amountAtomic: chunkQSSVOPWA_cjs.x402AuthorizationAmount(option),
1253
- amount: decimalFromUsdcAtomic(chunkQSSVOPWA_cjs.x402AuthorizationAmount(option)),
1413
+ amountAtomic: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option),
1414
+ amount: decimalFromUsdcAtomic(chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option)),
1254
1415
  token: token?.symbol ?? "USDC",
1255
1416
  // #1351: null when the asset is unrecognised on this network — the
1256
1417
  // `token` fallback above is a LABEL, not evidence of 6 decimals, and a
@@ -1289,7 +1450,7 @@ function buildX402Receipt(input) {
1289
1450
  payTo: input.merchantTo ?? input.accepted.payTo
1290
1451
  },
1291
1452
  x402: {
1292
- amount: chunkQSSVOPWA_cjs.x402AuthorizationAmount(input.accepted),
1453
+ amount: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(input.accepted),
1293
1454
  token: input.token,
1294
1455
  network: input.accepted.network,
1295
1456
  asset: input.accepted.asset,
@@ -1298,7 +1459,7 @@ function buildX402Receipt(input) {
1298
1459
  };
1299
1460
  }
1300
1461
  function buildX402ResumeState(input) {
1301
- const token = chunkQSSVOPWA_cjs.resolveTokenFromAddress(input.accepted.asset, input.accepted.network);
1462
+ const token = chunkJ6DQEBK2_cjs.resolveTokenFromAddress(input.accepted.asset, input.accepted.network);
1302
1463
  return {
1303
1464
  rail: "x402",
1304
1465
  paymentId: input.paymentId,
@@ -1309,8 +1470,8 @@ function buildX402ResumeState(input) {
1309
1470
  request: input.request,
1310
1471
  resourceUrl: input.paymentRequired.resource.url,
1311
1472
  description: input.paymentRequired.resource.description ?? input.accepted.description ?? null,
1312
- amountAtomic: chunkQSSVOPWA_cjs.x402AuthorizationAmount(input.accepted),
1313
- amount: decimalFromUsdcAtomic(chunkQSSVOPWA_cjs.x402AuthorizationAmount(input.accepted)),
1473
+ amountAtomic: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(input.accepted),
1474
+ amount: decimalFromUsdcAtomic(chunkJ6DQEBK2_cjs.x402AuthorizationAmount(input.accepted)),
1314
1475
  token: token?.symbol ?? "USDC",
1315
1476
  asset: input.accepted.asset,
1316
1477
  network: input.accepted.network,
@@ -1319,7 +1480,7 @@ function buildX402ResumeState(input) {
1319
1480
  };
1320
1481
  }
1321
1482
  function attachX402ResumeState(err, paymentRequired, accepted, idempotencyKey, request) {
1322
- if (!(err instanceof chunkJKUIE45B_cjs.HavenPaymentStateError)) return;
1483
+ if (!(err instanceof chunk3SVPI4LS_cjs.HavenPaymentStateError)) return;
1323
1484
  if (err.state.rail !== "x402") return;
1324
1485
  err.resumeState = buildX402ResumeState({
1325
1486
  paymentId: err.state.paymentId,
@@ -1340,17 +1501,17 @@ function attachResumeState(err, input) {
1340
1501
  }
1341
1502
  function assertCanResumeX402(status, paymentRequired, option) {
1342
1503
  if (status.rail !== "x402") {
1343
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(
1504
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(
1344
1505
  `Payment ${status.paymentId} is ${status.rail}, not x402.`,
1345
1506
  409,
1346
1507
  status
1347
1508
  );
1348
1509
  }
1349
- if (status.nextAction !== chunkJKUIE45B_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
1350
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
1510
+ if (status.nextAction !== chunk3SVPI4LS_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
1511
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
1351
1512
  }
1352
1513
  if (!status.txHash) {
1353
- throw new chunkJKUIE45B_cjs.HavenApiError(
1514
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1354
1515
  `x402 payment ${status.paymentId} is ready to retry but has no Haven transaction hash.`,
1355
1516
  502,
1356
1517
  status,
@@ -1358,7 +1519,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
1358
1519
  );
1359
1520
  }
1360
1521
  if (status.resourceUrl && status.resourceUrl !== paymentRequired.resource.url) {
1361
- throw new chunkJKUIE45B_cjs.HavenApiError(
1522
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1362
1523
  "x402 resume request does not match the approved resource URL.",
1363
1524
  409,
1364
1525
  { status, paymentRequired },
@@ -1366,7 +1527,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
1366
1527
  );
1367
1528
  }
1368
1529
  if (status.merchantAddress && !sameAddress(status.merchantAddress, option.payTo)) {
1369
- throw new chunkJKUIE45B_cjs.HavenApiError(
1530
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1370
1531
  "x402 resume request does not match the approved merchant.",
1371
1532
  409,
1372
1533
  { status, selectedPayment: option },
@@ -1375,7 +1536,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
1375
1536
  }
1376
1537
  const optionChainId = chainIdFromNetwork(option.network);
1377
1538
  if (status.chainId && optionChainId && status.chainId !== optionChainId) {
1378
- throw new chunkJKUIE45B_cjs.HavenApiError(
1539
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1379
1540
  "x402 resume request does not match the approved network.",
1380
1541
  409,
1381
1542
  { status, selectedPayment: option },
@@ -1383,7 +1544,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
1383
1544
  );
1384
1545
  }
1385
1546
  if (status.token && status.token !== "USDC") {
1386
- throw new chunkJKUIE45B_cjs.HavenApiError(
1547
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1387
1548
  "x402 resume request does not match the approved token.",
1388
1549
  409,
1389
1550
  { status, selectedPayment: option },
@@ -1391,9 +1552,9 @@ function assertCanResumeX402(status, paymentRequired, option) {
1391
1552
  );
1392
1553
  }
1393
1554
  const approvedAmount = status.amount ? normalizeDecimal(status.amount) : "";
1394
- const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(chunkQSSVOPWA_cjs.x402AuthorizationAmount(option)));
1555
+ const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option)));
1395
1556
  if (approvedAmount && approvedAmount !== requestedAmount) {
1396
- throw new chunkJKUIE45B_cjs.HavenApiError(
1557
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1397
1558
  "x402 resume request does not match the approved amount.",
1398
1559
  409,
1399
1560
  { status, selectedPayment: option },
@@ -1408,6 +1569,10 @@ function readX402ReceiptPayer(raw) {
1408
1569
  }
1409
1570
 
1410
1571
  // src/x402-funding-leg.ts
1572
+ function sameX402TaskBudget(a, b) {
1573
+ if (a === void 0 || b === void 0) return a === b;
1574
+ return a.toLowerCase() === b.toLowerCase();
1575
+ }
1411
1576
  var X402FundingLeg = class {
1412
1577
  delegateKey;
1413
1578
  delegateAddress;
@@ -1433,25 +1598,40 @@ var X402FundingLeg = class {
1433
1598
  this.assertSignableAuthorizationState = options.assertSignableAuthorizationState;
1434
1599
  }
1435
1600
  // ── Receipt cache ────────────────────────────────────────────────
1436
- /** A still-valid cached receipt for this key, or undefined. */
1437
- cachedReceipt(idempotencyKey) {
1601
+ /**
1602
+ * #3392: each cached receipt records the authorizing budget id(s) it was
1603
+ * created under (absent when none) — `taskBudgetId` since #3329, and since
1604
+ * #3330 `subBudgetId` (agent B's grant). A call naming a DIFFERENT
1605
+ * combination is refused here — before any network call — instead of
1606
+ * silently returning a receipt paid under another budget. Absent-vs-absent
1607
+ * and equal ids (case-insensitive) hit as before.
1608
+ */
1609
+ cachedReceipt(idempotencyKey, taskBudgetId, subBudgetId) {
1438
1610
  const cached = this.receiptCache.get(idempotencyKey);
1439
- if (cached && cached.expiresAt > Date.now()) return cached.receipt;
1440
- return void 0;
1611
+ if (!cached || cached.expiresAt <= Date.now()) return void 0;
1612
+ if (!sameX402TaskBudget(cached.taskBudgetId, taskBudgetId) || !sameX402TaskBudget(cached.subBudgetId, subBudgetId)) {
1613
+ throw new chunk3SVPI4LS_cjs.X402TaskBudgetMismatchError(
1614
+ `The x402 idempotency key '${idempotencyKey}' was already used under a different authorizing budget (task '${cached.taskBudgetId ?? "none"}' vs '${taskBudgetId ?? "none"}', sub '${cached.subBudgetId ?? "none"}' vs '${subBudgetId ?? "none"}'). Pass a new idempotencyKey to pay under this budget.`,
1615
+ idempotencyKey,
1616
+ cached.taskBudgetId,
1617
+ taskBudgetId
1618
+ );
1619
+ }
1620
+ return cached.receipt;
1441
1621
  }
1442
- cacheReceipt(idempotencyKey, paymentHeader, receipt) {
1622
+ cacheReceipt(idempotencyKey, paymentHeader, receipt, taskBudgetId, subBudgetId) {
1443
1623
  const expiresAt = getPaymentHeaderValidBefore(paymentHeader);
1444
1624
  if (expiresAt > Date.now()) {
1445
- this.receiptCache.set(idempotencyKey, { expiresAt, receipt });
1625
+ this.receiptCache.set(idempotencyKey, { expiresAt, taskBudgetId, subBudgetId, receipt });
1446
1626
  }
1447
1627
  }
1448
1628
  // ── Authorization ────────────────────────────────────────────────
1449
- async authorize(paymentRequired, option, idempotencyKey) {
1629
+ async authorize(paymentRequired, option, idempotencyKey, taskBudgetId, subBudgetId) {
1450
1630
  const raw = await this.post("/x402", {
1451
1631
  url: paymentRequired.resource.url,
1452
1632
  payTo: this.delegateAddress,
1453
1633
  merchantPayTo: option.payTo,
1454
- amount: chunkQSSVOPWA_cjs.x402AuthorizationAmount(option),
1634
+ amount: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option),
1455
1635
  asset: option.asset,
1456
1636
  network: option.network,
1457
1637
  description: paymentRequired.resource.description,
@@ -1459,20 +1639,28 @@ var X402FundingLeg = class {
1459
1639
  // #1360: same explicit funding-leg declaration as createX402Intent —
1460
1640
  // this local-key path derives payTo from the key (never stale), but the
1461
1641
  // declaration keeps both writers of the 3009 shape loud-by-default.
1462
- settlementScheme: "eip3009"
1642
+ settlementScheme: "eip3009",
1643
+ // #3329: `/x402` bodies are camelCase (`X402AuthorizeRequest`) — do not
1644
+ // switch this to `task_budget_id`, which is only the `POST /payments` key.
1645
+ ...taskBudgetId ? { taskBudgetId } : {},
1646
+ // #3330: same camelCase channel one level deeper — agent B pays through
1647
+ // the sub-budget agent A granted it (`[funding, B grant, A parent-child,
1648
+ // A budget]`). Mutually exclusive with `taskBudgetId` server-side; the
1649
+ // backend refuses a body naming both.
1650
+ ...subBudgetId ? { subBudgetId } : {}
1463
1651
  });
1464
1652
  const state = paymentStateFromRaw("x402 payment", raw);
1465
- const executedReplay = raw.success && raw.tx_hash ? "idempotency-collision" : state?.nextAction === chunkJKUIE45B_cjs.AgentPaymentNextAction.RetryOriginalX402Request ? "approval-resume" : null;
1653
+ const executedReplay = raw.success && raw.tx_hash ? "idempotency-collision" : state?.nextAction === chunk3SVPI4LS_cjs.AgentPaymentNextAction.RetryOriginalX402Request ? "approval-resume" : null;
1466
1654
  if (executedReplay) {
1467
1655
  const canFund = await this.delegateCanFund(
1468
1656
  raw.chain_id ?? state?.chainId ?? chainIdFromNetwork(option.network),
1469
1657
  option.asset,
1470
- chunkQSSVOPWA_cjs.x402AuthorizationAmount(option)
1658
+ chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option)
1471
1659
  );
1472
1660
  const refuse = executedReplay === "idempotency-collision" ? canFund !== true : canFund === false;
1473
1661
  if (refuse) {
1474
1662
  const settledReceipt = state && executedReplay === "approval-resume" ? this.receiptFromStatus(paymentRequired, option, void 0, state) : this.receiptFromAuthorization(paymentRequired, option, void 0, raw);
1475
- throw new chunkJKUIE45B_cjs.X402AlreadySettledError(
1663
+ throw new chunk3SVPI4LS_cjs.X402AlreadySettledError(
1476
1664
  canFund === false ? "This x402 payment already settled \u2014 the delegate no longer holds the funds to authorize it again. To buy the same item a second time, pass a distinct `idempotencyKey`; the synthesised key intentionally collapses repeat calls for the same product within a 5-minute window so a retried request cannot pay twice." : "This x402 payment already settled, and whether the delegate can still fund a new authorization could not be verified (no `chainRpcs` entry for this chain). Refusing rather than issue an authorization that may be unfundable. To buy the same item a second time, pass a distinct `idempotencyKey`; to finish an interrupted payment, resume it by `paymentId`.",
1477
1665
  settledReceipt,
1478
1666
  canFund === false ? "settled" : "unverifiable"
@@ -1482,19 +1670,22 @@ var X402FundingLeg = class {
1482
1670
  const paymentHeader = await this.createPaymentHeader(paymentRequired, option);
1483
1671
  if (raw.success && raw.tx_hash) {
1484
1672
  const receipt2 = this.receiptFromAuthorization(paymentRequired, option, paymentHeader, raw);
1485
- this.cacheReceipt(idempotencyKey, paymentHeader, receipt2);
1673
+ this.cacheReceipt(idempotencyKey, paymentHeader, receipt2, taskBudgetId, subBudgetId);
1486
1674
  return receipt2;
1487
1675
  }
1488
- if (state?.nextAction === chunkJKUIE45B_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
1676
+ if (state?.nextAction === chunk3SVPI4LS_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
1489
1677
  const receipt2 = this.receiptFromStatus(paymentRequired, option, paymentHeader, state);
1490
- this.cacheReceipt(idempotencyKey, paymentHeader, receipt2);
1678
+ this.cacheReceipt(idempotencyKey, paymentHeader, receipt2, taskBudgetId, subBudgetId);
1491
1679
  return receipt2;
1492
1680
  }
1493
1681
  this.assertSignableAuthorizationState("x402 payment", raw);
1494
1682
  if (!raw.sign_data?.hash) {
1495
- throw new chunkJKUIE45B_cjs.HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
1683
+ throw new chunk3SVPI4LS_cjs.HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
1496
1684
  }
1497
- const sig = await this.signForData(raw.sign_data);
1685
+ const sig = await this.signForData(raw.sign_data, {
1686
+ asset: option.asset,
1687
+ amount: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option)
1688
+ });
1498
1689
  const execResult = await this.post(
1499
1690
  `/payments/${raw.payment_id}/sign`,
1500
1691
  { signature: sig }
@@ -1507,31 +1698,31 @@ var X402FundingLeg = class {
1507
1698
  execResult.chain_id ?? chainIdFromNetwork(option.network)
1508
1699
  );
1509
1700
  const receipt = this.receiptFromAuthorization(paymentRequired, option, paymentHeader, raw, execResult);
1510
- this.cacheReceipt(idempotencyKey, paymentHeader, receipt);
1701
+ this.cacheReceipt(idempotencyKey, paymentHeader, receipt, taskBudgetId, subBudgetId);
1511
1702
  return receipt;
1512
1703
  }
1513
1704
  // ── Header minting ───────────────────────────────────────────────
1514
1705
  async createPaymentHeader(paymentRequired, option) {
1515
1706
  if (!this.delegateKey) {
1516
- throw new chunkJKUIE45B_cjs.HavenSigningError("delegateKey is required to sign x402 payment headers.");
1707
+ throw new chunk3SVPI4LS_cjs.HavenSigningError("delegateKey is required to sign x402 payment headers.");
1517
1708
  }
1518
1709
  const account = accounts.privateKeyToAccount(this.delegateKey);
1519
- const requirements = chunkQSSVOPWA_cjs.toStandardPaymentRequirements(paymentRequired, option);
1710
+ const requirements = chunkJ6DQEBK2_cjs.toStandardPaymentRequirements(paymentRequired, option);
1520
1711
  const header = await schemes.exact.evm.createPaymentHeader(
1521
1712
  account,
1522
1713
  paymentRequired.x402Version,
1523
1714
  requirements
1524
1715
  );
1525
1716
  if (paymentRequired.x402Version < 2) return header;
1526
- const payment = chunkQSSVOPWA_cjs.decodeBase64Json(header);
1527
- return chunkQSSVOPWA_cjs.encodeBase64Json(chunkQSSVOPWA_cjs.x402V2PaymentEnvelope(paymentRequired, option, payment.payload));
1717
+ const payment = chunkJ6DQEBK2_cjs.decodeBase64Json(header);
1718
+ return chunkJ6DQEBK2_cjs.encodeBase64Json(chunkJ6DQEBK2_cjs.x402V2PaymentEnvelope(paymentRequired, option, payment.payload));
1528
1719
  }
1529
1720
  // ── Receipt mapping ──────────────────────────────────────────────
1530
1721
  receiptFromAuthorization(paymentRequired, option, paymentHeader, raw, execResult) {
1531
1722
  const txHash = execResult?.tx_hash ?? raw.tx_hash ?? "";
1532
1723
  const chainId = execResult?.chain_id ?? raw.chain_id ?? chainIdFromNetwork(option.network);
1533
1724
  const token = execResult?.token ?? raw.token ?? "USDC";
1534
- const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(chunkQSSVOPWA_cjs.x402AuthorizationAmount(option));
1725
+ const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option));
1535
1726
  const to = execResult?.to ?? raw.to ?? this.delegateAddress ?? "";
1536
1727
  const explorerUrl = execResult?.explorer_url ?? raw.explorer_url ?? explorerUrlOrEmpty(chainId, txHash);
1537
1728
  const merchantTo = execResult?.merchant_to ?? raw.merchant_to ?? option.payTo;
@@ -1553,7 +1744,7 @@ var X402FundingLeg = class {
1553
1744
  }
1554
1745
  receiptFromStatus(paymentRequired, option, paymentHeader, status) {
1555
1746
  if (!status.txHash) {
1556
- throw new chunkJKUIE45B_cjs.HavenApiError(
1747
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1557
1748
  `x402 payment ${status.paymentId} is ready to retry but has no Haven transaction hash.`,
1558
1749
  502,
1559
1750
  status,
@@ -1564,7 +1755,7 @@ var X402FundingLeg = class {
1564
1755
  paymentId: status.paymentId,
1565
1756
  txHash: status.txHash,
1566
1757
  token: status.token || "USDC",
1567
- amount: status.amount || decimalFromUsdcAtomic(chunkQSSVOPWA_cjs.x402AuthorizationAmount(option)),
1758
+ amount: status.amount || decimalFromUsdcAtomic(chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option)),
1568
1759
  to: this.delegateAddress ?? "",
1569
1760
  resourceUrl: paymentRequired.resource.url,
1570
1761
  explorerUrl: explorerUrlOrEmpty(status.chainId, status.txHash),
@@ -1592,7 +1783,7 @@ var X402FundingLeg = class {
1592
1783
  const provider = createJsonRpcProvider(rpcUrl);
1593
1784
  const onChainReceipt = await provider.waitForTransaction(txHash, 1, timeoutMs);
1594
1785
  if (!onChainReceipt || onChainReceipt.status !== 1) {
1595
- throw new chunkJKUIE45B_cjs.HavenApiError(
1786
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1596
1787
  "Funding tx did not confirm on-chain within the timeout window.",
1597
1788
  500,
1598
1789
  { txHash, chainId }
@@ -1641,7 +1832,7 @@ var X402FundingLeg = class {
1641
1832
  };
1642
1833
  function getPaymentHeaderValidBefore(paymentHeader) {
1643
1834
  try {
1644
- const payment = chunkQSSVOPWA_cjs.decodeBase64Json(
1835
+ const payment = chunkJ6DQEBK2_cjs.decodeBase64Json(
1645
1836
  paymentHeader
1646
1837
  );
1647
1838
  const payload = payment.payload;
@@ -1696,7 +1887,7 @@ var X402Erc7710 = class {
1696
1887
  */
1697
1888
  async settle(paymentRequired, options = {}) {
1698
1889
  if (!this.delegateKey) {
1699
- throw new chunkJKUIE45B_cjs.HavenSigningError(
1890
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
1700
1891
  "delegateKey is required for x402 payments. Pass it in the HavenClient config."
1701
1892
  );
1702
1893
  }
@@ -1721,21 +1912,21 @@ var X402Erc7710 = class {
1721
1912
  async prepare(paymentRequired, options = {}) {
1722
1913
  const delegationRail = options.delegationRail ?? (await this.getAgent()).executionRail === "delegation";
1723
1914
  if (!delegationRail) {
1724
- throw new chunkJKUIE45B_cjs.HavenApiError(
1915
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1725
1916
  "erc7710 settlement requires a delegation-rail account; this one is not on it. Use authorizeX402() for the standard EIP-3009 path.",
1726
1917
  400
1727
1918
  );
1728
1919
  }
1729
- const selection = chunkQSSVOPWA_cjs.selectX402SettlementScheme(paymentRequired.accepts, { delegationRail });
1920
+ const selection = chunkJ6DQEBK2_cjs.selectX402SettlementScheme(paymentRequired.accepts, { delegationRail });
1730
1921
  if (!selection || selection.scheme !== "erc7710") {
1731
- throw new chunkJKUIE45B_cjs.HavenApiError(
1922
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1732
1923
  "This merchant does not advertise an erc7710 settlement option (no accepts[] entry carries extra.assetTransferMethod: 'erc7710'). Use authorizeX402() for the standard EIP-3009 path.",
1733
1924
  400
1734
1925
  );
1735
1926
  }
1736
1927
  const option = selection.option;
1737
1928
  const merchantPayTo = option.payTo;
1738
- const amountAtomic = chunkQSSVOPWA_cjs.x402AuthorizationAmount(option);
1929
+ const amountAtomic = chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option);
1739
1930
  const raw = await this.post("/x402", {
1740
1931
  url: options.resourceUrl ?? paymentRequired.resource?.url,
1741
1932
  // #2373: the full 402 challenge, persisted verbatim by the backend
@@ -1770,14 +1961,33 @@ var X402Erc7710 = class {
1770
1961
  ...selection.facilitatorAddresses ? { facilitatorAddresses: selection.facilitatorAddresses } : {},
1771
1962
  // #1307/#1547: persisted so the settle leg can rehydrate the merchant
1772
1963
  // call by payment_id on this scheme too, not only on the 3009 bridge.
1773
- ...options.mcpCallContext ? { mcpCallContext: options.mcpCallContext } : {}
1964
+ ...options.mcpCallContext ? { mcpCallContext: options.mcpCallContext } : {},
1965
+ // #3329: `/x402` bodies are camelCase (`X402AuthorizeRequest`) — do not
1966
+ // switch this to `task_budget_id`, which is only the `POST /payments` key.
1967
+ ...options.taskBudgetId ? { taskBudgetId: options.taskBudgetId } : {},
1968
+ // #3330: same camelCase channel one level deeper; mutually exclusive
1969
+ // with `taskBudgetId` server-side.
1970
+ ...options.subBudgetId ? { subBudgetId: options.subBudgetId } : {}
1774
1971
  });
1775
1972
  if (!raw.payment_id) {
1776
- throw new chunkJKUIE45B_cjs.HavenApiError("No payment_id returned from x402/authorize", 500, raw);
1973
+ throw new chunk3SVPI4LS_cjs.HavenApiError("No payment_id returned from x402/authorize", 500, raw);
1974
+ }
1975
+ if (raw.status === "confirmed" && raw.tx_hash) {
1976
+ const requestedUrl = options.resourceUrl ?? paymentRequired.resource?.url;
1977
+ const samePurchase = typeof raw.to === "string" && raw.to.toLowerCase() === merchantPayTo.toLowerCase() && raw.resource_url === requestedUrl;
1978
+ if (!samePurchase) {
1979
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1980
+ `Idempotency key already belongs to confirmed payment ${raw.payment_id}, which is not this erc7710 purchase (different payee or resource). Nothing was signed and nothing was charged. Check that payment's status before buying again: a funded but undelivered EIP-3009 payment is recovered, not paid twice. Otherwise use a new idempotency key for this purchase.`,
1981
+ 409,
1982
+ raw,
1983
+ raw.payment_id
1984
+ );
1985
+ }
1986
+ throw new chunk3SVPI4LS_cjs.X402Erc7710AlreadySettledError(raw.payment_id, raw.tx_hash, raw);
1777
1987
  }
1778
1988
  const signData = raw.sign_data;
1779
1989
  if (signData?.signature_scheme !== "eip712_delegation" || !signData.typed_data) {
1780
- throw new chunkJKUIE45B_cjs.HavenApiError(
1990
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1781
1991
  `x402/authorize did not return an erc7710 settlement child (signature_scheme was ${JSON.stringify(signData?.signature_scheme)}). Refusing to sign a payload this path did not ask for.`,
1782
1992
  500,
1783
1993
  raw
@@ -1805,12 +2015,22 @@ var X402Erc7710 = class {
1805
2015
  * hosted boundary) is irrelevant here.
1806
2016
  */
1807
2017
  async submit(paymentId, signature) {
1808
- const settled = await this.post(
1809
- `/x402/${paymentId}/settle`,
1810
- { signature }
1811
- );
2018
+ let settled;
2019
+ try {
2020
+ settled = await this.post(`/x402/${paymentId}/settle`, { signature });
2021
+ } catch (err) {
2022
+ const body = err instanceof chunk3SVPI4LS_cjs.HavenApiError ? err.body : void 0;
2023
+ if (err instanceof chunk3SVPI4LS_cjs.HavenApiError && err.statusCode === 409 && body?.code === "payment_already_settled" && typeof body.tx_hash === "string") {
2024
+ throw new chunk3SVPI4LS_cjs.X402Erc7710AlreadySettledError(
2025
+ typeof body.payment_id === "string" ? body.payment_id : paymentId,
2026
+ body.tx_hash,
2027
+ body
2028
+ );
2029
+ }
2030
+ throw err;
2031
+ }
1812
2032
  if (!settled.payment_header) {
1813
- throw new chunkJKUIE45B_cjs.HavenApiError(
2033
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1814
2034
  "x402 settle returned no payment_header \u2014 the merchant cannot be retried.",
1815
2035
  500,
1816
2036
  settled
@@ -1820,9 +2040,9 @@ var X402Erc7710 = class {
1820
2040
  }
1821
2041
  };
1822
2042
  function settlementExpectationFromQuote(settlement) {
1823
- const chainId = chunkJKUIE45B_cjs.chainIdForNetwork(settlement.network);
2043
+ const chainId = chunk3SVPI4LS_cjs.chainIdForNetwork(settlement.network);
1824
2044
  if (chainId === void 0) {
1825
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2045
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
1826
2046
  `Refusing to sign the x402 settlement child: the merchant's network ${JSON.stringify(settlement.network)} is not one this SDK can verify a settlement child on.`
1827
2047
  );
1828
2048
  }
@@ -1872,7 +2092,7 @@ function x402ToolReceipt(receipt) {
1872
2092
  };
1873
2093
  }
1874
2094
  function toolError(err) {
1875
- if (err instanceof chunkJKUIE45B_cjs.HavenPaymentStateError) {
2095
+ if (err instanceof chunk3SVPI4LS_cjs.HavenPaymentStateError) {
1876
2096
  return {
1877
2097
  success: false,
1878
2098
  payment_id: err.state.paymentId,
@@ -1917,7 +2137,7 @@ function toolError(err) {
1917
2137
  error: err.message
1918
2138
  };
1919
2139
  }
1920
- if (err instanceof chunkJKUIE45B_cjs.HavenApiError) {
2140
+ if (err instanceof chunk3SVPI4LS_cjs.HavenApiError) {
1921
2141
  return {
1922
2142
  success: false,
1923
2143
  status_code: err.statusCode,
@@ -1954,10 +2174,10 @@ var MerchantCompletion = class {
1954
2174
  }
1955
2175
  async retryRequest(url, initialInit, paymentRequired, receipt) {
1956
2176
  if (!receipt.accepted) {
1957
- throw new chunkJKUIE45B_cjs.HavenApiError("No accepted x402 option was recorded for payment retry", 500);
2177
+ throw new chunk3SVPI4LS_cjs.HavenApiError("No accepted x402 option was recorded for payment retry", 500);
1958
2178
  }
1959
2179
  if (!receipt.paymentHeader) {
1960
- throw new chunkJKUIE45B_cjs.HavenApiError("No x402 payment header was returned for payment retry", 500);
2180
+ throw new chunk3SVPI4LS_cjs.HavenApiError("No x402 payment header was returned for payment retry", 500);
1961
2181
  }
1962
2182
  const retryResponse = await this.merchantTransport.deliverPaymentRecoveringSession(
1963
2183
  url,
@@ -1982,7 +2202,7 @@ var MerchantCompletion = class {
1982
2202
  delegate_to: receipt.to
1983
2203
  }
1984
2204
  });
1985
- throw new chunkJKUIE45B_cjs.HavenApiError(
2205
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
1986
2206
  "x402 retry failed after Haven funded the delegate wallet; reconciliation may be required.",
1987
2207
  inBandRejection ? X402_RETRY_REJECTED_STATUS : merchant.merchant_status,
1988
2208
  {
@@ -2015,7 +2235,7 @@ var MerchantCompletion = class {
2015
2235
  merchantStatus: retryResponse.status,
2016
2236
  challengePayload: paymentRequired,
2017
2237
  selectedPayment: receipt.accepted,
2018
- paymentProofHeaderName: chunkQSSVOPWA_cjs.x402PaymentHeaderNamesSent(receipt.paymentHeader),
2238
+ paymentProofHeaderName: chunkJ6DQEBK2_cjs.x402PaymentHeaderNamesSent(receipt.paymentHeader),
2019
2239
  paymentProofHeader: receipt.paymentHeader,
2020
2240
  protocolReceiptHeaderName,
2021
2241
  protocolReceiptHeader
@@ -2056,18 +2276,18 @@ var MerchantCompletion = class {
2056
2276
  async resolveCompletionContext(input) {
2057
2277
  const status = await this.getPaymentStatus(input.paymentId);
2058
2278
  if (status.rail !== "x402") {
2059
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(
2279
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(
2060
2280
  `Payment ${status.paymentId} is ${status.rail}, not x402.`,
2061
2281
  409,
2062
2282
  status
2063
2283
  );
2064
2284
  }
2065
- const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction === chunkJKUIE45B_cjs.AgentPaymentNextAction.RetryOriginalX402Request || status.kind === "payment_intent" && status.status === "confirmed" && status.phase === chunkJKUIE45B_cjs.AgentPaymentPhase.PaymentConfirmed && status.nextAction === chunkJKUIE45B_cjs.AgentPaymentNextAction.None;
2285
+ const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction === chunk3SVPI4LS_cjs.AgentPaymentNextAction.RetryOriginalX402Request || status.kind === "payment_intent" && status.status === "confirmed" && status.phase === chunk3SVPI4LS_cjs.AgentPaymentPhase.PaymentConfirmed && status.nextAction === chunk3SVPI4LS_cjs.AgentPaymentNextAction.None;
2066
2286
  if (!readyForMerchantCompletion) {
2067
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
2287
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
2068
2288
  }
2069
2289
  if (!input.noFundingLeg && !status.txHash) {
2070
- throw new chunkJKUIE45B_cjs.HavenApiError(
2290
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
2071
2291
  `x402 payment ${status.paymentId} is ready for merchant completion but has no Haven transaction hash.`,
2072
2292
  502,
2073
2293
  status,
@@ -2076,7 +2296,7 @@ var MerchantCompletion = class {
2076
2296
  }
2077
2297
  const approvedResourceUrl = status.resourceUrl ?? status.x402?.resourceUrl ?? null;
2078
2298
  if (approvedResourceUrl && approvedResourceUrl !== input.url) {
2079
- throw new chunkJKUIE45B_cjs.HavenApiError(
2299
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
2080
2300
  "x402 merchant completion does not match the approved resource URL.",
2081
2301
  409,
2082
2302
  { status, url: input.url },
@@ -2162,7 +2382,7 @@ var MerchantCompletion = class {
2162
2382
  */
2163
2383
  async reportMerchantOutcome(input) {
2164
2384
  if (!Number.isInteger(input.merchantStatus) || input.merchantStatus < 100 || input.merchantStatus > 599) {
2165
- throw new chunkJKUIE45B_cjs.HavenApiError(
2385
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
2166
2386
  `merchant_status must be an integer HTTP status from 100 to 599 (received ${input.merchantStatus}).`,
2167
2387
  400,
2168
2388
  void 0,
@@ -2171,7 +2391,7 @@ var MerchantCompletion = class {
2171
2391
  }
2172
2392
  const looksAccepted = input.merchantStatus >= 200 && input.merchantStatus < 300;
2173
2393
  if (looksAccepted !== (input.outcome === "accepted")) {
2174
- throw new chunkJKUIE45B_cjs.HavenApiError(
2394
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
2175
2395
  `outcome "${input.outcome}" contradicts merchant_status ${input.merchantStatus}: report "accepted" only for a 2xx and "rejected" only for a non-2xx.`,
2176
2396
  400,
2177
2397
  void 0,
@@ -2180,14 +2400,14 @@ var MerchantCompletion = class {
2180
2400
  }
2181
2401
  const status = await this.getPaymentStatus(input.paymentId);
2182
2402
  if (status.rail !== "x402") {
2183
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(
2403
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(
2184
2404
  `Payment ${status.paymentId} is ${status.rail}, not x402 \u2014 there is no merchant retry to report.`,
2185
2405
  409,
2186
2406
  status
2187
2407
  );
2188
2408
  }
2189
2409
  if (status.status !== "confirmed" || !status.txHash) {
2190
- throw new chunkJKUIE45B_cjs.HavenPaymentStateError(
2410
+ throw new chunk3SVPI4LS_cjs.HavenPaymentStateError(
2191
2411
  `Payment ${status.paymentId} has no confirmed Haven funding transaction to anchor a merchant report to (status ${status.status}). ${status.message}`,
2192
2412
  paymentStateStatusCode(status.status, 409),
2193
2413
  status
@@ -2195,7 +2415,7 @@ var MerchantCompletion = class {
2195
2415
  }
2196
2416
  const resourceUrl = status.resourceUrl ?? status.x402?.resourceUrl ?? null;
2197
2417
  if (!resourceUrl) {
2198
- throw new chunkJKUIE45B_cjs.HavenApiError(
2418
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
2199
2419
  `Payment ${status.paymentId} has no recorded resource URL, so a merchant report cannot be stored.`,
2200
2420
  409,
2201
2421
  status,
@@ -2248,7 +2468,7 @@ var MerchantCompletion = class {
2248
2468
  await this.post("/machine-payments/evidence", body);
2249
2469
  return { outcome: "confirmed" };
2250
2470
  } catch (err) {
2251
- const statusCode = err instanceof chunkJKUIE45B_cjs.HavenApiError ? err.statusCode : void 0;
2471
+ const statusCode = err instanceof chunk3SVPI4LS_cjs.HavenApiError ? err.statusCode : void 0;
2252
2472
  const retryable = statusCode === EVIDENCE_RETRYABLE_STATUS;
2253
2473
  if (!retryable) {
2254
2474
  return { outcome: "refused", statusCode: statusCode ?? 0 };
@@ -2285,7 +2505,7 @@ var MerchantCompletion = class {
2285
2505
  */
2286
2506
  async reportSettlementEvidence(paymentId, settlementTxHash) {
2287
2507
  if (isZeroSettlementTxHash(settlementTxHash)) {
2288
- throw new chunkJKUIE45B_cjs.HavenZeroSettlementHashError(paymentId);
2508
+ throw new chunk3SVPI4LS_cjs.HavenZeroSettlementHashError(paymentId);
2289
2509
  }
2290
2510
  return this.reportEvidence({
2291
2511
  paymentId,
@@ -2305,7 +2525,7 @@ function parseMerchantSettlement(header) {
2305
2525
  }
2306
2526
  function parseProtocolReceiptHeader(value) {
2307
2527
  try {
2308
- return chunkQSSVOPWA_cjs.decodeBase64Json(value);
2528
+ return chunkJ6DQEBK2_cjs.decodeBase64Json(value);
2309
2529
  } catch {
2310
2530
  try {
2311
2531
  return JSON.parse(value);
@@ -2322,7 +2542,7 @@ function x402TypedDataDigest(typedData) {
2322
2542
  try {
2323
2543
  return viem.hashTypedData(typedData);
2324
2544
  } catch (err) {
2325
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2545
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2326
2546
  `The x402 funding intent carried a sign_data.typed_data that is not a valid EIP-712 payload (needs domain, types, primaryType, message), so its digest cannot be derived and no signer could accept it. Underlying error: ${err instanceof Error ? err.message : String(err)}`
2327
2547
  );
2328
2548
  }
@@ -2371,6 +2591,15 @@ var HavenClient = class {
2371
2591
  pollingInterval;
2372
2592
  chainRpcs;
2373
2593
  inFlightX402 = /* @__PURE__ */ new Map();
2594
+ /**
2595
+ * #3392: the task budget each in-flight x402 entry was created under
2596
+ * (`undefined` = none). A call joining an in-flight entry under a
2597
+ * different budget is refused before any network call — never silently
2598
+ * charged to another budget's payment.
2599
+ */
2600
+ inFlightX402TaskBudget = /* @__PURE__ */ new Map();
2601
+ /** #3330: the sub-budget each in-flight entry was created under, same pin as `inFlightX402TaskBudget`. */
2602
+ inFlightX402SubBudget = /* @__PURE__ */ new Map();
2374
2603
  /**
2375
2604
  * The EIP-3009 funding-leg lifecycle (#1618). The facade holds a reference
2376
2605
  * and delegates; it does not reimplement any of it.
@@ -2404,7 +2633,7 @@ var HavenClient = class {
2404
2633
  });
2405
2634
  this.x402Wallet = config.x402Wallet;
2406
2635
  this.merchantTransport = new McpMerchantTransport({ merchantTimeout: config.merchantTimeout });
2407
- this.confirmationTimeout = config.confirmationTimeout ?? chunkJKUIE45B_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS;
2636
+ this.confirmationTimeout = config.confirmationTimeout ?? chunk3SVPI4LS_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS;
2408
2637
  this.pollingInterval = config.pollingInterval ?? DEFAULT_POLLING_INTERVAL;
2409
2638
  this.chainRpcs = config.chainRpcs ?? {};
2410
2639
  if (this.delegateKey) {
@@ -2416,7 +2645,7 @@ var HavenClient = class {
2416
2645
  x402Wallet: this.x402Wallet,
2417
2646
  chainRpcs: this.chainRpcs,
2418
2647
  post: (path, body) => this.post(path, body),
2419
- signForData: (signData) => this.signForData(signData),
2648
+ signForData: (signData, fundingExpectation) => this.signForData(signData, void 0, fundingExpectation),
2420
2649
  assertSignableAuthorizationState: (label, raw) => this.throwIfNonSignableAuthorizationState(label, raw)
2421
2650
  });
2422
2651
  this.merchantCompletion = new MerchantCompletion({
@@ -2473,7 +2702,7 @@ var HavenClient = class {
2473
2702
  */
2474
2703
  async pay(request) {
2475
2704
  if (!this.delegateKey) {
2476
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2705
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2477
2706
  "Cannot use pay() without a delegateKey. Use createIntent() + submitSignature() for manual signing."
2478
2707
  );
2479
2708
  }
@@ -2493,7 +2722,11 @@ var HavenClient = class {
2493
2722
  token: request.token,
2494
2723
  amount: request.amount,
2495
2724
  to: request.to,
2496
- ...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {}
2725
+ ...request.idempotencyKey ? { idempotency_key: request.idempotencyKey } : {},
2726
+ ...request.taskBudgetId ? { task_budget_id: request.taskBudgetId } : {},
2727
+ // #3330: `POST /payments` is snake_case — agent B pays through the
2728
+ // sub-budget A granted it; the backend refuses a body naming both ids.
2729
+ ...request.subBudgetId ? { sub_budget_id: request.subBudgetId } : {}
2497
2730
  });
2498
2731
  if (raw.status === "pending_approval") {
2499
2732
  throwPaymentStateError("Payment", raw);
@@ -2522,15 +2755,15 @@ var HavenClient = class {
2522
2755
  * on-chain allowance — there is nothing to sign until the user approves.
2523
2756
  */
2524
2757
  async createX402Intent(paymentRequired, options = {}) {
2525
- const option = chunkQSSVOPWA_cjs.selectStandardPaymentOption(paymentRequired.accepts);
2758
+ const option = chunkJ6DQEBK2_cjs.selectStandardPaymentOption(paymentRequired.accepts);
2526
2759
  if (!option) {
2527
2760
  throw noCompatiblePaymentOptionError(paymentRequired.accepts);
2528
2761
  }
2529
2762
  const fundingTo = options.delegateAddress ?? (await this.getAgent()).delegateAddress;
2530
2763
  if (!fundingTo) {
2531
- throw new chunkJKUIE45B_cjs.HavenApiError("Authenticated agent has no delegate address registered.", 502);
2764
+ throw new chunk3SVPI4LS_cjs.HavenApiError("Authenticated agent has no delegate address registered.", 502);
2532
2765
  }
2533
- const idempotencyKey = options.idempotencyKey ?? chunkQSSVOPWA_cjs.buildX402IdempotencyKey(paymentRequired, option);
2766
+ const idempotencyKey = options.idempotencyKey ?? chunkJ6DQEBK2_cjs.buildX402IdempotencyKey(paymentRequired, option);
2534
2767
  const raw = await this.post("/x402", {
2535
2768
  url: paymentRequired.resource.url,
2536
2769
  payTo: fundingTo,
@@ -2541,7 +2774,7 @@ var HavenClient = class {
2541
2774
  // of a silent reroute to the erc7710 settlement branch (the #1358
2542
2775
  // review's open-budget misroute). Legacy-rail backends ignore the field.
2543
2776
  settlementScheme: "eip3009",
2544
- amount: chunkQSSVOPWA_cjs.x402AuthorizationAmount(option),
2777
+ amount: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option),
2545
2778
  asset: option.asset,
2546
2779
  network: option.network,
2547
2780
  description: paymentRequired.resource.description,
@@ -2553,21 +2786,28 @@ var HavenClient = class {
2553
2786
  // the agent passes only payment_id. Bounded: the backend rejects >64KB,
2554
2787
  // so an oversized blob is omitted here (signer falls back to the
2555
2788
  // caller-supplied copy) rather than failing the intent.
2556
- ...new TextEncoder().encode(JSON.stringify(paymentRequired)).length <= 65536 ? { paymentRequired } : {}
2789
+ ...new TextEncoder().encode(JSON.stringify(paymentRequired)).length <= 65536 ? { paymentRequired } : {},
2790
+ // #3329: `/x402` bodies are camelCase (`X402AuthorizeRequest`), unlike
2791
+ // `POST /payments`'s snake_case `task_budget_id` above — the two
2792
+ // surfaces use different conventions, so this key is NOT `task_budget_id`.
2793
+ ...options.taskBudgetId ? { taskBudgetId: options.taskBudgetId } : {},
2794
+ // #3330: same camelCase channel one level deeper (`X402AuthorizeRequest`);
2795
+ // mutually exclusive with `taskBudgetId` server-side.
2796
+ ...options.subBudgetId ? { subBudgetId: options.subBudgetId } : {}
2557
2797
  });
2558
2798
  if (raw.status !== "pending_signature") {
2559
2799
  throwPaymentStateError("x402 payment", raw);
2560
2800
  }
2561
2801
  if (!raw.sign_data?.hash) {
2562
- throw new chunkJKUIE45B_cjs.HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
2802
+ throw new chunk3SVPI4LS_cjs.HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
2563
2803
  }
2564
2804
  if (raw.sign_data.signature_scheme !== void 0 && !raw.sign_data.typed_data) {
2565
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2805
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2566
2806
  `This account's x402 funding intent declares signature scheme '${raw.sign_data.signature_scheme}' but carried no typed_data to sign. Refusing to fall back to the bare hash \u2014 the account would reject that signature on-chain. This is a backend contract violation; report it rather than working around it.`
2567
2807
  );
2568
2808
  }
2569
2809
  if (!raw.x402_expected_auth) {
2570
- throw new chunkJKUIE45B_cjs.HavenApiError("No x402 expected-context binding returned from x402/authorize", 500, raw);
2810
+ throw new chunk3SVPI4LS_cjs.HavenApiError("No x402 expected-context binding returned from x402/authorize", 500, raw);
2571
2811
  }
2572
2812
  return {
2573
2813
  paymentId: raw.payment_id,
@@ -2578,7 +2818,7 @@ var HavenClient = class {
2578
2818
  accepted: option,
2579
2819
  resourceUrl: paymentRequired.resource.url,
2580
2820
  merchantTo: raw.merchant_to ?? option.payTo,
2581
- amountAtomic: chunkQSSVOPWA_cjs.x402AuthorizationAmount(option),
2821
+ amountAtomic: chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option),
2582
2822
  asset: option.asset,
2583
2823
  network: option.network,
2584
2824
  expectedAuth: raw.x402_expected_auth,
@@ -2603,13 +2843,13 @@ var HavenClient = class {
2603
2843
  */
2604
2844
  sign(hash) {
2605
2845
  if (!this.delegateKey) {
2606
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2846
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2607
2847
  "Cannot sign without a delegateKey. Pass the private key in HavenClient config, or sign externally."
2608
2848
  );
2609
2849
  }
2610
2850
  const signature = signHash(this.delegateKey, hash);
2611
2851
  if (!verifySignature(hash, signature, this.delegateAddress)) {
2612
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2852
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2613
2853
  "Local signature verification failed \u2014 recovered address does not match delegate key."
2614
2854
  );
2615
2855
  }
@@ -2625,51 +2865,58 @@ var HavenClient = class {
2625
2865
  * (#834) — the backend refuses those intents with HTTP 410 before any
2626
2866
  * sign_data reaches a client, so encountering it here is a hard error too.
2627
2867
  */
2628
- async signForData(signData, settlementExpectation) {
2868
+ async signForData(signData, settlementExpectation, fundingExpectation) {
2629
2869
  if (!this.delegateKey) {
2630
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2870
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2631
2871
  "Cannot sign without a delegateKey. Pass the private key in HavenClient config, or sign externally."
2632
2872
  );
2633
2873
  }
2634
2874
  const scheme = signData.signature_scheme;
2635
2875
  if (scheme === "eip191_userop") {
2636
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2876
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2637
2877
  "The session rail is retired \u2014 'eip191_userop' intents can no longer be signed. Re-onboard the account on the delegation rail."
2638
2878
  );
2639
2879
  }
2640
2880
  if (scheme === "eip712_userop") {
2641
2881
  if (!signData.typed_data) {
2642
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2882
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2643
2883
  "sign_data.signature_scheme is eip712_userop but typed_data is missing \u2014 refusing to sign the bare hash (the account would reject it)."
2644
2884
  );
2645
2885
  }
2646
- chunkJKUIE45B_cjs.assertUserOpTypedDataBinding(signData.typed_data, signData.hash);
2647
- chunkQSSVOPWA_cjs.assertBoundDirectPaymentUserOp(
2886
+ chunk3SVPI4LS_cjs.assertUserOpTypedDataBinding(signData.typed_data, signData.hash);
2887
+ chunkJ6DQEBK2_cjs.assertBoundDirectPaymentUserOp(
2648
2888
  signData.typed_data,
2649
2889
  this.delegateAddress
2650
2890
  );
2891
+ if (fundingExpectation) {
2892
+ chunkJ6DQEBK2_cjs.assertFundingLegPaysDelegate(signData.typed_data, {
2893
+ delegateAddress: this.delegateAddress,
2894
+ asset: fundingExpectation.asset,
2895
+ amount: fundingExpectation.amount
2896
+ });
2897
+ }
2651
2898
  return signUserOpTypedDataForDelegation(this.delegateKey, signData.typed_data);
2652
2899
  }
2653
2900
  if (scheme === "eip712_delegation") {
2654
2901
  if (!signData.typed_data) {
2655
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2902
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2656
2903
  "sign_data.signature_scheme is eip712_delegation but typed_data is missing \u2014 refusing to sign the bare hash (the settlement would be rejected on redemption)."
2657
2904
  );
2658
2905
  }
2659
2906
  if (!settlementExpectation) {
2660
- throw new chunkQSSVOPWA_cjs.HavenTypedDataRefusedError(
2907
+ throw new chunkJ6DQEBK2_cjs.HavenTypedDataRefusedError(
2661
2908
  "Refusing to sign an x402 settlement child without an independent expectation of what it must pay (the merchant's 402). Pay erc7710 merchants through settleX402Erc7710(), which supplies it."
2662
2909
  );
2663
2910
  }
2664
- chunkQSSVOPWA_cjs.assertOwnSettlementChild(signData.typed_data, settlementExpectation, this.delegateAddress);
2911
+ chunkJ6DQEBK2_cjs.assertOwnSettlementChild(signData.typed_data, settlementExpectation, this.delegateAddress);
2665
2912
  return signSettlementDelegationTypedData(this.delegateKey, signData.typed_data);
2666
2913
  }
2667
2914
  if (scheme === void 0) {
2668
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2915
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2669
2916
  "sign_data.signature_scheme is required \u2014 the legacy AllowanceModule rail that signed the bare hash is retired (#2850). Refusing to guess a signing scheme."
2670
2917
  );
2671
2918
  }
2672
- throw new chunkJKUIE45B_cjs.HavenSigningError(
2919
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2673
2920
  `Unknown sign_data.signature_scheme '${scheme}' \u2014 refusing to guess a signing scheme. Update @haven_ai/sdk.`
2674
2921
  );
2675
2922
  }
@@ -2853,7 +3100,7 @@ var HavenClient = class {
2853
3100
  */
2854
3101
  async getPaymentStatusWithPostPurchaseAllowance(paymentId) {
2855
3102
  const status = await this.getPaymentStatus(paymentId);
2856
- if (status.rail === chunkJKUIE45B_cjs.AgentPaymentRail.X402 && status.phase === chunkJKUIE45B_cjs.AgentPaymentPhase.PaymentConfirmed) {
3103
+ if (status.rail === chunk3SVPI4LS_cjs.AgentPaymentRail.X402 && status.phase === chunk3SVPI4LS_cjs.AgentPaymentPhase.PaymentConfirmed) {
2857
3104
  const { allowance, warnings } = await this.getPostPurchaseAllowanceSummary(paymentId);
2858
3105
  return { ...status, allowance, ...warnings.length > 0 ? { warnings } : {} };
2859
3106
  }
@@ -2926,7 +3173,12 @@ var HavenClient = class {
2926
3173
  async listReceipts(options = {}) {
2927
3174
  return this.accountReads.listReceipts(options);
2928
3175
  }
2929
- /** #3128: one page of receipts with `total`, `hasMore` and `nextCursor`. */
3176
+ /**
3177
+ * One page of receipts with `total`, `hasMore` and `nextCursor` (#3128).
3178
+ * `compact: true` (#3423) drops each row's
3179
+ * `challengePayload`, `selectedPayment` and `protocolReceiptPayload`; the
3180
+ * default shape is unchanged.
3181
+ */
2930
3182
  async listReceiptsPage(options = {}) {
2931
3183
  return this.accountReads.listReceiptsPage(options);
2932
3184
  }
@@ -2939,6 +3191,96 @@ var HavenClient = class {
2939
3191
  async getReceipt(paymentId) {
2940
3192
  return this.accountReads.getReceipt(paymentId);
2941
3193
  }
3194
+ // ── Task Budgets (#3329) ────────────────────────────────────────────
3195
+ /**
3196
+ * Open a task budget: a self-delegated, time-boxed slice of the agent's own
3197
+ * budget delegation. Returns the pending row plus the child delegation's
3198
+ * `sign_data` — sign it (via `signForData` / `haven_sign` with
3199
+ * `task_budget_id`) and pass the signature to `submitTaskBudget` to make it
3200
+ * OPEN. Nothing is on-chain until then.
3201
+ */
3202
+ async openTaskBudget(request) {
3203
+ const raw = await this.post("/task-budgets", {
3204
+ ...request.tokenAddress ? { token_address: request.tokenAddress } : {},
3205
+ max_amount_atomic: request.maxAmountAtomic,
3206
+ ttl_seconds: request.ttlSeconds,
3207
+ ...request.recipientAddress ? { recipient_address: request.recipientAddress } : {},
3208
+ ...request.label ? { label: request.label } : {}
3209
+ });
3210
+ return {
3211
+ taskBudget: mapTaskBudget(raw.task_budget),
3212
+ signData: raw.sign_data,
3213
+ nextAction: raw.next_action,
3214
+ instructions: raw.instructions
3215
+ };
3216
+ }
3217
+ /** Read one task budget by id. */
3218
+ async getTaskBudget(id) {
3219
+ const raw = await this.get(`/task-budgets/${encodeURIComponent(id)}`);
3220
+ return mapTaskBudget(raw.task_budget);
3221
+ }
3222
+ /** List this agent's task budgets — `status: 'open'` (default; unexpired only) or `'all'`. */
3223
+ async listTaskBudgets(options = {}) {
3224
+ const query = options.status ? `?status=${encodeURIComponent(options.status)}` : "";
3225
+ const raw = await this.get(`/task-budgets${query}`);
3226
+ return raw.task_budgets.map(mapTaskBudget);
3227
+ }
3228
+ /**
3229
+ * The exact signing payload for a pending (purpose `open`) or closing
3230
+ * (purpose `close`) task budget — the `task_budget_id` counterpart of
3231
+ * `getResumeState` / the payment sign-context reads. `haven_sign` with
3232
+ * `task_budget_id` fetches this itself; call it directly only for manual
3233
+ * signing.
3234
+ */
3235
+ async getTaskBudgetSignContext(id) {
3236
+ const raw = await this.get(`/task-budgets/${encodeURIComponent(id)}/sign-context`);
3237
+ if (raw.purpose === "close") {
3238
+ return {
3239
+ taskBudgetId: raw.task_budget_id,
3240
+ purpose: "close",
3241
+ taskSignContextVersion: raw.task_sign_context_version,
3242
+ typedData: raw.typed_data,
3243
+ userOperation: raw.user_operation,
3244
+ userOpHash: raw.user_op_hash,
3245
+ expected: raw.expected
3246
+ };
3247
+ }
3248
+ return {
3249
+ taskBudgetId: raw.task_budget_id,
3250
+ purpose: "open",
3251
+ taskSignContextVersion: raw.task_sign_context_version,
3252
+ typedData: raw.typed_data,
3253
+ expected: raw.expected
3254
+ };
3255
+ }
3256
+ /** Submit a signature for a pending (open) or closing task budget. */
3257
+ async submitTaskBudget(id, signature) {
3258
+ const raw = await this.post(
3259
+ `/task-budgets/${encodeURIComponent(id)}/submit`,
3260
+ { signature }
3261
+ );
3262
+ return {
3263
+ taskBudget: mapTaskBudget(raw.task_budget),
3264
+ status: raw.status,
3265
+ ...raw.close_tx_hash ? { closeTxHash: raw.close_tx_hash } : {}
3266
+ };
3267
+ }
3268
+ /**
3269
+ * Close a task budget early. A `pending` or already-expired `open` budget
3270
+ * closes immediately (nothing was ever signed or is on-chain). A live
3271
+ * `open` budget returns `sign_data` for an on-chain `disableDelegation`
3272
+ * UserOp — sign it (`haven_sign` with `task_budget_id`) and call
3273
+ * `submitTaskBudget`.
3274
+ */
3275
+ async closeTaskBudget(id) {
3276
+ const raw = await this.post(`/task-budgets/${encodeURIComponent(id)}/close`, {});
3277
+ return {
3278
+ taskBudget: mapTaskBudget(raw.task_budget),
3279
+ status: raw.status,
3280
+ ...raw.sign_data ? { signData: raw.sign_data } : {},
3281
+ ...raw.next_action ? { nextAction: raw.next_action } : {}
3282
+ };
3283
+ }
2942
3284
  /**
2943
3285
  * Rehydrate the x402 resume-state bundle for a payment id (#1328: the MPP
2944
3286
  * resume-state variant retired along with the rest of the mpp_demo surface).
@@ -2961,7 +3303,7 @@ var HavenClient = class {
2961
3303
  }
2962
3304
  await sleep(this.pollingInterval);
2963
3305
  }
2964
- throw new chunkJKUIE45B_cjs.HavenTimeoutError(paymentId);
3306
+ throw new chunk3SVPI4LS_cjs.HavenTimeoutError(paymentId);
2965
3307
  }
2966
3308
  // ── x402 Protocol Support ────────────────────────────────────────
2967
3309
  /**
@@ -2975,24 +3317,42 @@ var HavenClient = class {
2975
3317
  */
2976
3318
  async authorizeX402(paymentRequired, options = {}) {
2977
3319
  if (!this.delegateKey) {
2978
- throw new chunkJKUIE45B_cjs.HavenSigningError(
3320
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
2979
3321
  "delegateKey is required for x402 payments. Pass it in the HavenClient config."
2980
3322
  );
2981
3323
  }
2982
3324
  if (!this.delegateAddress) {
2983
- throw new chunkJKUIE45B_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
3325
+ throw new chunk3SVPI4LS_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
2984
3326
  }
2985
- const option = chunkQSSVOPWA_cjs.selectStandardPaymentOption(paymentRequired.accepts);
3327
+ const option = chunkJ6DQEBK2_cjs.selectStandardPaymentOption(paymentRequired.accepts);
2986
3328
  if (!option) {
2987
3329
  throw noCompatiblePaymentOptionError(paymentRequired.accepts);
2988
3330
  }
2989
- const idempotencyKey = options.idempotencyKey ?? chunkQSSVOPWA_cjs.buildX402IdempotencyKey(paymentRequired, option);
2990
- const cached = this.fundingLeg.cachedReceipt(idempotencyKey);
3331
+ const idempotencyKey = options.idempotencyKey ?? chunkJ6DQEBK2_cjs.buildX402IdempotencyKey(paymentRequired, option);
3332
+ const cached = this.fundingLeg.cachedReceipt(idempotencyKey, options.taskBudgetId, options.subBudgetId);
2991
3333
  if (cached) return cached;
2992
3334
  const inFlight = this.inFlightX402.get(idempotencyKey);
2993
- if (inFlight) return inFlight;
2994
- const promise = this.fundingLeg.authorize(paymentRequired, option, idempotencyKey);
3335
+ if (inFlight) {
3336
+ if (!sameX402TaskBudget(this.inFlightX402TaskBudget.get(idempotencyKey), options.taskBudgetId) || !sameX402TaskBudget(this.inFlightX402SubBudget.get(idempotencyKey), options.subBudgetId)) {
3337
+ throw new chunk3SVPI4LS_cjs.X402TaskBudgetMismatchError(
3338
+ `The x402 idempotency key '${idempotencyKey}' has an in-flight payment created under a different authorizing budget (task '${this.inFlightX402TaskBudget.get(idempotencyKey) ?? "none"}' vs '${options.taskBudgetId ?? "none"}', sub '${this.inFlightX402SubBudget.get(idempotencyKey) ?? "none"}' vs '${options.subBudgetId ?? "none"}'). Pass a new idempotencyKey to pay under this budget.`,
3339
+ idempotencyKey,
3340
+ this.inFlightX402TaskBudget.get(idempotencyKey),
3341
+ options.taskBudgetId
3342
+ );
3343
+ }
3344
+ return inFlight;
3345
+ }
3346
+ const promise = this.fundingLeg.authorize(
3347
+ paymentRequired,
3348
+ option,
3349
+ idempotencyKey,
3350
+ options.taskBudgetId,
3351
+ options.subBudgetId
3352
+ );
2995
3353
  this.inFlightX402.set(idempotencyKey, promise);
3354
+ this.inFlightX402TaskBudget.set(idempotencyKey, options.taskBudgetId);
3355
+ this.inFlightX402SubBudget.set(idempotencyKey, options.subBudgetId);
2996
3356
  try {
2997
3357
  return await promise;
2998
3358
  } catch (err) {
@@ -3004,6 +3364,8 @@ var HavenClient = class {
3004
3364
  throw err;
3005
3365
  } finally {
3006
3366
  this.inFlightX402.delete(idempotencyKey);
3367
+ this.inFlightX402TaskBudget.delete(idempotencyKey);
3368
+ this.inFlightX402SubBudget.delete(idempotencyKey);
3007
3369
  }
3008
3370
  }
3009
3371
  /**
@@ -3026,16 +3388,16 @@ var HavenClient = class {
3026
3388
  } catch {
3027
3389
  body = void 0;
3028
3390
  }
3029
- throw new chunkJKUIE45B_cjs.X402UnexpectedStatusError(
3391
+ throw new chunk3SVPI4LS_cjs.X402UnexpectedStatusError(
3030
3392
  `Expected an x402 quote response with HTTP 402, got HTTP ${response.status}.`,
3031
3393
  response.status || 400,
3032
3394
  body
3033
3395
  );
3034
3396
  }
3035
3397
  if (response.headers.get("MACHINE-PAYMENT-CHALLENGE")) {
3036
- throw new chunkJKUIE45B_cjs.HavenApiError("quoteX402 only supports standard x402 Payment Required responses.", 400);
3398
+ throw new chunk3SVPI4LS_cjs.HavenApiError("quoteX402 only supports standard x402 Payment Required responses.", 400);
3037
3399
  }
3038
- const paymentRequired = await chunkQSSVOPWA_cjs.parsePaymentRequiredResponse(response);
3400
+ const paymentRequired = await chunkJ6DQEBK2_cjs.parsePaymentRequiredResponse(response);
3039
3401
  const mcpTransport = await this.merchantTransport.detect(url, paymentRequired, response);
3040
3402
  return buildX402Quote(paymentRequired, request, options.idempotencyKey, mcpTransport);
3041
3403
  }
@@ -3053,7 +3415,7 @@ var HavenClient = class {
3053
3415
  const wallet = await this.merchantCompletion.resolveWalletForMerchantCall();
3054
3416
  const sessionId = await this.merchantTransport.initialize(url, init, wallet);
3055
3417
  if (!sessionId) {
3056
- throw new chunkJKUIE45B_cjs.HavenApiError(
3418
+ throw new chunk3SVPI4LS_cjs.HavenApiError(
3057
3419
  "The merchant did not establish an MCP session before the x402 quote. No payment was created.",
3058
3420
  502,
3059
3421
  { mcpSessionNotEstablished: true }
@@ -3073,7 +3435,7 @@ var HavenClient = class {
3073
3435
  async payX402Quote(quote, options = {}) {
3074
3436
  const idempotencyKey = options.idempotencyKey ?? quote.idempotencyKey;
3075
3437
  try {
3076
- const receipt = await this.authorizeX402(quote.paymentRequired, { idempotencyKey });
3438
+ const receipt = await this.authorizeX402(quote.paymentRequired, { ...options, idempotencyKey });
3077
3439
  return this.merchantCompletion.retryRequest(
3078
3440
  quote.request.url,
3079
3441
  requestInitFromSnapshot(quote.request),
@@ -3127,29 +3489,29 @@ var HavenClient = class {
3127
3489
  }
3128
3490
  async resumeAuthorizedX402(input) {
3129
3491
  if (!this.delegateKey) {
3130
- throw new chunkJKUIE45B_cjs.HavenSigningError(
3492
+ throw new chunk3SVPI4LS_cjs.HavenSigningError(
3131
3493
  "delegateKey is required for x402 payments. Pass it in the HavenClient config."
3132
3494
  );
3133
3495
  }
3134
3496
  if (!this.delegateAddress) {
3135
- throw new chunkJKUIE45B_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
3497
+ throw new chunk3SVPI4LS_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
3136
3498
  }
3137
- const option = chunkQSSVOPWA_cjs.selectStandardPaymentOption(input.paymentRequired.accepts);
3499
+ const option = chunkJ6DQEBK2_cjs.selectStandardPaymentOption(input.paymentRequired.accepts);
3138
3500
  if (!option) {
3139
3501
  throw noCompatiblePaymentOptionError(input.paymentRequired.accepts);
3140
3502
  }
3141
- const idempotencyKey = input.idempotencyKey ?? chunkQSSVOPWA_cjs.buildX402IdempotencyKey(input.paymentRequired, option);
3142
- const cached = this.fundingLeg.cachedReceipt(idempotencyKey);
3503
+ const idempotencyKey = input.idempotencyKey ?? chunkJ6DQEBK2_cjs.buildX402IdempotencyKey(input.paymentRequired, option);
3504
+ const cached = this.fundingLeg.cachedReceipt(idempotencyKey, input.taskBudgetId);
3143
3505
  if (cached) return cached;
3144
3506
  const status = await this.getPaymentStatus(input.paymentId);
3145
3507
  assertCanResumeX402(status, input.paymentRequired, option);
3146
3508
  const canFund = await this.fundingLeg.delegateCanFund(
3147
3509
  status.chainId ?? chainIdFromNetwork(option.network),
3148
3510
  option.asset,
3149
- chunkQSSVOPWA_cjs.x402AuthorizationAmount(option)
3511
+ chunkJ6DQEBK2_cjs.x402AuthorizationAmount(option)
3150
3512
  );
3151
3513
  if (canFund === false) {
3152
- throw new chunkJKUIE45B_cjs.X402AlreadySettledError(
3514
+ throw new chunk3SVPI4LS_cjs.X402AlreadySettledError(
3153
3515
  `x402 payment ${status.paymentId} has already settled \u2014 the delegate no longer holds the funds to authorize it again, so there is nothing left to resume.`,
3154
3516
  this.fundingLeg.receiptFromStatus(input.paymentRequired, option, void 0, status),
3155
3517
  "settled"
@@ -3157,7 +3519,7 @@ var HavenClient = class {
3157
3519
  }
3158
3520
  const paymentHeader = await this.fundingLeg.createPaymentHeader(input.paymentRequired, option);
3159
3521
  const receipt = this.fundingLeg.receiptFromStatus(input.paymentRequired, option, paymentHeader, status);
3160
- this.fundingLeg.cacheReceipt(idempotencyKey, paymentHeader, receipt);
3522
+ this.fundingLeg.cacheReceipt(idempotencyKey, paymentHeader, receipt, input.taskBudgetId);
3161
3523
  return receipt;
3162
3524
  }
3163
3525
  async resumeX402Payment(input) {
@@ -3170,13 +3532,13 @@ var HavenClient = class {
3170
3532
  const url = input.url ?? input.request?.url;
3171
3533
  if (!paymentRequired) {
3172
3534
  if (!url) {
3173
- throw new chunkJKUIE45B_cjs.HavenApiError("x402 resume requires the original URL or a captured request snapshot.", 400);
3535
+ throw new chunk3SVPI4LS_cjs.HavenApiError("x402 resume requires the original URL or a captured request snapshot.", 400);
3174
3536
  }
3175
3537
  const response = await this.merchantTransport.fetch(url, initialInit);
3176
3538
  if (response.status !== 402) {
3177
- throw new chunkJKUIE45B_cjs.HavenApiError("Expected the original x402 request to return HTTP 402 before resuming.", 400);
3539
+ throw new chunk3SVPI4LS_cjs.HavenApiError("Expected the original x402 request to return HTTP 402 before resuming.", 400);
3178
3540
  }
3179
- paymentRequired = await chunkQSSVOPWA_cjs.parsePaymentRequiredResponse(response);
3541
+ paymentRequired = await chunkJ6DQEBK2_cjs.parsePaymentRequiredResponse(response);
3180
3542
  }
3181
3543
  const receipt = await this.resumeAuthorizedX402({
3182
3544
  paymentId: input.paymentId,
@@ -3229,7 +3591,7 @@ var HavenClient = class {
3229
3591
  nativeChallenge = true;
3230
3592
  } else {
3231
3593
  try {
3232
- paymentRequired = await chunkQSSVOPWA_cjs.parsePaymentRequiredResponse(response);
3594
+ paymentRequired = await chunkJ6DQEBK2_cjs.parsePaymentRequiredResponse(response);
3233
3595
  } catch {
3234
3596
  return response;
3235
3597
  }
@@ -3239,8 +3601,8 @@ var HavenClient = class {
3239
3601
  if (mcpSessionId) requestInit = this.merchantTransport.withSessionHeaders(requestInit, mcpSessionId);
3240
3602
  }
3241
3603
  const request = snapshotX402Request(url, requestInit);
3242
- const option = chunkQSSVOPWA_cjs.selectStandardPaymentOption(paymentRequired.accepts);
3243
- const idempotencyKey = options.idempotencyKey ?? (option ? chunkQSSVOPWA_cjs.buildX402IdempotencyKey(paymentRequired, option) : void 0);
3604
+ const option = chunkJ6DQEBK2_cjs.selectStandardPaymentOption(paymentRequired.accepts);
3605
+ const idempotencyKey = options.idempotencyKey ?? (option ? chunkJ6DQEBK2_cjs.buildX402IdempotencyKey(paymentRequired, option) : void 0);
3244
3606
  let receipt;
3245
3607
  try {
3246
3608
  receipt = await this.authorizeX402(paymentRequired, options);
@@ -3367,7 +3729,7 @@ var HavenClient = class {
3367
3729
  txHash: evidenceTxHash,
3368
3730
  resourceUrl: evidenceContext.resourceUrl,
3369
3731
  merchantStatus: surfaced.status,
3370
- paymentProofHeaderName: chunkQSSVOPWA_cjs.x402PaymentHeaderNamesSent(input.paymentHeader),
3732
+ paymentProofHeaderName: chunkJ6DQEBK2_cjs.x402PaymentHeaderNamesSent(input.paymentHeader),
3371
3733
  paymentProofHeader: input.paymentHeader,
3372
3734
  protocolReceiptHeaderName,
3373
3735
  protocolReceiptHeader
@@ -3584,7 +3946,7 @@ var toolDescriptions = {
3584
3946
  // deleted `/demo/mpp/*` route. Use the x402 fragments above instead.
3585
3947
  getPaymentStatus: {
3586
3948
  summary: "Fetch structured Haven payment status for agent recovery.",
3587
- behavior: "State: phase, nextAction, rail, amount, merchant, resource, idempotency, message; parties: treasury/delegate/delegateAccount/merchant. awaiting_settlement_evidence: poll once, else unverified.",
3949
+ behavior: "State: phase, nextAction, rail, amount, merchant, resource, idempotency, message; delivered when the merchant answered; parties: treasury/delegate/delegateAccount/merchant. awaiting_settlement_evidence: poll once, else unverified. delivered_unverified: terminal, stop.",
3588
3950
  nextActionGuidance: ""
3589
3951
  },
3590
3952
  getResumeState: {
@@ -3619,9 +3981,9 @@ var toolDescriptions = {
3619
3981
  nextActionGuidance: ""
3620
3982
  },
3621
3983
  verifyReceipt: {
3622
- summary: "Verify a payment receipt offline \u2014 confirm the agent authorised the transfer.",
3623
- selectionGuidance: "Use this to check a receipt you already hold; it needs no network and does not trust Haven. Use the history tool to fetch receipts in the first place.",
3624
- behavior: "Recovers the signer from the receipt authorisation and confirms it matches the agent delegate. Returns verified true/false with the recovered signer or a reason. Pure and local \u2014 no backend call.",
3984
+ summary: "Verify a signed payment receipt offline \u2014 confirm the agent delegate signed its authorisation.",
3985
+ selectionGuidance: "Takes the signed bundle from GET /payments/{id}/receipt, not a haven_list_receipts row \u2014 a row carries no signature and returns not_a_signed_receipt. No network.",
3986
+ behavior: "Never throws. An erc7710 bundle verifies over the delegation digest the delegate signed; a direct or eip3009 bundle returns not_verifiable_offline. verified true means only that the delegate signed the hash named by verifiedOver \u2014 payment facts are Haven-asserted and settlement is not proven; check settlementTxHash on an explorer.",
3625
3987
  nextActionGuidance: ""
3626
3988
  },
3627
3989
  payMcpTool: {
@@ -3651,7 +4013,7 @@ var toolDescriptions = {
3651
4013
  send: {
3652
4014
  summary: "Send ETH or USDC directly from the agent's Haven wallet to a recipient address.",
3653
4015
  selectionGuidance: "Use this for plain transfers \u2014 refunding a user, paying a freelancer, topping up a co-agent's wallet, or moving funds between addresses. Do NOT use for x402 paid endpoints \u2014 use haven_pay_x402 instead. Do NOT use for read-only allowance, budget, or what-can-I-spend questions \u2014 use haven_get_allowances. Do NOT use to check whether funds are held before sending \u2014 use haven_check_funds.",
3654
- behavior: "Sends the amount by redeeming the agent's on-chain budget delegation, account to recipient with no funding leg. Budget, recipient and expiry are enforced on-chain while the transfer is prepared, so a request outside them is declined before any money moves or any signing \u2014 never queued for a human to approve. The agent's signing key signs the account's typed data, refusing any that mismatches the payment's hash; Haven never receives the key.",
4016
+ behavior: "Sends the amount by redeeming the agent's on-chain budget delegation, account to recipient with no funding leg. Budget, recipient and expiry are enforced on-chain while the transfer is prepared, so a request outside them is declined before any money moves or any signing \u2014 never queued for a human to approve. The agent's signing key signs the account's typed data; a current signer refuses any that does not match the payment's hash (USEROP_BINDING_MISMATCH), an older signer signs it and the account rejects it on-chain. Haven never receives the key.",
3655
4017
  nextActionGuidance: "On a decline, report the reason to the user and ask them to grant or raise the budget in Haven \u2014 there is nothing to poll and no approval will arrive. After a successful send, poll haven_get_payment_status until nextAction=none."
3656
4018
  },
3657
4019
  reportSettlementEvidence: {
@@ -3908,7 +4270,7 @@ Your user gives you a **budget on their own account** \u2014 not their wallet, a
3908
4270
 
3909
4271
  Four of the six steps are your user's \u2014 each needs a human signature or a human decision. The rest is yours. If they already have a funded account, start at step 3.
3910
4272
 
3911
- 1. **HUMAN \u2014 create the account.** Name, email, password, then a passkey (Face ID / Touch ID) or a wallet. Never offer to enter any of it: you must not have their password, and the passkey is bound to their device. With a terminal, \`npx @haven_ai/cli@<channel> login --api <api-url>\` afterwards gets you a scoped session for steps 3-4 (that flag or \`HAVEN_API_URL\`, on the first command \u2014 the session then remembers the backend; **the CLI's built-in default is Haven's hosted production backend**, so on any other deployment an omitted flag connects you somewhere real and wrong rather than failing) \u2014 they approve a code in the browser, you never hold their password. The \`<channel>\` in that command is the tag your deployment names \u2014 read it from \`/.well-known/haven.json\` (\`packages.cli.channel\`), never a tag you pick. Do not hold the process open while you wait: under \`--json\`, pass \`--no-wait\` to get the link object back at once, then poll it with \`haven login --poll <device_code>\` \u2014 one round per invocation, exit 3 while it is still pending, 0 once approved. It can set up agents and read the account; it cannot sign, approve a budget, move funds, or rotate any agent's keys.
4273
+ 1. **HUMAN \u2014 create the account.** Name, email, password, then a passkey (Face ID / Touch ID) or a wallet. Never offer to enter any of it: you must not have their password, and the passkey is bound to their device. With a terminal, \`<packages.cli.one_liner> login --api <api-url>\` afterwards gets you a scoped session for steps 3-4 (that flag or \`HAVEN_API_URL\`, on the first command \u2014 the session then remembers the backend; **the CLI's built-in default is Haven's hosted production backend**, so on any other deployment an omitted flag connects you somewhere real and wrong rather than failing) \u2014 they approve a code in the browser, you never hold their password. That command is the manifest's \`packages.cli.one_liner\` (\`/.well-known/haven.json\`) \u2014 run it as given: \`packages.cli.channel\` serves the full spec. Do not hold the process open while you wait: under \`--json\`, pass \`--no-wait\` to get the link object back at once, then poll it with \`haven login --poll <device_code>\` \u2014 one round per invocation, exit 3 while it is still pending, 0 once approved. It can set up agents and read the account; it cannot sign, approve a budget, move funds, or rotate any agent's keys.
3912
4274
  2. **HUMAN \u2014 fund it.** USDC only, no ETH: Haven sponsors the gas. \`/.well-known/haven.json\` names \`chains.default\` as the deployment's expected chain, but after login \`haven wallets funding\` prints the address, the amount and which chain in one place; confirm that chain before you message your user. Without a CLI session, the dashboard's funding card shows the address and amount and its Receive-funds screen names the chain; never assume one: a testnet deployment and production both call themselves Haven. Before you write that message, read the manifest: \`environment\` says whether this deployment is \`production\`, and each \`chains.supported\` entry says whether that chain is a \`testnet\`. Real money is at stake only on a non-testnet chain of a \`production\` deployment \u2014 tell your user which case theirs is.
3913
4275
  3. **HUMAN \u2014 create the agent, set its budget**, and paste you the **setup prompt** it hands back. With a CLI session (step 1) you can do this step yourself: \`haven agents connect --name <n> --budget <amount> --token USDC --period <minutes>\` prints the same connector command and approval link; add \`--run\` to do step 4 too.
3914
4276
  4. **YOU \u2014 run the connector command** in that prompt (below). It makes your signing key locally, registering only the public address.
@@ -3984,6 +4346,10 @@ Call \`haven_get_agent\`, one of the Haven MCP tools the connector wires into yo
3984
4346
 
3985
4347
  Nothing here needs you to. Steps 1-3 are links: hand your user the full \`<host>/\u2026\` URL and ask them to say when it is done. Step 5 is a link only when your run reported one in \`approval.url\` \u2014 otherwise it is the tab they already have open, as above. Then poll \`haven_get_agent\` until it reads \`ready\`. Do not route around the sign-in wall \u2014 it makes the account theirs, not yours.
3986
4348
 
4349
+ ## If something breaks
4350
+
4351
+ If a Haven result carries \`client_update\`, that client is out of date: run its \`upgrade_command\` as given, then any repair line it prints, then retry. \`required: true\` means payments are refused until you do. What changed: [/releases](/releases).
4352
+
3987
4353
  ## Vocabulary
3988
4354
 
3989
4355
  | Term | What it is |
@@ -4002,12 +4368,12 @@ Start by reading {{HAVEN_ORIGIN}}/for-agents.md \u2014 it is written for you and
4002
4368
 
4003
4369
  Then:
4004
4370
 
4005
- 1. Run \`npx @haven_ai/cli@<channel> login\`. The \`<channel>\` in that command is the tag your deployment names \u2014 read it from \`/.well-known/haven.json\` (\`packages.cli.channel\`), never a tag you pick. It prints a link and a code and does not need my password \u2014 it must never ask for it. Give me the link straight away and wait for me to approve it in my browser.
4371
+ 1. Run \`<packages.cli.one_liner> login\`. That command is the manifest's \`packages.cli.one_liner\` (\`/.well-known/haven.json\`) \u2014 run it as given: \`packages.cli.channel\` serves the full spec. It prints a link and a code and does not need my password \u2014 it must never ask for it. Give me the link straight away and wait for me to approve it in my browser.
4006
4372
  2. Once I have approved, run \`haven agents connect --name <a name you choose> --budget <amount> --token USDC --period <minutes>\` with the budget I tell you. If I have not given you one, ask me before running it. Add \`--run\` to complete the connection in the same step.
4007
4373
  3. ${AGENT_APPROVAL_RELAY_JSON_SENTENCE}
4008
4374
  4. Once I have approved the budget, verify with the \`haven_get_agent\` tool: \`ready\` means you can pay, \`needs_approval\` means my approval has not landed yet.
4009
4375
 
4010
- Two things only I can do: approving that budget with my passkey, and funding the account with USDC on Base \u2014 no ETH, Haven sponsors the gas. Tell me if either is missing rather than working around it.
4376
+ Two things only I can do: approving that budget with my passkey, and funding the account with USDC \u2014 no ETH, Haven sponsors the gas. Tell me if either is missing rather than working around it.
4011
4377
 
4012
4378
  ${AGENT_SECRET_HYGIENE_SENTENCE}`;
4013
4379
 
@@ -4151,28 +4517,43 @@ the budget in the Haven dashboard, or wait for the period reset.
4151
4517
  4. Then FOLLOW THE RESPONSE'S GUIDANCE FIELDS: \`next_action\`, \`next_tool\`,
4152
4518
  and \`next_arguments\` name the exact next call \u2014 act on those first; the
4153
4519
  prose in this section is fallback and debugging detail. If the catalog
4154
- entry is missing or degraded, the response instead names
4155
- \`mcp__haven__haven_pay_mcp_tool\` (merchant URL, tool name, arguments) as
4156
- the manual fallback.
4520
+ row is a plain-HTTP x402 paywall (no MCP tool metadata), the response
4521
+ instead names \`mcp__haven__haven_quote_x402\` with the entry's resource
4522
+ URL as \`url\`. If an MCP row is degraded or has no tool name, the response
4523
+ instead names \`mcp__haven__haven_pay_mcp_tool\` (merchant URL, tool name,
4524
+ arguments) as the manual fallback.
4157
4525
 
4158
- **Signing:** \`mcp__haven-signer__haven_sign_x402\` with \`payment_id\` ONLY \u2014
4526
+ **Signing:** which signer tool to call depends on the settlement scheme the
4527
+ prepare/pay response already named as \`next_tool\` \u2014 follow that field, never
4528
+ hard-code a choice. **erc7710** (direct settlement \u2014 chosen per merchant when
4529
+ its 402 advertises \`assetTransferMethod: "erc7710"\` AND your account is on
4530
+ the delegation rail; never a blanket default): \`mcp__haven-signer__haven_sign\`
4531
+ with \`payment_id\` ONLY; the signer fetches the settlement child itself.
4532
+ **EIP-3009** (the bridge \u2014 used otherwise, whenever the merchant offers a
4533
+ standard entry): \`mcp__haven-signer__haven_sign_x402\` with \`payment_id\` ONLY \u2014
4159
4534
  the local signer fetches the exact signing bytes AND \`payment_required\`
4160
- itself, so never relay \`typed_data\` or the 402 blob yourself. If the signer
4161
- reports its fetched context carried no \`payment_required\` (older backend),
4162
- re-call with \`payment_required\` added verbatim. Fallback for an older signer
4163
- or backend: re-run the quote/prepare tool with the SAME \`idempotency_key\`
4164
- plus \`include_signing_payload=true\`, then pass \`payload_hash\`,
4165
- \`x402_expected\` (the nested \`x402.expected\` object), and
4535
+ itself, so never relay \`typed_data\` or the 402 blob yourself. A merchant
4536
+ that advertises ONLY erc7710 against an account that is NOT on the
4537
+ delegation rail is refused outright \u2014 it does not fall back to EIP-3009. If
4538
+ the signer reports its fetched context carried no \`payment_required\` (older
4539
+ backend), re-call with \`payment_required\` added verbatim. Fallback for an
4540
+ older signer or backend: re-run the quote/prepare tool with the SAME
4541
+ \`idempotency_key\` plus \`include_signing_payload=true\`, then pass
4542
+ \`payload_hash\`, \`x402_expected\` (the nested \`x402.expected\` object), and
4166
4543
  \`typed_data\`/\`typed_data_b64\` through unchanged.
4167
4544
 
4168
- **Settle:** \`mcp__haven__haven_settle_mcp_tool\` with \`payment_id\`,
4169
- \`signature\`, and \`payment_header\` ONLY \u2014 Haven rehydrates the merchant call
4545
+ **Settle:** \`mcp__haven__haven_settle_mcp_tool\` with \`payment_id\` and
4546
+ \`signature\` always. On **erc7710**, pass no \`payment_header\` \u2014 Haven
4547
+ assembles it at settle, so there is nothing to build locally and no funding
4548
+ transaction to wait for. On **EIP-3009**, also pass \`payment_header\` (from
4549
+ \`haven_sign_x402\`) ONLY. Either way Haven rehydrates the merchant call
4170
4550
  context (\`merchant_url\`, \`tool_name\`, \`arguments\`, \`mcp_transport\`)
4171
4551
  server-side from \`payment_id\`. Pass those four fields explicitly only as a
4172
4552
  version-skew fallback when Haven has no stored context for the id \u2014 both or
4173
- none together, never just one. If the settle result carries \`settled: false\`,
4174
- funding has not confirmed \u2014 follow the result's guidance fields and check
4175
- status later, do not re-pay.
4553
+ none together, never just one. On **EIP-3009**, \`settled: false\` means
4554
+ funding has not confirmed; on **erc7710** it means the merchant delivered but
4555
+ settlement is not yet verified. Either way, follow the result's guidance
4556
+ fields and do not re-pay.
4176
4557
 
4177
4558
  Step-by-step alternative (also key-safe; for an older signer or backend, or
4178
4559
  when you already have a merchant URL and tool name instead of a
@@ -4364,435 +4745,475 @@ function sameUrl(a, b) {
4364
4745
 
4365
4746
  Object.defineProperty(exports, "DEFAULT_NEXT_TOOL_BY_ACTION", {
4366
4747
  enumerable: true,
4367
- get: function () { return chunkQSSVOPWA_cjs.DEFAULT_NEXT_TOOL_BY_ACTION; }
4748
+ get: function () { return chunkJ6DQEBK2_cjs.DEFAULT_NEXT_TOOL_BY_ACTION; }
4368
4749
  });
4369
4750
  Object.defineProperty(exports, "ERC7710_ASSET_TRANSFER_METHOD", {
4370
4751
  enumerable: true,
4371
- get: function () { return chunkQSSVOPWA_cjs.ERC7710_ASSET_TRANSFER_METHOD; }
4752
+ get: function () { return chunkJ6DQEBK2_cjs.ERC7710_ASSET_TRANSFER_METHOD; }
4372
4753
  });
4373
4754
  Object.defineProperty(exports, "HAVEN_CLIENT_HEADER", {
4374
4755
  enumerable: true,
4375
- get: function () { return chunkQSSVOPWA_cjs.HAVEN_CLIENT_HEADER; }
4756
+ get: function () { return chunkJ6DQEBK2_cjs.HAVEN_CLIENT_HEADER; }
4376
4757
  });
4377
4758
  Object.defineProperty(exports, "HAVEN_MINIMUM_NODE_VERSION", {
4378
4759
  enumerable: true,
4379
- get: function () { return chunkQSSVOPWA_cjs.HAVEN_MINIMUM_NODE_VERSION; }
4760
+ get: function () { return chunkJ6DQEBK2_cjs.HAVEN_MINIMUM_NODE_VERSION; }
4380
4761
  });
4381
4762
  Object.defineProperty(exports, "HavenTypedDataRefusedError", {
4382
4763
  enumerable: true,
4383
- get: function () { return chunkQSSVOPWA_cjs.HavenTypedDataRefusedError; }
4764
+ get: function () { return chunkJ6DQEBK2_cjs.HavenTypedDataRefusedError; }
4765
+ });
4766
+ Object.defineProperty(exports, "MAX_TASK_BUDGET_TTL_SECONDS", {
4767
+ enumerable: true,
4768
+ get: function () { return chunkJ6DQEBK2_cjs.MAX_TASK_BUDGET_TTL_SECONDS; }
4384
4769
  });
4385
4770
  Object.defineProperty(exports, "NEXT_TOOL_SERVER_NAMES", {
4386
4771
  enumerable: true,
4387
- get: function () { return chunkQSSVOPWA_cjs.NEXT_TOOL_SERVER_NAMES; }
4772
+ get: function () { return chunkJ6DQEBK2_cjs.NEXT_TOOL_SERVER_NAMES; }
4388
4773
  });
4389
4774
  Object.defineProperty(exports, "NEXT_TOOL_SERVER_ROLES", {
4390
4775
  enumerable: true,
4391
- get: function () { return chunkQSSVOPWA_cjs.NEXT_TOOL_SERVER_ROLES; }
4776
+ get: function () { return chunkJ6DQEBK2_cjs.NEXT_TOOL_SERVER_ROLES; }
4392
4777
  });
4393
4778
  Object.defineProperty(exports, "SDK_CLIENT_IDENTITY", {
4394
4779
  enumerable: true,
4395
- get: function () { return chunkQSSVOPWA_cjs.SDK_CLIENT_IDENTITY; }
4780
+ get: function () { return chunkJ6DQEBK2_cjs.SDK_CLIENT_IDENTITY; }
4396
4781
  });
4397
4782
  Object.defineProperty(exports, "SDK_VERSION", {
4398
4783
  enumerable: true,
4399
- get: function () { return chunkQSSVOPWA_cjs.SDK_VERSION; }
4784
+ get: function () { return chunkJ6DQEBK2_cjs.SDK_VERSION; }
4400
4785
  });
4401
4786
  Object.defineProperty(exports, "SWEEP_BASE_CHAIN_ID", {
4402
4787
  enumerable: true,
4403
- get: function () { return chunkQSSVOPWA_cjs.SWEEP_BASE_CHAIN_ID; }
4788
+ get: function () { return chunkJ6DQEBK2_cjs.SWEEP_BASE_CHAIN_ID; }
4404
4789
  });
4405
4790
  Object.defineProperty(exports, "SWEEP_BASE_SEPOLIA_CHAIN_ID", {
4406
4791
  enumerable: true,
4407
- get: function () { return chunkQSSVOPWA_cjs.SWEEP_BASE_SEPOLIA_CHAIN_ID; }
4792
+ get: function () { return chunkJ6DQEBK2_cjs.SWEEP_BASE_SEPOLIA_CHAIN_ID; }
4408
4793
  });
4409
4794
  Object.defineProperty(exports, "SWEEP_BASE_SEPOLIA_USDC_ADDRESS", {
4410
4795
  enumerable: true,
4411
- get: function () { return chunkQSSVOPWA_cjs.SWEEP_BASE_SEPOLIA_USDC_ADDRESS; }
4796
+ get: function () { return chunkJ6DQEBK2_cjs.SWEEP_BASE_SEPOLIA_USDC_ADDRESS; }
4412
4797
  });
4413
4798
  Object.defineProperty(exports, "SWEEP_BASE_USDC_ADDRESS", {
4414
4799
  enumerable: true,
4415
- get: function () { return chunkQSSVOPWA_cjs.SWEEP_BASE_USDC_ADDRESS; }
4800
+ get: function () { return chunkJ6DQEBK2_cjs.SWEEP_BASE_USDC_ADDRESS; }
4416
4801
  });
4417
4802
  Object.defineProperty(exports, "TRANSFER_WITH_AUTHORIZATION_TYPES", {
4418
4803
  enumerable: true,
4419
- get: function () { return chunkQSSVOPWA_cjs.TRANSFER_WITH_AUTHORIZATION_TYPES; }
4804
+ get: function () { return chunkJ6DQEBK2_cjs.TRANSFER_WITH_AUTHORIZATION_TYPES; }
4420
4805
  });
4421
4806
  Object.defineProperty(exports, "TYPED_DATA_NOT_ALLOWED", {
4422
4807
  enumerable: true,
4423
- get: function () { return chunkQSSVOPWA_cjs.TYPED_DATA_NOT_ALLOWED; }
4808
+ get: function () { return chunkJ6DQEBK2_cjs.TYPED_DATA_NOT_ALLOWED; }
4424
4809
  });
4425
4810
  Object.defineProperty(exports, "X402PaymentHeaderValidationError", {
4426
4811
  enumerable: true,
4427
- get: function () { return chunkQSSVOPWA_cjs.X402PaymentHeaderValidationError; }
4812
+ get: function () { return chunkJ6DQEBK2_cjs.X402PaymentHeaderValidationError; }
4428
4813
  });
4429
4814
  Object.defineProperty(exports, "X402_LEGACY_PAYMENT_HEADER_NAME", {
4430
4815
  enumerable: true,
4431
- get: function () { return chunkQSSVOPWA_cjs.X402_LEGACY_PAYMENT_HEADER_NAME; }
4816
+ get: function () { return chunkJ6DQEBK2_cjs.X402_LEGACY_PAYMENT_HEADER_NAME; }
4432
4817
  });
4433
4818
  Object.defineProperty(exports, "X402_MAX_AUTHORIZATION_WINDOW_SECONDS", {
4434
4819
  enumerable: true,
4435
- get: function () { return chunkQSSVOPWA_cjs.X402_MAX_AUTHORIZATION_WINDOW_SECONDS; }
4820
+ get: function () { return chunkJ6DQEBK2_cjs.X402_MAX_AUTHORIZATION_WINDOW_SECONDS; }
4436
4821
  });
4437
4822
  Object.defineProperty(exports, "X402_PAYMENT_HEADER_NAME", {
4438
4823
  enumerable: true,
4439
- get: function () { return chunkQSSVOPWA_cjs.X402_PAYMENT_HEADER_NAME; }
4824
+ get: function () { return chunkJ6DQEBK2_cjs.X402_PAYMENT_HEADER_NAME; }
4440
4825
  });
4441
4826
  Object.defineProperty(exports, "X402_PAYMENT_HEADER_NAMES_SENT", {
4442
4827
  enumerable: true,
4443
- get: function () { return chunkQSSVOPWA_cjs.X402_PAYMENT_HEADER_NAMES_SENT; }
4828
+ get: function () { return chunkJ6DQEBK2_cjs.X402_PAYMENT_HEADER_NAMES_SENT; }
4444
4829
  });
4445
4830
  Object.defineProperty(exports, "X402_PAYMENT_REQUIRED_HEADER_NAME", {
4446
4831
  enumerable: true,
4447
- get: function () { return chunkQSSVOPWA_cjs.X402_PAYMENT_REQUIRED_HEADER_NAME; }
4832
+ get: function () { return chunkJ6DQEBK2_cjs.X402_PAYMENT_REQUIRED_HEADER_NAME; }
4448
4833
  });
4449
4834
  Object.defineProperty(exports, "X402_PAYMENT_RESPONSE_HEADER_NAME", {
4450
4835
  enumerable: true,
4451
- get: function () { return chunkQSSVOPWA_cjs.X402_PAYMENT_RESPONSE_HEADER_NAME; }
4836
+ get: function () { return chunkJ6DQEBK2_cjs.X402_PAYMENT_RESPONSE_HEADER_NAME; }
4452
4837
  });
4453
4838
  Object.defineProperty(exports, "X402_SETTLEMENT_FORWARD_MARGIN_SECONDS", {
4454
4839
  enumerable: true,
4455
- get: function () { return chunkQSSVOPWA_cjs.X402_SETTLEMENT_FORWARD_MARGIN_SECONDS; }
4840
+ get: function () { return chunkJ6DQEBK2_cjs.X402_SETTLEMENT_FORWARD_MARGIN_SECONDS; }
4456
4841
  });
4457
4842
  Object.defineProperty(exports, "assertBoundDirectPaymentUserOp", {
4458
4843
  enumerable: true,
4459
- get: function () { return chunkQSSVOPWA_cjs.assertBoundDirectPaymentUserOp; }
4844
+ get: function () { return chunkJ6DQEBK2_cjs.assertBoundDirectPaymentUserOp; }
4845
+ });
4846
+ Object.defineProperty(exports, "assertOwnTaskBudgetCloseUserOp", {
4847
+ enumerable: true,
4848
+ get: function () { return chunkJ6DQEBK2_cjs.assertOwnTaskBudgetCloseUserOp; }
4849
+ });
4850
+ Object.defineProperty(exports, "assertOwnTaskChild", {
4851
+ enumerable: true,
4852
+ get: function () { return chunkJ6DQEBK2_cjs.assertOwnTaskChild; }
4460
4853
  });
4461
4854
  Object.defineProperty(exports, "buildSweepAuthorizationMessage", {
4462
4855
  enumerable: true,
4463
- get: function () { return chunkQSSVOPWA_cjs.buildSweepAuthorizationMessage; }
4856
+ get: function () { return chunkJ6DQEBK2_cjs.buildSweepAuthorizationMessage; }
4464
4857
  });
4465
4858
  Object.defineProperty(exports, "buildSweepTypedData", {
4466
4859
  enumerable: true,
4467
- get: function () { return chunkQSSVOPWA_cjs.buildSweepTypedData; }
4860
+ get: function () { return chunkJ6DQEBK2_cjs.buildSweepTypedData; }
4468
4861
  });
4469
4862
  Object.defineProperty(exports, "buildX402ExpectedMessage", {
4470
4863
  enumerable: true,
4471
- get: function () { return chunkQSSVOPWA_cjs.buildX402ExpectedMessage; }
4864
+ get: function () { return chunkJ6DQEBK2_cjs.buildX402ExpectedMessage; }
4472
4865
  });
4473
4866
  Object.defineProperty(exports, "compareNodeVersions", {
4474
4867
  enumerable: true,
4475
- get: function () { return chunkQSSVOPWA_cjs.compareNodeVersions; }
4868
+ get: function () { return chunkJ6DQEBK2_cjs.compareNodeVersions; }
4476
4869
  });
4477
4870
  Object.defineProperty(exports, "createNextStepBuilder", {
4478
4871
  enumerable: true,
4479
- get: function () { return chunkQSSVOPWA_cjs.createNextStepBuilder; }
4872
+ get: function () { return chunkJ6DQEBK2_cjs.createNextStepBuilder; }
4480
4873
  });
4481
4874
  Object.defineProperty(exports, "decodeBase64Json", {
4482
4875
  enumerable: true,
4483
- get: function () { return chunkQSSVOPWA_cjs.decodeBase64Json; }
4876
+ get: function () { return chunkJ6DQEBK2_cjs.decodeBase64Json; }
4484
4877
  });
4485
4878
  Object.defineProperty(exports, "decodeBase64Utf8", {
4486
4879
  enumerable: true,
4487
- get: function () { return chunkQSSVOPWA_cjs.decodeBase64Utf8; }
4880
+ get: function () { return chunkJ6DQEBK2_cjs.decodeBase64Utf8; }
4488
4881
  });
4489
4882
  Object.defineProperty(exports, "defaultNextToolFor", {
4490
4883
  enumerable: true,
4491
- get: function () { return chunkQSSVOPWA_cjs.defaultNextToolFor; }
4884
+ get: function () { return chunkJ6DQEBK2_cjs.defaultNextToolFor; }
4492
4885
  });
4493
4886
  Object.defineProperty(exports, "encodeBase64Json", {
4494
4887
  enumerable: true,
4495
- get: function () { return chunkQSSVOPWA_cjs.encodeBase64Json; }
4888
+ get: function () { return chunkJ6DQEBK2_cjs.encodeBase64Json; }
4496
4889
  });
4497
4890
  Object.defineProperty(exports, "encodeBase64Utf8", {
4498
4891
  enumerable: true,
4499
- get: function () { return chunkQSSVOPWA_cjs.encodeBase64Utf8; }
4892
+ get: function () { return chunkJ6DQEBK2_cjs.encodeBase64Utf8; }
4500
4893
  });
4501
4894
  Object.defineProperty(exports, "encodePaymentProof", {
4502
4895
  enumerable: true,
4503
- get: function () { return chunkQSSVOPWA_cjs.encodePaymentProof; }
4896
+ get: function () { return chunkJ6DQEBK2_cjs.encodePaymentProof; }
4897
+ });
4898
+ Object.defineProperty(exports, "hashDelegation", {
4899
+ enumerable: true,
4900
+ get: function () { return chunkJ6DQEBK2_cjs.hashDelegation; }
4504
4901
  });
4505
4902
  Object.defineProperty(exports, "havenClientIdentity", {
4506
4903
  enumerable: true,
4507
- get: function () { return chunkQSSVOPWA_cjs.havenClientIdentity; }
4904
+ get: function () { return chunkJ6DQEBK2_cjs.havenClientIdentity; }
4508
4905
  });
4509
4906
  Object.defineProperty(exports, "isErc7710Option", {
4510
4907
  enumerable: true,
4511
- get: function () { return chunkQSSVOPWA_cjs.isErc7710Option; }
4908
+ get: function () { return chunkJ6DQEBK2_cjs.isErc7710Option; }
4512
4909
  });
4513
4910
  Object.defineProperty(exports, "isSupportedNodeVersion", {
4514
4911
  enumerable: true,
4515
- get: function () { return chunkQSSVOPWA_cjs.isSupportedNodeVersion; }
4912
+ get: function () { return chunkJ6DQEBK2_cjs.isSupportedNodeVersion; }
4516
4913
  });
4517
4914
  Object.defineProperty(exports, "isSweepableChain", {
4518
4915
  enumerable: true,
4519
- get: function () { return chunkQSSVOPWA_cjs.isSweepableChain; }
4916
+ get: function () { return chunkJ6DQEBK2_cjs.isSweepableChain; }
4917
+ });
4918
+ Object.defineProperty(exports, "isTaskChildTypedData", {
4919
+ enumerable: true,
4920
+ get: function () { return chunkJ6DQEBK2_cjs.isTaskChildTypedData; }
4520
4921
  });
4521
4922
  Object.defineProperty(exports, "normalizePaymentRequired", {
4522
4923
  enumerable: true,
4523
- get: function () { return chunkQSSVOPWA_cjs.normalizePaymentRequired; }
4924
+ get: function () { return chunkJ6DQEBK2_cjs.normalizePaymentRequired; }
4524
4925
  });
4525
4926
  Object.defineProperty(exports, "parseNextTool", {
4526
4927
  enumerable: true,
4527
- get: function () { return chunkQSSVOPWA_cjs.parseNextTool; }
4928
+ get: function () { return chunkJ6DQEBK2_cjs.parseNextTool; }
4528
4929
  });
4529
4930
  Object.defineProperty(exports, "parsePaymentRequired", {
4530
4931
  enumerable: true,
4531
- get: function () { return chunkQSSVOPWA_cjs.parsePaymentRequired; }
4932
+ get: function () { return chunkJ6DQEBK2_cjs.parsePaymentRequired; }
4532
4933
  });
4533
4934
  Object.defineProperty(exports, "parsePaymentRequiredResponse", {
4534
4935
  enumerable: true,
4535
- get: function () { return chunkQSSVOPWA_cjs.parsePaymentRequiredResponse; }
4936
+ get: function () { return chunkJ6DQEBK2_cjs.parsePaymentRequiredResponse; }
4536
4937
  });
4537
4938
  Object.defineProperty(exports, "readClientUpdate", {
4538
4939
  enumerable: true,
4539
- get: function () { return chunkQSSVOPWA_cjs.readClientUpdate; }
4940
+ get: function () { return chunkJ6DQEBK2_cjs.readClientUpdate; }
4540
4941
  });
4541
4942
  Object.defineProperty(exports, "renderNextTool", {
4542
4943
  enumerable: true,
4543
- get: function () { return chunkQSSVOPWA_cjs.renderNextTool; }
4944
+ get: function () { return chunkJ6DQEBK2_cjs.renderNextTool; }
4945
+ });
4946
+ Object.defineProperty(exports, "resolveTokenBySymbol", {
4947
+ enumerable: true,
4948
+ get: function () { return chunkJ6DQEBK2_cjs.resolveTokenBySymbol; }
4544
4949
  });
4545
4950
  Object.defineProperty(exports, "resolveTokenFromAddress", {
4546
4951
  enumerable: true,
4547
- get: function () { return chunkQSSVOPWA_cjs.resolveTokenFromAddress; }
4952
+ get: function () { return chunkJ6DQEBK2_cjs.resolveTokenFromAddress; }
4548
4953
  });
4549
4954
  Object.defineProperty(exports, "selectErc7710PaymentOption", {
4550
4955
  enumerable: true,
4551
- get: function () { return chunkQSSVOPWA_cjs.selectErc7710PaymentOption; }
4956
+ get: function () { return chunkJ6DQEBK2_cjs.selectErc7710PaymentOption; }
4552
4957
  });
4553
4958
  Object.defineProperty(exports, "selectPaymentOption", {
4554
4959
  enumerable: true,
4555
- get: function () { return chunkQSSVOPWA_cjs.selectPaymentOption; }
4960
+ get: function () { return chunkJ6DQEBK2_cjs.selectPaymentOption; }
4556
4961
  });
4557
4962
  Object.defineProperty(exports, "selectStandardPaymentOption", {
4558
4963
  enumerable: true,
4559
- get: function () { return chunkQSSVOPWA_cjs.selectStandardPaymentOption; }
4964
+ get: function () { return chunkJ6DQEBK2_cjs.selectStandardPaymentOption; }
4560
4965
  });
4561
4966
  Object.defineProperty(exports, "selectX402SettlementScheme", {
4562
4967
  enumerable: true,
4563
- get: function () { return chunkQSSVOPWA_cjs.selectX402SettlementScheme; }
4968
+ get: function () { return chunkJ6DQEBK2_cjs.selectX402SettlementScheme; }
4564
4969
  });
4565
4970
  Object.defineProperty(exports, "sweepUsdcAddress", {
4566
4971
  enumerable: true,
4567
- get: function () { return chunkQSSVOPWA_cjs.sweepUsdcAddress; }
4972
+ get: function () { return chunkJ6DQEBK2_cjs.sweepUsdcAddress; }
4568
4973
  });
4569
4974
  Object.defineProperty(exports, "sweepUsdcDomain", {
4570
4975
  enumerable: true,
4571
- get: function () { return chunkQSSVOPWA_cjs.sweepUsdcDomain; }
4976
+ get: function () { return chunkJ6DQEBK2_cjs.sweepUsdcDomain; }
4572
4977
  });
4573
4978
  Object.defineProperty(exports, "toStandardPaymentRequirements", {
4574
4979
  enumerable: true,
4575
- get: function () { return chunkQSSVOPWA_cjs.toStandardPaymentRequirements; }
4980
+ get: function () { return chunkJ6DQEBK2_cjs.toStandardPaymentRequirements; }
4576
4981
  });
4577
4982
  Object.defineProperty(exports, "unsupportedNodeVersionMessage", {
4578
4983
  enumerable: true,
4579
- get: function () { return chunkQSSVOPWA_cjs.unsupportedNodeVersionMessage; }
4984
+ get: function () { return chunkJ6DQEBK2_cjs.unsupportedNodeVersionMessage; }
4580
4985
  });
4581
4986
  Object.defineProperty(exports, "validateStandardX402PaymentHeader", {
4582
4987
  enumerable: true,
4583
- get: function () { return chunkQSSVOPWA_cjs.validateStandardX402PaymentHeader; }
4988
+ get: function () { return chunkJ6DQEBK2_cjs.validateStandardX402PaymentHeader; }
4584
4989
  });
4585
4990
  Object.defineProperty(exports, "x402AssetTransferMethod", {
4586
4991
  enumerable: true,
4587
- get: function () { return chunkQSSVOPWA_cjs.x402AssetTransferMethod; }
4992
+ get: function () { return chunkJ6DQEBK2_cjs.x402AssetTransferMethod; }
4588
4993
  });
4589
4994
  Object.defineProperty(exports, "x402AuthorizationAmount", {
4590
4995
  enumerable: true,
4591
- get: function () { return chunkQSSVOPWA_cjs.x402AuthorizationAmount; }
4996
+ get: function () { return chunkJ6DQEBK2_cjs.x402AuthorizationAmount; }
4592
4997
  });
4593
4998
  Object.defineProperty(exports, "x402FacilitatorAddresses", {
4594
4999
  enumerable: true,
4595
- get: function () { return chunkQSSVOPWA_cjs.x402FacilitatorAddresses; }
5000
+ get: function () { return chunkJ6DQEBK2_cjs.x402FacilitatorAddresses; }
4596
5001
  });
4597
5002
  Object.defineProperty(exports, "x402V2PaymentEnvelope", {
4598
5003
  enumerable: true,
4599
- get: function () { return chunkQSSVOPWA_cjs.x402V2PaymentEnvelope; }
5004
+ get: function () { return chunkJ6DQEBK2_cjs.x402V2PaymentEnvelope; }
4600
5005
  });
4601
5006
  Object.defineProperty(exports, "AGENT_PAYMENT_FAILURE_CODE_VALUES", {
4602
5007
  enumerable: true,
4603
- get: function () { return chunkJKUIE45B_cjs.AGENT_PAYMENT_FAILURE_CODE_VALUES; }
5008
+ get: function () { return chunk3SVPI4LS_cjs.AGENT_PAYMENT_FAILURE_CODE_VALUES; }
4604
5009
  });
4605
5010
  Object.defineProperty(exports, "AGENT_PAYMENT_NEXT_ACTION_VALUES", {
4606
5011
  enumerable: true,
4607
- get: function () { return chunkJKUIE45B_cjs.AGENT_PAYMENT_NEXT_ACTION_VALUES; }
5012
+ get: function () { return chunk3SVPI4LS_cjs.AGENT_PAYMENT_NEXT_ACTION_VALUES; }
4608
5013
  });
4609
5014
  Object.defineProperty(exports, "AGENT_PAYMENT_PHASE_VALUES", {
4610
5015
  enumerable: true,
4611
- get: function () { return chunkJKUIE45B_cjs.AGENT_PAYMENT_PHASE_VALUES; }
5016
+ get: function () { return chunk3SVPI4LS_cjs.AGENT_PAYMENT_PHASE_VALUES; }
4612
5017
  });
4613
5018
  Object.defineProperty(exports, "AGENT_PAYMENT_RAIL_VALUES", {
4614
5019
  enumerable: true,
4615
- get: function () { return chunkJKUIE45B_cjs.AGENT_PAYMENT_RAIL_VALUES; }
5020
+ get: function () { return chunk3SVPI4LS_cjs.AGENT_PAYMENT_RAIL_VALUES; }
4616
5021
  });
4617
5022
  Object.defineProperty(exports, "AgentPaymentFailureCode", {
4618
5023
  enumerable: true,
4619
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentFailureCode; }
5024
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentFailureCode; }
4620
5025
  });
4621
5026
  Object.defineProperty(exports, "AgentPaymentFailureCodeDescriptions", {
4622
5027
  enumerable: true,
4623
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentFailureCodeDescriptions; }
5028
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentFailureCodeDescriptions; }
4624
5029
  });
4625
5030
  Object.defineProperty(exports, "AgentPaymentFailureCodeSchema", {
4626
5031
  enumerable: true,
4627
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentFailureCodeSchema; }
5032
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentFailureCodeSchema; }
4628
5033
  });
4629
5034
  Object.defineProperty(exports, "AgentPaymentNextAction", {
4630
5035
  enumerable: true,
4631
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentNextAction; }
5036
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentNextAction; }
4632
5037
  });
4633
5038
  Object.defineProperty(exports, "AgentPaymentNextActionDescriptions", {
4634
5039
  enumerable: true,
4635
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentNextActionDescriptions; }
5040
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentNextActionDescriptions; }
4636
5041
  });
4637
5042
  Object.defineProperty(exports, "AgentPaymentNextActionSchema", {
4638
5043
  enumerable: true,
4639
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentNextActionSchema; }
5044
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentNextActionSchema; }
4640
5045
  });
4641
5046
  Object.defineProperty(exports, "AgentPaymentPhase", {
4642
5047
  enumerable: true,
4643
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentPhase; }
5048
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentPhase; }
4644
5049
  });
4645
5050
  Object.defineProperty(exports, "AgentPaymentPhaseDescriptions", {
4646
5051
  enumerable: true,
4647
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentPhaseDescriptions; }
5052
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentPhaseDescriptions; }
4648
5053
  });
4649
5054
  Object.defineProperty(exports, "AgentPaymentPhaseSchema", {
4650
5055
  enumerable: true,
4651
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentPhaseSchema; }
5056
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentPhaseSchema; }
4652
5057
  });
4653
5058
  Object.defineProperty(exports, "AgentPaymentRail", {
4654
5059
  enumerable: true,
4655
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentRail; }
5060
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentRail; }
4656
5061
  });
4657
5062
  Object.defineProperty(exports, "AgentPaymentRailDescriptions", {
4658
5063
  enumerable: true,
4659
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentRailDescriptions; }
5064
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentRailDescriptions; }
4660
5065
  });
4661
5066
  Object.defineProperty(exports, "AgentPaymentRailSchema", {
4662
5067
  enumerable: true,
4663
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentRailSchema; }
5068
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentRailSchema; }
4664
5069
  });
4665
5070
  Object.defineProperty(exports, "AgentPaymentWarningCode", {
4666
5071
  enumerable: true,
4667
- get: function () { return chunkJKUIE45B_cjs.AgentPaymentWarningCode; }
5072
+ get: function () { return chunk3SVPI4LS_cjs.AgentPaymentWarningCode; }
4668
5073
  });
4669
5074
  Object.defineProperty(exports, "CONNECTOR_PACKAGE_NAME", {
4670
5075
  enumerable: true,
4671
- get: function () { return chunkJKUIE45B_cjs.CONNECTOR_PACKAGE_NAME; }
5076
+ get: function () { return chunk3SVPI4LS_cjs.CONNECTOR_PACKAGE_NAME; }
4672
5077
  });
4673
5078
  Object.defineProperty(exports, "DEFAULT_CONFIRMATION_TIMEOUT_MS", {
4674
5079
  enumerable: true,
4675
- get: function () { return chunkJKUIE45B_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS; }
5080
+ get: function () { return chunk3SVPI4LS_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS; }
4676
5081
  });
4677
5082
  Object.defineProperty(exports, "DIRECT_SIGN_CONTEXT_VERSION", {
4678
5083
  enumerable: true,
4679
- get: function () { return chunkJKUIE45B_cjs.DIRECT_SIGN_CONTEXT_VERSION; }
5084
+ get: function () { return chunk3SVPI4LS_cjs.DIRECT_SIGN_CONTEXT_VERSION; }
4680
5085
  });
4681
5086
  Object.defineProperty(exports, "ENTRY_POINT_V07", {
4682
5087
  enumerable: true,
4683
- get: function () { return chunkJKUIE45B_cjs.ENTRY_POINT_V07; }
5088
+ get: function () { return chunk3SVPI4LS_cjs.ENTRY_POINT_V07; }
4684
5089
  });
4685
5090
  Object.defineProperty(exports, "HAVEN_CONNECTOR_CHANNEL", {
4686
5091
  enumerable: true,
4687
- get: function () { return chunkJKUIE45B_cjs.HAVEN_CONNECTOR_CHANNEL; }
5092
+ get: function () { return chunk3SVPI4LS_cjs.HAVEN_CONNECTOR_CHANNEL; }
4688
5093
  });
4689
5094
  Object.defineProperty(exports, "HYBRID_DELEGATOR_DOMAIN_NAME", {
4690
5095
  enumerable: true,
4691
- get: function () { return chunkJKUIE45B_cjs.HYBRID_DELEGATOR_DOMAIN_NAME; }
5096
+ get: function () { return chunk3SVPI4LS_cjs.HYBRID_DELEGATOR_DOMAIN_NAME; }
4692
5097
  });
4693
5098
  Object.defineProperty(exports, "HYBRID_DELEGATOR_DOMAIN_VERSION", {
4694
5099
  enumerable: true,
4695
- get: function () { return chunkJKUIE45B_cjs.HYBRID_DELEGATOR_DOMAIN_VERSION; }
5100
+ get: function () { return chunk3SVPI4LS_cjs.HYBRID_DELEGATOR_DOMAIN_VERSION; }
4696
5101
  });
4697
5102
  Object.defineProperty(exports, "HavenApiError", {
4698
5103
  enumerable: true,
4699
- get: function () { return chunkJKUIE45B_cjs.HavenApiError; }
5104
+ get: function () { return chunk3SVPI4LS_cjs.HavenApiError; }
4700
5105
  });
4701
5106
  Object.defineProperty(exports, "HavenError", {
4702
5107
  enumerable: true,
4703
- get: function () { return chunkJKUIE45B_cjs.HavenError; }
5108
+ get: function () { return chunk3SVPI4LS_cjs.HavenError; }
4704
5109
  });
4705
5110
  Object.defineProperty(exports, "HavenPaymentStateError", {
4706
5111
  enumerable: true,
4707
- get: function () { return chunkJKUIE45B_cjs.HavenPaymentStateError; }
5112
+ get: function () { return chunk3SVPI4LS_cjs.HavenPaymentStateError; }
4708
5113
  });
4709
5114
  Object.defineProperty(exports, "HavenSigningError", {
4710
5115
  enumerable: true,
4711
- get: function () { return chunkJKUIE45B_cjs.HavenSigningError; }
5116
+ get: function () { return chunk3SVPI4LS_cjs.HavenSigningError; }
4712
5117
  });
4713
5118
  Object.defineProperty(exports, "HavenTimeoutError", {
4714
5119
  enumerable: true,
4715
- get: function () { return chunkJKUIE45B_cjs.HavenTimeoutError; }
5120
+ get: function () { return chunk3SVPI4LS_cjs.HavenTimeoutError; }
4716
5121
  });
4717
5122
  Object.defineProperty(exports, "HavenUnsupportedSignerVersionError", {
4718
5123
  enumerable: true,
4719
- get: function () { return chunkJKUIE45B_cjs.HavenUnsupportedSignerVersionError; }
5124
+ get: function () { return chunk3SVPI4LS_cjs.HavenUnsupportedSignerVersionError; }
4720
5125
  });
4721
5126
  Object.defineProperty(exports, "HavenUserOpBindingError", {
4722
5127
  enumerable: true,
4723
- get: function () { return chunkJKUIE45B_cjs.HavenUserOpBindingError; }
5128
+ get: function () { return chunk3SVPI4LS_cjs.HavenUserOpBindingError; }
4724
5129
  });
4725
5130
  Object.defineProperty(exports, "HavenZeroSettlementHashError", {
4726
5131
  enumerable: true,
4727
- get: function () { return chunkJKUIE45B_cjs.HavenZeroSettlementHashError; }
5132
+ get: function () { return chunk3SVPI4LS_cjs.HavenZeroSettlementHashError; }
4728
5133
  });
4729
5134
  Object.defineProperty(exports, "MerchantTimeoutError", {
4730
5135
  enumerable: true,
4731
- get: function () { return chunkJKUIE45B_cjs.MerchantTimeoutError; }
5136
+ get: function () { return chunk3SVPI4LS_cjs.MerchantTimeoutError; }
4732
5137
  });
4733
5138
  Object.defineProperty(exports, "PACKED_USER_OPERATION_FIELDS", {
4734
5139
  enumerable: true,
4735
- get: function () { return chunkJKUIE45B_cjs.PACKED_USER_OPERATION_FIELDS; }
5140
+ get: function () { return chunk3SVPI4LS_cjs.PACKED_USER_OPERATION_FIELDS; }
4736
5141
  });
4737
5142
  Object.defineProperty(exports, "ROOT_AUTHORITY", {
4738
5143
  enumerable: true,
4739
- get: function () { return chunkJKUIE45B_cjs.ROOT_AUTHORITY; }
5144
+ get: function () { return chunk3SVPI4LS_cjs.ROOT_AUTHORITY; }
4740
5145
  });
4741
5146
  Object.defineProperty(exports, "SIGNER_UPDATE_FALLBACK", {
4742
5147
  enumerable: true,
4743
- get: function () { return chunkJKUIE45B_cjs.SIGNER_UPDATE_FALLBACK; }
5148
+ get: function () { return chunk3SVPI4LS_cjs.SIGNER_UPDATE_FALLBACK; }
4744
5149
  });
4745
5150
  Object.defineProperty(exports, "SignerRefusalCode", {
4746
5151
  enumerable: true,
4747
- get: function () { return chunkJKUIE45B_cjs.SignerRefusalCode; }
5152
+ get: function () { return chunk3SVPI4LS_cjs.SignerRefusalCode; }
5153
+ });
5154
+ Object.defineProperty(exports, "TASK_SIGN_CONTEXT_VERSION", {
5155
+ enumerable: true,
5156
+ get: function () { return chunk3SVPI4LS_cjs.TASK_SIGN_CONTEXT_VERSION; }
4748
5157
  });
4749
5158
  Object.defineProperty(exports, "X402AlreadySettledError", {
4750
5159
  enumerable: true,
4751
- get: function () { return chunkJKUIE45B_cjs.X402AlreadySettledError; }
5160
+ get: function () { return chunk3SVPI4LS_cjs.X402AlreadySettledError; }
5161
+ });
5162
+ Object.defineProperty(exports, "X402Erc7710AlreadySettledError", {
5163
+ enumerable: true,
5164
+ get: function () { return chunk3SVPI4LS_cjs.X402Erc7710AlreadySettledError; }
5165
+ });
5166
+ Object.defineProperty(exports, "X402TaskBudgetMismatchError", {
5167
+ enumerable: true,
5168
+ get: function () { return chunk3SVPI4LS_cjs.X402TaskBudgetMismatchError; }
4752
5169
  });
4753
5170
  Object.defineProperty(exports, "X402UnexpectedStatusError", {
4754
5171
  enumerable: true,
4755
- get: function () { return chunkJKUIE45B_cjs.X402UnexpectedStatusError; }
5172
+ get: function () { return chunk3SVPI4LS_cjs.X402UnexpectedStatusError; }
4756
5173
  });
4757
5174
  Object.defineProperty(exports, "assertUserOpTypedDataBinding", {
4758
5175
  enumerable: true,
4759
- get: function () { return chunkJKUIE45B_cjs.assertUserOpTypedDataBinding; }
5176
+ get: function () { return chunk3SVPI4LS_cjs.assertUserOpTypedDataBinding; }
4760
5177
  });
4761
5178
  Object.defineProperty(exports, "connectorRerunCommand", {
4762
5179
  enumerable: true,
4763
- get: function () { return chunkJKUIE45B_cjs.connectorRerunCommand; }
5180
+ get: function () { return chunk3SVPI4LS_cjs.connectorRerunCommand; }
4764
5181
  });
4765
5182
  Object.defineProperty(exports, "connectorSpec", {
4766
5183
  enumerable: true,
4767
- get: function () { return chunkJKUIE45B_cjs.connectorSpec; }
5184
+ get: function () { return chunk3SVPI4LS_cjs.connectorSpec; }
5185
+ });
5186
+ Object.defineProperty(exports, "connectorUpgradeCommand", {
5187
+ enumerable: true,
5188
+ get: function () { return chunk3SVPI4LS_cjs.connectorUpgradeCommand; }
4768
5189
  });
4769
5190
  Object.defineProperty(exports, "deriveDelegateAccountAddress", {
4770
5191
  enumerable: true,
4771
- get: function () { return chunkJKUIE45B_cjs.deriveDelegateAccountAddress; }
5192
+ get: function () { return chunk3SVPI4LS_cjs.deriveDelegateAccountAddress; }
4772
5193
  });
4773
5194
  Object.defineProperty(exports, "isConnectorChannel", {
4774
5195
  enumerable: true,
4775
- get: function () { return chunkJKUIE45B_cjs.isConnectorChannel; }
5196
+ get: function () { return chunk3SVPI4LS_cjs.isConnectorChannel; }
4776
5197
  });
4777
5198
  Object.defineProperty(exports, "isPackedUserOperationTypedData", {
4778
5199
  enumerable: true,
4779
- get: function () { return chunkJKUIE45B_cjs.isPackedUserOperationTypedData; }
5200
+ get: function () { return chunk3SVPI4LS_cjs.isPackedUserOperationTypedData; }
4780
5201
  });
4781
5202
  Object.defineProperty(exports, "packedUserOperationHash", {
4782
5203
  enumerable: true,
4783
- get: function () { return chunkJKUIE45B_cjs.packedUserOperationHash; }
5204
+ get: function () { return chunk3SVPI4LS_cjs.packedUserOperationHash; }
4784
5205
  });
4785
5206
  Object.defineProperty(exports, "resolveConnectorChannel", {
4786
5207
  enumerable: true,
4787
- get: function () { return chunkJKUIE45B_cjs.resolveConnectorChannel; }
5208
+ get: function () { return chunk3SVPI4LS_cjs.resolveConnectorChannel; }
4788
5209
  });
4789
5210
  Object.defineProperty(exports, "signerUpdateFallback", {
4790
5211
  enumerable: true,
4791
- get: function () { return chunkJKUIE45B_cjs.signerUpdateFallback; }
5212
+ get: function () { return chunk3SVPI4LS_cjs.signerUpdateFallback; }
4792
5213
  });
4793
5214
  Object.defineProperty(exports, "verifySettlementChild", {
4794
5215
  enumerable: true,
4795
- get: function () { return chunkJKUIE45B_cjs.verifySettlementChild; }
5216
+ get: function () { return chunk3SVPI4LS_cjs.verifySettlementChild; }
4796
5217
  });
4797
5218
  exports.AGENT_APPROVAL_RELAY_JSON_SENTENCE = AGENT_APPROVAL_RELAY_JSON_SENTENCE;
4798
5219
  exports.AGENT_APPROVAL_RELAY_PROSE_SENTENCE = AGENT_APPROVAL_RELAY_PROSE_SENTENCE;
@@ -4818,6 +5239,7 @@ exports.addressFromKey = addressFromKey;
4818
5239
  exports.assertSecureX402RetryTarget = assertSecureX402RetryTarget;
4819
5240
  exports.composeDescription = composeDescription;
4820
5241
  exports.discoverMerchantMcpUrl = discoverMerchantMcpUrl;
5242
+ exports.formatTokenAmount = formatTokenAmount;
4821
5243
  exports.havenTools = havenTools;
4822
5244
  exports.isSecureX402RetryTarget = isSecureX402RetryTarget;
4823
5245
  exports.isZeroSettlementTxHash = isZeroSettlementTxHash;