@dvmkit/sdk 0.12.0 → 0.14.0
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-RPUFWIT4.js → chunk-5JSPTVIK.js} +52 -2
- package/dist/{chunk-5H7P3ORL.js → chunk-5UC7TOQC.js} +22 -0
- package/dist/{chunk-2VGMZ7VF.js → chunk-A2YESDQM.js} +47 -11
- package/dist/{chunk-WFCVS6QB.js → chunk-HULU2UVM.js} +1 -1
- package/dist/{chunk-S7PIFHE4.js → chunk-JFH34P3M.js} +258 -31
- package/dist/{chunk-HW2UCOOC.js → chunk-SXL44PL5.js} +1 -1
- package/dist/{chunk-POYUX2NN.js → chunk-TKJBUFYY.js} +11 -3
- package/dist/{content-retention-a1yRdmhI.d.ts → content-retention-BcHNpP2F.d.ts} +1 -1
- package/dist/{credit-ledger-MF23UKRJ.js → credit-ledger-D3UUR2GW.js} +2 -2
- package/dist/{credit-menu-B2T-O9oY.d.ts → credit-menu-C-kmf61K.d.ts} +57 -5
- package/dist/{fx-DLhscRUh.d.ts → fx-hFlF4Cn8.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/internal/caller.d.ts +160 -9
- package/dist/internal/caller.js +141 -10
- package/dist/internal/index.js +1 -1
- package/dist/internal/server.d.ts +7 -7
- package/dist/internal/server.js +7 -7
- package/dist/{job-store-B8Ijr5V6.d.ts → job-store-DVCATwhU.d.ts} +1 -1
- package/dist/{lightning-backend-DmwMSgaM.d.ts → lightning-backend-DXNVlVs9.d.ts} +1 -1
- package/dist/{memory-credit-ledger-ERD764PS.js → memory-credit-ledger-SCXQO4HZ.js} +3 -3
- package/dist/server/index.d.ts +17 -13
- package/dist/server/index.js +9 -9
- package/dist/{step-cache-DQqpwXa8.d.ts → step-cache-CoORQQ_Y.d.ts} +108 -11
- package/dist/testing/index.d.ts +3 -3
- package/dist/{usd-D5kk2nIT.d.ts → usd-CeXGiyTC.d.ts} +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeResultHash,
|
|
3
3
|
isDrainReceipt,
|
|
4
|
+
isDrawFundingReceipt,
|
|
4
5
|
isFundingReceipt,
|
|
5
6
|
verifyDrainReceipt,
|
|
7
|
+
verifyDrawFundingReceipt,
|
|
6
8
|
verifyFundingReceipt,
|
|
7
9
|
verifyReceipt
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5UC7TOQC.js";
|
|
9
11
|
import {
|
|
10
12
|
DvmError
|
|
11
13
|
} from "./chunk-BPYMEMQX.js";
|
|
@@ -30,7 +32,7 @@ function isX402SettlementReconciliationReason(value) {
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
// src/lib/credit-implicit.ts
|
|
33
|
-
var IMPLICIT_CREDIT_TTL_MS =
|
|
35
|
+
var IMPLICIT_CREDIT_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
34
36
|
|
|
35
37
|
// src/lib/payment-rails/tempo-wire.ts
|
|
36
38
|
var TEMPO_SESSION_UPDATED_REASON = "Tempo session updated; attach the next voucher to fund this credit.";
|
|
@@ -1699,6 +1701,53 @@ function verifyFundingReceiptChain(args) {
|
|
|
1699
1701
|
receipt: named
|
|
1700
1702
|
};
|
|
1701
1703
|
}
|
|
1704
|
+
function verifyDrawFundingReceiptChain(args) {
|
|
1705
|
+
const named = isDrawFundingReceipt(args.receipt) ? args.receipt : void 0;
|
|
1706
|
+
const check = (actual, expected) => expected === void 0 ? "unchecked" : actual === expected ? "ok" : "mismatch";
|
|
1707
|
+
const checks = {
|
|
1708
|
+
credit_id: check(named?.credit_id, args.expectedCreditId),
|
|
1709
|
+
job_id: check(named?.job_id, args.expectedJobId),
|
|
1710
|
+
draw_id: check(named?.draw_id, args.expectedDrawId),
|
|
1711
|
+
fund_id: check(named?.fund_id, args.expectedFundId),
|
|
1712
|
+
currency: check(named?.currency, args.expectedCurrency),
|
|
1713
|
+
funded_micro: check(named?.funded_micro, args.expectedFundedMicro),
|
|
1714
|
+
ledger_seq: check(named?.ledger_seq, args.expectedLedgerSeq),
|
|
1715
|
+
caller_pubkey: check(named?.caller_pubkey, args.expectedCallerPubkey),
|
|
1716
|
+
signature: named !== void 0 && verifyDrawFundingReceipt(named),
|
|
1717
|
+
attestation: "absent"
|
|
1718
|
+
};
|
|
1719
|
+
const mismatch = [
|
|
1720
|
+
["credit_id", "credit_id_mismatch"],
|
|
1721
|
+
["job_id", "job_id_mismatch"],
|
|
1722
|
+
["draw_id", "draw_id_mismatch"],
|
|
1723
|
+
["fund_id", "fund_id_mismatch"],
|
|
1724
|
+
["currency", "funding_currency_mismatch"],
|
|
1725
|
+
["funded_micro", "funding_amount_mismatch"],
|
|
1726
|
+
["ledger_seq", "funding_ledger_seq_mismatch"],
|
|
1727
|
+
["caller_pubkey", "caller_pubkey_mismatch"]
|
|
1728
|
+
];
|
|
1729
|
+
for (const [field, reason] of mismatch) {
|
|
1730
|
+
if (checks[field] === "mismatch") return { status: "invalid", checks, reason, receipt: named };
|
|
1731
|
+
}
|
|
1732
|
+
if (!named || !checks.signature) {
|
|
1733
|
+
return { status: "invalid", checks, reason: "signature_invalid", receipt: named };
|
|
1734
|
+
}
|
|
1735
|
+
checks.attestation = checkReceiptAttestation(named, args.builder);
|
|
1736
|
+
if (checks.attestation === "invalid") {
|
|
1737
|
+
return { status: "invalid", checks, reason: "attestation_invalid", receipt: named };
|
|
1738
|
+
}
|
|
1739
|
+
if (checks.attestation === "identity_mismatch") {
|
|
1740
|
+
return { status: "invalid", checks, reason: "dvm_identity_mismatch", receipt: named };
|
|
1741
|
+
}
|
|
1742
|
+
if (checks.attestation === "key_mismatch") {
|
|
1743
|
+
return { status: "invalid", checks, reason: "receipt_key_mismatch", receipt: named };
|
|
1744
|
+
}
|
|
1745
|
+
return {
|
|
1746
|
+
status: checks.attestation === "ok" ? "verified" : "verified_unattested",
|
|
1747
|
+
checks,
|
|
1748
|
+
receipt: named
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1702
1751
|
function weakestReceiptVerdict(statuses) {
|
|
1703
1752
|
if (statuses.length === 0) return "absent";
|
|
1704
1753
|
if (statuses.includes("invalid")) return "invalid";
|
|
@@ -1862,6 +1911,7 @@ export {
|
|
|
1862
1911
|
checkReceiptAttestation,
|
|
1863
1912
|
verifyDrainReceiptChain,
|
|
1864
1913
|
verifyFundingReceiptChain,
|
|
1914
|
+
verifyDrawFundingReceiptChain,
|
|
1865
1915
|
weakestReceiptVerdict,
|
|
1866
1916
|
isPublicRequestId,
|
|
1867
1917
|
parseTraceparent,
|
|
@@ -63,6 +63,25 @@ function verifyFundingReceipt(receipt) {
|
|
|
63
63
|
return false;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
function signDrawFundingReceipt(unsigned, secretHex) {
|
|
67
|
+
const bytes = canonicaliseForSigning(unsigned);
|
|
68
|
+
const signature = bytesToHex(schnorr.sign(bytes, hexToBytes(secretHex)));
|
|
69
|
+
return { ...unsigned, signature };
|
|
70
|
+
}
|
|
71
|
+
function isDrawFundingReceipt(value) {
|
|
72
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
73
|
+
const r = value;
|
|
74
|
+
return r.v === 1 && r.kind === "credit_draw_funding" && typeof r.credit_id === "string" && typeof r.job_id === "string" && typeof r.draw_id === "string" && typeof r.fund_id === "string" && (r.payment_seq === void 0 || typeof r.payment_seq === "number") && typeof r.currency === "string" && typeof r.funded_micro === "number" && typeof r.balance_after_micro === "number" && typeof r.ledger_seq === "number" && typeof r.issued_at === "number" && typeof r.caller_pubkey === "string" && typeof r.dvm_id === "string" && typeof r.dvm === "string" && typeof r.receipt_pubkey === "string" && typeof r.signature === "string";
|
|
75
|
+
}
|
|
76
|
+
function verifyDrawFundingReceipt(receipt) {
|
|
77
|
+
try {
|
|
78
|
+
const { signature, ...unsigned } = receipt;
|
|
79
|
+
const bytes = canonicaliseForSigning(unsigned);
|
|
80
|
+
return schnorr.verify(hexToBytes(signature), bytes, hexToBytes(receipt.receipt_pubkey));
|
|
81
|
+
} catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
66
85
|
function isDrainReceipt(value) {
|
|
67
86
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
68
87
|
const r = value;
|
|
@@ -87,6 +106,9 @@ export {
|
|
|
87
106
|
signFundingReceipt,
|
|
88
107
|
isFundingReceipt,
|
|
89
108
|
verifyFundingReceipt,
|
|
109
|
+
signDrawFundingReceipt,
|
|
110
|
+
isDrawFundingReceipt,
|
|
111
|
+
verifyDrawFundingReceipt,
|
|
90
112
|
isDrainReceipt,
|
|
91
113
|
verifyDrainReceipt
|
|
92
114
|
};
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
isSignedJobReceipt,
|
|
9
9
|
verifyReceipt
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5UC7TOQC.js";
|
|
11
11
|
import {
|
|
12
12
|
applyRetryToPool
|
|
13
13
|
} from "./chunk-EP7OVWI5.js";
|
|
@@ -1345,7 +1345,11 @@ var CreditLedger = class {
|
|
|
1345
1345
|
"caller_pubkey TEXT",
|
|
1346
1346
|
"balance_after_micro BIGINT",
|
|
1347
1347
|
"ledger_seq BIGINT",
|
|
1348
|
-
"receipt JSONB"
|
|
1348
|
+
"receipt JSONB",
|
|
1349
|
+
// Mid-job draw funding bindings; null on opening and `/v1/credit` fundings.
|
|
1350
|
+
"job_id TEXT",
|
|
1351
|
+
"draw_id TEXT",
|
|
1352
|
+
"payment_seq BIGINT"
|
|
1349
1353
|
]) {
|
|
1350
1354
|
await this.pool.query(`ALTER TABLE credit_fundings ADD COLUMN IF NOT EXISTS ${column}`);
|
|
1351
1355
|
}
|
|
@@ -1546,8 +1550,8 @@ var CreditLedger = class {
|
|
|
1546
1550
|
);
|
|
1547
1551
|
}
|
|
1548
1552
|
/**
|
|
1549
|
-
* Funding adds balance and
|
|
1550
|
-
* not idempotent: the caller’s rail marker or funding record must prevent replay. Owner and
|
|
1553
|
+
* Funding adds balance and extends expiry without shortening it, reviving an expired credit.
|
|
1554
|
+
* It is additive, not idempotent: the caller’s rail marker or funding record must prevent replay. Owner and
|
|
1551
1555
|
* currency must match; rail and reusable-channel bindings cannot be mixed with other
|
|
1552
1556
|
* instruments. A legacy NULL rail adopts its first typed top-up.
|
|
1553
1557
|
*
|
|
@@ -1616,7 +1620,7 @@ var CreditLedger = class {
|
|
|
1616
1620
|
ON CONFLICT (credit_id) DO UPDATE
|
|
1617
1621
|
SET balance_micro = credits.balance_micro + EXCLUDED.balance_micro,
|
|
1618
1622
|
last_funding_ledger_seq = credits.last_ledger_seq,
|
|
1619
|
-
expiry_ms = EXCLUDED.expiry_ms,
|
|
1623
|
+
expiry_ms = GREATEST(credits.expiry_ms, EXCLUDED.expiry_ms),
|
|
1620
1624
|
rail = COALESCE(credits.rail, EXCLUDED.rail),
|
|
1621
1625
|
native_asset = COALESCE(EXCLUDED.native_asset, credits.native_asset),
|
|
1622
1626
|
mint = COALESCE(EXCLUDED.mint, credits.mint),
|
|
@@ -2467,11 +2471,21 @@ var CreditLedger = class {
|
|
|
2467
2471
|
});
|
|
2468
2472
|
const nowMs = args.nowMs ?? Date.now();
|
|
2469
2473
|
const { rows } = await q.query(
|
|
2470
|
-
`INSERT INTO credit_fundings
|
|
2471
|
-
|
|
2474
|
+
`INSERT INTO credit_fundings
|
|
2475
|
+
(credit_id, fund_id, amount_micro, rail, created_at, job_id, draw_id, payment_seq)
|
|
2476
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
2472
2477
|
ON CONFLICT (credit_id, fund_id) DO NOTHING
|
|
2473
2478
|
RETURNING *`,
|
|
2474
|
-
[
|
|
2479
|
+
[
|
|
2480
|
+
args.creditId,
|
|
2481
|
+
args.fundId,
|
|
2482
|
+
args.amountMicro,
|
|
2483
|
+
args.rail ?? null,
|
|
2484
|
+
nowMs,
|
|
2485
|
+
args.jobId ?? null,
|
|
2486
|
+
args.drawId ?? null,
|
|
2487
|
+
args.paymentSeq ?? null
|
|
2488
|
+
]
|
|
2475
2489
|
);
|
|
2476
2490
|
if (rows.length === 0) {
|
|
2477
2491
|
throw new CreditLedgerError(
|
|
@@ -2494,6 +2508,19 @@ var CreditLedger = class {
|
|
|
2494
2508
|
);
|
|
2495
2509
|
return rows.length > 0 ? fundingRecordFromRow(rows[0]) : void 0;
|
|
2496
2510
|
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Every funding accepted against one job's draw, oldest first. The order is
|
|
2513
|
+
* stable across reads so a job read lists the same evidence each time.
|
|
2514
|
+
*/
|
|
2515
|
+
async listDrawFundings(args) {
|
|
2516
|
+
const { rows } = await this.pool.query(
|
|
2517
|
+
`SELECT * FROM credit_fundings
|
|
2518
|
+
WHERE credit_id = $1 AND draw_id = $2
|
|
2519
|
+
ORDER BY created_at ASC, fund_id ASC`,
|
|
2520
|
+
[args.creditId, args.drawId]
|
|
2521
|
+
);
|
|
2522
|
+
return rows.map(fundingRecordFromRow);
|
|
2523
|
+
}
|
|
2497
2524
|
/** Fix the funding-time receipt tuple inside the rail's open transaction. */
|
|
2498
2525
|
async completeFunding(args) {
|
|
2499
2526
|
const q = args.tx ?? this.pool;
|
|
@@ -2693,7 +2720,10 @@ var CreditLedger = class {
|
|
|
2693
2720
|
[args.creditId, args.fundId, settledAt]
|
|
2694
2721
|
);
|
|
2695
2722
|
if (args.depositOutbox) {
|
|
2696
|
-
await args.depositOutbox.enqueue(client,
|
|
2723
|
+
await args.depositOutbox.enqueue(client, {
|
|
2724
|
+
...args.depositOutbox.payload,
|
|
2725
|
+
expiryMs: credit.expiryMs
|
|
2726
|
+
});
|
|
2697
2727
|
}
|
|
2698
2728
|
await client.query("COMMIT");
|
|
2699
2729
|
return {
|
|
@@ -2864,7 +2894,10 @@ var CreditLedger = class {
|
|
|
2864
2894
|
]
|
|
2865
2895
|
);
|
|
2866
2896
|
if (args.depositOutbox) {
|
|
2867
|
-
await args.depositOutbox.enqueue(client,
|
|
2897
|
+
await args.depositOutbox.enqueue(client, {
|
|
2898
|
+
...args.depositOutbox.payload,
|
|
2899
|
+
expiryMs: credit.expiryMs
|
|
2900
|
+
});
|
|
2868
2901
|
}
|
|
2869
2902
|
await client.query("COMMIT");
|
|
2870
2903
|
return {
|
|
@@ -4330,7 +4363,10 @@ function fundingRecordFromRow(row) {
|
|
|
4330
4363
|
callerPubkey: row.caller_pubkey,
|
|
4331
4364
|
balanceAfterMicro: row.balance_after_micro === null ? null : toSafeInt(row.balance_after_micro),
|
|
4332
4365
|
ledgerSeq: row.ledger_seq === null ? null : toSafeInt(row.ledger_seq),
|
|
4333
|
-
receipt: row.receipt
|
|
4366
|
+
receipt: row.receipt,
|
|
4367
|
+
jobId: row.job_id ?? null,
|
|
4368
|
+
drawId: row.draw_id ?? null,
|
|
4369
|
+
paymentSeq: row.payment_seq === null || row.payment_seq === void 0 ? null : toSafeInt(row.payment_seq)
|
|
4334
4370
|
};
|
|
4335
4371
|
}
|
|
4336
4372
|
function invoiceRecordFromRow(row) {
|