@dvmkit/sdk 0.5.0-rc.1 → 0.6.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 (32) hide show
  1. package/README.md +100 -0
  2. package/dist/chunk-AFV77S4C.js +258 -0
  3. package/dist/chunk-BQJIFRAZ.js +36 -0
  4. package/dist/{chunk-PB4FYZET.js → chunk-EQLA4FFY.js} +54 -4
  5. package/dist/{chunk-TZ2WKCDD.js → chunk-HCLVYZUZ.js} +2 -2
  6. package/dist/{chunk-EYTHFFFU.js → chunk-HHBDBMEO.js} +159 -34
  7. package/dist/{chunk-O5AT6S5T.js → chunk-IV6Q7NRW.js} +25 -195
  8. package/dist/{chunk-Z4KLECAC.js → chunk-N5RZ5HVB.js} +1 -1
  9. package/dist/{chunk-TUA7PYH7.js → chunk-OQA7IHI4.js} +124 -124
  10. package/dist/{chunk-6DOGTAHA.js → chunk-QR2EF2NI.js} +9 -43
  11. package/dist/{chunk-A4YFWZ7R.js → chunk-RCM3P2HE.js} +1 -1
  12. package/dist/content-retention-BTGSQRfP.d.ts +78 -0
  13. package/dist/{credit-menu-CAfqe8IY.d.ts → credit-menu-BAsrRu3z.d.ts} +98 -5
  14. package/dist/{fx-D9nsN3n4.d.ts → fx-BgDmyTdd.d.ts} +1 -1
  15. package/dist/index.d.ts +5 -5
  16. package/dist/index.js +3 -3
  17. package/dist/internal/caller.d.ts +16 -15
  18. package/dist/internal/caller.js +7 -5
  19. package/dist/internal/server.d.ts +8 -99
  20. package/dist/internal/server.js +12 -9
  21. package/dist/{job-store-Bx-VFRjg.d.ts → job-store-BVeF5_Jq.d.ts} +1 -1
  22. package/dist/{lightning-backend-BAx2Y8pP.d.ts → lightning-backend-40fIzz1W.d.ts} +1 -1
  23. package/dist/{postgres-consumed-credential-store-CUQJKRSL.js → postgres-consumed-credential-store-BUVCAPLS.js} +13 -0
  24. package/dist/{postgres-job-store-VLXLWXUQ.js → postgres-job-store-VHLQBJZC.js} +3 -1
  25. package/dist/server/index.d.ts +28 -10
  26. package/dist/server/index.js +22 -9
  27. package/dist/{step-cache-QG_h5-3G.d.ts → step-cache-CPdH1hei.d.ts} +2 -2
  28. package/dist/testing/index.d.ts +9 -2
  29. package/dist/testing/index.js +6 -3
  30. package/dist/{usd-EwRqCPF-.d.ts → usd-AWlrwlM5.d.ts} +1 -1
  31. package/package.json +3 -2
  32. package/recipes/postgres/financial-export-v1.sql +137 -0
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-FYRR2UEZ.js";
15
15
  import {
16
16
  PostgresJobStore
17
- } from "./chunk-PB4FYZET.js";
17
+ } from "./chunk-EQLA4FFY.js";
18
18
  import {
19
19
  parseStoreValue
20
20
  } from "./chunk-YG7G4DPZ.js";
@@ -25,24 +25,30 @@ import {
25
25
  humanizeZodIssues,
26
26
  signedRequestInput,
27
27
  zodIssuesOf
28
- } from "./chunk-Z4KLECAC.js";
28
+ } from "./chunk-N5RZ5HVB.js";
29
29
  import {
30
- JobCancelledError,
31
30
  MemoryJobStore,
32
31
  UNCAPPABLE_ASK_TOTAL,
33
- abortJob,
34
32
  accumulateAskedTopUp,
35
33
  createInstrumentedFetch,
36
- fromJobRecord,
37
34
  isJobRetentionStore,
38
35
  isReceiptIssuingStore,
39
- isStreamableJobStore,
36
+ isStreamableJobStore
37
+ } from "./chunk-IV6Q7NRW.js";
38
+ import {
39
+ ContentHoldError,
40
+ JobCancelledError,
41
+ abortJob,
42
+ baselineContentExpiry,
43
+ contentMetadata,
44
+ fromJobRecord,
45
+ isContentHoldStore,
40
46
  isTerminal,
41
47
  isYieldMessage,
42
48
  localMessage,
43
49
  providerMessage,
44
50
  toJobRecord
45
- } from "./chunk-O5AT6S5T.js";
51
+ } from "./chunk-AFV77S4C.js";
46
52
  import {
47
53
  ADMIN_AUTH_CLOCK_SKEW_SECONDS,
48
54
  ADMIN_AUTH_NONCE_TTL_SECONDS,
@@ -63,7 +69,7 @@ import {
63
69
  toLockPubkey,
64
70
  verifyCashuToken,
65
71
  verifyChallenge
66
- } from "./chunk-TUA7PYH7.js";
72
+ } from "./chunk-OQA7IHI4.js";
67
73
  import {
68
74
  X402_BATCH_SETTLEMENT_SCHEME,
69
75
  X402_DEFAULT_FACILITATOR,
@@ -97,18 +103,20 @@ import {
97
103
  RAIL_REFUNDABLE,
98
104
  canonicalRequestPath,
99
105
  isZodSchema
100
- } from "./chunk-A4YFWZ7R.js";
106
+ } from "./chunk-RCM3P2HE.js";
101
107
  import {
102
108
  canonicalize
103
109
  } from "./chunk-OFVV37XC.js";
104
110
  import {
105
- StepCache,
106
111
  createConsoleLogger,
107
112
  loggers,
108
113
  pinDimension,
109
114
  withSpan,
110
115
  withTraceContext
111
- } from "./chunk-6DOGTAHA.js";
116
+ } from "./chunk-QR2EF2NI.js";
117
+ import {
118
+ StepCache
119
+ } from "./chunk-BQJIFRAZ.js";
112
120
  import {
113
121
  FxRateUnavailableError,
114
122
  InvalidCurrencyError,
@@ -768,6 +776,15 @@ var MemoryConsumedCredentialStore = class {
768
776
  }
769
777
  return Promise.resolve(true);
770
778
  }
779
+ consume(realm, challengeId, ttlSeconds) {
780
+ const key = `${realm}:${challengeId}`;
781
+ const now = Date.now();
782
+ if ((this.data.get(key) ?? 0) > now) return Promise.resolve(false);
783
+ for (const [entry, expiry] of this.data) if (expiry <= now) this.data.delete(entry);
784
+ if (this.data.size >= this.maxEntries) return Promise.reject(new Error("Nonce store capacity exhausted"));
785
+ this.data.set(key, now + ttlSeconds * 1e3);
786
+ return Promise.resolve(true);
787
+ }
771
788
  mark(realm, challengeId, ttlSeconds) {
772
789
  const key = `${realm}:${challengeId}`;
773
790
  if (this.data.has(key)) this.data.delete(key);
@@ -8707,10 +8724,14 @@ async function verifyAdminAuth(opts) {
8707
8724
  nonceHex,
8708
8725
  unixSeconds: unixStr
8709
8726
  });
8710
- const matched = opts.acceptedPubkeys.some((pk) => verifyChallenge(pk, digest, sigHex));
8727
+ const matched = opts.acceptedPubkeys.find((pk) => verifyChallenge(pk, digest, sigHex));
8711
8728
  if (!matched) return { ok: false, reason: "bad_signature" };
8712
- await opts.nonceStore.mark(NONCE_REALM, nonceHex, NONCE_TTL_SECONDS);
8713
- return { ok: true };
8729
+ if (opts.nonceStore.consume) {
8730
+ if (!await opts.nonceStore.consume(NONCE_REALM, nonceHex, NONCE_TTL_SECONDS)) return { ok: false, reason: "replay" };
8731
+ } else {
8732
+ await opts.nonceStore.mark(NONCE_REALM, nonceHex, NONCE_TTL_SECONDS);
8733
+ }
8734
+ return { ok: true, actor: matched };
8714
8735
  }
8715
8736
  function installAdminCashuRoutes(app, opts) {
8716
8737
  app.get("/admin/cashu/pending-batches", (c) => handlePendingBatches(c, opts));
@@ -8975,6 +8996,69 @@ async function handleRotateLockPubkey(c, opts) {
8975
8996
  });
8976
8997
  }
8977
8998
 
8999
+ // src/sdk/server/admin-content.ts
9000
+ function installAdminContentRoutes(app, opts) {
9001
+ app.get("/admin/jobs/:jobId/content-holds", (c) => handle(c, opts));
9002
+ app.post("/admin/jobs/:jobId/content-holds", (c) => handle(c, opts, "placed"));
9003
+ app.post("/admin/jobs/:jobId/content-holds/:holdId/renew", (c) => handle(c, opts, "renewed"));
9004
+ app.post("/admin/jobs/:jobId/content-holds/:holdId/clear", (c) => handle(c, opts, "cleared"));
9005
+ }
9006
+ async function handle(c, opts, action) {
9007
+ const loaded = await loadAdminLockPubkeyState(c, opts);
9008
+ if ("response" in loaded) return loaded.response;
9009
+ const auth = await verifyAdminAuth({
9010
+ authHeader: c.req.header("Authorization"),
9011
+ method: c.req.method,
9012
+ path: c.req.path,
9013
+ dvmId: opts.dvmId,
9014
+ acceptedPubkeys: [loaded.state.current, ...loaded.state.retired.map((item) => item.pubkey)],
9015
+ nonceStore: opts.nonceStore,
9016
+ now: opts.now
9017
+ });
9018
+ if (!auth.ok) return c.json({ error: "unauthorized", reason: auth.reason }, 401);
9019
+ if (!isContentHoldStore(opts.store) || !opts.nonceStore.consume) {
9020
+ return c.json({ error: "content_holds_unavailable", message: "This service requires a content-hold store and atomic admin nonce store." }, 503);
9021
+ }
9022
+ const jobId = c.req.param("jobId") ?? "";
9023
+ const at = opts.now?.() ?? Date.now();
9024
+ try {
9025
+ if (action) {
9026
+ let body;
9027
+ try {
9028
+ body = await c.req.json();
9029
+ } catch {
9030
+ return c.json({ error: "invalid_body", message: "Send a JSON object." }, 400);
9031
+ }
9032
+ if (!body || typeof body !== "object" || Array.isArray(body)) return c.json({ error: "invalid_body" }, 400);
9033
+ const allowed = action === "placed" ? ["purpose", "reason", "review_due_at"] : action === "renewed" ? ["reason", "review_due_at"] : ["reason"];
9034
+ if (Object.keys(body).some((key) => !allowed.includes(key))) return c.json({ error: "invalid_body", message: "Only purpose, reason and review_due_at are accepted as applicable; identity and times are server-derived." }, 400);
9035
+ if (typeof body.reason !== "string" || body.reason.trim().length === 0 || body.reason.length > 1e3) return c.json({ error: "invalid_reason", message: "reason must contain 1..1000 characters." }, 400);
9036
+ if (action !== "cleared" && (!Number.isSafeInteger(body.review_due_at) || body.review_due_at <= at)) return c.json({ error: "invalid_review_due_at", message: "review_due_at must be a future epoch millisecond integer." }, 400);
9037
+ const base2 = { reason: body.reason.trim(), actor: auth.actor, at };
9038
+ let mutation;
9039
+ if (action === "placed") {
9040
+ if (body.purpose !== "support" && body.purpose !== "dispute") return c.json({ error: "invalid_purpose" }, 400);
9041
+ mutation = { ...base2, action, purpose: body.purpose, review_due_at: body.review_due_at };
9042
+ } else if (action === "renewed") {
9043
+ mutation = { ...base2, action, hold_id: c.req.param("holdId") ?? "", review_due_at: body.review_due_at };
9044
+ } else mutation = { ...base2, action, hold_id: c.req.param("holdId") ?? "" };
9045
+ await opts.store.mutateContentHold(jobId, mutation, opts.dvmId);
9046
+ }
9047
+ const snapshot = await opts.store.getContentSnapshot(jobId, opts.dvmId);
9048
+ if (!snapshot) return c.json({ error: "job_not_found" }, 404);
9049
+ return c.json({
9050
+ job_id: jobId,
9051
+ ...contentMetadata(snapshot.job, opts.retentionDays, snapshot.history.holds),
9052
+ baseline_content_expires_at: baselineContentExpiry(snapshot.job, opts.retentionDays),
9053
+ holds: snapshot.history.holds.map((hold) => ({ ...hold, review_overdue: hold.cleared_at === null && hold.review_due_at <= at })),
9054
+ events: snapshot.history.events
9055
+ }, action === "placed" ? 201 : 200);
9056
+ } catch (error) {
9057
+ if (error instanceof ContentHoldError) return c.json({ error: error.code }, error.code === "job_not_found" ? 404 : 409);
9058
+ throw error;
9059
+ }
9060
+ }
9061
+
8978
9062
  // src/sdk/server/x402-exact-settlement.ts
8979
9063
  import { createHash as createHash4 } from "crypto";
8980
9064
  var X402ExactSettlementServer = class {
@@ -19944,6 +20028,13 @@ var DVMServer = class {
19944
20028
  ...payoutReporter ? { onMelted: payoutReporter.meltHook() } : {}
19945
20029
  });
19946
20030
  }
20031
+ installAdminContentRoutes(this.app, {
20032
+ dvmId,
20033
+ store: this.jobManager.store,
20034
+ retentionDays: this.descriptor.jobRetentionDays,
20035
+ getLockPubkeyState: () => this.loadActiveLockPubkeyState(db, dvmId),
20036
+ nonceStore: this.adminCashuNonceStore
20037
+ });
19947
20038
  installAdminCreditRoutes(this.app, {
19948
20039
  db,
19949
20040
  dvmId,
@@ -20250,12 +20341,12 @@ var DVMServer = class {
20250
20341
  ownerDisplayBlock() {
20251
20342
  const owner = this.opts.owner;
20252
20343
  const env = this.opts.env;
20253
- const handle = owner?.handle ?? env.DVMKIT_OWNER_HANDLE;
20254
- if (!handle) return null;
20344
+ const handle2 = owner?.handle ?? env.DVMKIT_OWNER_HANDLE;
20345
+ if (!handle2) return null;
20255
20346
  const type = owner?.type ?? env.DVMKIT_OWNER_TYPE ?? "builder";
20256
20347
  const displayName = owner?.displayName ?? env.DVMKIT_OWNER_DISPLAY_NAME ?? null;
20257
20348
  const avatarUrl = owner?.avatarUrl ?? env.DVMKIT_OWNER_AVATAR_URL ?? null;
20258
- return { handle, display_name: displayName, avatar_url: avatarUrl, type };
20349
+ return { handle: handle2, display_name: displayName, avatar_url: avatarUrl, type };
20259
20350
  }
20260
20351
  defaultPaymentMethods() {
20261
20352
  const methods = [];
@@ -21140,7 +21231,7 @@ var DVMServer = class {
21140
21231
  if (prior?.requestId !== requestId || prior.requesterPubkey !== authPubkey || prior.requestFingerprint !== fingerprint || prior.requesterId !== c.get("requesterId")) {
21141
21232
  return requestResultNotFound(c, requestId);
21142
21233
  }
21143
- return buildRequestResultResponse(c, requestId, prior);
21234
+ return buildRequestResultResponse(c, requestId, prior, await this.contentFields(prior));
21144
21235
  }
21145
21236
  async handleCreateJob(c, resumeOnly = false) {
21146
21237
  if (!resumeOnly) this.maybeSweepTempoSessions();
@@ -21270,7 +21361,7 @@ var DVMServer = class {
21270
21361
  const prior = priorId ? await this.jobManager.store.get(priorId) : void 0;
21271
21362
  if (prior && prior.requestFingerprint === fingerprint && prior.requesterId === c.get("requesterId") && (!this.descriptor.auth || prior.requesterPubkey === authPubkey)) {
21272
21363
  await this.jobManager.ensureReceipt(prior);
21273
- return buildSubmitResponse(c, prior, prior.requesterToken);
21364
+ return await this.submitResponse(c, prior, prior.requesterToken);
21274
21365
  }
21275
21366
  }
21276
21367
  if (!resumeOnly && this.opts.hostingControlInstance && creditEnvelope && authPubkey) {
@@ -21312,7 +21403,7 @@ var DVMServer = class {
21312
21403
  if (publicRequestId && authPubkey && recoveryStore) {
21313
21404
  const prior = await recoveryStore.findJobByRequestId(publicRequestId, authPubkey);
21314
21405
  if (prior) {
21315
- return resumeOnly ? buildSubmitResponse(c, prior, prior.requesterToken) : requestIdExists(c, publicRequestId);
21406
+ return resumeOnly ? await this.submitResponse(c, prior, prior.requesterToken) : requestIdExists(c, publicRequestId);
21316
21407
  }
21317
21408
  }
21318
21409
  let jobId = publicRequestClaimResult?.jobId ?? this.jobManager.allocateJobId();
@@ -21528,7 +21619,7 @@ var DVMServer = class {
21528
21619
  exactAdmission.intentId
21529
21620
  );
21530
21621
  await this.jobManager.ensureReceipt(prior);
21531
- return buildSubmitResponse(c, prior, prior.requesterToken);
21622
+ return await this.submitResponse(c, prior, prior.requesterToken);
21532
21623
  }
21533
21624
  }
21534
21625
  if (this.descriptor.auth && authEnvelope) {
@@ -21589,7 +21680,7 @@ var DVMServer = class {
21589
21680
  await jm.finalizeStoredTerminal(jobId);
21590
21681
  }
21591
21682
  const terminal = await store.get(jobId);
21592
- if (terminal) return buildSubmitResponse(c, terminal, jobToken);
21683
+ if (terminal) return await this.submitResponse(c, terminal, jobToken);
21593
21684
  }
21594
21685
  if (exactAdmission) {
21595
21686
  await this.x402ExactSettlement?.completeAdmission(
@@ -21604,7 +21695,7 @@ var DVMServer = class {
21604
21695
  setTimeout(resolve, 0);
21605
21696
  });
21606
21697
  await awaitTerminalWork(job);
21607
- let response = buildSubmitResponse(c, job, jobToken);
21698
+ let response = await this.submitResponse(c, job, jobToken);
21608
21699
  if (payment.x402SettleResponseHeader) {
21609
21700
  response = new Response(response.body, response);
21610
21701
  response.headers.set("PAYMENT-RESPONSE", payment.x402SettleResponseHeader);
@@ -21692,7 +21783,7 @@ var DVMServer = class {
21692
21783
  return void 0;
21693
21784
  }
21694
21785
  await this.jobManager.ensureReceipt(prior);
21695
- return buildSubmitResponse(c, prior, prior.requesterToken);
21786
+ return await this.submitResponse(c, prior, prior.requesterToken);
21696
21787
  }
21697
21788
  /**
21698
21789
  * Resolve the recorded draw's job under the same fingerprint/pubkey/requester
@@ -21737,7 +21828,7 @@ var DVMServer = class {
21737
21828
  return void 0;
21738
21829
  }
21739
21830
  await this.jobManager.ensureReceipt(prior);
21740
- return buildSubmitResponse(c, prior, prior.requesterToken);
21831
+ return await this.submitResponse(c, prior, prior.requesterToken);
21741
21832
  }
21742
21833
  /**
21743
21834
  * Resume the gap between a durable x402/Tempo marker+draw commit and the
@@ -21886,6 +21977,23 @@ var DVMServer = class {
21886
21977
  };
21887
21978
  }
21888
21979
  }
21980
+ async submitResponse(c, job, jobToken) {
21981
+ const snapshot = { ...job, messages: [...job.messages] };
21982
+ return buildSubmitResponse(c, snapshot, jobToken, await this.contentFields(snapshot));
21983
+ }
21984
+ async contentFields(job) {
21985
+ const store = this.jobManager.store;
21986
+ const responseStatus = job.status;
21987
+ if (isContentHoldStore(store)) {
21988
+ const snapshot = await store.getContentSnapshot(job.id);
21989
+ if (snapshot) return { ...contentMetadata({ ...snapshot.job, status: responseStatus }, this.descriptor.jobRetentionDays, snapshot.history.holds) };
21990
+ }
21991
+ return isContentHoldStore(store) ? { ...contentMetadata(job, this.descriptor.jobRetentionDays) } : {};
21992
+ }
21993
+ async messageFields(job, messages) {
21994
+ const fields = await this.contentFields(job);
21995
+ return { messages: fields.content_available === false ? [] : messages, ...fields };
21996
+ }
21889
21997
  async handleGetJob(c) {
21890
21998
  if (!jobCredential.presents(c.req)) return c.json(jobCredential.body(), 401);
21891
21999
  const id = c.req.param("id") ?? "";
@@ -21894,7 +22002,8 @@ var DVMServer = class {
21894
22002
  if (!isJobOwner(c, job)) return c.json({ error: "Job not found" }, 404);
21895
22003
  await this.jobManager.ensureReceipt(job);
21896
22004
  const res2 = { job_id: job.id, status: job.status };
21897
- Object.assign(res2, terminalResponseFields(job));
22005
+ Object.assign(res2, terminalResponseFields(job), await this.contentFields(job));
22006
+ removeUnavailableContent(res2);
21898
22007
  return c.json(res2);
21899
22008
  }
21900
22009
  const record = await this.jobManager.store.get(id);
@@ -21902,7 +22011,8 @@ var DVMServer = class {
21902
22011
  if (!isJobOwner(c, record)) return c.json({ error: "Job not found" }, 404);
21903
22012
  await this.jobManager.ensureReceipt(record);
21904
22013
  const res = { job_id: record.id, status: record.status };
21905
- Object.assign(res, terminalResponseFields(record));
22014
+ Object.assign(res, terminalResponseFields(record), await this.contentFields(record));
22015
+ removeUnavailableContent(res);
21906
22016
  return c.json(res);
21907
22017
  }
21908
22018
  async handleGetMessages(c) {
@@ -21973,7 +22083,9 @@ var DVMServer = class {
21973
22083
  });
21974
22084
  });
21975
22085
  }
22086
+ const fields = await this.contentFields(record);
21976
22087
  return streamSSE(c, async (stream) => {
22088
+ if (fields.content_available === false) return;
21977
22089
  for (const msg of filtered) {
21978
22090
  await stream.writeSSE({ data: JSON.stringify(msg), event: "message" });
21979
22091
  }
@@ -21981,13 +22093,15 @@ var DVMServer = class {
21981
22093
  }
21982
22094
  if (isStreamableJobStore(store) && !isTerminal(record.status)) {
21983
22095
  const msgs = await store.getMessages(id, after);
21984
- if (msgs.length > 0) return c.json({ messages: msgs });
22096
+ if (msgs.length > 0) return c.json(await this.messageFields(record, msgs));
21985
22097
  }
21986
- return c.json({ messages: filtered });
22098
+ return c.json(await this.messageFields(record, filtered));
21987
22099
  }
21988
22100
  if (!isJobOwner(c, job)) return c.json({ error: "Job not found" }, 404);
21989
22101
  if (accept.includes("text/event-stream")) {
22102
+ const fields = await this.contentFields(job);
21990
22103
  return streamSSE(c, async (stream) => {
22104
+ if (fields.content_available === false) return;
21991
22105
  const existing = job.messages.filter((m) => m.seq > after);
21992
22106
  let yielded = false;
21993
22107
  for (const msg of existing) {
@@ -22016,7 +22130,7 @@ var DVMServer = class {
22016
22130
  });
22017
22131
  });
22018
22132
  }
22019
- return c.json({ messages: job.messages.filter((m) => m.seq > after) });
22133
+ return c.json(await this.messageFields(job, job.messages.filter((m) => m.seq > after)));
22020
22134
  }
22021
22135
  jobNotActiveResponse(c) {
22022
22136
  return c.json(
@@ -22260,12 +22374,13 @@ function timingSafeEqualHex(a, b) {
22260
22374
  for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
22261
22375
  return diff === 0;
22262
22376
  }
22263
- function buildSubmitResponse(c, job, jobToken) {
22377
+ function buildSubmitResponse(c, job, jobToken, contentFields) {
22264
22378
  const res = { job_id: job.id };
22265
22379
  if (jobToken) res.job_token = jobToken;
22266
22380
  if (job.status === "awaiting-input") res.status = "awaiting-input";
22267
22381
  else if (job.status === "completed") res.status = "completed";
22268
- Object.assign(res, terminalResponseFields(job));
22382
+ Object.assign(res, terminalResponseFields(job), contentFields);
22383
+ removeUnavailableContent(res);
22269
22384
  return c.json(res, job.status === "completed" ? 200 : 202);
22270
22385
  }
22271
22386
  function requestRecoveryStore(store) {
@@ -22321,7 +22436,7 @@ function requestNotAccepted(c, requestId) {
22321
22436
  409
22322
22437
  );
22323
22438
  }
22324
- function buildRequestResultResponse(c, requestId, job) {
22439
+ function buildRequestResultResponse(c, requestId, job, contentFields) {
22325
22440
  const status = job.status === "working" ? "processing" : job.status;
22326
22441
  const res = {
22327
22442
  request_id: requestId,
@@ -22330,7 +22445,8 @@ function buildRequestResultResponse(c, requestId, job) {
22330
22445
  };
22331
22446
  if (job.requesterToken) res.job_token = job.requesterToken;
22332
22447
  if (job.paymentTransactionHash) res.transaction_hash = job.paymentTransactionHash;
22333
- Object.assign(res, terminalResponseFields(job));
22448
+ Object.assign(res, terminalResponseFields(job), contentFields);
22449
+ removeUnavailableContent(res);
22334
22450
  return c.json(res, isTerminal(job.status) ? 200 : 202);
22335
22451
  }
22336
22452
  function requestResultNotFound(c, requestId) {
@@ -22358,6 +22474,14 @@ async function awaitTerminalWork(job) {
22358
22474
  ]);
22359
22475
  clearTimeout(timer);
22360
22476
  }
22477
+ function removeUnavailableContent(fields) {
22478
+ if (fields.content_available === false) {
22479
+ delete fields.summary;
22480
+ fields.has_artifacts = false;
22481
+ delete fields.artifact_count;
22482
+ delete fields.payload_in;
22483
+ }
22484
+ }
22361
22485
  function terminalResponseFields(job) {
22362
22486
  const fields = {};
22363
22487
  if (job.status === "completed") {
@@ -22750,6 +22874,7 @@ export {
22750
22874
  handleCreditRequest,
22751
22875
  installAdminCashuRoutes,
22752
22876
  createAdminCashuNonceStore,
22877
+ installAdminContentRoutes,
22753
22878
  X402ExactSettlementServer,
22754
22879
  X402ExactSettlementEvidenceMissingError,
22755
22880
  HostedSettlementReportObligations,