@dvmkit/sdk 0.1.1-rc.7 → 0.1.3-rc.7

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 (47) hide show
  1. package/README.md +14 -0
  2. package/dist/chunk-2K7E3N2D.js +1709 -0
  3. package/dist/{chunk-Y6W5ZZTW.js → chunk-3ZHMQCYP.js} +666 -3031
  4. package/dist/{chunk-TKA6ZP4M.js → chunk-4B56DEEV.js} +50 -426
  5. package/dist/{chunk-X3IKFWJA.js → chunk-6BQM7TOW.js} +4 -1
  6. package/dist/chunk-BIFLRKMO.js +87 -0
  7. package/dist/chunk-BQ2NMWKE.js +160 -0
  8. package/dist/{chunk-LDTWX7JW.js → chunk-BTZY7VPH.js} +13 -1
  9. package/dist/{chunk-FJDCFHW5.js → chunk-C6JHBLMW.js} +3 -81
  10. package/dist/{chunk-EXHBXA4U.js → chunk-DBCLBYHP.js} +13 -1
  11. package/dist/chunk-EPNDZ5DH.js +1010 -0
  12. package/dist/{chunk-P4RUVDU7.js → chunk-H2MEFVH6.js} +12 -141
  13. package/dist/chunk-KXZUCCEY.js +142 -0
  14. package/dist/{chunk-6JZIX5WW.js → chunk-LLXV32HA.js} +82 -5
  15. package/dist/{chunk-LWUR4CGG.js → chunk-MLRCSJYX.js} +11 -3
  16. package/dist/{chunk-2ABMGUDS.js → chunk-NFRM5QYP.js} +83 -10
  17. package/dist/chunk-RW5LP57K.js +44 -0
  18. package/dist/chunk-YDIYXGYL.js +384 -0
  19. package/dist/{chunk-JGGI65I3.js → chunk-Z4BNLUZF.js} +1 -150
  20. package/dist/{credit-ledger-ED6JXKVD.js → credit-ledger-2DFQHNLB.js} +2 -2
  21. package/dist/{credit-menu-BrTfAr7l.d.ts → credit-menu-C7zAJElJ.d.ts} +1632 -1946
  22. package/dist/{fx-H6K6qcH1.d.ts → fx-BF_SG2i0.d.ts} +1 -1
  23. package/dist/index.d.ts +7 -6
  24. package/dist/index.js +8 -4
  25. package/dist/internal/caller.d.ts +10429 -0
  26. package/dist/internal/caller.js +9957 -0
  27. package/dist/internal/index.d.ts +2 -10816
  28. package/dist/internal/index.js +2 -10130
  29. package/dist/internal/server.d.ts +404 -0
  30. package/dist/internal/server.js +202 -0
  31. package/dist/job-store-Bn23V3QU.d.ts +576 -0
  32. package/dist/lightning-backend-C04nH94l.d.ts +367 -0
  33. package/dist/{memory-credit-ledger-XJ5VQEVP.js → memory-credit-ledger-OP24Z2KO.js} +3 -3
  34. package/dist/{payout-reporter-3UB5WRCV.js → payout-reporter-RG6XNGPI.js} +1 -1
  35. package/dist/{postgres-job-store-J5F4GUWU.js → postgres-job-store-TAONYLIF.js} +1 -1
  36. package/dist/{revenue-reporter-JIKUPXOK.js → revenue-reporter-XXSU5KVB.js} +1 -1
  37. package/dist/server/index.d.ts +27 -11
  38. package/dist/server/index.js +93 -69
  39. package/dist/{job-store-DOSfYnLX.d.ts → step-cache-3cT4Shk0.d.ts} +38 -585
  40. package/dist/{tempo-session-store-DALMRIWN.js → tempo-session-store-2JNOKJGX.js} +2 -2
  41. package/dist/testing/index.d.ts +16 -4
  42. package/dist/testing/index.js +7 -3
  43. package/dist/{usd-Civ738b3.d.ts → usd-BnuXoFl5.d.ts} +1 -1
  44. package/dist/wallet-CJC8lwxx.d.ts +29 -0
  45. package/dist/{x402-FTG2GRAQ.js → x402-T2C5MX3T.js} +6 -3
  46. package/package.json +7 -2
  47. package/dist/{chunk-RU7SXHLO.js → chunk-UP2F5RRT.js} +3 -3
@@ -0,0 +1,160 @@
1
+ import {
2
+ X402_DEFAULT_FACILITATOR
3
+ } from "./chunk-Z4BNLUZF.js";
4
+ import {
5
+ callerLoggers
6
+ } from "./chunk-66HGCPBU.js";
7
+
8
+ // src/lib/x402/facilitator.ts
9
+ import { createPrivateKey, randomBytes } from "crypto";
10
+ import { HTTPFacilitatorClient } from "@x402/core/server";
11
+ import { importJWK, importPKCS8, SignJWT } from "jose";
12
+ var AUTH_HEADER_TTL_MS = 6e4;
13
+ var AUTH_TOKEN_TTL_SECONDS = 120;
14
+ var FACILITATOR_PATHS = {
15
+ verify: "POST",
16
+ settle: "POST",
17
+ supported: "GET"
18
+ };
19
+ function createX402FacilitatorAuthHeaders(config) {
20
+ const auth = config.facilitatorAuth;
21
+ if (!auth) return void 0;
22
+ const facilitator = new URL(config.facilitator ?? X402_DEFAULT_FACILITATOR);
23
+ const basePath = facilitator.pathname.replace(/\/+$/, "");
24
+ let cached;
25
+ return async () => {
26
+ const nowMs = Date.now();
27
+ if (cached && nowMs < cached.refreshAtMs) return cached.headers;
28
+ const entries = await Promise.all(
29
+ Object.entries(FACILITATOR_PATHS).map(async ([path, method]) => {
30
+ const requestPath = `${basePath}/${path}`;
31
+ const jwt = await generateCdpJwt(
32
+ auth.keyId,
33
+ auth.keySecret,
34
+ `${method} ${facilitator.host}${requestPath}`
35
+ );
36
+ return [path, { Authorization: `Bearer ${jwt}` }];
37
+ })
38
+ );
39
+ const headers = Object.fromEntries(entries);
40
+ cached = { headers, refreshAtMs: nowMs + AUTH_HEADER_TTL_MS };
41
+ return headers;
42
+ };
43
+ }
44
+ function createX402FacilitatorClient(config, opts = {}) {
45
+ return new HTTPFacilitatorClient({
46
+ url: config.facilitator ?? X402_DEFAULT_FACILITATOR,
47
+ ...opts.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : {},
48
+ ...config.facilitatorAuth ? { createAuthHeaders: createX402FacilitatorAuthHeaders(config) } : {}
49
+ });
50
+ }
51
+ async function generateCdpJwt(keyId, keySecret, uri) {
52
+ const now = Math.floor(Date.now() / 1e3);
53
+ const nonce = randomBytes(16).toString("hex");
54
+ const claims = { sub: keyId, iss: "cdp", uris: [uri] };
55
+ try {
56
+ const ecKey = await importPKCS8(normalizeEs256KeySecret(keySecret), "ES256");
57
+ return await new SignJWT(claims).setProtectedHeader({ alg: "ES256", kid: keyId, typ: "JWT", nonce }).setIssuedAt(now).setNotBefore(now).setExpirationTime(now + AUTH_TOKEN_TTL_SECONDS).sign(ecKey);
58
+ } catch {
59
+ }
60
+ const decoded = Buffer.from(keySecret, "base64");
61
+ if (decoded.length !== 64) {
62
+ throw new Error("Invalid CDP key secret: expected an ES256 PEM or base64 Ed25519 key");
63
+ }
64
+ const jwk = {
65
+ kty: "OKP",
66
+ crv: "Ed25519",
67
+ d: decoded.subarray(0, 32).toString("base64url"),
68
+ x: decoded.subarray(32).toString("base64url")
69
+ };
70
+ const edKey = await importJWK(jwk, "EdDSA");
71
+ return new SignJWT(claims).setProtectedHeader({ alg: "EdDSA", kid: keyId, typ: "JWT", nonce }).setIssuedAt(now).setNotBefore(now).setExpirationTime(now + AUTH_TOKEN_TTL_SECONDS).sign(edKey);
72
+ }
73
+ function normalizeEs256KeySecret(keySecret) {
74
+ if (!keySecret.includes("-----BEGIN EC PRIVATE KEY-----")) return keySecret;
75
+ return createPrivateKey(keySecret).export({ format: "pem", type: "pkcs8" });
76
+ }
77
+
78
+ // src/lib/x402/facilitator-request.ts
79
+ async function verifyWithFacilitator(payload, requirements, config = {}, createAuthHeaders = createX402FacilitatorAuthHeaders(config)) {
80
+ const facilitator = config.facilitator ?? X402_DEFAULT_FACILITATOR;
81
+ const url = facilitator.replace(/\/$/, "") + "/verify";
82
+ return callerLoggers.x402.span(
83
+ "x402.verify_with_facilitator",
84
+ { facilitator_url: url },
85
+ async () => {
86
+ const authHeaders = (await createAuthHeaders?.())?.verify ?? {};
87
+ const res = await fetch(url, {
88
+ method: "POST",
89
+ headers: { "Content-Type": "application/json", ...authHeaders },
90
+ body: JSON.stringify({
91
+ x402Version: payload.x402Version,
92
+ paymentPayload: payload,
93
+ paymentRequirements: requirements
94
+ })
95
+ });
96
+ if (!res.ok) {
97
+ const rejection = await readFacilitatorRejection(res);
98
+ if (rejection?.isValid === false && typeof rejection.invalidReason === "string" && rejection.invalidReason.length > 0) {
99
+ return rejection;
100
+ }
101
+ return { isValid: false, invalidReason: `facilitator_status_${res.status}` };
102
+ }
103
+ const data = await res.json();
104
+ callerLoggers.x402.info("x402.verify_with_facilitator.result", { is_valid: data.isValid });
105
+ return data;
106
+ }
107
+ );
108
+ }
109
+ async function settleWithFacilitator(payload, requirements, config = {}, createAuthHeaders = createX402FacilitatorAuthHeaders(config)) {
110
+ const facilitator = config.facilitator ?? X402_DEFAULT_FACILITATOR;
111
+ const url = facilitator.replace(/\/$/, "") + "/settle";
112
+ return callerLoggers.x402.span(
113
+ "x402.settle_with_facilitator",
114
+ { facilitator_url: url },
115
+ async () => {
116
+ const authHeaders = (await createAuthHeaders?.())?.settle ?? {};
117
+ const res = await fetch(url, {
118
+ method: "POST",
119
+ headers: { "Content-Type": "application/json", ...authHeaders },
120
+ body: JSON.stringify({
121
+ x402Version: payload.x402Version,
122
+ paymentPayload: payload,
123
+ paymentRequirements: requirements
124
+ })
125
+ });
126
+ if (!res.ok) {
127
+ const rejection = await readFacilitatorRejection(res);
128
+ if (rejection?.success === false && typeof rejection.errorReason === "string" && rejection.errorReason.length > 0) {
129
+ return rejection;
130
+ }
131
+ return { success: false, errorReason: `facilitator_status_${res.status}` };
132
+ }
133
+ const data = await res.json();
134
+ callerLoggers.x402.info("x402.settle_with_facilitator.result", {
135
+ success: data.success,
136
+ tx_hash: data.transaction
137
+ });
138
+ return data;
139
+ }
140
+ );
141
+ }
142
+ async function readFacilitatorRejection(res) {
143
+ if (res.status !== 400) return null;
144
+ try {
145
+ const body = await res.json();
146
+ return isRecord(body) ? body : null;
147
+ } catch {
148
+ return null;
149
+ }
150
+ }
151
+ function isRecord(value) {
152
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
153
+ }
154
+
155
+ export {
156
+ createX402FacilitatorAuthHeaders,
157
+ createX402FacilitatorClient,
158
+ verifyWithFacilitator,
159
+ settleWithFacilitator
160
+ };
@@ -2,8 +2,9 @@ import {
2
2
  DEFAULT_CREDIT_MAX,
3
3
  DEFAULT_CREDIT_MIN,
4
4
  DEFAULT_CREDIT_TTL_SECONDS,
5
+ DEFAULT_JOB_RETENTION_DAYS,
5
6
  isZodSchema
6
- } from "./chunk-P4RUVDU7.js";
7
+ } from "./chunk-KXZUCCEY.js";
7
8
  import {
8
9
  InvalidCurrencyError,
9
10
  validateCurrency
@@ -20,6 +21,7 @@ function configureDVM(config) {
20
21
  const tags = collectTags(config);
21
22
  const currency = resolvePricingCurrency(config.currency);
22
23
  const capabilities = buildCapabilityMap(config, currency);
24
+ const jobRetentionDays = resolveJobRetentionDays(config.jobRetentionDays);
23
25
  const onlyCapability = singleCapabilityEntry(capabilities);
24
26
  const descriptor = {
25
27
  name: config.name,
@@ -31,6 +33,7 @@ function configureDVM(config) {
31
33
  state: onlyCapability?.state ?? {},
32
34
  idleTimeout: config.idleTimeout ?? 3600,
33
35
  processingWatchdog: config.processingWatchdog,
36
+ jobRetentionDays,
34
37
  config,
35
38
  capabilities,
36
39
  paymentMethods: config.paymentMethods,
@@ -42,6 +45,15 @@ function configureDVM(config) {
42
45
  CONFIGURED_DVM_DESCRIPTORS.add(descriptor);
43
46
  return Object.freeze(descriptor);
44
47
  }
48
+ function resolveJobRetentionDays(raw) {
49
+ const days = raw ?? DEFAULT_JOB_RETENTION_DAYS;
50
+ if (!Number.isSafeInteger(days) || days < 0) {
51
+ throw new Error(
52
+ `configureDVM: jobRetentionDays must be a non-negative whole number of days; received ${JSON.stringify(raw)}`
53
+ );
54
+ }
55
+ return days;
56
+ }
45
57
  function isConfiguredDVMDescriptor(value) {
46
58
  return typeof value === "object" && value !== null && CONFIGURED_DVM_DESCRIPTORS.has(value);
47
59
  }
@@ -18,20 +18,14 @@ import {
18
18
  assertSupportedX402Network,
19
19
  buildPaymentRequirements,
20
20
  chainIdFromCaip2,
21
- createX402FacilitatorAuthHeaders,
22
- decodePayment,
23
21
  encodePayment,
24
- encodeSettleResponseHeader,
25
- exactEvmAuthorization,
26
- settleWithFacilitator,
27
22
  usdcContractFor,
28
23
  usdcDomainNameFor,
29
24
  usdcDomainVersionFor,
30
- verifyWithFacilitator,
31
25
  x402NetworkByCaip2,
32
26
  x402NetworkToCaip2,
33
27
  x402SupportedNetworksHint
34
- } from "./chunk-JGGI65I3.js";
28
+ } from "./chunk-Z4BNLUZF.js";
35
29
  import {
36
30
  costAnchor,
37
31
  fetchBtcUsdRate,
@@ -48,9 +42,6 @@ import {
48
42
  resolveRpcHttpTransportOptions,
49
43
  resolveRpcOverride
50
44
  } from "./chunk-MKI6OVW4.js";
51
- import {
52
- callerLoggers
53
- } from "./chunk-66HGCPBU.js";
54
45
  import {
55
46
  redactUrl,
56
47
  redactUrlsInText
@@ -77,9 +68,6 @@ function x402WrongAssetHint(asset) {
77
68
  return `This rail reads only ${asset.label} (${asset.address}) on ${asset.networkLabel}. ${wrongToken} USDC on a different chain is invisible here too \u2014 this wallet reads ${asset.networkLabel} alone. If you funded the wrong one, swap it to ${asset.label} on ${asset.networkLabel}, or bridge the funds across to ${asset.networkLabel}; either way they land where this rail can spend them.`;
78
69
  }
79
70
 
80
- // src/lib/x402/client.ts
81
- import { randomBytes } from "crypto";
82
-
83
71
  // src/lib/btc-rate.ts
84
72
  async function resolveBtcUsdRate(purpose) {
85
73
  try {
@@ -783,6 +771,7 @@ async function getX402Balance(wallet) {
783
771
  }
784
772
 
785
773
  // src/lib/x402/client.ts
774
+ import { randomBytes } from "crypto";
786
775
  async function tryX402Payment(request, wallet) {
787
776
  const selection = selectPaymentRequirement(request);
788
777
  let networkSlug;
@@ -990,72 +979,6 @@ async function priceableRate(btcRate) {
990
979
  }
991
980
  }
992
981
 
993
- // src/lib/x402/verify.ts
994
- async function verifyX402Payment(paymentHeader, config, requiredUsdcMicro, resource, btcUsdRate, exactVersions = { v1: true, v2: true }) {
995
- return callerLoggers.x402.span(
996
- "x402.verify_payment",
997
- {
998
- resource,
999
- required_usdc_micro: Number(requiredUsdcMicro),
1000
- facilitator_url: config.facilitator
1001
- },
1002
- async () => {
1003
- let payload;
1004
- try {
1005
- payload = decodePayment(paymentHeader);
1006
- } catch {
1007
- return { verified: false, amountMsats: 0, invalidReason: "decode_failed" };
1008
- }
1009
- if (payload.x402Version === 1 && !exactVersions.v1 || payload.x402Version === 2 && !exactVersions.v2) {
1010
- return { verified: false, amountMsats: 0, invalidReason: "unsupported_version" };
1011
- }
1012
- const requirementOpts = { x402Config: config, requiredUsdcMicro, resource };
1013
- const requirements = payload.x402Version === 1 ? buildPaymentRequirements({ ...requirementOpts, version: 1 }) : buildPaymentRequirements({ ...requirementOpts, version: 2 });
1014
- const createAuthHeaders = createX402FacilitatorAuthHeaders(config);
1015
- const verifyRes = await verifyWithFacilitator(
1016
- payload,
1017
- requirements,
1018
- config,
1019
- createAuthHeaders
1020
- );
1021
- if (!verifyRes.isValid) {
1022
- return {
1023
- verified: false,
1024
- amountMsats: 0,
1025
- invalidReason: verifyRes.invalidReason ?? "verify_failed"
1026
- };
1027
- }
1028
- const settleRes = await settleWithFacilitator(
1029
- payload,
1030
- requirements,
1031
- config,
1032
- createAuthHeaders
1033
- );
1034
- if (!settleRes.success) {
1035
- return {
1036
- verified: false,
1037
- amountMsats: 0,
1038
- invalidReason: settleRes.errorReason ?? "settle_failed"
1039
- };
1040
- }
1041
- const amountUsdcMicro = Number.parseInt(exactEvmAuthorization(payload).value, 10);
1042
- const amountMsats = usdcToMsats(amountUsdcMicro / 1e6, btcUsdRate);
1043
- callerLoggers.x402.info("x402.verify_payment.result", {
1044
- verified: true,
1045
- tx_hash: settleRes.transaction,
1046
- amount_msats: amountMsats
1047
- });
1048
- return {
1049
- verified: true,
1050
- amountMsats,
1051
- amountUsdcMicro,
1052
- txHash: settleRes.transaction,
1053
- settleResponseHeader: encodeSettleResponseHeader(settleRes)
1054
- };
1055
- }
1056
- );
1057
- }
1058
-
1059
982
  export {
1060
983
  resolveX402Asset,
1061
984
  x402WrongAssetHint,
@@ -1099,6 +1022,5 @@ export {
1099
1022
  removeX402Wallet,
1100
1023
  getX402Balance,
1101
1024
  tryX402Payment,
1102
- isSignableExactRequirement,
1103
- verifyX402Payment
1025
+ isSignableExactRequirement
1104
1026
  };
@@ -15,7 +15,7 @@ import {
15
15
  lotOwedSats,
16
16
  netOwedSats,
17
17
  x402SettlementPending
18
- } from "./chunk-LWUR4CGG.js";
18
+ } from "./chunk-MLRCSJYX.js";
19
19
 
20
20
  // src/sdk/server/memory-credit-ledger.ts
21
21
  import { randomUUID } from "crypto";
@@ -624,6 +624,18 @@ var MemoryCreditLedger = class {
624
624
  }
625
625
  return Promise.resolve(matches.length === 1 ? matches[0] : void 0);
626
626
  }
627
+ listDrawsByJobId(jobId) {
628
+ const matches = [];
629
+ for (const credit of this.credits.values()) {
630
+ for (const draw of credit.draws.values()) {
631
+ if (draw.jobId === jobId) matches.push(drawRecord(draw, credit));
632
+ }
633
+ }
634
+ matches.sort(
635
+ (a, b) => a.createdAt - b.createdAt || a.creditId.localeCompare(b.creditId) || a.ledgerSeq - b.ledgerSeq
636
+ );
637
+ return Promise.resolve(matches);
638
+ }
627
639
  listPendingDraws(creditId) {
628
640
  const credit = this.credits.get(creditId);
629
641
  if (!credit) return Promise.resolve([]);