@dvmkit/sdk 0.6.0-rc.1 → 0.7.0-rc.2

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.
Files changed (74) hide show
  1. package/README.md +2 -0
  2. package/dist/{chunk-PLG4XER6.js → chunk-26W6GPCD.js} +48 -6
  3. package/dist/{chunk-FI4CST2D.js → chunk-2OM2QPBE.js} +6 -8
  4. package/dist/{chunk-IWQHUSMO.js → chunk-62FI3NJF.js} +78 -2
  5. package/dist/{chunk-VHNPVGSA.js → chunk-6STC5TCP.js} +3 -3
  6. package/dist/{chunk-N5RZ5HVB.js → chunk-72V5DTEC.js} +2 -2
  7. package/dist/chunk-A262WVYX.js +6 -0
  8. package/dist/{chunk-HHBDBMEO.js → chunk-A6CXKAQV.js} +186 -93
  9. package/dist/{chunk-QR2EF2NI.js → chunk-AQ7OX5NX.js} +2 -2
  10. package/dist/{chunk-RLTSCKRI.js → chunk-BPYMEMQX.js} +50 -3
  11. package/dist/{chunk-BYCEKO65.js → chunk-CLIAFTUR.js} +102 -13
  12. package/dist/{chunk-GAOAYHZA.js → chunk-DNG4KGSC.js} +3 -3
  13. package/dist/{chunk-Z4ZT5LNT.js → chunk-GSLS4464.js} +3 -3
  14. package/dist/{chunk-7ZUKL4IV.js → chunk-H5FVVEEN.js} +17 -6
  15. package/dist/{chunk-IXR5RFK7.js → chunk-HCE4MPZ5.js} +1 -1
  16. package/dist/{chunk-FYRR2UEZ.js → chunk-I555L2WK.js} +1 -1
  17. package/dist/{chunk-EQLA4FFY.js → chunk-IIZQNDQU.js} +3 -3
  18. package/dist/{chunk-FUJ36YDV.js → chunk-KXWROQGK.js} +24 -1
  19. package/dist/{chunk-ETXDTUJO.js → chunk-LAKP6FUI.js} +55 -0
  20. package/dist/{chunk-X7EZ5CLI.js → chunk-MON76YBJ.js} +3 -3
  21. package/dist/chunk-OFSOLHRX.js +120 -0
  22. package/dist/{chunk-IV6Q7NRW.js → chunk-RAGX6VG7.js} +2 -2
  23. package/dist/{chunk-KA6VN5FK.js → chunk-RXPHMS4C.js} +3 -3
  24. package/dist/{chunk-JH3SX3LY.js → chunk-SPYEJXI7.js} +6 -6
  25. package/dist/{chunk-P6QON7ER.js → chunk-TRNMTTPX.js} +1 -1
  26. package/dist/{chunk-RCM3P2HE.js → chunk-UKD3R2KU.js} +55 -4
  27. package/dist/chunk-USL7ZEXN.js +17 -0
  28. package/dist/{chunk-OQA7IHI4.js → chunk-VB5OLOZH.js} +403 -235
  29. package/dist/{content-retention-BTGSQRfP.d.ts → content-retention-CbnouEnh.d.ts} +1 -1
  30. package/dist/{credit-ledger-MI2H7NEC.js → credit-ledger-7Z7LOCTN.js} +4 -5
  31. package/dist/{credit-menu-BAsrRu3z.d.ts → credit-menu-BO8yJppy.d.ts} +4 -4
  32. package/dist/{fx-BgDmyTdd.d.ts → fx-DSOZQ2z7.d.ts} +1 -1
  33. package/dist/index.d.ts +5 -5
  34. package/dist/index.js +236 -16
  35. package/dist/internal/caller.d.ts +4495 -7305
  36. package/dist/internal/caller.js +4415 -8122
  37. package/dist/internal/index.js +1 -1
  38. package/dist/internal/server.d.ts +7 -7
  39. package/dist/internal/server.js +27 -32
  40. package/dist/{job-store-BVeF5_Jq.d.ts → job-store-BJRlmq2Q.d.ts} +1 -1
  41. package/dist/{lightning-backend-40fIzz1W.d.ts → lightning-backend-f16-fsYK.d.ts} +4 -2
  42. package/dist/memory-credit-ledger-3WOS74UH.js +11 -0
  43. package/dist/{mpp-setup-RF5FXGGV.js → mpp-setup-XB4KATMU.js} +2 -2
  44. package/dist/{payout-reporter-3Y2U55ZX.js → payout-reporter-WT7XYW42.js} +2 -2
  45. package/dist/{postgres-consumed-credential-store-BUVCAPLS.js → postgres-consumed-credential-store-W7UP33AH.js} +3 -3
  46. package/dist/{postgres-job-store-VHLQBJZC.js → postgres-job-store-3KGUGFRD.js} +2 -2
  47. package/dist/{postgres-replay-store-ARZSQ45X.js → postgres-replay-store-CVNJJOQG.js} +2 -2
  48. package/dist/{pricing-XT2IAPNE.js → pricing-QAVZUTZR.js} +12 -12
  49. package/dist/{revenue-reporter-MAERPYGK.js → revenue-reporter-7UR3W2SD.js} +2 -2
  50. package/dist/server/index.d.ts +10 -10
  51. package/dist/server/index.js +46 -53
  52. package/dist/{step-cache-CPdH1hei.d.ts → step-cache-CJFiZU3n.d.ts} +1 -1
  53. package/dist/{tempo-charge-store-Q3D7KYMH.js → tempo-charge-store-GA6CED6O.js} +2 -2
  54. package/dist/{tempo-session-store-ZRNCOX7P.js → tempo-session-store-WZWQRITB.js} +3 -3
  55. package/dist/testing/index.d.ts +3 -3
  56. package/dist/testing/index.js +6 -7
  57. package/dist/{usd-AWlrwlM5.d.ts → usd-DmHHg0_4.d.ts} +1 -1
  58. package/dist/{x402-R6HPBY5D.js → x402-ZU4GML7Z.js} +9 -30
  59. package/package.json +3 -2
  60. package/dist/chunk-66HGCPBU.js +0 -25
  61. package/dist/chunk-AT6V3SY7.js +0 -102
  62. package/dist/chunk-B2IROPQF.js +0 -1844
  63. package/dist/chunk-CZULM42S.js +0 -143
  64. package/dist/chunk-GFY5FRX3.js +0 -218
  65. package/dist/chunk-HCLVYZUZ.js +0 -244
  66. package/dist/chunk-LE74UEV7.js +0 -1071
  67. package/dist/chunk-LIRAHP7B.js +0 -53
  68. package/dist/chunk-MZRJR2CW.js +0 -776
  69. package/dist/chunk-OFVV37XC.js +0 -57
  70. package/dist/chunk-PAIM66YA.js +0 -347
  71. package/dist/chunk-UOCZXO2Z.js +0 -1663
  72. package/dist/memory-credit-ledger-W2BAUYJP.js +0 -12
  73. package/dist/tempo-lifecycle-ZBBLFBMH.js +0 -15
  74. package/dist/tempo-wallet-B5XXV3YH.js +0 -40
@@ -1,4 +1,4 @@
1
- import { b as JobStore, J as JobRecord } from './job-store-BVeF5_Jq.js';
1
+ import { b as JobStore, J as JobRecord } from './job-store-BJRlmq2Q.js';
2
2
 
3
3
  /** Authenticated caller metadata; omitted fields on older services mean unknown. */
4
4
  interface JobContentMetadata {
@@ -10,12 +10,11 @@ import {
10
10
  isDrainMethod,
11
11
  isFundingRail,
12
12
  x402SettlementPending
13
- } from "./chunk-JH3SX3LY.js";
13
+ } from "./chunk-SPYEJXI7.js";
14
+ import "./chunk-TRNMTTPX.js";
15
+ import "./chunk-BPYMEMQX.js";
16
+ import "./chunk-LAKP6FUI.js";
14
17
  import "./chunk-COYKJRMM.js";
15
- import "./chunk-P6QON7ER.js";
16
- import "./chunk-RLTSCKRI.js";
17
- import "./chunk-LIRAHP7B.js";
18
- import "./chunk-ETXDTUJO.js";
19
18
  export {
20
19
  CreditLedger,
21
20
  CreditLedgerError,
@@ -1,11 +1,11 @@
1
- import { g as LockPubkey, f as CheckMintHealthOptions, b as LightningBackend, A as AttestationPayload } from './lightning-backend-40fIzz1W.js';
2
- import { cf as HostingCleanupFence, cV as HostedIntent, ah as FundingMethod, o as PaymentMethod, bN as CreditLedgerLike, a1 as Message, X as FundingReceipt, bP as CreditSnapshot, Y as JobReceipt, S as SDKJobContext, aw as StepCache, u as ResponseContent, P as PaymentContent, a2 as MessageType, bj as X402Receipt, aE as X402Config, bi as X402ExactVersionSupport, cW as X402SettlementIntent, aq as PaymentRequirementsV2, cX as HostedFundingReservation, c2 as CreditLedgerQuerier, cY as X402SettlementCursor, bR as X402SettlementStatus, cZ as X402SettlementWriteOff, bO as X402RefundSettlementGate, c_ as X402FacilitatorAuth, c$ as X402BatchSettlementConfig, cB as PostgresX402ChannelStorage, d0 as X402PayoutObserver, bL as HostedSettlementReportObligations, br as MppxServer, ac as CashuMode, d1 as CreditDepositEnqueue, d2 as X402SettlementReconciliationReason, ao as PaymentRequirements, a0 as MppxCredential, bm as CreditDepositPayload, bQ as DrawResult, cp as CreditLedgerError, a7 as ReceiptCredit, ae as DrainReceiptEvent, a6 as DrainReceipt, K as KVStore, y as SignedRequestAudience, d3 as CreditDrawReleaseEnqueue, cz as JobCostReportPayload, cA as JobTerminalReportPayload, cD as RevenueSkippedNoRailPayload, Z as ZodLike, a as DVMDescriptor, bW as CreditInvoiceRecord, bX as InvoiceSettlement, cj as ClientCompatibilityGate, ch as ClientCompatibility, bv as PostgresTempoSessionStore, bu as PayoutReporter, R as ResolvedCreditConfig, g as CreditView } from './step-cache-CPdH1hei.js';
1
+ import { f as LockPubkey, e as CheckMintHealthOptions, b as LightningBackend, A as AttestationPayload } from './lightning-backend-f16-fsYK.js';
2
+ import { cf as HostingCleanupFence, cV as HostedIntent, ai as FundingMethod, o as PaymentMethod, bN as CreditLedgerLike, a4 as Message, _ as FundingReceipt, bP as CreditSnapshot, $ as JobReceipt, S as SDKJobContext, aw as StepCache, u as ResponseContent, P as PaymentContent, a0 as MessageType, bj as X402Receipt, aE as X402Config, bi as X402ExactVersionSupport, cW as X402SettlementIntent, aa as PaymentRequirementsV2, cX as HostedFundingReservation, c2 as CreditLedgerQuerier, cY as X402SettlementCursor, bR as X402SettlementStatus, cZ as X402SettlementWriteOff, bO as X402RefundSettlementGate, c_ as X402FacilitatorAuth, c$ as X402BatchSettlementConfig, cB as PostgresX402ChannelStorage, d0 as X402PayoutObserver, bL as HostedSettlementReportObligations, br as MppxServer, ad as CashuMode, d1 as CreditDepositEnqueue, d2 as X402SettlementReconciliationReason, ap as PaymentRequirements, a2 as MppxCredential, bm as CreditDepositPayload, bQ as DrawResult, cp as CreditLedgerError, a6 as ReceiptCredit, af as DrainReceiptEvent, a7 as DrainReceipt, K as KVStore, y as SignedRequestAudience, d3 as CreditDrawReleaseEnqueue, cz as JobCostReportPayload, cA as JobTerminalReportPayload, cD as RevenueSkippedNoRailPayload, Z as ZodLike, a as DVMDescriptor, bW as CreditInvoiceRecord, bX as InvoiceSettlement, cj as ClientCompatibilityGate, ch as ClientCompatibility, bv as PostgresTempoSessionStore, bu as PayoutReporter, R as ResolvedCreditConfig, g as CreditView } from './step-cache-CJFiZU3n.js';
3
3
  import { ProofLike, SerializedDLEQ, Proof } from '@cashu/cashu-ts';
4
4
  import { Hono, Context } from 'hono';
5
5
  import { Pool } from 'pg';
6
- import { b as FxRateSnapshot, F as FxFetcher } from './fx-BgDmyTdd.js';
6
+ import { b as FxRateSnapshot, F as FxFetcher } from './fx-DSOZQ2z7.js';
7
7
  import { Store, Challenge } from 'mppx';
8
- import { T as TopUpCapUnenforcedReason, A as AppendOutgoingOptions, J as JobRecord, b as JobStore } from './job-store-BVeF5_Jq.js';
8
+ import { T as TopUpCapUnenforcedReason, A as AppendOutgoingOptions, J as JobRecord, b as JobStore } from './job-store-BJRlmq2Q.js';
9
9
  import { SettleResponse, SupportedResponse } from '@x402/core/types';
10
10
  import { Channel, AutoSettlementConfig } from '@x402/evm/batch-settlement/server';
11
11
  import { FacilitatorClient } from '@x402/core/server';
@@ -1,4 +1,4 @@
1
- import { C as Currency } from './step-cache-CPdH1hei.js';
1
+ import { C as Currency } from './step-cache-CJFiZU3n.js';
2
2
 
3
3
  /**
4
4
  * Quote-time FX snapshot. `rates` maps configured lowercase currency codes to
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as Currency, Z as ZodLike, D as DVMConfig, a as DVMDescriptor } from './step-cache-CPdH1hei.js';
2
- export { A as ApprovalContent, b as ArtifactContent, c as CancelContent, d as CanonicalEnvelope, e as CreateSignedRequestVerifierOpts, f as CreditConfig, g as CreditView, h as DEFAULT_CREDIT_MAX, i as DEFAULT_CREDIT_MIN, j as DEFAULT_CREDIT_TTL_SECONDS, k as DEFAULT_JOB_RETENTION_DAYS, l as DVMRouteContext, I as IncomingMessage, m as InputType, n as InvalidCurrencyError, J as JobCost, K as KVStore, L as Logger, P as PaymentContent, o as PaymentMethod, p as PriceValue, q as ProgressContent, r as PromptOpts, Q as QuoteConfig, s as QuoteContext, t as QuoteResult, R as ResolvedCreditConfig, u as ResponseContent, S as SDKJobContext, v as SDKPaymentRequestOpts, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, y as SignedRequestAudience, z as SignedRequestDomain, B as SignedRequestError, E as SignedRequestFailure, F as SignedRequestReplayStore, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, U as UnsupportedCurrencyError, N as createSignedRequestVerifier, O as isZodSchema, T as signedRequestStatementHeader, V as validateCurrency } from './step-cache-CPdH1hei.js';
3
- export { C as CreateFxFetcherOpts, D as DEFAULT_FX_CURRENCIES, a as DEFAULT_FX_RATE_SOURCE, F as FxFetcher, b as FxRateSnapshot, c as FxRateUnavailableError, P as PlatformFxSource, d as createFxFetcher, f as fxRateFor, r as resolveFxSourceFromEnv } from './fx-BgDmyTdd.js';
4
- export { I as InvalidFxRateError, f as fiatToSatsCeil, a as formatFiat, b as formatUsd, r as roundUsd, s as satsToFiat } from './usd-AWlrwlM5.js';
5
- export { J as JobRecord, a as JobStatus, b as JobStore } from './job-store-BVeF5_Jq.js';
1
+ import { C as Currency, Z as ZodLike, D as DVMConfig, a as DVMDescriptor } from './step-cache-CJFiZU3n.js';
2
+ export { A as ApprovalContent, b as ArtifactContent, c as CancelContent, d as CanonicalEnvelope, e as CreateSignedRequestVerifierOpts, f as CreditConfig, g as CreditView, h as DEFAULT_CREDIT_MAX, i as DEFAULT_CREDIT_MIN, j as DEFAULT_CREDIT_TTL_SECONDS, k as DEFAULT_JOB_RETENTION_DAYS, l as DVMRouteContext, I as IncomingMessage, m as InputType, n as InvalidCurrencyError, J as JobCost, K as KVStore, L as Logger, P as PaymentContent, o as PaymentMethod, p as PriceValue, q as ProgressContent, r as PromptOpts, Q as QuoteConfig, s as QuoteContext, t as QuoteResult, R as ResolvedCreditConfig, u as ResponseContent, S as SDKJobContext, v as SDKPaymentRequestOpts, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, y as SignedRequestAudience, z as SignedRequestDomain, B as SignedRequestError, E as SignedRequestFailure, F as SignedRequestReplayStore, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, U as UnsupportedCurrencyError, N as createSignedRequestVerifier, O as isZodSchema, T as signedRequestStatementHeader, V as validateCurrency } from './step-cache-CJFiZU3n.js';
3
+ export { C as CreateFxFetcherOpts, D as DEFAULT_FX_CURRENCIES, a as DEFAULT_FX_RATE_SOURCE, F as FxFetcher, b as FxRateSnapshot, c as FxRateUnavailableError, P as PlatformFxSource, d as createFxFetcher, f as fxRateFor, r as resolveFxSourceFromEnv } from './fx-DSOZQ2z7.js';
4
+ export { I as InvalidFxRateError, f as fiatToSatsCeil, a as formatFiat, b as formatUsd, r as roundUsd, s as satsToFiat } from './usd-DmHHg0_4.js';
5
+ export { J as JobRecord, a as JobStatus, b as JobStore } from './job-store-BJRlmq2Q.js';
6
6
  export { P as PinnedFetch, S as SSRFError, a as SSRFGuardOpts, b as SSRFReason, c as SSRFResolver, d as assertSafeUrl, e as createPinnedFetch } from './ssrf-dMooihtY.js';
7
7
  export { z } from 'zod';
8
8
  import 'hono';
package/dist/index.js CHANGED
@@ -5,13 +5,12 @@ import {
5
5
  envFlag
6
6
  } from "./chunk-TVI4V7GF.js";
7
7
  import {
8
- configureDVM,
9
- isConfiguredDVMDescriptor
10
- } from "./chunk-HCLVYZUZ.js";
8
+ CAPABILITY_NAME_RE
9
+ } from "./chunk-A262WVYX.js";
11
10
  import {
12
11
  SignedRequestError,
13
12
  createSignedRequestVerifier
14
- } from "./chunk-N5RZ5HVB.js";
13
+ } from "./chunk-72V5DTEC.js";
15
14
  import {
16
15
  DEFAULT_CREDIT_MAX,
17
16
  DEFAULT_CREDIT_MIN,
@@ -21,29 +20,250 @@ import {
21
20
  SIGNED_REQUEST_STATEMENT_VERSION,
22
21
  isZodSchema,
23
22
  signedRequestStatementHeader
24
- } from "./chunk-RCM3P2HE.js";
25
- import "./chunk-OFVV37XC.js";
23
+ } from "./chunk-UKD3R2KU.js";
24
+ import {
25
+ buildUpfront
26
+ } from "./chunk-USL7ZEXN.js";
26
27
  import {
27
28
  DEFAULT_FX_CURRENCIES,
28
29
  DEFAULT_FX_RATE_SOURCE,
29
30
  FxRateUnavailableError,
30
31
  InvalidCurrencyError,
32
+ InvalidFxRateError,
31
33
  UnsupportedCurrencyError,
32
- buildUpfront,
33
34
  createFxFetcher,
34
- fxRateFor,
35
- resolveFxSourceFromEnv,
36
- validateCurrency
37
- } from "./chunk-BYCEKO65.js";
38
- import {
39
- InvalidFxRateError,
40
35
  fiatToSatsCeil,
41
36
  formatFiat,
42
37
  formatUsd,
38
+ fxRateFor,
39
+ parseUsdPrice,
40
+ resolveFxSourceFromEnv,
43
41
  roundUsd,
44
- satsToFiat
45
- } from "./chunk-AT6V3SY7.js";
46
- import "./chunk-ETXDTUJO.js";
42
+ satsToFiat,
43
+ validateCurrency
44
+ } from "./chunk-CLIAFTUR.js";
45
+ import "./chunk-LAKP6FUI.js";
46
+
47
+ // src/sdk/configure.ts
48
+ function configureDVM(config) {
49
+ const tags = collectTags(config);
50
+ const currency = resolvePricingCurrency(config.currency);
51
+ const capabilities = buildCapabilityMap(config, currency);
52
+ const jobRetentionDays = resolveJobRetentionDays(config.jobRetentionDays);
53
+ const onlyCapability = singleCapabilityEntry(capabilities);
54
+ const descriptor = {
55
+ name: config.name,
56
+ description: config.description ?? "",
57
+ tags,
58
+ currency,
59
+ price: onlyCapability?.price,
60
+ inputSchema: onlyCapability?.input,
61
+ state: onlyCapability?.state ?? {},
62
+ idleTimeout: config.idleTimeout ?? 3600,
63
+ processingWatchdog: config.processingWatchdog,
64
+ jobRetentionDays,
65
+ config,
66
+ capabilities,
67
+ paymentMethods: config.paymentMethods,
68
+ x402: config.x402,
69
+ mpp: config.mpp,
70
+ credit: resolveCreditConfig(config.credit),
71
+ auth: config.auth
72
+ };
73
+ CONFIGURED_DVM_DESCRIPTORS.add(descriptor);
74
+ return Object.freeze(descriptor);
75
+ }
76
+ function resolveJobRetentionDays(raw) {
77
+ const days = raw ?? DEFAULT_JOB_RETENTION_DAYS;
78
+ if (!Number.isSafeInteger(days) || days < 0 || days > Math.floor((Number.MAX_SAFE_INTEGER - Date.now()) / 864e5)) {
79
+ throw new Error(
80
+ `configureDVM: jobRetentionDays must be a non-negative whole number of days; received ${JSON.stringify(raw)}`
81
+ );
82
+ }
83
+ return days;
84
+ }
85
+ function isConfiguredDVMDescriptor(value) {
86
+ return typeof value === "object" && value !== null && CONFIGURED_DVM_DESCRIPTORS.has(value);
87
+ }
88
+ var CONFIGURED_DVM_DESCRIPTORS = /* @__PURE__ */ new WeakSet();
89
+ function resolvePricingCurrency(raw) {
90
+ if (raw === void 0) return "usd";
91
+ try {
92
+ return validateCurrency(raw);
93
+ } catch (err) {
94
+ if (err instanceof InvalidCurrencyError) {
95
+ throw new Error(
96
+ `configureDVM: currency ${JSON.stringify(raw)} is not an ISO 4217 lowercase code like "usd" or "eur". Omit the field to price in USD.`,
97
+ { cause: err }
98
+ );
99
+ }
100
+ throw err;
101
+ }
102
+ }
103
+ function resolveCreditConfig(credit) {
104
+ if (!credit) return void 0;
105
+ const min = credit.min ?? DEFAULT_CREDIT_MIN;
106
+ const max = credit.max ?? DEFAULT_CREDIT_MAX;
107
+ const ttlSeconds = credit.ttl ?? DEFAULT_CREDIT_TTL_SECONDS;
108
+ const minAmount = validatePriceLiteral(min, "credit.min");
109
+ const maxAmount = validatePriceLiteral(max, "credit.max");
110
+ if (minAmount > maxAmount) {
111
+ throw new Error(
112
+ `credit.min (${JSON.stringify(min)}) exceeds credit.max (${JSON.stringify(max)}) \u2014 no funding amount could satisfy both.`
113
+ );
114
+ }
115
+ if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {
116
+ throw new Error(`credit.ttl must be a positive number of seconds (got ${ttlSeconds}).`);
117
+ }
118
+ const allowOneShotStablecoin = credit.allowOneShotStablecoin === true;
119
+ return { min, max, ttlSeconds, allowOneShotStablecoin };
120
+ }
121
+ function validatePriceLiteral(value, field, key = field) {
122
+ if (typeof value === "number") {
123
+ throw new Error(
124
+ `${field} is a number (${value}). Prices are USD literals \u2014 write ${key}: "$0.01" for one cent. Callers still pay in sats; the SDK converts at request time. Omit the field for a free capability, or use \`onQuote\` for dynamic pricing.`
125
+ );
126
+ }
127
+ if (typeof value !== "string") {
128
+ throw new Error(`${field} must be a USD literal like "$0.05" (got ${JSON.stringify(value)}).`);
129
+ }
130
+ return parseUsdPrice(value, field);
131
+ }
132
+ function validateCapabilityPrice(price, capabilityName, currency) {
133
+ if (price === void 0) return;
134
+ if (currency !== "usd") {
135
+ throw new Error(
136
+ `configureDVM: capability "${capabilityName}" declares a static price (${JSON.stringify(price)}) but this DVM prices in ${currency}. Static prices are USD literals, so they cannot express ${currency} \u2014 price this capability with \`onQuote\` returning { amount, currency: ${JSON.stringify(currency)} }, or drop the DVM-level \`currency\` to price in USD.`
137
+ );
138
+ }
139
+ validatePriceLiteral(price, `configureDVM: capability "${capabilityName}" price`, "price");
140
+ }
141
+ function collectTags(config) {
142
+ const tagSet = /* @__PURE__ */ new Set();
143
+ if (config.tag) tagSet.add(config.tag);
144
+ if (config.tags) {
145
+ for (const t of config.tags) tagSet.add(t);
146
+ }
147
+ return [...tagSet];
148
+ }
149
+ function buildCapabilityMap(config, currency) {
150
+ const hasExplicitBlock = config.capabilities !== void 0;
151
+ const hasFlatCapabilityName = typeof config.capability === "string";
152
+ const hasFlatHandler = typeof config.onJob === "function";
153
+ if (hasExplicitBlock && (hasFlatCapabilityName || hasFlatHandler || flatPerCapFieldsSet(config))) {
154
+ throw new Error(
155
+ "configureDVM: pass either the flat single-capability shape (capability + onJob + ...) or the explicit `capabilities` block, not both."
156
+ );
157
+ }
158
+ if (hasExplicitBlock) {
159
+ return buildExplicitCapabilities(config.capabilities ?? {}, currency);
160
+ }
161
+ if (!hasFlatHandler) {
162
+ throw new Error("configureDVM: onJob handler is required");
163
+ }
164
+ const name = typeof config.capability === "string" ? config.capability : slugifyCapabilityName(config.name);
165
+ validateCapabilityName(name);
166
+ validateCapabilityPrice(config.price, name, currency);
167
+ validateExampleAgainstInput(name, config.input, config.example);
168
+ const entry = {
169
+ name,
170
+ description: config.description ?? "",
171
+ input: config.input,
172
+ example: config.example,
173
+ state: config.state ?? {},
174
+ price: config.price,
175
+ onQuote: config.onQuote,
176
+ onJob: config.onJob,
177
+ onResponse: config.onResponse,
178
+ onPayment: config.onPayment,
179
+ onApproval: config.onApproval,
180
+ onCancel: config.onCancel,
181
+ onMessage: config.onMessage
182
+ };
183
+ return { [name]: entry };
184
+ }
185
+ function buildExplicitCapabilities(capabilities, currency) {
186
+ const keys = Object.keys(capabilities);
187
+ if (keys.length === 0) {
188
+ throw new Error("configureDVM: `capabilities` block must declare at least one capability");
189
+ }
190
+ const out = {};
191
+ for (const name of keys) {
192
+ validateCapabilityName(name);
193
+ const cap = capabilities[name];
194
+ if (typeof cap.onJob !== "function") {
195
+ throw new Error(`configureDVM: capability "${name}" is missing required onJob handler`);
196
+ }
197
+ validateCapabilityPrice(cap.price, name, currency);
198
+ validateExampleAgainstInput(name, cap.input, cap.example);
199
+ const entry = {
200
+ name,
201
+ description: cap.description ?? "",
202
+ // Per-capability `input` is the builder's Zod schema; the `any` widening
203
+ // through `Record<string, CapabilityConfig<any, any>>` is unavoidable
204
+ // here.
205
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
206
+ input: cap.input,
207
+ example: cap.example,
208
+ state: cap.state !== void 0 ? structuredClone(cap.state) : {},
209
+ price: cap.price,
210
+ onQuote: cap.onQuote,
211
+ onJob: cap.onJob,
212
+ onResponse: cap.onResponse,
213
+ onPayment: cap.onPayment,
214
+ onApproval: cap.onApproval,
215
+ onCancel: cap.onCancel,
216
+ onMessage: cap.onMessage
217
+ };
218
+ out[name] = entry;
219
+ }
220
+ return out;
221
+ }
222
+ function flatPerCapFieldsSet(config) {
223
+ return config.input !== void 0 || config.example !== void 0 || config.state !== void 0 || config.price !== void 0 || config.onQuote !== void 0 || typeof config.onResponse === "function" || typeof config.onPayment === "function" || typeof config.onApproval === "function" || typeof config.onCancel === "function" || typeof config.onMessage === "function";
224
+ }
225
+ function validateExampleAgainstInput(capName, input, example) {
226
+ if (example === void 0) return;
227
+ if (!isZodSchema(input)) return;
228
+ const result = input.safeParse(example);
229
+ if (result.success) return;
230
+ throw new Error(
231
+ `configureDVM: capability "${capName}" example does not satisfy its input schema. Update the example to match the schema (including any \`.refine()\` checks). Issues: ${formatZodIssues(result.error)}`
232
+ );
233
+ }
234
+ function formatZodIssues(err) {
235
+ if (err && typeof err === "object" && "issues" in err && Array.isArray(err.issues)) {
236
+ const issues = err.issues;
237
+ if (issues.length === 0) return "(no issues reported)";
238
+ return issues.map((issue) => {
239
+ const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
240
+ return `${path}: ${issue.message}`;
241
+ }).join("; ");
242
+ }
243
+ if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
244
+ return err.message.replace(/\s+/g, " ").trim();
245
+ }
246
+ try {
247
+ return JSON.stringify(err);
248
+ } catch {
249
+ return String(err);
250
+ }
251
+ }
252
+ function validateCapabilityName(name) {
253
+ if (!CAPABILITY_NAME_RE.test(name)) {
254
+ throw new Error(
255
+ `configureDVM: invalid capability name "${name}" \u2014 must be lowercase letters/digits/hyphens, must start with a letter or digit, must not contain slashes.`
256
+ );
257
+ }
258
+ }
259
+ function slugifyCapabilityName(name) {
260
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
261
+ }
262
+ function singleCapabilityEntry(capabilities) {
263
+ const keys = Object.keys(capabilities);
264
+ if (keys.length !== 1) return void 0;
265
+ return capabilities[keys[0]];
266
+ }
47
267
 
48
268
  // src/sdk/heartbeat.ts
49
269
  async function withProgressHeartbeat(opts, fn) {