@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.
- package/README.md +14 -0
- package/dist/chunk-2K7E3N2D.js +1709 -0
- package/dist/{chunk-Y6W5ZZTW.js → chunk-3ZHMQCYP.js} +666 -3031
- package/dist/{chunk-TKA6ZP4M.js → chunk-4B56DEEV.js} +50 -426
- package/dist/{chunk-X3IKFWJA.js → chunk-6BQM7TOW.js} +4 -1
- package/dist/chunk-BIFLRKMO.js +87 -0
- package/dist/chunk-BQ2NMWKE.js +160 -0
- package/dist/{chunk-LDTWX7JW.js → chunk-BTZY7VPH.js} +13 -1
- package/dist/{chunk-FJDCFHW5.js → chunk-C6JHBLMW.js} +3 -81
- package/dist/{chunk-EXHBXA4U.js → chunk-DBCLBYHP.js} +13 -1
- package/dist/chunk-EPNDZ5DH.js +1010 -0
- package/dist/{chunk-P4RUVDU7.js → chunk-H2MEFVH6.js} +12 -141
- package/dist/chunk-KXZUCCEY.js +142 -0
- package/dist/{chunk-6JZIX5WW.js → chunk-LLXV32HA.js} +82 -5
- package/dist/{chunk-LWUR4CGG.js → chunk-MLRCSJYX.js} +11 -3
- package/dist/{chunk-2ABMGUDS.js → chunk-NFRM5QYP.js} +83 -10
- package/dist/chunk-RW5LP57K.js +44 -0
- package/dist/chunk-YDIYXGYL.js +384 -0
- package/dist/{chunk-JGGI65I3.js → chunk-Z4BNLUZF.js} +1 -150
- package/dist/{credit-ledger-ED6JXKVD.js → credit-ledger-2DFQHNLB.js} +2 -2
- package/dist/{credit-menu-BrTfAr7l.d.ts → credit-menu-C7zAJElJ.d.ts} +1632 -1946
- package/dist/{fx-H6K6qcH1.d.ts → fx-BF_SG2i0.d.ts} +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +8 -4
- package/dist/internal/caller.d.ts +10429 -0
- package/dist/internal/caller.js +9957 -0
- package/dist/internal/index.d.ts +2 -10816
- package/dist/internal/index.js +2 -10130
- package/dist/internal/server.d.ts +404 -0
- package/dist/internal/server.js +202 -0
- package/dist/job-store-Bn23V3QU.d.ts +576 -0
- package/dist/lightning-backend-C04nH94l.d.ts +367 -0
- package/dist/{memory-credit-ledger-XJ5VQEVP.js → memory-credit-ledger-OP24Z2KO.js} +3 -3
- package/dist/{payout-reporter-3UB5WRCV.js → payout-reporter-RG6XNGPI.js} +1 -1
- package/dist/{postgres-job-store-J5F4GUWU.js → postgres-job-store-TAONYLIF.js} +1 -1
- package/dist/{revenue-reporter-JIKUPXOK.js → revenue-reporter-XXSU5KVB.js} +1 -1
- package/dist/server/index.d.ts +27 -11
- package/dist/server/index.js +93 -69
- package/dist/{job-store-DOSfYnLX.d.ts → step-cache-3cT4Shk0.d.ts} +38 -585
- package/dist/{tempo-session-store-DALMRIWN.js → tempo-session-store-2JNOKJGX.js} +2 -2
- package/dist/testing/index.d.ts +16 -4
- package/dist/testing/index.js +7 -3
- package/dist/{usd-Civ738b3.d.ts → usd-BnuXoFl5.d.ts} +1 -1
- package/dist/wallet-CJC8lwxx.d.ts +29 -0
- package/dist/{x402-FTG2GRAQ.js → x402-T2C5MX3T.js} +6 -3
- package/package.json +7 -2
- 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-
|
|
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-
|
|
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-
|
|
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([]);
|