@haven_ai/sdk 0.1.26-alpha.0 → 0.1.28-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1861 -1690
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -161
- package/dist/index.d.ts +53 -161
- package/dist/index.js +1861 -1690
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -607,7 +607,21 @@ interface HavenAgentAllowanceSummary {
|
|
|
607
607
|
* from a single call at session start. Superset of {@link HavenAgent}.
|
|
608
608
|
*/
|
|
609
609
|
interface HavenAgentSummary extends HavenAgent {
|
|
610
|
+
/**
|
|
611
|
+
* @deprecated Use {@link HavenAgentSummary.spend_authority_readiness} —
|
|
612
|
+
* same value, honest name. This signal covers hosted identity + on-chain
|
|
613
|
+
* spend authority ONLY; it says nothing about the LOCAL signer, which the
|
|
614
|
+
* hosted side cannot see (verify via a signer tool or connect --doctor).
|
|
615
|
+
* Kept as an alias; removal earliest after the next release train (#1590).
|
|
616
|
+
*/
|
|
610
617
|
readiness: HavenAgentReadiness;
|
|
618
|
+
/**
|
|
619
|
+
* Spend-authority readiness: hosted identity + on-chain remaining spend
|
|
620
|
+
* authority. Deliberately named for what it covers — the LOCAL signer's
|
|
621
|
+
* availability is NOT included and must be verified separately (a signer
|
|
622
|
+
* tool call, or `npx @haven_ai/connect@alpha --doctor`).
|
|
623
|
+
*/
|
|
624
|
+
spend_authority_readiness: HavenAgentReadiness;
|
|
611
625
|
allowances: HavenAgentAllowanceSummary[];
|
|
612
626
|
}
|
|
613
627
|
interface HavenPaymentReceipt {
|
|
@@ -1342,32 +1356,31 @@ declare function buildSweepTypedData(auth: SweepAuthorization): SweepTypedData;
|
|
|
1342
1356
|
declare function buildSweepAuthorizationMessage(auth: SweepAuthorization): string;
|
|
1343
1357
|
|
|
1344
1358
|
declare class HavenClient {
|
|
1345
|
-
private readonly apiKey;
|
|
1346
1359
|
private readonly delegateKey;
|
|
1347
|
-
private readonly
|
|
1360
|
+
private readonly havenApi;
|
|
1361
|
+
private readonly accountReads;
|
|
1362
|
+
private readonly delegateSweep;
|
|
1348
1363
|
private readonly x402Wallet;
|
|
1349
|
-
private readonly
|
|
1350
|
-
private readonly merchantTimeout;
|
|
1364
|
+
private readonly merchantTransport;
|
|
1351
1365
|
private readonly confirmationTimeout;
|
|
1352
1366
|
private readonly pollingInterval;
|
|
1353
1367
|
private readonly chainRpcs;
|
|
1354
1368
|
private readonly inFlightX402;
|
|
1355
|
-
private readonly x402ReceiptCache;
|
|
1356
1369
|
/**
|
|
1357
|
-
*
|
|
1358
|
-
*
|
|
1359
|
-
* scoping so concurrent requests don't race on shared mutable state.
|
|
1370
|
+
* The EIP-3009 funding-leg lifecycle (#1618). The facade holds a reference
|
|
1371
|
+
* and delegates; it does not reimplement any of it.
|
|
1360
1372
|
*/
|
|
1361
|
-
private readonly
|
|
1373
|
+
private readonly fundingLeg;
|
|
1362
1374
|
/**
|
|
1363
|
-
*
|
|
1364
|
-
*
|
|
1365
|
-
* overlapping async work — like two MCP tool dispatches in flight at
|
|
1366
|
-
* the same time — see their own headers without stepping on each other.
|
|
1375
|
+
* The erc7710 direct-settlement lifecycle (#1619). Separate from the funding
|
|
1376
|
+
* leg on purpose: this scheme has no funding leg to share.
|
|
1367
1377
|
*/
|
|
1368
|
-
private readonly
|
|
1369
|
-
/**
|
|
1370
|
-
|
|
1378
|
+
private readonly erc7710;
|
|
1379
|
+
/**
|
|
1380
|
+
* Merchant delivery and the evidence trail behind it (#1620). Scheme-neutral
|
|
1381
|
+
* on purpose — both settlement schemes finish through the same door.
|
|
1382
|
+
*/
|
|
1383
|
+
private readonly merchantCompletion;
|
|
1371
1384
|
/** Delegate address derived from the private key (if provided) */
|
|
1372
1385
|
readonly delegateAddress: string | undefined;
|
|
1373
1386
|
constructor(config: HavenClientConfig);
|
|
@@ -1460,8 +1473,6 @@ declare class HavenClient {
|
|
|
1460
1473
|
* Get the agent identity tied to this API key.
|
|
1461
1474
|
*/
|
|
1462
1475
|
getAgent(): Promise<HavenAgent>;
|
|
1463
|
-
private agentInFlight;
|
|
1464
|
-
private fetchAgent;
|
|
1465
1476
|
/**
|
|
1466
1477
|
* One-shot "am I ready?" bootstrap: identity + live spend authority + a
|
|
1467
1478
|
* readiness signal, in a single call. Folds {@link getAgent} and
|
|
@@ -1532,7 +1543,6 @@ declare class HavenClient {
|
|
|
1532
1543
|
getPostPurchaseAllowanceSummary(paymentId: string): Promise<{
|
|
1533
1544
|
allowance: PostPurchaseAllowanceSummary | null;
|
|
1534
1545
|
warnings: AgentPaymentWarning[];
|
|
1535
|
-
/** Same authenticated payment-state read used to resolve the settled token. */
|
|
1536
1546
|
payment: PaymentStatusResult | null;
|
|
1537
1547
|
}>;
|
|
1538
1548
|
/**
|
|
@@ -1633,35 +1643,16 @@ declare class HavenClient {
|
|
|
1633
1643
|
* Pay a previously inspected x402 quote and retry the exact captured request.
|
|
1634
1644
|
*/
|
|
1635
1645
|
payX402Quote(quote: X402Quote, options?: X402AuthorizationOptions): Promise<Response>;
|
|
1636
|
-
private authorizeStandardX402;
|
|
1637
1646
|
/**
|
|
1638
1647
|
* Pay a merchant through **erc7710 direct settlement** (#1454, epic #1450).
|
|
1639
1648
|
*
|
|
1640
|
-
*
|
|
1641
|
-
*
|
|
1642
|
-
*
|
|
1643
|
-
*
|
|
1644
|
-
* method is SMALLER than the 3009 path — the backend assembles the merchant
|
|
1645
|
-
* `X-PAYMENT` header in `assembleSettlementPayload`, so the SDK builds no
|
|
1646
|
-
* header locally.
|
|
1647
|
-
*
|
|
1648
|
-
* authorize (payTo = the MERCHANT) → sign the child → settle → header
|
|
1649
|
-
*
|
|
1650
|
-
* The caller then retries the merchant with that header. **Nothing has
|
|
1651
|
-
* settled when this returns** — that is why it does not return an
|
|
1652
|
-
* `X402Receipt`.
|
|
1649
|
+
* **Nothing has settled when this returns** — that is why it does not return
|
|
1650
|
+
* an `X402Receipt`; the caller still has to retry the merchant with the
|
|
1651
|
+
* header. **MCP callers must pass `options.resourceUrl`**, because an in-band
|
|
1652
|
+
* MCP 402 challenge frequently carries no `resource` object at all.
|
|
1653
1653
|
*
|
|
1654
|
-
*
|
|
1655
|
-
*
|
|
1656
|
-
* request the backend would only reject: an error a client can explain is
|
|
1657
|
-
* worth more than a 400 it has to decode.
|
|
1658
|
-
*
|
|
1659
|
-
* **MCP callers must pass `options.resourceUrl`.** An in-band MCP 402
|
|
1660
|
-
* challenge frequently carries no `resource` object at all, so
|
|
1661
|
-
* `paymentRequired.resource?.url` is undefined and the backend answers
|
|
1662
|
-
* "Valid url is required". The QA scenario this path was ported from falls
|
|
1663
|
-
* back to the request URL for exactly that reason — the SDK cannot, because
|
|
1664
|
-
* it never saw the request. Pass it.
|
|
1654
|
+
* Both caveats, and why this scheme has no funding leg, are explained where
|
|
1655
|
+
* the lifecycle lives: `x402-erc7710.ts` (#1619).
|
|
1665
1656
|
*/
|
|
1666
1657
|
settleX402Erc7710(paymentRequired: X402PaymentRequired, options?: {
|
|
1667
1658
|
resourceUrl?: string;
|
|
@@ -1672,24 +1663,23 @@ declare class HavenClient {
|
|
|
1672
1663
|
*
|
|
1673
1664
|
* Split out because the hosted topology cannot use `settleX402Erc7710()`:
|
|
1674
1665
|
* that method signs in-process with `delegateKey`, and hosted Haven does not
|
|
1675
|
-
* have one and must not.
|
|
1676
|
-
* the LOCAL signer in between, so the key stays where it belongs and the
|
|
1677
|
-
* request shaping stays in one place rather than being reimplemented.
|
|
1666
|
+
* have one and must not.
|
|
1678
1667
|
*/
|
|
1679
1668
|
prepareX402Erc7710(paymentRequired: X402PaymentRequired, options?: {
|
|
1680
1669
|
resourceUrl?: string;
|
|
1681
1670
|
/**
|
|
1682
|
-
* The account's rail, when the caller has ALREADY read it
|
|
1683
|
-
*
|
|
1684
|
-
*
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
* This is an optimisation, not a trust boundary: omit it and the rail is
|
|
1688
|
-
* read here, and either way the backend independently refuses erc7710
|
|
1689
|
-
* from a non-delegation account (`validateGenericSchemeRail`). A caller
|
|
1690
|
-
* that asserted the wrong rail would build a request the backend rejects.
|
|
1671
|
+
* The account's rail, when the caller has ALREADY read it — passing it
|
|
1672
|
+
* skips a duplicate fetch (#1456). An optimisation, not a trust
|
|
1673
|
+
* boundary: the backend independently refuses erc7710 from a
|
|
1674
|
+
* non-delegation account (`validateGenericSchemeRail`).
|
|
1691
1675
|
*/
|
|
1692
1676
|
delegationRail?: boolean;
|
|
1677
|
+
/**
|
|
1678
|
+
* #1547: the merchant MCP-tool call this authorization was quoted
|
|
1679
|
+
* against, persisted so the settle leg can rehydrate it by payment_id
|
|
1680
|
+
* (#1307).
|
|
1681
|
+
*/
|
|
1682
|
+
mcpCallContext?: X402McpCallContext;
|
|
1693
1683
|
}): Promise<{
|
|
1694
1684
|
paymentId: string;
|
|
1695
1685
|
signData: SignData;
|
|
@@ -1699,9 +1689,8 @@ declare class HavenClient {
|
|
|
1699
1689
|
* The SETTLE half (#1456): exchange the signed child for the merchant header.
|
|
1700
1690
|
*
|
|
1701
1691
|
* The SDK builds no header on this path — the backend assembles the MetaMask
|
|
1702
|
-
* erc7710 payload
|
|
1703
|
-
*
|
|
1704
|
-
* hosted boundary) is irrelevant here.
|
|
1692
|
+
* erc7710 payload. Whoever produced the signature (an in-process delegate
|
|
1693
|
+
* key, or the local edge signer over the hosted boundary) is irrelevant.
|
|
1705
1694
|
*/
|
|
1706
1695
|
submitX402Erc7710(paymentId: string, signature: string): Promise<string>;
|
|
1707
1696
|
resumeAuthorizedX402(input: ResumeAuthorizedX402Input): Promise<X402Receipt>;
|
|
@@ -1730,45 +1719,6 @@ declare class HavenClient {
|
|
|
1730
1719
|
* Requires `delegateKey` to be set in the client config.
|
|
1731
1720
|
*/
|
|
1732
1721
|
fetch(url: string, init?: RequestInit, options?: X402AuthorizationOptions): Promise<Response>;
|
|
1733
|
-
/**
|
|
1734
|
-
* Run the MCP `initialize` handshake against a Streamable-HTTP endpoint and
|
|
1735
|
-
* return the `mcp-session-id` the server assigns.
|
|
1736
|
-
*
|
|
1737
|
-
* Returns `undefined` whenever the endpoint is not actually an MCP server —
|
|
1738
|
-
* a transport/HTTP error, a missing session id, or a JSON-RPC error in the
|
|
1739
|
-
* handshake response — so the caller can fall back to plain x402.
|
|
1740
|
-
*/
|
|
1741
|
-
private mcpInitialize;
|
|
1742
|
-
/**
|
|
1743
|
-
* Send the MCP `notifications/initialized` notification that completes the
|
|
1744
|
-
* lifecycle handshake. Best-effort: the session is already established, so a
|
|
1745
|
-
* failed notification must not abort the payment.
|
|
1746
|
-
*/
|
|
1747
|
-
private mcpNotifyInitialized;
|
|
1748
|
-
/** Read a single JSON-RPC message from an MCP response (JSON or SSE body). */
|
|
1749
|
-
private readMcpMessage;
|
|
1750
|
-
/** Add the MCP transport headers (session id + SSE Accept) to a request. */
|
|
1751
|
-
private withMcpHeaders;
|
|
1752
|
-
/**
|
|
1753
|
-
* Collapse an MCP SSE response into a plain JSON response carrying the
|
|
1754
|
-
* JSON-RPC `result`, so callers of `fetch()` never see raw SSE framing.
|
|
1755
|
-
* Non-SSE responses pass through untouched.
|
|
1756
|
-
*/
|
|
1757
|
-
private surfaceMcpResult;
|
|
1758
|
-
private retryX402Request;
|
|
1759
|
-
/**
|
|
1760
|
-
* #956: capture the merchant's OWN receipt when the paid response carries
|
|
1761
|
-
* one, and report it to Haven so the reporting feed can attach it next to
|
|
1762
|
-
* the Haven-generated payment evidence (#498). Two supported signals on the
|
|
1763
|
-
* paid response:
|
|
1764
|
-
*
|
|
1765
|
-
* x-receipt-json: base64-encoded JSON receipt document (inline)
|
|
1766
|
-
* x-receipt-url: https URL to the receipt document (reference)
|
|
1767
|
-
*
|
|
1768
|
-
* Strictly best-effort: absence is the normal case, and no failure here may
|
|
1769
|
-
* ever affect the completed payment — the response is already paid for.
|
|
1770
|
-
*/
|
|
1771
|
-
private reportMerchantReceipt;
|
|
1772
1722
|
/**
|
|
1773
1723
|
* Deliver an already-signed x402 payment header to the merchant and return
|
|
1774
1724
|
* the merchant's response. Used by the hosted MCP server to complete the
|
|
@@ -1792,7 +1742,7 @@ declare class HavenClient {
|
|
|
1792
1742
|
* and before delivering the X-PAYMENT header, so the merchant's
|
|
1793
1743
|
* balanceOf(delegate) / transferWithAuthorization verification sees the funded
|
|
1794
1744
|
* balance — otherwise it rejects with "Payment verification failed". The
|
|
1795
|
-
* SDK's local path already does this (see
|
|
1745
|
+
* SDK's local path already does this (see `X402FundingLeg.authorize`); the hosted
|
|
1796
1746
|
* split flow regressed when the 5→3 collapse removed the incidental
|
|
1797
1747
|
* inter-call latency that used to mask it.
|
|
1798
1748
|
*
|
|
@@ -1841,16 +1791,6 @@ declare class HavenClient {
|
|
|
1841
1791
|
* fallback (re-send the full context explicitly).
|
|
1842
1792
|
*/
|
|
1843
1793
|
getX402MerchantCallContext(paymentId: string): Promise<X402MerchantCallContext>;
|
|
1844
|
-
private resolveX402MerchantCompletionContext;
|
|
1845
|
-
private resolveX402WalletForMerchantCall;
|
|
1846
|
-
private assertCanResumeX402;
|
|
1847
|
-
private mapX402ReceiptFromAuthorization;
|
|
1848
|
-
private mapX402ReceiptFromStatus;
|
|
1849
|
-
private buildX402Receipt;
|
|
1850
|
-
private createStandardX402Header;
|
|
1851
|
-
private cacheX402Receipt;
|
|
1852
|
-
private recordMerchantRetryRejected;
|
|
1853
|
-
private reportMachinePaymentEvidence;
|
|
1854
1794
|
/**
|
|
1855
1795
|
* Wait for a funding tx to be mined with ≥1 confirmation before the
|
|
1856
1796
|
* merchant retry, eliminating the race where the merchant's
|
|
@@ -1860,39 +1800,7 @@ declare class HavenClient {
|
|
|
1860
1800
|
* backend has already confirmed on-chain submission and callers accept the
|
|
1861
1801
|
* small propagation window as a trade-off for not configuring an RPC URL.
|
|
1862
1802
|
*/
|
|
1863
|
-
private waitForFundingTx;
|
|
1864
|
-
/**
|
|
1865
|
-
* Can the delegate EOA still fund an authorization for `amountAtomic`?
|
|
1866
|
-
*
|
|
1867
|
-
* #1521: the only question that separates a legitimate resume (funding
|
|
1868
|
-
* confirmed, merchant never paid — the delegate still holds the money) from
|
|
1869
|
-
* a replayed settled payment (funding confirmed, merchant paid, delegate
|
|
1870
|
-
* spent). The intent's own `status: 'confirmed'` is identical in both.
|
|
1871
|
-
*
|
|
1872
|
-
* The balance is asked of the CHAIN rather than of Haven's bookkeeping on
|
|
1873
|
-
* purpose: the merchant-settlement evidence record is written by this SDK
|
|
1874
|
-
* *after* the merchant call, so a client that dies between the two leaves
|
|
1875
|
-
* the backend believing the merchant was never paid — the exact case the
|
|
1876
|
-
* discriminator has to get right. The chain cannot be behind in that way.
|
|
1877
|
-
*
|
|
1878
|
-
* Returns `null` — never a guess — when `chainRpcs` has no entry for the
|
|
1879
|
-
* chain or the read fails. Callers must treat that as "unverifiable", not
|
|
1880
|
-
* as "funded".
|
|
1881
|
-
*/
|
|
1882
|
-
private delegateCanFund;
|
|
1883
1803
|
private throwIfNonSignableAuthorizationState;
|
|
1884
|
-
private throwPaymentStateError;
|
|
1885
|
-
private paymentStateFromRaw;
|
|
1886
|
-
private x402PayerAddress;
|
|
1887
|
-
private snapshotX402Request;
|
|
1888
|
-
private snapshotRequestBody;
|
|
1889
|
-
private requestInitFromSnapshot;
|
|
1890
|
-
private withX402Wallet;
|
|
1891
|
-
private buildX402Quote;
|
|
1892
|
-
private detectX402McpTransport;
|
|
1893
|
-
private buildX402ResumeState;
|
|
1894
|
-
private attachResumeState;
|
|
1895
|
-
private attachX402ResumeState;
|
|
1896
1804
|
/**
|
|
1897
1805
|
* Execute a tool call by name and input.
|
|
1898
1806
|
*
|
|
@@ -1906,24 +1814,8 @@ declare class HavenClient {
|
|
|
1906
1814
|
* ```
|
|
1907
1815
|
*/
|
|
1908
1816
|
executeTool(toolName: string, input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
1909
|
-
private toolX402PaymentRequired;
|
|
1910
|
-
private x402ToolReceipt;
|
|
1911
|
-
private toolError;
|
|
1912
1817
|
private post;
|
|
1913
1818
|
private get;
|
|
1914
|
-
/**
|
|
1915
|
-
* #1300: every MERCHANT-facing fetch goes through here. Haven API calls
|
|
1916
|
-
* have always been bounded (request() below); the merchant probes/retries
|
|
1917
|
-
* called globalThis.fetch bare, so a slow-loris merchant could hold a tool
|
|
1918
|
-
* call open forever. A caller-supplied signal still applies (combined via
|
|
1919
|
-
* AbortSignal.any); a timeout abort surfaces as a clear HavenApiError 504
|
|
1920
|
-
* naming the URL rather than a bare AbortError.
|
|
1921
|
-
*/
|
|
1922
|
-
private merchantFetch;
|
|
1923
|
-
private request;
|
|
1924
|
-
private mapPaymentResult;
|
|
1925
|
-
private mapPaymentStatusResult;
|
|
1926
|
-
private mapPaymentReceipt;
|
|
1927
1819
|
}
|
|
1928
1820
|
|
|
1929
1821
|
/**
|
|
@@ -2085,9 +1977,9 @@ declare const toolDescriptions: {
|
|
|
2085
1977
|
readonly nextActionGuidance: "";
|
|
2086
1978
|
};
|
|
2087
1979
|
readonly getAgent: {
|
|
2088
|
-
readonly summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status,
|
|
1980
|
+
readonly summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status, spend_authority_readiness, and per-token remaining allowance (atomic + human-readable). The recommended first call in a new session to confirm who you are and whether Haven will let you spend right now.";
|
|
2089
1981
|
readonly selectionGuidance: "Use this as the one-shot orientation/bootstrap at the start of a session, or whenever you need to confirm identity together with whether the agent can spend right now. For a detailed per-token breakdown (configured vs spent vs reset window) use haven_get_allowances.";
|
|
2090
|
-
readonly behavior: "Reads identity plus the live spend-authority snapshot in one shot — the on-chain AllowanceModule on the legacy rail, the active budget delegation on the delegation rail. readiness 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. What an over-budget payment does differs by rail: on the legacy AllowanceModule rail it is queued for the wallet owner to approve in Haven; on the delegation rail there is no approval queue — an over-budget redemption reverts on-chain, so ask the owner to grant or raise the budget in Haven rather than waiting for an approval. allowances[] carries remainingAtomic and remainingDisplay per token. Identity fields (id, name, status, safeAddress, delegateAddress, chainId) are unchanged from before.";
|
|
1982
|
+
readonly behavior: "Reads identity plus the live spend-authority snapshot in one shot — the on-chain AllowanceModule on the legacy rail, the active budget delegation on the delegation rail. spend_authority_readiness (readiness is a deprecated alias, same value) is \"ready\" when at least one token has remaining spend authority, \"needs_approval\" when the agent is active but has none, and \"revoked\" when the credential is not active. It covers hosted identity + on-chain spend authority ONLY — the hosted server cannot see the LOCAL signer, so \"ready\" does not mean the signer can start; verify the signer with a signer tool call or connect --doctor. What an over-budget payment does differs by rail: on the legacy AllowanceModule rail it is queued for the wallet owner to approve in Haven; on the delegation rail there is no approval queue — an over-budget redemption reverts on-chain, so ask the owner to grant or raise the budget in Haven rather than waiting for an approval. allowances[] carries remainingAtomic and remainingDisplay per token. Identity fields (id, name, status, safeAddress, delegateAddress, chainId) are unchanged from before.";
|
|
2091
1983
|
readonly nextActionGuidance: "";
|
|
2092
1984
|
};
|
|
2093
1985
|
readonly getAllowances: {
|
|
@@ -2118,7 +2010,7 @@ declare const toolDescriptions: {
|
|
|
2118
2010
|
readonly summary: "Step 1 of a purchase: discover payable services from Haven's curated merchant catalog — names, prices, and which pay tool to use next.";
|
|
2119
2011
|
readonly selectionGuidance: string;
|
|
2120
2012
|
readonly behavior: string;
|
|
2121
|
-
readonly nextActionGuidance: "Pick an entry and pay it with the tool named in suggested_tool, passing the entry's resource_url, tool_name, and tool_arguments for MCP merchants. Confirm the price from the live pay-tool result (not the catalog), and pass the user's cap as max_amount_human in whole tokens (\"no more than 1 USDC\" → max_amount_human: \"1\") — never convert it to atomic units by hand
|
|
2013
|
+
readonly nextActionGuidance: "Pick an entry and pay it with the tool named in suggested_tool, passing the entry's resource_url, tool_name, and tool_arguments for MCP merchants. Confirm the price from the live pay-tool result (not the catalog), and pass the user's cap as max_amount_human in whole tokens (\"no more than 1 USDC\" → max_amount_human: \"1\") — never convert it to atomic units by hand.";
|
|
2122
2014
|
};
|
|
2123
2015
|
readonly sweep_delegate: {
|
|
2124
2016
|
readonly summary: "Sweep stranded USDC and/or ETH from the delegate wallet back to the originating Safe.";
|
|
@@ -2154,7 +2046,7 @@ type SharedToolKey = keyof typeof toolDescriptions;
|
|
|
2154
2046
|
* this canonical string and asserts byte-for-byte equality, so the two copies
|
|
2155
2047
|
* cannot drift.
|
|
2156
2048
|
*/
|
|
2157
|
-
declare const HAVEN_SKILL_MD = "---\nname: haven-pay\ndescription: Pay for things from the user's Haven wallet within their agent rules. Use when the user asks to send, pay, tip, or transfer crypto \u2014 or when a request hits an HTTP 402 (x402) paywall.\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; payments above the remaining budget wait for the\nuser's approval in Haven.\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.\nTool results carry the exact next step (`next_action`, `next_tool`,\n`next_arguments`) \u2014 follow those fields first; the prose below is fallback\nand orientation, not the 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## 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 a readiness signal (`ready` / `needs_approval` /\n `revoked`) and live remaining per-token allowance, in one shot.\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 queued for the user to approve in the Haven dashboard \u2014 this is\nnormal, not an error.\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 is queued for the user's approval \u2014 tell them and check status later,\ndo 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`. Pass `payment_required`,\n`arguments`, and `mcp_transport` verbatim from the quote/prepare result.\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\nrecipient, 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, sign in the local Haven signer, and retry the original request only\nwhen the result says `retry_original_x402_request`.\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 amount\nHaven authorizes for that call \u2014 a ceiling the merchant settles at or below \u2014\nso present it as the most the user will pay.\n\n**Status:** `mcp__haven__haven_get_payment_status` with a `payment_id` to\ncheck on queued or in-flight payments. Do not poll in a tight loop.\n\n## Approval semantics\n\n- A result with `pending_approval` means the payment exceeded the remaining\n budget and is waiting for the user in Haven. Tell the user, then check\n status later.\n- `safe_to_continue: false` on a guidance block is the same 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 setup 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- `pending_approval`: queued for the user's approval (see above).\n- `insufficient_funds`: the Haven wallet doesn't hold enough of that token.\n Suggest the user add funds in the Haven dashboard.\n- `PRICE_EXCEEDS_MAX`: the live merchant price exceeded your cap. No funds\n moved; ask the user before retrying with a higher one.\n- `AMBIGUOUS_MAX_AMOUNT`: you sent both `max_amount` and\n `max_amount_human`. Nothing was contacted or spent \u2014 re-send with exactly\n one (`max_amount_human` for a cap the user stated in tokens).\n- `MAX_AMOUNT_UNCONVERTIBLE`: `max_amount_human` does not fit this quote's\n asset \u2014 unknown decimals, or more decimal places than the asset supports.\n Round the cap, or send an exact atomic `max_amount`.\n- `PAYMENT_WINDOW_EXPIRED`: re-run the quote/prepare tool with the same\n `idempotency_key`, then sign the fresh payload.\n- `MERCHANT_REJECTED_AFTER_FUNDING`: the merchant refused the paid retry.\n Stop-and-sweep \u2014 stop retrying the merchant and use\n `mcp__haven__haven_sweep_delegate` to recover stranded delegate funds.\n- `MERCHANT_UNRESPONSIVE_AFTER_FUNDING`: funding confirmed on-chain, but the\n merchant never answered the paid retry. This is NOT proof of rejection \u2014 the\n merchant may still settle late. Verify-then-sweep, never a blind sweep:\n check `mcp__haven__haven_get_payment_status`, retry\n `mcp__haven__haven_complete_mcp_tool` ONCE, and only sweep with\n `mcp__haven__haven_sweep_delegate` if no settlement appears.\n- Budget exceeded: tell the user how much remains (from\n `mcp__haven__haven_get_allowances`) and that they can raise the budget in\n Haven.\n\n## Reporting after a purchase\n\nA settled `mcp__haven__haven_settle_mcp_tool` response carries\n`agent_summary.purchase_summary` and the remaining post-purchase allowance\nin `allowance` \u2014 report the product, Haven-derived payment/transaction\nfields, and what is left from those fields directly. `result` is optional\nraw merchant evidence; never use it to decide whether the purchase was paid.\nDo not call `haven_get_agent` or `haven_get_allowances` again just to\nreport a purchase you already made.\n\n## Revoke\n\nIf this agent's credential may have leaked, tell the user to pause or revoke\nthe agent in the Haven dashboard under Agents. New requests stop immediately\nfor that credential.\n";
|
|
2049
|
+
declare const HAVEN_SKILL_MD = "---\nname: haven-pay\ndescription: Pay for things from the user's Haven wallet within their agent rules. Use when the user asks to send, pay, tip, or transfer crypto \u2014 or when a request hits an HTTP 402 (x402) paywall.\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; payments above the remaining budget wait for the\nuser's approval in Haven.\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## 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 queued for the user to approve in the Haven dashboard \u2014 this is\nnormal, not an error.\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 is queued for the user's approval \u2014 tell them and check status later,\ndo 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`. Pass `payment_required`,\n`arguments`, and `mcp_transport` verbatim from the quote/prepare result.\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\nrecipient, 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, sign in the local Haven signer, and retry the original request only\nwhen the result says `retry_original_x402_request`.\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 amount\nHaven authorizes for that call \u2014 a ceiling the merchant settles at or below \u2014\nso present it as the most the user will pay.\n\n**Status:** `mcp__haven__haven_get_payment_status` with a `payment_id` to\ncheck on queued or in-flight payments. Do not poll in a tight loop.\n\n## Approval semantics\n\n- A result with `pending_approval` means the payment exceeded the remaining\n budget and is waiting for the user in Haven. Tell the user, then check\n status later.\n- `safe_to_continue: false` on a guidance block is the same 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 setup 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- `pending_approval`: queued for the user's approval (see above).\n- `insufficient_funds`: the Haven wallet doesn't hold enough of that token.\n Suggest the user add funds in the Haven dashboard.\n- `PRICE_EXCEEDS_MAX`: the live merchant price exceeded your cap. No funds\n moved; ask the user before retrying with a higher one.\n- `AMBIGUOUS_MAX_AMOUNT`: you sent both `max_amount` and\n `max_amount_human`. Nothing was contacted or spent \u2014 re-send with exactly\n one (`max_amount_human` for a cap the user stated in tokens).\n- `MAX_AMOUNT_UNCONVERTIBLE`: `max_amount_human` does not fit this quote's\n asset \u2014 unknown decimals, or more decimal places than the asset supports.\n Round the cap, or send an exact atomic `max_amount`.\n- `PAYMENT_WINDOW_EXPIRED`: re-run the quote/prepare tool with the same\n `idempotency_key`, then sign the fresh payload.\n- `MERCHANT_REJECTED_AFTER_FUNDING`: the merchant refused the paid retry.\n Stop-and-sweep \u2014 stop retrying the merchant and use\n `mcp__haven__haven_sweep_delegate` to recover stranded delegate funds.\n- `MERCHANT_UNRESPONSIVE_AFTER_FUNDING`: funding confirmed on-chain, but the\n merchant never answered the paid retry. This is NOT proof of rejection \u2014 the\n merchant may still settle late. Verify-then-sweep, never a blind sweep:\n check `mcp__haven__haven_get_payment_status`, retry\n `mcp__haven__haven_complete_mcp_tool` ONCE, and only sweep with\n `mcp__haven__haven_sweep_delegate` if no settlement appears.\n- Budget exceeded: tell the user how much remains (from\n `mcp__haven__haven_get_allowances`) and that they can raise the budget in\n Haven.\n\n## Reporting after a purchase\n\nA settled `mcp__haven__haven_settle_mcp_tool` response carries\n`agent_summary.purchase_summary` and the remaining post-purchase allowance\nin `allowance` \u2014 report the product, Haven-derived payment/transaction\nfields, and what is left from those fields directly. `result` is optional\nraw merchant evidence; never use it to decide whether the purchase was paid.\nDo not call `haven_get_agent` or `haven_get_allowances` again just to\nreport a purchase you already made.\n\n## Revoke\n\nIf this agent's credential may have leaked, tell the user to pause or revoke\nthe agent in the Haven dashboard under Agents. New requests stop immediately\nfor that credential.\n";
|
|
2158
2050
|
/** Directory name for the installed skill folder. */
|
|
2159
2051
|
declare const SKILL_FOLDER_NAME = "haven-pay";
|
|
2160
2052
|
/**
|