@dvmkit/sdk 0.1.0-rc.2 → 0.1.0-rc.4
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 +10 -2
- package/dist/{revenue-reporter-GB4WKLDC.js → chunk-2ABMGUDS.js} +1 -0
- package/dist/chunk-2K6UXDAN.js +1557 -0
- package/dist/chunk-4UVRXDNY.js +21745 -0
- package/dist/chunk-66HGCPBU.js +25 -0
- package/dist/{chunk-DCNT4PJS.js → chunk-AAJNGQMC.js} +6 -258
- package/dist/{chunk-KQAJVVZT.js → chunk-AZBXSXQT.js} +27 -287
- package/dist/{chunk-H25M54MI.js → chunk-C3MTFLC6.js} +16 -0
- package/dist/chunk-EDU6COY2.js +1057 -0
- package/dist/{chunk-OJ5WFIB2.js → chunk-EXHBXA4U.js} +1 -1
- package/dist/chunk-F2L6KIMD.js +380 -0
- package/dist/{chunk-KXWROQGK.js → chunk-FUJ36YDV.js} +1 -24
- package/dist/chunk-GJD7PVWY.js +1090 -0
- package/dist/{tempo-charge-store-6GJEMNUU.js → chunk-JZWELPFH.js} +1 -0
- package/dist/{chunk-365P52XQ.js → chunk-LWUR4CGG.js} +2 -1
- package/dist/{tempo-session-store-FTEEGZXA.js → chunk-RU7SXHLO.js} +2 -1
- package/dist/{chunk-7IH5SG2A.js → chunk-TKA6ZP4M.js} +62 -41
- package/dist/chunk-TVI4V7GF.js +283 -0
- package/dist/{payout-reporter-4TNWRS5F.js → chunk-X3IKFWJA.js} +3 -2
- package/dist/chunk-XYTSDAPH.js +232 -0
- package/dist/{credit-ledger-RO4FGSHG.js → credit-ledger-ED6JXKVD.js} +2 -2
- package/dist/credit-menu-ClA1JyYW.d.ts +5076 -0
- package/dist/{ssrf-DZi-xJyn.d.ts → fx-ptKVFOwq.d.ts} +37 -119
- package/dist/index.d.ts +8 -66
- package/dist/index.js +11 -219
- package/dist/internal/index.d.ts +5896 -0
- package/dist/internal/index.js +6407 -0
- package/dist/{job-store-6gR4pZRP.d.ts → job-store-DxFqDPYq.d.ts} +1498 -12
- package/dist/{memory-credit-ledger-I2G64DDK.js → memory-credit-ledger-XJ5VQEVP.js} +3 -3
- package/dist/payout-reporter-3UB5WRCV.js +13 -0
- package/dist/revenue-reporter-JIKUPXOK.js +7 -0
- package/dist/server/index.d.ts +14 -3590
- package/dist/server/index.js +155 -20850
- package/dist/ssrf-DbFkpDv0.d.ts +118 -0
- package/dist/tempo-charge-store-RIFTALZK.js +8 -0
- package/dist/tempo-session-store-DALMRIWN.js +11 -0
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +3 -2
- package/dist/usd-Cha_j80I.d.ts +97 -0
- package/dist/x402-XXFQQAAD.js +81 -0
- package/package.json +6 -2
- package/dist/x402-35VLYFKZ.js +0 -1272
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_CREDIT_MAX,
|
|
3
|
+
DEFAULT_CREDIT_MIN,
|
|
4
|
+
DEFAULT_CREDIT_TTL_SECONDS,
|
|
5
|
+
isZodSchema
|
|
6
|
+
} from "./chunk-AZBXSXQT.js";
|
|
7
|
+
import {
|
|
8
|
+
InvalidCurrencyError,
|
|
9
|
+
validateCurrency
|
|
10
|
+
} from "./chunk-27V2ILSR.js";
|
|
11
|
+
import {
|
|
12
|
+
parseUsdPrice
|
|
13
|
+
} from "./chunk-AT6V3SY7.js";
|
|
14
|
+
|
|
15
|
+
// src/lib/wire-schema.ts
|
|
16
|
+
var CAPABILITY_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
17
|
+
|
|
18
|
+
// src/sdk/configure.ts
|
|
19
|
+
function configureDVM(config) {
|
|
20
|
+
const tags = collectTags(config);
|
|
21
|
+
const currency = resolvePricingCurrency(config.currency);
|
|
22
|
+
const capabilities = buildCapabilityMap(config, currency);
|
|
23
|
+
const onlyCapability = singleCapabilityEntry(capabilities);
|
|
24
|
+
const descriptor = {
|
|
25
|
+
name: config.name,
|
|
26
|
+
description: config.description ?? "",
|
|
27
|
+
tags,
|
|
28
|
+
currency,
|
|
29
|
+
price: onlyCapability?.price,
|
|
30
|
+
inputSchema: onlyCapability?.input,
|
|
31
|
+
state: onlyCapability?.state ?? {},
|
|
32
|
+
idleTimeout: config.idleTimeout ?? 3600,
|
|
33
|
+
processingWatchdog: config.processingWatchdog,
|
|
34
|
+
config,
|
|
35
|
+
capabilities,
|
|
36
|
+
paymentMethods: config.paymentMethods,
|
|
37
|
+
x402: config.x402,
|
|
38
|
+
mpp: config.mpp,
|
|
39
|
+
credit: resolveCreditConfig(config.credit),
|
|
40
|
+
auth: config.auth
|
|
41
|
+
};
|
|
42
|
+
CONFIGURED_DVM_DESCRIPTORS.add(descriptor);
|
|
43
|
+
return Object.freeze(descriptor);
|
|
44
|
+
}
|
|
45
|
+
function isConfiguredDVMDescriptor(value) {
|
|
46
|
+
return typeof value === "object" && value !== null && CONFIGURED_DVM_DESCRIPTORS.has(value);
|
|
47
|
+
}
|
|
48
|
+
var CONFIGURED_DVM_DESCRIPTORS = /* @__PURE__ */ new WeakSet();
|
|
49
|
+
function resolvePricingCurrency(raw) {
|
|
50
|
+
if (raw === void 0) return "usd";
|
|
51
|
+
try {
|
|
52
|
+
return validateCurrency(raw);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (err instanceof InvalidCurrencyError) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
`configureDVM: currency ${JSON.stringify(raw)} is not an ISO 4217 lowercase code like "usd" or "eur". Omit the field to price in USD.`,
|
|
57
|
+
{ cause: err }
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function resolveCreditConfig(credit) {
|
|
64
|
+
if (!credit) return void 0;
|
|
65
|
+
const min = credit.min ?? DEFAULT_CREDIT_MIN;
|
|
66
|
+
const max = credit.max ?? DEFAULT_CREDIT_MAX;
|
|
67
|
+
const ttlSeconds = credit.ttl ?? DEFAULT_CREDIT_TTL_SECONDS;
|
|
68
|
+
const minAmount = validatePriceLiteral(min, "credit.min");
|
|
69
|
+
const maxAmount = validatePriceLiteral(max, "credit.max");
|
|
70
|
+
if (minAmount > maxAmount) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`credit.min (${JSON.stringify(min)}) exceeds credit.max (${JSON.stringify(max)}) \u2014 no funding amount could satisfy both.`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {
|
|
76
|
+
throw new Error(`credit.ttl must be a positive number of seconds (got ${ttlSeconds}).`);
|
|
77
|
+
}
|
|
78
|
+
const allowOneShotStablecoin = credit.allowOneShotStablecoin === true;
|
|
79
|
+
return { min, max, ttlSeconds, allowOneShotStablecoin };
|
|
80
|
+
}
|
|
81
|
+
function validatePriceLiteral(value, field, key = field) {
|
|
82
|
+
if (typeof value === "number") {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`${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.`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (typeof value !== "string") {
|
|
88
|
+
throw new Error(`${field} must be a USD literal like "$0.05" (got ${JSON.stringify(value)}).`);
|
|
89
|
+
}
|
|
90
|
+
return parseUsdPrice(value, field);
|
|
91
|
+
}
|
|
92
|
+
function validateCapabilityPrice(price, capabilityName, currency) {
|
|
93
|
+
if (price === void 0) return;
|
|
94
|
+
if (currency !== "usd") {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`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.`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
validatePriceLiteral(price, `configureDVM: capability "${capabilityName}" price`, "price");
|
|
100
|
+
}
|
|
101
|
+
function collectTags(config) {
|
|
102
|
+
const tagSet = /* @__PURE__ */ new Set();
|
|
103
|
+
if (config.tag) tagSet.add(config.tag);
|
|
104
|
+
if (config.tags) {
|
|
105
|
+
for (const t of config.tags) tagSet.add(t);
|
|
106
|
+
}
|
|
107
|
+
return [...tagSet];
|
|
108
|
+
}
|
|
109
|
+
function buildCapabilityMap(config, currency) {
|
|
110
|
+
const hasExplicitBlock = config.capabilities !== void 0;
|
|
111
|
+
const hasFlatCapabilityName = typeof config.capability === "string";
|
|
112
|
+
const hasFlatHandler = typeof config.onJob === "function";
|
|
113
|
+
if (hasExplicitBlock && (hasFlatCapabilityName || hasFlatHandler || flatPerCapFieldsSet(config))) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
"configureDVM: pass either the flat single-capability shape (capability + onJob + ...) or the explicit `capabilities` block, not both."
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
if (hasExplicitBlock) {
|
|
119
|
+
return buildExplicitCapabilities(config.capabilities ?? {}, currency);
|
|
120
|
+
}
|
|
121
|
+
if (!hasFlatHandler) {
|
|
122
|
+
throw new Error("configureDVM: onJob handler is required");
|
|
123
|
+
}
|
|
124
|
+
const name = typeof config.capability === "string" ? config.capability : slugifyCapabilityName(config.name);
|
|
125
|
+
validateCapabilityName(name);
|
|
126
|
+
validateCapabilityPrice(config.price, name, currency);
|
|
127
|
+
validateExampleAgainstInput(name, config.input, config.example);
|
|
128
|
+
const entry = {
|
|
129
|
+
name,
|
|
130
|
+
description: config.description ?? "",
|
|
131
|
+
input: config.input,
|
|
132
|
+
example: config.example,
|
|
133
|
+
state: config.state ?? {},
|
|
134
|
+
price: config.price,
|
|
135
|
+
onQuote: config.onQuote,
|
|
136
|
+
onJob: config.onJob,
|
|
137
|
+
onResponse: config.onResponse,
|
|
138
|
+
onPayment: config.onPayment,
|
|
139
|
+
onApproval: config.onApproval,
|
|
140
|
+
onCancel: config.onCancel,
|
|
141
|
+
onMessage: config.onMessage
|
|
142
|
+
};
|
|
143
|
+
return { [name]: entry };
|
|
144
|
+
}
|
|
145
|
+
function buildExplicitCapabilities(capabilities, currency) {
|
|
146
|
+
const keys = Object.keys(capabilities);
|
|
147
|
+
if (keys.length === 0) {
|
|
148
|
+
throw new Error("configureDVM: `capabilities` block must declare at least one capability");
|
|
149
|
+
}
|
|
150
|
+
const out = {};
|
|
151
|
+
for (const name of keys) {
|
|
152
|
+
validateCapabilityName(name);
|
|
153
|
+
const cap = capabilities[name];
|
|
154
|
+
if (typeof cap.onJob !== "function") {
|
|
155
|
+
throw new Error(`configureDVM: capability "${name}" is missing required onJob handler`);
|
|
156
|
+
}
|
|
157
|
+
validateCapabilityPrice(cap.price, name, currency);
|
|
158
|
+
validateExampleAgainstInput(name, cap.input, cap.example);
|
|
159
|
+
const entry = {
|
|
160
|
+
name,
|
|
161
|
+
description: cap.description ?? "",
|
|
162
|
+
// Per-capability `input` is the builder's Zod schema; the `any` widening
|
|
163
|
+
// through `Record<string, CapabilityConfig<any, any>>` is unavoidable
|
|
164
|
+
// here.
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
166
|
+
input: cap.input,
|
|
167
|
+
example: cap.example,
|
|
168
|
+
state: cap.state !== void 0 ? structuredClone(cap.state) : {},
|
|
169
|
+
price: cap.price,
|
|
170
|
+
onQuote: cap.onQuote,
|
|
171
|
+
onJob: cap.onJob,
|
|
172
|
+
onResponse: cap.onResponse,
|
|
173
|
+
onPayment: cap.onPayment,
|
|
174
|
+
onApproval: cap.onApproval,
|
|
175
|
+
onCancel: cap.onCancel,
|
|
176
|
+
onMessage: cap.onMessage
|
|
177
|
+
};
|
|
178
|
+
out[name] = entry;
|
|
179
|
+
}
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
182
|
+
function flatPerCapFieldsSet(config) {
|
|
183
|
+
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";
|
|
184
|
+
}
|
|
185
|
+
function validateExampleAgainstInput(capName, input, example) {
|
|
186
|
+
if (example === void 0) return;
|
|
187
|
+
if (!isZodSchema(input)) return;
|
|
188
|
+
const result = input.safeParse(example);
|
|
189
|
+
if (result.success) return;
|
|
190
|
+
throw new Error(
|
|
191
|
+
`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)}`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
function formatZodIssues(err) {
|
|
195
|
+
if (err && typeof err === "object" && "issues" in err && Array.isArray(err.issues)) {
|
|
196
|
+
const issues = err.issues;
|
|
197
|
+
if (issues.length === 0) return "(no issues reported)";
|
|
198
|
+
return issues.map((issue) => {
|
|
199
|
+
const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
200
|
+
return `${path}: ${issue.message}`;
|
|
201
|
+
}).join("; ");
|
|
202
|
+
}
|
|
203
|
+
if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
|
|
204
|
+
return err.message.replace(/\s+/g, " ").trim();
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
return JSON.stringify(err);
|
|
208
|
+
} catch {
|
|
209
|
+
return String(err);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function validateCapabilityName(name) {
|
|
213
|
+
if (!CAPABILITY_NAME_RE.test(name)) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`configureDVM: invalid capability name "${name}" \u2014 must be lowercase letters/digits/hyphens, must start with a letter or digit, must not contain slashes.`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function slugifyCapabilityName(name) {
|
|
220
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
221
|
+
}
|
|
222
|
+
function singleCapabilityEntry(capabilities) {
|
|
223
|
+
const keys = Object.keys(capabilities);
|
|
224
|
+
if (keys.length !== 1) return void 0;
|
|
225
|
+
return capabilities[keys[0]];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export {
|
|
229
|
+
CAPABILITY_NAME_RE,
|
|
230
|
+
configureDVM,
|
|
231
|
+
isConfiguredDVMDescriptor
|
|
232
|
+
};
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
isDrainMethod,
|
|
11
11
|
isFundingRail,
|
|
12
12
|
x402SettlementPending
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-LWUR4CGG.js";
|
|
14
|
+
import "./chunk-C3MTFLC6.js";
|
|
15
15
|
import "./chunk-S3XAHZQY.js";
|
|
16
16
|
export {
|
|
17
17
|
CreditLedger,
|