@dvmkit/sdk 0.10.0 → 0.11.0-rc.1
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/dist/{chunk-3Q6FTZDB.js → chunk-3YFFZLW7.js} +2 -2
- package/dist/{chunk-YOSZIWC3.js → chunk-55DVLBCD.js} +135 -8
- package/dist/{chunk-VMHYGKWT.js → chunk-566CFXGU.js} +9 -1
- package/dist/chunk-5H7P3ORL.js +92 -0
- package/dist/{chunk-3R7NQA3Z.js → chunk-7KQLPVV7.js} +1 -1
- package/dist/{chunk-QNKK7SPY.js → chunk-AIQGF52I.js} +350 -71
- package/dist/{chunk-JNECYURT.js → chunk-D4FFS3IS.js} +1 -1
- package/dist/{chunk-VTHYQCDB.js → chunk-E7ZBCT5U.js} +1 -1
- package/dist/{chunk-MMGSYMIC.js → chunk-EP7OVWI5.js} +1 -1
- package/dist/{chunk-LDIPVPKI.js → chunk-FFRTAQUW.js} +1 -1
- package/dist/chunk-H3GGFEE5.js +57 -0
- package/dist/{chunk-M3T5JYDJ.js → chunk-HNXMWHLU.js} +1 -1
- package/dist/{chunk-Y6DO5WSO.js → chunk-HQPQ4PFI.js} +43 -21
- package/dist/{chunk-UKD3R2KU.js → chunk-HW2UCOOC.js} +4 -55
- package/dist/{chunk-FFXXGCVG.js → chunk-ITRSITFP.js} +1 -1
- package/dist/{chunk-MU3IE434.js → chunk-JLT2YIBS.js} +267 -52
- package/dist/{chunk-STJBBVNL.js → chunk-K2ZNIQZP.js} +458 -69
- package/dist/{chunk-KFCEXCZM.js → chunk-KJZVTWMX.js} +1 -1
- package/dist/{chunk-W3VGCNG6.js → chunk-LDKV4UHI.js} +1 -1
- package/dist/{chunk-AJ6UHXUA.js → chunk-M4NFYEEY.js} +1 -1
- package/dist/{chunk-MB6R4XPZ.js → chunk-NS2OMIU7.js} +15 -3
- package/dist/{chunk-VUGEEMLT.js → chunk-RPUFWIT4.js} +11 -89
- package/dist/{chunk-EWZFANHJ.js → chunk-VWIMQ5H5.js} +1 -1
- package/dist/{chunk-2XQLL6N6.js → chunk-WFCVS6QB.js} +2 -2
- package/dist/{chunk-QGNXYVBO.js → chunk-Z4FOPROB.js} +17 -0
- package/dist/{content-retention-CrILCNxk.d.ts → content-retention-ySTD1wwZ.d.ts} +1 -1
- package/dist/{credit-ledger-4PZNAMDT.js → credit-ledger-4CBYLSLY.js} +6 -3
- package/dist/{credit-menu-VwX_6KM7.d.ts → credit-menu-BYySnZBk.d.ts} +6 -4
- package/dist/{fx-BM5h4o5S.d.ts → fx-DVTNs9q1.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +6 -5
- package/dist/internal/caller.d.ts +6 -6
- package/dist/internal/caller.js +26 -22
- package/dist/internal/server.d.ts +7 -7
- package/dist/internal/server.js +24 -22
- package/dist/{job-store-92v8e1LQ.d.ts → job-store-DRwXCJDI.d.ts} +1 -1
- package/dist/{lightning-backend-9oky_wJi.d.ts → lightning-backend-BX5YvjnM.d.ts} +1 -1
- package/dist/memory-credit-ledger-DKCN7FY2.js +14 -0
- package/dist/{mpp-setup-FURD45LI.js → mpp-setup-JU3MT7QX.js} +3 -3
- package/dist/{payout-reporter-HVJ6WUF3.js → payout-reporter-NXWQVKXW.js} +2 -2
- package/dist/{postgres-consumed-credential-store-WO6OCFXZ.js → postgres-consumed-credential-store-WXJLM6J7.js} +1 -1
- package/dist/{postgres-job-store-FSRUPYH2.js → postgres-job-store-WIIVRZPD.js} +2 -2
- package/dist/{postgres-replay-store-XXJSA457.js → postgres-replay-store-QJ4FG6AR.js} +2 -2
- package/dist/{pricing-X4XU5HXY.js → pricing-KCLENT2C.js} +3 -3
- package/dist/{revenue-reporter-EV3K5L6B.js → revenue-reporter-HD4GMXGD.js} +2 -2
- package/dist/server/index.d.ts +29 -12
- package/dist/server/index.js +31 -29
- package/dist/{step-cache--7yA5Ihr.d.ts → step-cache-d-VKen4K.d.ts} +147 -13
- package/dist/{tempo-charge-store-5JOIYUIH.js → tempo-charge-store-7LTUAQHQ.js} +2 -2
- package/dist/{tempo-session-store-S6QMLQUA.js → tempo-session-store-LYAIDR2B.js} +3 -3
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +6 -6
- package/dist/{usd-C7lvLvLk.d.ts → usd-DSroMJ--.d.ts} +1 -1
- package/dist/{x402-EN5LSOVM.js → x402-RUJ4LUKF.js} +3 -3
- package/package.json +1 -1
- package/recipes/postgres/financial-export-v1.sql +19 -5
- package/dist/memory-credit-ledger-RP7DT5IY.js +0 -11
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/lib/cast-auth/canonical-json.ts
|
|
2
|
+
function canonicalize(value) {
|
|
3
|
+
return JSON.stringify(sortDeep(value));
|
|
4
|
+
}
|
|
5
|
+
function canonicaliseForSigning(value) {
|
|
6
|
+
return new TextEncoder().encode(canonicalize(value));
|
|
7
|
+
}
|
|
8
|
+
function sortDeep(value) {
|
|
9
|
+
if (value === null) return null;
|
|
10
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
11
|
+
if (typeof value === "number") {
|
|
12
|
+
if (!Number.isFinite(value)) {
|
|
13
|
+
throw new TypeError(`canonicalize: non-finite number is not JSON-serialisable`);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(value)) return value.map(sortDeep);
|
|
18
|
+
if (typeof value === "object") {
|
|
19
|
+
const sorted = {};
|
|
20
|
+
for (const key of Object.keys(value).sort()) {
|
|
21
|
+
const v = value[key];
|
|
22
|
+
if (v === void 0) continue;
|
|
23
|
+
sorted[key] = sortDeep(v);
|
|
24
|
+
}
|
|
25
|
+
return sorted;
|
|
26
|
+
}
|
|
27
|
+
throw new TypeError(`canonicalize: unsupported value of type ${typeof value}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/lib/cast-auth/verify.ts
|
|
31
|
+
import { schnorr } from "@noble/curves/secp256k1.js";
|
|
32
|
+
function verifyCanonicalSignedRequest(payload, signatureHex, pubkeyHex) {
|
|
33
|
+
if (!/^[0-9a-f]{64}$/i.test(pubkeyHex) || !/^[0-9a-f]{128}$/i.test(signatureHex)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const data = canonicaliseForSigning(payload);
|
|
37
|
+
const signature = hexToBytes(signatureHex);
|
|
38
|
+
const pubkey = hexToBytes(pubkeyHex);
|
|
39
|
+
try {
|
|
40
|
+
return schnorr.verify(signature, data, pubkey);
|
|
41
|
+
} catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function hexToBytes(hex) {
|
|
46
|
+
const out = new Uint8Array(hex.length / 2);
|
|
47
|
+
for (let i = 0; i < out.length; i++) {
|
|
48
|
+
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
canonicalize,
|
|
55
|
+
canonicaliseForSigning,
|
|
56
|
+
verifyCanonicalSignedRequest
|
|
57
|
+
};
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-COYKJRMM.js";
|
|
8
8
|
import {
|
|
9
9
|
diagnosticConsole
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Z4FOPROB.js";
|
|
11
11
|
|
|
12
12
|
// src/sdk/server/postgres-job-store.ts
|
|
13
13
|
import { createHash } from "crypto";
|
|
@@ -483,7 +483,16 @@ var PostgresJobStore = class {
|
|
|
483
483
|
held.client.release();
|
|
484
484
|
}
|
|
485
485
|
async save(record) {
|
|
486
|
-
|
|
486
|
+
const dvmId = record[JOB_DVM_ID];
|
|
487
|
+
for (let attempt = 0; ; attempt++) {
|
|
488
|
+
try {
|
|
489
|
+
await this.saveRecord(record, dvmId);
|
|
490
|
+
return;
|
|
491
|
+
} catch (error) {
|
|
492
|
+
if (attempt >= 7 || !await this.canRetrySnapshot(error, record)) throw error;
|
|
493
|
+
await new Promise((resolve) => setTimeout(resolve, 5 * (attempt + 1)));
|
|
494
|
+
}
|
|
495
|
+
}
|
|
487
496
|
}
|
|
488
497
|
/** Persist a job while retaining its mount identity for cost-report recovery. */
|
|
489
498
|
async saveForDvm(record, dvmId) {
|
|
@@ -495,6 +504,17 @@ var PostgresJobStore = class {
|
|
|
495
504
|
delete scoped[JOB_DVM_ID];
|
|
496
505
|
}
|
|
497
506
|
}
|
|
507
|
+
async canRetrySnapshot(error, record) {
|
|
508
|
+
if (error === null || typeof error !== "object") return false;
|
|
509
|
+
const { code, constraint } = error;
|
|
510
|
+
if (code === "40P01") return true;
|
|
511
|
+
if (code !== "23505" || constraint !== "idx_jobs_request_id_caller") return false;
|
|
512
|
+
const { rows } = await this.pool.query(
|
|
513
|
+
"SELECT id FROM jobs WHERE requester_pubkey=$1 AND request_id=$2",
|
|
514
|
+
[record.requesterPubkey, record.requestId]
|
|
515
|
+
);
|
|
516
|
+
return rows[0]?.id === record.id;
|
|
517
|
+
}
|
|
498
518
|
async saveRecord(record, dvmId) {
|
|
499
519
|
const now = Date.now();
|
|
500
520
|
const write = (q) => q.query(
|
|
@@ -642,14 +662,14 @@ var PostgresJobStore = class {
|
|
|
642
662
|
]
|
|
643
663
|
);
|
|
644
664
|
let rowCount;
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
665
|
+
const tx = await this.pool.connect();
|
|
666
|
+
try {
|
|
667
|
+
await tx.query("BEGIN");
|
|
668
|
+
const existing = await tx.query(
|
|
669
|
+
"SELECT dvm_id FROM jobs WHERE id=$1 FOR UPDATE",
|
|
670
|
+
[record.id]
|
|
671
|
+
);
|
|
672
|
+
if (this.hostingCleanupFence) {
|
|
653
673
|
if (existing.rows[0]) {
|
|
654
674
|
if (existing.rows[0].dvm_id !== null && existing.rows[0].dvm_id !== this.hostingCleanupFence.dvmId) {
|
|
655
675
|
throw new Error("Hosted job belongs to another DVM");
|
|
@@ -657,16 +677,14 @@ var PostgresJobStore = class {
|
|
|
657
677
|
} else {
|
|
658
678
|
await this.hostingCleanupFence.assertNewIntent(tx, { jobId: record.id });
|
|
659
679
|
}
|
|
660
|
-
({ rowCount } = await write(tx));
|
|
661
|
-
await tx.query("COMMIT");
|
|
662
|
-
} catch (error) {
|
|
663
|
-
await tx.query("ROLLBACK").catch(() => void 0);
|
|
664
|
-
throw error;
|
|
665
|
-
} finally {
|
|
666
|
-
tx.release();
|
|
667
680
|
}
|
|
668
|
-
|
|
669
|
-
|
|
681
|
+
({ rowCount } = await write(tx));
|
|
682
|
+
await tx.query("COMMIT");
|
|
683
|
+
} catch (error) {
|
|
684
|
+
await tx.query("ROLLBACK").catch(() => void 0);
|
|
685
|
+
throw error;
|
|
686
|
+
} finally {
|
|
687
|
+
tx.release();
|
|
670
688
|
}
|
|
671
689
|
if (rowCount === 0) {
|
|
672
690
|
diagnosticConsole.warn(
|
|
@@ -1393,8 +1411,12 @@ var PostgresJobStore = class {
|
|
|
1393
1411
|
return true;
|
|
1394
1412
|
}
|
|
1395
1413
|
async deleteResolvedMessages(jobId) {
|
|
1396
|
-
await this.pool.query(
|
|
1397
|
-
|
|
1414
|
+
await this.pool.query(
|
|
1415
|
+
`DELETE FROM job_messages WHERE job_id=$1 AND NOT (
|
|
1416
|
+
data->>'type'='payment' AND (status='pending-verification'
|
|
1417
|
+
OR ($2::boolean AND status='failed-verify')))`,
|
|
1418
|
+
[jobId, !!this.hostingCleanupFence]
|
|
1419
|
+
);
|
|
1398
1420
|
}
|
|
1399
1421
|
async fetchCountersTx(client, jobId) {
|
|
1400
1422
|
const { rows } = await client.query(
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
canonicaliseForSigning
|
|
3
|
+
} from "./chunk-H3GGFEE5.js";
|
|
4
|
+
|
|
1
5
|
// src/sdk/types.ts
|
|
2
6
|
function isZodSchema(value) {
|
|
3
7
|
return typeof value === "object" && value !== null && "_zod" in value && "parse" in value && "safeParse" in value;
|
|
@@ -12,58 +16,6 @@ var DEFAULT_CREDIT_MAX = "$5.00";
|
|
|
12
16
|
var DEFAULT_CREDIT_TTL_SECONDS = 30 * 24 * 60 * 60;
|
|
13
17
|
var DEFAULT_JOB_RETENTION_DAYS = 730;
|
|
14
18
|
|
|
15
|
-
// src/lib/cast-auth/canonical-json.ts
|
|
16
|
-
function canonicalize(value) {
|
|
17
|
-
return JSON.stringify(sortDeep(value));
|
|
18
|
-
}
|
|
19
|
-
function canonicaliseForSigning(value) {
|
|
20
|
-
return new TextEncoder().encode(canonicalize(value));
|
|
21
|
-
}
|
|
22
|
-
function sortDeep(value) {
|
|
23
|
-
if (value === null) return null;
|
|
24
|
-
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
25
|
-
if (typeof value === "number") {
|
|
26
|
-
if (!Number.isFinite(value)) {
|
|
27
|
-
throw new TypeError(`canonicalize: non-finite number is not JSON-serialisable`);
|
|
28
|
-
}
|
|
29
|
-
return value;
|
|
30
|
-
}
|
|
31
|
-
if (Array.isArray(value)) return value.map(sortDeep);
|
|
32
|
-
if (typeof value === "object") {
|
|
33
|
-
const sorted = {};
|
|
34
|
-
for (const key of Object.keys(value).sort()) {
|
|
35
|
-
const v = value[key];
|
|
36
|
-
if (v === void 0) continue;
|
|
37
|
-
sorted[key] = sortDeep(v);
|
|
38
|
-
}
|
|
39
|
-
return sorted;
|
|
40
|
-
}
|
|
41
|
-
throw new TypeError(`canonicalize: unsupported value of type ${typeof value}`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// src/lib/cast-auth/verify.ts
|
|
45
|
-
import { schnorr } from "@noble/curves/secp256k1.js";
|
|
46
|
-
function verifyCanonicalSignedRequest(payload, signatureHex, pubkeyHex) {
|
|
47
|
-
if (!/^[0-9a-f]{64}$/i.test(pubkeyHex) || !/^[0-9a-f]{128}$/i.test(signatureHex)) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
const data = canonicaliseForSigning(payload);
|
|
51
|
-
const signature = hexToBytes(signatureHex);
|
|
52
|
-
const pubkey = hexToBytes(pubkeyHex);
|
|
53
|
-
try {
|
|
54
|
-
return schnorr.verify(signature, data, pubkey);
|
|
55
|
-
} catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function hexToBytes(hex) {
|
|
60
|
-
const out = new Uint8Array(hex.length / 2);
|
|
61
|
-
for (let i = 0; i < out.length; i++) {
|
|
62
|
-
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
63
|
-
}
|
|
64
|
-
return out;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
19
|
// src/lib/signed-request-statement.ts
|
|
68
20
|
var SIGNED_REQUEST_AUTH_ID = "secp256k1-schnorr-v2";
|
|
69
21
|
var SIGNED_REQUEST_STATEMENT_VERSION = 2;
|
|
@@ -129,9 +81,6 @@ export {
|
|
|
129
81
|
DEFAULT_CREDIT_MAX,
|
|
130
82
|
DEFAULT_CREDIT_TTL_SECONDS,
|
|
131
83
|
DEFAULT_JOB_RETENTION_DAYS,
|
|
132
|
-
canonicalize,
|
|
133
|
-
canonicaliseForSigning,
|
|
134
|
-
verifyCanonicalSignedRequest,
|
|
135
84
|
SIGNED_REQUEST_AUTH_ID,
|
|
136
85
|
SIGNED_REQUEST_STATEMENT_VERSION,
|
|
137
86
|
signedRequestStatementHeader,
|