@dvmkit/sdk 0.14.2 → 0.16.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.
Files changed (53) hide show
  1. package/dist/{chunk-IVW5UMD3.js → chunk-2UZOJRRS.js} +1 -1
  2. package/dist/{chunk-G47UY3BK.js → chunk-4IFZHJQK.js} +1 -1
  3. package/dist/{chunk-BAHZK334.js → chunk-5U2RG3ZW.js} +6 -2
  4. package/dist/{chunk-GB2N4NG5.js → chunk-7N5VDCG3.js} +2 -2
  5. package/dist/{chunk-CVT5LTAK.js → chunk-7QGS27UT.js} +1 -1
  6. package/dist/{chunk-FOXGN4KQ.js → chunk-ELNWQS24.js} +1 -1
  7. package/dist/{chunk-I2H2XYQV.js → chunk-F2LNWZCV.js} +1 -1
  8. package/dist/{chunk-RQK7OFJO.js → chunk-FRGKANTZ.js} +1 -1
  9. package/dist/{chunk-2I6NXIPG.js → chunk-ICHC4VDZ.js} +1 -1
  10. package/dist/{chunk-LM6E4YHQ.js → chunk-K4ZQE7IB.js} +2 -2
  11. package/dist/{chunk-FL6Q3JNJ.js → chunk-KVKJ7R5V.js} +56 -2
  12. package/dist/{chunk-P5KQKLWL.js → chunk-MD34LE6M.js} +1 -1
  13. package/dist/{chunk-PJAKJD2U.js → chunk-N4SBDUVD.js} +31 -9
  14. package/dist/{chunk-IUODXRQN.js → chunk-OYBSDJR6.js} +2 -2
  15. package/dist/{chunk-CRH6BMMG.js → chunk-PBT3H2LZ.js} +1 -1
  16. package/dist/{chunk-33J3NQDZ.js → chunk-PP5WHB6T.js} +1 -1
  17. package/dist/{chunk-VG74TVFF.js → chunk-SGSHDMHP.js} +114 -41
  18. package/dist/{chunk-R7FH7SHX.js → chunk-TN6MWTZI.js} +2 -2
  19. package/dist/{chunk-R3FSW66G.js → chunk-V4CBI5HB.js} +39 -13
  20. package/dist/{chunk-ZO2ZAPG3.js → chunk-V73WRF46.js} +1 -1
  21. package/dist/{chunk-7NZRJPEP.js → chunk-VQHBJXBL.js} +1 -1
  22. package/dist/{chunk-LZFZGY7L.js → chunk-XBQTFOIT.js} +1 -1
  23. package/dist/{chunk-QRYGBKCR.js → chunk-XSF5YTEY.js} +1 -1
  24. package/dist/{content-retention-DA2mlW31.d.ts → content-retention-BASsjgKw.d.ts} +1 -1
  25. package/dist/{credit-ledger-EZDZYLSK.js → credit-ledger-VWZ5NP7V.js} +3 -3
  26. package/dist/{credit-menu-BXHL3jHA.d.ts → credit-menu-B239nIY5.d.ts} +13 -6
  27. package/dist/{fx-UnO-P6Cj.d.ts → fx-BmvWGISH.d.ts} +1 -1
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.js +4 -4
  30. package/dist/internal/caller.d.ts +11 -7
  31. package/dist/internal/caller.js +7 -7
  32. package/dist/internal/server.d.ts +7 -7
  33. package/dist/internal/server.js +21 -21
  34. package/dist/{job-store-AxjHh5Gp.d.ts → job-store-CA7u1nHV.d.ts} +11 -3
  35. package/dist/{lightning-backend-C5_GKiKR.d.ts → lightning-backend-BOcopzXk.d.ts} +1 -1
  36. package/dist/{memory-credit-ledger-REZGHPJP.js → memory-credit-ledger-DZWRQGSF.js} +4 -4
  37. package/dist/{mpp-setup-RG5JDMIO.js → mpp-setup-3NJY354I.js} +3 -3
  38. package/dist/{payout-reporter-DDQ7FGRC.js → payout-reporter-P3652TLG.js} +2 -2
  39. package/dist/{postgres-consumed-credential-store-I4WTNVQZ.js → postgres-consumed-credential-store-S2CBQ4NO.js} +1 -1
  40. package/dist/{postgres-job-store-VDSDXCHR.js → postgres-job-store-JRSG54VJ.js} +3 -3
  41. package/dist/{postgres-replay-store-3F5FCUXN.js → postgres-replay-store-ZPILIJIW.js} +2 -2
  42. package/dist/{pricing-HLYEGPXD.js → pricing-3P7KAONY.js} +3 -3
  43. package/dist/{revenue-reporter-RIEHBKRA.js → revenue-reporter-2P3PWJJM.js} +2 -2
  44. package/dist/server/index.d.ts +14 -12
  45. package/dist/server/index.js +28 -28
  46. package/dist/{step-cache-MA3hpa7F.d.ts → step-cache-BCRHimiY.d.ts} +23 -1
  47. package/dist/{tempo-charge-store-B5SYDCBK.js → tempo-charge-store-2LK6IDLS.js} +2 -2
  48. package/dist/{tempo-session-store-FHW7N22I.js → tempo-session-store-5MHCH3YW.js} +3 -3
  49. package/dist/testing/index.d.ts +7 -4
  50. package/dist/testing/index.js +7 -7
  51. package/dist/{usd-CLGrKw9p.d.ts → usd-B8_WMfHT.d.ts} +1 -1
  52. package/dist/{x402-AY6P5KV4.js → x402-6T73AZQ6.js} +3 -3
  53. package/package.json +1 -1
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-XRLKGCAW.js";
6
6
  import {
7
7
  x402EarnedCeiling
8
- } from "./chunk-2I6NXIPG.js";
8
+ } from "./chunk-ICHC4VDZ.js";
9
9
  import {
10
10
  createX402FacilitatorAuthHeaders,
11
11
  createX402FacilitatorClient,
@@ -14,13 +14,13 @@ import {
14
14
  verifyWithFacilitator,
15
15
  withPaymentDiagnostics,
16
16
  withPaymentStage
17
- } from "./chunk-I2H2XYQV.js";
17
+ } from "./chunk-F2LNWZCV.js";
18
18
  import {
19
19
  MemoryCreditLedger
20
- } from "./chunk-33J3NQDZ.js";
20
+ } from "./chunk-PP5WHB6T.js";
21
21
  import {
22
22
  PostgresJobStore
23
- } from "./chunk-PJAKJD2U.js";
23
+ } from "./chunk-N4SBDUVD.js";
24
24
  import {
25
25
  SIGNED_ENVELOPE_FIELDS,
26
26
  SignedRequestError,
@@ -28,7 +28,7 @@ import {
28
28
  humanizeZodIssues,
29
29
  signedRequestInput,
30
30
  zodIssuesOf
31
- } from "./chunk-ZO2ZAPG3.js";
31
+ } from "./chunk-V73WRF46.js";
32
32
  import {
33
33
  MemoryJobStore,
34
34
  UNCAPPABLE_ASK_TOTAL,
@@ -37,7 +37,7 @@ import {
37
37
  isJobRetentionStore,
38
38
  isReceiptIssuingStore,
39
39
  isStreamableJobStore
40
- } from "./chunk-R3FSW66G.js";
40
+ } from "./chunk-V4CBI5HB.js";
41
41
  import {
42
42
  ContentHoldError,
43
43
  JobCancelledError,
@@ -47,13 +47,16 @@ import {
47
47
  contentMetadata,
48
48
  fromJobRecord,
49
49
  hasCallerDeadline,
50
+ holdJobHistory,
50
51
  isContentHoldStore,
51
52
  isTerminal,
52
53
  isYieldMessage,
53
54
  localMessage,
54
55
  providerMessage,
55
- toJobRecord
56
- } from "./chunk-FL6Q3JNJ.js";
56
+ releaseJobHistory,
57
+ toJobRecord,
58
+ visibleJobMessages
59
+ } from "./chunk-KVKJ7R5V.js";
57
60
  import {
58
61
  ADMIN_AUTH_CLOCK_SKEW_SECONDS,
59
62
  ADMIN_AUTH_NONCE_TTL_SECONDS,
@@ -75,7 +78,7 @@ import {
75
78
  receiptPubkeyFromSecret,
76
79
  toLockPubkey,
77
80
  verifyChallenge
78
- } from "./chunk-LZFZGY7L.js";
81
+ } from "./chunk-XBQTFOIT.js";
79
82
  import {
80
83
  X402_BATCH_SETTLEMENT_SCHEME,
81
84
  X402_DEFAULT_FACILITATOR,
@@ -102,7 +105,7 @@ import {
102
105
  } from "./chunk-SXL44PL5.js";
103
106
  import {
104
107
  createConsoleLogger
105
- } from "./chunk-7NZRJPEP.js";
108
+ } from "./chunk-VQHBJXBL.js";
106
109
  import {
107
110
  StepCache
108
111
  } from "./chunk-BQJIFRAZ.js";
@@ -119,7 +122,7 @@ import {
119
122
  roundUsd,
120
123
  satsToFiat,
121
124
  validateCurrency
122
- } from "./chunk-CVT5LTAK.js";
125
+ } from "./chunk-7QGS27UT.js";
123
126
  import {
124
127
  CreditLedger,
125
128
  CreditLedgerError,
@@ -135,7 +138,7 @@ import {
135
138
  isNonChannelBitcoinRail,
136
139
  netOwedSats,
137
140
  x402SettlementPending
138
- } from "./chunk-LM6E4YHQ.js";
141
+ } from "./chunk-K4ZQE7IB.js";
139
142
  import {
140
143
  parseStoreValue
141
144
  } from "./chunk-YG7G4DPZ.js";
@@ -153,7 +156,7 @@ import {
153
156
  } from "./chunk-5UC7TOQC.js";
154
157
  import {
155
158
  withPostgresRecoveryContext
156
- } from "./chunk-FOXGN4KQ.js";
159
+ } from "./chunk-ELNWQS24.js";
157
160
  import {
158
161
  DvmError,
159
162
  x402NetworkByCaip2
@@ -171,17 +174,17 @@ import {
171
174
  installHostedTempoCloseGuard,
172
175
  isTempoInsufficientFundsError,
173
176
  resolveTempoNetwork
174
- } from "./chunk-GB2N4NG5.js";
177
+ } from "./chunk-7N5VDCG3.js";
175
178
  import {
176
179
  loggers,
177
180
  pinDimension,
178
181
  withSpan,
179
182
  withTraceContext
180
- } from "./chunk-R7FH7SHX.js";
183
+ } from "./chunk-TN6MWTZI.js";
181
184
  import {
182
185
  createDiagnosticCapabilityAuthority,
183
186
  diagnosticConsole
184
- } from "./chunk-BAHZK334.js";
187
+ } from "./chunk-5U2RG3ZW.js";
185
188
 
186
189
  // src/sdk/server/lock-pubkey-store.ts
187
190
  async function initLockPubkeyTable(db) {
@@ -3183,6 +3186,26 @@ function isRecord(value) {
3183
3186
  return !!value && typeof value === "object" && !Array.isArray(value);
3184
3187
  }
3185
3188
 
3189
+ // src/sdk/server/upfront-payment.ts
3190
+ function upfrontPaymentFromDraw(draw) {
3191
+ const value = draw.railValue;
3192
+ const rail = value.rail;
3193
+ return {
3194
+ amount_msats: value.drawMsats,
3195
+ ...value.creditCurrency !== null && {
3196
+ amount_micro: draw.amountMicro,
3197
+ currency: value.creditCurrency
3198
+ },
3199
+ ...rail === "cashu" || rail === "x402" || rail === "tempo" || rail === "lightning" ? { rail } : {},
3200
+ ...value.drawNative !== null && value.nativeAsset !== null && {
3201
+ native_amount: value.drawNative,
3202
+ native_asset: value.nativeAsset
3203
+ },
3204
+ credit_id: draw.creditId,
3205
+ draw_id: draw.drawId
3206
+ };
3207
+ }
3208
+
3186
3209
  // src/sdk/server/payment-diagnostics.ts
3187
3210
  import { Errors } from "mppx";
3188
3211
  function paymentFailureFields(error) {
@@ -3562,7 +3585,18 @@ async function issueUpfrontChallenges(mpp, requiredMsats, resourcePath, btcUsdRa
3562
3585
  );
3563
3586
  }
3564
3587
  async function verifyUpfrontPayment(opts) {
3565
- return withPaymentDiagnostics(() => verifyUpfrontPaymentInScope(opts));
3588
+ const result = await withPaymentDiagnostics(() => verifyUpfrontPaymentInScope(opts));
3589
+ if (!result.error && !result.replayedDraw && !result.upfrontPayment && !opts.fundOnly) {
3590
+ result.upfrontPayment = {
3591
+ amount_msats: result.paidMsats,
3592
+ ...result.paymentRail && { rail: result.paymentRail },
3593
+ ...result.nativeAmount !== void 0 && result.nativeAsset !== void 0 && {
3594
+ native_amount: result.nativeAmount,
3595
+ native_asset: result.nativeAsset
3596
+ }
3597
+ };
3598
+ }
3599
+ return result;
3566
3600
  }
3567
3601
  async function verifyUpfrontPaymentInScope(opts) {
3568
3602
  const {
@@ -3894,7 +3928,7 @@ async function verifyUpfrontPaymentInScope(opts) {
3894
3928
  x402Requirements
3895
3929
  });
3896
3930
  }
3897
- const { verifyX402Payment } = await import("./x402-AY6P5KV4.js");
3931
+ const { verifyX402Payment } = await import("./x402-6T73AZQ6.js");
3898
3932
  const receipt = await withPaymentStage("verifier_broadcast", () => verifyX402Payment(
3899
3933
  x402Payment,
3900
3934
  x402Config,
@@ -4330,7 +4364,8 @@ async function verifyUpfrontPaymentInScope(opts) {
4330
4364
  creditId: draw.creditId,
4331
4365
  drawId: draw.drawId,
4332
4366
  drawAmountMicro: draw.amountMicro,
4333
- creditCurrency: ledgerCtx.priceFiat.currency
4367
+ creditCurrency: ledgerCtx.priceFiat.currency,
4368
+ upfrontPayment: upfrontPaymentFromDraw(draw)
4334
4369
  };
4335
4370
  } catch (err) {
4336
4371
  if (err instanceof CreditLedgerError) return creditLedgerErrorResult(err, x402Requirements);
@@ -4918,7 +4953,7 @@ async function verifyIncomingPaymentInScope(body, opts, snapshot) {
4918
4953
  snapshot
4919
4954
  });
4920
4955
  }
4921
- const { verifyX402Payment } = await import("./x402-AY6P5KV4.js");
4956
+ const { verifyX402Payment } = await import("./x402-6T73AZQ6.js");
4922
4957
  const receipt = await withPaymentStage("verifier_broadcast", () => verifyX402Payment(
4923
4958
  body.content.x402_payment,
4924
4959
  opts.x402Config,
@@ -5157,7 +5192,9 @@ async function verifyIncomingPaymentInScope(body, opts, snapshot) {
5157
5192
  };
5158
5193
  }
5159
5194
  }
5160
- return {};
5195
+ return { error: { status: 402, body: paymentErrorBody("payment_invalid", {
5196
+ message: "Payment method is not configured"
5197
+ }) } };
5161
5198
  }
5162
5199
  function midJobFundedMsats(snapshot, railMsats) {
5163
5200
  const pending = snapshot.pendingPaymentMsats ?? 0;
@@ -5367,7 +5404,7 @@ async function processIncomingPaymentInScope(job, body, opts) {
5367
5404
  try {
5368
5405
  const requiredMsats = job.pendingPaymentMsats ?? 0;
5369
5406
  const requiredUsdcMicro = job.pendingX402AmountUsdcMicro !== void 0 ? BigInt(job.pendingX402AmountUsdcMicro) : BigInt(msatsToUsdc(requiredMsats, rate));
5370
- const { verifyX402Payment } = await import("./x402-AY6P5KV4.js");
5407
+ const { verifyX402Payment } = await import("./x402-6T73AZQ6.js");
5371
5408
  const receipt = await withPaymentStage("verifier_broadcast", () => verifyX402Payment(
5372
5409
  body.content.x402_payment,
5373
5410
  opts.x402Config,
@@ -5966,7 +6003,8 @@ function withDrawBasis(info, ctx, committed) {
5966
6003
  const withDraw = {
5967
6004
  ...base2,
5968
6005
  drawId,
5969
- drawAmountMicro: draw.amountMicro
6006
+ drawAmountMicro: draw.amountMicro,
6007
+ ...!ctx.midJob && !ctx.fundOnly && { upfrontPayment: upfrontPaymentFromDraw(draw) }
5970
6008
  };
5971
6009
  if (!ctx.drawBasis) return withDraw;
5972
6010
  const { drawMsats, drawNative } = committed.added ?? draw.railValue;
@@ -13474,6 +13512,7 @@ var JobManager = class {
13474
13512
  // Bind live resolvers and recovery scaffolds to the store-allocated ask identity.
13475
13513
  paymentAskSeqs = /* @__PURE__ */ new WeakMap();
13476
13514
  reactivationAskSeqs = /* @__PURE__ */ new WeakMap();
13515
+ pendingPaymentMessages = /* @__PURE__ */ new WeakMap();
13477
13516
  // Every local input resume holds this queue through its durable wait update.
13478
13517
  // A prompt response and a payment NOTIFY must not mistake each other for a
13479
13518
  // different machine's successful claim.
@@ -13799,6 +13838,7 @@ var JobManager = class {
13799
13838
  status: "processing",
13800
13839
  messages: [],
13801
13840
  seq: 0,
13841
+ upfrontPayment: payment.upfrontPayment ? structuredClone(payment.upfrontPayment) : void 0,
13802
13842
  paidMsats: payment.paidMsats,
13803
13843
  paymentMint: payment.paymentMint,
13804
13844
  paymentRail: payment.paymentRail,
@@ -14050,7 +14090,7 @@ var JobManager = class {
14050
14090
  if (await this.adoptDurableTerminal(job)) return;
14051
14091
  const record = toJobRecord(job);
14052
14092
  if (isTerminal(job.status) && isStreamableJobStore(this.jobStore)) {
14053
- const durable = await this.jobStore.getMessages(job.id, 0);
14093
+ const durable = await this.jobStore.getMessages(job.id, 0, { includeHeld: true });
14054
14094
  if (durable.length >= record.messages.length) {
14055
14095
  record.messages = durable;
14056
14096
  const highSeq = durable.length ? durable[durable.length - 1].seq : record.seq;
@@ -15139,8 +15179,9 @@ var JobManager = class {
15139
15179
  }
15140
15180
  }
15141
15181
  /**
15142
- * Record an inbound client message durably via Tx B and append
15143
- * it to the in-memory `job.messages` array. Returns the DB-allocated seq
15182
+ * Record an inbound client message durably via Tx B. Payments stay outside
15183
+ * visible history until processPayment accepts them; other messages append
15184
+ * to `job.messages` immediately. Returns the DB-allocated seq
15144
15185
  * (`null` when the store isn't streamable — non-Postgres test fallback).
15145
15186
  *
15146
15187
  * Status starts as `pending-verification`; a follow-up Tx C call
@@ -15159,13 +15200,24 @@ var JobManager = class {
15159
15200
  });
15160
15201
  }
15161
15202
  job.seq++;
15162
- job.messages.push({
15203
+ const message = {
15163
15204
  seq: job.seq,
15164
15205
  from: "requester",
15165
15206
  timestamp,
15166
15207
  type: msgType,
15167
15208
  content: msgContent
15168
- });
15209
+ };
15210
+ if (msgType === "payment") {
15211
+ let pending = this.pendingPaymentMessages.get(job);
15212
+ if (!pending) {
15213
+ pending = /* @__PURE__ */ new Map();
15214
+ this.pendingPaymentMessages.set(job, pending);
15215
+ }
15216
+ pending.set(txSeq ?? msgContent, message);
15217
+ holdJobHistory(job, message.seq);
15218
+ } else {
15219
+ job.messages.push(message);
15220
+ }
15169
15221
  job.lastActivityAt = Date.now();
15170
15222
  return txSeq;
15171
15223
  }
@@ -15274,6 +15326,22 @@ var JobManager = class {
15274
15326
  * 500. See `creditInbound`.
15275
15327
  */
15276
15328
  async processPayment(job, body, inboundSeq, extra) {
15329
+ const pending = this.pendingPaymentMessages.get(job);
15330
+ const key = inboundSeq ?? body.content;
15331
+ const message = pending?.get(key);
15332
+ let accepted;
15333
+ try {
15334
+ const outcome = await this.processPaymentAndCredit(job, body, inboundSeq, extra);
15335
+ if (!outcome.error && message && pending?.get(key) === message) {
15336
+ accepted = message;
15337
+ }
15338
+ return outcome;
15339
+ } finally {
15340
+ pending?.delete(key);
15341
+ if (message) releaseJobHistory(job, message.seq, accepted);
15342
+ }
15343
+ }
15344
+ async processPaymentAndCredit(job, body, inboundSeq, extra) {
15277
15345
  if (body.type !== "payment") return {};
15278
15346
  const devAuto = this.opts.devMode === true && body.content.dev_auto === true && !hasPaymentProof(body.content);
15279
15347
  if (devAuto || devModeSkipsPaymentVerification(this.opts)) {
@@ -15358,7 +15426,7 @@ var JobManager = class {
15358
15426
  };
15359
15427
  }
15360
15428
  const info = verifyResult.verified;
15361
- if (!info) return {};
15429
+ if (!info) return { error: { status: 402, body: { error: "payment_invalid", message: "Payment was not accepted" } } };
15362
15430
  const drawFundingReceipt = await this.drawFundingReceiptFor(info.drawFunding, info.funding?.currency);
15363
15431
  let unappliedCredit;
15364
15432
  const fullyUnapplied = info.unappliedMicro !== void 0 && info.funding !== void 0 && info.unappliedMicro >= info.funding.amountMicro;
@@ -20946,7 +21014,7 @@ async function createDVMServer(descriptor, opts) {
20946
21014
  }
20947
21015
  }
20948
21016
  if (!opts.onJobCompleted && platformToken && platformUrl && dvmId && opts.db) {
20949
- const { RevenueReporter } = await import("./revenue-reporter-RIEHBKRA.js");
21017
+ const { RevenueReporter } = await import("./revenue-reporter-2P3PWJJM.js");
20950
21018
  const reporter = new RevenueReporter(
20951
21019
  opts.db,
20952
21020
  platformUrl,
@@ -20956,7 +21024,7 @@ async function createDVMServer(descriptor, opts) {
20956
21024
  revenueReporter = reporter;
20957
21025
  await reporter.init();
20958
21026
  reporter.startRetryLoop();
20959
- const { MemoryX402BatchStore, PayoutReporter } = await import("./payout-reporter-DDQ7FGRC.js");
21027
+ const { MemoryX402BatchStore, PayoutReporter } = await import("./payout-reporter-P3652TLG.js");
20960
21028
  payoutReporter = new PayoutReporter({
20961
21029
  dvmId,
20962
21030
  db: opts.db,
@@ -23610,14 +23678,21 @@ var DVMServer = class {
23610
23678
  const job = this.jobManager.activeJobs.get(id);
23611
23679
  const after = Number(c.req.query("after") ?? "0");
23612
23680
  const accept = c.req.header("Accept") ?? "";
23613
- if (!job) {
23614
- const store = this.jobManager.store;
23681
+ const store = this.jobManager.store;
23682
+ if (job && !isJobOwner(c, job)) return c.json({ error: "Job not found" }, 404);
23683
+ if (!job || isStreamableJobStore(store)) {
23684
+ if (job) await job.messageAppenderTail;
23615
23685
  const record = await store.get(id);
23616
23686
  if (!record) return c.json({ error: "Job not found" }, 404);
23617
23687
  if (!isJobOwner(c, record)) return c.json({ error: "Job not found" }, 404);
23618
- const filtered = record.messages.filter((m) => m.seq > after);
23688
+ const terminal = isTerminal(record.status) || job !== void 0 && isTerminal(job.status);
23689
+ let filtered = record.messages.filter((m) => m.seq > after);
23690
+ if (isStreamableJobStore(store)) {
23691
+ const durable = await store.getMessages(id, after, { includeHeld: terminal });
23692
+ if (durable.length > 0 || !terminal) filtered = durable;
23693
+ }
23619
23694
  if (accept.includes("text/event-stream")) {
23620
- if (isStreamableJobStore(store) && !isTerminal(record.status)) {
23695
+ if (isStreamableJobStore(store) && !terminal) {
23621
23696
  return streamSSE(c, async (stream) => {
23622
23697
  let unsubFn;
23623
23698
  await new Promise((resolve) => {
@@ -23680,10 +23755,6 @@ var DVMServer = class {
23680
23755
  }
23681
23756
  });
23682
23757
  }
23683
- if (isStreamableJobStore(store) && !isTerminal(record.status)) {
23684
- const msgs = await store.getMessages(id, after);
23685
- if (msgs.length > 0) return c.json(await this.messageFields(record, msgs));
23686
- }
23687
23758
  return c.json(await this.messageFields(record, filtered));
23688
23759
  }
23689
23760
  if (!isJobOwner(c, job)) return c.json({ error: "Job not found" }, 404);
@@ -23691,7 +23762,7 @@ var DVMServer = class {
23691
23762
  const fields = await this.contentFields(job);
23692
23763
  return streamSSE(c, async (stream) => {
23693
23764
  if (fields.content_available === false) return;
23694
- const existing = job.messages.filter((m) => m.seq > after);
23765
+ const existing = visibleJobMessages(job).filter((m) => m.seq > after);
23695
23766
  let yielded = false;
23696
23767
  for (const msg of existing) {
23697
23768
  await stream.writeSSE({ data: JSON.stringify(msg), event: "message" });
@@ -23719,7 +23790,7 @@ var DVMServer = class {
23719
23790
  });
23720
23791
  });
23721
23792
  }
23722
- return c.json(await this.messageFields(job, job.messages.filter((m) => m.seq > after)));
23793
+ return c.json(await this.messageFields(job, visibleJobMessages(job).filter((m) => m.seq > after)));
23723
23794
  }
23724
23795
  jobNotActiveResponse(c) {
23725
23796
  return c.json(
@@ -24095,6 +24166,7 @@ function recordedDrawPayment(draw, opts) {
24095
24166
  ...rail === "cashu" ? { cashuFlow: "p2pk_accumulator" } : {},
24096
24167
  creditId: draw.creditId,
24097
24168
  drawId: draw.drawId,
24169
+ upfrontPayment: upfrontPaymentFromDraw(draw),
24098
24170
  drawAmountMicro: draw.amountMicro,
24099
24171
  ...draw.railValue.creditCurrency ? { creditCurrency: draw.railValue.creditCurrency } : {}
24100
24172
  };
@@ -24180,6 +24252,7 @@ function removeUnavailableContent(fields) {
24180
24252
  }
24181
24253
  function terminalResponseFields(job) {
24182
24254
  const fields = {};
24255
+ if (job.upfrontPayment !== void 0) fields.upfront_payment = job.upfrontPayment;
24183
24256
  if (job.status === "completed") {
24184
24257
  if (job.summary !== void 0) fields.summary = job.summary;
24185
24258
  const artifactCount = job.messages.filter((m) => m.type === "artifact").length;
@@ -7,7 +7,7 @@ import {
7
7
  extendDiagnosticIdentityAuthority,
8
8
  projectDiagnosticFields,
9
9
  projectSpanRow
10
- } from "./chunk-BAHZK334.js";
10
+ } from "./chunk-5U2RG3ZW.js";
11
11
 
12
12
  // src/observability/context.ts
13
13
  import { AsyncLocalStorage } from "async_hooks";
@@ -137,7 +137,7 @@ function ownDataValue(input, key) {
137
137
  }
138
138
  function ownIdentityKeys(input) {
139
139
  try {
140
- return ["dvm_id", "dvm_slug", "builder_id"].filter((key) => {
140
+ return ["dvm_id", "dvm_slug", "builder_id", "dvm_resolution"].filter((key) => {
141
141
  const descriptor = (typeof input === "object" && input !== null || typeof input === "function") && Object.getOwnPropertyDescriptor(input, key);
142
142
  return descriptor && "value" in descriptor;
143
143
  });
@@ -4,13 +4,13 @@ import {
4
4
  callerDeadline,
5
5
  hasCallerDeadline,
6
6
  isTerminal
7
- } from "./chunk-FL6Q3JNJ.js";
7
+ } from "./chunk-KVKJ7R5V.js";
8
8
  import {
9
9
  redactUrl
10
10
  } from "./chunk-FUJ36YDV.js";
11
11
  import {
12
12
  loggers
13
- } from "./chunk-R7FH7SHX.js";
13
+ } from "./chunk-TN6MWTZI.js";
14
14
 
15
15
  // src/sdk/server/job-store.ts
16
16
  function accumulateAskedTopUp(prior, ask) {
@@ -116,7 +116,10 @@ var MemoryJobStore = class {
116
116
  return Promise.resolve();
117
117
  }
118
118
  const snapshot = structuredClone(record);
119
- if (existing) snapshot.createdAt = existing.createdAt;
119
+ if (existing) {
120
+ snapshot.createdAt = existing.createdAt;
121
+ snapshot.upfrontPayment = structuredClone(existing.upfrontPayment);
122
+ }
120
123
  if (existing && isTerminal(existing.status)) snapshot.lastActivityAt = existing.lastActivityAt;
121
124
  if (existing?.receipt) snapshot.receipt = existing.receipt;
122
125
  snapshot.timingKnown = existing ? existing.timingKnown ?? false : record.timingKnown ?? true;
@@ -125,6 +128,7 @@ var MemoryJobStore = class {
125
128
  const cur = this.nextSeq.get(record.id) ?? 1;
126
129
  this.nextSeq.set(record.id, Math.max(cur, record.seq + 1));
127
130
  if (isTerminal(record.status)) {
131
+ this.notify(record.id);
128
132
  this.messages.delete(record.id);
129
133
  }
130
134
  return Promise.resolve();
@@ -236,7 +240,7 @@ var MemoryJobStore = class {
236
240
  }
237
241
  if (!isTerminal(record.status)) record.lastActivityAt = Date.now();
238
242
  if (seq > record.seq) record.seq = seq;
239
- this.notify(jobId, fullMessage);
243
+ this.notify(jobId);
240
244
  return Promise.resolve(seq);
241
245
  }
242
246
  recordInbound(jobId, message) {
@@ -297,7 +301,7 @@ var MemoryJobStore = class {
297
301
  }
298
302
  }
299
303
  if (!isTerminal(record.status)) record.lastActivityAt = Date.now();
300
- this.notify(jobId, stored.message);
304
+ this.notify(jobId);
301
305
  return Promise.resolve({
302
306
  counters: snapshotCounters(record),
303
307
  alreadyVerified: false,
@@ -318,6 +322,7 @@ var MemoryJobStore = class {
318
322
  const stored = this.messagesFor(jobId).find((m) => m.message.seq === seq);
319
323
  if (stored?.status === "pending-verification") {
320
324
  stored.status = "failed-verify";
325
+ this.notify(jobId);
321
326
  }
322
327
  return Promise.resolve();
323
328
  }
@@ -408,11 +413,8 @@ var MemoryJobStore = class {
408
413
  if (subSet.size === 0) this.notifySubscribers.delete(jobId);
409
414
  });
410
415
  }
411
- getMessages(jobId, afterSeq) {
412
- const stored = this.messagesFor(jobId);
413
- return Promise.resolve(
414
- stored.filter((m) => m.status === "verified" && m.message.seq > afterSeq).map((m) => m.message)
415
- );
416
+ getMessages(jobId, afterSeq, options) {
417
+ return Promise.resolve(this.visibleMessages(jobId, afterSeq, options?.includeHeld));
416
418
  }
417
419
  initStreaming() {
418
420
  return Promise.resolve();
@@ -458,7 +460,7 @@ var MemoryJobStore = class {
458
460
  record.messages = [...terminalMessages, cancelMsg];
459
461
  record.seq = seq;
460
462
  record.lastActivityAt = Date.now();
461
- this.notify(jobId, cancelMsg);
463
+ this.notify(jobId);
462
464
  this.messages.delete(jobId);
463
465
  return Promise.resolve(true);
464
466
  }
@@ -475,11 +477,35 @@ var MemoryJobStore = class {
475
477
  }
476
478
  return list;
477
479
  }
478
- notify(jobId, message) {
480
+ visibleMessages(jobId, afterSeq, includeHeld = false) {
481
+ const stored = this.messagesFor(jobId);
482
+ const record = this.data.get(jobId);
483
+ const terminal = record && isTerminal(record.status);
484
+ const terminalMessage = stored.some((entry) => entry.status === "verified" && entry.message.from === "provider" && (entry.message.type === "complete" || entry.message.type === "cancel"));
485
+ let boundary = Infinity;
486
+ if (!includeHeld && !terminal && !terminalMessage) {
487
+ for (const entry of stored) {
488
+ if (entry.status === "pending-verification" && entry.message.type === "payment") {
489
+ boundary = Math.min(boundary, entry.message.seq);
490
+ }
491
+ }
492
+ }
493
+ const messages = /* @__PURE__ */ new Map();
494
+ if (terminal) {
495
+ for (const message of record.messages) if (message.seq > afterSeq) messages.set(message.seq, message);
496
+ }
497
+ for (const entry of stored) {
498
+ if (entry.status === "verified" && entry.message.seq > afterSeq && entry.message.seq < boundary) {
499
+ messages.set(entry.message.seq, entry.message);
500
+ }
501
+ }
502
+ return [...messages.values()].sort((a, b) => a.seq - b.seq);
503
+ }
504
+ notify(jobId) {
479
505
  const subs = this.messageSubscribers.get(jobId);
480
506
  if (subs) {
481
507
  for (const sub of subs) {
482
- if (message.seq > sub.afterSeq) {
508
+ for (const message of this.visibleMessages(jobId, sub.afterSeq)) {
483
509
  sub.afterSeq = message.seq;
484
510
  sub.cb(message);
485
511
  }
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-SXL44PL5.js";
8
8
  import {
9
9
  diagnosticConsole
10
- } from "./chunk-BAHZK334.js";
10
+ } from "./chunk-5U2RG3ZW.js";
11
11
 
12
12
  // src/sdk/server/zod-error.ts
13
13
  function humanizeZodError(err, opts) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  emitDiagnostic,
3
3
  projectDiagnosticFields
4
- } from "./chunk-BAHZK334.js";
4
+ } from "./chunk-5U2RG3ZW.js";
5
5
 
6
6
  // src/sdk/logger.ts
7
7
  function createConsoleLogger(_jobId) {
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-66HGCPBU.js";
20
20
  import {
21
21
  diagnosticConsole
22
- } from "./chunk-BAHZK334.js";
22
+ } from "./chunk-5U2RG3ZW.js";
23
23
 
24
24
  // src/lib/cashu/lock-pubkey.ts
25
25
  function toLockPubkey(raw) {
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  diagnosticConsole,
6
6
  projectSpanRow
7
- } from "./chunk-BAHZK334.js";
7
+ } from "./chunk-5U2RG3ZW.js";
8
8
 
9
9
  // src/lib/x402/env.ts
10
10
  import { isAddress } from "viem";
@@ -1,4 +1,4 @@
1
- import { b as JobStore, J as JobRecord } from './job-store-AxjHh5Gp.js';
1
+ import { b as JobStore, J as JobRecord } from './job-store-CA7u1nHV.js';
2
2
 
3
3
  /** Authenticated caller metadata; omitted fields on older services mean unknown. */
4
4
  interface JobContentMetadata {
@@ -10,14 +10,14 @@ import {
10
10
  isDrainMethod,
11
11
  isFundingRail,
12
12
  x402SettlementPending
13
- } from "./chunk-LM6E4YHQ.js";
13
+ } from "./chunk-K4ZQE7IB.js";
14
14
  import "./chunk-YG7G4DPZ.js";
15
15
  import "./chunk-COYKJRMM.js";
16
16
  import "./chunk-5UC7TOQC.js";
17
- import "./chunk-FOXGN4KQ.js";
17
+ import "./chunk-ELNWQS24.js";
18
18
  import "./chunk-BPYMEMQX.js";
19
19
  import "./chunk-H3GGFEE5.js";
20
- import "./chunk-BAHZK334.js";
20
+ import "./chunk-5U2RG3ZW.js";
21
21
  export {
22
22
  CreditLedger,
23
23
  CreditLedgerError,