@haven_ai/sdk 0.1.4 → 0.1.5

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 CHANGED
@@ -68,6 +68,15 @@ The agent will pay a tiny amount (~0.01 EURe on Gnosis Chain), receive the demo
68
68
  | Gnosis Chain | `eip155:100` | EURe, USDC.e, xDAI |
69
69
  | Base | `eip155:8453` | USDC, ETH |
70
70
 
71
+ ## Credential Lifecycle
72
+
73
+ - The Haven API key identifies the agent. It is not payment authority.
74
+ - The delegate key signs payment payloads locally. Haven's backend never receives it.
75
+ - On-chain Safe AllowanceModule state enforces the agent budget.
76
+ - `getAllowances()` / `get_allowances` is the right path for budget, remaining amount, reset period, or "what can I spend?" questions.
77
+ - If an API key is exposed or lost, rotate it from the Haven agent detail page. The new key is shown once and the old key stops working.
78
+ - If a delegate key is exposed or lost, pause or revoke the agent and create a new signing path.
79
+
71
80
  ## Step-by-Step API
72
81
 
73
82
  For agents that need control over each step (e.g., external signing):
@@ -94,7 +103,7 @@ const result = await haven.waitForConfirmation(intent.paymentId)
94
103
 
95
104
  Production merchant acceptance, facilitator, settlement, fiat, or acquiring functionality needs separate product and legal review under the repo's [CASP / MiCA guardrails](../../docs/regulatory/casp-risk-guardrails.md). The hosted x402 endpoint is an internal technical demo, not a merchant settlement product.
96
105
 
97
- Haven natively supports the [x402](https://x402.org) payment protocol. When an API returns HTTP 402, the SDK evaluates the challenge against the agent's approved limits, uses the configured delegate key for the required signature, and retries automatically:
106
+ The SDK supports [x402](https://x402.org) client flows. When an API returns HTTP 402, the SDK evaluates the challenge against the agent's approved limits, uses the configured delegate key for the required signature, and retries automatically:
98
107
 
99
108
  ```typescript
100
109
  // Automatic — fetch() intercepts 402, pays, and retries.
@@ -178,8 +187,12 @@ for (const block of response.content) {
178
187
  |------|-------------|
179
188
  | `make_payment` | Request and sign a payment from the user-controlled Safe within approved limits |
180
189
  | `get_payment_status` | Check the status of a payment intent or approval request |
190
+ | `get_allowances` | Read configured and on-chain allowance state, including spent and remaining allowance |
181
191
  | `authorize_x402_payment` | Authorize a policy-limited x402 payment and return a payment header for an HTTP 402 resource |
182
192
  | `resume_x402_payment` | Resume an approved x402 payment and return a merchant payment header without creating a duplicate approval |
193
+ | `authorize_machine_payment` | Authorize an internal Haven MPP demo challenge and return proof details |
194
+
195
+ Use `get_allowances` for allowance, budget, spend-limit, remaining amount, reset-period, or "what can I spend?" questions. Payment tools still require the agent-held delegate key and on-chain Safe allowance state; the Haven API key identifies the agent but does not authorize spending by itself.
183
196
 
184
197
  ## Configuration
185
198
 
@@ -214,7 +227,7 @@ Every payment or approval state returned by Haven includes:
214
227
 
215
228
  - `phase`: where the Haven-side payment currently is.
216
229
  - `nextAction`: the stable action an agent should take next.
217
- - `rail`: which payment rail produced the state, such as `direct`, `x402`, or `mpp`.
230
+ - `rail`: which payment rail produced the state. Categorical values (`direct`, `x402`, `mpp`) appear on resume-state discriminators; granular values (`mpp_demo`, `mpp_crypto`, `stripe_deposit`, `spt`) appear on response bodies.
218
231
  - `message`: human-readable guidance for the same state.
219
232
 
220
233
  The enum values and JSON Schema fragments are exported from `@haven_ai/sdk`:
@@ -230,22 +243,74 @@ import {
230
243
  } from '@haven_ai/sdk'
231
244
  ```
232
245
 
246
+ ### Flow diagram
247
+
233
248
  ```text
234
- agent_signature_required -> payment_submitted -> payment_confirmed
235
- |
236
- v
237
- user_approval_required -> user_execution_required -> funding_sent
238
- |
239
- v
240
- waiting_for_additional_approvals
249
+ ┌─────────────────────────┐
250
+ │ agent_signature_required│
251
+ └──────────┬──────────────┘
252
+ │ sign_and_submit_payment
253
+
254
+ ┌─────────────────────────┐
255
+ │ payment_submitted │
256
+ └──────────┬──────────────┘
257
+ │ check_status_later
258
+ ┌──────────┴──────────────┐
259
+ ▼ ▼
260
+ ┌────────────────────────┐ ┌──────────────────────┐
261
+ │ payment_confirmed (✔) │ │ user_approval_required│
262
+ └────────────────────────┘ └──────────┬───────────┘
263
+ │ wait_for_user_approval
264
+ ┌─────────────────┴───────────────────┐
265
+ │ single-owner Safe │ multisig Safe
266
+ ▼ ▼
267
+ ┌──────────────────────────┐ ┌──────────────────────────────────┐
268
+ │ user_execution_required │ │ waiting_for_additional_approvals │
269
+ └──────────┬───────────────┘ └────────────────┬─────────────────┘
270
+ │ wait_for_user_to_complete_payment │ wait_for_user_approval
271
+ └─────────────────┬───────────────────┘
272
+
273
+ ┌───────────────────────┐
274
+ │ funding_sent │
275
+ └──────────┬────────────┘
276
+ │ retry_original_x402_request (x402)
277
+ │ none (direct)
278
+
279
+ ┌───────────────────────┐
280
+ │ executed (✔) │
281
+ └───────────────────────┘
282
+
283
+ Terminal from any non-confirmed phase:
284
+ rejected → stop_and_tell_user
285
+ failed → stop_and_tell_user
286
+ expired → request_again_if_user_still_wants_it
241
287
  ```
242
288
 
289
+ ### `phase` reference
290
+
291
+ | `phase` | Meaning | Terminal? |
292
+ |---------|---------|-----------|
293
+ | `agent_signature_required` | Haven prepared a payment intent; the agent must sign and submit. | no |
294
+ | `payment_submitted` | Haven received the signed payment; the agent should poll for confirmation. | no |
295
+ | `payment_confirmed` | Direct payment is confirmed on chain. | yes |
296
+ | `user_approval_required` | Payment exceeds remaining on-chain allowance; wallet owner must approve in Haven. | no |
297
+ | `user_execution_required` | Owner approved; the funding payment has not been sent yet (single-owner Safe). | no |
298
+ | `waiting_for_additional_approvals` | Funding payment was proposed and is waiting for the remaining multisig approvals. | no |
299
+ | `funding_sent` | Haven funding leg landed; the agent can continue the merchant/protocol leg. | no |
300
+ | `rejected` | Owner rejected the request. | yes |
301
+ | `expired` | Payment or approval request expired before completion. | yes |
302
+ | `failed` | Haven could not complete the payment. | yes |
303
+
304
+ The merchant settlement leg of x402 (and the MPP retry) is the agent's own request to the merchant — it does not have a Haven `phase`. The payment is `funding_sent` until the agent retries with `X-PAYMENT` (x402) or the MPP proof header; from Haven's perspective the payment becomes `executed` only after the agent successfully resumes.
305
+
306
+ ### `nextAction` reference
307
+
243
308
  | `nextAction` | What the agent should do |
244
309
  |--------------|--------------------------|
245
310
  | `sign_and_submit_payment` | Sign with the delegate key and submit the payment to Haven. |
246
311
  | `check_status_later` | Poll `getPaymentStatus(payment_id)` later. |
247
312
  | `none` | Stop polling; no more action is needed for this payment id. |
248
- | `wait_for_user_approval` | Tell the user the payment is waiting in Haven, then poll later. Do not create a duplicate payment. |
313
+ | `wait_for_user_approval` | Tell the user the payment is waiting in Haven, then poll later. Do not create a duplicate payment. Same `nextAction` covers both the single-owner case (waiting for one owner to approve) and the multisig case (waiting for additional approvals after the first one). |
249
314
  | `wait_for_user_to_complete_payment` | The user approved the request; wait for them to finish the funding payment. |
250
315
  | `retry_original_x402_request` | Resume this payment id and retry the original x402 request with the merchant payment header. Do not start a new merchant session. |
251
316
  | `stop_and_tell_user` | Stop retrying and tell the user the payment failed or was rejected. |
package/dist/index.cjs CHANGED
@@ -54,8 +54,16 @@ var AgentPaymentRail = {
54
54
  Direct: "direct",
55
55
  /** x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg. */
56
56
  X402: "x402",
57
- /** Machine Payment Protocol flow. */
58
- Mpp: "mpp"
57
+ /** Machine Payment Protocol family — categorical value used as a resume-state discriminator. */
58
+ Mpp: "mpp",
59
+ /** Haven internal MPP demo rail. Not for production traffic. */
60
+ MppDemo: "mpp_demo",
61
+ /** Crypto-settled MPP rail. */
62
+ MppCrypto: "mpp_crypto",
63
+ /** Stripe-deposit-backed MPP rail. */
64
+ StripeDeposit: "stripe_deposit",
65
+ /** Stripe Payment Token MPP rail. */
66
+ Spt: "spt"
59
67
  };
60
68
  var AGENT_PAYMENT_PHASE_VALUES = Object.values(AgentPaymentPhase);
61
69
  var AGENT_PAYMENT_NEXT_ACTION_VALUES = Object.values(AgentPaymentNextAction);
@@ -85,7 +93,11 @@ var AgentPaymentNextActionDescriptions = {
85
93
  var AgentPaymentRailDescriptions = {
86
94
  [AgentPaymentRail.Direct]: "Standard Haven payment from the user-controlled Safe through an approved delegate allowance.",
87
95
  [AgentPaymentRail.X402]: "x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg.",
88
- [AgentPaymentRail.Mpp]: "Machine Payment Protocol flow."
96
+ [AgentPaymentRail.Mpp]: "Categorical MPP rail value used as a resume-state discriminator. Response bodies carry a granular mpp_* value instead.",
97
+ [AgentPaymentRail.MppDemo]: "Haven internal MPP demo rail. Not for production traffic.",
98
+ [AgentPaymentRail.MppCrypto]: "Crypto-settled MPP rail.",
99
+ [AgentPaymentRail.StripeDeposit]: "Stripe-deposit-backed MPP rail.",
100
+ [AgentPaymentRail.Spt]: "Stripe Payment Token MPP rail."
89
101
  };
90
102
  var AgentPaymentPhaseSchema = {
91
103
  type: "string",
@@ -325,6 +337,23 @@ function selectStandardPaymentOption(accepts) {
325
337
  }
326
338
  return null;
327
339
  }
340
+ function x402AuthorizationAmount(option) {
341
+ return option.maxAmountRequired ?? option.amount;
342
+ }
343
+ function buildX402ExpectedMessage(context) {
344
+ return `Haven x402 expected context v1
345
+ ${stableStringify({
346
+ version: 1,
347
+ kind: "haven.x402.expected",
348
+ paymentId: context.paymentId,
349
+ payloadHash: context.payloadHash.toLowerCase(),
350
+ resourceUrl: context.resourceUrl,
351
+ merchantTo: context.merchantTo.toLowerCase(),
352
+ amount: context.amount,
353
+ asset: context.asset.toLowerCase(),
354
+ network: context.network
355
+ })}`;
356
+ }
328
357
  function toStandardPaymentRequirements(paymentRequired, option) {
329
358
  const network = STANDARD_X402_NETWORKS[option.network];
330
359
  if (!network) {
@@ -336,7 +365,7 @@ function toStandardPaymentRequirements(paymentRequired, option) {
336
365
  return {
337
366
  scheme: "exact",
338
367
  network,
339
- maxAmountRequired: option.maxAmountRequired ?? option.amount,
368
+ maxAmountRequired: x402AuthorizationAmount(option),
340
369
  resource: option.resource ?? paymentRequired.resource.url,
341
370
  description: option.description ?? paymentRequired.resource.description ?? "Haven x402 payment",
342
371
  mimeType: option.mimeType ?? paymentRequired.resource.mimeType ?? "application/octet-stream",
@@ -353,7 +382,7 @@ function buildX402IdempotencyKey(paymentRequired, option, now = Date.now()) {
353
382
  paymentRequired.resource.description ?? "",
354
383
  option.payTo.toLowerCase(),
355
384
  option.asset.toLowerCase(),
356
- option.amount,
385
+ x402AuthorizationAmount(option),
357
386
  option.network,
358
387
  bucket
359
388
  ].join("|");
@@ -382,6 +411,15 @@ function resolveTokenFromAddress(address, network) {
382
411
  }
383
412
  return ALL_TOKENS[lower] ?? null;
384
413
  }
414
+ function stableStringify(value) {
415
+ if (value === null || typeof value !== "object") {
416
+ const primitive = JSON.stringify(value);
417
+ return primitive === void 0 ? "undefined" : primitive;
418
+ }
419
+ if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(",")}]`;
420
+ const object = value;
421
+ return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(object[key])}`).join(",")}}`;
422
+ }
385
423
  function decodeBase64Json2(value, label) {
386
424
  try {
387
425
  return JSON.parse(atob(value));
@@ -659,6 +697,70 @@ var HavenClient = class {
659
697
  signData: raw.sign_data
660
698
  };
661
699
  }
700
+ /**
701
+ * Keyless x402 construct.
702
+ *
703
+ * The non-custodial half of an x402 payment: posts the funding request to
704
+ * `/x402` and returns the unsigned funding hash plus the data the caller
705
+ * needs to build and sign the EIP-3009 merchant header itself. Crucially it
706
+ * does **not** sign — neither the funding hash nor the merchant header — so
707
+ * it works without a `delegateKey`. Both delegate signatures happen on the
708
+ * machine that holds the key (the edge); the hosted MCP server relays only.
709
+ *
710
+ * Use this from the hosted, keyless server. The all-in-one `authorizeX402`
711
+ * remains for local clients that hold the key.
712
+ *
713
+ * Throws (via the shared payment-state path) when the amount exceeds the
714
+ * on-chain allowance — there is nothing to sign until the user approves.
715
+ */
716
+ async createX402Intent(paymentRequired, options = {}) {
717
+ const option = selectStandardPaymentOption(paymentRequired.accepts);
718
+ if (!option) {
719
+ throw new HavenApiError(
720
+ "No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC.",
721
+ 400
722
+ );
723
+ }
724
+ const agent = await this.getAgent();
725
+ const fundingTo = agent.delegateAddress;
726
+ if (!fundingTo) {
727
+ throw new HavenApiError("Authenticated agent has no delegate address registered.", 502);
728
+ }
729
+ const idempotencyKey = options.idempotencyKey ?? buildX402IdempotencyKey(paymentRequired, option);
730
+ const raw = await this.post("/x402", {
731
+ url: paymentRequired.resource.url,
732
+ payTo: fundingTo,
733
+ merchantPayTo: option.payTo,
734
+ amount: x402AuthorizationAmount(option),
735
+ asset: option.asset,
736
+ network: option.network,
737
+ description: paymentRequired.resource.description,
738
+ idempotencyKey
739
+ });
740
+ if (raw.status !== "pending_signature") {
741
+ this.throwPaymentStateError("x402 payment", raw);
742
+ }
743
+ if (!raw.sign_data?.hash) {
744
+ throw new HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
745
+ }
746
+ if (!raw.x402_expected_auth) {
747
+ throw new HavenApiError("No x402 expected-context binding returned from x402/authorize", 500, raw);
748
+ }
749
+ return {
750
+ paymentId: raw.payment_id,
751
+ status: "pending_signature",
752
+ expiresAt: raw.expires_at,
753
+ signData: raw.sign_data,
754
+ accepted: option,
755
+ resourceUrl: paymentRequired.resource.url,
756
+ merchantTo: raw.merchant_to ?? option.payTo,
757
+ amountAtomic: x402AuthorizationAmount(option),
758
+ asset: option.asset,
759
+ network: option.network,
760
+ expectedAuth: raw.x402_expected_auth,
761
+ fundingTo
762
+ };
763
+ }
662
764
  /**
663
765
  * Step 2: Sign a hash with the delegate key.
664
766
  *
@@ -882,7 +984,7 @@ var HavenClient = class {
882
984
  url: paymentRequired.resource.url,
883
985
  payTo: this.delegateAddress,
884
986
  merchantPayTo: option.payTo,
885
- amount: option.amount,
987
+ amount: x402AuthorizationAmount(option),
886
988
  asset: option.asset,
887
989
  network: option.network,
888
990
  description: paymentRequired.resource.description,
@@ -1319,7 +1421,7 @@ var HavenClient = class {
1319
1421
  );
1320
1422
  }
1321
1423
  const approvedAmount = status.amount ? normalizeDecimal(status.amount) : "";
1322
- const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(option.amount));
1424
+ const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(x402AuthorizationAmount(option)));
1323
1425
  if (approvedAmount && approvedAmount !== requestedAmount) {
1324
1426
  throw new HavenApiError(
1325
1427
  "x402 resume request does not match the approved amount.",
@@ -1395,7 +1497,7 @@ var HavenClient = class {
1395
1497
  const txHash = execResult?.tx_hash ?? raw.tx_hash ?? "";
1396
1498
  const chainId = execResult?.chain_id ?? raw.chain_id ?? chainIdFromNetwork(option.network);
1397
1499
  const token = execResult?.token ?? raw.token ?? "USDC";
1398
- const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(option.amount);
1500
+ const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(x402AuthorizationAmount(option));
1399
1501
  const to = execResult?.to ?? raw.to ?? this.delegateAddress ?? "";
1400
1502
  const explorerUrl = execResult?.explorer_url ?? raw.explorer_url ?? explorerUrlOrEmpty(chainId, txHash);
1401
1503
  const merchantTo = execResult?.merchant_to ?? raw.merchant_to ?? option.payTo;
@@ -1428,7 +1530,7 @@ var HavenClient = class {
1428
1530
  paymentId: status.paymentId,
1429
1531
  txHash: status.txHash,
1430
1532
  token: status.token || "USDC",
1431
- amount: status.amount || decimalFromUsdcAtomic(option.amount),
1533
+ amount: status.amount || decimalFromUsdcAtomic(x402AuthorizationAmount(option)),
1432
1534
  to: this.delegateAddress ?? "",
1433
1535
  resourceUrl: paymentRequired.resource.url,
1434
1536
  explorerUrl: explorerUrlOrEmpty(status.chainId, status.txHash),
@@ -1464,7 +1566,7 @@ var HavenClient = class {
1464
1566
  payTo: input.merchantTo ?? input.accepted.payTo
1465
1567
  },
1466
1568
  x402: {
1467
- amount: input.accepted.amount,
1569
+ amount: x402AuthorizationAmount(input.accepted),
1468
1570
  token: input.token,
1469
1571
  network: input.accepted.network,
1470
1572
  asset: input.accepted.asset,
@@ -1714,8 +1816,8 @@ var HavenClient = class {
1714
1816
  resourceUrl: paymentRequired.resource.url,
1715
1817
  description: paymentRequired.resource.description ?? option.description ?? null,
1716
1818
  mimeType: paymentRequired.resource.mimeType ?? option.mimeType ?? null,
1717
- amountAtomic: option.amount,
1718
- amount: decimalFromUsdcAtomic(option.amount),
1819
+ amountAtomic: x402AuthorizationAmount(option),
1820
+ amount: decimalFromUsdcAtomic(x402AuthorizationAmount(option)),
1719
1821
  token: token?.symbol ?? "USDC",
1720
1822
  asset: option.asset,
1721
1823
  network: option.network,
@@ -1736,8 +1838,8 @@ var HavenClient = class {
1736
1838
  request: input.request,
1737
1839
  resourceUrl: input.paymentRequired.resource.url,
1738
1840
  description: input.paymentRequired.resource.description ?? input.accepted.description ?? null,
1739
- amountAtomic: input.accepted.amount,
1740
- amount: decimalFromUsdcAtomic(input.accepted.amount),
1841
+ amountAtomic: x402AuthorizationAmount(input.accepted),
1842
+ amount: decimalFromUsdcAtomic(x402AuthorizationAmount(input.accepted)),
1741
1843
  token: token?.symbol ?? "USDC",
1742
1844
  asset: input.accepted.asset,
1743
1845
  network: input.accepted.network,
@@ -1932,6 +2034,9 @@ var HavenClient = class {
1932
2034
  message: result.message
1933
2035
  };
1934
2036
  }
2037
+ if (toolName === "get_allowances") {
2038
+ return { ...await this.getAllowances() };
2039
+ }
1935
2040
  throw new Error(`Unknown tool: ${toolName}`);
1936
2041
  }
1937
2042
  toolX402PaymentRequired(input) {
@@ -2189,6 +2294,72 @@ async function responseSnippet(response) {
2189
2294
  }
2190
2295
  }
2191
2296
 
2297
+ // src/tool-descriptions.ts
2298
+ function composeDescription(d) {
2299
+ return [d.summary, d.selectionGuidance, d.behavior, d.nextActionGuidance].filter(Boolean).join(" ");
2300
+ }
2301
+ var toolDescriptions = {
2302
+ quoteX402: {
2303
+ summary: "Inspect an HTTP 402 x402 paid resource without creating a Haven payment, signature, approval, or on-chain transaction.",
2304
+ behavior: "Probes the merchant directly and parses the 402 response. Pure read-only client behavior \u2014 Haven is not contacted.",
2305
+ nextActionGuidance: ""
2306
+ },
2307
+ payX402: {
2308
+ summary: "Pay an inspected x402 quote. The delegate key signs locally; Haven only validates and relays signed, on-chain-constrained payment transactions.",
2309
+ selectionGuidance: "Do not use this for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.",
2310
+ behavior: "Signs the EIP-3009 payment from the delegate wallet, asks Haven for a Safe AllowanceModule top-up if needed, and returns the merchant response or a pending-approval state.",
2311
+ nextActionGuidance: "If approval is needed, preserve the returned resume_state and wait for nextAction=retry_original_x402_request before resuming."
2312
+ },
2313
+ resumeX402: {
2314
+ summary: "Resume an x402 payment after the Haven wallet owner approved the funding step.",
2315
+ behavior: "Accepts either resume_state or payment_id, validates the original x402 details against the approved Haven funding, and retries the merchant request with the X-PAYMENT header. No new Haven approval is created.",
2316
+ nextActionGuidance: "Only use when get_payment_status returns nextAction=retry_original_x402_request; do not start a new merchant session."
2317
+ },
2318
+ quoteMpp: {
2319
+ summary: "Inspect a Haven MPP challenge or paid MPP URL without creating a Haven payment, signature, approval, or on-chain transaction.",
2320
+ behavior: "Parses an MPP challenge envelope and returns a typed quote with rail tag, amount, asset, and merchant context. Pure read-only \u2014 Haven is not contacted.",
2321
+ nextActionGuidance: ""
2322
+ },
2323
+ payMpp: {
2324
+ summary: "Pay an inspected MPP challenge. The delegate key signs locally; Haven only validates and relays signed, on-chain-constrained payment transactions.",
2325
+ selectionGuidance: "Do not use this for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.",
2326
+ behavior: "Authorizes the payment through Haven within the on-chain allowance, signs the challenge proof, and returns the proof header for retrying the original paid resource.",
2327
+ nextActionGuidance: "If approval is needed, preserve resume_state or payment_id and wait for nextAction=retry_original_x402_request before resuming."
2328
+ },
2329
+ resumeMpp: {
2330
+ summary: "Resume an MPP payment after the Haven wallet owner approved the funding step.",
2331
+ behavior: "Accepts either resume_state or payment_id and retries the original paid resource with the MPP proof header. No new Haven approval is created.",
2332
+ nextActionGuidance: ""
2333
+ },
2334
+ getPaymentStatus: {
2335
+ summary: "Fetch structured Haven payment status, including phase and nextAction taxonomy for agent recovery.",
2336
+ behavior: "Accepts a payment intent or approval request id and returns the full state taxonomy (phase, nextAction, rail, amount, merchant, resource url, idempotency key, message).",
2337
+ nextActionGuidance: ""
2338
+ },
2339
+ getResumeState: {
2340
+ summary: "Rehydrate stored x402 or MPP resume_state by payment_id.",
2341
+ behavior: "Returns the context that the agent originally received in a pending-approval response, reconstructed from Haven's database. This is context only; signing still happens locally when a resume tool is called.",
2342
+ nextActionGuidance: ""
2343
+ },
2344
+ getAgent: {
2345
+ summary: "Return the authenticated agent identity, Haven wallet, delegate address, chain, and status.",
2346
+ behavior: "Read-only identity lookup. Useful for verifying which on-chain Safe and delegate the credential is bound to.",
2347
+ nextActionGuidance: ""
2348
+ },
2349
+ getAllowances: {
2350
+ summary: "Return configured and on-chain allowance state for the authenticated agent. On-chain allowance is the real spend gate.",
2351
+ 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.",
2352
+ behavior: "Reads the Safe AllowanceModule snapshot per token (allowance, spent, remaining, reset window). Configured amounts from Haven are returned alongside the on-chain truth.",
2353
+ nextActionGuidance: ""
2354
+ },
2355
+ listReceipts: {
2356
+ summary: "List recent machine-payment receipts and evidence for bookkeeping.",
2357
+ selectionGuidance: "Use this for transaction history, receipts, payment evidence, or bookkeeping; use the allowance tool instead for remaining allowance, budget, spend-limit, or what-can-I-spend questions.",
2358
+ behavior: "Returns the agent's recent machine-payment receipts ordered by recency. Proof header values are not returned.",
2359
+ nextActionGuidance: ""
2360
+ }
2361
+ };
2362
+
2192
2363
  // src/tools.ts
2193
2364
  var makePaymentSchema = {
2194
2365
  type: "object",
@@ -2222,6 +2393,11 @@ var getPaymentStatusSchema = {
2222
2393
  },
2223
2394
  required: ["payment_id"]
2224
2395
  };
2396
+ var getAllowancesSchema = {
2397
+ type: "object",
2398
+ properties: {},
2399
+ required: []
2400
+ };
2225
2401
  var authorizeX402Schema = {
2226
2402
  type: "object",
2227
2403
  properties: {
@@ -2304,11 +2480,12 @@ var authorizeMachinePaymentSchema = {
2304
2480
  },
2305
2481
  required: ["challenge"]
2306
2482
  };
2307
- var MAKE_PAYMENT_DESCRIPTION = "Request and sign a payment from the user-controlled Safe within approved on-chain limits. Haven authenticates the agent, validates the signed intent, and relays the Safe AllowanceModule transaction; it does not hold keys or control funds. Gnosis Chain tokens: EURe, USDC.e, xDAI. Base tokens: USDC, ETH.";
2308
- var GET_STATUS_DESCRIPTION = "Check the status of a previously initiated payment. Accepts payment intent IDs and approval request IDs. Returns the current status, phase, next_action, transaction hash if available, and payment details.";
2309
- var AUTHORIZE_X402_DESCRIPTION = "Authorize payment for an HTTP 402 (Payment Required) response. When a paid API returns x402 payment requirements, use this tool to sign with the agent-owned delegate key and request a policy-limited Safe AllowanceModule top-up when needed. Haven relays signed transactions only; the agent key authorizes payment and on-chain limits enforce spend. If this returns pending_approval, tell the user it is waiting in Haven, preserve the original merchant/MCP session and x402 details, call get_payment_status later, and use resume_x402_payment only when next_action is retry_original_x402_request. Do not start a new merchant session or loop retries while approval is pending. Use the returned payment_header as the X-PAYMENT header on the retry request when doing a manual HTTP retry.";
2310
- var RESUME_X402_DESCRIPTION = "Resume an x402 payment after the user approved it in Haven. Use this only after get_payment_status returns next_action=retry_original_x402_request. It checks the approved payment, validates the original x402 details, and returns a merchant X-PAYMENT header without creating a new approval request or merchant session.";
2311
- var AUTHORIZE_MACHINE_PAYMENT_DESCRIPTION = "Authorize a Haven machine-payment challenge, currently for the internal MPP demo rail. The agent signs the payment, Haven relays it within the on-chain allowance, and the tool returns a proof header for the retry request.";
2483
+ var MAKE_PAYMENT_DESCRIPTION = "Request and sign a payment from the user-controlled Safe within approved on-chain limits. For read-only allowance, budget, spend-limit, remaining-amount, or reset-period questions, use get_allowances instead of making a payment. Haven authenticates the agent, validates the signed intent, and relays the Safe AllowanceModule transaction; it does not hold keys or control funds. Gnosis Chain tokens: EURe, USDC.e, xDAI. Base tokens: USDC, ETH.";
2484
+ var GET_STATUS_DESCRIPTION = toolDescriptions.getPaymentStatus.summary + " Accepts payment intent IDs and approval request IDs. Returns the current status, phase, next_action, transaction hash if available, and payment details.";
2485
+ var GET_ALLOWANCES_DESCRIPTION = composeDescription(toolDescriptions.getAllowances);
2486
+ var AUTHORIZE_X402_DESCRIPTION = composeDescription(toolDescriptions.payX402) + " In this SDK tool set, the allowance lookup tool is get_allowances. When a paid API returns x402 payment requirements, use this tool to sign with the agent-owned delegate key and request a policy-limited Safe AllowanceModule top-up when needed. Haven relays signed transactions only; the agent key authorizes payment and on-chain limits enforce spend. If this returns pending_approval, tell the user it is waiting in Haven, preserve the original merchant/MCP session and x402 details, call get_payment_status later, and use resume_x402_payment only when next_action is retry_original_x402_request. Do not start a new merchant session or loop retries while approval is pending. Use the returned payment_header as the X-PAYMENT header on the retry request when doing a manual HTTP retry.";
2487
+ var RESUME_X402_DESCRIPTION = toolDescriptions.resumeX402.summary + " Use this only after get_payment_status returns next_action=retry_original_x402_request. It checks the approved payment, validates the original x402 details, and returns a merchant X-PAYMENT header without creating a new approval request or merchant session.";
2488
+ var AUTHORIZE_MACHINE_PAYMENT_DESCRIPTION = composeDescription(toolDescriptions.payMpp) + " In this SDK tool set, the allowance lookup tool is get_allowances. Currently scoped to the internal MPP demo rail. The agent signs the payment, Haven relays it within the on-chain allowance, and the tool returns a proof header for the retry request.";
2312
2489
  function claudeTools() {
2313
2490
  return [
2314
2491
  {
@@ -2321,6 +2498,11 @@ function claudeTools() {
2321
2498
  description: GET_STATUS_DESCRIPTION,
2322
2499
  input_schema: getPaymentStatusSchema
2323
2500
  },
2501
+ {
2502
+ name: "get_allowances",
2503
+ description: GET_ALLOWANCES_DESCRIPTION,
2504
+ input_schema: getAllowancesSchema
2505
+ },
2324
2506
  {
2325
2507
  name: "authorize_x402_payment",
2326
2508
  description: AUTHORIZE_X402_DESCRIPTION,
@@ -2356,6 +2538,14 @@ function openaiTools() {
2356
2538
  parameters: getPaymentStatusSchema
2357
2539
  }
2358
2540
  },
2541
+ {
2542
+ type: "function",
2543
+ function: {
2544
+ name: "get_allowances",
2545
+ description: GET_ALLOWANCES_DESCRIPTION,
2546
+ parameters: getAllowancesSchema
2547
+ }
2548
+ },
2359
2549
  {
2360
2550
  type: "function",
2361
2551
  function: {
@@ -2409,6 +2599,8 @@ exports.HavenSigningError = HavenSigningError;
2409
2599
  exports.HavenTimeoutError = HavenTimeoutError;
2410
2600
  exports.addressFromKey = addressFromKey;
2411
2601
  exports.buildMachinePaymentIdempotencyKey = buildMachinePaymentIdempotencyKey;
2602
+ exports.buildX402ExpectedMessage = buildX402ExpectedMessage;
2603
+ exports.composeDescription = composeDescription;
2412
2604
  exports.encodeMachinePaymentProof = encodeMachinePaymentProof;
2413
2605
  exports.encodePaymentProof = encodePaymentProof;
2414
2606
  exports.havenTools = havenTools;
@@ -2417,7 +2609,11 @@ exports.parseMachinePaymentChallengeResponse = parseMachinePaymentChallengeRespo
2417
2609
  exports.parsePaymentRequired = parsePaymentRequired;
2418
2610
  exports.parsePaymentRequiredResponse = parsePaymentRequiredResponse;
2419
2611
  exports.selectPaymentOption = selectPaymentOption;
2612
+ exports.selectStandardPaymentOption = selectStandardPaymentOption;
2420
2613
  exports.signHash = signHash;
2614
+ exports.toStandardPaymentRequirements = toStandardPaymentRequirements;
2615
+ exports.toolDescriptions = toolDescriptions;
2421
2616
  exports.verifySignature = verifySignature;
2617
+ exports.x402AuthorizationAmount = x402AuthorizationAmount;
2422
2618
  //# sourceMappingURL=index.cjs.map
2423
2619
  //# sourceMappingURL=index.cjs.map