@dvmkit/sdk 0.10.1 → 0.12.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.
Files changed (57) hide show
  1. package/dist/{chunk-STJBBVNL.js → chunk-2VGMZ7VF.js} +487 -71
  2. package/dist/{chunk-3Q6FTZDB.js → chunk-3YFFZLW7.js} +2 -2
  3. package/dist/{chunk-VMHYGKWT.js → chunk-566CFXGU.js} +9 -1
  4. package/dist/chunk-5H7P3ORL.js +92 -0
  5. package/dist/{chunk-3R7NQA3Z.js → chunk-7KQLPVV7.js} +1 -1
  6. package/dist/{chunk-JNECYURT.js → chunk-D4FFS3IS.js} +1 -1
  7. package/dist/{chunk-VTHYQCDB.js → chunk-E7ZBCT5U.js} +1 -1
  8. package/dist/{chunk-MMGSYMIC.js → chunk-EP7OVWI5.js} +1 -1
  9. package/dist/{chunk-LDIPVPKI.js → chunk-FFRTAQUW.js} +1 -1
  10. package/dist/chunk-H3GGFEE5.js +57 -0
  11. package/dist/{chunk-M3T5JYDJ.js → chunk-HNXMWHLU.js} +1 -1
  12. package/dist/{chunk-UKD3R2KU.js → chunk-HW2UCOOC.js} +4 -55
  13. package/dist/{chunk-FFXXGCVG.js → chunk-ITRSITFP.js} +1 -1
  14. package/dist/{chunk-MU3IE434.js → chunk-JLT2YIBS.js} +267 -52
  15. package/dist/{chunk-KFCEXCZM.js → chunk-KJZVTWMX.js} +1 -1
  16. package/dist/{chunk-W3VGCNG6.js → chunk-LDKV4UHI.js} +1 -1
  17. package/dist/{chunk-AJ6UHXUA.js → chunk-M4NFYEEY.js} +1 -1
  18. package/dist/{chunk-MB6R4XPZ.js → chunk-NS2OMIU7.js} +15 -3
  19. package/dist/{chunk-YOSZIWC3.js → chunk-POYUX2NN.js} +149 -11
  20. package/dist/{chunk-VUGEEMLT.js → chunk-RPUFWIT4.js} +11 -89
  21. package/dist/{chunk-SYBFMHXQ.js → chunk-S7PIFHE4.js} +590 -67
  22. package/dist/{chunk-2OGBZPPJ.js → chunk-TWKQFIOW.js} +21 -3
  23. package/dist/{chunk-EWZFANHJ.js → chunk-VWIMQ5H5.js} +1 -1
  24. package/dist/{chunk-2XQLL6N6.js → chunk-WFCVS6QB.js} +2 -2
  25. package/dist/{chunk-QGNXYVBO.js → chunk-Z4FOPROB.js} +17 -0
  26. package/dist/{content-retention-CrILCNxk.d.ts → content-retention-a1yRdmhI.d.ts} +1 -1
  27. package/dist/{credit-ledger-4PZNAMDT.js → credit-ledger-MF23UKRJ.js} +6 -3
  28. package/dist/{credit-menu-BWsVqMh-.d.ts → credit-menu-B2T-O9oY.d.ts} +11 -4
  29. package/dist/{fx-BM5h4o5S.d.ts → fx-DLhscRUh.d.ts} +1 -1
  30. package/dist/index.d.ts +5 -5
  31. package/dist/index.js +6 -5
  32. package/dist/internal/caller.d.ts +8 -6
  33. package/dist/internal/caller.js +27 -22
  34. package/dist/internal/server.d.ts +7 -7
  35. package/dist/internal/server.js +24 -22
  36. package/dist/{job-store-92v8e1LQ.d.ts → job-store-B8Ijr5V6.d.ts} +3 -1
  37. package/dist/{lightning-backend-9oky_wJi.d.ts → lightning-backend-DmwMSgaM.d.ts} +1 -1
  38. package/dist/memory-credit-ledger-ERD764PS.js +14 -0
  39. package/dist/{mpp-setup-FURD45LI.js → mpp-setup-JU3MT7QX.js} +3 -3
  40. package/dist/{payout-reporter-HVJ6WUF3.js → payout-reporter-NXWQVKXW.js} +2 -2
  41. package/dist/{postgres-consumed-credential-store-WO6OCFXZ.js → postgres-consumed-credential-store-WXJLM6J7.js} +1 -1
  42. package/dist/{postgres-job-store-H45PRBLA.js → postgres-job-store-ZVMAN6L2.js} +2 -2
  43. package/dist/{postgres-replay-store-XXJSA457.js → postgres-replay-store-QJ4FG6AR.js} +2 -2
  44. package/dist/{pricing-X4XU5HXY.js → pricing-KCLENT2C.js} +3 -3
  45. package/dist/{revenue-reporter-EV3K5L6B.js → revenue-reporter-HD4GMXGD.js} +2 -2
  46. package/dist/server/index.d.ts +30 -12
  47. package/dist/server/index.js +32 -30
  48. package/dist/{step-cache--7yA5Ihr.d.ts → step-cache-DQqpwXa8.d.ts} +206 -47
  49. package/dist/{tempo-charge-store-5JOIYUIH.js → tempo-charge-store-7LTUAQHQ.js} +2 -2
  50. package/dist/{tempo-session-store-S6QMLQUA.js → tempo-session-store-LYAIDR2B.js} +3 -3
  51. package/dist/testing/index.d.ts +3 -3
  52. package/dist/testing/index.js +6 -6
  53. package/dist/{usd-C7lvLvLk.d.ts → usd-D5kk2nIT.d.ts} +1 -1
  54. package/dist/{x402-EN5LSOVM.js → x402-RUJ4LUKF.js} +3 -3
  55. package/package.json +1 -1
  56. package/recipes/postgres/financial-export-v1.sql +19 -5
  57. package/dist/memory-credit-ledger-RP7DT5IY.js +0 -11
@@ -10,12 +10,15 @@ import {
10
10
  fifoOrder,
11
11
  growthRailValue,
12
12
  inKindDrawMsats,
13
+ isFundingRail,
13
14
  isInKindDepletion,
14
15
  isNonChannelBitcoinRail,
15
16
  lotOwedSats,
16
17
  netOwedSats,
18
+ refundAssetDelta,
19
+ refundRequest,
17
20
  x402SettlementPending
18
- } from "./chunk-STJBBVNL.js";
21
+ } from "./chunk-2VGMZ7VF.js";
19
22
 
20
23
  // src/sdk/server/memory-credit-ledger.ts
21
24
  import { randomUUID } from "crypto";
@@ -26,7 +29,9 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
26
29
  * machine and drawing on another would `credit_not_found`.
27
30
  */
28
31
  durable = false;
32
+ tempoCreditLossEvidenceVersion = 1;
29
33
  credits = /* @__PURE__ */ new Map();
34
+ refunds = /* @__PURE__ */ new Map();
30
35
  fundings = /* @__PURE__ */ new Map();
31
36
  invoices = /* @__PURE__ */ new Map();
32
37
  tempoLosses = /* @__PURE__ */ new Map();
@@ -35,7 +40,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
35
40
  /** Internal disposable transaction snapshot. The caller must serialize every ledger access. */
36
41
  forkForTransaction() {
37
42
  const fork = new _MemoryCreditLedger();
38
- for (const name of ["credits", "fundings", "invoices", "tempoLosses", "x402Losses"]) {
43
+ for (const name of ["credits", "fundings", "invoices", "tempoLosses", "x402Losses", "refunds"]) {
39
44
  const target = fork[name];
40
45
  for (const [key, value] of this[name]) target.set(key, structuredClone(value));
41
46
  }
@@ -54,6 +59,90 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
54
59
  if (wedged) throw x402SettlementPending(args.creditId ?? randomUUID(), wedged);
55
60
  return run(() => this.fundSync(args));
56
61
  }
62
+ /** Development accounting parity; this non-durable store cannot mount admin refunds. */
63
+ refundDraw(args) {
64
+ return run(() => {
65
+ const request = refundRequest(args);
66
+ const prior = this.refunds.get(args.refundId);
67
+ if (prior) {
68
+ if (prior.request !== request) throw new CreditLedgerError("refund_conflict", "This refundId was recorded with different arguments.");
69
+ return { ...prior.result, replayed: true };
70
+ }
71
+ const matches = [...this.credits.values()].flatMap((credit2) => [...credit2.draws.values()].filter((draw2) => args.jobId !== void 0 ? draw2.jobId === args.jobId : credit2.creditId === args.creditId && draw2.drawId === args.drawId).map((draw2) => ({ credit: credit2, draw: draw2 })));
72
+ if (matches.length !== 1 || !matches[0].draw.jobId) {
73
+ throw new CreditLedgerError("draw_not_found", "No unique job-bound draw matches this selector.");
74
+ }
75
+ const { credit, draw } = matches[0];
76
+ if (draw.status !== "settled") throw new CreditLedgerError("draw_not_completed", "Only a settled completed draw can be refunded.");
77
+ const nowMs = args.nowMs ?? Date.now();
78
+ const lastDrain = [...credit.drains.values()].filter((drain) => drain.status !== "released").sort((a, b) => b.ledgerSeq - a.ledgerSeq)[0];
79
+ const drained = lastDrain && lastDrain.balanceAfterMicro === 0 && (credit.lastFundingLedgerSeq === null || credit.lastFundingLedgerSeq < lastDrain.ledgerSeq) && ![...credit.draws.values()].some((later) => later.ledgerSeq > lastDrain.ledgerSeq && later.amountMicro > 0) && ![...this.fundings.values()].some((funding) => funding.creditId === credit.creditId && funding.ledgerSeq !== null && funding.ledgerSeq >= lastDrain.ledgerSeq && funding.amountMicro > 0);
80
+ if (credit.status !== "active" || credit.expiryMs <= nowMs) {
81
+ throw new CreditLedgerError("credit_not_open", "The original credit is no longer open for refunds.");
82
+ }
83
+ if (credit.tempoChannelId || credit.x402ChannelId) {
84
+ throw new CreditLedgerError("credit_refund_channel_unsupported", "Channel collateral cannot back a refund of settled spending.");
85
+ }
86
+ if (credit.balanceMicro === 0 && drained) {
87
+ if (credit.lastFundingLedgerSeq === null) {
88
+ throw new CreditLedgerError("credit_refund_state_unavailable", "The original credit's historical funding and drain order cannot be established.");
89
+ }
90
+ throw new CreditLedgerError("credit_not_open", "The original credit is no longer open for refunds.");
91
+ }
92
+ const before = [...this.refunds.values()].reduce((sum, refund) => sum + (refund.result.creditId === credit.creditId && refund.result.drawId === draw.drawId ? refund.result.amountMicro : 0), 0);
93
+ const amountMicro = args.amountMicro ?? draw.amountMicro - before;
94
+ if (amountMicro <= 0 || amountMicro > draw.amountMicro - before) {
95
+ throw new CreditLedgerError("refund_exceeds_draw", "The refund exceeds the draw's remaining unrefunded charge.");
96
+ }
97
+ if (!isFundingRail(credit.rail)) throw new CreditLedgerError("credit_refund_basis_unavailable", "The original funding rail is not recorded on this older credit.");
98
+ const bitcoin = isNonChannelBitcoinRail(credit.rail);
99
+ const originalSats = draw.settledSats ?? null;
100
+ if (bitcoin && originalSats === null) throw new CreditLedgerError("credit_refund_basis_unavailable", "The original Bitcoin value is not provable from this older draw.");
101
+ const after = before + amountMicro;
102
+ const restoredSats = bitcoin ? refundAssetDelta(originalSats, draw.amountMicro, before, after) : null;
103
+ const restoredMsats = restoredSats === null ? refundAssetDelta(draw.drawMsats, draw.amountMicro, before, after) : restoredSats * 1e3;
104
+ const restoredNative = draw.drawNative === null ? null : refundAssetDelta(draw.drawNative, draw.amountMicro, before, after);
105
+ const balanceAfterMicro = credit.balanceMicro + amountMicro;
106
+ const ledgerSeq = credit.lastLedgerSeq + 1;
107
+ if (![
108
+ balanceAfterMicro,
109
+ ledgerSeq,
110
+ credit.msatsRemaining + restoredMsats,
111
+ (credit.nativeRemaining ?? 0) + (restoredNative ?? 0)
112
+ ].every(Number.isSafeInteger)) {
113
+ throw new Error("credit ledger: refund exceeds safe integer range");
114
+ }
115
+ credit.balanceMicro = balanceAfterMicro;
116
+ credit.lastLedgerSeq = ledgerSeq;
117
+ credit.msatsRemaining += restoredMsats;
118
+ if (credit.nativeRemaining !== null) credit.nativeRemaining += restoredNative ?? 0;
119
+ if (bitcoin) credit.lots.push({
120
+ lotId: `lot:refund:${randomUUID()}`,
121
+ creditId: credit.creditId,
122
+ rail: credit.rail,
123
+ satsFunded: restoredSats,
124
+ satsBasisKnown: true,
125
+ creditedMicro: amountMicro,
126
+ remainingMicro: amountMicro,
127
+ fundingRef: args.refundId,
128
+ createdAt: nowMs
129
+ });
130
+ const result = {
131
+ refundId: args.refundId,
132
+ creditId: credit.creditId,
133
+ drawId: draw.drawId,
134
+ jobId: draw.jobId,
135
+ amountMicro,
136
+ currency: credit.currency,
137
+ ledgerSeq,
138
+ refundedAt: nowMs,
139
+ balanceAfterMicro,
140
+ replayed: false
141
+ };
142
+ this.refunds.set(args.refundId, { request, result });
143
+ return { ...result };
144
+ });
145
+ }
57
146
  async draw(args) {
58
147
  const blocking = await this.blockingRefundForCredit(
59
148
  args.creditId,
@@ -68,8 +157,9 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
68
157
  blockingRefundForCredit(creditId, statuses) {
69
158
  return this.blockingX402Refund(this.credits.get(creditId)?.x402ChannelId, statuses);
70
159
  }
71
- growDraw(args) {
72
- return run(() => this.growDrawSync(args));
160
+ async growDraw(args) {
161
+ const blocking = args.spendExistingBalance ? await this.blockingRefundForCredit(args.creditId, X402_SPEND_BLOCKING_SETTLEMENT_STATUSES) : void 0;
162
+ return run(() => this.growDrawSync(args, blocking));
73
163
  }
74
164
  settle(args) {
75
165
  return run(() => {
@@ -427,6 +517,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
427
517
  }
428
518
  );
429
519
  }
520
+ existing.lastFundingLedgerSeq = existing.lastLedgerSeq;
430
521
  existing.balanceMicro += args.amountMicro;
431
522
  existing.expiryMs = args.expiryMs;
432
523
  applyBasis(existing, b);
@@ -457,6 +548,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
457
548
  expiryMs: args.expiryMs,
458
549
  status: "active",
459
550
  lastLedgerSeq: 0,
551
+ lastFundingLedgerSeq: 0,
460
552
  createdAt: nowMs,
461
553
  draws: /* @__PURE__ */ new Map(),
462
554
  rail: null,
@@ -537,7 +629,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
537
629
  credit.draws.set(args.drawId, draw);
538
630
  return { ...drawResult(draw, credit), replayed: false };
539
631
  }
540
- growDrawSync(args) {
632
+ growDrawSync(args, x402Refund) {
541
633
  assertAmount(args.addAmountMicro, { min: 1 });
542
634
  const credit = this.requireCredit(args.creditId);
543
635
  const draw = credit.draws.get(args.drawId);
@@ -562,6 +654,16 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
562
654
  { expectedJobId: draw.jobId }
563
655
  );
564
656
  }
657
+ if (args.spendExistingBalance) {
658
+ if (credit.expiryMs <= (args.nowMs ?? Date.now())) {
659
+ throw new CreditLedgerError("credit_expired", `credit ${args.creditId} expired`, {
660
+ expiryMs: credit.expiryMs,
661
+ balanceMicro: credit.balanceMicro
662
+ });
663
+ }
664
+ if (x402Refund) throw x402SettlementPending(args.creditId, x402Refund);
665
+ if (credit.tempoChannelId) throw new CreditLedgerError("tempo_channel_closing", "Tempo balance growth requires a durable channel lifecycle");
666
+ }
565
667
  const pending = pendingSums(credit);
566
668
  const available = credit.balanceMicro - pending.micro;
567
669
  const headroom = args.capMicro === void 0 ? args.addAmountMicro : Math.max(0, args.capMicro - draw.grownMicro);
@@ -687,6 +789,15 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
687
789
  return run(() => {
688
790
  const channelId = evidence.channelId.toLowerCase();
689
791
  const observedAt = evidence.observedAt ?? Date.now();
792
+ const refunded = evidence.refundedToPayerNative ?? 0n;
793
+ if (refunded < 0n) throw new Error("Tempo close refund must be nonnegative");
794
+ const payerExit = evidence.closeKind === "payer_exit";
795
+ if (payerExit && evidence.refundedToPayerNative !== void 0 || evidence.closeKind === "cooperative_close" && evidence.refundedToPayerNative === void 0) {
796
+ throw new Error("Tempo close kind requires matching exact cooperative refund evidence");
797
+ }
798
+ const lossNative = (payerExit ? evidence.consumedNative : evidence.highestVoucherNative) - evidence.settledOnChainNative - (payerExit ? 0n : refunded);
799
+ const lossBasis = payerExit ? "payer_exit" : evidence.refundedToPayerNative === void 0 ? "caller_asserted" : "cooperative_close";
800
+ if (lossNative <= 0n) return [...this.tempoLosses.values()].filter((loss) => loss.channelId === channelId);
690
801
  for (const credit of this.credits.values()) {
691
802
  if (credit.tempoChannelId !== channelId) continue;
692
803
  if (credit.status === "unbacked") continue;
@@ -701,6 +812,9 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
701
812
  highestVoucherNative: evidence.highestVoucherNative,
702
813
  consumedServiceMicro,
703
814
  consumedNative: evidence.consumedNative,
815
+ refundedToPayerNative: evidence.refundedToPayerNative ?? null,
816
+ lossNative,
817
+ lossBasis,
704
818
  observedAt
705
819
  });
706
820
  credit.status = "unbacked";
@@ -708,9 +822,9 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
708
822
  return [...this.tempoLosses.values()].filter((loss) => loss.channelId === channelId);
709
823
  });
710
824
  }
711
- listTempoCreditLosses(args) {
825
+ listTempoCreditLosses(args, _tx) {
712
826
  return Promise.resolve(
713
- [...this.tempoLosses.values()].sort((a, b) => b.observedAt - a.observedAt || a.creditId.localeCompare(b.creditId)).slice(0, args?.limit ?? 50)
827
+ [...this.tempoLosses.values()].filter((loss) => !args?.channelId || loss.channelId === args.channelId.toLowerCase()).sort((a, b) => b.observedAt - a.observedAt || a.creditId.localeCompare(b.creditId)).slice(0, args?.limit ?? 50)
714
828
  );
715
829
  }
716
830
  terminalizeX402Credit(evidence, _tx) {
@@ -841,7 +955,9 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
841
955
  sentAt: null,
842
956
  releasedAt: null,
843
957
  writeOffNote: null,
844
- writtenOffAt: null
958
+ writtenOffAt: null,
959
+ provenRefundNative: null,
960
+ refundPaymentProven: false
845
961
  };
846
962
  applyLotDebits(credit, drain.lotDebits, -1);
847
963
  credit.drains.set(args.drainId, drain);
@@ -874,7 +990,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
874
990
  const lots = openLots(credit);
875
991
  const covered = lots.reduce((sum, lot) => sum + lot.remainingMicro, 0);
876
992
  const basisless = lots.reduce(
877
- (sum, lot) => sum + (lot.satsFunded === 0 ? lot.remainingMicro : 0),
993
+ (sum, lot) => sum + (lot.satsFunded === 0 && !lot.satsBasisKnown ? lot.remainingMicro : 0),
878
994
  0
879
995
  );
880
996
  const inKind = covered >= credit.balanceMicro && basisless === 0;
@@ -947,7 +1063,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
947
1063
  for (const drain of credit.drains.values()) {
948
1064
  if (drain.status !== "pending" && drain.status !== "exit_required" || drain.method !== "tempo") continue;
949
1065
  if (drain.createdAt > args.createdBeforeMs) continue;
950
- if (!args.includeResolved && drain.writtenOffAt !== null) continue;
1066
+ if (!args.includeResolved && !args.includeWrittenOff && drain.writtenOffAt !== null) continue;
951
1067
  out.push(drainRecord(drain, credit));
952
1068
  }
953
1069
  }
@@ -992,6 +1108,25 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
992
1108
  return { drain: drainRecord(drain, credit), replayed: false };
993
1109
  });
994
1110
  }
1111
+ recordTempoDrainRefund(args) {
1112
+ const amount = String(args.refundedNative);
1113
+ if (!/^\d{1,78}$/.test(amount)) return Promise.reject(new CreditLedgerError("invalid_basis", "Tempo refund evidence must be a bounded non-negative integer."));
1114
+ return this.recordTempoDrainRefundEvidence(args, amount);
1115
+ }
1116
+ recordTempoDrainPayment(args) {
1117
+ return this.recordTempoDrainRefundEvidence(args, null);
1118
+ }
1119
+ recordTempoDrainRefundEvidence(args, amount) {
1120
+ return run(() => {
1121
+ const credit = this.credits.get(args.creditId);
1122
+ const drain = credit?.drains.get(args.drainId);
1123
+ if (!credit?.tempoChannelId || !drain || drain.method !== "tempo" || drain.status !== "pending" && drain.status !== "exit_required") return;
1124
+ if (amount !== null && (drain.provenRefundNative === null || BigInt(amount) > BigInt(drain.provenRefundNative))) {
1125
+ drain.provenRefundNative = amount;
1126
+ }
1127
+ drain.refundPaymentProven ||= amount === null || BigInt(amount) > 0n;
1128
+ });
1129
+ }
995
1130
  releaseDrain(args) {
996
1131
  return run(() => {
997
1132
  const { credit, drain } = this.requireDrain(args.creditId, args.drainId);
@@ -1115,6 +1250,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
1115
1250
  if (isNonChannelBitcoinRail(credit.rail)) {
1116
1251
  const depletion = depleteLots(openLots(credit), draw.amountMicro);
1117
1252
  const settledMsats = inKindDrawMsats(depletion, draw.amountMicro);
1253
+ draw.settledSats = settledMsats === null ? null : settledMsats / 1e3;
1118
1254
  if (settledMsats !== null && settledMsats !== draw.drawMsats) {
1119
1255
  draw.allocatedMsats = draw.drawMsats;
1120
1256
  draw.drawMsats = settledMsats;
@@ -1295,7 +1431,9 @@ function drainRecord(drain, credit) {
1295
1431
  sentAt: drain.sentAt,
1296
1432
  releasedAt: drain.releasedAt,
1297
1433
  writeOffNote: drain.writeOffNote,
1298
- writtenOffAt: drain.writtenOffAt
1434
+ writtenOffAt: drain.writtenOffAt,
1435
+ provenRefundNative: drain.provenRefundNative,
1436
+ refundPaymentProven: drain.refundPaymentProven
1299
1437
  };
1300
1438
  }
1301
1439
  function assertAmount(amountMicro, opts) {
@@ -1,15 +1,23 @@
1
1
  import {
2
- canonicaliseForSigning
3
- } from "./chunk-UKD3R2KU.js";
2
+ computeResultHash,
3
+ isDrainReceipt,
4
+ isFundingReceipt,
5
+ verifyDrainReceipt,
6
+ verifyFundingReceipt,
7
+ verifyReceipt
8
+ } from "./chunk-5H7P3ORL.js";
4
9
  import {
5
10
  DvmError
6
11
  } from "./chunk-BPYMEMQX.js";
12
+ import {
13
+ canonicaliseForSigning
14
+ } from "./chunk-H3GGFEE5.js";
7
15
  import {
8
16
  callerLoggers
9
17
  } from "./chunk-66HGCPBU.js";
10
18
  import {
11
19
  diagnosticConsole
12
- } from "./chunk-QGNXYVBO.js";
20
+ } from "./chunk-Z4FOPROB.js";
13
21
 
14
22
  // src/lib/cashu/lock-pubkey.ts
15
23
  function toLockPubkey(raw) {
@@ -1553,82 +1561,6 @@ function hexToBytes4(hex) {
1553
1561
  return out;
1554
1562
  }
1555
1563
 
1556
- // src/lib/receipt.ts
1557
- import { schnorr as schnorr4 } from "@noble/curves/secp256k1.js";
1558
- import { sha256 as sha2564 } from "@noble/hashes/sha2.js";
1559
- import { bytesToHex as bytesToHex5, hexToBytes as hexToBytes5 } from "@noble/hashes/utils.js";
1560
- function computeResultHash(summary, artifactContents) {
1561
- const artifactHashes = artifactContents.map(
1562
- (content) => bytesToHex5(sha2564(canonicaliseForSigning(content)))
1563
- );
1564
- return bytesToHex5(
1565
- sha2564(
1566
- canonicaliseForSigning({
1567
- summary: summary ?? null,
1568
- artifact_hashes: artifactHashes
1569
- })
1570
- )
1571
- );
1572
- }
1573
- function signReceipt(unsigned, secretHex) {
1574
- const bytes = canonicaliseForSigning(unsigned);
1575
- const signature = bytesToHex5(schnorr4.sign(bytes, hexToBytes5(secretHex)));
1576
- return { ...unsigned, signature };
1577
- }
1578
- function verifyReceipt(receipt) {
1579
- try {
1580
- const { signature, ...unsigned } = receipt;
1581
- const bytes = canonicaliseForSigning(unsigned);
1582
- return schnorr4.verify(hexToBytes5(signature), bytes, hexToBytes5(receipt.receipt_pubkey));
1583
- } catch {
1584
- return false;
1585
- }
1586
- }
1587
- function isSignedJobReceipt(value) {
1588
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1589
- const r = value;
1590
- const paid = r.paid;
1591
- return r.v === 1 && typeof r.job_id === "string" && typeof r.dvm_id === "string" && typeof r.dvm === "string" && typeof r.capability === "string" && (r.outcome === "completed" || r.outcome === "failed" || r.outcome === "cancelled") && typeof r.seq === "number" && typeof r.issued_at === "number" && typeof r.receipt_pubkey === "string" && typeof r.signature === "string" && !!paid && typeof paid === "object" && !Array.isArray(paid) && typeof paid.msats === "number";
1592
- }
1593
- function signDrainReceipt(unsigned, secretHex) {
1594
- const bytes = canonicaliseForSigning(unsigned);
1595
- const signature = bytesToHex5(schnorr4.sign(bytes, hexToBytes5(secretHex)));
1596
- return { ...unsigned, signature };
1597
- }
1598
- function signFundingReceipt(unsigned, secretHex) {
1599
- const bytes = canonicaliseForSigning(unsigned);
1600
- const signature = bytesToHex5(schnorr4.sign(bytes, hexToBytes5(secretHex)));
1601
- return { ...unsigned, signature };
1602
- }
1603
- function isFundingReceipt(value) {
1604
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1605
- const r = value;
1606
- return r.v === 1 && r.kind === "credit_funding" && typeof r.credit_id === "string" && typeof r.fund_id === "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";
1607
- }
1608
- function verifyFundingReceipt(receipt) {
1609
- try {
1610
- const { signature, ...unsigned } = receipt;
1611
- const bytes = canonicaliseForSigning(unsigned);
1612
- return schnorr4.verify(hexToBytes5(signature), bytes, hexToBytes5(receipt.receipt_pubkey));
1613
- } catch {
1614
- return false;
1615
- }
1616
- }
1617
- function isDrainReceipt(value) {
1618
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1619
- const r = value;
1620
- return r.v === 1 && r.kind === "credit_drain" && typeof r.credit_id === "string" && typeof r.drain_id === "string" && (r.event === "requested" || r.event === "parked" || r.event === "picked_up" || r.event === "sent" || r.event === "released") && typeof r.method === "string" && typeof r.amount_micro === "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";
1621
- }
1622
- function verifyDrainReceipt(receipt) {
1623
- try {
1624
- const { signature, ...unsigned } = receipt;
1625
- const bytes = canonicaliseForSigning(unsigned);
1626
- return schnorr4.verify(hexToBytes5(signature), bytes, hexToBytes5(receipt.receipt_pubkey));
1627
- } catch {
1628
- return false;
1629
- }
1630
- }
1631
-
1632
1564
  // src/lib/receipt-verify.ts
1633
1565
  function attestedDvmIdentity(builder) {
1634
1566
  const builderPubkey = authenticatedBuilderPubkey(builder);
@@ -1924,16 +1856,6 @@ export {
1924
1856
  buildAttestation,
1925
1857
  signAttestation,
1926
1858
  verifyAttestation,
1927
- computeResultHash,
1928
- signReceipt,
1929
- verifyReceipt,
1930
- isSignedJobReceipt,
1931
- signDrainReceipt,
1932
- signFundingReceipt,
1933
- isFundingReceipt,
1934
- verifyFundingReceipt,
1935
- isDrainReceipt,
1936
- verifyDrainReceipt,
1937
1859
  attestedDvmIdentity,
1938
1860
  authenticatedBuilderPubkey,
1939
1861
  verifyJobReceipt,