@haven_ai/sdk 0.3.0-alpha.0 → 0.4.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -706,7 +706,13 @@ function normalizePaymentOption(value) {
706
706
  mimeType: candidate.mimeType,
707
707
  asset: candidate.asset,
708
708
  payTo: candidate.payTo,
709
- maxTimeoutSeconds: clampAuthorizationWindow(candidate.maxTimeoutSeconds),
709
+ // Keep the merchant offer intact for v2 `accepted` matching. Only the
710
+ // signing conversion may cap its authorization lifetime (#3117).
711
+ // Retain legacy fallback behavior for missing or unusable timeouts.
712
+ // Integer, because the authorize body types it `integer` and the child's
713
+ // timestamp caveat is built from it — the old clamp floored, so keeping a
714
+ // fractional value here would 400 a merchant that used to work (#3117).
715
+ maxTimeoutSeconds: typeof candidate.maxTimeoutSeconds === "number" && Number.isFinite(candidate.maxTimeoutSeconds) && candidate.maxTimeoutSeconds >= 1 ? Math.floor(candidate.maxTimeoutSeconds) : clampAuthorizationWindow(candidate.maxTimeoutSeconds),
710
716
  extra: candidate.extra
711
717
  };
712
718
  }
@@ -857,6 +863,13 @@ function selectPaymentOption(accepts) {
857
863
  return null;
858
864
  }
859
865
  var ERC7710_ASSET_TRANSFER_METHOD = "erc7710";
866
+ function isEip3009ConstructibleOption(option) {
867
+ const rawMethod = option.extra?.assetTransferMethod;
868
+ if (rawMethod !== void 0 && rawMethod !== "eip3009") return false;
869
+ const rawFlow = option.extra?.paymentFlow;
870
+ if (rawFlow !== void 0 && rawFlow !== "authorization") return false;
871
+ return true;
872
+ }
860
873
  function x402AssetTransferMethod(option) {
861
874
  const raw = option.extra?.assetTransferMethod;
862
875
  return typeof raw === "string" ? raw : null;
@@ -877,7 +890,8 @@ function selectStandardPaymentOption(accepts) {
877
890
  if (!accepts || accepts.length === 0) return null;
878
891
  for (const opt of accepts) {
879
892
  if (opt === null || typeof opt !== "object") continue;
880
- if (!isErc7710Option(opt) && isPayableStandardOption(opt)) return opt;
893
+ if (!isEip3009ConstructibleOption(opt)) continue;
894
+ if (isPayableStandardOption(opt)) return opt;
881
895
  }
882
896
  return null;
883
897
  }
@@ -886,6 +900,7 @@ function selectErc7710PaymentOption(accepts) {
886
900
  for (const opt of accepts) {
887
901
  if (opt === null || typeof opt !== "object") continue;
888
902
  if (isErc7710Option(opt) && isPayableStandardOption(opt)) return opt;
903
+ if (!isEip3009ConstructibleOption(opt)) continue;
889
904
  }
890
905
  return null;
891
906
  }
@@ -947,6 +962,11 @@ function toStandardPaymentRequirements(paymentRequired, option) {
947
962
  if (option.scheme !== "exact") {
948
963
  throw new Error(`Unsupported x402 scheme: ${option.scheme}`);
949
964
  }
965
+ if (!isEip3009ConstructibleOption(option)) {
966
+ throw new Error(
967
+ "Unsupported x402 payment requirements: this SDK constructs EIP-3009 authorization payments only. The merchant advertised a different extra.assetTransferMethod or an unrecognized extra.paymentFlow."
968
+ );
969
+ }
950
970
  return {
951
971
  scheme: "exact",
952
972
  network,
@@ -956,14 +976,11 @@ function toStandardPaymentRequirements(paymentRequired, option) {
956
976
  mimeType: option.mimeType ?? paymentRequired.resource.mimeType ?? "application/octet-stream",
957
977
  payTo: option.payTo,
958
978
  asset: option.asset,
959
- // Second enforcement point (#715): the parse path clamps too, but this is
960
- // the last stop before the x402 library turns the timeout into
961
- // `validBefore` — options constructed without parsing are bounded here.
962
- // The forward margin (#1256) is added ONLY here, at signing: the parse
963
- // path keeps recording the merchant's advertised timeout unchanged, and
964
- // the library's `validBefore = now + this value` then carries enough
965
- // slack to satisfy the facilitator's `validBefore ≥ now + maxTimeout`
966
- // verify rule after our funding leg confirms.
979
+ // Signing-only policy (#715/#3117): parsed and directly supplied options
980
+ // share this cap before the library computes validBefore. Keep the offer
981
+ // echoed in `accepted` unchanged. The forward margin (#1256) adds time
982
+ // for funding/retry, but does not guarantee a merchant timeout above the
983
+ // total bounded lifetime can pass facilitator verification.
967
984
  maxTimeoutSeconds: clampAuthorizationWindow(option.maxTimeoutSeconds) + X402_SETTLEMENT_FORWARD_MARGIN_SECONDS,
968
985
  extra: option.extra
969
986
  };
@@ -1418,6 +1435,51 @@ function throwPaymentStateError(label, raw) {
1418
1435
  throw new HavenApiError(message, statusCode, raw);
1419
1436
  }
1420
1437
 
1438
+ // src/x402-retry-target.ts
1439
+ function resolveX402RetryTarget(input) {
1440
+ const requestUrl = input.requestUrl?.trim() || void 0;
1441
+ if (requestUrl) {
1442
+ return {
1443
+ url: requestUrl,
1444
+ source: "request",
1445
+ resourceUrlDiffersFromRequest: requestUrl !== input.resourceUrl
1446
+ };
1447
+ }
1448
+ return { url: input.resourceUrl, source: "resource" };
1449
+ }
1450
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "::1", "[::1]"]);
1451
+ var RESERVED_SUFFIXES = [".test", ".localhost", ".invalid", ".example"];
1452
+ var IPV4_LOOPBACK = /^127(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
1453
+ function isSecureX402RetryTarget(url) {
1454
+ let parsed;
1455
+ try {
1456
+ parsed = new URL(url);
1457
+ } catch {
1458
+ return false;
1459
+ }
1460
+ if (parsed.protocol === "https:") return true;
1461
+ if (parsed.protocol !== "http:") return false;
1462
+ const host = parsed.hostname.toLowerCase();
1463
+ if (LOOPBACK_HOSTS.has(host) || IPV4_LOOPBACK.test(host)) return true;
1464
+ return RESERVED_SUFFIXES.some((suffix) => host.endsWith(suffix));
1465
+ }
1466
+ var INSECURE_RETRY_TARGET_CODE = "INSECURE_RETRY_TARGET";
1467
+ var HavenInsecureRetryTargetError = class extends HavenError {
1468
+ constructor(url) {
1469
+ super(
1470
+ `Refusing to send a payment header to ${url}: the paid x402 retry must go to an https URL (or a loopback / reserved test host). The merchant's challenge declared this resource URL; retry with the https URL you quoted (pass it as \`url\`), and report a merchant whose challenge downgrades the scheme.`,
1471
+ INSECURE_RETRY_TARGET_CODE,
1472
+ 400
1473
+ );
1474
+ this.url = url;
1475
+ this.name = "HavenInsecureRetryTargetError";
1476
+ }
1477
+ url;
1478
+ };
1479
+ function assertSecureX402RetryTarget(url) {
1480
+ if (!isSecureX402RetryTarget(url)) throw new HavenInsecureRetryTargetError(url);
1481
+ }
1482
+
1421
1483
  // src/mcp-merchant-transport.ts
1422
1484
  var DEFAULT_MERCHANT_TIMEOUT = 3e5;
1423
1485
  var MCP_NOTIFICATION_TIMEOUT = 1e4;
@@ -1575,6 +1637,7 @@ var McpMerchantTransport = class {
1575
1637
  * overwrite, which is worse than the duplicate this change removes.
1576
1638
  */
1577
1639
  async deliverPayment(url, init, paymentHeader) {
1640
+ assertSecureX402RetryTarget(url);
1578
1641
  const headers = new Headers(init?.headers);
1579
1642
  const send = x402PaymentHeaderNamesFor(paymentHeader);
1580
1643
  for (const name of X402_PAYMENT_HEADER_NAMES) {
@@ -1689,6 +1752,10 @@ function deriveReadiness(status, allowances) {
1689
1752
  if (status !== "active") return "revoked";
1690
1753
  return allowances.some((allowance) => safeBigInt(allowance.remainingAtomic) > 0n) ? "ready" : "needs_approval";
1691
1754
  }
1755
+ function formatRemainingDisplay(tokenAddress, tokenSymbol, remainingAtomic) {
1756
+ const token = resolveTokenFromAddress(tokenAddress);
1757
+ return token ? `${formatAtomicAmount(safeBigInt(remainingAtomic), token.decimals)} ${tokenSymbol}` : `${remainingAtomic} ${tokenSymbol} (atomic; unknown decimals)`;
1758
+ }
1692
1759
  var AccountReads = class {
1693
1760
  transport;
1694
1761
  getPaymentStatus;
@@ -1710,12 +1777,12 @@ var AccountReads = class {
1710
1777
  async getAgentSummary() {
1711
1778
  const [agent, allowanceSummary] = await Promise.all([this.getAgent(), this.getAllowances()]);
1712
1779
  const allowances = allowanceSummary.allowances.map((allowance) => {
1713
- const token = resolveTokenFromAddress(allowance.tokenAddress);
1714
- const remainingDisplay = token ? `${formatAtomicAmount(safeBigInt(allowance.onchain.remaining), token.decimals)} ${allowance.tokenSymbol}` : `${allowance.onchain.remaining} ${allowance.tokenSymbol} (atomic; unknown decimals)`;
1715
1780
  return {
1781
+ id: allowance.id,
1716
1782
  tokenSymbol: allowance.tokenSymbol,
1783
+ tokenAddress: allowance.tokenAddress,
1717
1784
  remainingAtomic: allowance.onchain.remaining,
1718
- remainingDisplay,
1785
+ remainingDisplay: allowance.remainingDisplay,
1719
1786
  configuredAmount: allowance.configuredAmount,
1720
1787
  resetPeriodMin: allowance.resetPeriodMin,
1721
1788
  isResetPending: allowance.onchain.isResetPending
@@ -1743,6 +1810,7 @@ var AccountReads = class {
1743
1810
  tokenSymbol: allowance.token_symbol,
1744
1811
  configuredAmount: allowance.configured_amount,
1745
1812
  resetPeriodMin: allowance.reset_period_min,
1813
+ remainingDisplay: formatRemainingDisplay(allowance.token_address, allowance.token_symbol, allowance.onchain.remaining),
1746
1814
  onchain: {
1747
1815
  amount: allowance.onchain.amount,
1748
1816
  spent: allowance.onchain.spent,
@@ -1757,6 +1825,33 @@ var AccountReads = class {
1757
1825
  }))
1758
1826
  };
1759
1827
  }
1828
+ /**
1829
+ * #3126 — the sufficiency signal behind {@link HavenBalanceCoverage}.
1830
+ *
1831
+ * Deliberately NOT a balance read: the endpoint answers whether the
1832
+ * account HOLDS at least the checked amount, as `covered
1833
+ * true/false/null`, and never returns the balance itself. The camelCase
1834
+ * mapping is permissive (raw fields flow through; the server owns the
1835
+ * wire shape, pinned by the backend's `expectMatchesSpec` assertion), so
1836
+ * an older server that has not deployed the endpoint surfaces its 404 as
1837
+ * a thrown error rather than a fabricated answer.
1838
+ */
1839
+ async checkFunds(input) {
1840
+ const query = `token=${encodeURIComponent(input.token)}&amount_atomic=${encodeURIComponent(input.amountAtomic)}`;
1841
+ const raw = await this.transport.get(
1842
+ `/machine-payments/balance-coverage?${query}`
1843
+ );
1844
+ return {
1845
+ covered: raw.covered,
1846
+ ...raw.coverage_error !== void 0 ? { coverageError: raw.coverage_error } : {},
1847
+ chainId: raw.chain_id,
1848
+ tokenAddress: raw.token_address,
1849
+ tokenSymbol: raw.token_symbol,
1850
+ checkedAmountAtomic: raw.checked_amount_atomic,
1851
+ budgetRemainingAtomic: raw.budget_remaining_atomic,
1852
+ ...raw.budget_remaining_is_from_chain !== void 0 ? { budgetRemainingIsFromChain: raw.budget_remaining_is_from_chain } : {}
1853
+ };
1854
+ }
1760
1855
  async getPostPurchaseAllowanceSummary(paymentId) {
1761
1856
  const unavailable = (detail, payment2 = null) => ({
1762
1857
  payment: payment2,
@@ -1808,10 +1903,23 @@ var AccountReads = class {
1808
1903
  return unavailable(error instanceof Error ? error.message : String(error));
1809
1904
  }
1810
1905
  }
1906
+ /** The first page's receipts as a bare array — the pre-#3128 shape, kept for callers that never page. */
1811
1907
  async listReceipts(options = {}) {
1812
- const query = options.limit ? `?limit=${encodeURIComponent(String(options.limit))}` : "";
1908
+ return (await this.listReceiptsPage(options)).receipts;
1909
+ }
1910
+ /** #3128: one page with `total`, `hasMore` and `nextCursor` — see {@link HavenPaymentReceiptsPage}. */
1911
+ async listReceiptsPage(options = {}) {
1912
+ const params = new URLSearchParams();
1913
+ if (options.limit) params.set("limit", String(options.limit));
1914
+ if (options.cursor) params.set("cursor", options.cursor);
1915
+ const query = params.size > 0 ? `?${params.toString()}` : "";
1813
1916
  const raw = await this.transport.get(`/machine-payments/receipts${query}`);
1814
- return raw.receipts.map(mapPaymentReceipt);
1917
+ return {
1918
+ receipts: raw.receipts.map(mapPaymentReceipt),
1919
+ total: typeof raw.total === "number" ? raw.total : null,
1920
+ hasMore: typeof raw.has_more === "boolean" ? raw.has_more : null,
1921
+ nextCursor: typeof raw.next_cursor === "string" ? raw.next_cursor : null
1922
+ };
1815
1923
  }
1816
1924
  async getReceipt(paymentId) {
1817
1925
  const { receipt } = await this.transport.get(`/payments/${paymentId}/receipt`);
@@ -1983,8 +2091,11 @@ function requestInitFromSnapshot(request) {
1983
2091
  }
1984
2092
  function noCompatiblePaymentOptionError(accepts) {
1985
2093
  const erc7710Only = selectErc7710PaymentOption(accepts) !== null;
2094
+ const unsupportedOnly = !erc7710Only && accepts.some(
2095
+ (opt) => opt !== null && typeof opt === "object" && !isErc7710Option(opt) && (x402AssetTransferMethod(opt) !== null || opt.extra?.paymentFlow !== void 0)
2096
+ );
1986
2097
  return new HavenApiError(
1987
- "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)." : ""),
2098
+ "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC." + (erc7710Only ? " The only Haven-compatible option this merchant advertises is tagged extra.assetTransferMethod: 'erc7710' (direct settlement), which this EIP-3009 payment path cannot settle \u2014 the limitation is the settlement scheme, not the asset. Paying this merchant requires a delegation-rail erc7710 flow (settleX402Erc7710, or the hosted MCP purchase tools)." : unsupportedOnly ? " Every option this merchant advertises asks for a transfer method or payment flow Haven cannot construct (for example extra.assetTransferMethod: 'permit2', or an unrecognized extra.paymentFlow). No payment intent was created and no funds moved." : ""),
1988
2099
  400
1989
2100
  );
1990
2101
  }
@@ -2004,6 +2115,11 @@ function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport)
2004
2115
  request,
2005
2116
  ...mcpTransport ? { mcpTransport } : {},
2006
2117
  resourceUrl: paymentRequired.resource.url,
2118
+ // #3097: the merchant's declaration vs the URL the caller quoted. The
2119
+ // paid retry goes to the caller's URL; a quote that says the two disagree
2120
+ // is how an agent sees a challenge that downgrades the scheme or moves
2121
+ // the host before it pays.
2122
+ resourceUrlDiffersFromRequest: paymentRequired.resource.url !== request.url,
2007
2123
  description: paymentRequired.resource.description ?? option.description ?? null,
2008
2124
  mimeType: paymentRequired.resource.mimeType ?? option.mimeType ?? null,
2009
2125
  amountAtomic: x402AuthorizationAmount(option),
@@ -3077,7 +3193,18 @@ function mapCatalogEntry(entry) {
3077
3193
  verifiedAt: entry.verified_at,
3078
3194
  source: entry.source,
3079
3195
  domainVerified: entry.domain_verified,
3080
- verifiedPayable: entry.verified_payable
3196
+ verifiedPayable: entry.verified_payable,
3197
+ // #3078: absent (older backend) or null (unresolved join) both mean "no
3198
+ // merchant known" — the public field is then absent, never null.
3199
+ ...entry.merchant ? {
3200
+ merchant: {
3201
+ id: entry.merchant.id,
3202
+ slug: entry.merchant.slug,
3203
+ name: entry.merchant.name,
3204
+ listingStatus: entry.merchant.listing_status,
3205
+ isTestMerchant: entry.merchant.is_test_merchant
3206
+ }
3207
+ } : {}
3081
3208
  };
3082
3209
  }
3083
3210
  var HavenClient = class {
@@ -3459,6 +3586,49 @@ var HavenClient = class {
3459
3586
  async getAllowances() {
3460
3587
  return this.accountReads.getAllowances();
3461
3588
  }
3589
+ /**
3590
+ * #3126 — is the checked amount of the token actually HELD on the
3591
+ * agent's own account?
3592
+ *
3593
+ * This is the companion to {@link getAllowances}, not a variant of it:
3594
+ * allowances answer what the agent is PERMITTED to spend this period;
3595
+ * this answers whether the account HOLDS funds behind that permission,
3596
+ * as a sufficiency signal — `covered: true | false | null` — never as a
3597
+ * balance. `covered: null` means the chain read failed: treat it as
3598
+ * unverifiable, not as absence (`coverageError` says why). The account's
3599
+ * balance itself is deliberately not returned.
3600
+ */
3601
+ async checkFunds(input) {
3602
+ return this.accountReads.checkFunds(input);
3603
+ }
3604
+ /**
3605
+ * `POST /machine-payments/budget-precheck` (#3054): ask Haven to decide —
3606
+ * server-side — whether `amountAtomic` of `token` fits the agent's
3607
+ * remaining delegation budget, the same compare the guided prepare used to
3608
+ * run locally over its allowances read.
3609
+ *
3610
+ * On insufficiency Haven refuses (403, `delegation_budget_exceeded`) and
3611
+ * the refusal reaches the `payment_refusals` ledger with
3612
+ * `source: 'hosted_prepare'` — the point of the endpoint. This method
3613
+ * surfaces that decision as a thrown {@link HavenApiError}; it does NOT
3614
+ * swallow it, because swallowing would turn a decided refusal into the
3615
+ * degrade-to-warning path and the ledger row would still land while the
3616
+ * purchase proceeded.
3617
+ *
3618
+ * camelCase body like the route family; the response mirrors the wire
3619
+ * (`sufficient`, `remaining_atomic`). `resourceUrl` is the merchant
3620
+ * resource being bought — the ledger dedupe window's discriminating
3621
+ * column — never this request's own URL.
3622
+ */
3623
+ async precheckBudget(input) {
3624
+ return this.post("/machine-payments/budget-precheck", {
3625
+ chainId: input.chainId,
3626
+ token: input.token,
3627
+ amountAtomic: input.amountAtomic,
3628
+ ...input.merchantTo !== void 0 ? { merchantTo: input.merchantTo } : {},
3629
+ ...input.resourceUrl !== void 0 ? { resourceUrl: input.resourceUrl } : {}
3630
+ });
3631
+ }
3462
3632
  /**
3463
3633
  * Post-purchase allowance/budget summary for a settled payment (#1310).
3464
3634
  *
@@ -3581,6 +3751,10 @@ var HavenClient = class {
3581
3751
  async listReceipts(options = {}) {
3582
3752
  return this.accountReads.listReceipts(options);
3583
3753
  }
3754
+ /** #3128: one page of receipts with `total`, `hasMore` and `nextCursor`. */
3755
+ async listReceiptsPage(options = {}) {
3756
+ return this.accountReads.listReceiptsPage(options);
3757
+ }
3584
3758
  /**
3585
3759
  * Fetch the verifiable receipt bundle for a settled payment and verify it
3586
3760
  * locally. The server's own verification is ignored — the receipt is verified
@@ -4218,21 +4392,29 @@ var toolDescriptions = {
4218
4392
  nextActionGuidance: ""
4219
4393
  },
4220
4394
  getAgent: {
4221
- 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.",
4222
- 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.",
4223
- 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, accountAddress, delegateAddress, chainId.`,
4395
+ summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status, spend_authority_readiness, per-token remaining allowance (atomic + human-readable). The recommended first call in a new session.",
4396
+ selectionGuidance: "Use this as the session bootstrap, or to confirm identity together with whether the agent can spend right now. For per-token detail (configured vs spent vs reset window) use haven_get_allowances.",
4397
+ behavior: 'Reads identity plus the live spend-authority snapshot \u2014 the 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 \u2014 ask the owner to grant or raise the budget in Haven. allowances[] carries id, tokenAddress, remainingAtomic, remainingDisplay per token. Identity fields: id, name, status, accountAddress, delegateAddress, chainId.',
4224
4398
  nextActionGuidance: ""
4225
4399
  },
4226
4400
  getAllowances: {
4227
4401
  summary: "Return configured and on-chain allowance state for the authenticated agent. On-chain allowance is the real spend gate.",
4228
- 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.",
4229
- 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.",
4402
+ 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. For whether the account actually HOLDS funds behind the budget use haven_check_funds.",
4403
+ 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), each with id, onchain.remaining, remainingDisplay. An over-budget payment is declined before any money moves; nothing queues. Configured amounts from Haven are returned alongside.",
4230
4404
  nextActionGuidance: ""
4231
4405
  },
4406
+ // #3126 — the sufficiency signal, deliberately NOT a balance tool. The
4407
+ // constrained actor reads a boolean, never the treasury total.
4408
+ checkFunds: {
4409
+ summary: "Check whether the agent's account actually holds at least the given amount of a token \u2014 funds held, not spend permitted.",
4410
+ selectionGuidance: "Use this before attempting a payment when it matters whether the money is really there: allowance answers say what you are PERMITTED to spend, never whether the account HOLDS it. For allowance, budget, spend-limit, remaining-budget, reset-period, or what-can-I-spend questions use the allowance lookup tool instead.",
4411
+ behavior: "Returns covered: true (the account holds at least the checked amount), false (a live chain read reports less \u2014 the budget is backed by an empty account; stop and tell the user funds are missing), or null (the chain read failed \u2014 unverifiable, never treat it as absence; coverageError says why). The account balance itself is deliberately not returned: this is a sufficiency signal, not a balance read. budget_remaining_atomic is the permitted figure from the allowance lookup (the SDK spells it budgetRemainingAtomic), named so it can never be confused with holdings.",
4412
+ nextActionGuidance: "On covered=false, do not attempt the payment \u2014 tell the user the account is short and let them fund it; on covered=null, retry the check shortly or proceed knowing the payment may fail on-chain."
4413
+ },
4232
4414
  listReceipts: {
4233
- summary: "List recent machine-payment receipts and evidence for bookkeeping.",
4234
- selectionGuidance: "Use this for transaction history, receipts, payment evidence, or bookkeeping; use the allowance tool instead for remaining allowance, budget, spend-limit, or what-can-I-spend questions.",
4235
- behavior: "Returns the agent's recent machine-payment receipts ordered by recency. Proof header values are not returned.",
4415
+ summary: "List machine-payment receipts, newest first, by page.",
4416
+ selectionGuidance: "For transaction history or payment evidence; use the allowance tool instead for remaining allowance or what-can-I-spend questions.",
4417
+ behavior: "Page: { receipts, total, hasMore, nextCursor }; total 0 = none exist (no indexing delay); hasMore = cut at limit, send nextCursor as cursor. parties.treasuryAccount is Haven's authoritative payer. protocolReceiptPayload is the merchant's PAYMENT-RESPONSE, relayed verbatim: merchant-controlled, unverified, not Haven's record; payer may differ from payerAddress. Proof header values are omitted.",
4236
4418
  nextActionGuidance: ""
4237
4419
  },
4238
4420
  verifyReceipt: {
@@ -4248,10 +4430,10 @@ var toolDescriptions = {
4248
4430
  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."
4249
4431
  },
4250
4432
  discoverTools: {
4251
- 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.",
4252
- 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 for entries Haven watched pass a live quote probe (operator-curated or self-submitted) \u2014 domain_verified is the only ownership claim; never treat these 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.",
4253
- 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.",
4254
- 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.`
4433
+ summary: "Step 1 of a purchase: discover payable services from Haven's curated merchant catalog \u2014 names, prices, the next call.",
4434
+ 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 for entries Haven watched pass a live quote probe (operator-curated or self-submitted) \u2014 domain_verified is the only ownership claim; never treat these 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 next tool to call.",
4435
+ behavior: "Use each entry's suggested_tool + suggested_arguments first; an entry without them says why. 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, the hint, 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.",
4436
+ nextActionGuidance: `Call suggested_tool with suggested_arguments VERBATIM (no hint: read suggested_tool_omitted_reason). Confirm the price from the live quote or pay result, not the catalog; if the next tool takes a cap, pass the user's cap as max_amount_human in whole tokens ("no more than 1 USDC" \u2192 max_amount_human: "1"), never atomic units by hand.`
4255
4437
  },
4256
4438
  submitCatalogEntry: {
4257
4439
  summary: "Submit a merchant's payable (x402/MCP) endpoint to Haven's Verified Payable Directory for verification and listing.",
@@ -4261,13 +4443,13 @@ var toolDescriptions = {
4261
4443
  },
4262
4444
  sweep_delegate: {
4263
4445
  summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating account.",
4264
- 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.",
4446
+ 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, or haven_check_funds for whether the account holds funds.",
4265
4447
  behavior: `Reads the delegate EOA's on-chain USDC and ETH balances. For each non-zero balance, signs and submits a transfer from the delegate EOA to the originating account (hardcoded destination). The delegate key signs locally \u2014 Haven never sees it and the backend never constructs signed transactions (CASP/MiCA Red Line #2). Returns tx hashes and recovered amounts. Returns an empty transfers list when nothing is stranded. Each transfer carries confirmation: "confirmed" (a receipt was seen \u2014 the funds are in the account) or "unconfirmed" (broadcast but not confirmed within 90 seconds \u2014 still in the mempool, may still land). The top-level unconfirmed flag is true when any transfer is unconfirmed.`,
4266
4448
  nextActionGuidance: 'If transfers is non-empty, confirm the amounts with the user. Report a transfer as recovered ONLY when its confirmation is "confirmed". For an "unconfirmed" transfer, tell the user it was submitted but not yet confirmed, give them its txHash and explorerUrl to check, and do not re-run the sweep immediately \u2014 a re-run after it lands will simply find nothing stranded.'
4267
4449
  },
4268
4450
  send: {
4269
4451
  summary: "Send ETH or USDC directly from the agent's Haven wallet to a recipient address.",
4270
- 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.",
4452
+ selectionGuidance: "Use this for plain transfers \u2014 refunding a user, paying a freelancer, topping up a co-agent's wallet, or moving funds between addresses. Do NOT use for x402 paid endpoints \u2014 use haven_pay_x402 instead. Do NOT use for read-only allowance, budget, or what-can-I-spend questions \u2014 use haven_get_allowances. Do NOT use to check whether funds are held before sending \u2014 use haven_check_funds.",
4271
4453
  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.",
4272
4454
  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."
4273
4455
  },
@@ -4646,8 +4828,10 @@ the \`mcp__haven-signer__\` namespace and keep the delegate key on this machine.
4646
4828
  That namespacing is Claude-family; other runtimes name the servers by their
4647
4829
  own config keys (Codex: \`haven\`, \`haven_signer\`). Tool results carry the
4648
4830
  exact next step (\`next_action\`, \`next_tool\`, \`next_arguments\`, plus the
4649
- runtime-neutral \`next_tool_server\` + \`next_tool_name\` \u2014 the bare tool name
4650
- on that logical server, whatever your runtime calls it).
4831
+ runtime-neutral \`next_tool_server\` + \`next_tool_name\` + \`next_tool_server_role\`
4832
+ \u2014 the bare tool name on that logical server, whatever your runtime calls it).
4833
+ When no tool follows, \`next_tool\` is absent and \`next_tool_omitted_reason\`
4834
+ says why; that is a complete answer.
4651
4835
  Follow those fields first; the prose below is fallback and orientation, not
4652
4836
  the source of truth.
4653
4837
 
@@ -4734,6 +4918,13 @@ spending:
4734
4918
  local signer; the signer is verified by calling any signer tool.
4735
4919
  - \`mcp__haven__haven_get_allowances\` \u2014 detailed per-token breakdown
4736
4920
  (configured, spent, reset window) when you need more than the summary.
4921
+ - \`mcp__haven__haven_check_funds\` \u2014 whether the account actually HOLDS at
4922
+ least a given amount of a token. Allowance answers above say what you are
4923
+ permitted to spend; this one says whether the money is really there,
4924
+ answered as \`covered\` true/false/null \u2014 never as a balance. On
4925
+ \`covered: false\`, stop and tell the user the account is short; on
4926
+ \`covered: null\` (the chain read failed), treat it as unverifiable rather
4927
+ than as absence.
4737
4928
 
4738
4929
  Budgets reset on a period the user chose. If a payment exceeds the remaining
4739
4930
  budget it is declined before any money moves \u2014 tell the user; they can raise
@@ -4862,8 +5053,10 @@ check on in-flight payments. Do not poll in a tight loop.
4862
5053
  ## Failure handling
4863
5054
 
4864
5055
  Haven tool failures are shaped like \`{ success: false, code, message, ... }\`
4865
- or older \`{ error, status, details? }\` responses. Branch on \`code\` when
4866
- present and surface \`message\` or \`error\` verbatim. Common cases:
5056
+ or older \`{ error, status, details? }\` responses. A failure carries the same
5057
+ \`next_action\` / \`next_tool\` / \`next_arguments\` / \`next_tool_omitted_reason\`
5058
+ fields a success does; follow them first, then branch on \`code\` and surface
5059
+ \`message\` or \`error\` verbatim. Common cases:
4867
5060
 
4868
5061
  - \`insufficient_funds\`: the Haven wallet doesn't hold enough of that token.
4869
5062
  Suggest the user add funds in the Haven dashboard.
@@ -4924,6 +5117,64 @@ for that credential.
4924
5117
  var SKILL_FOLDER_NAME = "haven-pay";
4925
5118
  var HAVEN_SKILL_BODY_MD = HAVEN_SKILL_MD.replace(/^---\n[\s\S]*?\n---\n+/, "");
4926
5119
 
5120
+ // src/next-step.ts
5121
+ var NEXT_TOOL_SERVER_NAMES = {
5122
+ hosted: "haven",
5123
+ signer: "haven-signer"
5124
+ };
5125
+ var NEXT_TOOL_SERVER_ROLES = {
5126
+ haven: "hosted",
5127
+ "haven-signer": "signer"
5128
+ };
5129
+ function renderNextTool(role, name) {
5130
+ return `mcp__${NEXT_TOOL_SERVER_NAMES[role]}__${name}`;
5131
+ }
5132
+ function parseNextTool(literal) {
5133
+ const m = /^mcp__([a-z0-9-]+)__([a-z0-9_]+)$/.exec(literal);
5134
+ if (!m) return null;
5135
+ const role = NEXT_TOOL_SERVER_ROLES[m[1]];
5136
+ return { server: m[1], name: m[2], ...role ? { role } : {} };
5137
+ }
5138
+ var DEFAULT_NEXT_TOOL_BY_ACTION = {
5139
+ check_status_later: "haven_get_payment_status",
5140
+ sweep_stranded_funds: "haven_sweep_delegate"
5141
+ // `retry_original_x402_request` is NOT here: its only live emitter
5142
+ // (state-direct-recovery.ts, erc7710) names no tool on purpose — the retry
5143
+ // is the agent's own HTTP call — so a default would contradict the site.
5144
+ };
5145
+ function defaultNextToolFor(action) {
5146
+ return DEFAULT_NEXT_TOOL_BY_ACTION[action];
5147
+ }
5148
+ function createNextStepBuilder(targets) {
5149
+ return function nextStep(input) {
5150
+ const i = input;
5151
+ const base = {
5152
+ next_action: input.nextAction,
5153
+ safe_to_continue: input.safeToContinue,
5154
+ reason: input.reason
5155
+ };
5156
+ if (i.nextTool === null) {
5157
+ return { ...base, next_tool_omitted_reason: i.nextToolOmittedReason ?? "no next tool" };
5158
+ }
5159
+ const target = targets[i.nextTool];
5160
+ if (!target) {
5161
+ return { ...base, next_tool_omitted_reason: `${i.nextTool} is not a registered next-step target` };
5162
+ }
5163
+ const problem = target.validate(i.nextArguments);
5164
+ if (problem) {
5165
+ return { ...base, next_tool_omitted_reason: `next_arguments do not parse under ${i.nextTool}: ${problem}` };
5166
+ }
5167
+ return {
5168
+ ...base,
5169
+ next_tool: renderNextTool(target.role, i.nextTool),
5170
+ next_tool_server: NEXT_TOOL_SERVER_NAMES[target.role],
5171
+ next_tool_name: i.nextTool,
5172
+ next_tool_server_role: target.role,
5173
+ next_arguments: i.nextArguments
5174
+ };
5175
+ };
5176
+ }
5177
+
4927
5178
  // src/node-version.ts
4928
5179
  var HAVEN_MINIMUM_NODE_VERSION = "22.0.0";
4929
5180
  function parseNodeVersion(value) {
@@ -5007,6 +5258,6 @@ function sameUrl(a, b) {
5007
5258
  }
5008
5259
  }
5009
5260
 
5010
- export { AGENT_APPROVAL_RELAY_JSON_SENTENCE, AGENT_APPROVAL_RELAY_PROSE_SENTENCE, AGENT_COMMAND_MODIFICATION_SENTENCE, AGENT_JSON_MODE_SENTENCE, AGENT_LOCAL_KEY_SENTENCE, AGENT_NETWORK_ACCESS_SENTENCE, AGENT_ONBOARDING_PROMPT, AGENT_PAYMENT_FAILURE_CODE_VALUES, AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, AGENT_README_SECTION_MD, AGENT_SECRET_HYGIENE_SENTENCE, AGENT_WIRING_COLLISION_RELAY_SENTENCE, AgentPaymentFailureCode, AgentPaymentFailureCodeDescriptions, AgentPaymentFailureCodeSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, AgentPaymentWarningCode, CONNECTOR_PACKAGE_NAME, DEFAULT_CONFIRMATION_TIMEOUT_MS, DISCOVERY_MAX_BYTES, ERC7710_ASSET_TRANSFER_METHOD, HAVEN_AGENT_RUNBOOK_MD, HAVEN_CONNECTOR_CHANNEL, HAVEN_MINIMUM_NODE_VERSION, HAVEN_SKILL_BODY_MD, HAVEN_SKILL_MD, HavenApiError, HavenClient, HavenError, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, HavenZeroSettlementHashError, MERCHANT_DISCOVERY_PATHS, MerchantTimeoutError, RECEIPT_VERSION, SIGNER_UPDATE_FALLBACK, SKILL_FOLDER_NAME, SWEEP_BASE_CHAIN_ID, SWEEP_BASE_SEPOLIA_CHAIN_ID, SWEEP_BASE_SEPOLIA_USDC_ADDRESS, SWEEP_BASE_USDC_ADDRESS, SignerRefusalCode, TRANSFER_WITH_AUTHORIZATION_TYPES, X402AlreadySettledError, X402PaymentHeaderValidationError, X402UnexpectedStatusError, X402_LEGACY_PAYMENT_HEADER_NAME, X402_MAX_AUTHORIZATION_WINDOW_SECONDS, X402_PAYMENT_HEADER_NAME, X402_PAYMENT_HEADER_NAMES_SENT, X402_PAYMENT_REQUIRED_HEADER_NAME, X402_PAYMENT_RESPONSE_HEADER_NAME, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS, addressFromKey, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, compareNodeVersions, composeDescription, connectorRerunCommand, connectorSpec, decodeBase64Json, decodeBase64Utf8, discoverMerchantMcpUrl, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, havenTools, isConnectorChannel, isErc7710Option, isSupportedNodeVersion, isSweepableChain, isZeroSettlementTxHash, normalizePaymentRequired, parsePaymentRequired, parsePaymentRequiredResponse, readX402ReceiptPayer, resolveConnectorChannel, resolveTokenFromAddress, sameUrl, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signHash, signUserOpTypedDataForDelegation, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, toolDescriptions, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, verifyPaymentReceipt, verifySignature, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402V2PaymentEnvelope };
5261
+ export { AGENT_APPROVAL_RELAY_JSON_SENTENCE, AGENT_APPROVAL_RELAY_PROSE_SENTENCE, AGENT_COMMAND_MODIFICATION_SENTENCE, AGENT_JSON_MODE_SENTENCE, AGENT_LOCAL_KEY_SENTENCE, AGENT_NETWORK_ACCESS_SENTENCE, AGENT_ONBOARDING_PROMPT, AGENT_PAYMENT_FAILURE_CODE_VALUES, AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, AGENT_README_SECTION_MD, AGENT_SECRET_HYGIENE_SENTENCE, AGENT_WIRING_COLLISION_RELAY_SENTENCE, AgentPaymentFailureCode, AgentPaymentFailureCodeDescriptions, AgentPaymentFailureCodeSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, AgentPaymentWarningCode, CONNECTOR_PACKAGE_NAME, DEFAULT_CONFIRMATION_TIMEOUT_MS, DEFAULT_NEXT_TOOL_BY_ACTION, DISCOVERY_MAX_BYTES, ERC7710_ASSET_TRANSFER_METHOD, HAVEN_AGENT_RUNBOOK_MD, HAVEN_CONNECTOR_CHANNEL, HAVEN_MINIMUM_NODE_VERSION, HAVEN_SKILL_BODY_MD, HAVEN_SKILL_MD, HavenApiError, HavenClient, HavenError, HavenInsecureRetryTargetError, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, HavenZeroSettlementHashError, INSECURE_RETRY_TARGET_CODE, MERCHANT_DISCOVERY_PATHS, MerchantTimeoutError, NEXT_TOOL_SERVER_NAMES, NEXT_TOOL_SERVER_ROLES, RECEIPT_VERSION, SIGNER_UPDATE_FALLBACK, SKILL_FOLDER_NAME, SWEEP_BASE_CHAIN_ID, SWEEP_BASE_SEPOLIA_CHAIN_ID, SWEEP_BASE_SEPOLIA_USDC_ADDRESS, SWEEP_BASE_USDC_ADDRESS, SignerRefusalCode, TRANSFER_WITH_AUTHORIZATION_TYPES, X402AlreadySettledError, X402PaymentHeaderValidationError, X402UnexpectedStatusError, X402_LEGACY_PAYMENT_HEADER_NAME, X402_MAX_AUTHORIZATION_WINDOW_SECONDS, X402_PAYMENT_HEADER_NAME, X402_PAYMENT_HEADER_NAMES_SENT, X402_PAYMENT_REQUIRED_HEADER_NAME, X402_PAYMENT_RESPONSE_HEADER_NAME, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS, addressFromKey, assertSecureX402RetryTarget, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, compareNodeVersions, composeDescription, connectorRerunCommand, connectorSpec, createNextStepBuilder, decodeBase64Json, decodeBase64Utf8, defaultNextToolFor, discoverMerchantMcpUrl, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, havenTools, isConnectorChannel, isErc7710Option, isSecureX402RetryTarget, isSupportedNodeVersion, isSweepableChain, isZeroSettlementTxHash, normalizePaymentRequired, parseNextTool, parsePaymentRequired, parsePaymentRequiredResponse, readX402ReceiptPayer, renderNextTool, resolveConnectorChannel, resolveTokenFromAddress, resolveX402RetryTarget, sameUrl, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signHash, signUserOpTypedDataForDelegation, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, toolDescriptions, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, verifyPaymentReceipt, verifySignature, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402V2PaymentEnvelope };
5011
5262
  //# sourceMappingURL=index.js.map
5012
5263
  //# sourceMappingURL=index.js.map