@dvmkit/sdk 0.19.0 → 0.19.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-Y6JJDOGO.js → chunk-6RJAE332.js} +17 -7
- package/dist/{chunk-A6EY4K46.js → chunk-QCZXKUS2.js} +45 -13
- package/dist/{chunk-NLMRNLKA.js → chunk-RPJKEWRR.js} +125 -39
- package/dist/{content-retention-sUCPlA1J.d.ts → content-retention-C_TToHCi.d.ts} +1 -1
- package/dist/{credit-menu-D88XuTLU.d.ts → credit-menu-BlODG4E7.d.ts} +10 -1
- package/dist/index.d.ts +1 -1
- package/dist/internal/server.d.ts +3 -3
- package/dist/internal/server.js +3 -3
- package/dist/{job-store-Dy-ogco6.d.ts → job-store-D4-18IKm.d.ts} +4 -0
- package/dist/{postgres-job-store-E5GXLRB4.js → postgres-job-store-QKN5LGAH.js} +1 -1
- package/dist/server/index.d.ts +7 -6
- package/dist/server/index.js +4 -4
- package/dist/testing/index.d.ts +4 -2
- package/dist/testing/index.js +1 -1
- package/package.json +2 -2
|
@@ -49,6 +49,7 @@ var MemoryJobStore = class {
|
|
|
49
49
|
data = /* @__PURE__ */ new Map();
|
|
50
50
|
messages = /* @__PURE__ */ new Map();
|
|
51
51
|
nextSeq = /* @__PURE__ */ new Map();
|
|
52
|
+
outgoingAppends = /* @__PURE__ */ new Map();
|
|
52
53
|
messageSubscribers = /* @__PURE__ */ new Map();
|
|
53
54
|
notifySubscribers = /* @__PURE__ */ new Map();
|
|
54
55
|
reactivationLocks = /* @__PURE__ */ new Set();
|
|
@@ -136,6 +137,7 @@ var MemoryJobStore = class {
|
|
|
136
137
|
delete(id) {
|
|
137
138
|
this.contentHolds.delete(id);
|
|
138
139
|
this.data.delete(id);
|
|
140
|
+
this.outgoingAppends.delete(id);
|
|
139
141
|
this.messages.delete(id);
|
|
140
142
|
this.nextSeq.delete(id);
|
|
141
143
|
this.receiptSeqs.delete(id);
|
|
@@ -205,6 +207,8 @@ var MemoryJobStore = class {
|
|
|
205
207
|
if (!record || record.redactedAt !== void 0) {
|
|
206
208
|
return Promise.reject(new Error(`appendOutgoing: job ${jobId} not found`));
|
|
207
209
|
}
|
|
210
|
+
const prior = opts?.appendId ? this.outgoingAppends.get(jobId)?.get(opts.appendId) : void 0;
|
|
211
|
+
if (prior !== void 0) return Promise.resolve(prior);
|
|
208
212
|
const seq = this.allocateSeq(jobId);
|
|
209
213
|
const fullMessage = { ...message, seq };
|
|
210
214
|
if (opts?.awaitingInput && !isTerminal(record.status)) {
|
|
@@ -240,6 +244,11 @@ var MemoryJobStore = class {
|
|
|
240
244
|
}
|
|
241
245
|
if (!isTerminal(record.status)) record.lastActivityAt = Date.now();
|
|
242
246
|
if (seq > record.seq) record.seq = seq;
|
|
247
|
+
if (opts?.appendId) {
|
|
248
|
+
let appends = this.outgoingAppends.get(jobId);
|
|
249
|
+
if (!appends) this.outgoingAppends.set(jobId, appends = /* @__PURE__ */ new Map());
|
|
250
|
+
appends.set(opts.appendId, seq);
|
|
251
|
+
}
|
|
243
252
|
this.notify(jobId);
|
|
244
253
|
return Promise.resolve(seq);
|
|
245
254
|
}
|
|
@@ -356,6 +365,9 @@ var MemoryJobStore = class {
|
|
|
356
365
|
cancelJob(jobId, reason) {
|
|
357
366
|
return this.terminateJob(jobId, reason, "cancelled", null);
|
|
358
367
|
}
|
|
368
|
+
failJob(jobId, reason) {
|
|
369
|
+
return this.terminateJob(jobId, reason, "failed", null);
|
|
370
|
+
}
|
|
359
371
|
getCounters(jobId) {
|
|
360
372
|
const record = this.data.get(jobId);
|
|
361
373
|
if (!record) return Promise.resolve(void 0);
|
|
@@ -435,13 +447,11 @@ var MemoryJobStore = class {
|
|
|
435
447
|
if (!record) return Promise.resolve(false);
|
|
436
448
|
const eligible = (record.status === "processing" || record.status === "working" || record.status === "awaiting-input") && (expectedActivityBefore === null || record.lastActivityAt <= expectedActivityBefore);
|
|
437
449
|
if (!eligible) return Promise.resolve(false);
|
|
438
|
-
|
|
450
|
+
const messages = this.messagesFor(jobId).filter((entry) => entry.status === "verified").map((entry) => entry.message);
|
|
451
|
+
const terminalMessages = messages.length ? messages : record.messages;
|
|
439
452
|
if (expectedActivityBefore !== null) {
|
|
440
|
-
const
|
|
441
|
-
const
|
|
442
|
-
terminalMessages = history;
|
|
443
|
-
const deadline = callerDeadline({ ...record, messages: history });
|
|
444
|
-
const awaiting = deadline !== void 0 || record.status === "awaiting-input" && !hasCallerDeadline(history);
|
|
453
|
+
const deadline = callerDeadline({ ...record, messages: terminalMessages });
|
|
454
|
+
const awaiting = deadline !== void 0 || record.status === "awaiting-input" && !hasCallerDeadline(terminalMessages);
|
|
445
455
|
if (terminalStatus === "cancelled" !== awaiting || deadline !== void 0 && Date.now() < deadline) return Promise.resolve(false);
|
|
446
456
|
}
|
|
447
457
|
const seq = this.allocateSeq(jobId);
|
|
@@ -453,7 +463,7 @@ var MemoryJobStore = class {
|
|
|
453
463
|
content: { reason }
|
|
454
464
|
};
|
|
455
465
|
this.messagesFor(jobId).push({ message: cancelMsg, status: "verified" });
|
|
456
|
-
record.endedBy =
|
|
466
|
+
record.endedBy = terminalStatus === "cancelled" ? "caller" : "provider";
|
|
457
467
|
applyTiming(record, structuredClone(record), Date.now(), terminalStatus);
|
|
458
468
|
record.status = terminalStatus;
|
|
459
469
|
record.summary = record.summary ?? reason;
|
|
@@ -345,6 +345,15 @@ var PostgresJobStore = class {
|
|
|
345
345
|
ALTER TABLE job_messages ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'verified';
|
|
346
346
|
ALTER TABLE job_messages ADD COLUMN IF NOT EXISTS created_at_ms BIGINT;
|
|
347
347
|
|
|
348
|
+
-- Survives terminal message cleanup so a lost COMMIT acknowledgement can
|
|
349
|
+
-- be retried without allocating another sequence or applying counters twice.
|
|
350
|
+
CREATE TABLE IF NOT EXISTS job_outgoing_appends (
|
|
351
|
+
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
|
352
|
+
append_id TEXT NOT NULL,
|
|
353
|
+
seq INTEGER NOT NULL,
|
|
354
|
+
PRIMARY KEY (job_id, append_id)
|
|
355
|
+
);
|
|
356
|
+
|
|
348
357
|
-- per-DVM monotonic receipt counter. Single row by
|
|
349
358
|
-- construction (the CHECK pins the key), and per-DVM by construction
|
|
350
359
|
-- too \u2014 the SDK runs one database per DVM (see postgres-kv-store.ts).
|
|
@@ -791,7 +800,11 @@ var PostgresJobStore = class {
|
|
|
791
800
|
if (this.hostingCleanupFence) {
|
|
792
801
|
throw new Error("Hosted job deletion cannot discard obligation evidence");
|
|
793
802
|
}
|
|
794
|
-
await this.pool.query(
|
|
803
|
+
await this.pool.query(
|
|
804
|
+
`WITH deleted AS (DELETE FROM jobs WHERE id=$1 RETURNING id)
|
|
805
|
+
DELETE FROM job_outgoing_appends WHERE job_id IN (SELECT id FROM deleted)`,
|
|
806
|
+
[id]
|
|
807
|
+
);
|
|
795
808
|
await this.deleteResolvedMessages(id).catch(() => void 0);
|
|
796
809
|
}
|
|
797
810
|
async listJobsForRetention(args) {
|
|
@@ -945,6 +958,18 @@ var PostgresJobStore = class {
|
|
|
945
958
|
const client = await this.pool.connect();
|
|
946
959
|
try {
|
|
947
960
|
await client.query("BEGIN");
|
|
961
|
+
if (opts?.appendId) {
|
|
962
|
+
const owner = await client.query("SELECT id FROM jobs WHERE id=$1 AND redacted_at IS NULL FOR UPDATE", [jobId]);
|
|
963
|
+
if (!owner.rows.length) throw new Error(`appendOutgoing: job ${jobId} not found`);
|
|
964
|
+
const prior = await client.query(
|
|
965
|
+
"SELECT seq FROM job_outgoing_appends WHERE job_id=$1 AND append_id=$2",
|
|
966
|
+
[jobId, opts.appendId]
|
|
967
|
+
);
|
|
968
|
+
if (prior.rows[0]) {
|
|
969
|
+
await client.query("COMMIT");
|
|
970
|
+
return prior.rows[0].seq;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
948
973
|
const { rows } = await client.query(
|
|
949
974
|
`UPDATE jobs SET next_seq = next_seq + 1, last_activity_at = CASE WHEN status IN ('completed','failed','cancelled') THEN last_activity_at ELSE $2 END,
|
|
950
975
|
awaiting_input_at_ms = CASE WHEN $3::boolean AND status NOT IN ('completed', 'failed', 'cancelled')
|
|
@@ -1024,6 +1049,12 @@ var PostgresJobStore = class {
|
|
|
1024
1049
|
]
|
|
1025
1050
|
);
|
|
1026
1051
|
}
|
|
1052
|
+
if (opts?.appendId) {
|
|
1053
|
+
await client.query(
|
|
1054
|
+
"INSERT INTO job_outgoing_appends (job_id, append_id, seq) VALUES ($1,$2,$3)",
|
|
1055
|
+
[jobId, opts.appendId, seq]
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1027
1058
|
await client.query("SELECT pg_notify('job_messages', $1)", [jobId]);
|
|
1028
1059
|
await client.query("COMMIT");
|
|
1029
1060
|
return seq;
|
|
@@ -1239,6 +1270,9 @@ var PostgresJobStore = class {
|
|
|
1239
1270
|
cancelJob(jobId, reason) {
|
|
1240
1271
|
return this.terminateJob(jobId, reason, "cancelled", null, "caller");
|
|
1241
1272
|
}
|
|
1273
|
+
failJob(jobId, reason) {
|
|
1274
|
+
return this.terminateJob(jobId, reason, "failed", null, "provider");
|
|
1275
|
+
}
|
|
1242
1276
|
cancelJobForHosting(jobId, reason) {
|
|
1243
1277
|
return this.terminateJob(jobId, reason, "cancelled", null, "provider");
|
|
1244
1278
|
}
|
|
@@ -1429,17 +1463,15 @@ var PostgresJobStore = class {
|
|
|
1429
1463
|
await client.query("ROLLBACK");
|
|
1430
1464
|
return false;
|
|
1431
1465
|
}
|
|
1432
|
-
|
|
1466
|
+
const record = rowToRecord(rows[0]);
|
|
1467
|
+
const { rows: messages } = await client.query(
|
|
1468
|
+
"SELECT data FROM job_messages WHERE job_id=$1 AND status='verified' ORDER BY seq",
|
|
1469
|
+
[jobId]
|
|
1470
|
+
);
|
|
1471
|
+
const terminalMessages = messages.length ? messages.map((row) => row.data) : record.messages;
|
|
1433
1472
|
if (staleOnly) {
|
|
1434
|
-
const
|
|
1435
|
-
const
|
|
1436
|
-
"SELECT data FROM job_messages WHERE job_id=$1 AND status='verified' ORDER BY seq",
|
|
1437
|
-
[jobId]
|
|
1438
|
-
);
|
|
1439
|
-
const history = messages.length ? messages.map((row) => row.data) : record.messages;
|
|
1440
|
-
terminalMessages = history;
|
|
1441
|
-
const deadline = callerDeadline({ ...record, messages: history });
|
|
1442
|
-
const awaiting = deadline !== void 0 || record.status === "awaiting-input" && !hasCallerDeadline(history);
|
|
1473
|
+
const deadline = callerDeadline({ ...record, messages: terminalMessages });
|
|
1474
|
+
const awaiting = deadline !== void 0 || record.status === "awaiting-input" && !hasCallerDeadline(terminalMessages);
|
|
1443
1475
|
if (terminalStatus === "cancelled" !== awaiting || deadline !== void 0 && Date.now() < deadline) {
|
|
1444
1476
|
await client.query("ROLLBACK");
|
|
1445
1477
|
return false;
|
|
@@ -1467,7 +1499,7 @@ var PostgresJobStore = class {
|
|
|
1467
1499
|
awaiting_input_at_ms = NULL,
|
|
1468
1500
|
status = $6,
|
|
1469
1501
|
summary = COALESCE(summary, $2),
|
|
1470
|
-
messages = $
|
|
1502
|
+
messages = $3::jsonb,
|
|
1471
1503
|
seq = $4,
|
|
1472
1504
|
next_seq = $4 + 1,
|
|
1473
1505
|
last_activity_at = $5
|
|
@@ -1475,7 +1507,7 @@ var PostgresJobStore = class {
|
|
|
1475
1507
|
[
|
|
1476
1508
|
jobId,
|
|
1477
1509
|
reason,
|
|
1478
|
-
JSON.stringify([...terminalMessages
|
|
1510
|
+
JSON.stringify([...terminalMessages, cancelMsg]),
|
|
1479
1511
|
nextSeq,
|
|
1480
1512
|
now,
|
|
1481
1513
|
terminalStatus,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./chunk-DJRTYBEE.js";
|
|
21
21
|
import {
|
|
22
22
|
PostgresJobStore
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-QCZXKUS2.js";
|
|
24
24
|
import {
|
|
25
25
|
CASHU_MIN_LOCKTIME_SECONDS,
|
|
26
26
|
DEFAULT_CASHU_LOCK_WINDOW_SECONDS,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
isJobRetentionStore,
|
|
43
43
|
isReceiptIssuingStore,
|
|
44
44
|
isStreamableJobStore
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-6RJAE332.js";
|
|
46
46
|
import {
|
|
47
47
|
ContentHoldError,
|
|
48
48
|
JobCancelledError,
|
|
@@ -14604,6 +14604,7 @@ var ORPHAN_SWEEP_CLAIMS = /* @__PURE__ */ new WeakSet();
|
|
|
14604
14604
|
var ATTACH_RAILS = ["cashu", "x402", "tempo"];
|
|
14605
14605
|
var CREDIT_INBOUND_ATTEMPTS = 3;
|
|
14606
14606
|
var CREDIT_INBOUND_BACKOFF_MS = 50;
|
|
14607
|
+
var TERMINAL_PERSIST_RETRY_MS = 3e4;
|
|
14607
14608
|
var TERMINAL_COST_HANDOFF_RETRY_INITIAL_MS = 100;
|
|
14608
14609
|
var TERMINAL_COST_HANDOFF_RETRY_MAX_MS = 3e4;
|
|
14609
14610
|
var CREDIT_INBOUND_READ_ATTEMPTS = 2;
|
|
@@ -14618,6 +14619,11 @@ var JobManager = class {
|
|
|
14618
14619
|
idleTimers = /* @__PURE__ */ new Map();
|
|
14619
14620
|
cleanupTimers = /* @__PURE__ */ new Map();
|
|
14620
14621
|
terminalReadRepairs = /* @__PURE__ */ new Map();
|
|
14622
|
+
terminalSnapshots = /* @__PURE__ */ new WeakMap();
|
|
14623
|
+
terminalFailures = /* @__PURE__ */ new WeakMap();
|
|
14624
|
+
terminalPersistenceRetries = /* @__PURE__ */ new Map();
|
|
14625
|
+
terminalPersistenceStopped = false;
|
|
14626
|
+
outgoingQueues = /* @__PURE__ */ new WeakMap();
|
|
14621
14627
|
/** Cost revisions held only by a terminal handler owner until its durable merge succeeds. */
|
|
14622
14628
|
terminalCostHandoffRetryTimers = /* @__PURE__ */ new Map();
|
|
14623
14629
|
/** Per-job NOTIFY unsubscribe handles for the durable-status watch. */
|
|
@@ -15229,10 +15235,82 @@ var JobManager = class {
|
|
|
15229
15235
|
* subscriber's NOTIFY-driven fetch can see it).
|
|
15230
15236
|
*/
|
|
15231
15237
|
async persistJob(job) {
|
|
15238
|
+
if (!isTerminal(job.status)) return this.persistSnapshot(job);
|
|
15239
|
+
let work = this.terminalSnapshots.get(job);
|
|
15240
|
+
if (!work) {
|
|
15241
|
+
work = this.persistTerminalSnapshot(job).then(() => {
|
|
15242
|
+
clearTimeout(this.terminalPersistenceRetries.get(job.id));
|
|
15243
|
+
this.terminalPersistenceRetries.delete(job.id);
|
|
15244
|
+
}).catch((error) => {
|
|
15245
|
+
if (this.terminalFailures.has(job)) this.scheduleTerminalPersistenceRetry(job);
|
|
15246
|
+
throw error;
|
|
15247
|
+
}).finally(() => this.terminalSnapshots.delete(job));
|
|
15248
|
+
this.terminalSnapshots.set(job, work);
|
|
15249
|
+
}
|
|
15250
|
+
return work;
|
|
15251
|
+
}
|
|
15252
|
+
scheduleTerminalPersistenceRetry(job) {
|
|
15253
|
+
if (this.terminalPersistenceStopped || this.terminalPersistenceRetries.has(job.id)) return;
|
|
15254
|
+
const timer = setTimeout(() => {
|
|
15255
|
+
this.terminalPersistenceRetries.delete(job.id);
|
|
15256
|
+
job.terminalWork = this.handleJobTerminal(job).catch(() => {
|
|
15257
|
+
this.scheduleTerminalPersistenceRetry(job);
|
|
15258
|
+
});
|
|
15259
|
+
}, 1e3);
|
|
15260
|
+
timer.unref?.();
|
|
15261
|
+
this.terminalPersistenceRetries.set(job.id, timer);
|
|
15262
|
+
}
|
|
15263
|
+
async persistTerminalSnapshot(job) {
|
|
15264
|
+
const deadline = performance.now() + TERMINAL_PERSIST_RETRY_MS;
|
|
15265
|
+
await job.messageAppenderTail;
|
|
15266
|
+
while (!this.terminalFailures.has(job)) {
|
|
15267
|
+
try {
|
|
15268
|
+
if (await this.adoptDurableTerminal(job)) return;
|
|
15269
|
+
await this.flushOutgoing(job);
|
|
15270
|
+
await this.persistSnapshot(job, true);
|
|
15271
|
+
return;
|
|
15272
|
+
} catch {
|
|
15273
|
+
if (performance.now() >= deadline) break;
|
|
15274
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(500, deadline - performance.now())));
|
|
15275
|
+
}
|
|
15276
|
+
}
|
|
15277
|
+
const reason = this.terminalFailures.get(job) ?? (job.status === "completed" ? "terminal_persistence_failed" : job.messages.findLast((m) => m.type === "cancel")?.content?.reason ?? job.summary ?? "terminal_persistence_failed");
|
|
15278
|
+
this.terminalFailures.set(job, reason);
|
|
15279
|
+
const durable = await this.jobStore.get(job.id);
|
|
15280
|
+
if (durable && isTerminal(durable.status)) {
|
|
15281
|
+
const adopted = await this.adoptDurableTerminal(job);
|
|
15282
|
+
if (!adopted && durable.status !== "completed") await this.tryPersistAdoptedTerminalCost(job, 1);
|
|
15283
|
+
return;
|
|
15284
|
+
}
|
|
15285
|
+
job.status = "failed";
|
|
15286
|
+
job.summary = reason;
|
|
15287
|
+
this.outgoingQueues.delete(job);
|
|
15288
|
+
const store = this.jobStore;
|
|
15289
|
+
if (isStreamableJobStore(store) && store.failJob) {
|
|
15290
|
+
await store.failJob(job.id, reason);
|
|
15291
|
+
const saved = await store.get(job.id);
|
|
15292
|
+
if (!saved || !isTerminal(saved.status)) throw new JobSnapshotPersistenceError("failure not committed");
|
|
15293
|
+
job.status = saved.status;
|
|
15294
|
+
job.summary = saved.summary;
|
|
15295
|
+
job.messages = saved.messages;
|
|
15296
|
+
job.seq = saved.seq;
|
|
15297
|
+
job.endedBy = saved.endedBy;
|
|
15298
|
+
job.terminalAtMs = saved.terminalAtMs;
|
|
15299
|
+
job.callerWaitMs = saved.callerWaitMs;
|
|
15300
|
+
job.timingKnown = saved.timingKnown;
|
|
15301
|
+
await this.tryPersistAdoptedTerminalCost(job, 1);
|
|
15302
|
+
} else {
|
|
15303
|
+
job.messages = job.messages.filter((m) => m.type !== "complete");
|
|
15304
|
+
localMessage(job, "provider", "cancel", { reason });
|
|
15305
|
+
await this.persistSnapshot(job, true);
|
|
15306
|
+
}
|
|
15307
|
+
}
|
|
15308
|
+
async persistSnapshot(job, terminalReady = false) {
|
|
15232
15309
|
if (job.messageAppenderTail) {
|
|
15233
15310
|
await job.messageAppenderTail.catch(() => void 0);
|
|
15234
15311
|
}
|
|
15235
15312
|
if (await this.adoptDurableTerminal(job)) return;
|
|
15313
|
+
if (isTerminal(job.status) && !terminalReady) return this.persistJob(job);
|
|
15236
15314
|
const record = toJobRecord(job);
|
|
15237
15315
|
if (isTerminal(job.status) && isStreamableJobStore(this.jobStore)) {
|
|
15238
15316
|
const durable = await this.jobStore.getMessages(job.id, 0, { includeHeld: true });
|
|
@@ -15501,44 +15579,37 @@ var JobManager = class {
|
|
|
15501
15579
|
*/
|
|
15502
15580
|
wireMessageAppender(job) {
|
|
15503
15581
|
if (!isStreamableJobStore(this.jobStore)) return;
|
|
15504
|
-
const store = this.jobStore;
|
|
15505
15582
|
const jobId = job.id;
|
|
15506
15583
|
job.messageAppender = (msg, opts) => {
|
|
15584
|
+
let queue = this.outgoingQueues.get(job);
|
|
15585
|
+
if (!queue) this.outgoingQueues.set(job, queue = []);
|
|
15586
|
+
queue.push({ msg: structuredClone(msg), opts: { ...opts, appendId: randomBytes4(16).toString("hex") } });
|
|
15507
15587
|
const prev = job.messageAppenderTail ?? Promise.resolve();
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
return store.appendOutgoing(
|
|
15511
|
-
jobId,
|
|
15512
|
-
{
|
|
15513
|
-
from: msg.from,
|
|
15514
|
-
type: msg.type,
|
|
15515
|
-
timestamp: msg.timestamp,
|
|
15516
|
-
content: msg.content
|
|
15517
|
-
},
|
|
15518
|
-
opts
|
|
15519
|
-
).then((stored) => {
|
|
15520
|
-
if (msg.type === "payment-request" && pending && job.pendingPayment === pending) {
|
|
15521
|
-
this.paymentAskSeqs.set(pending, stored);
|
|
15522
|
-
}
|
|
15523
|
-
}).catch((_err) => {
|
|
15524
|
-
diagnosticConsole.error(
|
|
15525
|
-
{
|
|
15526
|
-
level: "job_message_append_failed",
|
|
15527
|
-
jobId,
|
|
15528
|
-
// In-memory counter, NOT the authoritative DB-allocated seq:
|
|
15529
|
-
// `appendOutgoing` allocates the real seq via `UPDATE ...
|
|
15530
|
-
// RETURNING` inside the transaction that just failed, so no DB
|
|
15531
|
-
// seq was assigned for this message.
|
|
15532
|
-
localSeq: msg.seq,
|
|
15533
|
-
note: void 0,
|
|
15534
|
-
error: void 0
|
|
15535
|
-
}
|
|
15536
|
-
);
|
|
15537
|
-
});
|
|
15588
|
+
job.messageAppenderTail = prev.then(() => this.flushOutgoing(job)).catch(() => {
|
|
15589
|
+
diagnosticConsole.error({ level: "job_message_append_failed", jobId, localSeq: msg.seq });
|
|
15538
15590
|
});
|
|
15539
|
-
job.messageAppenderTail = next;
|
|
15540
15591
|
};
|
|
15541
15592
|
}
|
|
15593
|
+
async flushOutgoing(job) {
|
|
15594
|
+
const store = this.jobStore;
|
|
15595
|
+
if (!isStreamableJobStore(store)) return;
|
|
15596
|
+
const queue = this.outgoingQueues.get(job);
|
|
15597
|
+
while (queue?.length) {
|
|
15598
|
+
const entry = queue[0];
|
|
15599
|
+
if (entry.pending === void 0) entry.pending = job.pendingPayment;
|
|
15600
|
+
const { msg, opts, pending } = entry;
|
|
15601
|
+
const stored = await store.appendOutgoing(job.id, {
|
|
15602
|
+
from: msg.from,
|
|
15603
|
+
type: msg.type,
|
|
15604
|
+
timestamp: msg.timestamp,
|
|
15605
|
+
content: msg.content
|
|
15606
|
+
}, opts);
|
|
15607
|
+
if (msg.type === "payment-request" && pending && job.pendingPayment === pending) {
|
|
15608
|
+
this.paymentAskSeqs.set(pending, stored);
|
|
15609
|
+
}
|
|
15610
|
+
queue.shift();
|
|
15611
|
+
}
|
|
15612
|
+
}
|
|
15542
15613
|
startIdleTimer(job, deadline = callerDeadline(job, this.descriptor.idleTimeout * 1e3)) {
|
|
15543
15614
|
this.clearIdleTimer(job.id);
|
|
15544
15615
|
if (deadline === void 0) return;
|
|
@@ -17157,7 +17228,8 @@ var JobManager = class {
|
|
|
17157
17228
|
try {
|
|
17158
17229
|
const seq = await store.claimReceiptSeq(record.id);
|
|
17159
17230
|
const receipt = issuer.issue(record, seq, void 0, credit);
|
|
17160
|
-
const saved = await store.saveReceipt(record.id, receipt)
|
|
17231
|
+
const saved = await store.saveReceipt(record.id, receipt);
|
|
17232
|
+
if (!saved) return void 0;
|
|
17161
17233
|
await this.observePaidCompletion(record);
|
|
17162
17234
|
return saved;
|
|
17163
17235
|
} catch (_err) {
|
|
@@ -17196,6 +17268,17 @@ var JobManager = class {
|
|
|
17196
17268
|
async resolveCreditDraw(record) {
|
|
17197
17269
|
const ledger = this.opts.creditLedger;
|
|
17198
17270
|
if (!ledger || !record.creditId || !record.drawId) return void 0;
|
|
17271
|
+
const args = this.drawResolutionArgs(record.creditId, record.drawId);
|
|
17272
|
+
const existing = await ledger.getDraw(args);
|
|
17273
|
+
if (existing?.status === "settled" && this.settlesDraw(record.status)) {
|
|
17274
|
+
return {
|
|
17275
|
+
credit_id: existing.creditId,
|
|
17276
|
+
draw_id: existing.drawId,
|
|
17277
|
+
amount: existing.amountMicro,
|
|
17278
|
+
balance_after: existing.balanceAfterMicro,
|
|
17279
|
+
ledger_seq: existing.ledgerSeq
|
|
17280
|
+
};
|
|
17281
|
+
}
|
|
17199
17282
|
const deferredIntent = deferredX402IntentId(record.creditId);
|
|
17200
17283
|
if (deferredIntent) {
|
|
17201
17284
|
const deferred = this.opts.deferredX402;
|
|
@@ -17214,7 +17297,6 @@ var JobManager = class {
|
|
|
17214
17297
|
return void 0;
|
|
17215
17298
|
}
|
|
17216
17299
|
}
|
|
17217
|
-
const args = this.drawResolutionArgs(record.creditId, record.drawId);
|
|
17218
17300
|
try {
|
|
17219
17301
|
const res = this.settlesDraw(record.status) ? await ledger.settle(args) : await ledger.release(args);
|
|
17220
17302
|
return {
|
|
@@ -17400,7 +17482,7 @@ var JobManager = class {
|
|
|
17400
17482
|
this.clearIdleTimer(job.id);
|
|
17401
17483
|
if (await this.adoptDurableTerminal(job)) return;
|
|
17402
17484
|
const durable = await this.jobStore.get(job.id);
|
|
17403
|
-
if (!durable || !isTerminal(durable.status)) await this.persistJob(job);
|
|
17485
|
+
if (!durable || !isTerminal(durable.status) || this.terminalFailures.has(job)) await this.persistJob(job);
|
|
17404
17486
|
await this.attachReceipt(job);
|
|
17405
17487
|
const booked = await this.bookRevenue(job);
|
|
17406
17488
|
if (!booked) await this.reportJobCost(job);
|
|
@@ -17673,6 +17755,7 @@ var JobManager = class {
|
|
|
17673
17755
|
this.cleanupTimers.set(job.id, timer);
|
|
17674
17756
|
}
|
|
17675
17757
|
shutdown() {
|
|
17758
|
+
this.terminalPersistenceStopped = true;
|
|
17676
17759
|
for (const [id] of this.idleTimers) {
|
|
17677
17760
|
this.clearIdleTimer(id);
|
|
17678
17761
|
}
|
|
@@ -17680,6 +17763,8 @@ var JobManager = class {
|
|
|
17680
17763
|
clearTimeout(timer);
|
|
17681
17764
|
this.cleanupTimers.delete(id);
|
|
17682
17765
|
}
|
|
17766
|
+
for (const timer of this.terminalPersistenceRetries.values()) clearTimeout(timer);
|
|
17767
|
+
this.terminalPersistenceRetries.clear();
|
|
17683
17768
|
for (const [id, timer] of this.terminalCostHandoffRetryTimers) {
|
|
17684
17769
|
clearTimeout(timer);
|
|
17685
17770
|
this.terminalCostHandoffRetryTimers.delete(id);
|
|
@@ -24543,11 +24628,12 @@ var DVMServer = class {
|
|
|
24543
24628
|
async contentFields(job) {
|
|
24544
24629
|
const store = this.jobManager.store;
|
|
24545
24630
|
const responseStatus = job.status;
|
|
24631
|
+
const evidence = isTerminal(job.status) && this.jobManager.receiptsEnabled && !job.receipt ? { receipt_pending: true } : {};
|
|
24546
24632
|
if (isContentHoldStore(store)) {
|
|
24547
24633
|
const snapshot = await store.getContentSnapshot(job.id);
|
|
24548
|
-
if (snapshot) return { ...contentMetadata({ ...snapshot.job, status: responseStatus }, this.descriptor.jobRetentionDays, snapshot.history.holds) };
|
|
24634
|
+
if (snapshot) return { ...evidence, ...contentMetadata({ ...snapshot.job, status: responseStatus }, this.descriptor.jobRetentionDays, snapshot.history.holds) };
|
|
24549
24635
|
}
|
|
24550
|
-
return isContentHoldStore(store) ? { ...contentMetadata(job, this.descriptor.jobRetentionDays) } :
|
|
24636
|
+
return isContentHoldStore(store) ? { ...evidence, ...contentMetadata(job, this.descriptor.jobRetentionDays) } : evidence;
|
|
24551
24637
|
}
|
|
24552
24638
|
async messageFields(job, messages) {
|
|
24553
24639
|
const fields = await this.contentFields(job);
|
|
@@ -5,7 +5,7 @@ import { Hono, Context } from 'hono';
|
|
|
5
5
|
import { Pool } from 'pg';
|
|
6
6
|
import { d as FxSourceFailure, b as FxRateSnapshot, F as FxFetcher } from './fx-QoVA2oBc.js';
|
|
7
7
|
import { Store, Challenge } from 'mppx';
|
|
8
|
-
import { T as TopUpCapUnenforcedReason, A as AppendOutgoingOptions, J as JobRecord, b as JobStore } from './job-store-
|
|
8
|
+
import { T as TopUpCapUnenforcedReason, A as AppendOutgoingOptions, J as JobRecord, b as JobStore } from './job-store-D4-18IKm.js';
|
|
9
9
|
import { SettleResponse, SupportedResponse } from '@x402/core/types';
|
|
10
10
|
import { Channel, AutoSettlementConfig } from '@x402/evm/batch-settlement/server';
|
|
11
11
|
import { FacilitatorClient } from '@x402/core/server';
|
|
@@ -3131,6 +3131,11 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
3131
3131
|
private readonly idleTimers;
|
|
3132
3132
|
private readonly cleanupTimers;
|
|
3133
3133
|
private readonly terminalReadRepairs;
|
|
3134
|
+
private readonly terminalSnapshots;
|
|
3135
|
+
private readonly terminalFailures;
|
|
3136
|
+
private readonly terminalPersistenceRetries;
|
|
3137
|
+
private terminalPersistenceStopped;
|
|
3138
|
+
private readonly outgoingQueues;
|
|
3134
3139
|
/** Cost revisions held only by a terminal handler owner until its durable merge succeeds. */
|
|
3135
3140
|
private readonly terminalCostHandoffRetryTimers;
|
|
3136
3141
|
/** Per-job NOTIFY unsubscribe handles for the durable-status watch. */
|
|
@@ -3323,6 +3328,9 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
3323
3328
|
* subscriber's NOTIFY-driven fetch can see it).
|
|
3324
3329
|
*/
|
|
3325
3330
|
persistJob(job: ServerJob): Promise<void>;
|
|
3331
|
+
private scheduleTerminalPersistenceRetry;
|
|
3332
|
+
private persistTerminalSnapshot;
|
|
3333
|
+
private persistSnapshot;
|
|
3326
3334
|
/**
|
|
3327
3335
|
* Cross-machine terminal guard. `buildContext`'s guard reads the
|
|
3328
3336
|
* in-memory `job.status`, so on its own it only protects the machine running
|
|
@@ -3407,6 +3415,7 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
3407
3415
|
* `artifact`'s NOTIFY silently drops the artifact.
|
|
3408
3416
|
*/
|
|
3409
3417
|
private wireMessageAppender;
|
|
3418
|
+
private flushOutgoing;
|
|
3410
3419
|
startIdleTimer(job: ServerJob, deadline?: number | undefined): void;
|
|
3411
3420
|
clearIdleTimer(id: string): void;
|
|
3412
3421
|
/** Cancel a job due to idle timeout. Exposed for the reactivation path's idle-expiry guard. */
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { C as Currency, Z as ZodLike, D as DVMConfig, a as DVMDescriptor } from
|
|
|
2
2
|
export { A as ApprovalContent, b as ArtifactContent, c as CancelContent, d as CanonicalEnvelope, e as CapabilityRate, f as CashuConfig, g as CreateSignedRequestVerifierOpts, h as CreditConfig, i as CreditView, j as DEFAULT_CREDIT_MAX, k as DEFAULT_CREDIT_MIN, l as DEFAULT_CREDIT_TTL_SECONDS, m as DEFAULT_JOB_RETENTION_DAYS, n as DVMRouteContext, I as IncomingMessage, o as InputType, p as InvalidCurrencyError, J as JobCost, K as KVStore, L as Logger, P as PaymentContent, q as PaymentMethod, r as PriceValue, s as ProgressContent, t as PromptOpts, Q as QuoteConfig, u as QuoteContext, v as QuoteResult, R as ResolvedCashuConfig, w as ResolvedCreditConfig, x as ResponseContent, S as SDKJobContext, y as SDKPaymentRequestOpts, z as SIGNED_REQUEST_AUTH_ID, B as SIGNED_REQUEST_STATEMENT_VERSION, E as SignedRequestAudience, F as SignedRequestDomain, G as SignedRequestError, H as SignedRequestFailure, M as SignedRequestReplayStore, N as SignedRequestSignOpts, O as SignedRequestStatementHeader, T as SignedRequestVerifier, U as UnsupportedCurrencyError, V as UpfrontPayment, W as createSignedRequestVerifier, X as isZodSchema, Y as signedRequestStatementHeader, _ as validateCurrency } from './step-cache-B83Y9T9p.js';
|
|
3
3
|
export { C as CreateFxFetcherOpts, D as DEFAULT_FX_CURRENCIES, a as DEFAULT_FX_RATE_SOURCE, F as FxFetcher, b as FxRateSnapshot, c as FxRateUnavailableError, d as FxSourceFailure, e as FxSourceFailureCategory, P as PlatformFxSource, f as createFxFetcher, g as fxRateFor, r as resolveFxSourceFromEnv } from './fx-QoVA2oBc.js';
|
|
4
4
|
export { I as InvalidFxRateError, f as fiatToSatsCeil, a as formatFiat, b as formatUsd, r as roundUsd, s as satsToFiat } from './usd-g9kCw86F.js';
|
|
5
|
-
export { J as JobRecord, a as JobStatus, b as JobStore } from './job-store-
|
|
5
|
+
export { J as JobRecord, a as JobStatus, b as JobStore } from './job-store-D4-18IKm.js';
|
|
6
6
|
export { P as PinnedFetch, S as SSRFError, a as SSRFGuardOpts, b as SSRFReason, c as SSRFResolver, d as assertSafeUrl, e as createPinnedFetch } from './ssrf-dMooihtY.js';
|
|
7
7
|
export { z } from 'zod';
|
|
8
8
|
import 'hono';
|
|
@@ -6,9 +6,9 @@ import { Env, BlankSchema } from 'hono/types';
|
|
|
6
6
|
import { Pool } from 'pg';
|
|
7
7
|
export { Pool } from 'pg';
|
|
8
8
|
import { g as getWallet } from '../wallet-Dwjs5n_M.js';
|
|
9
|
-
import { C as ConsumedCredentialStore, L as LockPubkeyStateLoader } from '../credit-menu-
|
|
10
|
-
export { A as AccumulatorPool, a as AppEnv, b as CreditFundingReport, D as DEFAULT_LOCK_PUBKEY_GRACE_SECONDS, F as FiatDenomination, c as FiatDenominationFailure, d as FundOnlyRequest, I as IncomingPaymentOpts, J as JobCancelledError, e as LockPubkeyPool, f as LockPubkeyState, M as MintHealthTracker, P as PAYMENT_PROOF_KEYS, g as PaymentErrorCode, h as PaymentErrorDetail, i as PaymentInfo, j as PostgresTempoChargeStore, R as ReporterBannerOpts, k as ResolvedFx, l as RevenueBootCheckOpts, S as SDKServerOpts, m as ServerJob, n as ShortPayForfeit, T as TempoChannelReport, o as TempoObserverHealth, p as TempoSessionChannelMismatchError, U as UpfrontPaymentOpts, V as VerifiedIncomingPayment, q as VerifyIncomingSnapshot, X as X402BatchChannelObservation, r as X402FacilitatorHealth, s as X402SettlementEvidenceOutcome, t as X402SettlementRepair, u as X402SettlementRepairRefusal, v as X402SettlementRepaired, w as X402WedgedSettlement, x as X402WedgedSettlementPage, y as X402_BATCH_SETTLEMENT_MAINNET_NETWORK, z as abortJob, B as activePubkeySet, E as applyPaymentInfoToJob, G as assertRevenueReporterReady, H as buildPaymentErrorResponse, K as clearAccumulatorForDvm, N as createDVMServer, O as creditDepositPayload, Q as derivedFundCreditId, W as devModeSkipsPaymentVerification, Y as fromJobRecord, Z as fundedMicroFor, _ as hasPaymentProof, $ as hashLockKey, a0 as implicitCreditId, a1 as initLockPubkeyTable, a2 as initWalletAccumulatorTable, a3 as insertAccumulatorRows, a4 as isDerivedCreditId, a5 as isTerminal, a6 as isYieldMessage, a7 as issueUpfrontChallenges, a8 as loadLockPubkeyState, a9 as msatsToFiatMicro, aa as paymentErrorBody, ab as pinAskFiat, ac as priceFiatMicro, ad as processIncomingPayment, ae as providerMessage, af as pruneRetired, ag as repairX402ExactSettlementEffect, ah as resolveFxSnapshot, ai as resolvePriceFiat, aj as revenueReporterBannerState, ak as rotateLockPubkey, al as seedLockPubkeyState, am as toCreditTerms, an as toJobRecord, ao as unknownRouteNotFound, ap as verifyIncomingPayment, aq as verifyTempoSessionManagementCredential, ar as verifyUpfrontPayment, as as x402RequiredUsdcMicro, at as x402SettledShare } from '../credit-menu-
|
|
11
|
-
export { O as OutgoingMessage, S as StaleJobReapable, i as isStaleJobReapable } from '../job-store-
|
|
9
|
+
import { C as ConsumedCredentialStore, L as LockPubkeyStateLoader } from '../credit-menu-BlODG4E7.js';
|
|
10
|
+
export { A as AccumulatorPool, a as AppEnv, b as CreditFundingReport, D as DEFAULT_LOCK_PUBKEY_GRACE_SECONDS, F as FiatDenomination, c as FiatDenominationFailure, d as FundOnlyRequest, I as IncomingPaymentOpts, J as JobCancelledError, e as LockPubkeyPool, f as LockPubkeyState, M as MintHealthTracker, P as PAYMENT_PROOF_KEYS, g as PaymentErrorCode, h as PaymentErrorDetail, i as PaymentInfo, j as PostgresTempoChargeStore, R as ReporterBannerOpts, k as ResolvedFx, l as RevenueBootCheckOpts, S as SDKServerOpts, m as ServerJob, n as ShortPayForfeit, T as TempoChannelReport, o as TempoObserverHealth, p as TempoSessionChannelMismatchError, U as UpfrontPaymentOpts, V as VerifiedIncomingPayment, q as VerifyIncomingSnapshot, X as X402BatchChannelObservation, r as X402FacilitatorHealth, s as X402SettlementEvidenceOutcome, t as X402SettlementRepair, u as X402SettlementRepairRefusal, v as X402SettlementRepaired, w as X402WedgedSettlement, x as X402WedgedSettlementPage, y as X402_BATCH_SETTLEMENT_MAINNET_NETWORK, z as abortJob, B as activePubkeySet, E as applyPaymentInfoToJob, G as assertRevenueReporterReady, H as buildPaymentErrorResponse, K as clearAccumulatorForDvm, N as createDVMServer, O as creditDepositPayload, Q as derivedFundCreditId, W as devModeSkipsPaymentVerification, Y as fromJobRecord, Z as fundedMicroFor, _ as hasPaymentProof, $ as hashLockKey, a0 as implicitCreditId, a1 as initLockPubkeyTable, a2 as initWalletAccumulatorTable, a3 as insertAccumulatorRows, a4 as isDerivedCreditId, a5 as isTerminal, a6 as isYieldMessage, a7 as issueUpfrontChallenges, a8 as loadLockPubkeyState, a9 as msatsToFiatMicro, aa as paymentErrorBody, ab as pinAskFiat, ac as priceFiatMicro, ad as processIncomingPayment, ae as providerMessage, af as pruneRetired, ag as repairX402ExactSettlementEffect, ah as resolveFxSnapshot, ai as resolvePriceFiat, aj as revenueReporterBannerState, ak as rotateLockPubkey, al as seedLockPubkeyState, am as toCreditTerms, an as toJobRecord, ao as unknownRouteNotFound, ap as verifyIncomingPayment, aq as verifyTempoSessionManagementCredential, ar as verifyUpfrontPayment, as as x402RequiredUsdcMicro, at as x402SettledShare } from '../credit-menu-BlODG4E7.js';
|
|
11
|
+
export { O as OutgoingMessage, S as StaleJobReapable, i as isStaleJobReapable } from '../job-store-D4-18IKm.js';
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
export { f as LockPubkeyStoreLockPubkey, t as lockPubkeyStoreToLockPubkey } from '../lightning-backend-B2wMBR-x.js';
|
|
14
14
|
import 'mppx';
|
package/dist/internal/server.js
CHANGED
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
verifyUpfrontPayment,
|
|
62
62
|
x402RequiredUsdcMicro,
|
|
63
63
|
x402SettledShare
|
|
64
|
-
} from "../chunk-
|
|
64
|
+
} from "../chunk-RPJKEWRR.js";
|
|
65
65
|
import "../chunk-XRLKGCAW.js";
|
|
66
66
|
import {
|
|
67
67
|
PayoutReporter
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
verifyWithFacilitator
|
|
72
72
|
} from "../chunk-C65P6MGZ.js";
|
|
73
73
|
import "../chunk-DJRTYBEE.js";
|
|
74
|
-
import "../chunk-
|
|
74
|
+
import "../chunk-QCZXKUS2.js";
|
|
75
75
|
import {
|
|
76
76
|
SIGNED_ENVELOPE_FIELDS,
|
|
77
77
|
SIGNED_ENVELOPE_TYPES,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
import {
|
|
82
82
|
createInstrumentedFetch,
|
|
83
83
|
isStaleJobReapable
|
|
84
|
-
} from "../chunk-
|
|
84
|
+
} from "../chunk-6RJAE332.js";
|
|
85
85
|
import {
|
|
86
86
|
JobCancelledError,
|
|
87
87
|
abortJob,
|
|
@@ -256,6 +256,8 @@ interface PaymentCreditDelta {
|
|
|
256
256
|
}
|
|
257
257
|
/** Atomic side effects applied with an outgoing provider message. */
|
|
258
258
|
interface AppendOutgoingOptions {
|
|
259
|
+
/** Stable identity for retrying an append whose commit acknowledgement was lost. */
|
|
260
|
+
appendId?: string;
|
|
259
261
|
/** A suspending SDK prompt/payment yield; event-driven messages leave status unchanged. */
|
|
260
262
|
awaitingInput?: boolean;
|
|
261
263
|
pendingPaymentDelta?: number;
|
|
@@ -567,6 +569,8 @@ interface StreamableJobStore extends JobStore {
|
|
|
567
569
|
* machine won).
|
|
568
570
|
*/
|
|
569
571
|
cancelJob(jobId: string, reason: string): Promise<boolean>;
|
|
572
|
+
/** Atomically fail a nonterminal job with its final reason and durable message history. */
|
|
573
|
+
failJob?(jobId: string, reason: string): Promise<boolean>;
|
|
570
574
|
/**
|
|
571
575
|
* Bump `last_activity_at` to `now` (Unix ms) for the given jobs that are
|
|
572
576
|
* still in `processing`/`working`. Called on a
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { ai as CashuMode, bT as CreditLedgerQuerier, bU as CreditDrainEnqueue, bV as HostedSettlementReportObligations, w as ResolvedCreditConfig, bW as DVMAuthScheme, F as SignedRequestDomain, bX as CreditLedgerLike, bY as X402RefundSettlementGate, bZ as CreditSnapshot, b_ as CreditDrawRefundArgs, b$ as CreditDrawRefundResult, c0 as DrawResult, c1 as X402SettlementStatus, c2 as X402UnresolvedRefund, c3 as GrownDrawResult, c4 as DrawResolution, c5 as FundingRecord, c6 as CreditFundingEvidence, c7 as CreditInvoiceRecord, c8 as InvoiceSettlement, c9 as BlockedInvoiceCursor, ca as InvoiceReconciliation, cb as InvoiceWriteOff, cc as DrawRecord, cd as StalePendingDrawCursor, ce as TempoCreditLossEvidence, cf as TempoCreditLoss, cg as X402CreditLossEvidence, ch as X402CreditLoss, ci as DrainMethod, cj as DrainRequestResult, ck as BitcoinDepositLiability, bx as FundingLot, cl as CreditDrainRecord, cm as ChannelDrainCursor, cn as DrainWriteOff, co as DrainTransitionResult, cp as DrainReleaseResult, cq as DrainFulfilment, cr as HostingCleanupFence, aC as StepRecord, a4 as JobReceipt, a9 as Message, K as KVStore, M as SignedRequestReplayStore, Z as ZodLike, a as DVMDescriptor } from '../step-cache-B83Y9T9p.js';
|
|
2
2
|
export { cs as CLIENT_COMPATIBILITY_HEADERS, d as CanonicalEnvelope, ct as ClientCompatibility, cu as ClientCompatibilityEnv, cv as ClientCompatibilityGate, cw as ClientCompatibilityRequirement, cx as ClientSemVer, g as CreateSignedRequestVerifierOpts, cy as CreditFundingBasis, cz as CreditInvoiceStatus, cA as CreditLedger, cB as CreditLedgerError, cC as CreditLedgerErrorCode, cD as CreditLedgerErrorDetails, cE as CreditLedgerPool, cF as CreditStatus, cG as DRAIN_DELIVERY_RESERVE_SATS, cH as DVM_PROTOCOL_VERSION, cI as DrainConflictReason, cJ as DrawRailValue, cK as DrawStatus, cL as HostedTempoCloseReportWriteOff, cM as JobCostReportPayload, cN as JobTerminalReportPayload, cO as PostgresX402ChannelStorage, cP as ReplayStoreBackend, cQ as RevenueSkippedNoRailPayload, cR as RevenueSkippedNoRailReason, z as SIGNED_REQUEST_AUTH_ID, B as SIGNED_REQUEST_STATEMENT_VERSION, cS as Secp256k1AuthOpts, E as SignedRequestAudience, G as SignedRequestError, H as SignedRequestFailure, N as SignedRequestSignOpts, O as SignedRequestStatementHeader, T as SignedRequestVerifier, cT as TempoDrainDecision, cU as TempoDrainDecisionArgs, cV as TempoDrainDecisionResult, cW as TempoDrainHoldReason, V as UpfrontPayment, cX as X402ChannelStorageOpts, cY as X402RelayLockHolder, cZ as X402RelaySubmissionLock, c_ as X402RelaySubmissionLockError, c$ as allocateDrawValue, d0 as clientCompatibilityAttributes, d1 as clientCompatibilityMiddleware, d2 as clientUpgradeRequired, W as createSignedRequestVerifier, d3 as parseClientCapabilities, d4 as parseClientCompatibility, d5 as parseDvmClient, d6 as parseProtocolVersion, d7 as requireClientCompatibility, d8 as retryHostedTempoCloseReport, d9 as secp256k1Auth, da as signedRequestInput, Y as signedRequestStatementHeader, db as writeOffHostedTempoCloseReport } from '../step-cache-B83Y9T9p.js';
|
|
3
3
|
import { Pool } from 'pg';
|
|
4
|
-
import { au as CreditMenu, a as AppEnv, U as UpfrontPaymentOpts, i as PaymentInfo, av as ReceiptIssuer, aw as LightningReceive, ax as TempoSettlementReadiness, ay as DVMHostOpts, az as DVMServeResult, L as LockPubkeyStateLoader, C as ConsumedCredentialStore } from '../credit-menu-
|
|
5
|
-
export { aA as BuildCreditMenuArgs, aB as BuilderIdentity, aC as CREDIT_ENVELOPE_KEYS, aD as CreateX402BatchSettlementServerOpts, aE as CreditEnvelope, aF as CreditEnvelopeError, aG as CreditFundCommitment, aH as CreditTerms, aI as DEFAULT_INVOICE_TTL_SECONDS, aJ as DVMHost, aK as HostingClosureCommand, aL as HostingClosureEvidence, aM as HostingControlCommand, aN as HostingControlConfig, aO as HostingControlStatus, aP as JobManager, aQ as JobManagerOpts, aR as LightningReceiveConfig, aS as MIN_INVOICE_TTL_SECONDS, aT as MemoryConsumedCredentialStore, aU as MemoryConsumedCredentialStoreOpts, aV as MemoryProcessedPaymentStore, aW as MemoryX402ExactSettlementStore, aX as MountOpts, aY as OwnerDisplay, aZ as PaidJobCompletion, a_ as PaymentMode, a$ as PlatformReporterOpts, b0 as PostgresProcessedPaymentStore, b1 as PostgresX402ExactSettlementStore, b2 as PriceFiat, b3 as ProcessedPaymentQuerier, b4 as ProcessedPaymentRail, b5 as ProcessedPaymentRecord, b6 as ProcessedPaymentReplayError, b7 as ProcessedPaymentStore, b8 as X402BatchAcceptance, b9 as X402BatchFunding, ba as X402BatchRefusal, bb as X402BatchSettlementServer, bc as X402ExactAcceptance, bd as X402ExactIntentConflictError, be as X402ExactSettlementAttempt, bf as X402ExactSettlementChainEvidence, bg as X402ExactSettlementEffect, bh as X402ExactSettlementEvidenceMissingError, bi as X402ExactSettlementEvidenceReader, bj as X402ExactSettlementIntent, bk as X402ExactSettlementNotReadyError, bl as X402ExactSettlementServer, bm as X402ExactSettlementServerOpts, bn as X402ExactSettlementStatus, bo as X402ExactSettlementStore, bp as X402SettlementChainEvidence, bq as X402SettlementEvidenceReader, br as X402SettlementSubmissionError, bs as X402_BATCH_AUTO_SETTLEMENT, bt as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bu as X402_BATCH_SETTLEMENT_NETWORK, bv as attachCreditMenu, bw as buildCreditMenu, bx as createDVMHost, by as createX402BatchSettlementServer, bz as creditEnvelopeIgnoreFields, bA as drawSettlementRef, bB as extractCreditEnvelope, bC as fundingCommitment, bD as selectPrimaryCredit, bE as signHostingClosure, bF as signHostingControl, bG as stripCreditEnvelope, bH as toCreditView } from '../credit-menu-
|
|
4
|
+
import { au as CreditMenu, a as AppEnv, U as UpfrontPaymentOpts, i as PaymentInfo, av as ReceiptIssuer, aw as LightningReceive, ax as TempoSettlementReadiness, ay as DVMHostOpts, az as DVMServeResult, L as LockPubkeyStateLoader, C as ConsumedCredentialStore } from '../credit-menu-BlODG4E7.js';
|
|
5
|
+
export { aA as BuildCreditMenuArgs, aB as BuilderIdentity, aC as CREDIT_ENVELOPE_KEYS, aD as CreateX402BatchSettlementServerOpts, aE as CreditEnvelope, aF as CreditEnvelopeError, aG as CreditFundCommitment, aH as CreditTerms, aI as DEFAULT_INVOICE_TTL_SECONDS, aJ as DVMHost, aK as HostingClosureCommand, aL as HostingClosureEvidence, aM as HostingControlCommand, aN as HostingControlConfig, aO as HostingControlStatus, aP as JobManager, aQ as JobManagerOpts, aR as LightningReceiveConfig, aS as MIN_INVOICE_TTL_SECONDS, aT as MemoryConsumedCredentialStore, aU as MemoryConsumedCredentialStoreOpts, aV as MemoryProcessedPaymentStore, aW as MemoryX402ExactSettlementStore, aX as MountOpts, aY as OwnerDisplay, aZ as PaidJobCompletion, a_ as PaymentMode, a$ as PlatformReporterOpts, b0 as PostgresProcessedPaymentStore, b1 as PostgresX402ExactSettlementStore, b2 as PriceFiat, b3 as ProcessedPaymentQuerier, b4 as ProcessedPaymentRail, b5 as ProcessedPaymentRecord, b6 as ProcessedPaymentReplayError, b7 as ProcessedPaymentStore, b8 as X402BatchAcceptance, b9 as X402BatchFunding, ba as X402BatchRefusal, bb as X402BatchSettlementServer, bc as X402ExactAcceptance, bd as X402ExactIntentConflictError, be as X402ExactSettlementAttempt, bf as X402ExactSettlementChainEvidence, bg as X402ExactSettlementEffect, bh as X402ExactSettlementEvidenceMissingError, bi as X402ExactSettlementEvidenceReader, bj as X402ExactSettlementIntent, bk as X402ExactSettlementNotReadyError, bl as X402ExactSettlementServer, bm as X402ExactSettlementServerOpts, bn as X402ExactSettlementStatus, bo as X402ExactSettlementStore, bp as X402SettlementChainEvidence, bq as X402SettlementEvidenceReader, br as X402SettlementSubmissionError, bs as X402_BATCH_AUTO_SETTLEMENT, bt as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bu as X402_BATCH_SETTLEMENT_NETWORK, bv as attachCreditMenu, bw as buildCreditMenu, bx as createDVMHost, by as createX402BatchSettlementServer, bz as creditEnvelopeIgnoreFields, bA as drawSettlementRef, bB as extractCreditEnvelope, bC as fundingCommitment, bD as selectPrimaryCredit, bE as signHostingClosure, bF as signHostingControl, bG as stripCreditEnvelope, bH as toCreditView } from '../credit-menu-BlODG4E7.js';
|
|
6
6
|
import { Context, Hono } from 'hono';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { F as FxFetcher } from '../fx-QoVA2oBc.js';
|
|
9
|
-
import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters, b as JobStore } from '../job-store-
|
|
10
|
-
export { a as JobStatus, h as isStreamableJobStore } from '../job-store-
|
|
11
|
-
import { C as ContentHoldHistory, a as ContentHoldMutation } from '../content-retention-
|
|
12
|
-
export { b as ContentHold, c as ContentHoldError, d as ContentHoldEvent, e as ContentHoldStore, f as ContentHoldsResponse, J as JobContentMetadata, g as baselineContentExpiry, h as contentMetadata, i as isContentHoldStore } from '../content-retention-
|
|
9
|
+
import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters, b as JobStore } from '../job-store-D4-18IKm.js';
|
|
10
|
+
export { a as JobStatus, h as isStreamableJobStore } from '../job-store-D4-18IKm.js';
|
|
11
|
+
import { C as ContentHoldHistory, a as ContentHoldMutation } from '../content-retention-C_TToHCi.js';
|
|
12
|
+
export { b as ContentHold, c as ContentHoldError, d as ContentHoldEvent, e as ContentHoldStore, f as ContentHoldsResponse, J as JobContentMetadata, g as baselineContentExpiry, h as contentMetadata, i as isContentHoldStore } from '../content-retention-C_TToHCi.js';
|
|
13
13
|
export { P as PinnedFetch, S as SSRFError, a as SSRFGuardOpts, b as SSRFReason, c as SSRFResolver, d as assertSafeUrl, e as createPinnedFetch } from '../ssrf-dMooihtY.js';
|
|
14
14
|
import { Env, BlankSchema } from 'hono/types';
|
|
15
15
|
import 'mppx';
|
|
@@ -472,6 +472,7 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
|
|
|
472
472
|
heartbeatActiveJobs(jobIds: string[], now: number): Promise<void>;
|
|
473
473
|
cancelStaleJob(jobId: string, expectedActivityBefore: number, reason: string, terminalStatus: "failed" | "cancelled"): Promise<boolean>;
|
|
474
474
|
cancelJob(jobId: string, reason: string): Promise<boolean>;
|
|
475
|
+
failJob(jobId: string, reason: string): Promise<boolean>;
|
|
475
476
|
cancelJobForHosting(jobId: string, reason: string): Promise<boolean>;
|
|
476
477
|
getCounters(jobId: string): Promise<JobCounters | undefined>;
|
|
477
478
|
claimForProcessing(jobId: string): Promise<boolean>;
|
package/dist/server/index.js
CHANGED
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
toCreditView,
|
|
83
83
|
unknownRouteNotFound,
|
|
84
84
|
writeOffHostedTempoCloseReport
|
|
85
|
-
} from "../chunk-
|
|
85
|
+
} from "../chunk-RPJKEWRR.js";
|
|
86
86
|
import {
|
|
87
87
|
MemoryProcessedPaymentStore,
|
|
88
88
|
PostgresProcessedPaymentStore,
|
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
} from "../chunk-DJRTYBEE.js";
|
|
96
96
|
import {
|
|
97
97
|
PostgresJobStore
|
|
98
|
-
} from "../chunk-
|
|
98
|
+
} from "../chunk-QCZXKUS2.js";
|
|
99
99
|
import {
|
|
100
100
|
SignedRequestError,
|
|
101
101
|
createDefaultReplayStore,
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
} from "../chunk-MXESSBXF.js";
|
|
105
105
|
import {
|
|
106
106
|
isStreamableJobStore
|
|
107
|
-
} from "../chunk-
|
|
107
|
+
} from "../chunk-6RJAE332.js";
|
|
108
108
|
import {
|
|
109
109
|
ContentHoldError,
|
|
110
110
|
baselineContentExpiry,
|
|
@@ -1193,7 +1193,7 @@ function createDVMHost(opts = {}) {
|
|
|
1193
1193
|
});
|
|
1194
1194
|
applyRetryToPool(pool, "dvm-host");
|
|
1195
1195
|
pgPool = pool;
|
|
1196
|
-
const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-
|
|
1196
|
+
const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-QKN5LGAH.js");
|
|
1197
1197
|
const pgJobStore = new PostgresJobStore2(pool);
|
|
1198
1198
|
pendingInits.push(pgJobStore.init(), pgJobStore.initStreaming());
|
|
1199
1199
|
jobStore = pgJobStore;
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as ContentHoldHistory, a as ContentHoldMutation } from '../content-retention-
|
|
1
|
+
import { C as ContentHoldHistory, a as ContentHoldMutation } from '../content-retention-C_TToHCi.js';
|
|
2
2
|
import { a4 as JobReceipt, a9 as Message, a5 as MessageType, K as KVStore, L as Logger, x as ResponseContent, P as PaymentContent, S as SDKJobContext } from '../step-cache-B83Y9T9p.js';
|
|
3
|
-
import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-
|
|
3
|
+
import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-D4-18IKm.js';
|
|
4
4
|
import 'hono';
|
|
5
5
|
import 'mppx';
|
|
6
6
|
import '@x402/core/server';
|
|
@@ -21,6 +21,7 @@ declare class MemoryJobStore implements StreamableJobStore, ReceiptIssuingStore
|
|
|
21
21
|
private data;
|
|
22
22
|
private messages;
|
|
23
23
|
private nextSeq;
|
|
24
|
+
private outgoingAppends;
|
|
24
25
|
private messageSubscribers;
|
|
25
26
|
private notifySubscribers;
|
|
26
27
|
private reactivationLocks;
|
|
@@ -62,6 +63,7 @@ declare class MemoryJobStore implements StreamableJobStore, ReceiptIssuingStore
|
|
|
62
63
|
heartbeatActiveJobs(jobIds: string[], now: number): Promise<void>;
|
|
63
64
|
cancelStaleJob(jobId: string, expectedActivityBefore: number, reason: string, terminalStatus: "failed" | "cancelled"): Promise<boolean>;
|
|
64
65
|
cancelJob(jobId: string, reason: string): Promise<boolean>;
|
|
66
|
+
failJob(jobId: string, reason: string): Promise<boolean>;
|
|
65
67
|
getCounters(jobId: string): Promise<JobCounters | undefined>;
|
|
66
68
|
claimForProcessing(jobId: string): Promise<boolean>;
|
|
67
69
|
tryReactivationLock<T>(jobId: string, fn: () => Promise<T>): Promise<{
|
package/dist/testing/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dvmkit/sdk",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "SDK for building Digital Vending Machines: pay-per-use HTTPS services AI agents can find, pay, and call with no account or API key",
|
|
5
5
|
"author": "DVM Technologies Ltd",
|
|
6
6
|
"keywords": [
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"hono": "4.13.14",
|
|
93
93
|
"jose": "6.2.1",
|
|
94
94
|
"mppx": "0.8.15",
|
|
95
|
-
"nostr-tools": "2.
|
|
95
|
+
"nostr-tools": "2.25.4",
|
|
96
96
|
"proper-lockfile": "4.1.2",
|
|
97
97
|
"undici": "7.30.1",
|
|
98
98
|
"ws": "8.21.0",
|