@haven_ai/sdk 0.6.0-alpha.0 → 0.7.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,6 +74,14 @@ interface PaymentRequest {
74
74
  * token/recipient/parent disagree with this request.
75
75
  */
76
76
  taskBudgetId?: string;
77
+ /**
78
+ * #3330: redeem against this open sub-budget's grant (this agent is the
79
+ * sub-agent B) instead of the agent's budget delegation directly —
80
+ * `[grant, parent-child, budget]`. The backend refuses (404/409) when the
81
+ * id is unknown, not open, or its token/recipient/parent disagree with
82
+ * this request. Mutually exclusive with `taskBudgetId`.
83
+ */
84
+ subBudgetId?: string;
77
85
  }
78
86
  interface SignData {
79
87
  /** The hash to sign (keccak256, 0x-prefixed) */
@@ -277,8 +285,23 @@ interface X402AuthorizationOptions {
277
285
  * a task budget's recipient pin is compared with the agent's own delegate
278
286
  * wallet, so a merchant-pinned task budget is refused there
279
287
  * (`task_budget_recipient_mismatch`); it pays through erc7710 only (#3378).
288
+ * #3392: the receipt cache and in-flight map record this id per entry —
289
+ * reusing an idempotency key under a DIFFERENT budget throws
290
+ * `X402TaskBudgetMismatchError` before any network call; pay again under a
291
+ * new key instead.
280
292
  */
281
293
  taskBudgetId?: string;
294
+ /**
295
+ * #3330: redeem against this open sub-budget's grant (this agent is the
296
+ * sub-agent B) for the funding leg / erc7710 settlement instead of the
297
+ * agent's budget delegation directly. Same refusal contract as
298
+ * `PaymentRequest.subBudgetId`; mutually exclusive with `taskBudgetId`.
299
+ * The receipt cache and in-flight map pin this id per entry exactly as
300
+ * they pin `taskBudgetId` (#3392) — a key reused under a different
301
+ * authorizing child throws the typed mismatch error before any network
302
+ * call.
303
+ */
304
+ subBudgetId?: string;
282
305
  }
283
306
  /**
284
307
  * Keyless x402 construct result.
@@ -693,7 +716,7 @@ interface HavenAgentAllowanceSummary {
693
716
  remainingAtomic: string;
694
717
  /** Human-readable remaining, e.g. "4.96 USDC". */
695
718
  remainingDisplay: string;
696
- /** Configured allowance amount (atomic) the owner granted. */
719
+ /** Configured allowance amount in whole token units (human decimal, e.g. "1.00" — NOT atomic; on-chain.amount is the atomic figure). */
697
720
  configuredAmount: string;
698
721
  resetPeriodMin: number;
699
722
  isResetPending: boolean;
@@ -831,6 +854,33 @@ interface PaymentParties {
831
854
  delegate: string | null;
832
855
  delegateAccount: string | null;
833
856
  merchant: string | null;
857
+ /**
858
+ * #3332: the paying agent's owner's company details — additive, present
859
+ * only when the backend has `HAVEN_OWNER_COMPANY_DETAILS` on AND the owner
860
+ * saved details; absent (not `undefined`-valued, the KEY is absent)
861
+ * otherwise. `viesStatus: 'valid'` means VIES accepted the VAT number —
862
+ * never render that as "verified" (see Haven's agent-passport docs on the
863
+ * same naming discipline).
864
+ *
865
+ * Present only on the receipt surfaces — `GET /payments/:id/receipt` and
866
+ * `GET /machine-payments/receipts` (`HavenClient.getReceipt()`,
867
+ * `listReceipts()`/`listReceiptsPage()`) — never on `GET
868
+ * /machine-payments/:id/status` (`getPaymentStatus`) or the evidence-attach echo,
869
+ * even with the feature on: those report payment/settlement state, not the
870
+ * buyer's company details (out of scope for #3332, see
871
+ * docs/product/owner-company-details.md).
872
+ */
873
+ buyer?: PaymentPartiesBuyer;
874
+ }
875
+ interface PaymentPartiesBuyer {
876
+ legalName: string;
877
+ /** ISO 3166-1 alpha-2. */
878
+ country: string;
879
+ /** For a sole trader this IS the personal identity number. */
880
+ orgNumber: string;
881
+ vatNumber: string | null;
882
+ viesStatus: 'pending' | 'valid' | 'invalid' | 'not_verifiable' | null;
883
+ viesCheckedAt: string | null;
834
884
  }
835
885
  /** @internal wire shape of {@link PaymentParties}. */
836
886
  interface RawPaymentParties {
@@ -838,6 +888,16 @@ interface RawPaymentParties {
838
888
  delegate: string | null;
839
889
  delegate_account: string | null;
840
890
  merchant: string | null;
891
+ buyer?: RawPaymentPartiesBuyer;
892
+ }
893
+ /** @internal wire shape of {@link PaymentPartiesBuyer}. */
894
+ interface RawPaymentPartiesBuyer {
895
+ legal_name: string;
896
+ country: string;
897
+ org_number: string;
898
+ vat_number: string | null;
899
+ vies_status: 'pending' | 'valid' | 'invalid' | 'not_verifiable' | null;
900
+ vies_checked_at: string | null;
841
901
  }
842
902
  /**
843
903
  * #3132 (owner decision 3 on #3130): what population a list row came from and
@@ -1065,6 +1125,20 @@ declare const AgentPaymentPhase: {
1065
1125
  * the funds.
1066
1126
  */
1067
1127
  readonly FundedButUnsettled: "funded_but_unsettled";
1128
+ /**
1129
+ * #3420: TERMINAL — a `submitted` erc7710 x402 intent whose settlement
1130
+ * window AND the sweep's last attribution chance have both passed with no
1131
+ * verified evidence. The sweep's tick (120s) only ever confirms a
1132
+ * transaction mined inside the payment's own settlement window (the child
1133
+ * delegation's on-chain `timestamp` caveat, plus the verifier's 120s
1134
+ * clock-skew allowance), so once authorize + window + skew is behind the
1135
+ * payment, no poll — and no sweep tick — can ever change the answer.
1136
+ * The paired `next_action` is `stop_and_tell_user`: tell the user the goods
1137
+ * were delivered but Haven holds no verified settlement evidence; reporting
1138
+ * a real settlement hash (`haven_report_settlement_evidence`) still works
1139
+ * at any age.
1140
+ */
1141
+ readonly DeliveredUnverified: "delivered_unverified";
1068
1142
  };
1069
1143
  type AgentPaymentPhase = (typeof AgentPaymentPhase)[keyof typeof AgentPaymentPhase];
1070
1144
  declare const AgentPaymentNextAction: {
@@ -1222,7 +1296,7 @@ declare const AgentPaymentRail: {
1222
1296
  type AgentPaymentRail = (typeof AgentPaymentRail)[keyof typeof AgentPaymentRail];
1223
1297
  type PaymentPhase = AgentPaymentPhase;
1224
1298
  type PaymentNextAction = AgentPaymentNextAction;
1225
- 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")[];
1299
+ 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" | "delivered_unverified")[];
1226
1300
  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_account_or_raise_allowance" | "sweep_stranded_funds" | "awaiting_settlement_evidence")[];
1227
1301
  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")[];
1228
1302
  declare const AGENT_PAYMENT_RAIL_VALUES: ("x402" | "mpp_demo" | "mpp_crypto" | "stripe_deposit" | "spt" | "direct" | "mpp")[];
@@ -1408,6 +1482,11 @@ interface PaymentStatusResult {
1408
1482
  expiresAt: string;
1409
1483
  chainId: number;
1410
1484
  message: string;
1485
+ /**
1486
+ * #3420: `true` = the merchant answered 2xx (a `machine_payment_evidence`
1487
+ * row records its response); absent = unknown. See the raw field's doc.
1488
+ */
1489
+ delivered?: boolean;
1411
1490
  /** Platform fee surfaced so it's never silently collected (#386). */
1412
1491
  fee?: PaymentFee | null;
1413
1492
  amountAtomic?: string | null;
@@ -1568,6 +1647,32 @@ declare class MerchantTimeoutError extends HavenApiError {
1568
1647
  readonly merchantErrorCode: "merchant_timeout";
1569
1648
  constructor(message: string);
1570
1649
  }
1650
+ /**
1651
+ * #3417: an erc7710 `POST /x402` authorize replayed a key whose payment to THIS
1652
+ * merchant for THIS resource has already settled. The backend returns
1653
+ * `200 { status: 'confirmed', tx_hash, to, resource_url }` and, correctly, no
1654
+ * `sign_data`, because nothing is left to sign
1655
+ * (`packages/backend/src/modules/x402/replay.ts`). Before this class the
1656
+ * erc7710 path read that answer as a scheme mismatch and threw a 500, which
1657
+ * hosted callers relayed as "transient, retry". Typed so a caller can report
1658
+ * the original settlement instead of retrying, and never signs anything.
1659
+ *
1660
+ * Only thrown when the confirmed row pays the merchant this request names, for
1661
+ * the resource it asked for. The backend's replay lookup is keyed on the
1662
+ * idempotency key alone, so a key reused for another payee or resource — or
1663
+ * first spent on an EIP-3009 funding leg, whose confirmed `tx_hash` proves only
1664
+ * that the delegate was funded — is refused as a 409 collision instead of read
1665
+ * as this settlement. Amount and the MCP tool call are not compared: on an MCP
1666
+ * merchant the resource is its endpoint, so a key reused for another tool
1667
+ * there is answered as that merchant's earlier payment. A `HavenError`, not a `HavenApiError`: nothing failed upstream.
1668
+ */
1669
+ declare class X402Erc7710AlreadySettledError extends HavenError {
1670
+ readonly paymentId: string;
1671
+ readonly txHash: string;
1672
+ readonly body?: unknown | undefined;
1673
+ readonly x402ErrorCode: "payment_already_settled";
1674
+ constructor(paymentId: string, txHash: string, body?: unknown | undefined);
1675
+ }
1571
1676
  declare class X402UnexpectedStatusError extends HavenApiError {
1572
1677
  readonly x402ErrorCode: "unexpected_non_402_status";
1573
1678
  /**
@@ -1626,6 +1731,33 @@ declare class HavenPaymentStateError extends HavenApiError {
1626
1731
  get phase(): PaymentPhase;
1627
1732
  get nextAction(): PaymentNextAction;
1628
1733
  }
1734
+ /**
1735
+ * #3392: the SDK's x402 receipt cache and in-flight map record the
1736
+ * `taskBudgetId` each entry was created under. A call reusing an idempotency
1737
+ * key whose cached/in-flight entry was created under a DIFFERENT task budget
1738
+ * is refused with this typed error BEFORE any network call — the alternative
1739
+ * was silently returning (or joining) a payment charged to another budget.
1740
+ * Typed rather than `HavenApiError`-shaped: no request was attempted, so
1741
+ * there is no HTTP status or response body to carry (the
1742
+ * `HavenZeroSettlementHashError` precedent). A caller that genuinely wants to
1743
+ * pay again under a different budget passes a new `idempotencyKey`.
1744
+ */
1745
+ declare class X402TaskBudgetMismatchError extends HavenError {
1746
+ /** The idempotency key whose cached entry was created under another budget. */
1747
+ readonly idempotencyKey: string;
1748
+ /** The budget the cached/in-flight entry was created under (undefined = none). */
1749
+ readonly entryTaskBudgetId: string | undefined;
1750
+ /** The budget this call named (undefined = none). */
1751
+ readonly requestedTaskBudgetId: string | undefined;
1752
+ readonly x402ErrorCode: "task_budget_mismatch";
1753
+ constructor(message: string,
1754
+ /** The idempotency key whose cached entry was created under another budget. */
1755
+ idempotencyKey: string,
1756
+ /** The budget the cached/in-flight entry was created under (undefined = none). */
1757
+ entryTaskBudgetId: string | undefined,
1758
+ /** The budget this call named (undefined = none). */
1759
+ requestedTaskBudgetId: string | undefined);
1760
+ }
1629
1761
  declare class HavenSigningError extends HavenError {
1630
1762
  constructor(message: string);
1631
1763
  }
@@ -1901,7 +2033,7 @@ declare function buildSweepAuthorizationMessage(auth: SweepAuthorization): strin
1901
2033
  * This SDK's own version. Owned by `scripts/release-bump.mjs`, which rewrites
1902
2034
  * it with the package version on every release — never hand-edit it.
1903
2035
  */
1904
- declare const SDK_VERSION = "0.6.0-alpha.0";
2036
+ declare const SDK_VERSION = "0.7.0-alpha.0";
1905
2037
  /** The request header every published Haven client sends. */
1906
2038
  declare const HAVEN_CLIENT_HEADER = "X-Haven-Client";
1907
2039
  /** `<package>/<version>` — the value of {@link HAVEN_CLIENT_HEADER}. */
@@ -2120,6 +2252,28 @@ declare function connectorRerunCommand(args?: string, options?: {
2120
2252
  channel?: string;
2121
2253
  npxFlags?: string;
2122
2254
  }): string;
2255
+ /**
2256
+ * The command every UPGRADE hint names (#3412): `npx -y @haven_ai/connect@<channel> --doctor`.
2257
+ *
2258
+ * A bare connector re-run is a SETUP command — on a machine that is already
2259
+ * set up it stops at "Missing --setup <hv_setup_...> setup token", so an
2260
+ * outdated signer, local MCP or connector told to "re-run the connector" was
2261
+ * handed a dead end. The flagless doctor works as pasted on an existing
2262
+ * install (#3210: it resolves the runtime from the setup record), diagnoses an
2263
+ * outdated signer, and prints the exact `--doctor --repair` line for the agent
2264
+ * it describes — with `--credentials-dir` whenever more than one agent lives on
2265
+ * the machine, so the repair cannot land on a different agent.
2266
+ *
2267
+ * `-y` because an upgrade hint is often run by an agent in a non-interactive
2268
+ * shell. `@haven_ai/core`'s `upgradeCommandFor` (the backend's
2269
+ * `client_update.upgrade_command`) cannot import this package, so it carries a
2270
+ * copy; `packages/backend/src/__tests__/connector-upgrade-command-parity.test.ts`
2271
+ * fails if the two ever disagree. Setup-time hints (identity restore,
2272
+ * mid-setup retry) legitimately stay on {@link connectorRerunCommand}.
2273
+ */
2274
+ declare function connectorUpgradeCommand(options?: {
2275
+ channel?: string;
2276
+ }): string;
2123
2277
 
2124
2278
  /**
2125
2279
  * The Node.js floor Haven's published packages support (#1161).
@@ -2472,6 +2626,19 @@ declare function resolveTokenFromAddress(address: string, network?: string): {
2472
2626
  symbol: string;
2473
2627
  decimals: number;
2474
2628
  } | null;
2629
+ /**
2630
+ * #3410: token decimals from a SYMBOL + CHAIN — the same registry
2631
+ * `resolveTokenFromAddress` reads, keyed the other way. The address-based
2632
+ * resolver needs the token's contract address, which the consent seed path
2633
+ * (setup-time credential files) does not carry; the symbol and chain it does
2634
+ * carry. Null when the symbol is not registered on that chain (unknown or
2635
+ * custom tokens) — callers must fall back to an explicit atomic label rather
2636
+ * than reading an atomic amount as whole tokens.
2637
+ */
2638
+ declare function resolveTokenBySymbol(chainId: number, symbol: string): {
2639
+ symbol: string;
2640
+ decimals: number;
2641
+ } | null;
2475
2642
 
2476
2643
  /**
2477
2644
  * #3271: the integrity check every client runs before signing a direct
@@ -2502,6 +2669,19 @@ declare function resolveTokenFromAddress(address: string, network?: string): {
2502
2669
  */
2503
2670
  /** Version of the direct-payment sign context (`GET /payments/:id/sign-context`). */
2504
2671
  declare const DIRECT_SIGN_CONTEXT_VERSION = 1;
2672
+ /**
2673
+ * #3419: version of the task-budget sign context (`GET
2674
+ * /task-budgets/:id/sign-context`), the sign-then-submit envelope every
2675
+ * `haven_sign { task_budget_id }` call fetches. The backend emits it
2676
+ * (`task-budget-service.ts`, `task_sign_context_version: 1`); the signer
2677
+ * derives its enforced set `SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS` from this
2678
+ * constant — never a second literal — and the hosted/local task-budget
2679
+ * handoffs report it in `signer_compatibility.task_sign_context_version`.
2680
+ * The signer could not carry the single source itself (a published package
2681
+ * cannot host a constant the backend also serves), so it lives beside the
2682
+ * other binding constants here, exactly as `DIRECT_SIGN_CONTEXT_VERSION` does.
2683
+ */
2684
+ declare const TASK_SIGN_CONTEXT_VERSION = 1;
2505
2685
  /** The ERC-4337 v0.7 EntryPoint — the only one the delegation rail submits to. */
2506
2686
  declare const ENTRY_POINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
2507
2687
  /**
@@ -2955,4 +3135,4 @@ declare function encodeBase64Json(value: unknown): string;
2955
3135
  */
2956
3136
  declare function decodeBase64Json<T>(value: string, label?: string): T;
2957
3137
 
2958
- export { AgentPaymentPhase as $, type AgentPaymentWarning as A, type ResumeAuthorizedX402Input as B, type CloseTaskBudgetResult as C, type ResumeX402PaymentInput as D, type X402ResumeState as E, type X402McpTransport as F, type X402MerchantCallContext as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, AGENT_PAYMENT_RAIL_VALUES as M, type AgentNextStep as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentPaymentEnumSchema as Q, type RawPaymentParties as R, type SweepResult as S, type TaskBudgetSignContext as T, AgentPaymentFailureCode as U, AgentPaymentFailureCodeDescriptions as V, AgentPaymentFailureCodeSchema as W, type X402PaymentRequired as X, AgentPaymentNextAction as Y, AgentPaymentNextActionDescriptions as Z, AgentPaymentNextActionSchema as _, type HavenClientUpdate as a, type SweepExpectedAuth as a$, AgentPaymentPhaseDescriptions as a0, AgentPaymentPhaseSchema as a1, AgentPaymentRail as a2, AgentPaymentRailDescriptions as a3, AgentPaymentRailSchema as a4, type AgentPaymentSummary as a5, AgentPaymentWarningCode as a6, type AgentPurchaseSummary as a7, CONNECTOR_PACKAGE_NAME as a8, type CatalogSubmissionAccepted as a9, NEXT_TOOL_SERVER_NAMES as aA, NEXT_TOOL_SERVER_ROLES as aB, type NextStep as aC, type NextStepArguments as aD, type NextStepHandoff as aE, type NextStepInput as aF, type NextStepTarget as aG, type NextStepTargets as aH, type NextToolServerRole as aI, PACKED_USER_OPERATION_FIELDS as aJ, type PaymentFee as aK, type PaymentNextAction as aL, type PaymentPhase as aM, type PaymentStatus as aN, ROOT_AUTHORITY as aO, SDK_CLIENT_IDENTITY as aP, SDK_VERSION as aQ, SIGNER_UPDATE_FALLBACK as aR, SWEEP_BASE_CHAIN_ID as aS, SWEEP_BASE_SEPOLIA_CHAIN_ID as aT, SWEEP_BASE_SEPOLIA_USDC_ADDRESS as aU, SWEEP_BASE_USDC_ADDRESS as aV, type SettlementChildExpectation as aW, SignerRefusalCode as aX, type SweepConfirmation as aY, type SweepEip712Domain as aZ, type SweepEntry as a_, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, DEFAULT_NEXT_TOOL_BY_ACTION as ab, DIRECT_SIGN_CONTEXT_VERSION as ac, ENTRY_POINT_V07 as ad, ERC7710_ASSET_TRANSFER_METHOD as ae, HAVEN_CLIENT_HEADER as af, HAVEN_CONNECTOR_CHANNEL as ag, HAVEN_MINIMUM_NODE_VERSION as ah, HYBRID_DELEGATOR_DOMAIN_NAME as ai, HYBRID_DELEGATOR_DOMAIN_VERSION as aj, type HavenAgentAllowanceSummary as ak, type HavenAgentReadiness as al, type HavenAllowance as am, HavenApiError as an, type HavenCatalogMerchant as ao, type HavenListScope as ap, HavenPaymentStateError as aq, HavenSigningError as ar, HavenTimeoutError as as, HavenTypedDataRefusedError as at, HavenUnsupportedSignerVersionError as au, HavenUserOpBindingError as av, HavenZeroSettlementHashError as aw, MAX_TASK_BUDGET_TTL_SECONDS as ax, type MachinePaymentRail as ay, MerchantTimeoutError as az, type PaymentResult as b, selectX402SettlementScheme as b$, type SweepPreparation as b0, type SweepSubmitResult as b1, type SweepTypedData as b2, TRANSFER_WITH_AUTHORIZATION_TYPES as b3, TYPED_DATA_NOT_ALLOWED as b4, type TaskBudgetCloseExpectation as b5, type TaskChildExpectation as b6, type TaskChildTypedData as b7, type UnsupportedNodeVersionMessageOptions as b8, X402AlreadySettledError as b9, decodeBase64Json as bA, decodeBase64Utf8 as bB, defaultNextToolFor as bC, deriveDelegateAccountAddress as bD, encodeBase64Json as bE, encodeBase64Utf8 as bF, encodePaymentProof as bG, hashDelegation as bH, havenClientIdentity as bI, isConnectorChannel as bJ, isErc7710Option as bK, isPackedUserOperationTypedData as bL, isSupportedNodeVersion as bM, isSweepableChain as bN, isTaskChildTypedData as bO, normalizePaymentRequired as bP, packedUserOperationHash as bQ, parseNextTool as bR, parsePaymentRequired as bS, parsePaymentRequiredResponse as bT, readClientUpdate as bU, renderNextTool as bV, resolveConnectorChannel as bW, resolveTokenFromAddress as bX, selectErc7710PaymentOption as bY, selectPaymentOption as bZ, selectStandardPaymentOption as b_, type X402ExpectedAuth as ba, type X402ExpectedContext as bb, type X402PaymentHeaderContext as bc, X402PaymentHeaderValidationError as bd, type X402PaymentOption as be, type X402RequestSnapshot as bf, type X402SchemeSelection as bg, X402UnexpectedStatusError as bh, X402_LEGACY_PAYMENT_HEADER_NAME as bi, X402_MAX_AUTHORIZATION_WINDOW_SECONDS as bj, X402_PAYMENT_HEADER_NAME as bk, X402_PAYMENT_HEADER_NAMES_SENT as bl, X402_PAYMENT_REQUIRED_HEADER_NAME as bm, X402_PAYMENT_RESPONSE_HEADER_NAME as bn, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS as bo, assertBoundDirectPaymentUserOp as bp, assertOwnTaskBudgetCloseUserOp as bq, assertOwnTaskChild as br, assertUserOpTypedDataBinding as bs, buildSweepAuthorizationMessage as bt, buildSweepTypedData as bu, buildX402ExpectedMessage as bv, compareNodeVersions as bw, connectorRerunCommand as bx, connectorSpec as by, createNextStepBuilder as bz, type PaymentIntent as c, signerUpdateFallback as c0, sweepUsdcAddress as c1, sweepUsdcDomain as c2, toStandardPaymentRequirements as c3, unsupportedNodeVersionMessage as c4, validateStandardX402PaymentHeader as c5, verifySettlementChild as c6, x402AssetTransferMethod as c7, x402AuthorizationAmount as c8, x402FacilitatorAddresses as c9, x402V2PaymentEnvelope as ca, CAVEAT_ENFORCERS as cb, CAVEAT_TYPEHASH as cc, DELEGATION_MANAGER as cd, DELEGATION_TYPEHASH as ce, DIRECT_PAYMENT_CHAIN_IDS as cf, type DelegationForHashing as cg, EXECUTE_ABI as ch, HYBRID_DELEGATOR_IMPLEMENTATION as ci, MAX_SETTLEMENT_WINDOW_SECONDS as cj, SIMPLE_FACTORY_ADDRESS as ck, type SettlementChildTypedData as cl, assertFundingLegPaysDelegate as cm, assertOwnSettlementChild as cn, chainIdForNetwork as co, isSettlementChildTypedData as cp, type X402AuthorizationOptions as d, type X402Intent as e, type PaymentStatusResult as f, type HavenAgent as g, type HavenAgentSummary as h, type SweepPrepareResponse as i, type SweepAuthorization as j, type SweepSubmitResponse as k, type HavenAllowanceSummary as l, type HavenBalanceCoverage as m, type PostPurchaseAllowanceSummary as n, type HavenCatalogEntry as o, type HavenCatalogSubmission as p, type HavenPaymentReceipt as q, type HavenPaymentReceiptsPage as r, type HavenTaskBudget as s, type SubmitTaskBudgetResult as t, type PaymentResumeState as u, type X402Receipt as v, type X402Quote as w, type X402Erc7710Settlement as x, type X402McpCallContext as y, type SignData as z };
3138
+ export { AgentPaymentPhase as $, type AgentPaymentWarning as A, type ResumeAuthorizedX402Input as B, type CloseTaskBudgetResult as C, type ResumeX402PaymentInput as D, type X402ResumeState as E, type X402McpTransport as F, type X402MerchantCallContext as G, type HavenClientConfig as H, HavenError as I, AGENT_PAYMENT_FAILURE_CODE_VALUES as J, AGENT_PAYMENT_NEXT_ACTION_VALUES as K, AGENT_PAYMENT_PHASE_VALUES as L, AGENT_PAYMENT_RAIL_VALUES as M, type AgentNextStep as N, type OpenTaskBudgetResult as O, type PaymentRequest as P, type AgentPaymentEnumSchema as Q, type RawPaymentParties as R, type SweepResult as S, type TaskBudgetSignContext as T, AgentPaymentFailureCode as U, AgentPaymentFailureCodeDescriptions as V, AgentPaymentFailureCodeSchema as W, type X402PaymentRequired as X, AgentPaymentNextAction as Y, AgentPaymentNextActionDescriptions as Z, AgentPaymentNextActionSchema as _, type HavenClientUpdate as a, type SweepExpectedAuth as a$, AgentPaymentPhaseDescriptions as a0, AgentPaymentPhaseSchema as a1, AgentPaymentRail as a2, AgentPaymentRailDescriptions as a3, AgentPaymentRailSchema as a4, type AgentPaymentSummary as a5, AgentPaymentWarningCode as a6, type AgentPurchaseSummary as a7, CONNECTOR_PACKAGE_NAME as a8, type CatalogSubmissionAccepted as a9, NEXT_TOOL_SERVER_NAMES as aA, NEXT_TOOL_SERVER_ROLES as aB, type NextStep as aC, type NextStepArguments as aD, type NextStepHandoff as aE, type NextStepInput as aF, type NextStepTarget as aG, type NextStepTargets as aH, type NextToolServerRole as aI, PACKED_USER_OPERATION_FIELDS as aJ, type PaymentFee as aK, type PaymentNextAction as aL, type PaymentPhase as aM, type PaymentStatus as aN, ROOT_AUTHORITY as aO, SDK_CLIENT_IDENTITY as aP, SDK_VERSION as aQ, SIGNER_UPDATE_FALLBACK as aR, SWEEP_BASE_CHAIN_ID as aS, SWEEP_BASE_SEPOLIA_CHAIN_ID as aT, SWEEP_BASE_SEPOLIA_USDC_ADDRESS as aU, SWEEP_BASE_USDC_ADDRESS as aV, type SettlementChildExpectation as aW, SignerRefusalCode as aX, type SweepConfirmation as aY, type SweepEip712Domain as aZ, type SweepEntry as a_, DEFAULT_CONFIRMATION_TIMEOUT_MS as aa, DEFAULT_NEXT_TOOL_BY_ACTION as ab, DIRECT_SIGN_CONTEXT_VERSION as ac, ENTRY_POINT_V07 as ad, ERC7710_ASSET_TRANSFER_METHOD as ae, HAVEN_CLIENT_HEADER as af, HAVEN_CONNECTOR_CHANNEL as ag, HAVEN_MINIMUM_NODE_VERSION as ah, HYBRID_DELEGATOR_DOMAIN_NAME as ai, HYBRID_DELEGATOR_DOMAIN_VERSION as aj, type HavenAgentAllowanceSummary as ak, type HavenAgentReadiness as al, type HavenAllowance as am, HavenApiError as an, type HavenCatalogMerchant as ao, type HavenListScope as ap, HavenPaymentStateError as aq, HavenSigningError as ar, HavenTimeoutError as as, HavenTypedDataRefusedError as at, HavenUnsupportedSignerVersionError as au, HavenUserOpBindingError as av, HavenZeroSettlementHashError as aw, MAX_TASK_BUDGET_TTL_SECONDS as ax, type MachinePaymentRail as ay, MerchantTimeoutError as az, type PaymentResult as b, resolveTokenBySymbol as b$, type SweepPreparation as b0, type SweepSubmitResult as b1, type SweepTypedData as b2, TASK_SIGN_CONTEXT_VERSION as b3, TRANSFER_WITH_AUTHORIZATION_TYPES as b4, TYPED_DATA_NOT_ALLOWED as b5, type TaskBudgetCloseExpectation as b6, type TaskChildExpectation as b7, type TaskChildTypedData as b8, type UnsupportedNodeVersionMessageOptions as b9, connectorRerunCommand as bA, connectorSpec as bB, connectorUpgradeCommand as bC, createNextStepBuilder as bD, decodeBase64Json as bE, decodeBase64Utf8 as bF, defaultNextToolFor as bG, deriveDelegateAccountAddress as bH, encodeBase64Json as bI, encodeBase64Utf8 as bJ, encodePaymentProof as bK, hashDelegation as bL, havenClientIdentity as bM, isConnectorChannel as bN, isErc7710Option as bO, isPackedUserOperationTypedData as bP, isSupportedNodeVersion as bQ, isSweepableChain as bR, isTaskChildTypedData as bS, normalizePaymentRequired as bT, packedUserOperationHash as bU, parseNextTool as bV, parsePaymentRequired as bW, parsePaymentRequiredResponse as bX, readClientUpdate as bY, renderNextTool as bZ, resolveConnectorChannel as b_, X402AlreadySettledError as ba, X402Erc7710AlreadySettledError as bb, type X402ExpectedAuth as bc, type X402ExpectedContext as bd, type X402PaymentHeaderContext as be, X402PaymentHeaderValidationError as bf, type X402PaymentOption as bg, type X402RequestSnapshot as bh, type X402SchemeSelection as bi, X402TaskBudgetMismatchError as bj, X402UnexpectedStatusError as bk, X402_LEGACY_PAYMENT_HEADER_NAME as bl, X402_MAX_AUTHORIZATION_WINDOW_SECONDS as bm, X402_PAYMENT_HEADER_NAME as bn, X402_PAYMENT_HEADER_NAMES_SENT as bo, X402_PAYMENT_REQUIRED_HEADER_NAME as bp, X402_PAYMENT_RESPONSE_HEADER_NAME as bq, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS as br, assertBoundDirectPaymentUserOp as bs, assertOwnTaskBudgetCloseUserOp as bt, assertOwnTaskChild as bu, assertUserOpTypedDataBinding as bv, buildSweepAuthorizationMessage as bw, buildSweepTypedData as bx, buildX402ExpectedMessage as by, compareNodeVersions as bz, type PaymentIntent as c, resolveTokenFromAddress as c0, selectErc7710PaymentOption as c1, selectPaymentOption as c2, selectStandardPaymentOption as c3, selectX402SettlementScheme as c4, signerUpdateFallback as c5, sweepUsdcAddress as c6, sweepUsdcDomain as c7, toStandardPaymentRequirements as c8, unsupportedNodeVersionMessage as c9, validateStandardX402PaymentHeader as ca, verifySettlementChild as cb, x402AssetTransferMethod as cc, x402AuthorizationAmount as cd, x402FacilitatorAddresses as ce, x402V2PaymentEnvelope as cf, type DelegationForHashing as cg, CAVEAT_ENFORCERS as ch, CAVEAT_TYPEHASH as ci, DELEGATION_MANAGER as cj, DELEGATION_TYPEHASH as ck, DIRECT_PAYMENT_CHAIN_IDS as cl, EXECUTE_ABI as cm, HYBRID_DELEGATOR_IMPLEMENTATION as cn, MAX_SETTLEMENT_WINDOW_SECONDS as co, SIMPLE_FACTORY_ADDRESS as cp, type SettlementChildTypedData as cq, assertFundingLegPaysDelegate as cr, assertOwnSettlementChild as cs, chainIdForNetwork as ct, isSettlementChildTypedData as cu, type X402AuthorizationOptions as d, type X402Intent as e, type PaymentStatusResult as f, type HavenAgent as g, type HavenAgentSummary as h, type SweepPrepareResponse as i, type SweepAuthorization as j, type SweepSubmitResponse as k, type HavenAllowanceSummary as l, type HavenBalanceCoverage as m, type PostPurchaseAllowanceSummary as n, type HavenCatalogEntry as o, type HavenCatalogSubmission as p, type HavenPaymentReceipt as q, type HavenPaymentReceiptsPage as r, type HavenTaskBudget as s, type SubmitTaskBudgetResult as t, type PaymentResumeState as u, type X402Receipt as v, type X402Quote as w, type X402Erc7710Settlement as x, type X402McpCallContext as y, type SignData as z };
@@ -28,6 +28,9 @@ function connectorRerunCommand(args, options) {
28
28
  const command = `npx ${flags}${connectorSpec(channel)}`;
29
29
  return args ? `${command} ${args}` : command;
30
30
  }
31
+ function connectorUpgradeCommand(options) {
32
+ return connectorRerunCommand("--doctor", { channel: options?.channel, npxFlags: "-y" });
33
+ }
31
34
 
32
35
  // src/types.ts
33
36
  var DEFAULT_CONFIRMATION_TIMEOUT_MS = 9e4;
@@ -73,7 +76,21 @@ var AgentPaymentPhase = {
73
76
  * agent should stop, tell the user, and wait for the sweep flow to reclaim
74
77
  * the funds.
75
78
  */
76
- FundedButUnsettled: "funded_but_unsettled"
79
+ FundedButUnsettled: "funded_but_unsettled",
80
+ /**
81
+ * #3420: TERMINAL — a `submitted` erc7710 x402 intent whose settlement
82
+ * window AND the sweep's last attribution chance have both passed with no
83
+ * verified evidence. The sweep's tick (120s) only ever confirms a
84
+ * transaction mined inside the payment's own settlement window (the child
85
+ * delegation's on-chain `timestamp` caveat, plus the verifier's 120s
86
+ * clock-skew allowance), so once authorize + window + skew is behind the
87
+ * payment, no poll — and no sweep tick — can ever change the answer.
88
+ * The paired `next_action` is `stop_and_tell_user`: tell the user the goods
89
+ * were delivered but Haven holds no verified settlement evidence; reporting
90
+ * a real settlement hash (`haven_report_settlement_evidence`) still works
91
+ * at any age.
92
+ */
93
+ DeliveredUnverified: "delivered_unverified"
77
94
  };
78
95
  var AgentPaymentNextAction = {
79
96
  /** Sign with the delegate key and submit the payment to Haven. */
@@ -221,7 +238,8 @@ var AgentPaymentPhaseDescriptions = {
221
238
  [AgentPaymentPhase.Expired]: "The payment expired before completion.",
222
239
  [AgentPaymentPhase.Failed]: "Haven could not complete the payment; the agent should stop and surface the failure.",
223
240
  [AgentPaymentPhase.InsufficientFunds]: "Pre-flight check determined the delegate balance plus the remaining on-chain budget cannot cover the requested amount, so no payment was created. The account must be funded or the agent budget raised before retrying.",
224
- [AgentPaymentPhase.FundedButUnsettled]: "Haven's funding leg confirmed on-chain but the merchant rejected the x402 retry. The delegate wallet may hold stranded funds. The agent should stop and wait for the wallet owner to sweep the stranded funds back to the account."
241
+ [AgentPaymentPhase.FundedButUnsettled]: "Haven's funding leg confirmed on-chain but the merchant rejected the x402 retry. The delegate wallet may hold stranded funds. The agent should stop and wait for the wallet owner to sweep the stranded funds back to the account.",
242
+ [AgentPaymentPhase.DeliveredUnverified]: "Terminal: the merchant delivered the goods and the settlement window plus the sweep's last attribution chance have both passed with no verified on-chain evidence. The payment can no longer resolve by polling. Tell the user the goods were delivered but Haven holds no verified settlement evidence for this payment."
225
243
  };
226
244
  var AgentPaymentNextActionDescriptions = {
227
245
  [AgentPaymentNextAction.SignAndSubmitPayment]: "Sign with the delegate key and submit the payment to Haven.",
@@ -356,6 +374,24 @@ var MerchantTimeoutError = class extends HavenApiError {
356
374
  this.name = "MerchantTimeoutError";
357
375
  }
358
376
  };
377
+ var X402Erc7710AlreadySettledError = class extends HavenError {
378
+ constructor(paymentId, txHash, body) {
379
+ super(
380
+ `Payment ${paymentId} already settled on-chain (tx ${txHash}). Nothing was signed and nothing new was charged.`,
381
+ "PAYMENT_ALREADY_SETTLED",
382
+ void 0,
383
+ paymentId
384
+ );
385
+ this.paymentId = paymentId;
386
+ this.txHash = txHash;
387
+ this.body = body;
388
+ this.name = "X402Erc7710AlreadySettledError";
389
+ }
390
+ paymentId;
391
+ txHash;
392
+ body;
393
+ x402ErrorCode = "payment_already_settled";
394
+ };
359
395
  var X402UnexpectedStatusError = class extends HavenApiError {
360
396
  x402ErrorCode = "unexpected_non_402_status";
361
397
  /**
@@ -402,6 +438,19 @@ var HavenPaymentStateError = class extends HavenApiError {
402
438
  return this.state.nextAction;
403
439
  }
404
440
  };
441
+ var X402TaskBudgetMismatchError = class extends HavenError {
442
+ constructor(message, idempotencyKey, entryTaskBudgetId, requestedTaskBudgetId) {
443
+ super(message, "X402_TASK_BUDGET_MISMATCH");
444
+ this.idempotencyKey = idempotencyKey;
445
+ this.entryTaskBudgetId = entryTaskBudgetId;
446
+ this.requestedTaskBudgetId = requestedTaskBudgetId;
447
+ this.name = "X402TaskBudgetMismatchError";
448
+ }
449
+ idempotencyKey;
450
+ entryTaskBudgetId;
451
+ requestedTaskBudgetId;
452
+ x402ErrorCode = "task_budget_mismatch";
453
+ };
405
454
  var HavenSigningError = class extends HavenError {
406
455
  constructor(message) {
407
456
  super(message, "SIGNING_ERROR");
@@ -426,7 +475,7 @@ var SignerRefusalCode = {
426
475
  UnsupportedSweepBindingVersion: "UNSUPPORTED_SWEEP_BINDING_VERSION"
427
476
  };
428
477
  function signerUpdateFallback(channel = HAVEN_CONNECTOR_CHANNEL) {
429
- return `Update @haven_ai/signer by rerunning \`${connectorRerunCommand(void 0, { channel })}\`, which reinstalls the pinned MCP runtime, then retry the same signing call. Nothing was signed or spent \u2014 the quote or payment this version came from is unaffected and does not need to be re-quoted.`;
478
+ return `Update @haven_ai/signer: run \`${connectorUpgradeCommand({ channel })}\` and then the repair line it prints, which reinstalls the pinned MCP runtime, then retry the same signing call. Nothing was signed or spent \u2014 the quote or payment this version came from is unaffected and does not need to be re-quoted.`;
430
479
  }
431
480
  var SIGNER_UPDATE_FALLBACK = signerUpdateFallback();
432
481
  var HavenUnsupportedSignerVersionError = class extends HavenError {
@@ -453,6 +502,7 @@ var HavenTimeoutError = class extends HavenError {
453
502
  }
454
503
  };
455
504
  var DIRECT_SIGN_CONTEXT_VERSION = 1;
505
+ var TASK_SIGN_CONTEXT_VERSION = 1;
456
506
  var EIP712_DOMAIN_FIELDS = [
457
507
  { name: "name", type: "string" },
458
508
  { name: "version", type: "string" },
@@ -850,7 +900,7 @@ var REDEEM_DELEGATIONS_ABI = [
850
900
  var SINGLE_DEFAULT_MODE = `0x${"00".repeat(32)}`;
851
901
  function refuse3(detail) {
852
902
  throw new HavenSigningError(
853
- `Refusing to sign: this UserOperation's redeemDelegations call ${detail}. This signer only signs one of two shapes: a single grant to the agent's own account, or a self-delegated task-budget child redeemed under it (the two-link [task child, budget] chain).`
903
+ `Refusing to sign: this UserOperation's redeemDelegations call ${detail}. This signer only signs one of three shapes: a single grant to the agent's own account, a self-delegated task-budget child redeemed under it (the two-link [task child, budget] chain), or a sub-budget grant redeemed under its parent's self-narrowing (the three-link [sub grant, parent child, budget] chain, #3330).`
854
904
  );
855
905
  }
856
906
  function assertRedeemsOwnBudgetDelegation(redeemCalldata, ownAccount) {
@@ -894,9 +944,9 @@ function assertRedeemsOwnBudgetDelegation(redeemCalldata, ownAccount) {
894
944
  "carries an EMPTY delegation chain \u2014 DelegationManager treats this as self-authorised and runs the paired execution as the account, with no caveat, budget or recipient pin"
895
945
  );
896
946
  }
897
- if (delegations.length !== 1 && delegations.length !== 2) {
947
+ if (delegations.length !== 1 && delegations.length !== 2 && delegations.length !== 3) {
898
948
  refuse3(
899
- `carries a ${delegations.length}-link delegation chain, not the single budget grant or the two-link [task child, budget] chain Haven emits`
949
+ `carries a ${delegations.length}-link delegation chain, not the single budget grant, the two-link [task child, budget] chain, or the three-link [sub grant, parent child, budget] chain Haven emits`
900
950
  );
901
951
  }
902
952
  const reEncodedContext = viem.encodeAbiParameters(DELEGATION_ARRAY_PARAM, [delegations]);
@@ -928,6 +978,37 @@ function assertRedeemsOwnBudgetDelegation(redeemCalldata, ownAccount) {
928
978
  }
929
979
  return;
930
980
  }
981
+ if (delegations.length === 3) {
982
+ if (leaf.delegator.toLowerCase() === ownAccount.toLowerCase()) {
983
+ refuse3(
984
+ "carries a three-link chain whose leaf is delegated by this signer's OWN account \u2014 a sub-budget grant always comes from the delegating agent, never from the sub-agent itself"
985
+ );
986
+ }
987
+ const parentChild = delegations[1];
988
+ const parentAccount = leaf.delegator;
989
+ if (parentChild.delegate.toLowerCase() !== parentAccount.toLowerCase()) {
990
+ refuse3(
991
+ `carries a three-link chain whose middle link delegates to ${parentChild.delegate}, not the delegating agent's account the leaf names as its delegator (${parentAccount})`
992
+ );
993
+ }
994
+ if (parentChild.delegator.toLowerCase() !== parentAccount.toLowerCase()) {
995
+ refuse3(
996
+ `carries a three-link chain whose middle link is delegated by ${parentChild.delegator}, not the delegating agent's own account (${parentAccount}) \u2014 the parent link is a self-delegated narrowing`
997
+ );
998
+ }
999
+ const budget = delegations[2];
1000
+ if (budget.delegate.toLowerCase() !== parentAccount.toLowerCase()) {
1001
+ refuse3(
1002
+ `carries a three-link chain whose budget link delegates to ${budget.delegate}, not the delegating agent's account (${parentAccount})`
1003
+ );
1004
+ }
1005
+ if (budget.delegator.toLowerCase() === parentAccount.toLowerCase()) {
1006
+ refuse3(
1007
+ "carries a three-link chain whose budget link is granted by the delegating agent's OWN account \u2014 a real budget delegation always comes from elsewhere"
1008
+ );
1009
+ }
1010
+ return;
1011
+ }
931
1012
  const root = delegations[delegations.length - 1];
932
1013
  if (root.delegator.toLowerCase() === ownAccount.toLowerCase()) {
933
1014
  refuse3(
@@ -981,13 +1062,17 @@ exports.SIGNER_UPDATE_FALLBACK = SIGNER_UPDATE_FALLBACK;
981
1062
  exports.SIMPLE_FACTORY_ADDRESS = SIMPLE_FACTORY_ADDRESS;
982
1063
  exports.SINGLE_DEFAULT_MODE = SINGLE_DEFAULT_MODE;
983
1064
  exports.SignerRefusalCode = SignerRefusalCode;
1065
+ exports.TASK_SIGN_CONTEXT_VERSION = TASK_SIGN_CONTEXT_VERSION;
984
1066
  exports.X402AlreadySettledError = X402AlreadySettledError;
1067
+ exports.X402Erc7710AlreadySettledError = X402Erc7710AlreadySettledError;
1068
+ exports.X402TaskBudgetMismatchError = X402TaskBudgetMismatchError;
985
1069
  exports.X402UnexpectedStatusError = X402UnexpectedStatusError;
986
1070
  exports.assertRedeemsOwnBudgetDelegation = assertRedeemsOwnBudgetDelegation;
987
1071
  exports.assertUserOpTypedDataBinding = assertUserOpTypedDataBinding;
988
1072
  exports.chainIdForNetwork = chainIdForNetwork;
989
1073
  exports.connectorRerunCommand = connectorRerunCommand;
990
1074
  exports.connectorSpec = connectorSpec;
1075
+ exports.connectorUpgradeCommand = connectorUpgradeCommand;
991
1076
  exports.deriveDelegateAccountAddress = deriveDelegateAccountAddress;
992
1077
  exports.isConnectorChannel = isConnectorChannel;
993
1078
  exports.isPackedUserOperationTypedData = isPackedUserOperationTypedData;
@@ -996,5 +1081,5 @@ exports.packedUserOperationHash = packedUserOperationHash;
996
1081
  exports.resolveConnectorChannel = resolveConnectorChannel;
997
1082
  exports.signerUpdateFallback = signerUpdateFallback;
998
1083
  exports.verifySettlementChild = verifySettlementChild;
999
- //# sourceMappingURL=chunk-S42QSWJY.cjs.map
1000
- //# sourceMappingURL=chunk-S42QSWJY.cjs.map
1084
+ //# sourceMappingURL=chunk-3SVPI4LS.cjs.map
1085
+ //# sourceMappingURL=chunk-3SVPI4LS.cjs.map