@haven_ai/sdk 0.1.30-alpha.0 → 0.1.32-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
@@ -18,33 +18,40 @@ var AgentPaymentPhase = {
18
18
  PaymentSubmitted: "payment_submitted",
19
19
  /** The direct payment is confirmed; the agent does not need to do more for this payment id. */
20
20
  PaymentConfirmed: "payment_confirmed",
21
- /** The payment needs wallet owner approval in Haven before it can continue. */
21
+ /**
22
+ * #2115: RETIRED wire value — no live rail produces it. It described the
23
+ * Safe rail's approval queue, which no longer exists. Kept so a stored value
24
+ * still typechecks; see `AgentPaymentPhaseDescriptions` below for the
25
+ * agent-visible wording, which this comment used to contradict.
26
+ */
22
27
  UserApprovalRequired: "user_approval_required",
23
- /** The wallet owner approved the request and still needs to complete the funding payment. */
28
+ /** #2115: RETIRED wire value no live rail produces it. Stop and tell the user. */
24
29
  UserExecutionRequired: "user_execution_required",
25
- /** The funding payment was proposed and is waiting for the remaining account approvals. */
30
+ /** #2115: RETIRED wire value no live rail produces it. Stop and tell the user. */
26
31
  WaitingForAdditionalApprovals: "waiting_for_additional_approvals",
27
32
  /** The Haven funding leg was sent; the agent can continue the merchant/protocol leg. */
28
33
  FundingSent: "funding_sent",
29
- /** The wallet owner rejected the request; the agent should stop and tell the user. */
34
+ /** The payment was rejected and cannot proceed; the agent should stop and tell the user. */
30
35
  Rejected: "rejected",
31
- /** The payment or approval request expired before completion. */
36
+ /** The payment expired before completion. */
32
37
  Expired: "expired",
33
38
  /** Haven could not complete the payment; the agent should stop and surface the failure. */
34
39
  Failed: "failed",
35
40
  /**
36
41
  * Pre-flight check determined the delegate's existing balance plus the
37
- * remaining on-chain allowance cannot cover the requested amount, so no
38
- * payment intent was created. Distinct from `UserApprovalRequired`: there
39
- * is no approval that would fix this — the originating Safe needs more
40
- * funds or the agent's per-token allowance needs to be raised first.
42
+ * remaining on-chain budget cannot cover the requested amount, so no
43
+ * payment intent was created. The account must be funded or the agent's
44
+ * budget raised before retrying #2115: the old wording contrasted this
45
+ * with `UserApprovalRequired` as if that were a live alternative, and named
46
+ * the retired rail's Safe and per-token allowance as the fix.
41
47
  */
42
48
  InsufficientFunds: "insufficient_funds",
43
49
  /**
44
- * Haven's funding leg (Safe → delegate) confirmed on-chain, but the
45
- * merchant rejected the x402 retry. The delegate wallet may hold stranded
46
- * USDC that was never settled to the merchant. The agent should stop, tell
47
- * the user, and wait for the sweep flow to reclaim the funds.
50
+ * Haven's funding leg (account → delegate, the #946 EIP-3009 bridge)
51
+ * confirmed on-chain, but the merchant rejected the x402 retry. The delegate
52
+ * wallet may hold stranded USDC that was never settled to the merchant. The
53
+ * agent should stop, tell the user, and wait for the sweep flow to reclaim
54
+ * the funds.
48
55
  */
49
56
  FundedButUnsettled: "funded_but_unsettled"
50
57
  };
@@ -55,9 +62,12 @@ var AgentPaymentNextAction = {
55
62
  CheckStatusLater: "check_status_later",
56
63
  /** No further agent action is required for this payment id. */
57
64
  None: "none",
58
- /** Wait for the wallet owner to approve or reject the request in Haven. */
65
+ /**
66
+ * #2115: RETIRED wire value — no live rail produces it and nothing maps to
67
+ * it. Stop and tell the user rather than polling; no approval will arrive.
68
+ */
59
69
  WaitForUserApproval: "wait_for_user_approval",
60
- /** Wait for the wallet owner to finish sending the approved funding payment. */
70
+ /** #2115: RETIRED wire value no live rail produces it. Stop and tell the user rather than polling. */
61
71
  WaitForUserToCompletePayment: "wait_for_user_to_complete_payment",
62
72
  /** Resume this payment id and retry the original x402 request with the merchant payment header. */
63
73
  RetryOriginalX402Request: "retry_original_x402_request",
@@ -147,29 +157,29 @@ var AgentPaymentPhaseDescriptions = {
147
157
  [AgentPaymentPhase.AgentSignatureRequired]: "The agent must sign and submit the prepared payment before Haven can relay it.",
148
158
  [AgentPaymentPhase.PaymentSubmitted]: "Haven has received the signed payment and the agent should poll for confirmation.",
149
159
  [AgentPaymentPhase.PaymentConfirmed]: "The direct payment is confirmed; the agent does not need to do more for this payment id.",
150
- [AgentPaymentPhase.UserApprovalRequired]: "The payment needs wallet owner approval in Haven before it can continue.",
151
- [AgentPaymentPhase.UserExecutionRequired]: "The wallet owner approved the request and still needs to complete the funding payment.",
152
- [AgentPaymentPhase.WaitingForAdditionalApprovals]: "The funding payment was proposed and is waiting for the remaining account approvals.",
160
+ [AgentPaymentPhase.UserApprovalRequired]: "Retired wire value: no live rail produces it. It described the Safe rail's approval queue, which no longer exists \u2014 an out-of-policy payment is declined before any money moves. If it is ever seen, stop and tell the user; no approval is pending.",
161
+ [AgentPaymentPhase.UserExecutionRequired]: "Retired wire value: no live rail produces it. Stop and tell the user.",
162
+ [AgentPaymentPhase.WaitingForAdditionalApprovals]: "Retired wire value: no live rail produces it. Stop and tell the user.",
153
163
  [AgentPaymentPhase.FundingSent]: "The Haven funding leg was sent; the agent can continue the merchant/protocol leg.",
154
- [AgentPaymentPhase.Rejected]: "The wallet owner rejected the request; the agent should stop and tell the user.",
155
- [AgentPaymentPhase.Expired]: "The payment or approval request expired before completion.",
164
+ [AgentPaymentPhase.Rejected]: "The payment was rejected and cannot proceed; the agent should stop and tell the user.",
165
+ [AgentPaymentPhase.Expired]: "The payment expired before completion.",
156
166
  [AgentPaymentPhase.Failed]: "Haven could not complete the payment; the agent should stop and surface the failure.",
157
- [AgentPaymentPhase.InsufficientFunds]: "Pre-flight check determined the delegate balance plus the remaining on-chain allowance cannot cover the requested amount, so no payment was created. The originating Safe must be funded or the agent allowance raised before retrying.",
158
- [AgentPaymentPhase.FundedButUnsettled]: "Haven's funding leg confirmed on-chain but the merchant rejected the x402 retry. The delegate wallet may hold stranded funds. The agent should stop and wait for the wallet owner to sweep the stranded funds back to the Safe."
167
+ [AgentPaymentPhase.InsufficientFunds]: "Pre-flight check determined the delegate balance plus the remaining on-chain budget cannot cover the requested amount, so no payment was created. The account must be funded or the agent budget raised before retrying.",
168
+ [AgentPaymentPhase.FundedButUnsettled]: "Haven's funding leg confirmed on-chain but the merchant rejected the x402 retry. The delegate wallet may hold stranded funds. The agent should stop and wait for the wallet owner to sweep the stranded funds back to the account."
159
169
  };
160
170
  var AgentPaymentNextActionDescriptions = {
161
171
  [AgentPaymentNextAction.SignAndSubmitPayment]: "Sign with the delegate key and submit the payment to Haven.",
162
172
  [AgentPaymentNextAction.CheckStatusLater]: "Poll getPaymentStatus later using this payment id.",
163
173
  [AgentPaymentNextAction.None]: "No further agent action is required for this payment id.",
164
- [AgentPaymentNextAction.WaitForUserApproval]: "Wait for the wallet owner to approve or reject the request in Haven.",
165
- [AgentPaymentNextAction.WaitForUserToCompletePayment]: "Wait for the wallet owner to finish sending the approved funding payment.",
174
+ [AgentPaymentNextAction.WaitForUserApproval]: "Retired wire value: no live rail produces it, and nothing maps to it. It described a per-payment approval queue that no longer exists. If it is ever seen, stop and tell the user rather than polling \u2014 no approval will arrive.",
175
+ [AgentPaymentNextAction.WaitForUserToCompletePayment]: "Retired wire value: no live rail produces it. Stop and tell the user rather than polling.",
166
176
  [AgentPaymentNextAction.RetryOriginalX402Request]: "Resume this payment id and retry the original x402 request with the merchant payment header.",
167
177
  [AgentPaymentNextAction.StopAndTellUser]: "Stop retrying this payment and tell the user what happened.",
168
178
  [AgentPaymentNextAction.RequestAgainIfUserStillWantsIt]: "Ask again only if the user still wants the payment after expiry.",
169
179
  [AgentPaymentNextAction.PaymentWindowExpired]: "The x402 funding/quote window expired. Re-quote with the same idempotency key before asking the signer to build a merchant payment header again.",
170
- [AgentPaymentNextAction.FundSafeOrRaiseAllowance]: "Stop and tell the user that the originating Safe needs to be funded or the agent allowance raised before the payment can succeed.",
180
+ [AgentPaymentNextAction.FundSafeOrRaiseAllowance]: "Stop and tell the user that the account needs to be funded or the agent budget raised before the payment can succeed.",
171
181
  [AgentPaymentNextAction.RetryWithExplicitContext]: "Retry the same tool call, this time passing merchant_url, tool_name, arguments, and mcp_transport explicitly \u2014 the server had no stored context to rehydrate for this payment id.",
172
- [AgentPaymentNextAction.SweepStrandedFunds]: "Tell the user that funds may be stranded in the delegate wallet and prompt them to initiate a sweep in Haven to return them to the originating Safe."
182
+ [AgentPaymentNextAction.SweepStrandedFunds]: "Tell the user that funds may be stranded in the delegate wallet and prompt them to initiate a sweep in Haven to return them to the originating account."
173
183
  };
174
184
  var AgentPaymentFailureCodeDescriptions = {
175
185
  [AgentPaymentFailureCode.PriceExceedsMax]: "The merchant-authoritative x402 amount exceeds the caller's max_amount cap. No funding transfer was created; ask the user before retrying with a larger cap.",
@@ -212,7 +222,7 @@ var AgentPaymentWarningCode = {
212
222
  AllowanceReadOptimistic: "ALLOWANCE_READ_OPTIMISTIC"
213
223
  };
214
224
  var AgentPaymentRailDescriptions = {
215
- [AgentPaymentRail.Direct]: "Standard Haven payment from the user-controlled Safe through an approved delegate allowance.",
225
+ [AgentPaymentRail.Direct]: "Standard Haven payment from the user-controlled account, redeeming the agent's on-chain budget delegation.",
216
226
  [AgentPaymentRail.X402]: "x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg.",
217
227
  [AgentPaymentRail.Mpp]: "Categorical MPP rail value used as a resume-state discriminator. Response bodies carry a granular mpp_* value instead.",
218
228
  [AgentPaymentRail.MppDemo]: "Haven internal MPP demo rail. Not for production traffic.",
@@ -1146,10 +1156,10 @@ function nextActionForStatus(status) {
1146
1156
  if (status === "pending_signature") return AgentPaymentNextAction.SignAndSubmitPayment;
1147
1157
  if (status === "submitted") return AgentPaymentNextAction.CheckStatusLater;
1148
1158
  if (status === "confirmed") return AgentPaymentNextAction.None;
1149
- if (status === "pending" || status === "pending_approval") return AgentPaymentNextAction.WaitForUserApproval;
1159
+ if (status === "pending" || status === "pending_approval") return AgentPaymentNextAction.StopAndTellUser;
1150
1160
  if (status === "approved") return AgentPaymentNextAction.WaitForUserToCompletePayment;
1151
- if (status === "proposed") return AgentPaymentNextAction.WaitForUserApproval;
1152
- if (status === "executed") return AgentPaymentNextAction.RetryOriginalX402Request;
1161
+ if (status === "proposed") return AgentPaymentNextAction.StopAndTellUser;
1162
+ if (status === "executed") return AgentPaymentNextAction.StopAndTellUser;
1153
1163
  if (status === "rejected") return AgentPaymentNextAction.StopAndTellUser;
1154
1164
  if (status === "expired") return AgentPaymentNextAction.RequestAgainIfUserStillWantsIt;
1155
1165
  if (status === "failed") return AgentPaymentNextAction.StopAndTellUser;
@@ -1157,10 +1167,10 @@ function nextActionForStatus(status) {
1157
1167
  }
1158
1168
  function messageForState(label, status, paymentId, nextAction) {
1159
1169
  if (status === "pending" || status === "pending_approval") {
1160
- return `${label} is above the remaining agent budget and is waiting for user approval in Haven (payment_id: ${paymentId}).`;
1170
+ return `${label} is not payable: it is outside the agent's on-chain budget and no approval is pending (payment_id: ${paymentId}). Ask the user to grant or raise the budget in Haven.`;
1161
1171
  }
1162
1172
  if (status === "executed") {
1163
- return "The user completed the funding payment. Retry the original x402 request.";
1173
+ return `This payment carries a retired status ("executed") that no live Haven rail produces (payment_id: ${paymentId}). Do not retry it \u2014 tell the user to review this payment in Haven.`;
1164
1174
  }
1165
1175
  if (status === "rejected") {
1166
1176
  return `The user rejected this payment request (payment_id: ${paymentId}).`;
@@ -1227,7 +1237,7 @@ function throwPaymentStateError(label, raw) {
1227
1237
  }
1228
1238
  if (raw.status === "pending_approval") {
1229
1239
  throw new HavenApiError(
1230
- `${label} exceeds the on-chain allowance and was queued for owner approval (payment_id: ${raw.payment_id}).`,
1240
+ `${label} exceeds the agent's on-chain budget and was declined; no approval is pending and none will arrive (payment_id: ${raw.payment_id}).`,
1231
1241
  statusCode,
1232
1242
  raw
1233
1243
  );
@@ -1771,13 +1781,18 @@ function requestInitFromSnapshot(request) {
1771
1781
  body: request.body
1772
1782
  };
1773
1783
  }
1784
+ function noCompatiblePaymentOptionError(accepts) {
1785
+ const erc7710Only = selectErc7710PaymentOption(accepts) !== null;
1786
+ return new HavenApiError(
1787
+ "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)." : ""),
1788
+ 400
1789
+ );
1790
+ }
1774
1791
  function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport) {
1775
- const option = selectStandardPaymentOption(paymentRequired.accepts);
1792
+ const standard = selectStandardPaymentOption(paymentRequired.accepts);
1793
+ const option = standard ?? selectErc7710PaymentOption(paymentRequired.accepts);
1776
1794
  if (!option) {
1777
- throw new HavenApiError(
1778
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
1779
- 400
1780
- );
1795
+ throw noCompatiblePaymentOptionError(paymentRequired.accepts);
1781
1796
  }
1782
1797
  const token = resolveTokenFromAddress(option.asset, option.network);
1783
1798
  return {
@@ -1785,6 +1800,7 @@ function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport)
1785
1800
  idempotencyKey: idempotencyKey ?? buildX402IdempotencyKey(paymentRequired, option),
1786
1801
  paymentRequired,
1787
1802
  accepted: option,
1803
+ acceptedScheme: standard ? "standard" : "erc7710",
1788
1804
  request,
1789
1805
  ...mcpTransport ? { mcpTransport } : {},
1790
1806
  resourceUrl: paymentRequired.resource.url,
@@ -2278,6 +2294,9 @@ var X402Erc7710 = class {
2278
2294
  // becomes a loud mismatch instead of a silent reroute to the 3009 leg.
2279
2295
  payTo: merchantPayTo,
2280
2296
  settlementScheme: "erc7710",
2297
+ // #2041: sent only when the caller supplied one, so an omitting caller's
2298
+ // request body is byte-identical to the pre-#2041 shape.
2299
+ ...options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {},
2281
2300
  amount: amountAtomic,
2282
2301
  asset: option.asset,
2283
2302
  network: option.network,
@@ -2439,6 +2458,8 @@ function toolError(err) {
2439
2458
 
2440
2459
  // src/merchant-completion.ts
2441
2460
  var MERCHANT_BODY_SNIPPET_LIMIT = 1e3;
2461
+ var EVIDENCE_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
2462
+ var EVIDENCE_RETRYABLE_STATUS = 503;
2442
2463
  var MerchantCompletion = class {
2443
2464
  post;
2444
2465
  merchantTransport;
@@ -2446,7 +2467,9 @@ var MerchantCompletion = class {
2446
2467
  getAgent;
2447
2468
  delegateAddress;
2448
2469
  x402Wallet;
2470
+ sleep;
2449
2471
  constructor(options) {
2472
+ this.sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
2450
2473
  this.post = options.post;
2451
2474
  this.merchantTransport = options.merchantTransport;
2452
2475
  this.getPaymentStatus = options.getPaymentStatus;
@@ -2620,22 +2643,29 @@ var MerchantCompletion = class {
2620
2643
  }
2621
2644
  }
2622
2645
  async reportEvidence(input) {
2623
- try {
2624
- await this.post("/machine-payments/evidence", {
2625
- paymentId: input.paymentId,
2626
- rail: input.rail,
2627
- txHash: input.txHash,
2628
- resourceUrl: input.resourceUrl,
2629
- merchantStatus: input.merchantStatus,
2630
- challengePayload: input.challengePayload,
2631
- selectedPayment: input.selectedPayment,
2632
- paymentProofHeaderName: input.paymentProofHeaderName,
2633
- paymentProofHeader: input.paymentProofHeader,
2634
- protocolReceiptHeaderName: input.protocolReceiptHeaderName,
2635
- protocolReceiptHeader: input.protocolReceiptHeader,
2636
- protocolReceiptPayload: input.protocolReceiptHeader ? parseProtocolReceiptHeader(input.protocolReceiptHeader) : void 0
2637
- });
2638
- } catch {
2646
+ const body = {
2647
+ paymentId: input.paymentId,
2648
+ rail: input.rail,
2649
+ txHash: input.txHash,
2650
+ resourceUrl: input.resourceUrl,
2651
+ merchantStatus: input.merchantStatus,
2652
+ challengePayload: input.challengePayload,
2653
+ selectedPayment: input.selectedPayment,
2654
+ paymentProofHeaderName: input.paymentProofHeaderName,
2655
+ paymentProofHeader: input.paymentProofHeader,
2656
+ protocolReceiptHeaderName: input.protocolReceiptHeaderName,
2657
+ protocolReceiptHeader: input.protocolReceiptHeader,
2658
+ protocolReceiptPayload: input.protocolReceiptHeader ? parseProtocolReceiptHeader(input.protocolReceiptHeader) : void 0
2659
+ };
2660
+ for (let attempt = 0; ; attempt += 1) {
2661
+ try {
2662
+ await this.post("/machine-payments/evidence", body);
2663
+ return;
2664
+ } catch (err) {
2665
+ const retryable = err instanceof HavenApiError && err.statusCode === EVIDENCE_RETRYABLE_STATUS;
2666
+ if (!retryable || attempt >= EVIDENCE_RETRY_DELAYS_MS.length) return;
2667
+ await this.sleep(EVIDENCE_RETRY_DELAYS_MS[attempt]);
2668
+ }
2639
2669
  }
2640
2670
  }
2641
2671
  };
@@ -2685,7 +2715,10 @@ function mapCatalogEntry(entry) {
2685
2715
  asset: entry.asset,
2686
2716
  network: entry.network,
2687
2717
  status: entry.status,
2688
- verifiedAt: entry.verified_at
2718
+ verifiedAt: entry.verified_at,
2719
+ source: entry.source,
2720
+ domainVerified: entry.domain_verified,
2721
+ verifiedPayable: entry.verified_payable
2689
2722
  };
2690
2723
  }
2691
2724
  var HavenClient = class {
@@ -2842,10 +2875,7 @@ var HavenClient = class {
2842
2875
  async createX402Intent(paymentRequired, options = {}) {
2843
2876
  const option = selectStandardPaymentOption(paymentRequired.accepts);
2844
2877
  if (!option) {
2845
- throw new HavenApiError(
2846
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
2847
- 400
2848
- );
2878
+ throw noCompatiblePaymentOptionError(paymentRequired.accepts);
2849
2879
  }
2850
2880
  const fundingTo = options.delegateAddress ?? (await this.getAgent()).delegateAddress;
2851
2881
  if (!fundingTo) {
@@ -3121,7 +3151,7 @@ var HavenClient = class {
3121
3151
  return status;
3122
3152
  }
3123
3153
  /**
3124
- * Discover payable services from Haven's curated merchant catalog.
3154
+ * Discover payable services from Haven's merchant catalog (epic #1717).
3125
3155
  *
3126
3156
  * Read-only: returns catalog entries (price, rail, protocol) so an agent
3127
3157
  * can choose a service and pay it with the regular payment tools in the
@@ -3134,7 +3164,39 @@ var HavenClient = class {
3134
3164
  if (options.rail) params.set("rail", options.rail);
3135
3165
  const query = params.size > 0 ? `?${params.toString()}` : "";
3136
3166
  const raw = await this.get(`/catalog${query}`);
3137
- return raw.entries.map(mapCatalogEntry);
3167
+ let entries = raw.entries.map(mapCatalogEntry);
3168
+ if (options.verified === "verified") entries = entries.filter((e) => e.source === "ingestion");
3169
+ if (options.verified === "operator") entries = entries.filter((e) => e.source === "operator");
3170
+ return entries;
3171
+ }
3172
+ /**
3173
+ * Submit a merchant's payable (x402/MCP) endpoint to the Verified Payable
3174
+ * Directory (epic #1717, #1716). Queue-only: writes a submission row and
3175
+ * returns the id + verify_token. The request path makes no outbound
3176
+ * request; domain-ownership proof and the read-only quote probe run later
3177
+ * on the leader-locked monitor. Ownership proof is ALWAYS required before
3178
+ * any listing — this method cannot skip it. `website` is a honeypot field
3179
+ * that bots fill; leave it unset.
3180
+ */
3181
+ async submitCatalogEntry(resourceUrl, options = {}) {
3182
+ const accepted = await this.post("/catalog/submit", {
3183
+ resource_url: resourceUrl,
3184
+ ...options.website ? { website: options.website } : {}
3185
+ });
3186
+ return {
3187
+ id: accepted.id,
3188
+ verifyToken: accepted.verify_token,
3189
+ status: accepted.status
3190
+ };
3191
+ }
3192
+ /**
3193
+ * Fetch one submission's coarse status by id (epic #1717, #1716). Public
3194
+ * and read-only. While the submission can still prove ownership the
3195
+ * response carries the exact well-known / DNS-TXT `instructions`; the
3196
+ * verify token is never returned here.
3197
+ */
3198
+ async getCatalogSubmissionStatus(id) {
3199
+ return this.get(`/catalog/submit/${encodeURIComponent(id)}`);
3138
3200
  }
3139
3201
  /**
3140
3202
  * Fetch one curated catalog entry by id (#1306).
@@ -3209,10 +3271,7 @@ var HavenClient = class {
3209
3271
  }
3210
3272
  const option = selectStandardPaymentOption(paymentRequired.accepts);
3211
3273
  if (!option) {
3212
- throw new HavenApiError(
3213
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
3214
- 400
3215
- );
3274
+ throw noCompatiblePaymentOptionError(paymentRequired.accepts);
3216
3275
  }
3217
3276
  const idempotencyKey = options.idempotencyKey ?? buildX402IdempotencyKey(paymentRequired, option);
3218
3277
  const cached = this.fundingLeg.cachedReceipt(idempotencyKey);
@@ -3352,10 +3411,7 @@ var HavenClient = class {
3352
3411
  }
3353
3412
  const option = selectStandardPaymentOption(input.paymentRequired.accepts);
3354
3413
  if (!option) {
3355
- throw new HavenApiError(
3356
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
3357
- 400
3358
- );
3414
+ throw noCompatiblePaymentOptionError(input.paymentRequired.accepts);
3359
3415
  }
3360
3416
  const idempotencyKey = input.idempotencyKey ?? buildX402IdempotencyKey(input.paymentRequired, option);
3361
3417
  const cached = this.fundingLeg.cachedReceipt(idempotencyKey);
@@ -3555,11 +3611,12 @@ var HavenClient = class {
3555
3611
  });
3556
3612
  }
3557
3613
  } else {
3558
- if (!input.noFundingLeg && fundingTxHash) {
3614
+ const evidenceTxHash = input.noFundingLeg ? settlement.settlementTxHash ?? void 0 : fundingTxHash ?? void 0;
3615
+ if (evidenceTxHash) {
3559
3616
  await this.merchantCompletion.reportEvidence({
3560
3617
  paymentId: evidenceContext.paymentId,
3561
3618
  rail: "x402",
3562
- txHash: fundingTxHash,
3619
+ txHash: evidenceTxHash,
3563
3620
  resourceUrl: evidenceContext.resourceUrl,
3564
3621
  merchantStatus: surfaced.status,
3565
3622
  paymentProofHeaderName: "X-PAYMENT",
@@ -3732,19 +3789,19 @@ var toolDescriptions = {
3732
3789
  payX402: {
3733
3790
  summary: "Pay an inspected x402 quote. The delegate key signs locally; Haven only validates and relays signed, on-chain-constrained payment transactions.",
3734
3791
  selectionGuidance: "Do not use this for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.",
3735
- behavior: "Signs the EIP-3009 payment from the delegate wallet, asks Haven for a Safe AllowanceModule top-up if needed, and returns the merchant response or a pending-approval state.",
3736
- nextActionGuidance: "If approval is needed, preserve the returned resume_state and wait for nextAction=retry_original_x402_request before resuming. If the response carries phase=insufficient_funds and nextAction=fund_safe_or_raise_allowance, the payment cannot be retried until the originating Safe is funded or the agent allowance raised \u2014 stop and tell the user the shortfall reported on the response."
3792
+ behavior: "Signs the payment locally and returns the merchant response. Settlement is either direct account-to-merchant with no funding leg, or a bridge that first redeems the agent's budget delegation to fund the delegate wallet for an EIP-3009 authorization. A payment outside the on-chain budget is declined before any money moves; nothing is queued for a human to approve later.",
3793
+ nextActionGuidance: "Preserve the returned resume_state \u2014 it identifies this payment if you need to ask about it later. This tool performs the merchant retry itself, so do not wait on a signal while the call is in flight. If the process crashes after this call and a later haven_get_payment_status reports nextAction=retry_original_x402_request, Haven's funding leg confirmed but no merchant response was ever recorded \u2014 call the resume tool with the preserved resume_state or payment_id instead of paying again. If the response carries phase=insufficient_funds and nextAction=fund_safe_or_raise_allowance, the payment cannot be retried until the account is funded or the agent budget raised \u2014 stop and tell the user the shortfall reported on the response."
3737
3794
  },
3738
3795
  payX402OneShot: {
3739
3796
  summary: "Fetch an x402 paid HTTP resource in a single call. Handles the full probe -> pay -> retry round trip and returns the merchant response.",
3740
3797
  selectionGuidance: "Prefer this over the quote+pay split when the agent just wants the paid resource and does not need to inspect the price first. If you already have a quote from haven_quote_x402, use haven_pay_x402_quote instead. Do not use for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.",
3741
- behavior: "Calls the URL, parses any HTTP 402 x402 challenge, signs the EIP-3009 payment from the delegate wallet, asks Haven for a Safe AllowanceModule top-up if needed, then retries the original request with the X-PAYMENT header and returns the merchant response. If the resource returns a non-402 status, returns it unchanged without contacting Haven.",
3742
- nextActionGuidance: "If approval is needed, preserve the returned resume_state or paymentId and call the resume tool once nextAction=retry_original_x402_request. If the response carries phase=insufficient_funds and nextAction=fund_safe_or_raise_allowance, the payment cannot be retried until the originating Safe is funded or the agent allowance raised \u2014 stop and tell the user the shortfall reported on the response."
3798
+ behavior: "Calls the URL, parses any HTTP 402 x402 challenge, signs the payment locally, then retries the original request with the X-PAYMENT header and returns the merchant response. Settlement is either direct account-to-merchant with no funding leg, or a bridge that first redeems the agent's budget delegation to fund the delegate wallet for an EIP-3009 authorization. A payment outside the on-chain budget is declined before any money moves; nothing is queued for a human to approve later. If the resource returns a non-402 status, returns it unchanged without contacting Haven.",
3799
+ nextActionGuidance: "Preserve the returned resume_state or paymentId \u2014 either identifies this payment if you need to ask about it later. This tool performs the merchant retry itself, so do not wait on a signal while the call is in flight. If the process crashes after this call and a later haven_get_payment_status reports nextAction=retry_original_x402_request, Haven's funding leg confirmed but no merchant response was ever recorded \u2014 call the resume tool with the preserved resume_state or payment_id instead of paying again. If the response carries phase=insufficient_funds and nextAction=fund_safe_or_raise_allowance, the payment cannot be retried until the account is funded or the agent budget raised \u2014 stop and tell the user the shortfall reported on the response."
3743
3800
  },
3744
3801
  resumeX402: {
3745
- summary: "Resume an x402 payment after the Haven wallet owner approved the funding step.",
3746
- behavior: "Accepts either resume_state or payment_id, validates the original x402 details against the approved Haven funding, and retries the merchant request with the X-PAYMENT header. No new Haven approval is created.",
3747
- nextActionGuidance: "Only use when get_payment_status returns nextAction=retry_original_x402_request; do not start a new merchant session."
3802
+ summary: "Resume an x402 payment whose Haven-side authorization already succeeded but whose merchant retry did not complete.",
3803
+ behavior: "Accepts either resume_state or payment_id, validates the original x402 details against the authorized Haven funding, and retries the merchant request with the X-PAYMENT header. No new Haven payment is created.",
3804
+ nextActionGuidance: "Only call this after haven_get_payment_status reports nextAction=retry_original_x402_request \u2014 that means Haven's funding leg confirmed but no merchant response was ever recorded, most often because the process crashed between funding and the merchant retry. Any other nextAction reports a conflict instead of retrying, so do not call this speculatively. Do not start a new merchant session and do not pay again \u2014 that would pay twice for one resource."
3748
3805
  },
3749
3806
  // #1328: quoteMpp / payMpp / resumeMpp (the mpp_demo challenge/quote/resume
3750
3807
  // fragments) are retired along with the client surface they described —
@@ -3752,24 +3809,24 @@ var toolDescriptions = {
3752
3809
  // deleted `/demo/mpp/*` route. Use the x402 fragments above instead.
3753
3810
  getPaymentStatus: {
3754
3811
  summary: "Fetch structured Haven payment status, including phase and nextAction taxonomy for agent recovery.",
3755
- behavior: "Accepts a payment intent or approval request id and returns the full state taxonomy (phase, nextAction, rail, amount, merchant, resource url, idempotency key, message).",
3812
+ behavior: "Accepts a payment intent id and returns the full state taxonomy (phase, nextAction, rail, amount, merchant, resource url, idempotency key, message).",
3756
3813
  nextActionGuidance: ""
3757
3814
  },
3758
3815
  getResumeState: {
3759
3816
  summary: "Rehydrate stored x402 resume_state by payment_id.",
3760
- behavior: "Returns the context that the agent originally received in a pending-approval response, reconstructed from Haven's database. This is context only; signing still happens locally when a resume tool is called.",
3817
+ behavior: "Returns the x402 context the agent originally received when the payment was authorized, reconstructed from Haven's database. This is context only; signing still happens locally when a resume tool is called.",
3761
3818
  nextActionGuidance: ""
3762
3819
  },
3763
3820
  getAgent: {
3764
3821
  summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status, spend_authority_readiness, and per-token remaining allowance (atomic + human-readable). The recommended first call in a new session to confirm who you are and whether Haven will let you spend right now.",
3765
3822
  selectionGuidance: "Use this as the one-shot orientation/bootstrap at the start of a session, or whenever you need to confirm identity together with whether the agent can spend right now. For a detailed per-token breakdown (configured vs spent vs reset window) use haven_get_allowances.",
3766
- behavior: 'Reads identity plus the live spend-authority snapshot in one shot \u2014 the on-chain AllowanceModule on the legacy rail, the active budget delegation on the delegation rail. spend_authority_readiness (readiness is a deprecated alias, same value) is "ready" when at least one token has remaining spend authority, "needs_approval" when the agent is active but has none, and "revoked" when the credential is not active. It covers hosted identity + on-chain spend authority ONLY \u2014 the hosted server cannot see the LOCAL signer, so "ready" does not mean the signer can start; verify the signer with a signer tool call or connect --doctor. What an over-budget payment does differs by rail: on the legacy AllowanceModule rail it is queued for the wallet owner to approve in Haven; on the delegation rail there is no approval queue \u2014 an over-budget redemption reverts on-chain, so ask the owner to grant or raise the budget in Haven rather than waiting for an approval. allowances[] carries remainingAtomic and remainingDisplay per token. Identity fields (id, name, status, safeAddress, delegateAddress, chainId) are unchanged from before.',
3823
+ behavior: `Reads identity plus the live spend-authority snapshot in one shot \u2014 the agent's active on-chain budget delegation. spend_authority_readiness (readiness is a deprecated alias, same value) is "ready" when at least one token has remaining spend authority, "needs_approval" when the agent is active but has none, and "revoked" when the credential is not active. It covers hosted identity + on-chain spend authority ONLY \u2014 the hosted server cannot see the LOCAL signer, so "ready" does not mean the signer can start; verify the signer with a signer tool call or connect --doctor. An over-budget payment is declined before any money moves: there is no approval queue, so ask the owner to grant or raise the budget in Haven rather than waiting for an approval. allowances[] carries remainingAtomic and remainingDisplay per token. Identity fields (id, name, status, safeAddress, delegateAddress, chainId) are unchanged from before.`,
3767
3824
  nextActionGuidance: ""
3768
3825
  },
3769
3826
  getAllowances: {
3770
3827
  summary: "Return configured and on-chain allowance state for the authenticated agent. On-chain allowance is the real spend gate.",
3771
3828
  selectionGuidance: "Use this when the user asks about allowance, budget, spend limit, remaining amount, remaining allowance, remaining budget, daily limit, reset period, what can I spend, or what the agent can still spend.",
3772
- behavior: "Returns the per-token spend authority for the account's rail: the Safe AllowanceModule snapshot (allowance, spent, remaining, reset window) on the legacy rail, or the active budget delegation (remaining = the period budget; over-budget redemptions revert on-chain, nothing queues) on the delegation rail. Configured amounts from Haven are returned alongside.",
3829
+ behavior: "Returns the per-token spend authority for the account: the active budget delegation (remaining = the period budget, which re-arms natively at the period boundary). An over-budget payment is declined before any money moves; nothing queues. Configured amounts from Haven are returned alongside.",
3773
3830
  nextActionGuidance: ""
3774
3831
  },
3775
3832
  listReceipts: {
@@ -3787,15 +3844,21 @@ var toolDescriptions = {
3787
3844
  payMcpTool: {
3788
3845
  summary: "Call a named tool on an MCP merchant that requires an x402 payment, handling the full initialize \u2192 pay \u2192 retry round trip in one call.",
3789
3846
  selectionGuidance: "Use this when the agent wants to call a specific tool on an MCP merchant (e.g. Soundside, Coinbase Bazaar) and payment is required. Prefer this over haven_pay_x402 when you know the merchant_url and tool_name \u2014 it builds the JSON-RPC envelope internally. Use haven_pay_x402 for arbitrary HTTP resources. Do NOT use for read-only allowance or budget questions \u2014 use haven_get_allowances.",
3790
- behavior: "Builds the JSON-RPC tools/call envelope, runs the MCP Streamable-HTTP initialize handshake automatically (if the endpoint is MCP-shaped), pays any HTTP 402 x402 challenge through Haven's AllowanceModule path, and retries the request, returning the JSON-RPC result (the actual merchant output) on success. Amounts within the on-chain allowance execute automatically; over-allowance transfers are queued as pending_approval \u2014 follow the response's nextAction when present.",
3791
- nextActionGuidance: "If pending_approval is returned, preserve payment_id and resume_state and wait for the wallet owner to approve in Haven. Use haven_resume_x402_payment once nextAction=retry_original_x402_request."
3847
+ behavior: "Builds the JSON-RPC tools/call envelope, runs the MCP Streamable-HTTP initialize handshake automatically (if the endpoint is MCP-shaped), pays any HTTP 402 x402 challenge against the agent's on-chain budget delegation, and retries the request, returning the JSON-RPC result (the actual merchant output) on success. Amounts within the remaining on-chain budget execute automatically; anything outside it is declined before any money moves \u2014 follow the response's nextAction when present.",
3848
+ nextActionGuidance: "On a decline, report the reason to the user and ask them to raise the budget in Haven \u2014 there is no approval queue to wait on. This tool retries the merchant itself while it runs, so do not wait on a signal mid-call. If the process crashes after payment, a later haven_get_payment_status call may report nextAction=retry_original_x402_request \u2014 resume via haven_resume_x402_payment instead of paying again."
3792
3849
  },
3793
3850
  discoverTools: {
3794
3851
  summary: "Step 1 of a purchase: discover payable services from Haven's curated merchant catalog \u2014 names, prices, and which pay tool to use next.",
3795
- selectionGuidance: "Use this when the user asks what the agent can buy, pay for, or which paid services exist \u2014 or when you need a resource URL for a service the user described. Do NOT use for balance, budget, or spend-limit questions \u2014 use haven_get_allowances. Do NOT use to pay \u2014 each returned entry names the pay tool to use next.",
3796
- behavior: "Use each entry's suggested_tool field first \u2014 it names the exact next call. Read-only lookup against Haven's curated catalog; entries are periodically re-verified against the live merchant and degraded entries are flagged. Use category for a case-insensitive category filter (for example, VPN or vpn), or search for a product name, category, or description term. Returns name, description, price, rail, resource URL, tool_name, tool_arguments, and suggested_tool. The catalog price (price_display/price_atomic, marked price_is_indicative) is a last-verified hint, NOT authoritative \u2014 the real price comes from the merchant's live 402 at pay time. Never creates a payment, signature, or approval.",
3852
+ selectionGuidance: "Use this when the user asks what the agent can buy, pay for, or which paid services exist \u2014 or when you need a resource URL for a service the user described. Use verified=verified to show only self-submitted directory entries that passed domain-ownership proof and a live quote probe \u2014 never treat those badges as proof of merchant honesty, quality, or reliability. Do NOT use for balance, budget, or spend-limit questions \u2014 use haven_get_allowances. Do NOT use to pay \u2014 each returned entry names the pay tool to use next.",
3853
+ behavior: "Use each entry's suggested_tool field first \u2014 it names the exact next call. Read-only lookup against Haven's curated catalog; entries are periodically re-verified against the live merchant and degraded entries are flagged. Use category for a case-insensitive category filter (for example, VPN or vpn), or search for a product name, category, or description term. Returns name, description, price, rail, resource URL, tool_name, tool_arguments, suggested_tool, and the provenance badges source/domain_verified/verified_payable. The catalog price (price_display/price_atomic, marked price_is_indicative) is a last-verified hint, NOT authoritative \u2014 the real price comes from the merchant's live 402 at pay time. Never creates a payment, signature, or approval.",
3797
3854
  nextActionGuidance: `Pick an entry and pay it with the tool named in suggested_tool, passing the entry's resource_url, tool_name, and tool_arguments for MCP merchants. Confirm the price from the live pay-tool result (not the catalog), and pass the user's cap as max_amount_human in whole tokens ("no more than 1 USDC" \u2192 max_amount_human: "1") \u2014 never convert it to atomic units by hand.`
3798
3855
  },
3856
+ submitCatalogEntry: {
3857
+ summary: "Submit a merchant's payable (x402/MCP) endpoint to Haven's Verified Payable Directory for verification and listing.",
3858
+ selectionGuidance: "Use this when a merchant or seller asks to be listed in the directory, or when you have discovered a payable endpoint and want it registered. The submission is queue-only: it books a spot and returns a verify_token. The seller must then prove control of the domain (a well-known line or DNS TXT record); only after that plus a live quote probe does the entry become listed. Do NOT use to pay \u2014 check the returned status with getCatalogSubmissionStatus instead.",
3859
+ behavior: "Sends the https resource_url to Haven's public submission endpoint. The request path makes no outbound request to the merchant. Returns id + verify_token + status; the verify_token is shown exactly once. Ownership proof is always required later and cannot be skipped from the agent side. The website field is a honeypot for bots \u2014 leave it unset.",
3860
+ nextActionGuidance: "Give the verify_token and the well-known instructions (from getCatalogSubmissionStatus) to the merchant so they can publish the proof line, then poll the submission status until it reaches verified_payable or failed."
3861
+ },
3799
3862
  sweep_delegate: {
3800
3863
  summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating Safe.",
3801
3864
  selectionGuidance: "Use this when the user instructs you to recover stranded funds on the delegate wallet, or when a payment status returns nextAction=sweep_stranded_funds. Do NOT use for normal payments \u2014 use haven_pay_x402. Do NOT use to read balances only \u2014 use haven_get_allowances.",
@@ -3805,8 +3868,8 @@ var toolDescriptions = {
3805
3868
  send: {
3806
3869
  summary: "Send ETH or USDC directly from the agent's Haven wallet to a recipient address.",
3807
3870
  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.",
3808
- behavior: "Sends the requested amount through the Safe AllowanceModule. Amounts within the remaining on-chain allowance for the asset execute automatically; amounts that exceed the allowance are queued as pending_approval for the wallet owner to approve in Haven. The agent's signing key signs the AllowanceModule transfer hash; Haven never receives the key.",
3809
- nextActionGuidance: "If pending_approval is returned, preserve the payment_id and wait for the wallet owner to approve in Haven. Poll haven_get_payment_status until nextAction=none."
3871
+ behavior: "Sends the requested 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 and before the agent is asked to sign \u2014 it is never queued for a human to approve later. The agent's signing key signs the account's typed data; Haven never receives the key.",
3872
+ 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."
3810
3873
  }
3811
3874
  };
3812
3875
 
@@ -3877,7 +3940,7 @@ var authorizeX402Schema = {
3877
3940
  },
3878
3941
  idempotencyKey: {
3879
3942
  type: "string",
3880
- description: "Stable caller-supplied key for this user intent. Reuse it when resuming after user approval."
3943
+ description: "Stable caller-supplied key for this user intent. Reuse it when resuming the same payment."
3881
3944
  }
3882
3945
  },
3883
3946
  required: ["url", "payTo", "amount", "asset", "network"]
@@ -3887,7 +3950,7 @@ var resumeX402Schema = {
3887
3950
  properties: {
3888
3951
  payment_id: {
3889
3952
  type: "string",
3890
- description: "The payment or approval request ID returned by authorize_x402_payment."
3953
+ description: "The payment ID returned by authorize_x402_payment."
3891
3954
  },
3892
3955
  url: {
3893
3956
  type: "string",
@@ -3920,11 +3983,11 @@ var resumeX402Schema = {
3920
3983
  },
3921
3984
  required: ["payment_id", "url", "payTo", "amount", "asset", "network"]
3922
3985
  };
3923
- var MAKE_PAYMENT_DESCRIPTION = "Request and sign a payment from the user-controlled Safe within approved on-chain limits. For read-only allowance, budget, spend-limit, remaining-amount, or reset-period questions, use get_allowances instead of making a payment. Haven authenticates the agent, validates the signed intent, and relays the Safe AllowanceModule transaction; it does not hold keys or control funds. Gnosis Chain tokens: EURe, USDC.e, xDAI. Base tokens: USDC, ETH.";
3924
- var GET_STATUS_DESCRIPTION = toolDescriptions.getPaymentStatus.summary + " Accepts payment intent IDs and approval request IDs. Returns the current status, phase, next_action, transaction hash if available, and payment details.";
3986
+ var MAKE_PAYMENT_DESCRIPTION = "Request and sign a payment from the user-controlled account within its on-chain budget. For read-only allowance, budget, spend-limit, remaining-amount, or reset-period questions, use get_allowances instead of making a payment. Haven authenticates the agent and relays the signed transaction that redeems the agent budget delegation; it does not hold keys or control funds. Gnosis Chain tokens: EURe, USDC.e, xDAI. Base tokens: USDC, ETH.";
3987
+ var GET_STATUS_DESCRIPTION = toolDescriptions.getPaymentStatus.summary + " Accepts payment intent IDs. Returns the current status, phase, next_action, transaction hash if available, and payment details.";
3925
3988
  var GET_ALLOWANCES_DESCRIPTION = composeDescription(toolDescriptions.getAllowances);
3926
- var AUTHORIZE_X402_DESCRIPTION = composeDescription(toolDescriptions.payX402) + " In this SDK tool set, the allowance lookup tool is get_allowances. When a paid API returns x402 payment requirements, use this tool to sign with the agent-owned delegate key and request a policy-limited Safe AllowanceModule top-up when needed. Haven relays signed transactions only; the agent key authorizes payment and on-chain limits enforce spend. If this returns pending_approval, tell the user it is waiting in Haven, preserve the original merchant/MCP session and x402 details, call get_payment_status later, and use resume_x402_payment only when next_action is retry_original_x402_request. Do not start a new merchant session or loop retries while approval is pending. Use the returned payment_header as the X-PAYMENT header on the retry request when doing a manual HTTP retry.";
3927
- var RESUME_X402_DESCRIPTION = toolDescriptions.resumeX402.summary + " Use this only after get_payment_status returns next_action=retry_original_x402_request. It checks the approved payment, validates the original x402 details, and returns a merchant X-PAYMENT header without creating a new approval request or merchant session.";
3989
+ var AUTHORIZE_X402_DESCRIPTION = composeDescription(toolDescriptions.payX402) + " In this SDK tool set, the allowance lookup tool is get_allowances. When a paid API returns x402 payment requirements, use this tool to sign with the agent-owned delegate key; funding, when the scheme needs it, is redeemed from the agent budget delegation and is bounded by it. Haven relays signed transactions only; the agent key authorizes payment and on-chain limits enforce spend. A payment outside the on-chain budget is declined before any money moves \u2014 report the decline and ask the user to raise the budget in Haven; do not loop retries and do not wait for an approval, because none is queued. Preserve the original merchant/MCP session and x402 details. Use the returned payment_header as the X-PAYMENT header on the retry request when doing a manual HTTP retry.";
3990
+ var RESUME_X402_DESCRIPTION = toolDescriptions.resumeX402.summary + " Only call this after get_payment_status reports nextAction=retry_original_x402_request \u2014 that means Haven's funding leg confirmed but no merchant response was ever recorded (typically a crash between funding and the merchant retry). Any other nextAction reports a conflict instead of retrying \u2014 do not call this speculatively, and do not pay again.";
3928
3991
  var SWEEP_DELEGATE_DESCRIPTION = composeDescription(toolDescriptions.sweep_delegate);
3929
3992
  var sweepDelegateSchema = {
3930
3993
  type: "object",
@@ -4034,8 +4097,8 @@ description: Pay for things from the user's Haven wallet within their agent rule
4034
4097
 
4035
4098
  This skill lets the agent make payments from the user's Haven wallet through
4036
4099
  the Haven MCP tools. Every payment is checked against the agent's on-chain
4037
- budget before money moves; payments above the remaining budget wait for the
4038
- user's approval in Haven.
4100
+ budget before money moves; a payment above the remaining budget is declined \u2014
4101
+ nothing is paid past the rules the user set.
4039
4102
 
4040
4103
  Hosted tools run in the \`mcp__haven__\` namespace. Local signing tools run in
4041
4104
  the \`mcp__haven-signer__\` namespace and keep the delegate key on this machine.
@@ -4079,8 +4142,8 @@ spending:
4079
4142
  (configured, spent, reset window) when you need more than the summary.
4080
4143
 
4081
4144
  Budgets reset on a period the user chose. If a payment exceeds the remaining
4082
- budget it is queued for the user to approve in the Haven dashboard \u2014 this is
4083
- normal, not an error.
4145
+ budget it is declined before any money moves \u2014 tell the user; they can raise
4146
+ the budget in the Haven dashboard, or wait for the period reset.
4084
4147
 
4085
4148
  ## Paying
4086
4149
 
@@ -4122,8 +4185,8 @@ context (\`merchant_url\`, \`tool_name\`, \`arguments\`, \`mcp_transport\`)
4122
4185
  server-side from \`payment_id\`. Pass those four fields explicitly only as a
4123
4186
  version-skew fallback when Haven has no stored context for the id \u2014 both or
4124
4187
  none together, never just one. If the settle result carries \`settled: false\`,
4125
- funding is queued for the user's approval \u2014 tell them and check status later,
4126
- do not re-pay.
4188
+ funding has not confirmed \u2014 follow the result's guidance fields and check
4189
+ status later, do not re-pay.
4127
4190
 
4128
4191
  Step-by-step alternative (also key-safe; for an older signer or backend, or
4129
4192
  when you already have a merchant URL and tool name instead of a
@@ -4146,8 +4209,12 @@ merchant leg for you.
4146
4209
  recipient, amount, and token for a plain transfer. For an arbitrary,
4147
4210
  non-MCP x402 paywall: \`mcp__haven__haven_quote_x402\` to get a quote, then
4148
4211
  \`mcp__haven__haven_pay_x402_quote\` \u2014 follow the result's guidance fields
4149
- first, sign in the local Haven signer, and retry the original request only
4150
- when the result says \`retry_original_x402_request\`.
4212
+ first and sign in the local Haven signer. The pay tool performs the merchant
4213
+ retry itself, so do not wait on a signal while it runs. If the process
4214
+ crashes after payment, a later \`mcp__haven__haven_get_payment_status\` call
4215
+ may report \`nextAction: 'retry_original_x402_request'\` \u2014 only then call
4216
+ \`mcp__haven__haven_resume_x402_payment\` with the preserved resume state or
4217
+ payment id, instead of paying again.
4151
4218
 
4152
4219
  **Catalog tool arguments:** when \`haven_discover_tools\` returns
4153
4220
  \`tool_arguments\`, pass that object unchanged as the pay tool's
@@ -4163,14 +4230,14 @@ Haven authorizes for that call \u2014 a ceiling the merchant settles at or below
4163
4230
  so present it as the most the user will pay.
4164
4231
 
4165
4232
  **Status:** \`mcp__haven__haven_get_payment_status\` with a \`payment_id\` to
4166
- check on queued or in-flight payments. Do not poll in a tight loop.
4233
+ check on in-flight payments. Do not poll in a tight loop.
4167
4234
 
4168
- ## Approval semantics
4235
+ ## Declines and stop signals
4169
4236
 
4170
- - A result with \`pending_approval\` means the payment exceeded the remaining
4171
- budget and is waiting for the user in Haven. Tell the user, then check
4172
- status later.
4173
- - \`safe_to_continue: false\` on a guidance block is the same signal in
4237
+ - A payment outside the agent's rules \u2014 above the remaining budget, wrong
4238
+ recipient, or expired budget \u2014 is declined before any money moves. Nothing
4239
+ is queued; tell the user, who can raise the budget in Haven.
4240
+ - \`safe_to_continue: false\` on a guidance block is a stop signal in
4174
4241
  machine-readable form: stop and involve the user before calling anything
4175
4242
  else for this payment.
4176
4243
  - Never ask the user for private keys. Signing happens only in the local Haven
@@ -4184,7 +4251,6 @@ Haven tool failures are shaped like \`{ success: false, code, message, ... }\`
4184
4251
  or older \`{ error, status, details? }\` responses. Branch on \`code\` when
4185
4252
  present and surface \`message\` or \`error\` verbatim. Common cases:
4186
4253
 
4187
- - \`pending_approval\`: queued for the user's approval (see above).
4188
4254
  - \`insufficient_funds\`: the Haven wallet doesn't hold enough of that token.
4189
4255
  Suggest the user add funds in the Haven dashboard.
4190
4256
  - \`PRICE_EXCEEDS_MAX\`: the live merchant price exceeded your cap. No funds