@haven_ai/sdk 0.1.37-alpha.0 → 0.2.1-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.d.cts CHANGED
@@ -1,59 +1,5 @@
1
1
  import { PaymentRequirements } from 'x402/types';
2
2
 
3
- /**
4
- * Verifiable payment receipts.
5
- *
6
- * A self-contained proof bundle for a settled Haven payment that anyone can
7
- * verify **independently of Haven**. The anchor is the agent delegate's
8
- * signature over the on-chain transfer hash: recover the signer and confirm it
9
- * is the agent's delegate, and you have cryptographic proof the agent authorised
10
- * exactly this transfer — no need to trust Haven's backend. The on-chain
11
- * `txHash` is the settlement source of truth (verify on any explorer).
12
- *
13
- * This lives in the SDK so agents and users can verify receipts client-side
14
- * with zero Haven trust.
15
- */
16
- declare const RECEIPT_VERSION = "haven-receipt-1";
17
- interface PaymentReceipt {
18
- version: typeof RECEIPT_VERSION;
19
- paymentId: string;
20
- payment: {
21
- token: string;
22
- tokenAddress: string;
23
- amount: string;
24
- amountSek: string | null;
25
- recipient: string;
26
- safe: string;
27
- chainId: number;
28
- settledAt: string | null;
29
- resourceUrl: string | null;
30
- };
31
- /** The agent's cryptographic authorisation — what makes the receipt verifiable. */
32
- authorization: {
33
- delegate: string;
34
- signHash: string;
35
- signature: string | null;
36
- };
37
- onChain: {
38
- txHash: string | null;
39
- chainId: number;
40
- };
41
- }
42
- type ReceiptVerification = {
43
- verified: true;
44
- recoveredSigner: string;
45
- } | {
46
- verified: false;
47
- reason: 'missing_signature' | 'bad_signature' | 'signer_mismatch';
48
- recoveredSigner?: string;
49
- };
50
- /**
51
- * Verify a receipt independently: recover the signer from the authorisation and
52
- * confirm it is the agent's delegate. Pure — `recover` is injectable but
53
- * defaults to standard ECDSA recovery, so this runs anywhere (no Haven backend).
54
- */
55
- declare function verifyPaymentReceipt(receipt: PaymentReceipt, recover?: (hash: string, signature: string) => string): ReceiptVerification;
56
-
57
3
  interface HavenClientConfig {
58
4
  /** Haven API key (sk_agent_xxx) */
59
5
  apiKey: string;
@@ -138,7 +84,14 @@ interface SignData {
138
84
  };
139
85
  /** Breakdown of values that were hashed — useful for debugging */
140
86
  components: {
87
+ /** @deprecated #2908 — same value as `payer_account`; the server drops it at #2914. */
141
88
  safe: string;
89
+ /**
90
+ * #2907 — the account-vocabulary twin of `safe`: the PAYER account
91
+ * (the user's smart account). Not to be confused with `account`, which on
92
+ * the funding shapes holds the DELEGATE account address.
93
+ */
94
+ payer_account?: string;
142
95
  token: string;
143
96
  to: string;
144
97
  amount: string;
@@ -522,6 +475,15 @@ interface HavenAgent {
522
475
  id: string;
523
476
  name: string;
524
477
  status: string;
478
+ /**
479
+ * The agent's Haven account (smart account) address — #2908, the
480
+ * account-vocabulary name. Same value as {@link HavenAgent.safeAddress}.
481
+ */
482
+ accountAddress: string;
483
+ /**
484
+ * @deprecated #2908 — same value as {@link HavenAgent.accountAddress}.
485
+ * Removed in the release after the one carrying #2908 (#2914).
486
+ */
525
487
  safeAddress: string;
526
488
  delegateAddress: string;
527
489
  chainId: number;
@@ -563,6 +525,12 @@ interface HavenAllowance {
563
525
  }
564
526
  interface HavenAllowanceSummary {
565
527
  agentId: string;
528
+ /** #2908 — the account-vocabulary name; same value as `safeAddress`. */
529
+ accountAddress: string;
530
+ /**
531
+ * @deprecated #2908 — same value as {@link HavenAllowanceSummary.accountAddress}.
532
+ * Removed in the release after the one carrying #2908 (#2914).
533
+ */
566
534
  safeAddress: string;
567
535
  delegateAddress: string;
568
536
  chainId: number;
@@ -656,6 +624,25 @@ interface HavenAgentSummary extends HavenAgent {
656
624
  spend_authority_readiness: HavenAgentReadiness;
657
625
  allowances: HavenAgentAllowanceSummary[];
658
626
  }
627
+ /**
628
+ * #2960 — one party vocabulary for "who paid" a Haven payment, additive
629
+ * alongside every existing lone `payer*`/`*Address` field (same discipline
630
+ * as the #2907 `safe`/`account` dual-emit, except these four are DISTINCT
631
+ * addresses, not same-value twins of one old field).
632
+ */
633
+ interface PaymentParties {
634
+ treasuryAccount: string | null;
635
+ delegate: string | null;
636
+ delegateAccount: string | null;
637
+ merchant: string | null;
638
+ }
639
+ /** @internal wire shape of {@link PaymentParties}. */
640
+ interface RawPaymentParties {
641
+ treasury_account: string | null;
642
+ delegate: string | null;
643
+ delegate_account: string | null;
644
+ merchant: string | null;
645
+ }
659
646
  interface HavenPaymentReceipt {
660
647
  id: string;
661
648
  paymentId: string;
@@ -663,11 +650,28 @@ interface HavenPaymentReceipt {
663
650
  approvalRequestId?: string | null;
664
651
  rail: string;
665
652
  proofStatus: string;
653
+ /**
654
+ * @deprecated (#2998) meaning depends on the settlement scheme — the
655
+ * account → delegate funding transaction on eip3009, the (only) settlement
656
+ * transaction on erc7710. Prefer {@link fundingTxHash} / {@link settlementTxHash}, which
657
+ * name which is which.
658
+ */
666
659
  txHash: string;
660
+ /** The account → delegate funding transaction, relayed by Haven (#2998); null on erc7710 (no funding leg) and on retired mpp-rail rows. */
661
+ fundingTxHash: string | null;
662
+ /**
663
+ * The delegate → merchant settlement transaction (#2998). Trust level differs
664
+ * by scheme: on erc7710 it is `txHash` itself and Haven VERIFIED it on-chain
665
+ * before the receipt existed; on eip3009 it is the merchant's claim as relayed
666
+ * (PAYMENT-RESPONSE), NOT verified on-chain by Haven — cite it as such.
667
+ */
668
+ settlementTxHash: string | null;
667
669
  chainId: number;
668
670
  resourceUrl: string;
669
671
  merchantAddress: string | null;
670
672
  payerAddress: string;
673
+ /** #2960: additive alongside `payerAddress` above (`parties.treasury_account` only). */
674
+ parties?: PaymentParties;
671
675
  settlementAddress: string;
672
676
  tokenSymbol: string;
673
677
  tokenAddress: string;
@@ -843,9 +847,14 @@ declare const AgentPaymentNextAction: {
843
847
  */
844
848
  readonly PaymentWindowExpired: "payment_window_expired";
845
849
  /**
846
- * Stop and tell the user that the originating Safe needs to be funded or
850
+ * Stop and tell the user that the originating account needs to be funded or
847
851
  * the agent's per-token allowance needs to be raised before the payment
848
852
  * can succeed. A user approval will not fix this state on its own.
853
+ *
854
+ * #2908: the wire twin `fund_account_or_raise_allowance`
855
+ * ({@link AgentPaymentNextActionAccountAlias}) means the same thing; the
856
+ * server keeps emitting THIS value until #2914. Compare via
857
+ * {@link canonicalAgentPaymentNextAction}.
849
858
  */
850
859
  readonly FundSafeOrRaiseAllowance: "fund_safe_or_raise_allowance";
851
860
  /**
@@ -854,19 +863,73 @@ declare const AgentPaymentNextAction: {
854
863
  * return those funds to the originating Safe.
855
864
  */
856
865
  readonly SweepStrandedFunds: "sweep_stranded_funds";
866
+ /**
867
+ * #2970: a `submitted` erc7710 x402 intent whose settlement window has
868
+ * passed with no on-chain settlement evidence Haven could verify. Distinct
869
+ * from {@link CheckStatusLater}, which this REPLACES once the window is
870
+ * past — but it is not futile: Haven's settlement sweep (120s tick) scans
871
+ * each candidate over its own window plus a 120s clock-skew allowance, so
872
+ * it can still attribute the settlement for a short while after this value
873
+ * first appears. Poll {@link CheckStatusLater}'s tool
874
+ * (`haven_get_payment_status`) once more, roughly two minutes later; if it
875
+ * still shows no evidence, tell the user the goods were delivered but
876
+ * Haven holds no verified settlement evidence for this payment. If the
877
+ * agent holds the merchant's real settlement transaction hash (from
878
+ * `PAYMENT-RESPONSE`'s `transaction` field, or a prior settle/complete
879
+ * result's `settlement_tx_hash`), report it with the hosted
880
+ * `haven_report_settlement_evidence` tool instead of waiting —
881
+ * `haven_report_x402_outcome` takes no hash and refuses a non-`confirmed`
882
+ * intent.
883
+ */
884
+ readonly AwaitingSettlementEvidence: "awaiting_settlement_evidence";
857
885
  };
858
886
  type AgentPaymentNextAction = (typeof AgentPaymentNextAction)[keyof typeof AgentPaymentNextAction];
887
+ /**
888
+ * #2908 (naming epic #2906): the account-vocabulary twin of
889
+ * {@link AgentPaymentNextAction.FundSafeOrRaiseAllowance}. The server ACCEPTS
890
+ * and DOCUMENTS this value from #2907 but keeps EMITTING the old one through
891
+ * the compatibility window; the emitted value flips at #2914.
892
+ *
893
+ * Deliberately declared beside `AgentPaymentNextAction` rather than inside
894
+ * it: the backend keeps a hand-mirror of that const, parity-pinned key-for-key
895
+ * and value-for-value (`agent-payment-taxonomy.parity.test.ts`), and the
896
+ * served `x-enumDescriptions` are the SDK's strings verbatim. Both consts
897
+ * move together at #2914; until then this alias is how a client handles both
898
+ * wire values without forking the taxonomy.
899
+ */
900
+ declare const AgentPaymentNextActionAccountAlias: {
901
+ /** Account-vocabulary twin of `fund_safe_or_raise_allowance`; same meaning. */
902
+ readonly FundAccountOrRaiseAllowance: "fund_account_or_raise_allowance";
903
+ };
904
+ type AgentPaymentNextActionAccountAlias = (typeof AgentPaymentNextActionAccountAlias)[keyof typeof AgentPaymentNextActionAccountAlias];
905
+ /** Every `next_action` value a server may put on the wire during the #2908 window. */
906
+ type AgentPaymentNextActionWire = AgentPaymentNextAction | AgentPaymentNextActionAccountAlias;
907
+ /**
908
+ * Collapse the #2908 account-vocabulary alias onto its canonical taxonomy
909
+ * value, and pass every other value through untouched.
910
+ *
911
+ * This is the one seam a `switch` over `AgentPaymentNextAction` needs: a
912
+ * case on `FundSafeOrRaiseAllowance` matches a server that emits either
913
+ * spelling, and no case falls through because the alias arrived. Unknown
914
+ * strings are returned as-is (the SDK never invents a value), so the return
915
+ * type is exactly the input type widened by the canonical value.
916
+ */
917
+ declare function canonicalAgentPaymentNextAction<T extends string | null | undefined>(value: T): Exclude<T, AgentPaymentNextActionAccountAlias> | typeof AgentPaymentNextAction.FundSafeOrRaiseAllowance;
918
+ /** True for EITHER spelling of the fund-or-raise-allowance next action (#2908). */
919
+ declare function isFundAccountOrRaiseAllowance(value: string | null | undefined): boolean;
859
920
  declare const AgentPaymentFailureCode: {
860
921
  /** A merchant-authoritative x402 price exceeds the caller's pre-funding max_amount cap. */
861
922
  readonly PriceExceedsMax: "PRICE_EXCEEDS_MAX";
862
923
  /** The x402 funding/quote window expired before the signer or hosted settle step could finish. */
863
924
  readonly PaymentWindowExpired: "PAYMENT_WINDOW_EXPIRED";
864
- /** The Haven funding leg succeeded, but the merchant rejected the paid retry. */
925
+ /** The merchant rejected the paid retry. On eip3009 the funding leg had succeeded (sweep);
926
+ * on erc7710 there is no funding leg — nothing to sweep, follow the message (#2983). */
865
927
  readonly MerchantRejectedAfterFunding: "MERCHANT_REJECTED_AFTER_FUNDING";
866
928
  /** #1300 review: funding is on-chain but the merchant never ANSWERED the
867
929
  * paid retry within the timeout. NOT proof of rejection — the merchant
868
- * holds a valid EIP-3009 authorization and may still settle late, so the
869
- * guidance is verify-then-sweep, never blind sweep. */
930
+ * may still settle late, so the guidance is verify-then-act. On eip3009
931
+ * the funding leg had succeeded (verify-then-sweep); on erc7710 there is
932
+ * no funding leg — nothing to sweep, follow the message (#3000). */
870
933
  readonly MerchantUnresponsiveAfterFunding: "MERCHANT_UNRESPONSIVE_AFTER_FUNDING";
871
934
  /**
872
935
  * #1307: the caller omitted merchant_url/tool_name (asking Haven to
@@ -893,6 +956,16 @@ declare const AgentPaymentFailureCode: {
893
956
  * The fallback is the exact atomic `max_amount`.
894
957
  */
895
958
  readonly MaxAmountUnconvertible: "MAX_AMOUNT_UNCONVERTIBLE";
959
+ /**
960
+ * #2979: the merchant answered a `tools/call` probe with its own
961
+ * machine-readable "cannot settle right now" refusal (HTTP 503,
962
+ * `{ error: 'merchant_not_ready', reason_code, ... }`) instead of a 402
963
+ * challenge — e.g. its settlement wallet is out of gas. No 402 was ever
964
+ * issued and no payment was created; this is honest and (per
965
+ * `retry_after_s`, when present) usually transient, unlike a permanent
966
+ * endpoint miss.
967
+ */
968
+ readonly MerchantNotReady: "MERCHANT_NOT_READY";
896
969
  };
897
970
  type AgentPaymentFailureCode = (typeof AgentPaymentFailureCode)[keyof typeof AgentPaymentFailureCode];
898
971
  /**
@@ -935,8 +1008,8 @@ type AgentPaymentRail = (typeof AgentPaymentRail)[keyof typeof AgentPaymentRail]
935
1008
  type PaymentPhase = AgentPaymentPhase;
936
1009
  type PaymentNextAction = AgentPaymentNextAction;
937
1010
  declare const AGENT_PAYMENT_PHASE_VALUES: ("rejected" | "expired" | "failed" | "agent_signature_required" | "payment_submitted" | "payment_confirmed" | "user_approval_required" | "user_execution_required" | "waiting_for_additional_approvals" | "funding_sent" | "insufficient_funds" | "funded_but_unsettled")[];
938
- declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "retry_with_explicit_context" | "payment_window_expired" | "fund_safe_or_raise_allowance" | "sweep_stranded_funds")[];
939
- declare const AGENT_PAYMENT_FAILURE_CODE_VALUES: ("PRICE_EXCEEDS_MAX" | "PAYMENT_WINDOW_EXPIRED" | "MERCHANT_REJECTED_AFTER_FUNDING" | "MERCHANT_UNRESPONSIVE_AFTER_FUNDING" | "MERCHANT_CALL_CONTEXT_UNAVAILABLE" | "AMBIGUOUS_MAX_AMOUNT" | "MAX_AMOUNT_UNCONVERTIBLE")[];
1011
+ declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "retry_with_explicit_context" | "payment_window_expired" | "fund_safe_or_raise_allowance" | "sweep_stranded_funds" | "awaiting_settlement_evidence")[];
1012
+ declare const AGENT_PAYMENT_FAILURE_CODE_VALUES: ("PRICE_EXCEEDS_MAX" | "PAYMENT_WINDOW_EXPIRED" | "MERCHANT_REJECTED_AFTER_FUNDING" | "MERCHANT_UNRESPONSIVE_AFTER_FUNDING" | "MERCHANT_CALL_CONTEXT_UNAVAILABLE" | "AMBIGUOUS_MAX_AMOUNT" | "MAX_AMOUNT_UNCONVERTIBLE" | "MERCHANT_NOT_READY")[];
940
1013
  declare const AGENT_PAYMENT_RAIL_VALUES: ("x402" | "mpp_demo" | "mpp_crypto" | "stripe_deposit" | "spt" | "direct" | "mpp")[];
941
1014
  declare const AgentPaymentPhaseDescriptions: Record<AgentPaymentPhase, string>;
942
1015
  declare const AgentPaymentNextActionDescriptions: Record<AgentPaymentNextAction, string>;
@@ -978,6 +1051,23 @@ declare const AgentPaymentWarningCode: {
978
1051
  * guidance shown here may be optimistic.
979
1052
  */
980
1053
  readonly AllowanceReadOptimistic: "ALLOWANCE_READ_OPTIMISTIC";
1054
+ /**
1055
+ * #2991: the quote tools' `expected_settlement_scheme` prediction of what
1056
+ * `haven_prepare_catalog_purchase` / `haven_pay_mcp_tool` will actually
1057
+ * select could not be computed — the agent's execution rail could not be
1058
+ * read from Haven, so `expected_settlement_scheme` is `null` rather than a
1059
+ * guess. `accepted_scheme` (the merchant's offer) is unaffected.
1060
+ */
1061
+ readonly X402SchemeUnknown: "X402_SCHEME_UNKNOWN";
1062
+ /**
1063
+ * #2968: the merchant answered 200 and handed over goods, but Haven holds NO
1064
+ * on-chain evidence that the payment moved. `settled: false` beside this code
1065
+ * is not a failure — it is the absence of proof, and the two must travel
1066
+ * together so an agent can tell "the user has the goods" apart from "the
1067
+ * money moved". Carries the intent's `expires_at`: after that instant the
1068
+ * settlement can no longer land at all.
1069
+ */
1070
+ readonly SettlementUnconfirmed: "SETTLEMENT_UNCONFIRMED";
981
1071
  };
982
1072
  type AgentPaymentWarningCode = (typeof AgentPaymentWarningCode)[keyof typeof AgentPaymentWarningCode];
983
1073
  interface AgentPaymentWarning {
@@ -992,7 +1082,15 @@ interface AgentPaymentWarning {
992
1082
  * (payment_required) are named in `reason` and taken from the SAME response.
993
1083
  */
994
1084
  interface AgentNextStep {
995
- next_action: AgentPaymentNextAction;
1085
+ /**
1086
+ * From `AgentPaymentNextAction`, widened by the #2908 account-vocabulary
1087
+ * alias for the compatibility window: the hosted server keeps emitting
1088
+ * `fund_safe_or_raise_allowance` until #2914, but a client compiled against
1089
+ * this type must not reject `fund_account_or_raise_allowance` when the flip
1090
+ * lands. Compare through {@link canonicalAgentPaymentNextAction} or
1091
+ * {@link isFundAccountOrRaiseAllowance}, never by one literal.
1092
+ */
1093
+ next_action: AgentPaymentNextActionWire;
996
1094
  /**
997
1095
  * Claude-family namespaced tool name for the next call
998
1096
  * (`mcp__<server>__<tool>`), when one exists.
@@ -1090,6 +1188,8 @@ interface PaymentStatusResult {
1090
1188
  merchantAddress: string | null;
1091
1189
  /** Delegate EOA captured on the payment intent when it was created. */
1092
1190
  payerAddress?: string | null;
1191
+ /** #2960: additive alongside `payerAddress` above (`parties.delegate` only). */
1192
+ parties?: PaymentParties;
1093
1193
  txHash: string | null;
1094
1194
  expiresAt: string;
1095
1195
  chainId: number;
@@ -1167,13 +1267,21 @@ interface HavenCatalogEntry {
1167
1267
  verifiedAt: string | null;
1168
1268
  /**
1169
1269
  * Where the entry came from. `operator` = curated in migrations/scripts
1170
- * (the operator vouches; no verification badges). `ingestion` = submitted
1270
+ * (the operator vouches for the listing; the catalog refresh probe still
1271
+ * checks the endpoint, see `verifiedPayable`). `ingestion` = submitted
1171
1272
  * through the Verified Payable Directory and passed domain-ownership proof
1172
1273
  * plus the read-only quote probe.
1173
1274
  */
1174
1275
  source: 'operator' | 'ingestion';
1175
- /** True only for `ingestion` entries. See the epic's trust claim (never merchant honesty or quality). */
1276
+ /** True only for `ingestion` entries — the one ownership claim. See the epic's trust claim (never merchant honesty or quality). */
1176
1277
  domainVerified: boolean;
1278
+ /**
1279
+ * True when Haven watched this endpoint answer a live quote (#2978): the
1280
+ * directory probe for `ingestion` rows, the periodic catalog refresh probe
1281
+ * for `operator` rows (`status === 'active'` with `verifiedAt` set). False
1282
+ * for a degraded row of either source. `discoverTools({ verified:
1283
+ * 'verified' })` filters on this field, not on `source`.
1284
+ */
1177
1285
  verifiedPayable: boolean;
1178
1286
  }
1179
1287
  /** @internal */
@@ -1217,7 +1325,17 @@ declare class MerchantTimeoutError extends HavenApiError {
1217
1325
  }
1218
1326
  declare class X402UnexpectedStatusError extends HavenApiError {
1219
1327
  readonly x402ErrorCode: "unexpected_non_402_status";
1220
- constructor(message: string, statusCode: number);
1328
+ /**
1329
+ * #2979: `body` is the merchant's own JSON, when the non-402 response
1330
+ * carried one — e.g. the demo merchant's `/mcp` readiness gate answers
1331
+ * `503 { error: 'merchant_not_ready', reason_code, ... }`. Optional and
1332
+ * best-effort: a non-JSON or unreadable body leaves this `undefined`, same
1333
+ * as before this field existed. Consumers key on it (not on the message
1334
+ * string) to distinguish an honest, machine-readable merchant refusal from
1335
+ * a genuine "this is not the x402 endpoint" miss, which otherwise look
1336
+ * identical — both are just "some non-402 status".
1337
+ */
1338
+ constructor(message: string, statusCode: number, body?: unknown);
1221
1339
  }
1222
1340
  /**
1223
1341
  * #1521: the idempotency key resolved to a payment that has already settled,
@@ -1266,6 +1384,19 @@ declare class HavenPaymentStateError extends HavenApiError {
1266
1384
  declare class HavenSigningError extends HavenError {
1267
1385
  constructor(message: string);
1268
1386
  }
1387
+ /**
1388
+ * #2972: `MerchantCompletion.reportSettlementEvidence` /
1389
+ * `HavenClient.reportSettlementEvidence` refuse a `0x00…00` settlement hash
1390
+ * BEFORE any network call — see `isZeroSettlementTxHash`. That marker is
1391
+ * never a real transaction (the demo merchant's own "delivered, not settled"
1392
+ * value), so posting it to `POST /machine-payments/evidence` could only ever
1393
+ * come back refused, at the cost of a real round trip. A typed error rather
1394
+ * than a `HavenApiError`-shaped 400: no request was ever attempted, so there
1395
+ * is no HTTP status or response body to carry.
1396
+ */
1397
+ declare class HavenZeroSettlementHashError extends HavenError {
1398
+ constructor(paymentId: string);
1399
+ }
1269
1400
  /**
1270
1401
  * Refusal codes the local signer returns when it does not recognise the
1271
1402
  * VERSION of a Haven-signed binding it was asked to sign (#1309). Distinct
@@ -1327,6 +1458,73 @@ declare class HavenTimeoutError extends HavenError {
1327
1458
  constructor(paymentId: string);
1328
1459
  }
1329
1460
 
1461
+ /**
1462
+ * Verifiable payment receipts.
1463
+ *
1464
+ * A self-contained proof bundle for a settled Haven payment that anyone can
1465
+ * verify **independently of Haven**. The anchor is the agent delegate's
1466
+ * signature over the on-chain transfer hash: recover the signer and confirm it
1467
+ * is the agent's delegate, and you have cryptographic proof the agent authorised
1468
+ * exactly this transfer — no need to trust Haven's backend. The on-chain
1469
+ * `txHash` is the settlement source of truth (verify on any explorer).
1470
+ *
1471
+ * This lives in the SDK so agents and users can verify receipts client-side
1472
+ * with zero Haven trust.
1473
+ */
1474
+ declare const RECEIPT_VERSION = "haven-receipt-1";
1475
+ interface PaymentReceipt {
1476
+ version: typeof RECEIPT_VERSION;
1477
+ paymentId: string;
1478
+ payment: {
1479
+ token: string;
1480
+ tokenAddress: string;
1481
+ amount: string;
1482
+ amountSek: string | null;
1483
+ recipient: string;
1484
+ /** @deprecated since #2907 — read `account`; removed in #2914 (the release after the naming window). Same value as `account`. */
1485
+ safe: string;
1486
+ /**
1487
+ * The payer's smart-account address (#2907 twin of `safe`). Optional for
1488
+ * the window: a server from before the twin emits `safe` only.
1489
+ */
1490
+ account?: string;
1491
+ /**
1492
+ * #2960: one party vocabulary for "who paid", additive alongside `safe`/
1493
+ * `account` above (which are `parties.treasury_account` only). Optional
1494
+ * for the window: a server from before #2960 emits neither. Ignored by
1495
+ * `verifyPaymentReceipt`, which reads only `authorization`.
1496
+ */
1497
+ parties?: RawPaymentParties;
1498
+ chainId: number;
1499
+ settledAt: string | null;
1500
+ resourceUrl: string | null;
1501
+ };
1502
+ /** The agent's cryptographic authorisation — what makes the receipt verifiable. */
1503
+ authorization: {
1504
+ delegate: string;
1505
+ signHash: string;
1506
+ signature: string | null;
1507
+ };
1508
+ onChain: {
1509
+ txHash: string | null;
1510
+ chainId: number;
1511
+ };
1512
+ }
1513
+ type ReceiptVerification = {
1514
+ verified: true;
1515
+ recoveredSigner: string;
1516
+ } | {
1517
+ verified: false;
1518
+ reason: 'missing_signature' | 'bad_signature' | 'signer_mismatch';
1519
+ recoveredSigner?: string;
1520
+ };
1521
+ /**
1522
+ * Verify a receipt independently: recover the signer from the authorisation and
1523
+ * confirm it is the agent's delegate. Pure — `recover` is injectable but
1524
+ * defaults to standard ECDSA recovery, so this runs anywhere (no Haven backend).
1525
+ */
1526
+ declare function verifyPaymentReceipt(receipt: PaymentReceipt, recover?: (hash: string, signature: string) => string): ReceiptVerification;
1527
+
1330
1528
  /**
1331
1529
  * Gasless delegate-sweep primitives — the single source of truth shared by the
1332
1530
  * edge signer (which signs) and the Haven backend (which relays).
@@ -1542,6 +1740,38 @@ interface X402MerchantOutcomeReport {
1542
1740
  resourceUrl: string;
1543
1741
  recorded: 'reconciliation_event' | 'evidence';
1544
1742
  }
1743
+ /**
1744
+ * #2970: what `reportEvidence` learned about the report it just made.
1745
+ *
1746
+ * `confirmed` mirrors the backend's 202 (`modules/mpp/evidence.ts`) — the
1747
+ * intent is now `confirmed` (or was already, on the funding-leg path) with
1748
+ * THIS hash recorded. `retryable` mirrors its 503 (`settlement_unobservable`,
1749
+ * exhausted the retry budget above): the chain could not be read, or the
1750
+ * transaction is not mined yet — ask again later. `refused` mirrors every
1751
+ * terminal refusal (409 `settlement_unverified`, a validation error, an
1752
+ * unknown payment id, or a transport failure with no HTTP status at all,
1753
+ * reported as `statusCode: 0`) — reporting the same hash again will not
1754
+ * change the answer.
1755
+ */
1756
+ type EvidenceReportOutcome = {
1757
+ outcome: 'confirmed';
1758
+ } | {
1759
+ outcome: 'retryable';
1760
+ statusCode: number | undefined;
1761
+ } | {
1762
+ outcome: 'refused';
1763
+ statusCode: number;
1764
+ };
1765
+ /**
1766
+ * #2970: a hash of the form `0x00…00` is never a real transaction — it is the
1767
+ * demo merchant's own "delivered, not settled" marker (`ZERO_TX_HASH` in
1768
+ * `packages/demo-merchant-mcp/src/x402.ts`), reused rather than invented here
1769
+ * so the hosted gate and any other consumer recognise it the same way. Treated
1770
+ * as equivalent to "no hash was reported": there is nothing on-chain to verify,
1771
+ * so asking the backend to look is a wasted round trip that can only ever
1772
+ * resolve to a refusal.
1773
+ */
1774
+ declare function isZeroSettlementTxHash(hash: string | null | undefined): boolean;
1545
1775
 
1546
1776
  declare class HavenClient {
1547
1777
  private readonly delegateKey;
@@ -1766,10 +1996,13 @@ declare class HavenClient {
1766
1996
  search?: string;
1767
1997
  rail?: 'x402' | 'mpp';
1768
1998
  /**
1769
- * Filter on the entry's provenance (epic #1717): `'verified'` returns
1770
- * only self-submitted, domain-verified, probe-verified directory
1771
- * entries; `'operator'` only the operator-curated ones; `'any'` (the
1772
- * default) returns the merged listing.
1999
+ * `'verified'` (epic #1717, #2978) returns entries whose endpoint Haven
2000
+ * watched answer a live quote — `verifiedPayable === true` — from
2001
+ * EITHER source: an operator-curated row that keeps passing its
2002
+ * periodic 402 probe, or a self-submitted row that also passed
2003
+ * domain-ownership proof. It is not a provenance filter; `'operator'`
2004
+ * still filters on provenance (`source === 'operator'`) regardless of
2005
+ * badge state, and `'any'` (the default) returns the merged listing.
1773
2006
  */
1774
2007
  verified?: 'any' | 'verified' | 'operator';
1775
2008
  }): Promise<HavenCatalogEntry[]>;
@@ -2019,6 +2252,15 @@ declare class HavenClient {
2019
2252
  ok: boolean;
2020
2253
  body: unknown;
2021
2254
  settlementTxHash?: string;
2255
+ /**
2256
+ * #2970: what the evidence report (below) learned, when one was made.
2257
+ * `undefined` when there was no hash to report at all — no funding tx on
2258
+ * the erc7710 branch and no (or a zero) merchant-reported settlement hash.
2259
+ * The hosted erc7710 settle/complete gate reads this to decide whether
2260
+ * `settled: true` is honest; the 3009 branch's `settled: true` does not
2261
+ * need it — see `paid-mcp-completion.ts` for why.
2262
+ */
2263
+ evidenceOutcome?: EvidenceReportOutcome;
2022
2264
  }>;
2023
2265
  /**
2024
2266
  * #2292: report the outcome of a merchant retry the AGENT performed.
@@ -2035,6 +2277,17 @@ declare class HavenClient {
2035
2277
  merchantStatus: number;
2036
2278
  merchantBody?: string;
2037
2279
  }): Promise<X402MerchantOutcomeReport>;
2280
+ /**
2281
+ * #2972: report the merchant's real settlement transaction hash for an
2282
+ * erc7710 x402 payment — the remedy for `DELIVERED_UNSETTLED` /
2283
+ * `SETTLEMENT_PENDING` / `awaiting_settlement_evidence` when the agent
2284
+ * holds the hash (`PAYMENT-RESPONSE.transaction`, or a prior settle/
2285
+ * complete result's `settlement_tx_hash`) and Haven does not. See
2286
+ * `MerchantCompletion.reportSettlementEvidence` for the fail-closed
2287
+ * verification this posts into (`observeErc7710Settlement`) and the
2288
+ * client-side zero-hash refusal.
2289
+ */
2290
+ reportSettlementEvidence(paymentId: string, settlementTxHash: string): Promise<EvidenceReportOutcome>;
2038
2291
  /**
2039
2292
  * GET /x402/:id/merchant-call-context — the settle-leg twin of #1263's
2040
2293
  * sign-context fetch (#1307). Re-serves the stored merchant MCP-tool call
@@ -2222,8 +2475,8 @@ declare const toolDescriptions: {
2222
2475
  readonly nextActionGuidance: string;
2223
2476
  };
2224
2477
  readonly getPaymentStatus: {
2225
- readonly summary: "Fetch structured Haven payment status, including phase and nextAction taxonomy for agent recovery.";
2226
- readonly behavior: "Accepts a payment intent id and returns the full state taxonomy (phase, nextAction, rail, amount, merchant, resource url, idempotency key, message).";
2478
+ readonly summary: "Fetch structured Haven payment status for agent recovery.";
2479
+ readonly behavior: "State: phase, nextAction, rail, amount, merchant, resource, idempotency, message; parties: treasury/delegate/delegateAccount/merchant. awaiting_settlement_evidence: poll once, else unverified.";
2227
2480
  readonly nextActionGuidance: "";
2228
2481
  };
2229
2482
  readonly getResumeState: {
@@ -2234,7 +2487,7 @@ declare const toolDescriptions: {
2234
2487
  readonly getAgent: {
2235
2488
  readonly 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.";
2236
2489
  readonly 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.";
2237
- readonly behavior: "Reads identity plus the live spend-authority snapshot in one shot — 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 — 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.";
2490
+ readonly behavior: "Reads identity plus the live spend-authority snapshot in one shot — 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 — 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 (safeAddress: deprecated alias, same value), delegateAddress, chainId.";
2238
2491
  readonly nextActionGuidance: "";
2239
2492
  };
2240
2493
  readonly getAllowances: {
@@ -2274,7 +2527,7 @@ declare const toolDescriptions: {
2274
2527
  readonly 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.";
2275
2528
  };
2276
2529
  readonly sweep_delegate: {
2277
- readonly summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating Safe.";
2530
+ readonly summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating account.";
2278
2531
  readonly selectionGuidance: string;
2279
2532
  readonly behavior: string;
2280
2533
  readonly nextActionGuidance: string;
@@ -2285,6 +2538,11 @@ declare const toolDescriptions: {
2285
2538
  readonly behavior: string;
2286
2539
  readonly nextActionGuidance: string;
2287
2540
  };
2541
+ readonly reportSettlementEvidence: {
2542
+ readonly summary: "Report an erc7710 payment's real settlement transaction hash so Haven can verify it on-chain and confirm the payment.";
2543
+ readonly behavior: "Pass payment_id and settlement_tx_hash (0x + 64 hex chars) — from PAYMENT-RESPONSE or a prior settlement_tx_hash. Haven verifies on-chain before confirming; a zero, mismatched, or reverted hash is refused. Your own payments only.";
2544
+ readonly nextActionGuidance: "code DELIVERED_UNSETTLED: did not verify, do not retry — poll haven_get_payment_status. code SETTLEMENT_PENDING (retryable:true): not mined or RPC unreachable — report the same hash again shortly.";
2545
+ };
2288
2546
  };
2289
2547
  type SharedToolKey = keyof typeof toolDescriptions;
2290
2548
 
@@ -2330,7 +2588,7 @@ type SharedToolKey = keyof typeof toolDescriptions;
2330
2588
  * live sibling constant not pulled in here; if it ever is, this applies to it
2331
2589
  * too (design review, #2537).
2332
2590
  */
2333
- declare const HAVEN_SKILL_MD = "---\nname: haven-pay\ndescription: Pay for things from the user's Haven wallet within their agent rules, and set Haven up when it is not yet connected. Use when the user asks to send, pay, tip, or transfer crypto; when a request hits an HTTP 402 (x402) paywall; or when they ask to create a Haven account, create an agent, or connect one.\n---\n\n# Haven: pay from a Haven wallet\n\nThis skill lets the agent make payments from the user's Haven wallet through\nthe Haven MCP tools. Every payment is checked against the agent's on-chain\nbudget before money moves; a payment above the remaining budget is declined \u2014\nnothing is paid past the rules the user set.\n\nHosted tools run in the `mcp__haven__` namespace. Local signing tools run in\nthe `mcp__haven-signer__` namespace and keep the delegate key on this machine.\nThat namespacing is Claude-family; other runtimes name the servers by their\nown config keys (Codex: `haven`, `haven_signer`). Tool results carry the\nexact next step (`next_action`, `next_tool`, `next_arguments`, plus the\nruntime-neutral `next_tool_server` + `next_tool_name` \u2014 the bare tool name\non that logical server, whatever your runtime calls it).\nFollow those fields first; the prose below is fallback and orientation, not\nthe source of truth.\n\n## When to use this skill\n\n- The user asks to send money, pay someone, tip, donate, or transfer tokens.\n- A request returns HTTP 402 (x402): use the Haven pay tools to settle it,\n then retry the original request.\n\n## Onboarding and setup\n\nYou are in this mode when there is no Haven agent credential on this machine,\nor when your user asks you to create a Haven account, create an agent, or\nconnect one \u2014 for themselves or for someone else.\n\n**None of the tools below creates authority.** They spend a budget a human\nalready signed. There is no tool here that opens an account, mints a\ncredential, or approves a budget, so reaching for one of them to \"set Haven\nup\" cannot work; the steps are the ones in this section instead.\n\nStart by reading `/for-agents.md` on the Haven host \u2014 the origin of the\n`api_url` in your `agent.json` if you have one, otherwise the host your user\nnames. It is the full runbook: six steps, which four are your user's, and what\nto say at each hand-off.\n\nTwo of those steps you can do yourself, from the shell with `@haven_ai/cli`\n(installs the `haven` command):\n\n- `haven login` \u2014 a device-code browser flow. It prints a code and a link\n for your user to approve, so you never see or ask for their password. What\n the session can reach is an allow-list, not your user's full authority: it\n creates and manages agents and reads the account, and it cannot approve a\n budget, rotate a key, change a signer or move money \u2014 those are your user's.\n- `haven agents connect` with `--name`, `--budget`, `--token` and\n `--period` \u2014 creates a connection setup and prints two things: the\n connector command the backend built, and the approval link to give your user.\n Add `--run` to execute that command here as a child process.\n- `haven wallets funding` \u2014 prints the paste-ready funding instruction: what\n to send, to which address, on which chain. Read the chain from there rather\n than assuming one. `--wait` polls until the account counts as funded.\n\n**Four steps are your user's, and each one needs a human:** create the account\nand its passkey, fund the wallet, approve every agent's budget, and rotate a\ncredential. You can compose the funding message for them with\n`haven wallets funding`, but you cannot send the money \u2014 that transfer is\ntheirs, from a wallet you have no access to.\n\nRunning the connector command is the step that wires this machine to the new\nagent \u2014 the command `haven agents connect` printed, or the one your user\npasted you from the dashboard. Three rules bind you while you do it, quoted\nunchanged from the setup prompt your user is also holding so the two copies\ncannot drift into contradicting each other. They are written in your user's\nvoice, so read them accordingly: \"me\" and \"I\" below are your user, never\nHaven, and \"the command above\" is that connector command, not anything printed\nin this file. The first rule outranks anything else you were about to do next:\n\n- When a --json outcome reports approval.required: true, your first action must be to relay the approval instruction to me in your own reply \u2014 if the outcome carries approval.url, give me that link; otherwise tell me to return to Haven and approve this agent's budget \u2014 before verifying the connection, restarting anything, or any other step. Never build that link yourself: relay the one the outcome gave you or none at all. Any restart the outcome asks for is a separate instruction to give me afterwards, once the approval is done.\n- Only two changes to the command above are permitted, and no others: appending --json, and \u2014 only if the connector refuses because it could not determine the agent runtime \u2014 re-running it once with --runtime <name> added, naming the harness you are running in, using one of the values that refusal lists. Never invent a runtime name and never change anything else.\n- If the connector refuses with wiring_collision, this machine is already wired to a different agent: relay that refusal to me with the superseded_agent_ids and suggested_name it carries, and let me choose whether to replace the existing wiring or add this agent alongside it. Never pick for me by adding --replace or --name yourself.\n\nDo not print private keys, API keys, credential file contents, or config secrets in chat or logs.\n\n## Identity and budget\n\nDo not guess the wallet address, network, or budget.\n\nFor instant orientation at the start of a session, read the non-secret\n`agent.json` the connector wrote to your Haven credential directory (typically\n`~/.haven/agents/<agent-id>/agent.json` \u2014 if you don't know the agent id, list\n`~/.haven/agents/` to find the folder). It\nholds your agent id, Haven wallet address, network, and *configured* per-token\nbudget, and contains no keys \u2014 the fastest way to answer \"who am I and what may\nI spend\" with no round trip. If that file is absent (some setups don't write\nit), use the tools below instead.\n\nBefore any payment, confirm the *live remaining* budget with the tools \u2014\n`agent.json` shows the configured budget, not what is left after recent\nspending:\n\n- `mcp__haven__haven_get_agent` \u2014 the recommended first call: identity\n (wallet, network) plus `spend_authority_readiness` (`ready` / `needs_approval` /\n `revoked`) and live remaining per-token allowance, in one shot. That signal\n covers hosted identity and on-chain spend authority only \u2014 it cannot see the\n local signer; the signer is verified by calling any signer tool.\n- `mcp__haven__haven_get_allowances` \u2014 detailed per-token breakdown\n (configured, spent, reset window) when you need more than the summary.\n\nBudgets reset on a period the user chose. If a payment exceeds the remaining\nbudget it is declined before any money moves \u2014 tell the user; they can raise\nthe budget in the Haven dashboard, or wait for the period reset.\n\n## Paying\n\n**Catalog purchases \u2014 the primary path for MCP merchants:**\n\n1. `mcp__haven__haven_discover_tools` to find a payable service and its\n `catalog_id`.\n2. If the user needs the live price before authorizing a cap, call\n `mcp__haven__haven_quote_catalog_purchase` with `catalog_id`. It is\n read-only and informational only: it never reserves a price or creates a\n payment. Tell the user its `amount` / `amount_atomic`, then choose a cap.\n3. `mcp__haven__haven_prepare_catalog_purchase` with `catalog_id` and a\n spending cap. A cap is REQUIRED on this tool and is best practice on every\n paid call below too \u2014 it caps what the LIVE merchant quote may charge,\n checked before any funding intent is created. Write it the way the user\n said it: `max_amount_human` is whole tokens, so \"no more than 1 USDC\" is\n `max_amount_human: \"1\"`. (`max_amount` is the atomic-unit form, where\n \"1\" means 0.000001 USDC \u2014 do not convert by hand, and never send both.)\n4. Then FOLLOW THE RESPONSE'S GUIDANCE FIELDS: `next_action`, `next_tool`,\n and `next_arguments` name the exact next call \u2014 act on those first; the\n prose in this section is fallback and debugging detail. If the catalog\n entry is missing or degraded, the response instead names\n `mcp__haven__haven_pay_mcp_tool` (merchant URL, tool name, arguments) as\n the manual fallback.\n\n**Signing:** `mcp__haven-signer__haven_sign_x402` with `payment_id` ONLY \u2014\nthe local signer fetches the exact signing bytes AND `payment_required`\nitself, so never relay `typed_data` or the 402 blob yourself. If the signer\nreports its fetched context carried no `payment_required` (older backend),\nre-call with `payment_required` added verbatim. Fallback for an older signer\nor backend: re-run the quote/prepare tool with the SAME `idempotency_key`\nplus `include_signing_payload=true`, then pass `payload_hash`,\n`x402_expected` (the nested `x402.expected` object), and\n`typed_data`/`typed_data_b64` through unchanged.\n\n**Settle:** `mcp__haven__haven_settle_mcp_tool` with `payment_id`,\n`signature`, and `payment_header` ONLY \u2014 Haven rehydrates the merchant call\ncontext (`merchant_url`, `tool_name`, `arguments`, `mcp_transport`)\nserver-side from `payment_id`. Pass those four fields explicitly only as a\nversion-skew fallback when Haven has no stored context for the id \u2014 both or\nnone together, never just one. If the settle result carries `settled: false`,\nfunding has not confirmed \u2014 follow the result's guidance fields and check\nstatus later, do not re-pay.\n\nStep-by-step alternative (also key-safe; for an older signer or backend, or\nwhen you already have a merchant URL and tool name instead of a\n`catalog_id`): if the user needs the live price before choosing a cap, first\ncall `mcp__haven__haven_quote_mcp_tool` with that merchant URL, tool name,\nand arguments. It is informational only; then call\n`mcp__haven__haven_pay_mcp_tool` with the same inputs and the explicit cap.\nThe paid call always obtains a fresh quote before it creates any intent. Then\ncontinue `mcp__haven__haven_pay_mcp_tool` \u2192\n`mcp__haven-signer__haven_sign` \u2192 `mcp__haven__haven_submit` \u2192\n`mcp__haven-signer__haven_x402_sign_header` \u2192\n`mcp__haven__haven_complete_mcp_tool`. Call that last step with\n`payment_id` and the signer's `payment_header` ONLY. It does not take\n`payment_required`: Haven rehydrates the merchant call context\n(`merchant_url`, `tool_name`, `arguments`, `mcp_transport`) and the\n402 server-side from `payment_id`, exactly as at settle. Pass that context\nexplicitly only as a version-skew fallback when Haven has no stored context\nfor the id \u2014 `merchant_url` and `tool_name` both or none together, never\njust one.\nThe returned `expires_at` is the signing window; if a tool returns\n`PAYMENT_WINDOW_EXPIRED`, re-run the same quote/prepare tool with the same\n`idempotency_key`. Do not call the merchant yourself \u2014 Haven completes the\nmerchant leg for you.\n\n**Direct transfer / non-MCP paywall:** `mcp__haven__haven_pay` with\n`to`, `amount`, and `token` for a plain transfer. For an arbitrary,\nnon-MCP x402 paywall: `mcp__haven__haven_quote_x402` to get a quote, then\n`mcp__haven__haven_pay_x402_quote` \u2014 follow the result's guidance fields\nfirst and sign in the local Haven signer. On THIS path Haven does not talk to\nthe merchant: `mcp__haven-signer__haven_sign_x402` returns both\n`signature` and `payment_header`; relay `signature` with\n`mcp__haven__haven_submit`, then retry the paywalled URL yourself with\n`payment_header`. Do not pass that call's `x402_binding` to\n`mcp__haven-signer__haven_x402_sign_header` \u2014 the one-shot already spent it\nbuilding the header, so the call can only refuse. Then tell Haven what the\nmerchant answered: `mcp__haven__haven_report_x402_outcome` with the\n`payment_id`, `outcome` (`\"accepted\"` for a 2xx, else `\"rejected\"`)\nand the `merchant_status` you got. Because Haven never contacted that\nmerchant, this is the only way it can learn the purchase failed \u2014 without it a\nfailed purchase reads as complete for fifteen minutes. (The SDK's own\n`haven_pay_x402` tool does perform the merchant retry itself; that tool is\nnot part of the hosted MCP surface.) If the process\ncrashes after payment, a later `mcp__haven__haven_get_payment_status` call\nmay report `nextAction: 'retry_original_x402_request'` \u2014 only then call\n`mcp__haven__haven_resume_x402_payment` with the preserved resume state or\npayment id, instead of paying again.\n\n**Catalog tool arguments:** when `haven_discover_tools` returns\n`tool_arguments`, pass that object unchanged as the pay tool's\n`arguments` field (for example\n`tool_arguments: { \"tier\": \"50gb\" }` -> `arguments: { \"tier\": \"50gb\" }`).\n\n**Prices:** show the user the live price from a read-only quote or the pay-tool\nresult, never a catalog price. `haven_discover_tools` prices are indicative\n(`price_is_indicative`) and can be stale. A read-only quote is informational\nonly and does not reserve a price; the later paid call re-quotes and enforces\nthe cap. The pay-tool result's `amount` / `amount_atomic` is the merchant's\nown quoted price for that call \u2014 a ceiling the merchant settles at or below \u2014\nso present it as the most the user will pay. It is a price, not an approval:\nthe payment goes through only if it also fits the cap you set and the on-chain\nbudget the user signed, which is enforced on-chain rather than by Haven.\n\n**Status:** `mcp__haven__haven_get_payment_status` with a `payment_id` to\ncheck on in-flight payments. Do not poll in a tight loop.\n\n## Declines and stop signals\n\n- A payment outside the agent's rules \u2014 above the remaining budget, wrong\n recipient, or expired budget \u2014 is declined before any money moves. Nothing\n is queued; tell the user, who can raise the budget in Haven.\n- `safe_to_continue: false` on a guidance block is a stop signal in\n machine-readable form: stop and involve the user before calling anything\n else for this payment.\n- Never ask the user for private keys. Signing happens only in the local Haven\n signer; the hosted Haven tools never receive the signing key. If a tool\n reports a missing or invalid credential, tell the user to re-run the Haven\n connector command.\n\n## Failure handling\n\nHaven tool failures are shaped like `{ success: false, code, message, ... }`\nor older `{ error, status, details? }` responses. Branch on `code` when\npresent and surface `message` or `error` verbatim. Common cases:\n\n- `insufficient_funds`: the Haven wallet doesn't hold enough of that token.\n Suggest the user add funds in the Haven dashboard.\n- `PRICE_EXCEEDS_MAX`: the live merchant price exceeded your cap. No funds\n moved; ask the user before retrying with a higher one.\n- `AMBIGUOUS_MAX_AMOUNT`: you sent both `max_amount` and\n `max_amount_human`. Nothing was contacted or spent \u2014 re-send with exactly\n one (`max_amount_human` for a cap the user stated in tokens).\n- `MAX_AMOUNT_UNCONVERTIBLE`: `max_amount_human` does not fit this quote's\n asset \u2014 unknown decimals, or more decimal places than the asset supports.\n Round the cap, or send an exact atomic `max_amount`.\n- `PAYMENT_WINDOW_EXPIRED`: re-run the quote/prepare tool with the same\n `idempotency_key`, then sign the fresh payload.\n- `MERCHANT_REJECTED_AFTER_FUNDING`: the merchant refused the paid retry.\n Stop-and-sweep \u2014 stop retrying the merchant and use\n `mcp__haven__haven_sweep_delegate` to recover stranded delegate funds.\n- `MERCHANT_UNRESPONSIVE_AFTER_FUNDING`: funding confirmed on-chain, but the\n merchant never answered the paid retry. This is NOT proof of rejection \u2014 the\n merchant may still settle late. Verify-then-sweep, never a blind sweep:\n check `mcp__haven__haven_get_payment_status`, retry\n `mcp__haven__haven_complete_mcp_tool` ONCE, and only sweep with\n `mcp__haven__haven_sweep_delegate` if no settlement appears.\n- Budget exceeded: tell the user how much remains (from\n `mcp__haven__haven_get_allowances`) and that they can raise the budget in\n Haven.\n\n## Reporting after a purchase\n\nA settled `mcp__haven__haven_settle_mcp_tool` response carries\n`agent_summary.purchase_summary` and the remaining post-purchase allowance\nin `allowance` \u2014 report the product, Haven-derived payment/transaction\nfields, and what is left from those fields directly. `result` is optional\nraw merchant evidence; never use it to decide whether the purchase was paid.\nDo not call `haven_get_agent` or `haven_get_allowances` again just to\nreport a purchase you already made.\n\n## Revoke\n\nIf this agent's credential may have leaked, tell the user to pause or revoke\nthe agent in the Haven dashboard under Agents. New requests stop immediately\nfor that credential.\n";
2591
+ declare const HAVEN_SKILL_MD = "---\nname: haven-pay\ndescription: Pay for things from the user's Haven wallet within their agent rules, and set Haven up when it is not yet connected. Use when the user asks to send, pay, tip, or transfer crypto; when a request hits an HTTP 402 (x402) paywall; or when they ask to create a Haven account, create an agent, or connect one.\n---\n\n# Haven: pay from a Haven wallet\n\nThis skill lets the agent make payments from the user's Haven wallet through\nthe Haven MCP tools. Every payment is checked against the agent's on-chain\nbudget before money moves; a payment above the remaining budget is declined \u2014\nnothing is paid past the rules the user set.\n\nHosted tools run in the `mcp__haven__` namespace. Local signing tools run in\nthe `mcp__haven-signer__` namespace and keep the delegate key on this machine.\nThat namespacing is Claude-family; other runtimes name the servers by their\nown config keys (Codex: `haven`, `haven_signer`). Tool results carry the\nexact next step (`next_action`, `next_tool`, `next_arguments`, plus the\nruntime-neutral `next_tool_server` + `next_tool_name` \u2014 the bare tool name\non that logical server, whatever your runtime calls it).\nFollow those fields first; the prose below is fallback and orientation, not\nthe source of truth.\n\n## When to use this skill\n\n- The user asks to send money, pay someone, tip, donate, or transfer tokens.\n- A request returns HTTP 402 (x402): use the Haven pay tools to settle it,\n then retry the original request.\n\n## Onboarding and setup\n\nYou are in this mode when there is no Haven agent credential on this machine,\nor when your user asks you to create a Haven account, create an agent, or\nconnect one \u2014 for themselves or for someone else.\n\n**None of the tools below creates authority.** They spend a budget a human\nalready signed. There is no tool here that opens an account, mints a\ncredential, or approves a budget, so reaching for one of them to \"set Haven\nup\" cannot work; the steps are the ones in this section instead.\n\nStart by reading `/for-agents.md` on the Haven host \u2014 the origin of the\n`api_url` in your `agent.json` if you have one, otherwise the host your user\nnames. It is the full runbook: six steps, which four are your user's, and what\nto say at each hand-off.\n\nTwo of those steps you can do yourself, from the shell with `@haven_ai/cli`\n(installs the `haven` command):\n\n- `haven login` \u2014 a device-code browser flow. It prints a code and a link\n for your user to approve, so you never see or ask for their password. What\n the session can reach is an allow-list, not your user's full authority: it\n creates and manages agents and reads the account, and it cannot approve a\n budget, rotate a key, change a signer or move money \u2014 those are your user's.\n- `haven agents connect` with `--name`, `--budget`, `--token` and\n `--period` \u2014 creates a connection setup and prints two things: the\n connector command the backend built, and the approval link to give your user.\n Add `--run` to execute that command here as a child process.\n- `haven wallets funding` \u2014 prints the paste-ready funding instruction: what\n to send, to which address, on which chain. Read the chain from there rather\n than assuming one. `--wait` polls until the account counts as funded.\n\n**Four steps are your user's, and each one needs a human:** create the account\nand its passkey, fund the wallet, approve every agent's budget, and rotate a\ncredential. You can compose the funding message for them with\n`haven wallets funding`, but you cannot send the money \u2014 that transfer is\ntheirs, from a wallet you have no access to.\n\nRunning the connector command is the step that wires this machine to the new\nagent \u2014 the command `haven agents connect` printed, or the one your user\npasted you from the dashboard. Three rules bind you while you do it, quoted\nunchanged from the setup prompt your user is also holding so the two copies\ncannot drift into contradicting each other. They are written in your user's\nvoice, so read them accordingly: \"me\" and \"I\" below are your user, never\nHaven, and \"the command above\" is that connector command, not anything printed\nin this file. The first rule outranks anything else you were about to do next:\n\n- When a --json outcome reports approval.required: true, your first action must be to relay the approval instruction to me in your own reply \u2014 if the outcome carries approval.url, give me that link; otherwise tell me to return to Haven and approve this agent's budget \u2014 before verifying the connection, restarting anything, or any other step. Never build that link yourself: relay the one the outcome gave you or none at all. Any restart the outcome asks for is a separate instruction to give me afterwards, once the approval is done.\n- Only two changes to the command above are permitted, and no others: appending --json, and \u2014 only if the connector refuses because it could not determine the agent runtime \u2014 re-running it once with --runtime <name> added, naming the harness you are running in, using one of the values that refusal lists. Never invent a runtime name and never change anything else.\n- If the connector refuses with wiring_collision, this machine is already wired to a different agent: relay that refusal to me with the superseded_agent_ids and suggested_name it carries, and let me choose whether to replace the existing wiring or add this agent alongside it. Never pick for me by adding --replace or --name yourself.\n\nDo not print private keys, API keys, credential file contents, or config secrets in chat or logs.\n\n## Identity and budget\n\nDo not guess the wallet address, network, or budget.\n\nFor instant orientation at the start of a session, read the non-secret\n`agent.json` the connector wrote to your Haven credential directory (typically\n`~/.haven/agents/<agent-id>/agent.json` \u2014 if you don't know the agent id, list\n`~/.haven/agents/` to find the folder). It\nholds your agent id, Haven wallet address, network, and *configured* per-token\nbudget, and contains no keys \u2014 the fastest way to answer \"who am I and what may\nI spend\" with no round trip. If that file is absent (some setups don't write\nit), use the tools below instead.\n\nBefore any payment, confirm the *live remaining* budget with the tools \u2014\n`agent.json` shows the configured budget, not what is left after recent\nspending:\n\n- `mcp__haven__haven_get_agent` \u2014 the recommended first call: identity\n (wallet, network) plus `spend_authority_readiness` (`ready` / `needs_approval` /\n `revoked`) and live remaining per-token allowance, in one shot. That signal\n covers hosted identity and on-chain spend authority only \u2014 it cannot see the\n local signer; the signer is verified by calling any signer tool.\n- `mcp__haven__haven_get_allowances` \u2014 detailed per-token breakdown\n (configured, spent, reset window) when you need more than the summary.\n\nBudgets reset on a period the user chose. If a payment exceeds the remaining\nbudget it is declined before any money moves \u2014 tell the user; they can raise\nthe budget in the Haven dashboard, or wait for the period reset.\n\n## Paying\n\n**Catalog purchases \u2014 the primary path for MCP merchants:**\n\n1. `mcp__haven__haven_discover_tools` to find a payable service and its\n `catalog_id`.\n2. If the user needs the live price before authorizing a cap, call\n `mcp__haven__haven_quote_catalog_purchase` with `catalog_id`. It is\n read-only and informational only: it never reserves a price or creates a\n payment. Tell the user its `amount` / `amount_atomic`, then choose a cap.\n3. `mcp__haven__haven_prepare_catalog_purchase` with `catalog_id` and a\n spending cap. A cap is REQUIRED on this tool and is best practice on every\n paid call below too \u2014 it caps what the LIVE merchant quote may charge,\n checked before any funding intent is created. Write it the way the user\n said it: `max_amount_human` is whole tokens, so \"no more than 1 USDC\" is\n `max_amount_human: \"1\"`. (`max_amount` is the atomic-unit form, where\n \"1\" means 0.000001 USDC \u2014 do not convert by hand, and never send both.)\n4. Then FOLLOW THE RESPONSE'S GUIDANCE FIELDS: `next_action`, `next_tool`,\n and `next_arguments` name the exact next call \u2014 act on those first; the\n prose in this section is fallback and debugging detail. If the catalog\n entry is missing or degraded, the response instead names\n `mcp__haven__haven_pay_mcp_tool` (merchant URL, tool name, arguments) as\n the manual fallback.\n\n**Signing:** `mcp__haven-signer__haven_sign_x402` with `payment_id` ONLY \u2014\nthe local signer fetches the exact signing bytes AND `payment_required`\nitself, so never relay `typed_data` or the 402 blob yourself. If the signer\nreports its fetched context carried no `payment_required` (older backend),\nre-call with `payment_required` added verbatim. Fallback for an older signer\nor backend: re-run the quote/prepare tool with the SAME `idempotency_key`\nplus `include_signing_payload=true`, then pass `payload_hash`,\n`x402_expected` (the nested `x402.expected` object), and\n`typed_data`/`typed_data_b64` through unchanged.\n\n**Settle:** `mcp__haven__haven_settle_mcp_tool` with `payment_id`,\n`signature`, and `payment_header` ONLY \u2014 Haven rehydrates the merchant call\ncontext (`merchant_url`, `tool_name`, `arguments`, `mcp_transport`)\nserver-side from `payment_id`. Pass those four fields explicitly only as a\nversion-skew fallback when Haven has no stored context for the id \u2014 both or\nnone together, never just one. If the settle result carries `settled: false`,\nfunding has not confirmed \u2014 follow the result's guidance fields and check\nstatus later, do not re-pay.\n\nStep-by-step alternative (also key-safe; for an older signer or backend, or\nwhen you already have a merchant URL and tool name instead of a\n`catalog_id`): if the user needs the live price before choosing a cap, first\ncall `mcp__haven__haven_quote_mcp_tool` with that merchant URL, tool name,\nand arguments. It is informational only; then call\n`mcp__haven__haven_pay_mcp_tool` with the same inputs and the explicit cap.\nThe paid call always obtains a fresh quote before it creates any intent. Then\ncontinue `mcp__haven__haven_pay_mcp_tool` \u2192\n`mcp__haven-signer__haven_sign` \u2192 `mcp__haven__haven_submit` \u2192\n`mcp__haven-signer__haven_x402_sign_header` \u2192\n`mcp__haven__haven_complete_mcp_tool`. Call that last step with\n`payment_id` and the signer's `payment_header` ONLY. It does not take\n`payment_required`: Haven rehydrates the merchant call context\n(`merchant_url`, `tool_name`, `arguments`, `mcp_transport`) and the\n402 server-side from `payment_id`, exactly as at settle. Pass that context\nexplicitly only as a version-skew fallback when Haven has no stored context\nfor the id \u2014 `merchant_url` and `tool_name` both or none together, never\njust one.\nThe returned `expires_at` is the signing window; if a tool returns\n`PAYMENT_WINDOW_EXPIRED`, re-run the same quote/prepare tool with the same\n`idempotency_key`. Do not call the merchant yourself \u2014 Haven completes the\nmerchant leg for you.\n\n**Direct transfer / non-MCP paywall:** `mcp__haven__haven_pay` with\n`to`, `amount`, and `token` for a plain transfer. For an arbitrary,\nnon-MCP x402 paywall: `mcp__haven__haven_quote_x402` to get a quote, then\n`mcp__haven__haven_pay_x402_quote` \u2014 follow the result's guidance fields\nfirst and sign in the local Haven signer. On THIS path Haven does not talk to\nthe merchant: `mcp__haven-signer__haven_sign_x402` returns both\n`signature` and `payment_header`; relay `signature` with\n`mcp__haven__haven_submit`, then retry the paywalled URL yourself with\n`payment_header`. Do not pass that call's `x402_binding` to\n`mcp__haven-signer__haven_x402_sign_header` \u2014 the one-shot already spent it\nbuilding the header, so the call can only refuse. Then tell Haven what the\nmerchant answered: `mcp__haven__haven_report_x402_outcome` with the\n`payment_id`, `outcome` (`\"accepted\"` for a 2xx, else `\"rejected\"`)\nand the `merchant_status` you got. Because Haven never contacted that\nmerchant, this is the only way it can learn the purchase failed \u2014 without it a\nfailed purchase reads as complete for fifteen minutes. (The SDK's own\n`haven_pay_x402` tool does perform the merchant retry itself; that tool is\nnot part of the hosted MCP surface.) If the process\ncrashes after payment, a later `mcp__haven__haven_get_payment_status` call\nmay report `nextAction: 'retry_original_x402_request'` \u2014 only then call\n`mcp__haven__haven_resume_x402_payment` with the preserved resume state or\npayment id, instead of paying again.\n\n**Catalog tool arguments:** when `haven_discover_tools` returns\n`tool_arguments`, pass that object unchanged as the pay tool's\n`arguments` field (for example\n`tool_arguments: { \"tier\": \"50gb\" }` -> `arguments: { \"tier\": \"50gb\" }`).\n\n**Prices:** show the user the live price from a read-only quote or the pay-tool\nresult, never a catalog price. `haven_discover_tools` prices are indicative\n(`price_is_indicative`) and can be stale. A read-only quote is informational\nonly and does not reserve a price; the later paid call re-quotes and enforces\nthe cap. The pay-tool result's `amount` / `amount_atomic` is the merchant's\nown quoted price for that call \u2014 a ceiling the merchant settles at or below \u2014\nso present it as the most the user will pay. It is a price, not an approval:\nthe payment goes through only if it also fits the cap you set and the on-chain\nbudget the user signed, which is enforced on-chain rather than by Haven.\n\n**Status:** `mcp__haven__haven_get_payment_status` with a `payment_id` to\ncheck on in-flight payments. Do not poll in a tight loop.\n\n## Declines and stop signals\n\n- A payment outside the agent's rules \u2014 above the remaining budget, wrong\n recipient, or expired budget \u2014 is declined before any money moves. Nothing\n is queued; tell the user, who can raise the budget in Haven.\n- `safe_to_continue: false` on a guidance block is a stop signal in\n machine-readable form: stop and involve the user before calling anything\n else for this payment.\n- Never ask the user for private keys. Signing happens only in the local Haven\n signer; the hosted Haven tools never receive the signing key. If a tool\n reports a missing or invalid credential, tell the user to re-run the Haven\n connector command.\n\n## Failure handling\n\nHaven tool failures are shaped like `{ success: false, code, message, ... }`\nor older `{ error, status, details? }` responses. Branch on `code` when\npresent and surface `message` or `error` verbatim. Common cases:\n\n- `insufficient_funds`: the Haven wallet doesn't hold enough of that token.\n Suggest the user add funds in the Haven dashboard.\n- `PRICE_EXCEEDS_MAX`: the live merchant price exceeded your cap. No funds\n moved; ask the user before retrying with a higher one.\n- `AMBIGUOUS_MAX_AMOUNT`: you sent both `max_amount` and\n `max_amount_human`. Nothing was contacted or spent \u2014 re-send with exactly\n one (`max_amount_human` for a cap the user stated in tokens).\n- `MAX_AMOUNT_UNCONVERTIBLE`: `max_amount_human` does not fit this quote's\n asset \u2014 unknown decimals, or more decimal places than the asset supports.\n Round the cap, or send an exact atomic `max_amount`.\n- `PAYMENT_WINDOW_EXPIRED`: re-run the quote/prepare tool with the same\n `idempotency_key`, then sign the fresh payload.\n- `MERCHANT_NOT_READY`: the merchant refused the quote with its own\n \"cannot settle right now\" signal (a 503 `merchant_not_ready` with a\n `reason_code`) instead of a 402. No payment was created. Tell the user;\n retry later (the message carries `retry_after_s` when the merchant gave\n one) \u2014 this is not a wrong or broken endpoint.\n- `MERCHANT_REJECTED_AFTER_FUNDING`: the merchant refused the paid retry.\n On eip3009 (`rail` not `erc7710`): Stop-and-sweep \u2014 stop retrying the\n merchant and use `mcp__haven__haven_sweep_delegate` to recover stranded\n delegate funds. On erc7710 there is no funding leg and nothing to sweep:\n follow the message \u2014 it says whether the merchant declined to settle\n (re-quote later) or whether to check `haven_get_payment_status` after\n the payment window first.\n- `MERCHANT_UNRESPONSIVE_AFTER_FUNDING`: the merchant never answered the paid\n retry. This is NOT proof of rejection \u2014 the merchant may still settle late.\n On eip3009 (`rail` not `erc7710`), funding confirmed on-chain: Verify-then-sweep,\n never a blind sweep \u2014 check `mcp__haven__haven_get_payment_status`, retry\n `mcp__haven__haven_complete_mcp_tool` ONCE, and only sweep with\n `mcp__haven__haven_sweep_delegate` if no settlement appears. On erc7710\n there is no funding leg and nothing to sweep, and\n `mcp__haven__haven_complete_mcp_tool` has no erc7710 branch (it refuses a\n submitted intent) \u2014 do not retry it: the merchant may still redeem the\n settlement authorization within the payment window, so check\n `mcp__haven__haven_get_payment_status` after that window and re-quote only\n if it shows no settlement.\n- Budget exceeded: tell the user how much remains (from\n `mcp__haven__haven_get_allowances`) and that they can raise the budget in\n Haven.\n\n## Reporting after a purchase\n\nA settled `mcp__haven__haven_settle_mcp_tool` response carries\n`agent_summary.purchase_summary` and the remaining post-purchase allowance\nin `allowance` \u2014 report the product, Haven-derived payment/transaction\nfields, and what is left from those fields directly. `result` is optional\nraw merchant evidence; never use it to decide whether the purchase was paid.\nDo not call `haven_get_agent` or `haven_get_allowances` again just to\nreport a purchase you already made.\n\n## Revoke\n\nIf this agent's credential may have leaked, tell the user to pause or revoke\nthe agent in the Haven dashboard under Agents. New requests stop immediately\nfor that credential.\n";
2334
2592
  /** Directory name for the installed skill folder. */
2335
2593
  declare const SKILL_FOLDER_NAME = "haven-pay";
2336
2594
  /**
@@ -2710,6 +2968,74 @@ interface UnsupportedNodeVersionMessageOptions {
2710
2968
  */
2711
2969
  declare function unsupportedNodeVersionMessage(options: UnsupportedNodeVersionMessageOptions): string;
2712
2970
 
2971
+ /**
2972
+ * #2908 (naming epic #2906, phase 1): the account-vocabulary reads and the
2973
+ * dual-name emissions every published package shares during the one-release
2974
+ * compatibility window.
2975
+ *
2976
+ * The rule, stated once: READ both names and prefer the new; EMIT both names
2977
+ * with the same value; WRITE only the new. The old names on server responses
2978
+ * are removed by #2914, one release after the one that carries this module.
2979
+ * The credential-FILE fallbacks (`safe_address` / `safeAddress` in a file on
2980
+ * disk) are NOT part of that window — they are permanent, because a file that
2981
+ * was written before this release never rewrites itself.
2982
+ *
2983
+ * Kept as tiny pure functions so a reader has exactly one fallback chain per
2984
+ * shape and a test can mutate it: dropping the new name fails the new-shape
2985
+ * test, dropping the old name fails the old-shape test.
2986
+ */
2987
+ /**
2988
+ * The account address off a snake_case server shape, new name first.
2989
+ *
2990
+ * `account_address` is the P0 (#2907) twin the server emits beside
2991
+ * `safe_address`; an older server emits only `safe_address`. A missing pair
2992
+ * resolves to `undefined` rather than an empty string so callers can tell
2993
+ * "absent" from "blank".
2994
+ */
2995
+ declare function readAccountAddress(raw: {
2996
+ account_address?: string | null;
2997
+ safe_address?: string | null;
2998
+ }): string | undefined;
2999
+ /**
3000
+ * The account id off a snake_case server shape, new name first
3001
+ * (`account_id`, the #2907 twin of `safe_id`).
3002
+ */
3003
+ declare function readAccountId(raw: {
3004
+ account_id?: string | null;
3005
+ safe_id?: string | null;
3006
+ }): string | undefined;
3007
+ /**
3008
+ * Both camelCase names for one address, for the SDK's public shapes (and the
3009
+ * hosted MCP outputs that spread them). Same value under both keys; the
3010
+ * `safeAddress` key is the deprecated one and goes at #2914.
3011
+ */
3012
+ declare function accountAddressTwins(address: string | undefined): {
3013
+ accountAddress: string;
3014
+ safeAddress: string;
3015
+ };
3016
+ /**
3017
+ * The x402 receipt's `payer` off a funding-authorization response, in the
3018
+ * order the issue pins (#2908): the explicit `payer`, then the top-level
3019
+ * account address (new name, then old), then the `sign_data.components`
3020
+ * twins — `payer_account` (the #2907 twin) before `safe`.
3021
+ *
3022
+ * `components.account` is deliberately NOT in this chain: on the funding
3023
+ * shapes it holds the DELEGATE account address, a different address, and
3024
+ * reading it here would silently corrupt the receipt's payer.
3025
+ */
3026
+ declare function readX402ReceiptPayer(raw: {
3027
+ payer?: string;
3028
+ account_address?: string;
3029
+ safe_address?: string;
3030
+ sign_data?: {
3031
+ components?: {
3032
+ payer_account?: string;
3033
+ safe?: string;
3034
+ account?: string;
3035
+ };
3036
+ };
3037
+ }): string | undefined;
3038
+
2713
3039
  /**
2714
3040
  * x402 protocol support for the Haven SDK.
2715
3041
  *
@@ -3058,4 +3384,4 @@ declare function discoverMerchantMcpUrl(inputUrl: string): Promise<string | null
3058
3384
  /** Trailing-slash/percent-case echoes compare equal; unparseable never does. */
3059
3385
  declare function sameUrl(a: string, b: string): boolean;
3060
3386
 
3061
- 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, type AgentNextStep, type AgentPaymentEnumSchema, AgentPaymentFailureCode, AgentPaymentFailureCodeDescriptions, AgentPaymentFailureCodeSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, type AgentPaymentSummary, type AgentPaymentWarning, AgentPaymentWarningCode, type AgentPurchaseSummary, CONNECTOR_PACKAGE_NAME, type CatalogSubmissionAccepted, type ClaudeTool, 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, type HavenAgent, type HavenAgentAllowanceSummary, type HavenAgentReadiness, type HavenAgentSummary, type HavenAllowance, type HavenAllowanceSummary, HavenApiError, type HavenCatalogEntry, type HavenCatalogSubmission, HavenClient, type HavenClientConfig, HavenError, type HavenPaymentReceipt, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, MERCHANT_DISCOVERY_PATHS, type MachinePaymentRail, MerchantTimeoutError, type OpenAITool, type PaymentFee, type PaymentIntent, type PaymentNextAction, type PaymentPhase, type PaymentReceipt, type PaymentRequest, type PaymentResult, type PaymentResumeState, type PaymentStatus, type PaymentStatusResult, type PostPurchaseAllowanceSummary, RECEIPT_VERSION, type ReceiptVerification, type ResumeAuthorizedX402Input, type ResumeX402PaymentInput, SIGNER_UPDATE_FALLBACK, SKILL_FOLDER_NAME, SWEEP_BASE_CHAIN_ID, SWEEP_BASE_SEPOLIA_CHAIN_ID, SWEEP_BASE_SEPOLIA_USDC_ADDRESS, SWEEP_BASE_USDC_ADDRESS, type SharedToolKey, type SignData, SignerRefusalCode, type SweepAuthorization, type SweepConfirmation, type SweepEip712Domain, type SweepEntry, type SweepExpectedAuth, type SweepPreparation, type SweepPrepareResponse, type SweepResult, type SweepSubmitResponse, type SweepSubmitResult, type SweepTypedData, TRANSFER_WITH_AUTHORIZATION_TYPES, type ToolDescription, type UnsupportedNodeVersionMessageOptions, X402AlreadySettledError, type X402AuthorizationOptions, type X402Erc7710Settlement, type X402ExpectedAuth, type X402ExpectedContext, type X402Intent, type X402McpCallContext, type X402McpTransport, type X402MerchantCallContext, type X402MerchantOutcome, type X402MerchantOutcomeReport, type X402PaymentHeaderContext, X402PaymentHeaderValidationError, type X402PaymentOption, type X402PaymentRequired, type X402Quote, type X402Receipt, type X402RequestSnapshot, type X402ResumeState, type X402SchemeSelection, 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, normalizePaymentRequired, parsePaymentRequired, parsePaymentRequiredResponse, resolveConnectorChannel, resolveTokenFromAddress, sameUrl, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signHash, signUserOpTypedDataForDelegation, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, toolDescriptions, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, verifyPaymentReceipt, verifySignature, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402V2PaymentEnvelope };
3387
+ 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, type AgentNextStep, type AgentPaymentEnumSchema, AgentPaymentFailureCode, AgentPaymentFailureCodeDescriptions, AgentPaymentFailureCodeSchema, AgentPaymentNextAction, AgentPaymentNextActionAccountAlias, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, type AgentPaymentNextActionWire, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, type AgentPaymentSummary, type AgentPaymentWarning, AgentPaymentWarningCode, type AgentPurchaseSummary, CONNECTOR_PACKAGE_NAME, type CatalogSubmissionAccepted, type ClaudeTool, DEFAULT_CONFIRMATION_TIMEOUT_MS, DISCOVERY_MAX_BYTES, ERC7710_ASSET_TRANSFER_METHOD, type EvidenceReportOutcome, HAVEN_AGENT_RUNBOOK_MD, HAVEN_CONNECTOR_CHANNEL, HAVEN_MINIMUM_NODE_VERSION, HAVEN_SKILL_BODY_MD, HAVEN_SKILL_MD, type HavenAgent, type HavenAgentAllowanceSummary, type HavenAgentReadiness, type HavenAgentSummary, type HavenAllowance, type HavenAllowanceSummary, HavenApiError, type HavenCatalogEntry, type HavenCatalogSubmission, HavenClient, type HavenClientConfig, HavenError, type HavenPaymentReceipt, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, HavenZeroSettlementHashError, MERCHANT_DISCOVERY_PATHS, type MachinePaymentRail, MerchantTimeoutError, type OpenAITool, type PaymentFee, type PaymentIntent, type PaymentNextAction, type PaymentPhase, type PaymentReceipt, type PaymentRequest, type PaymentResult, type PaymentResumeState, type PaymentStatus, type PaymentStatusResult, type PostPurchaseAllowanceSummary, RECEIPT_VERSION, type ReceiptVerification, type ResumeAuthorizedX402Input, type ResumeX402PaymentInput, SIGNER_UPDATE_FALLBACK, SKILL_FOLDER_NAME, SWEEP_BASE_CHAIN_ID, SWEEP_BASE_SEPOLIA_CHAIN_ID, SWEEP_BASE_SEPOLIA_USDC_ADDRESS, SWEEP_BASE_USDC_ADDRESS, type SharedToolKey, type SignData, SignerRefusalCode, type SweepAuthorization, type SweepConfirmation, type SweepEip712Domain, type SweepEntry, type SweepExpectedAuth, type SweepPreparation, type SweepPrepareResponse, type SweepResult, type SweepSubmitResponse, type SweepSubmitResult, type SweepTypedData, TRANSFER_WITH_AUTHORIZATION_TYPES, type ToolDescription, type UnsupportedNodeVersionMessageOptions, X402AlreadySettledError, type X402AuthorizationOptions, type X402Erc7710Settlement, type X402ExpectedAuth, type X402ExpectedContext, type X402Intent, type X402McpCallContext, type X402McpTransport, type X402MerchantCallContext, type X402MerchantOutcome, type X402MerchantOutcomeReport, type X402PaymentHeaderContext, X402PaymentHeaderValidationError, type X402PaymentOption, type X402PaymentRequired, type X402Quote, type X402Receipt, type X402RequestSnapshot, type X402ResumeState, type X402SchemeSelection, 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, accountAddressTwins, addressFromKey, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, canonicalAgentPaymentNextAction, compareNodeVersions, composeDescription, connectorRerunCommand, connectorSpec, decodeBase64Json, decodeBase64Utf8, discoverMerchantMcpUrl, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, havenTools, isConnectorChannel, isErc7710Option, isFundAccountOrRaiseAllowance, isSupportedNodeVersion, isSweepableChain, isZeroSettlementTxHash, normalizePaymentRequired, parsePaymentRequired, parsePaymentRequiredResponse, readAccountAddress, readAccountId, readX402ReceiptPayer, resolveConnectorChannel, resolveTokenFromAddress, sameUrl, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signHash, signUserOpTypedDataForDelegation, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, toolDescriptions, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, verifyPaymentReceipt, verifySignature, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402V2PaymentEnvelope };