@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.js CHANGED
@@ -16,33 +16,40 @@ var AgentPaymentPhase = {
16
16
  PaymentSubmitted: "payment_submitted",
17
17
  /** The direct payment is confirmed; the agent does not need to do more for this payment id. */
18
18
  PaymentConfirmed: "payment_confirmed",
19
- /** The payment needs wallet owner approval in Haven before it can continue. */
19
+ /**
20
+ * #2115: RETIRED wire value — no live rail produces it. It described the
21
+ * Safe rail's approval queue, which no longer exists. Kept so a stored value
22
+ * still typechecks; see `AgentPaymentPhaseDescriptions` below for the
23
+ * agent-visible wording, which this comment used to contradict.
24
+ */
20
25
  UserApprovalRequired: "user_approval_required",
21
- /** The wallet owner approved the request and still needs to complete the funding payment. */
26
+ /** #2115: RETIRED wire value — no live rail produces it. Stop and tell the user. */
22
27
  UserExecutionRequired: "user_execution_required",
23
- /** The funding payment was proposed and is waiting for the remaining account approvals. */
28
+ /** #2115: RETIRED wire value — no live rail produces it. Stop and tell the user. */
24
29
  WaitingForAdditionalApprovals: "waiting_for_additional_approvals",
25
30
  /** The Haven funding leg was sent; the agent can continue the merchant/protocol leg. */
26
31
  FundingSent: "funding_sent",
27
- /** The wallet owner rejected the request; the agent should stop and tell the user. */
32
+ /** The payment was rejected and cannot proceed; the agent should stop and tell the user. */
28
33
  Rejected: "rejected",
29
- /** The payment or approval request expired before completion. */
34
+ /** The payment expired before completion. */
30
35
  Expired: "expired",
31
36
  /** Haven could not complete the payment; the agent should stop and surface the failure. */
32
37
  Failed: "failed",
33
38
  /**
34
39
  * Pre-flight check determined the delegate's existing balance plus the
35
- * remaining on-chain allowance cannot cover the requested amount, so no
36
- * payment intent was created. Distinct from `UserApprovalRequired`: there
37
- * is no approval that would fix this — the originating Safe needs more
38
- * funds or the agent's per-token allowance needs to be raised first.
40
+ * remaining on-chain budget cannot cover the requested amount, so no
41
+ * payment intent was created. The account must be funded or the agent's
42
+ * budget raised before retrying — #2115: the old wording contrasted this
43
+ * with `UserApprovalRequired` as if that were a live alternative, and named
44
+ * the retired rail's Safe and per-token allowance as the fix.
39
45
  */
40
46
  InsufficientFunds: "insufficient_funds",
41
47
  /**
42
- * Haven's funding leg (Safe → delegate) confirmed on-chain, but the
43
- * merchant rejected the x402 retry. The delegate wallet may hold stranded
44
- * USDC that was never settled to the merchant. The agent should stop, tell
45
- * the user, and wait for the sweep flow to reclaim the funds.
48
+ * Haven's funding leg (account → delegate, the #946 EIP-3009 bridge)
49
+ * confirmed on-chain, but the merchant rejected the x402 retry. The delegate
50
+ * wallet may hold stranded USDC that was never settled to the merchant. The
51
+ * agent should stop, tell the user, and wait for the sweep flow to reclaim
52
+ * the funds.
46
53
  */
47
54
  FundedButUnsettled: "funded_but_unsettled"
48
55
  };
@@ -53,9 +60,12 @@ var AgentPaymentNextAction = {
53
60
  CheckStatusLater: "check_status_later",
54
61
  /** No further agent action is required for this payment id. */
55
62
  None: "none",
56
- /** Wait for the wallet owner to approve or reject the request in Haven. */
63
+ /**
64
+ * #2115: RETIRED wire value — no live rail produces it and nothing maps to
65
+ * it. Stop and tell the user rather than polling; no approval will arrive.
66
+ */
57
67
  WaitForUserApproval: "wait_for_user_approval",
58
- /** Wait for the wallet owner to finish sending the approved funding payment. */
68
+ /** #2115: RETIRED wire value — no live rail produces it. Stop and tell the user rather than polling. */
59
69
  WaitForUserToCompletePayment: "wait_for_user_to_complete_payment",
60
70
  /** Resume this payment id and retry the original x402 request with the merchant payment header. */
61
71
  RetryOriginalX402Request: "retry_original_x402_request",
@@ -145,29 +155,29 @@ var AgentPaymentPhaseDescriptions = {
145
155
  [AgentPaymentPhase.AgentSignatureRequired]: "The agent must sign and submit the prepared payment before Haven can relay it.",
146
156
  [AgentPaymentPhase.PaymentSubmitted]: "Haven has received the signed payment and the agent should poll for confirmation.",
147
157
  [AgentPaymentPhase.PaymentConfirmed]: "The direct payment is confirmed; the agent does not need to do more for this payment id.",
148
- [AgentPaymentPhase.UserApprovalRequired]: "The payment needs wallet owner approval in Haven before it can continue.",
149
- [AgentPaymentPhase.UserExecutionRequired]: "The wallet owner approved the request and still needs to complete the funding payment.",
150
- [AgentPaymentPhase.WaitingForAdditionalApprovals]: "The funding payment was proposed and is waiting for the remaining account approvals.",
158
+ [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.",
159
+ [AgentPaymentPhase.UserExecutionRequired]: "Retired wire value: no live rail produces it. Stop and tell the user.",
160
+ [AgentPaymentPhase.WaitingForAdditionalApprovals]: "Retired wire value: no live rail produces it. Stop and tell the user.",
151
161
  [AgentPaymentPhase.FundingSent]: "The Haven funding leg was sent; the agent can continue the merchant/protocol leg.",
152
- [AgentPaymentPhase.Rejected]: "The wallet owner rejected the request; the agent should stop and tell the user.",
153
- [AgentPaymentPhase.Expired]: "The payment or approval request expired before completion.",
162
+ [AgentPaymentPhase.Rejected]: "The payment was rejected and cannot proceed; the agent should stop and tell the user.",
163
+ [AgentPaymentPhase.Expired]: "The payment expired before completion.",
154
164
  [AgentPaymentPhase.Failed]: "Haven could not complete the payment; the agent should stop and surface the failure.",
155
- [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.",
156
- [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."
165
+ [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.",
166
+ [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."
157
167
  };
158
168
  var AgentPaymentNextActionDescriptions = {
159
169
  [AgentPaymentNextAction.SignAndSubmitPayment]: "Sign with the delegate key and submit the payment to Haven.",
160
170
  [AgentPaymentNextAction.CheckStatusLater]: "Poll getPaymentStatus later using this payment id.",
161
171
  [AgentPaymentNextAction.None]: "No further agent action is required for this payment id.",
162
- [AgentPaymentNextAction.WaitForUserApproval]: "Wait for the wallet owner to approve or reject the request in Haven.",
163
- [AgentPaymentNextAction.WaitForUserToCompletePayment]: "Wait for the wallet owner to finish sending the approved funding payment.",
172
+ [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.",
173
+ [AgentPaymentNextAction.WaitForUserToCompletePayment]: "Retired wire value: no live rail produces it. Stop and tell the user rather than polling.",
164
174
  [AgentPaymentNextAction.RetryOriginalX402Request]: "Resume this payment id and retry the original x402 request with the merchant payment header.",
165
175
  [AgentPaymentNextAction.StopAndTellUser]: "Stop retrying this payment and tell the user what happened.",
166
176
  [AgentPaymentNextAction.RequestAgainIfUserStillWantsIt]: "Ask again only if the user still wants the payment after expiry.",
167
177
  [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.",
168
- [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.",
178
+ [AgentPaymentNextAction.FundSafeOrRaiseAllowance]: "Stop and tell the user that the account needs to be funded or the agent budget raised before the payment can succeed.",
169
179
  [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.",
170
- [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."
180
+ [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."
171
181
  };
172
182
  var AgentPaymentFailureCodeDescriptions = {
173
183
  [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.",
@@ -210,7 +220,7 @@ var AgentPaymentWarningCode = {
210
220
  AllowanceReadOptimistic: "ALLOWANCE_READ_OPTIMISTIC"
211
221
  };
212
222
  var AgentPaymentRailDescriptions = {
213
- [AgentPaymentRail.Direct]: "Standard Haven payment from the user-controlled Safe through an approved delegate allowance.",
223
+ [AgentPaymentRail.Direct]: "Standard Haven payment from the user-controlled account, redeeming the agent's on-chain budget delegation.",
214
224
  [AgentPaymentRail.X402]: "x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg.",
215
225
  [AgentPaymentRail.Mpp]: "Categorical MPP rail value used as a resume-state discriminator. Response bodies carry a granular mpp_* value instead.",
216
226
  [AgentPaymentRail.MppDemo]: "Haven internal MPP demo rail. Not for production traffic.",
@@ -1144,10 +1154,10 @@ function nextActionForStatus(status) {
1144
1154
  if (status === "pending_signature") return AgentPaymentNextAction.SignAndSubmitPayment;
1145
1155
  if (status === "submitted") return AgentPaymentNextAction.CheckStatusLater;
1146
1156
  if (status === "confirmed") return AgentPaymentNextAction.None;
1147
- if (status === "pending" || status === "pending_approval") return AgentPaymentNextAction.WaitForUserApproval;
1157
+ if (status === "pending" || status === "pending_approval") return AgentPaymentNextAction.StopAndTellUser;
1148
1158
  if (status === "approved") return AgentPaymentNextAction.WaitForUserToCompletePayment;
1149
- if (status === "proposed") return AgentPaymentNextAction.WaitForUserApproval;
1150
- if (status === "executed") return AgentPaymentNextAction.RetryOriginalX402Request;
1159
+ if (status === "proposed") return AgentPaymentNextAction.StopAndTellUser;
1160
+ if (status === "executed") return AgentPaymentNextAction.StopAndTellUser;
1151
1161
  if (status === "rejected") return AgentPaymentNextAction.StopAndTellUser;
1152
1162
  if (status === "expired") return AgentPaymentNextAction.RequestAgainIfUserStillWantsIt;
1153
1163
  if (status === "failed") return AgentPaymentNextAction.StopAndTellUser;
@@ -1155,10 +1165,10 @@ function nextActionForStatus(status) {
1155
1165
  }
1156
1166
  function messageForState(label, status, paymentId, nextAction) {
1157
1167
  if (status === "pending" || status === "pending_approval") {
1158
- return `${label} is above the remaining agent budget and is waiting for user approval in Haven (payment_id: ${paymentId}).`;
1168
+ 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.`;
1159
1169
  }
1160
1170
  if (status === "executed") {
1161
- return "The user completed the funding payment. Retry the original x402 request.";
1171
+ 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.`;
1162
1172
  }
1163
1173
  if (status === "rejected") {
1164
1174
  return `The user rejected this payment request (payment_id: ${paymentId}).`;
@@ -1225,7 +1235,7 @@ function throwPaymentStateError(label, raw) {
1225
1235
  }
1226
1236
  if (raw.status === "pending_approval") {
1227
1237
  throw new HavenApiError(
1228
- `${label} exceeds the on-chain allowance and was queued for owner approval (payment_id: ${raw.payment_id}).`,
1238
+ `${label} exceeds the agent's on-chain budget and was declined; no approval is pending and none will arrive (payment_id: ${raw.payment_id}).`,
1229
1239
  statusCode,
1230
1240
  raw
1231
1241
  );
@@ -1769,13 +1779,18 @@ function requestInitFromSnapshot(request) {
1769
1779
  body: request.body
1770
1780
  };
1771
1781
  }
1782
+ function noCompatiblePaymentOptionError(accepts) {
1783
+ const erc7710Only = selectErc7710PaymentOption(accepts) !== null;
1784
+ return new HavenApiError(
1785
+ "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)." : ""),
1786
+ 400
1787
+ );
1788
+ }
1772
1789
  function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport) {
1773
- const option = selectStandardPaymentOption(paymentRequired.accepts);
1790
+ const standard = selectStandardPaymentOption(paymentRequired.accepts);
1791
+ const option = standard ?? selectErc7710PaymentOption(paymentRequired.accepts);
1774
1792
  if (!option) {
1775
- throw new HavenApiError(
1776
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
1777
- 400
1778
- );
1793
+ throw noCompatiblePaymentOptionError(paymentRequired.accepts);
1779
1794
  }
1780
1795
  const token = resolveTokenFromAddress(option.asset, option.network);
1781
1796
  return {
@@ -1783,6 +1798,7 @@ function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport)
1783
1798
  idempotencyKey: idempotencyKey ?? buildX402IdempotencyKey(paymentRequired, option),
1784
1799
  paymentRequired,
1785
1800
  accepted: option,
1801
+ acceptedScheme: standard ? "standard" : "erc7710",
1786
1802
  request,
1787
1803
  ...mcpTransport ? { mcpTransport } : {},
1788
1804
  resourceUrl: paymentRequired.resource.url,
@@ -2276,6 +2292,9 @@ var X402Erc7710 = class {
2276
2292
  // becomes a loud mismatch instead of a silent reroute to the 3009 leg.
2277
2293
  payTo: merchantPayTo,
2278
2294
  settlementScheme: "erc7710",
2295
+ // #2041: sent only when the caller supplied one, so an omitting caller's
2296
+ // request body is byte-identical to the pre-#2041 shape.
2297
+ ...options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {},
2279
2298
  amount: amountAtomic,
2280
2299
  asset: option.asset,
2281
2300
  network: option.network,
@@ -2437,6 +2456,8 @@ function toolError(err) {
2437
2456
 
2438
2457
  // src/merchant-completion.ts
2439
2458
  var MERCHANT_BODY_SNIPPET_LIMIT = 1e3;
2459
+ var EVIDENCE_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
2460
+ var EVIDENCE_RETRYABLE_STATUS = 503;
2440
2461
  var MerchantCompletion = class {
2441
2462
  post;
2442
2463
  merchantTransport;
@@ -2444,7 +2465,9 @@ var MerchantCompletion = class {
2444
2465
  getAgent;
2445
2466
  delegateAddress;
2446
2467
  x402Wallet;
2468
+ sleep;
2447
2469
  constructor(options) {
2470
+ this.sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
2448
2471
  this.post = options.post;
2449
2472
  this.merchantTransport = options.merchantTransport;
2450
2473
  this.getPaymentStatus = options.getPaymentStatus;
@@ -2618,22 +2641,29 @@ var MerchantCompletion = class {
2618
2641
  }
2619
2642
  }
2620
2643
  async reportEvidence(input) {
2621
- try {
2622
- await this.post("/machine-payments/evidence", {
2623
- paymentId: input.paymentId,
2624
- rail: input.rail,
2625
- txHash: input.txHash,
2626
- resourceUrl: input.resourceUrl,
2627
- merchantStatus: input.merchantStatus,
2628
- challengePayload: input.challengePayload,
2629
- selectedPayment: input.selectedPayment,
2630
- paymentProofHeaderName: input.paymentProofHeaderName,
2631
- paymentProofHeader: input.paymentProofHeader,
2632
- protocolReceiptHeaderName: input.protocolReceiptHeaderName,
2633
- protocolReceiptHeader: input.protocolReceiptHeader,
2634
- protocolReceiptPayload: input.protocolReceiptHeader ? parseProtocolReceiptHeader(input.protocolReceiptHeader) : void 0
2635
- });
2636
- } catch {
2644
+ const body = {
2645
+ paymentId: input.paymentId,
2646
+ rail: input.rail,
2647
+ txHash: input.txHash,
2648
+ resourceUrl: input.resourceUrl,
2649
+ merchantStatus: input.merchantStatus,
2650
+ challengePayload: input.challengePayload,
2651
+ selectedPayment: input.selectedPayment,
2652
+ paymentProofHeaderName: input.paymentProofHeaderName,
2653
+ paymentProofHeader: input.paymentProofHeader,
2654
+ protocolReceiptHeaderName: input.protocolReceiptHeaderName,
2655
+ protocolReceiptHeader: input.protocolReceiptHeader,
2656
+ protocolReceiptPayload: input.protocolReceiptHeader ? parseProtocolReceiptHeader(input.protocolReceiptHeader) : void 0
2657
+ };
2658
+ for (let attempt = 0; ; attempt += 1) {
2659
+ try {
2660
+ await this.post("/machine-payments/evidence", body);
2661
+ return;
2662
+ } catch (err) {
2663
+ const retryable = err instanceof HavenApiError && err.statusCode === EVIDENCE_RETRYABLE_STATUS;
2664
+ if (!retryable || attempt >= EVIDENCE_RETRY_DELAYS_MS.length) return;
2665
+ await this.sleep(EVIDENCE_RETRY_DELAYS_MS[attempt]);
2666
+ }
2637
2667
  }
2638
2668
  }
2639
2669
  };
@@ -2683,7 +2713,10 @@ function mapCatalogEntry(entry) {
2683
2713
  asset: entry.asset,
2684
2714
  network: entry.network,
2685
2715
  status: entry.status,
2686
- verifiedAt: entry.verified_at
2716
+ verifiedAt: entry.verified_at,
2717
+ source: entry.source,
2718
+ domainVerified: entry.domain_verified,
2719
+ verifiedPayable: entry.verified_payable
2687
2720
  };
2688
2721
  }
2689
2722
  var HavenClient = class {
@@ -2840,10 +2873,7 @@ var HavenClient = class {
2840
2873
  async createX402Intent(paymentRequired, options = {}) {
2841
2874
  const option = selectStandardPaymentOption(paymentRequired.accepts);
2842
2875
  if (!option) {
2843
- throw new HavenApiError(
2844
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
2845
- 400
2846
- );
2876
+ throw noCompatiblePaymentOptionError(paymentRequired.accepts);
2847
2877
  }
2848
2878
  const fundingTo = options.delegateAddress ?? (await this.getAgent()).delegateAddress;
2849
2879
  if (!fundingTo) {
@@ -3119,7 +3149,7 @@ var HavenClient = class {
3119
3149
  return status;
3120
3150
  }
3121
3151
  /**
3122
- * Discover payable services from Haven's curated merchant catalog.
3152
+ * Discover payable services from Haven's merchant catalog (epic #1717).
3123
3153
  *
3124
3154
  * Read-only: returns catalog entries (price, rail, protocol) so an agent
3125
3155
  * can choose a service and pay it with the regular payment tools in the
@@ -3132,7 +3162,39 @@ var HavenClient = class {
3132
3162
  if (options.rail) params.set("rail", options.rail);
3133
3163
  const query = params.size > 0 ? `?${params.toString()}` : "";
3134
3164
  const raw = await this.get(`/catalog${query}`);
3135
- return raw.entries.map(mapCatalogEntry);
3165
+ let entries = raw.entries.map(mapCatalogEntry);
3166
+ if (options.verified === "verified") entries = entries.filter((e) => e.source === "ingestion");
3167
+ if (options.verified === "operator") entries = entries.filter((e) => e.source === "operator");
3168
+ return entries;
3169
+ }
3170
+ /**
3171
+ * Submit a merchant's payable (x402/MCP) endpoint to the Verified Payable
3172
+ * Directory (epic #1717, #1716). Queue-only: writes a submission row and
3173
+ * returns the id + verify_token. The request path makes no outbound
3174
+ * request; domain-ownership proof and the read-only quote probe run later
3175
+ * on the leader-locked monitor. Ownership proof is ALWAYS required before
3176
+ * any listing — this method cannot skip it. `website` is a honeypot field
3177
+ * that bots fill; leave it unset.
3178
+ */
3179
+ async submitCatalogEntry(resourceUrl, options = {}) {
3180
+ const accepted = await this.post("/catalog/submit", {
3181
+ resource_url: resourceUrl,
3182
+ ...options.website ? { website: options.website } : {}
3183
+ });
3184
+ return {
3185
+ id: accepted.id,
3186
+ verifyToken: accepted.verify_token,
3187
+ status: accepted.status
3188
+ };
3189
+ }
3190
+ /**
3191
+ * Fetch one submission's coarse status by id (epic #1717, #1716). Public
3192
+ * and read-only. While the submission can still prove ownership the
3193
+ * response carries the exact well-known / DNS-TXT `instructions`; the
3194
+ * verify token is never returned here.
3195
+ */
3196
+ async getCatalogSubmissionStatus(id) {
3197
+ return this.get(`/catalog/submit/${encodeURIComponent(id)}`);
3136
3198
  }
3137
3199
  /**
3138
3200
  * Fetch one curated catalog entry by id (#1306).
@@ -3207,10 +3269,7 @@ var HavenClient = class {
3207
3269
  }
3208
3270
  const option = selectStandardPaymentOption(paymentRequired.accepts);
3209
3271
  if (!option) {
3210
- throw new HavenApiError(
3211
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
3212
- 400
3213
- );
3272
+ throw noCompatiblePaymentOptionError(paymentRequired.accepts);
3214
3273
  }
3215
3274
  const idempotencyKey = options.idempotencyKey ?? buildX402IdempotencyKey(paymentRequired, option);
3216
3275
  const cached = this.fundingLeg.cachedReceipt(idempotencyKey);
@@ -3350,10 +3409,7 @@ var HavenClient = class {
3350
3409
  }
3351
3410
  const option = selectStandardPaymentOption(input.paymentRequired.accepts);
3352
3411
  if (!option) {
3353
- throw new HavenApiError(
3354
- "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
3355
- 400
3356
- );
3412
+ throw noCompatiblePaymentOptionError(input.paymentRequired.accepts);
3357
3413
  }
3358
3414
  const idempotencyKey = input.idempotencyKey ?? buildX402IdempotencyKey(input.paymentRequired, option);
3359
3415
  const cached = this.fundingLeg.cachedReceipt(idempotencyKey);
@@ -3553,11 +3609,12 @@ var HavenClient = class {
3553
3609
  });
3554
3610
  }
3555
3611
  } else {
3556
- if (!input.noFundingLeg && fundingTxHash) {
3612
+ const evidenceTxHash = input.noFundingLeg ? settlement.settlementTxHash ?? void 0 : fundingTxHash ?? void 0;
3613
+ if (evidenceTxHash) {
3557
3614
  await this.merchantCompletion.reportEvidence({
3558
3615
  paymentId: evidenceContext.paymentId,
3559
3616
  rail: "x402",
3560
- txHash: fundingTxHash,
3617
+ txHash: evidenceTxHash,
3561
3618
  resourceUrl: evidenceContext.resourceUrl,
3562
3619
  merchantStatus: surfaced.status,
3563
3620
  paymentProofHeaderName: "X-PAYMENT",
@@ -3730,19 +3787,19 @@ var toolDescriptions = {
3730
3787
  payX402: {
3731
3788
  summary: "Pay an inspected x402 quote. The delegate key signs locally; Haven only validates and relays signed, on-chain-constrained payment transactions.",
3732
3789
  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.",
3733
- 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.",
3734
- 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."
3790
+ 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.",
3791
+ 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."
3735
3792
  },
3736
3793
  payX402OneShot: {
3737
3794
  summary: "Fetch an x402 paid HTTP resource in a single call. Handles the full probe -> pay -> retry round trip and returns the merchant response.",
3738
3795
  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.",
3739
- 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.",
3740
- 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."
3796
+ 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.",
3797
+ 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."
3741
3798
  },
3742
3799
  resumeX402: {
3743
- summary: "Resume an x402 payment after the Haven wallet owner approved the funding step.",
3744
- 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.",
3745
- nextActionGuidance: "Only use when get_payment_status returns nextAction=retry_original_x402_request; do not start a new merchant session."
3800
+ summary: "Resume an x402 payment whose Haven-side authorization already succeeded but whose merchant retry did not complete.",
3801
+ 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.",
3802
+ 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."
3746
3803
  },
3747
3804
  // #1328: quoteMpp / payMpp / resumeMpp (the mpp_demo challenge/quote/resume
3748
3805
  // fragments) are retired along with the client surface they described —
@@ -3750,24 +3807,24 @@ var toolDescriptions = {
3750
3807
  // deleted `/demo/mpp/*` route. Use the x402 fragments above instead.
3751
3808
  getPaymentStatus: {
3752
3809
  summary: "Fetch structured Haven payment status, including phase and nextAction taxonomy for agent recovery.",
3753
- 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).",
3810
+ behavior: "Accepts a payment intent id and returns the full state taxonomy (phase, nextAction, rail, amount, merchant, resource url, idempotency key, message).",
3754
3811
  nextActionGuidance: ""
3755
3812
  },
3756
3813
  getResumeState: {
3757
3814
  summary: "Rehydrate stored x402 resume_state by payment_id.",
3758
- 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.",
3815
+ 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.",
3759
3816
  nextActionGuidance: ""
3760
3817
  },
3761
3818
  getAgent: {
3762
3819
  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.",
3763
3820
  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.",
3764
- 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.',
3821
+ 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.`,
3765
3822
  nextActionGuidance: ""
3766
3823
  },
3767
3824
  getAllowances: {
3768
3825
  summary: "Return configured and on-chain allowance state for the authenticated agent. On-chain allowance is the real spend gate.",
3769
3826
  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.",
3770
- 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.",
3827
+ 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.",
3771
3828
  nextActionGuidance: ""
3772
3829
  },
3773
3830
  listReceipts: {
@@ -3785,15 +3842,21 @@ var toolDescriptions = {
3785
3842
  payMcpTool: {
3786
3843
  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.",
3787
3844
  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.",
3788
- 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.",
3789
- 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."
3845
+ 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.",
3846
+ 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."
3790
3847
  },
3791
3848
  discoverTools: {
3792
3849
  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.",
3793
- 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.",
3794
- 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.",
3850
+ 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.",
3851
+ 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.",
3795
3852
  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.`
3796
3853
  },
3854
+ submitCatalogEntry: {
3855
+ summary: "Submit a merchant's payable (x402/MCP) endpoint to Haven's Verified Payable Directory for verification and listing.",
3856
+ 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.",
3857
+ 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.",
3858
+ 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."
3859
+ },
3797
3860
  sweep_delegate: {
3798
3861
  summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating Safe.",
3799
3862
  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.",
@@ -3803,8 +3866,8 @@ var toolDescriptions = {
3803
3866
  send: {
3804
3867
  summary: "Send ETH or USDC directly from the agent's Haven wallet to a recipient address.",
3805
3868
  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.",
3806
- 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.",
3807
- 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."
3869
+ 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.",
3870
+ 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."
3808
3871
  }
3809
3872
  };
3810
3873
 
@@ -3875,7 +3938,7 @@ var authorizeX402Schema = {
3875
3938
  },
3876
3939
  idempotencyKey: {
3877
3940
  type: "string",
3878
- description: "Stable caller-supplied key for this user intent. Reuse it when resuming after user approval."
3941
+ description: "Stable caller-supplied key for this user intent. Reuse it when resuming the same payment."
3879
3942
  }
3880
3943
  },
3881
3944
  required: ["url", "payTo", "amount", "asset", "network"]
@@ -3885,7 +3948,7 @@ var resumeX402Schema = {
3885
3948
  properties: {
3886
3949
  payment_id: {
3887
3950
  type: "string",
3888
- description: "The payment or approval request ID returned by authorize_x402_payment."
3951
+ description: "The payment ID returned by authorize_x402_payment."
3889
3952
  },
3890
3953
  url: {
3891
3954
  type: "string",
@@ -3918,11 +3981,11 @@ var resumeX402Schema = {
3918
3981
  },
3919
3982
  required: ["payment_id", "url", "payTo", "amount", "asset", "network"]
3920
3983
  };
3921
- 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.";
3922
- 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.";
3984
+ 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.";
3985
+ 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.";
3923
3986
  var GET_ALLOWANCES_DESCRIPTION = composeDescription(toolDescriptions.getAllowances);
3924
- 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.";
3925
- 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.";
3987
+ 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.";
3988
+ 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.";
3926
3989
  var SWEEP_DELEGATE_DESCRIPTION = composeDescription(toolDescriptions.sweep_delegate);
3927
3990
  var sweepDelegateSchema = {
3928
3991
  type: "object",
@@ -4032,8 +4095,8 @@ description: Pay for things from the user's Haven wallet within their agent rule
4032
4095
 
4033
4096
  This skill lets the agent make payments from the user's Haven wallet through
4034
4097
  the Haven MCP tools. Every payment is checked against the agent's on-chain
4035
- budget before money moves; payments above the remaining budget wait for the
4036
- user's approval in Haven.
4098
+ budget before money moves; a payment above the remaining budget is declined \u2014
4099
+ nothing is paid past the rules the user set.
4037
4100
 
4038
4101
  Hosted tools run in the \`mcp__haven__\` namespace. Local signing tools run in
4039
4102
  the \`mcp__haven-signer__\` namespace and keep the delegate key on this machine.
@@ -4077,8 +4140,8 @@ spending:
4077
4140
  (configured, spent, reset window) when you need more than the summary.
4078
4141
 
4079
4142
  Budgets reset on a period the user chose. If a payment exceeds the remaining
4080
- budget it is queued for the user to approve in the Haven dashboard \u2014 this is
4081
- normal, not an error.
4143
+ budget it is declined before any money moves \u2014 tell the user; they can raise
4144
+ the budget in the Haven dashboard, or wait for the period reset.
4082
4145
 
4083
4146
  ## Paying
4084
4147
 
@@ -4120,8 +4183,8 @@ context (\`merchant_url\`, \`tool_name\`, \`arguments\`, \`mcp_transport\`)
4120
4183
  server-side from \`payment_id\`. Pass those four fields explicitly only as a
4121
4184
  version-skew fallback when Haven has no stored context for the id \u2014 both or
4122
4185
  none together, never just one. If the settle result carries \`settled: false\`,
4123
- funding is queued for the user's approval \u2014 tell them and check status later,
4124
- do not re-pay.
4186
+ funding has not confirmed \u2014 follow the result's guidance fields and check
4187
+ status later, do not re-pay.
4125
4188
 
4126
4189
  Step-by-step alternative (also key-safe; for an older signer or backend, or
4127
4190
  when you already have a merchant URL and tool name instead of a
@@ -4144,8 +4207,12 @@ merchant leg for you.
4144
4207
  recipient, amount, and token for a plain transfer. For an arbitrary,
4145
4208
  non-MCP x402 paywall: \`mcp__haven__haven_quote_x402\` to get a quote, then
4146
4209
  \`mcp__haven__haven_pay_x402_quote\` \u2014 follow the result's guidance fields
4147
- first, sign in the local Haven signer, and retry the original request only
4148
- when the result says \`retry_original_x402_request\`.
4210
+ first and sign in the local Haven signer. The pay tool performs the merchant
4211
+ retry itself, so do not wait on a signal while it runs. If the process
4212
+ crashes after payment, a later \`mcp__haven__haven_get_payment_status\` call
4213
+ may report \`nextAction: 'retry_original_x402_request'\` \u2014 only then call
4214
+ \`mcp__haven__haven_resume_x402_payment\` with the preserved resume state or
4215
+ payment id, instead of paying again.
4149
4216
 
4150
4217
  **Catalog tool arguments:** when \`haven_discover_tools\` returns
4151
4218
  \`tool_arguments\`, pass that object unchanged as the pay tool's
@@ -4161,14 +4228,14 @@ Haven authorizes for that call \u2014 a ceiling the merchant settles at or below
4161
4228
  so present it as the most the user will pay.
4162
4229
 
4163
4230
  **Status:** \`mcp__haven__haven_get_payment_status\` with a \`payment_id\` to
4164
- check on queued or in-flight payments. Do not poll in a tight loop.
4231
+ check on in-flight payments. Do not poll in a tight loop.
4165
4232
 
4166
- ## Approval semantics
4233
+ ## Declines and stop signals
4167
4234
 
4168
- - A result with \`pending_approval\` means the payment exceeded the remaining
4169
- budget and is waiting for the user in Haven. Tell the user, then check
4170
- status later.
4171
- - \`safe_to_continue: false\` on a guidance block is the same signal in
4235
+ - A payment outside the agent's rules \u2014 above the remaining budget, wrong
4236
+ recipient, or expired budget \u2014 is declined before any money moves. Nothing
4237
+ is queued; tell the user, who can raise the budget in Haven.
4238
+ - \`safe_to_continue: false\` on a guidance block is a stop signal in
4172
4239
  machine-readable form: stop and involve the user before calling anything
4173
4240
  else for this payment.
4174
4241
  - Never ask the user for private keys. Signing happens only in the local Haven
@@ -4182,7 +4249,6 @@ Haven tool failures are shaped like \`{ success: false, code, message, ... }\`
4182
4249
  or older \`{ error, status, details? }\` responses. Branch on \`code\` when
4183
4250
  present and surface \`message\` or \`error\` verbatim. Common cases:
4184
4251
 
4185
- - \`pending_approval\`: queued for the user's approval (see above).
4186
4252
  - \`insufficient_funds\`: the Haven wallet doesn't hold enough of that token.
4187
4253
  Suggest the user add funds in the Haven dashboard.
4188
4254
  - \`PRICE_EXCEEDS_MAX\`: the live merchant price exceeded your cap. No funds