@haven_ai/sdk 0.3.0-alpha.0 → 0.4.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.cjs +298 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +362 -16
- package/dist/index.d.ts +362 -16
- package/dist/index.js +287 -36
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -409,6 +409,8 @@ interface X402Quote {
|
|
|
409
409
|
request: X402RequestSnapshot;
|
|
410
410
|
mcpTransport?: X402McpTransport;
|
|
411
411
|
resourceUrl: string;
|
|
412
|
+
/** #3097: `resourceUrl` (the merchant's declaration) is not `request.url` (what was quoted). */
|
|
413
|
+
resourceUrlDiffersFromRequest: boolean;
|
|
412
414
|
description: string | null;
|
|
413
415
|
mimeType: string | null;
|
|
414
416
|
amountAtomic: string;
|
|
@@ -493,6 +495,14 @@ interface HavenAllowance {
|
|
|
493
495
|
tokenSymbol: string;
|
|
494
496
|
configuredAmount: string;
|
|
495
497
|
resetPeriodMin: number;
|
|
498
|
+
/**
|
|
499
|
+
* #3128: human-readable `onchain.remaining`, e.g. "4.96 USDC" — the SAME
|
|
500
|
+
* string {@link HavenAgentAllowanceSummary.remainingDisplay} carries for
|
|
501
|
+
* this allowance, computed by one function from `onchain.remaining` and
|
|
502
|
+
* the token's decimals, so the two reads cannot disagree. Additive; the
|
|
503
|
+
* wire carries no display form (it is derived client-side).
|
|
504
|
+
*/
|
|
505
|
+
remainingDisplay: string;
|
|
496
506
|
onchain: {
|
|
497
507
|
amount: string;
|
|
498
508
|
spent: string;
|
|
@@ -548,6 +558,63 @@ interface PostPurchaseAllowanceSummary {
|
|
|
548
558
|
reset_period?: number;
|
|
549
559
|
source: 'allowance_module' | 'active_delegations';
|
|
550
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* #3126 — the answer to "is there money actually HELD behind my budget?",
|
|
563
|
+
* asked as a sufficiency signal rather than a balance.
|
|
564
|
+
*
|
|
565
|
+
* Every other agent-readable figure in this package describes SPEND
|
|
566
|
+
* AUTHORITY — what the agent is PERMITTED to move this period
|
|
567
|
+
* ({@link HavenAllowanceSummary}). This shape answers the different question
|
|
568
|
+
* of whether the account HOLDS funds behind that authority, and deliberately
|
|
569
|
+
* answers it as `covered: boolean | null`, never as a figure: a constrained
|
|
570
|
+
* actor has no business reading the treasury total, and the boolean answers
|
|
571
|
+
* the only decision an agent has (attempt the payment, or tell the user
|
|
572
|
+
* funds are missing).
|
|
573
|
+
*
|
|
574
|
+
* The naming keeps the two concepts apart (the #3126 binding constraint):
|
|
575
|
+
* `budgetRemainingAtomic` is AUTHORITY — the same value
|
|
576
|
+
* {@link HavenAllowanceSummary} reports per token as `onchain.remaining` —
|
|
577
|
+
* while `covered` speaks only of HELD funds. Nothing here is named like the
|
|
578
|
+
* authority fields (`remaining`, `available`); nothing here returns a
|
|
579
|
+
* balance.
|
|
580
|
+
*
|
|
581
|
+
* `covered: null` means the chain read FAILED — unverifiable, never a
|
|
582
|
+
* guess. The same honesty rule `x402-funding-leg.ts`'s `delegateCanFund`
|
|
583
|
+
* established (#1521): treat null as "we do not know", not as "funded" or
|
|
584
|
+
* as absence; `coverageError` carries why.
|
|
585
|
+
*/
|
|
586
|
+
interface HavenBalanceCoverage {
|
|
587
|
+
/**
|
|
588
|
+
* true: the chain reports the agent's account holds at least
|
|
589
|
+
* `checkedAmountAtomic` of the token. false: the chain read succeeded and
|
|
590
|
+
* reports LESS — tell the user funds are missing rather than retrying.
|
|
591
|
+
* null: the chain read failed — unverifiable, never treated as absence.
|
|
592
|
+
*/
|
|
593
|
+
covered: boolean | null;
|
|
594
|
+
/** Present only when `covered` is null: why the chain read could not answer. */
|
|
595
|
+
coverageError?: string;
|
|
596
|
+
chainId: number;
|
|
597
|
+
tokenAddress: string;
|
|
598
|
+
tokenSymbol: string;
|
|
599
|
+
/** The amount the coverage question was asked about, in atomic units. */
|
|
600
|
+
checkedAmountAtomic: string;
|
|
601
|
+
/**
|
|
602
|
+
* Context, AUTHORITY not holdings: the agent's remaining spend authority
|
|
603
|
+
* for the requested token, in atomic units — the same derivation
|
|
604
|
+
* {@link HavenAllowanceSummary} reports (`onchain.remaining`; the #1090
|
|
605
|
+
* derivation, the #1145 enforcer read). Zero when no active budget row
|
|
606
|
+
* names the token. Compare it with `covered`, never instead of it.
|
|
607
|
+
*/
|
|
608
|
+
budgetRemainingAtomic: string;
|
|
609
|
+
/**
|
|
610
|
+
* Provenance of `budgetRemainingAtomic` (#1319, same semantics as
|
|
611
|
+
* {@link HavenAllowance.onchain.remainingIsFromChain}): true when the
|
|
612
|
+
* budget figure came from a live enforcer read, false when it fell back
|
|
613
|
+
* to the configured budget. Absent when no budget row existed for the
|
|
614
|
+
* token (nothing was read).
|
|
615
|
+
*/
|
|
616
|
+
budgetRemainingIsFromChain?: boolean;
|
|
617
|
+
}
|
|
551
618
|
/**
|
|
552
619
|
* Affirmative spend-readiness for the authenticated agent, derived from the raw
|
|
553
620
|
* agent status plus the remaining spend authority the backend reports per rail
|
|
@@ -572,9 +639,24 @@ interface PostPurchaseAllowanceSummary {
|
|
|
572
639
|
* funding surfaces at pay time as INSUFFICIENT_FUNDS.
|
|
573
640
|
*/
|
|
574
641
|
type HavenAgentReadiness = 'ready' | 'needs_approval' | 'revoked';
|
|
575
|
-
/**
|
|
642
|
+
/**
|
|
643
|
+
* Compact, agent-facing per-token spend authority for the bootstrap summary.
|
|
644
|
+
*
|
|
645
|
+
* #3128: a deliberately DIFFERENT view of the same allowance as
|
|
646
|
+
* {@link HavenAllowance} — flat, no `onchain` block, no spent/nonce/reset-time
|
|
647
|
+
* detail — but never a disjoint one: every field here is present on or
|
|
648
|
+
* derived from the {@link HavenAllowance} with the same `id`, and
|
|
649
|
+
* `remainingAtomic` / `remainingDisplay` equal that allowance's
|
|
650
|
+
* `onchain.remaining` / `remainingDisplay` byte for byte (pinned by test). A
|
|
651
|
+
* client that wants the id AND a display amount can therefore use either
|
|
652
|
+
* read alone.
|
|
653
|
+
*/
|
|
576
654
|
interface HavenAgentAllowanceSummary {
|
|
655
|
+
/** #3128: the {@link HavenAllowance.id} this row summarises. */
|
|
656
|
+
id: string;
|
|
577
657
|
tokenSymbol: string;
|
|
658
|
+
/** #3128: the {@link HavenAllowance.tokenAddress}. */
|
|
659
|
+
tokenAddress: string;
|
|
578
660
|
/** Live on-chain remaining allowance in atomic units. */
|
|
579
661
|
remainingAtomic: string;
|
|
580
662
|
/** Human-readable remaining, e.g. "4.96 USDC". */
|
|
@@ -667,6 +749,25 @@ interface HavenPaymentReceipt {
|
|
|
667
749
|
selectedPayment?: Record<string, unknown> | null;
|
|
668
750
|
paymentProofHeaderName: string | null;
|
|
669
751
|
protocolReceiptHeaderName: string | null;
|
|
752
|
+
/**
|
|
753
|
+
* #3125 — the merchant's `PAYMENT-RESPONSE` object relayed VERBATIM:
|
|
754
|
+
* opaque, unvalidated, unverified, MERCHANT-CONTROLLED third-party data.
|
|
755
|
+
* Haven neither authors nor verifies anything inside it, including
|
|
756
|
+
* `protocolReceiptPayload.payer` —
|
|
757
|
+
* that `payer` is the merchant's claim, NOT Haven's record, and is not
|
|
758
|
+
* {@link payerAddress} (Haven's own, authoritative; field observation
|
|
759
|
+
* 2026-09-18: the two held different addresses on every row read). For who
|
|
760
|
+
* paid, read `parties` ({@link PaymentParties}) — `treasuryAccount`,
|
|
761
|
+
* `delegate`, `delegateAccount`, `merchant` are Haven-derived and
|
|
762
|
+
* authoritative; anything inside this object is not.
|
|
763
|
+
*
|
|
764
|
+
* Deliberately NOT namespaced or key-prefixed on the wire (#3125): the
|
|
765
|
+
* relay must stay the merchant's object verbatim (its `transaction` key
|
|
766
|
+
* feeds `settlementTxHash`), and prefixing the envelope could not prefix
|
|
767
|
+
* the merchant-controlled keys inside it — the `payer` collision lives
|
|
768
|
+
* there, so provenance is made legible at the read surfaces instead (this
|
|
769
|
+
* comment and the tool descriptions).
|
|
770
|
+
*/
|
|
670
771
|
protocolReceiptPayload?: Record<string, unknown> | null;
|
|
671
772
|
merchantStatus: number | null;
|
|
672
773
|
confirmedAt: string | null;
|
|
@@ -1065,6 +1166,12 @@ interface AgentNextStep {
|
|
|
1065
1166
|
next_tool_server_role?: 'hosted' | 'signer';
|
|
1066
1167
|
/** Small literal arguments for next_tool. Bulky fields are referenced by reason. */
|
|
1067
1168
|
next_arguments?: Record<string, unknown>;
|
|
1169
|
+
/**
|
|
1170
|
+
* #3101 (epic #3105, decision 3): present exactly when `next_tool` is
|
|
1171
|
+
* absent — why no tool is named (the payment id is unknown, nothing is left
|
|
1172
|
+
* to do, the arguments could not be built). `next_tool` is never null.
|
|
1173
|
+
*/
|
|
1174
|
+
next_tool_omitted_reason?: string;
|
|
1068
1175
|
/** False when the agent should stop and involve the user before continuing. */
|
|
1069
1176
|
safe_to_continue: boolean;
|
|
1070
1177
|
reason: string;
|
|
@@ -1227,6 +1334,37 @@ interface HavenCatalogEntry {
|
|
|
1227
1334
|
* 'verified' })` filters on this field, not on `source`.
|
|
1228
1335
|
*/
|
|
1229
1336
|
verifiedPayable: boolean;
|
|
1337
|
+
/**
|
|
1338
|
+
* The merchant this entry belongs to (#3078). OPTIONAL on purpose: an
|
|
1339
|
+
* installed SDK may face a backend that predates the merchant layer, and
|
|
1340
|
+
* `discoverTools` must keep working against it — the field is absent, not
|
|
1341
|
+
* null, in that case.
|
|
1342
|
+
*/
|
|
1343
|
+
merchant?: HavenCatalogMerchant;
|
|
1344
|
+
}
|
|
1345
|
+
/** A catalog entry's merchant as the wire carries it (#3078). */
|
|
1346
|
+
interface HavenCatalogMerchant {
|
|
1347
|
+
id: string;
|
|
1348
|
+
slug: string;
|
|
1349
|
+
name: string;
|
|
1350
|
+
/** `coming_soon` never reaches an entry in practice (a prospect has no offers). */
|
|
1351
|
+
listingStatus: 'live' | 'coming_soon';
|
|
1352
|
+
/** Haven-run test content: the demo store and the stranded-funds fixture. */
|
|
1353
|
+
isTestMerchant: boolean;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* #3128: one page of receipts. `total` is the count Haven holds for the
|
|
1357
|
+
* agent (an empty page with `total: 0` means no receipt exists — there is no
|
|
1358
|
+
* indexing delay behind this list); `hasMore` says the page was cut at the
|
|
1359
|
+
* limit; `nextCursor` is fed back as `cursor` for the next page. Against a
|
|
1360
|
+
* backend older than #3128 the three are `null` — "unknown", never a
|
|
1361
|
+
* fabricated 0 / false.
|
|
1362
|
+
*/
|
|
1363
|
+
interface HavenPaymentReceiptsPage {
|
|
1364
|
+
receipts: HavenPaymentReceipt[];
|
|
1365
|
+
total: number | null;
|
|
1366
|
+
hasMore: boolean | null;
|
|
1367
|
+
nextCursor: string | null;
|
|
1230
1368
|
}
|
|
1231
1369
|
/** @internal */
|
|
1232
1370
|
/** Wire shape of POST /catalog/submit (#1717, #1716). */
|
|
@@ -1870,6 +2008,52 @@ declare class HavenClient {
|
|
|
1870
2008
|
* Get configured and on-chain allowances for the authenticated agent.
|
|
1871
2009
|
*/
|
|
1872
2010
|
getAllowances(): Promise<HavenAllowanceSummary>;
|
|
2011
|
+
/**
|
|
2012
|
+
* #3126 — is the checked amount of the token actually HELD on the
|
|
2013
|
+
* agent's own account?
|
|
2014
|
+
*
|
|
2015
|
+
* This is the companion to {@link getAllowances}, not a variant of it:
|
|
2016
|
+
* allowances answer what the agent is PERMITTED to spend this period;
|
|
2017
|
+
* this answers whether the account HOLDS funds behind that permission,
|
|
2018
|
+
* as a sufficiency signal — `covered: true | false | null` — never as a
|
|
2019
|
+
* balance. `covered: null` means the chain read failed: treat it as
|
|
2020
|
+
* unverifiable, not as absence (`coverageError` says why). The account's
|
|
2021
|
+
* balance itself is deliberately not returned.
|
|
2022
|
+
*/
|
|
2023
|
+
checkFunds(input: {
|
|
2024
|
+
token: string;
|
|
2025
|
+
amountAtomic: string;
|
|
2026
|
+
}): Promise<HavenBalanceCoverage>;
|
|
2027
|
+
/**
|
|
2028
|
+
* `POST /machine-payments/budget-precheck` (#3054): ask Haven to decide —
|
|
2029
|
+
* server-side — whether `amountAtomic` of `token` fits the agent's
|
|
2030
|
+
* remaining delegation budget, the same compare the guided prepare used to
|
|
2031
|
+
* run locally over its allowances read.
|
|
2032
|
+
*
|
|
2033
|
+
* On insufficiency Haven refuses (403, `delegation_budget_exceeded`) and
|
|
2034
|
+
* the refusal reaches the `payment_refusals` ledger with
|
|
2035
|
+
* `source: 'hosted_prepare'` — the point of the endpoint. This method
|
|
2036
|
+
* surfaces that decision as a thrown {@link HavenApiError}; it does NOT
|
|
2037
|
+
* swallow it, because swallowing would turn a decided refusal into the
|
|
2038
|
+
* degrade-to-warning path and the ledger row would still land while the
|
|
2039
|
+
* purchase proceeded.
|
|
2040
|
+
*
|
|
2041
|
+
* camelCase body like the route family; the response mirrors the wire
|
|
2042
|
+
* (`sufficient`, `remaining_atomic`). `resourceUrl` is the merchant
|
|
2043
|
+
* resource being bought — the ledger dedupe window's discriminating
|
|
2044
|
+
* column — never this request's own URL.
|
|
2045
|
+
*/
|
|
2046
|
+
precheckBudget(input: {
|
|
2047
|
+
chainId?: number;
|
|
2048
|
+
token: string;
|
|
2049
|
+
amountAtomic: string;
|
|
2050
|
+
merchantTo?: string;
|
|
2051
|
+
resourceUrl?: string;
|
|
2052
|
+
}): Promise<{
|
|
2053
|
+
sufficient: boolean;
|
|
2054
|
+
remaining_atomic: string;
|
|
2055
|
+
remaining_is_from_chain?: boolean;
|
|
2056
|
+
}>;
|
|
1873
2057
|
/**
|
|
1874
2058
|
* Post-purchase allowance/budget summary for a settled payment (#1310).
|
|
1875
2059
|
*
|
|
@@ -1996,6 +2180,11 @@ declare class HavenClient {
|
|
|
1996
2180
|
listReceipts(options?: {
|
|
1997
2181
|
limit?: number;
|
|
1998
2182
|
}): Promise<HavenPaymentReceipt[]>;
|
|
2183
|
+
/** #3128: one page of receipts with `total`, `hasMore` and `nextCursor`. */
|
|
2184
|
+
listReceiptsPage(options?: {
|
|
2185
|
+
limit?: number;
|
|
2186
|
+
cursor?: string;
|
|
2187
|
+
}): Promise<HavenPaymentReceiptsPage>;
|
|
1999
2188
|
/**
|
|
2000
2189
|
* Fetch the verifiable receipt bundle for a settled payment and verify it
|
|
2001
2190
|
* locally. The server's own verification is ignored — the receipt is verified
|
|
@@ -2424,21 +2613,27 @@ declare const toolDescriptions: {
|
|
|
2424
2613
|
readonly nextActionGuidance: "";
|
|
2425
2614
|
};
|
|
2426
2615
|
readonly getAgent: {
|
|
2427
|
-
readonly summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status, spend_authority_readiness,
|
|
2428
|
-
readonly selectionGuidance: "Use this as the
|
|
2429
|
-
readonly behavior: "Reads identity plus the live spend-authority snapshot
|
|
2616
|
+
readonly summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status, spend_authority_readiness, per-token remaining allowance (atomic + human-readable). The recommended first call in a new session.";
|
|
2617
|
+
readonly selectionGuidance: "Use this as the session bootstrap, or to confirm identity together with whether the agent can spend right now. For per-token detail (configured vs spent vs reset window) use haven_get_allowances.";
|
|
2618
|
+
readonly behavior: "Reads identity plus the live spend-authority snapshot — the active on-chain budget delegation. spend_authority_readiness (readiness is a deprecated alias, same value) is \"ready\" when at least one token has remaining spend authority, \"needs_approval\" when the agent is active but has none, and \"revoked\" when the credential is not active. It covers hosted identity + on-chain spend authority ONLY — 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 — ask the owner to grant or raise the budget in Haven. allowances[] carries id, tokenAddress, remainingAtomic, remainingDisplay per token. Identity fields: id, name, status, accountAddress, delegateAddress, chainId.";
|
|
2430
2619
|
readonly nextActionGuidance: "";
|
|
2431
2620
|
};
|
|
2432
2621
|
readonly getAllowances: {
|
|
2433
2622
|
readonly summary: "Return configured and on-chain allowance state for the authenticated agent. On-chain allowance is the real spend gate.";
|
|
2434
|
-
readonly selectionGuidance: "Use this when the user asks about allowance, budget, spend limit, remaining amount, remaining allowance, remaining budget, daily limit, reset period, what can I spend, or what the agent can still spend.";
|
|
2435
|
-
readonly behavior: "Returns the per-token spend authority for the account: the active budget delegation (remaining = the period budget, which re-arms natively at the period boundary). An over-budget payment is declined before any money moves; nothing queues. Configured amounts from Haven are returned alongside.";
|
|
2623
|
+
readonly selectionGuidance: "Use this when the user asks about allowance, budget, spend limit, remaining amount, remaining allowance, remaining budget, daily limit, reset period, what can I spend, or what the agent can still spend. For whether the account actually HOLDS funds behind the budget use haven_check_funds.";
|
|
2624
|
+
readonly behavior: "Returns the per-token spend authority for the account: the active budget delegation (remaining = the period budget, which re-arms natively at the period boundary), each with id, onchain.remaining, remainingDisplay. An over-budget payment is declined before any money moves; nothing queues. Configured amounts from Haven are returned alongside.";
|
|
2436
2625
|
readonly nextActionGuidance: "";
|
|
2437
2626
|
};
|
|
2627
|
+
readonly checkFunds: {
|
|
2628
|
+
readonly summary: "Check whether the agent's account actually holds at least the given amount of a token — funds held, not spend permitted.";
|
|
2629
|
+
readonly selectionGuidance: "Use this before attempting a payment when it matters whether the money is really there: allowance answers say what you are PERMITTED to spend, never whether the account HOLDS it. For allowance, budget, spend-limit, remaining-budget, reset-period, or what-can-I-spend questions use the allowance lookup tool instead.";
|
|
2630
|
+
readonly behavior: "Returns covered: true (the account holds at least the checked amount), false (a live chain read reports less — the budget is backed by an empty account; stop and tell the user funds are missing), or null (the chain read failed — unverifiable, never treat it as absence; coverageError says why). The account balance itself is deliberately not returned: this is a sufficiency signal, not a balance read. budget_remaining_atomic is the permitted figure from the allowance lookup (the SDK spells it budgetRemainingAtomic), named so it can never be confused with holdings.";
|
|
2631
|
+
readonly nextActionGuidance: "On covered=false, do not attempt the payment — tell the user the account is short and let them fund it; on covered=null, retry the check shortly or proceed knowing the payment may fail on-chain.";
|
|
2632
|
+
};
|
|
2438
2633
|
readonly listReceipts: {
|
|
2439
|
-
readonly summary: "List
|
|
2440
|
-
readonly selectionGuidance: "
|
|
2441
|
-
readonly behavior: "
|
|
2634
|
+
readonly summary: "List machine-payment receipts, newest first, by page.";
|
|
2635
|
+
readonly selectionGuidance: "For transaction history or payment evidence; use the allowance tool instead for remaining allowance or what-can-I-spend questions.";
|
|
2636
|
+
readonly behavior: "Page: { receipts, total, hasMore, nextCursor }; total 0 = none exist (no indexing delay); hasMore = cut at limit, send nextCursor as cursor. parties.treasuryAccount is Haven's authoritative payer. protocolReceiptPayload is the merchant's PAYMENT-RESPONSE, relayed verbatim: merchant-controlled, unverified, not Haven's record; payer may differ from payerAddress. Proof header values are omitted.";
|
|
2442
2637
|
readonly nextActionGuidance: "";
|
|
2443
2638
|
};
|
|
2444
2639
|
readonly verifyReceipt: {
|
|
@@ -2454,10 +2649,10 @@ declare const toolDescriptions: {
|
|
|
2454
2649
|
readonly nextActionGuidance: string;
|
|
2455
2650
|
};
|
|
2456
2651
|
readonly discoverTools: {
|
|
2457
|
-
readonly summary: "Step 1 of a purchase: discover payable services from Haven's curated merchant catalog — names, prices,
|
|
2652
|
+
readonly summary: "Step 1 of a purchase: discover payable services from Haven's curated merchant catalog — names, prices, the next call.";
|
|
2458
2653
|
readonly selectionGuidance: string;
|
|
2459
2654
|
readonly behavior: string;
|
|
2460
|
-
readonly nextActionGuidance: "
|
|
2655
|
+
readonly nextActionGuidance: "Call suggested_tool with suggested_arguments VERBATIM (no hint: read suggested_tool_omitted_reason). Confirm the price from the live quote or pay result, not the catalog; if the next tool takes a cap, pass the user's cap as max_amount_human in whole tokens (\"no more than 1 USDC\" → max_amount_human: \"1\"), never atomic units by hand.";
|
|
2461
2656
|
};
|
|
2462
2657
|
readonly submitCatalogEntry: {
|
|
2463
2658
|
readonly summary: "Submit a merchant's payable (x402/MCP) endpoint to Haven's Verified Payable Directory for verification and listing.";
|
|
@@ -2527,7 +2722,7 @@ type SharedToolKey = keyof typeof toolDescriptions;
|
|
|
2527
2722
|
* live sibling constant not pulled in here; if it ever is, this applies to it
|
|
2528
2723
|
* too (design review, #2537).
|
|
2529
2724
|
*/
|
|
2530
|
-
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";
|
|
2725
|
+
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` + `next_tool_server_role`\n\u2014 the bare tool name on that logical server, whatever your runtime calls it).\nWhen no tool follows, `next_tool` is absent and `next_tool_omitted_reason`\nsays why; that is a complete answer.\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- `mcp__haven__haven_check_funds` \u2014 whether the account actually HOLDS at\n least a given amount of a token. Allowance answers above say what you are\n permitted to spend; this one says whether the money is really there,\n answered as `covered` true/false/null \u2014 never as a balance. On\n `covered: false`, stop and tell the user the account is short; on\n `covered: null` (the chain read failed), treat it as unverifiable rather\n than as absence.\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. A failure carries the same\n`next_action` / `next_tool` / `next_arguments` / `next_tool_omitted_reason`\nfields a success does; follow them first, then branch on `code` and surface\n`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";
|
|
2531
2726
|
/** Directory name for the installed skill folder. */
|
|
2532
2727
|
declare const SKILL_FOLDER_NAME = "haven-pay";
|
|
2533
2728
|
/**
|
|
@@ -2740,6 +2935,104 @@ declare const HAVEN_AGENT_RUNBOOK_MD = "# Haven for agents \u2014 set your user
|
|
|
2740
2935
|
*/
|
|
2741
2936
|
declare const AGENT_ONBOARDING_PROMPT = "I have a Haven account and I am signed in at {{HAVEN_ORIGIN}}. Please set up Haven so you can pay for things within a budget I approve.\n\nStart by reading {{HAVEN_ORIGIN}}/for-agents.md \u2014 it is written for you and explains which steps are mine.\n\nThen:\n\n1. Run `npx @haven_ai/cli@<channel> login`. The `<channel>` in that command is the tag your deployment names \u2014 read it from `/.well-known/haven.json` (`packages.cli.channel`), never a tag you pick. It prints a link and a code and does not need my password \u2014 it must never ask for it. Give me the link straight away and wait for me to approve it in my browser.\n2. Once I have approved, run `haven agents connect --name <a name you choose> --budget <amount> --token USDC --period <minutes>` with the budget I tell you. If I have not given you one, ask me before running it. Add `--run` to complete the connection in the same step.\n3. 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.\n4. Once I have approved the budget, verify with the `haven_get_agent` tool: `ready` means you can pay, `needs_approval` means my approval has not landed yet.\n\nTwo things only I can do: approving that budget with my passkey, and funding the account with USDC on Base \u2014 no ETH, Haven sponsors the gas. Tell me if either is missing rather than working around it.\n\nDo not print private keys, API keys, credential file contents, or config secrets in chat or logs.";
|
|
2742
2937
|
|
|
2938
|
+
/**
|
|
2939
|
+
* #3101 (epic #3105, slice 2/5): the typed next-step builder.
|
|
2940
|
+
*
|
|
2941
|
+
* Every hosted payment tool ends by naming the agent's next tool and its
|
|
2942
|
+
* arguments (#1308). Until this module, the tool was a free string and the
|
|
2943
|
+
* arguments a `Record<string, unknown>`, so nothing tied the keys to the tool
|
|
2944
|
+
* named beside them — three sites handed `{ payment_id: null }` to a tool
|
|
2945
|
+
* whose `payment_id` is a required string, and the compiler could not see it.
|
|
2946
|
+
*
|
|
2947
|
+
* The builder is generic over a TARGET MAP the caller supplies: bare tool
|
|
2948
|
+
* name → { role, validate }. It is deliberately schema-library-agnostic (the
|
|
2949
|
+
* SDK carries no zod): the hosted server derives each target's argument type
|
|
2950
|
+
* from its own zod shape and passes a `validate` closure; this module only
|
|
2951
|
+
* needs to know the role (to render `mcp__<server>__<tool>`) and how to say
|
|
2952
|
+
* whether arguments parse. Keyed on the bare name + role (decision 1) so the
|
|
2953
|
+
* namespaced string is rendered in exactly one place and the runtime-neutral
|
|
2954
|
+
* `next_tool_server` / `next_tool_name` / `next_tool_server_role` fields are
|
|
2955
|
+
* derived from the same input rather than parsed back out of a literal.
|
|
2956
|
+
*
|
|
2957
|
+
* Decisions 3 and 8: `nextTool` is REQUIRED on the input and may be `null` —
|
|
2958
|
+
* a site that forgets it is a compile error; a site with no next tool says
|
|
2959
|
+
* why, and the wire omits `next_tool` and carries `next_tool_omitted_reason`.
|
|
2960
|
+
* `next_tool` is never null on the wire.
|
|
2961
|
+
*/
|
|
2962
|
+
type NextToolServerRole = 'hosted' | 'signer';
|
|
2963
|
+
/** The DEFAULT server name each role is wired under (#1588, #2550). */
|
|
2964
|
+
declare const NEXT_TOOL_SERVER_NAMES: Record<NextToolServerRole, string>;
|
|
2965
|
+
/** Default server name → role. An unknown server yields no role rather than a guess (#2550). */
|
|
2966
|
+
declare const NEXT_TOOL_SERVER_ROLES: Record<string, NextToolServerRole>;
|
|
2967
|
+
/** Renders the Claude-family namespaced tool name — the one string clients have followed since #1308. */
|
|
2968
|
+
declare function renderNextTool(role: NextToolServerRole, name: string): string;
|
|
2969
|
+
/** Parses a namespaced literal back into its parts; `role` is absent for an unknown server. */
|
|
2970
|
+
declare function parseNextTool(literal: string): {
|
|
2971
|
+
server: string;
|
|
2972
|
+
name: string;
|
|
2973
|
+
role?: NextToolServerRole;
|
|
2974
|
+
} | null;
|
|
2975
|
+
/**
|
|
2976
|
+
* One target the builder may hand off to. `TArgs` is the argument type the
|
|
2977
|
+
* caller derived from the tool's declared schema; `validate` is the runtime
|
|
2978
|
+
* twin of that type and returns `null` when the arguments parse, else why not.
|
|
2979
|
+
*/
|
|
2980
|
+
interface NextStepTarget<TArgs> {
|
|
2981
|
+
role: NextToolServerRole;
|
|
2982
|
+
validate: (input: unknown) => string | null;
|
|
2983
|
+
/** Phantom carrier for the argument type; never read at runtime. */
|
|
2984
|
+
readonly _args?: TArgs;
|
|
2985
|
+
}
|
|
2986
|
+
type NextStepTargets = Record<string, NextStepTarget<unknown>>;
|
|
2987
|
+
/** The argument type a target carries. */
|
|
2988
|
+
type NextStepArguments<Targets extends NextStepTargets, T extends keyof Targets> = Targets[T] extends NextStepTarget<infer A> ? A : never;
|
|
2989
|
+
/**
|
|
2990
|
+
* The handoff half of a next step: a registered tool with arguments that
|
|
2991
|
+
* tool accepts, or no tool with the reason. A discriminated union over the
|
|
2992
|
+
* target map's keys, so a wrong key, a missing required key, an unregistered
|
|
2993
|
+
* tool name and an omitted `nextTool` are each a compile error at the site.
|
|
2994
|
+
*/
|
|
2995
|
+
type NextStepHandoff<Targets extends NextStepTargets> = {
|
|
2996
|
+
[T in keyof Targets & string]: {
|
|
2997
|
+
nextTool: T;
|
|
2998
|
+
nextArguments: NextStepArguments<Targets, T>;
|
|
2999
|
+
};
|
|
3000
|
+
}[keyof Targets & string] | {
|
|
3001
|
+
nextTool: null;
|
|
3002
|
+
nextToolOmittedReason: string;
|
|
3003
|
+
};
|
|
3004
|
+
type NextStepInput<Targets extends NextStepTargets> = NextStepHandoff<Targets> & {
|
|
3005
|
+
nextAction: AgentPaymentNextAction;
|
|
3006
|
+
safeToContinue: boolean;
|
|
3007
|
+
reason: string;
|
|
3008
|
+
};
|
|
3009
|
+
/** The wire shape: `AgentNextStep` (its `next_tool` family) — never a null `next_tool`. */
|
|
3010
|
+
type NextStep = AgentNextStep;
|
|
3011
|
+
/**
|
|
3012
|
+
* Per-`next_action` default tool (decision 9): the tool a site names unless it
|
|
3013
|
+
* has a reason to override. Only actions with ONE sensible target are listed;
|
|
3014
|
+
* `retry_original_x402_request` is absent because its only live emitter names
|
|
3015
|
+
* no tool on purpose (the agent's own HTTP retry); `sign_and_submit_payment`
|
|
3016
|
+
* is absent because the signer tool
|
|
3017
|
+
* depends on the settlement scheme (`haven_sign` for erc7710 delegations,
|
|
3018
|
+
* `haven_sign_x402` for the EIP-3009 bridge) and a wrong default there would be
|
|
3019
|
+
* worse than none.
|
|
3020
|
+
*/
|
|
3021
|
+
declare const DEFAULT_NEXT_TOOL_BY_ACTION: {
|
|
3022
|
+
readonly check_status_later: "haven_get_payment_status";
|
|
3023
|
+
readonly sweep_stranded_funds: "haven_sweep_delegate";
|
|
3024
|
+
};
|
|
3025
|
+
declare function defaultNextToolFor(action: AgentPaymentNextAction): string | undefined;
|
|
3026
|
+
/**
|
|
3027
|
+
* Builds a `nextStep` function bound to a target map. The returned function
|
|
3028
|
+
* renders the wire fields from the bare name + role, and re-validates the
|
|
3029
|
+
* arguments at runtime: on a mismatch it FAILS SAFE — omits the tool and says
|
|
3030
|
+
* why in `next_tool_omitted_reason` — rather than throwing out of a handler
|
|
3031
|
+
* that has already moved money. The compile-time twin makes that branch
|
|
3032
|
+
* unreachable from typed sites; it exists for callers that bypass the types.
|
|
3033
|
+
*/
|
|
3034
|
+
declare function createNextStepBuilder<Targets extends NextStepTargets>(targets: Targets): (input: NextStepInput<Targets>) => NextStep;
|
|
3035
|
+
|
|
2743
3036
|
/**
|
|
2744
3037
|
* The npm dist-tag the published Haven packages tell a user to re-run (#2423,
|
|
2745
3038
|
* slice 3 of epic #2420).
|
|
@@ -2982,9 +3275,10 @@ declare class X402PaymentHeaderValidationError extends Error {
|
|
|
2982
3275
|
* challenge — without a cap, a malicious or sloppy merchant can request a
|
|
2983
3276
|
* year-long window and a leaked signed authorization stays spendable that
|
|
2984
3277
|
* whole time. 600 s is generous for any facilitator settle (typical is
|
|
2985
|
-
* 30–60 s)
|
|
2986
|
-
*
|
|
2987
|
-
*
|
|
3278
|
+
* 30–60 s). This cap applies only to the signed authorization, never to the
|
|
3279
|
+
* advertised requirements echoed in `accepted`. A merchant requiring more
|
|
3280
|
+
* than the bounded lifetime can still reject at verification; preserving its
|
|
3281
|
+
* offer does not widen Haven's signing policy.
|
|
2988
3282
|
*/
|
|
2989
3283
|
declare const X402_MAX_AUTHORIZATION_WINDOW_SECONDS = 600;
|
|
2990
3284
|
/**
|
|
@@ -3227,6 +3521,58 @@ declare function resolveTokenFromAddress(address: string, network?: string): {
|
|
|
3227
3521
|
decimals: number;
|
|
3228
3522
|
} | null;
|
|
3229
3523
|
|
|
3524
|
+
/**
|
|
3525
|
+
* Where the PAID retry goes — and whether it may go there at all (#3097).
|
|
3526
|
+
*
|
|
3527
|
+
* A merchant's 402 challenge declares `resource.url`. Haven records that
|
|
3528
|
+
* declaration as the resource's identity (the binding message, the intent
|
|
3529
|
+
* row, the resume checks all compare against it), but the paid request —
|
|
3530
|
+
* the one carrying `PAYMENT-SIGNATURE` — must go to the URL the CALLER
|
|
3531
|
+
* actually asked for whenever one exists. The declaration is the merchant's
|
|
3532
|
+
* word about itself, not an instruction to the client: the Ampersend
|
|
3533
|
+
* sandbox declares `http://` for a resource it serves over `https` (live,
|
|
3534
|
+
* 2026-09-17; its `http://` answers 308 → https), and a client that adopted
|
|
3535
|
+
* it sent the signed header in clear on the first hop.
|
|
3536
|
+
*
|
|
3537
|
+
* Two rules, both pure, both pinned by tests:
|
|
3538
|
+
*
|
|
3539
|
+
* - `resolveX402RetryTarget`: the caller's request URL wins; the merchant's
|
|
3540
|
+
* `resource.url` is the fallback for callers that only hold the challenge
|
|
3541
|
+
* (the hosted pay-from-quote path). The result says which one it chose and
|
|
3542
|
+
* whether the two disagree, so a quote can surface the disagreement.
|
|
3543
|
+
* - `isSecureX402RetryTarget`: `https` always; `http` only to a target that
|
|
3544
|
+
* cannot leave the machine or the test bench — loopback addresses and the
|
|
3545
|
+
* RFC 2606/6761 reserved names (`.test`, `.localhost`, `.invalid`,
|
|
3546
|
+
* `.example`), which every fixture in this repo uses. A public `http://`
|
|
3547
|
+
* target is refused BEFORE a signed header is handed to a transport.
|
|
3548
|
+
*/
|
|
3549
|
+
interface X402RetryTarget {
|
|
3550
|
+
/** The URL the paid request goes to. */
|
|
3551
|
+
url: string;
|
|
3552
|
+
/** Which input produced it. */
|
|
3553
|
+
source: 'request' | 'resource';
|
|
3554
|
+
/**
|
|
3555
|
+
* True when the merchant's declared `resource.url` is not the caller's URL.
|
|
3556
|
+
* Absent (undefined) when nothing was compared — the caller named no URL
|
|
3557
|
+
* and the declaration was adopted as-is — so a consumer never reads
|
|
3558
|
+
* "false" as "the merchant agrees with what you quoted".
|
|
3559
|
+
*/
|
|
3560
|
+
resourceUrlDiffersFromRequest?: boolean;
|
|
3561
|
+
}
|
|
3562
|
+
declare function resolveX402RetryTarget(input: {
|
|
3563
|
+
requestUrl?: string | null;
|
|
3564
|
+
resourceUrl: string;
|
|
3565
|
+
}): X402RetryTarget;
|
|
3566
|
+
/** True when a retry carrying a payment header may be sent to `url`. */
|
|
3567
|
+
declare function isSecureX402RetryTarget(url: string): boolean;
|
|
3568
|
+
declare const INSECURE_RETRY_TARGET_CODE = "INSECURE_RETRY_TARGET";
|
|
3569
|
+
/** Refused before any signed header leaves: the paid retry would travel in clear. */
|
|
3570
|
+
declare class HavenInsecureRetryTargetError extends HavenError {
|
|
3571
|
+
readonly url: string;
|
|
3572
|
+
constructor(url: string);
|
|
3573
|
+
}
|
|
3574
|
+
declare function assertSecureX402RetryTarget(url: string): void;
|
|
3575
|
+
|
|
3230
3576
|
/**
|
|
3231
3577
|
* Runtime-agnostic base64 helpers — the single source of truth for the wire
|
|
3232
3578
|
* encoding shared by the SDK and the edge signer (#325).
|
|
@@ -3293,4 +3639,4 @@ declare function discoverMerchantMcpUrl(inputUrl: string): Promise<string | null
|
|
|
3293
3639
|
/** Trailing-slash/percent-case echoes compare equal; unparseable never does. */
|
|
3294
3640
|
declare function sameUrl(a: string, b: string): boolean;
|
|
3295
3641
|
|
|
3296
|
-
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, 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, addressFromKey, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, compareNodeVersions, composeDescription, connectorRerunCommand, connectorSpec, decodeBase64Json, decodeBase64Utf8, discoverMerchantMcpUrl, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, havenTools, isConnectorChannel, isErc7710Option, isSupportedNodeVersion, isSweepableChain, isZeroSettlementTxHash, normalizePaymentRequired, parsePaymentRequired, parsePaymentRequiredResponse, readX402ReceiptPayer, resolveConnectorChannel, resolveTokenFromAddress, sameUrl, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signHash, signUserOpTypedDataForDelegation, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, toolDescriptions, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, verifyPaymentReceipt, verifySignature, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402V2PaymentEnvelope };
|
|
3642
|
+
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, DEFAULT_NEXT_TOOL_BY_ACTION, 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 HavenBalanceCoverage, type HavenCatalogEntry, type HavenCatalogMerchant, type HavenCatalogSubmission, HavenClient, type HavenClientConfig, HavenError, HavenInsecureRetryTargetError, type HavenPaymentReceipt, type HavenPaymentReceiptsPage, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, HavenZeroSettlementHashError, INSECURE_RETRY_TARGET_CODE, MERCHANT_DISCOVERY_PATHS, type MachinePaymentRail, MerchantTimeoutError, NEXT_TOOL_SERVER_NAMES, NEXT_TOOL_SERVER_ROLES, type NextStep, type NextStepArguments, type NextStepHandoff, type NextStepInput, type NextStepTarget, type NextStepTargets, type NextToolServerRole, 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 X402RetryTarget, 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, assertSecureX402RetryTarget, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, compareNodeVersions, composeDescription, connectorRerunCommand, connectorSpec, createNextStepBuilder, decodeBase64Json, decodeBase64Utf8, defaultNextToolFor, discoverMerchantMcpUrl, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, havenTools, isConnectorChannel, isErc7710Option, isSecureX402RetryTarget, isSupportedNodeVersion, isSweepableChain, isZeroSettlementTxHash, normalizePaymentRequired, parseNextTool, parsePaymentRequired, parsePaymentRequiredResponse, readX402ReceiptPayer, renderNextTool, resolveConnectorChannel, resolveTokenFromAddress, resolveX402RetryTarget, sameUrl, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signHash, signUserOpTypedDataForDelegation, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, toolDescriptions, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, verifyPaymentReceipt, verifySignature, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402V2PaymentEnvelope };
|