@dvmkit/sdk 0.1.1-rc.7 → 0.1.3-rc.7
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/README.md +14 -0
- package/dist/chunk-2K7E3N2D.js +1709 -0
- package/dist/{chunk-Y6W5ZZTW.js → chunk-3ZHMQCYP.js} +666 -3031
- package/dist/{chunk-TKA6ZP4M.js → chunk-4B56DEEV.js} +50 -426
- package/dist/{chunk-X3IKFWJA.js → chunk-6BQM7TOW.js} +4 -1
- package/dist/chunk-BIFLRKMO.js +87 -0
- package/dist/chunk-BQ2NMWKE.js +160 -0
- package/dist/{chunk-LDTWX7JW.js → chunk-BTZY7VPH.js} +13 -1
- package/dist/{chunk-FJDCFHW5.js → chunk-C6JHBLMW.js} +3 -81
- package/dist/{chunk-EXHBXA4U.js → chunk-DBCLBYHP.js} +13 -1
- package/dist/chunk-EPNDZ5DH.js +1010 -0
- package/dist/{chunk-P4RUVDU7.js → chunk-H2MEFVH6.js} +12 -141
- package/dist/chunk-KXZUCCEY.js +142 -0
- package/dist/{chunk-6JZIX5WW.js → chunk-LLXV32HA.js} +82 -5
- package/dist/{chunk-LWUR4CGG.js → chunk-MLRCSJYX.js} +11 -3
- package/dist/{chunk-2ABMGUDS.js → chunk-NFRM5QYP.js} +83 -10
- package/dist/chunk-RW5LP57K.js +44 -0
- package/dist/chunk-YDIYXGYL.js +384 -0
- package/dist/{chunk-JGGI65I3.js → chunk-Z4BNLUZF.js} +1 -150
- package/dist/{credit-ledger-ED6JXKVD.js → credit-ledger-2DFQHNLB.js} +2 -2
- package/dist/{credit-menu-BrTfAr7l.d.ts → credit-menu-C7zAJElJ.d.ts} +1632 -1946
- package/dist/{fx-H6K6qcH1.d.ts → fx-BF_SG2i0.d.ts} +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +8 -4
- package/dist/internal/caller.d.ts +10429 -0
- package/dist/internal/caller.js +9957 -0
- package/dist/internal/index.d.ts +2 -10816
- package/dist/internal/index.js +2 -10130
- package/dist/internal/server.d.ts +404 -0
- package/dist/internal/server.js +202 -0
- package/dist/job-store-Bn23V3QU.d.ts +576 -0
- package/dist/lightning-backend-C04nH94l.d.ts +367 -0
- package/dist/{memory-credit-ledger-XJ5VQEVP.js → memory-credit-ledger-OP24Z2KO.js} +3 -3
- package/dist/{payout-reporter-3UB5WRCV.js → payout-reporter-RG6XNGPI.js} +1 -1
- package/dist/{postgres-job-store-J5F4GUWU.js → postgres-job-store-TAONYLIF.js} +1 -1
- package/dist/{revenue-reporter-JIKUPXOK.js → revenue-reporter-XXSU5KVB.js} +1 -1
- package/dist/server/index.d.ts +27 -11
- package/dist/server/index.js +93 -69
- package/dist/{job-store-DOSfYnLX.d.ts → step-cache-3cT4Shk0.d.ts} +38 -585
- package/dist/{tempo-session-store-DALMRIWN.js → tempo-session-store-2JNOKJGX.js} +2 -2
- package/dist/testing/index.d.ts +16 -4
- package/dist/testing/index.js +7 -3
- package/dist/{usd-Civ738b3.d.ts → usd-BnuXoFl5.d.ts} +1 -1
- package/dist/wallet-CJC8lwxx.d.ts +29 -0
- package/dist/{x402-FTG2GRAQ.js → x402-T2C5MX3T.js} +6 -3
- package/package.json +7 -2
- package/dist/{chunk-RU7SXHLO.js → chunk-UP2F5RRT.js} +3 -3
|
@@ -1,42 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
StepCache,
|
|
3
|
+
loggers
|
|
4
|
+
} from "./chunk-YDIYXGYL.js";
|
|
4
5
|
import {
|
|
5
6
|
redactUrl
|
|
6
7
|
} from "./chunk-FUJ36YDV.js";
|
|
7
8
|
|
|
8
|
-
// src/sdk/step-cache.ts
|
|
9
|
-
var StepCache = class _StepCache {
|
|
10
|
-
cache = /* @__PURE__ */ new Map();
|
|
11
|
-
/** Check if a step result is cached. */
|
|
12
|
-
has(id) {
|
|
13
|
-
return this.cache.has(id);
|
|
14
|
-
}
|
|
15
|
-
/** Get a cached step result. Throws if not present. */
|
|
16
|
-
get(id) {
|
|
17
|
-
if (!this.cache.has(id)) {
|
|
18
|
-
throw new Error(`StepCache: no cached result for step "${id}"`);
|
|
19
|
-
}
|
|
20
|
-
return this.cache.get(id);
|
|
21
|
-
}
|
|
22
|
-
/** Cache a step result. */
|
|
23
|
-
set(id, value) {
|
|
24
|
-
this.cache.set(id, value);
|
|
25
|
-
}
|
|
26
|
-
/** Export all cached steps for persistence. */
|
|
27
|
-
serialize() {
|
|
28
|
-
return [...this.cache.entries()].map(([id, value]) => ({ id, value }));
|
|
29
|
-
}
|
|
30
|
-
/** Restore a StepCache from persisted records. */
|
|
31
|
-
static deserialize(records) {
|
|
32
|
-
const cache = new _StepCache();
|
|
33
|
-
for (const { id, value } of records) {
|
|
34
|
-
cache.set(id, value);
|
|
35
|
-
}
|
|
36
|
-
return cache;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
9
|
// src/sdk/server/job.ts
|
|
41
10
|
function toJobRecord(job) {
|
|
42
11
|
return {
|
|
@@ -218,6 +187,9 @@ function accumulateAskedTopUp(prior, ask) {
|
|
|
218
187
|
return { micro: prior.micro + ask.micro, currency: prior.currency, reason: prior.reason };
|
|
219
188
|
}
|
|
220
189
|
var UNCAPPABLE_ASK_TOTAL = -1;
|
|
190
|
+
function isJobRetentionStore(store) {
|
|
191
|
+
return "listJobsForRetention" in store && "redactJob" in store;
|
|
192
|
+
}
|
|
221
193
|
function isReceiptIssuingStore(store) {
|
|
222
194
|
return "claimReceiptSeq" in store && "saveReceipt" in store;
|
|
223
195
|
}
|
|
@@ -298,7 +270,7 @@ var MemoryJobStore = class {
|
|
|
298
270
|
}
|
|
299
271
|
}
|
|
300
272
|
}
|
|
301
|
-
if (existing && isTerminal(existing.status) && existing.status !== record.status) {
|
|
273
|
+
if (existing && (existing.redactedAt !== void 0 || isTerminal(existing.status) && existing.status !== record.status)) {
|
|
302
274
|
return Promise.resolve();
|
|
303
275
|
}
|
|
304
276
|
const snapshot = structuredClone(record);
|
|
@@ -318,6 +290,38 @@ var MemoryJobStore = class {
|
|
|
318
290
|
this.receiptSeqs.delete(id);
|
|
319
291
|
return Promise.resolve();
|
|
320
292
|
}
|
|
293
|
+
listJobsForRetention(args) {
|
|
294
|
+
const capabilitySet = args.capabilities === null ? null : new Set(args.capabilities);
|
|
295
|
+
const matches = [...this.data.values()].filter(
|
|
296
|
+
(record) => record.redactedAt === void 0 && isTerminal(record.status) && record.lastActivityAt < args.lastActivityBeforeMs && (capabilitySet === null || capabilitySet.has(record.capability)) && (!args.after || compareRetentionKey(record, args.after) > 0)
|
|
297
|
+
).sort(compareRetentionKey).slice(0, args.limit).map((record) => structuredClone(record));
|
|
298
|
+
return Promise.resolve(matches);
|
|
299
|
+
}
|
|
300
|
+
redactJob(args) {
|
|
301
|
+
const record = this.data.get(args.jobId);
|
|
302
|
+
if (!record || record.redactedAt !== void 0 || !isTerminal(record.status) || record.lastActivityAt !== args.expectedLastActivityAt) {
|
|
303
|
+
return Promise.resolve(false);
|
|
304
|
+
}
|
|
305
|
+
record.input = "";
|
|
306
|
+
record.params = {};
|
|
307
|
+
record.summary = void 0;
|
|
308
|
+
record.messages = [];
|
|
309
|
+
record.receivedProofs = [];
|
|
310
|
+
record.pendingPaymentMsats = void 0;
|
|
311
|
+
record.pendingMppChallengeIds = void 0;
|
|
312
|
+
record.pendingX402Nonce = void 0;
|
|
313
|
+
record.pendingX402AmountUsdcMicro = void 0;
|
|
314
|
+
record.pendingPaymentFiatMicro = void 0;
|
|
315
|
+
record.pendingPaymentFiatCurrency = void 0;
|
|
316
|
+
record.stepCache = [];
|
|
317
|
+
record.state = {};
|
|
318
|
+
record.requesterToken = void 0;
|
|
319
|
+
record.requestFingerprint = void 0;
|
|
320
|
+
record.authRequestPath = void 0;
|
|
321
|
+
record.redactedAt = args.redactedAt;
|
|
322
|
+
this.messages.delete(args.jobId);
|
|
323
|
+
return Promise.resolve(true);
|
|
324
|
+
}
|
|
321
325
|
claimReceiptSeq(jobId) {
|
|
322
326
|
if (!this.data.has(jobId)) {
|
|
323
327
|
return Promise.reject(new Error(`claimReceiptSeq: job ${jobId} not found`));
|
|
@@ -336,7 +340,9 @@ var MemoryJobStore = class {
|
|
|
336
340
|
}
|
|
337
341
|
appendOutgoing(jobId, message, opts) {
|
|
338
342
|
const record = this.data.get(jobId);
|
|
339
|
-
if (!record
|
|
343
|
+
if (!record || record.redactedAt !== void 0) {
|
|
344
|
+
return Promise.reject(new Error(`appendOutgoing: job ${jobId} not found`));
|
|
345
|
+
}
|
|
340
346
|
const seq = this.allocateSeq(jobId);
|
|
341
347
|
const fullMessage = { ...message, seq };
|
|
342
348
|
this.messagesFor(jobId).push({ message: fullMessage, status: "verified" });
|
|
@@ -373,7 +379,9 @@ var MemoryJobStore = class {
|
|
|
373
379
|
}
|
|
374
380
|
recordInbound(jobId, message) {
|
|
375
381
|
const record = this.data.get(jobId);
|
|
376
|
-
if (!record
|
|
382
|
+
if (!record || record.redactedAt !== void 0) {
|
|
383
|
+
return Promise.reject(new Error(`recordInbound: job ${jobId} not found`));
|
|
384
|
+
}
|
|
377
385
|
const seq = this.allocateSeq(jobId);
|
|
378
386
|
const fullMessage = { ...message, seq };
|
|
379
387
|
this.messagesFor(jobId).push({ message: fullMessage, status: "pending-verification" });
|
|
@@ -611,6 +619,9 @@ var MemoryJobStore = class {
|
|
|
611
619
|
if (subs) for (const cb of subs) cb();
|
|
612
620
|
}
|
|
613
621
|
};
|
|
622
|
+
function compareRetentionKey(a, b) {
|
|
623
|
+
return a.lastActivityAt - b.lastActivityAt || a.id.localeCompare(b.id);
|
|
624
|
+
}
|
|
614
625
|
function requestIdClaimKey(requesterPubkey, requestId) {
|
|
615
626
|
return `${requesterPubkey}\0${requestId}`;
|
|
616
627
|
}
|
|
@@ -629,340 +640,6 @@ function snapshotCounters(record) {
|
|
|
629
640
|
};
|
|
630
641
|
}
|
|
631
642
|
|
|
632
|
-
// src/sdk/logger.ts
|
|
633
|
-
function createConsoleLogger(jobId) {
|
|
634
|
-
const fmt = (message, data) => {
|
|
635
|
-
const parts = [`[${jobId}] ${message}`];
|
|
636
|
-
if (data) parts.push(data);
|
|
637
|
-
return parts;
|
|
638
|
-
};
|
|
639
|
-
return {
|
|
640
|
-
debug(message, data) {
|
|
641
|
-
console.debug(...fmt(message, data));
|
|
642
|
-
},
|
|
643
|
-
info(message, data) {
|
|
644
|
-
console.info(...fmt(message, data));
|
|
645
|
-
},
|
|
646
|
-
warn(message, data) {
|
|
647
|
-
console.warn(...fmt(message, data));
|
|
648
|
-
},
|
|
649
|
-
error(message, data) {
|
|
650
|
-
console.error(...fmt(message, data));
|
|
651
|
-
}
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
function createStdoutLogger(context) {
|
|
655
|
-
const emit = (sink, level) => (message, data) => {
|
|
656
|
-
sink(JSON.stringify({ level, msg: message, ...context, ...data }));
|
|
657
|
-
};
|
|
658
|
-
return {
|
|
659
|
-
debug: emit(console.debug.bind(console), "debug"),
|
|
660
|
-
info: emit(console.info.bind(console), "info"),
|
|
661
|
-
warn: emit(console.warn.bind(console), "warn"),
|
|
662
|
-
error: emit(console.error.bind(console), "error")
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
function createNoopLogger() {
|
|
666
|
-
const noop2 = () => {
|
|
667
|
-
};
|
|
668
|
-
return { debug: noop2, info: noop2, warn: noop2, error: noop2 };
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
// src/observability/context.ts
|
|
672
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
673
|
-
import { randomBytes, randomUUID } from "crypto";
|
|
674
|
-
var storage = new AsyncLocalStorage();
|
|
675
|
-
var defaultService = "unknown";
|
|
676
|
-
function setDefaultService(service) {
|
|
677
|
-
defaultService = service;
|
|
678
|
-
}
|
|
679
|
-
function randomTraceId() {
|
|
680
|
-
const buf = randomBytes(16);
|
|
681
|
-
const now = Date.now();
|
|
682
|
-
buf.writeUInt16BE(Math.floor(now / 4294967296), 0);
|
|
683
|
-
buf.writeUInt32BE(now % 4294967296, 2);
|
|
684
|
-
buf[6] = buf[6] & 15 | 112;
|
|
685
|
-
buf[8] = buf[8] & 63 | 128;
|
|
686
|
-
return buf.toString("hex");
|
|
687
|
-
}
|
|
688
|
-
function randomSpanId() {
|
|
689
|
-
return randomUUID().replace(/-/g, "").slice(0, 16);
|
|
690
|
-
}
|
|
691
|
-
function withTraceContext(ctx, fn) {
|
|
692
|
-
return storage.run(ctx, fn);
|
|
693
|
-
}
|
|
694
|
-
function currentContext(service) {
|
|
695
|
-
const ctx = storage.getStore();
|
|
696
|
-
if (ctx) return ctx;
|
|
697
|
-
return {
|
|
698
|
-
traceId: randomTraceId(),
|
|
699
|
-
spanId: null,
|
|
700
|
-
dimensions: {},
|
|
701
|
-
service: service ?? defaultService
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
function pinDimension(key, value) {
|
|
705
|
-
const ctx = storage.getStore();
|
|
706
|
-
if (ctx) {
|
|
707
|
-
ctx.dimensions = { ...ctx.dimensions, [key]: value };
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
function rawContext() {
|
|
711
|
-
return storage.getStore();
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
// src/observability/with-span.ts
|
|
715
|
-
import { hostname } from "os";
|
|
716
|
-
|
|
717
|
-
// src/observability/stdout-sink.ts
|
|
718
|
-
var SENSITIVE_KEY_RE = /secret|token|password|private|bearer|seed|preimage|api[_-]?key|signing[_-]?key|priv[_-]?key/i;
|
|
719
|
-
var isTTY = typeof process.stdout.isTTY === "boolean" && process.stdout.isTTY;
|
|
720
|
-
var RED = isTTY ? "\x1B[31m" : "";
|
|
721
|
-
var YELLOW = isTTY ? "\x1B[33m" : "";
|
|
722
|
-
var RESET = isTTY ? "\x1B[0m" : "";
|
|
723
|
-
function formatSpanLine(span) {
|
|
724
|
-
const ts = new Date(span.started_at_ms).toISOString();
|
|
725
|
-
const levelStr = colorLevel(span.level);
|
|
726
|
-
const parts = [`[${ts}]`, span.dataset, `${levelStr}:`, span.name];
|
|
727
|
-
if (span.trace_id) {
|
|
728
|
-
parts.push(`trace=${span.trace_id}`);
|
|
729
|
-
}
|
|
730
|
-
for (const [k, v] of Object.entries(span.dimensions)) {
|
|
731
|
-
parts.push(formatKV(k, v));
|
|
732
|
-
}
|
|
733
|
-
for (const [k, v] of Object.entries(span.attributes)) {
|
|
734
|
-
parts.push(formatKV(k, v));
|
|
735
|
-
}
|
|
736
|
-
const durationMs = span.ended_at_ms - span.started_at_ms;
|
|
737
|
-
if (durationMs > 0) {
|
|
738
|
-
parts.push(`duration=${durationMs}ms`);
|
|
739
|
-
}
|
|
740
|
-
if (span.error_message) {
|
|
741
|
-
parts.push(`error=${truncate(span.error_message, 120)}`);
|
|
742
|
-
}
|
|
743
|
-
return parts.join(" ");
|
|
744
|
-
}
|
|
745
|
-
function writeSpanLine(span) {
|
|
746
|
-
const line = formatSpanLine(span);
|
|
747
|
-
process.stdout.write(line + "\n");
|
|
748
|
-
}
|
|
749
|
-
function colorLevel(level) {
|
|
750
|
-
if (level === "error") return `${RED}error${RESET}`;
|
|
751
|
-
if (level === "warn") return `${YELLOW}warn${RESET}`;
|
|
752
|
-
return level;
|
|
753
|
-
}
|
|
754
|
-
function formatKV(key, value) {
|
|
755
|
-
if (SENSITIVE_KEY_RE.test(key)) return `${key}=[REDACTED]`;
|
|
756
|
-
return `${key}=${truncate(stringify(value), 80)}`;
|
|
757
|
-
}
|
|
758
|
-
function stringify(value) {
|
|
759
|
-
if (typeof value === "string") return value;
|
|
760
|
-
if (value === void 0) return "undefined";
|
|
761
|
-
if (value === null) return "null";
|
|
762
|
-
if (typeof value === "function") return "[function]";
|
|
763
|
-
if (typeof value === "symbol") return value.toString();
|
|
764
|
-
if (typeof value === "bigint") return value.toString();
|
|
765
|
-
return JSON.stringify(value);
|
|
766
|
-
}
|
|
767
|
-
function truncate(s, max) {
|
|
768
|
-
if (s.length <= max) return s;
|
|
769
|
-
return s.slice(0, max - 3) + "...";
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
// src/observability/with-span.ts
|
|
773
|
-
var emitter = null;
|
|
774
|
-
function setEmitter(fn) {
|
|
775
|
-
emitter = fn;
|
|
776
|
-
}
|
|
777
|
-
var cachedHost = hostname();
|
|
778
|
-
var serviceVersion = process.env.GIT_SHA ?? process.env.FLY_IMAGE_REF ?? "dev";
|
|
779
|
-
async function withSpan(opts, fn) {
|
|
780
|
-
const spanId = randomSpanId();
|
|
781
|
-
const existingCtx = rawContext();
|
|
782
|
-
const ctx = existingCtx ?? currentContext();
|
|
783
|
-
const startMs = opts.startMs ?? Date.now();
|
|
784
|
-
let status = "ok";
|
|
785
|
-
let level = opts.level;
|
|
786
|
-
let errorMessage = null;
|
|
787
|
-
let errorStack = null;
|
|
788
|
-
if (opts.err) {
|
|
789
|
-
status = "error";
|
|
790
|
-
errorMessage = opts.err.message;
|
|
791
|
-
errorStack = opts.err.stack ?? null;
|
|
792
|
-
}
|
|
793
|
-
const childCtx = {
|
|
794
|
-
traceId: ctx.traceId,
|
|
795
|
-
spanId,
|
|
796
|
-
dimensions: { ...ctx.dimensions, ...opts.dims },
|
|
797
|
-
service: ctx.service,
|
|
798
|
-
tracestate: ctx.tracestate
|
|
799
|
-
};
|
|
800
|
-
const emitRow = () => {
|
|
801
|
-
const endMs = opts.endMs ?? Date.now();
|
|
802
|
-
const row = {
|
|
803
|
-
span_id: spanId,
|
|
804
|
-
trace_id: ctx.traceId,
|
|
805
|
-
parent_span_id: ctx.spanId,
|
|
806
|
-
dataset: opts.dataset,
|
|
807
|
-
name: opts.name,
|
|
808
|
-
level: level ?? (status === "error" ? "error" : "info"),
|
|
809
|
-
status,
|
|
810
|
-
started_at_ms: startMs,
|
|
811
|
-
ended_at_ms: endMs,
|
|
812
|
-
service: ctx.service,
|
|
813
|
-
service_version: serviceVersion,
|
|
814
|
-
host: cachedHost,
|
|
815
|
-
pid: process.pid,
|
|
816
|
-
dimensions: childCtx.dimensions,
|
|
817
|
-
attributes: opts.attrs ?? {},
|
|
818
|
-
error_message: errorMessage,
|
|
819
|
-
error_stack: errorStack,
|
|
820
|
-
sample_rate: 1
|
|
821
|
-
};
|
|
822
|
-
writeSpanLine(row);
|
|
823
|
-
if (emitter) emitter(row);
|
|
824
|
-
};
|
|
825
|
-
try {
|
|
826
|
-
const result = await withTraceContext(childCtx, () => fn());
|
|
827
|
-
if (opts.inspect) {
|
|
828
|
-
const overrides = opts.inspect(result);
|
|
829
|
-
if (overrides) {
|
|
830
|
-
if (overrides.status) status = overrides.status;
|
|
831
|
-
if (overrides.level) level = overrides.level;
|
|
832
|
-
if (overrides.errorMessage !== void 0) errorMessage = overrides.errorMessage;
|
|
833
|
-
if (overrides.attrs) Object.assign(opts.attrs ??= {}, overrides.attrs);
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
emitRow();
|
|
837
|
-
return result;
|
|
838
|
-
} catch (err) {
|
|
839
|
-
status = "error";
|
|
840
|
-
if (err instanceof Error) {
|
|
841
|
-
errorMessage = err.message;
|
|
842
|
-
errorStack = err.stack ?? null;
|
|
843
|
-
} else {
|
|
844
|
-
errorMessage = String(err);
|
|
845
|
-
}
|
|
846
|
-
if (opts.onError) {
|
|
847
|
-
const overrides = opts.onError(err);
|
|
848
|
-
if (overrides) Object.assign(opts.attrs ??= {}, overrides);
|
|
849
|
-
}
|
|
850
|
-
emitRow();
|
|
851
|
-
throw err;
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
// src/observability/datasets.ts
|
|
856
|
-
var SPANS_DATASETS = [
|
|
857
|
-
{ name: "platform", retentionDays: 90 },
|
|
858
|
-
{ name: "cashu", retentionDays: 90 },
|
|
859
|
-
{ name: "lightning", retentionDays: 90 },
|
|
860
|
-
{ name: "stripe", retentionDays: 90 },
|
|
861
|
-
{ name: "x402", retentionDays: 90 },
|
|
862
|
-
{ name: "tempo", retentionDays: 90 },
|
|
863
|
-
{ name: "isolate", retentionDays: 90 },
|
|
864
|
-
{ name: "audit", retentionDays: 365 },
|
|
865
|
-
{ name: "cron", retentionDays: 30 }
|
|
866
|
-
];
|
|
867
|
-
var DATASET_NAMES = new Set(SPANS_DATASETS.map((d) => d.name));
|
|
868
|
-
|
|
869
|
-
// src/observability/loggers.ts
|
|
870
|
-
var noop = () => {
|
|
871
|
-
};
|
|
872
|
-
var loggers = buildNoopLoggers();
|
|
873
|
-
function initLoggers(writer, service) {
|
|
874
|
-
setEmitter((row) => {
|
|
875
|
-
writer.enqueue(row);
|
|
876
|
-
});
|
|
877
|
-
setDefaultService(service);
|
|
878
|
-
const result = {};
|
|
879
|
-
for (const ds of SPANS_DATASETS) {
|
|
880
|
-
result[ds.name] = createLogger(ds.name, {});
|
|
881
|
-
}
|
|
882
|
-
loggers = result;
|
|
883
|
-
initCallerLoggers(result);
|
|
884
|
-
return result;
|
|
885
|
-
}
|
|
886
|
-
function createLogger(dataset, bakedDims) {
|
|
887
|
-
const logger = {
|
|
888
|
-
info(name, attrs) {
|
|
889
|
-
void withSpan({ dataset, name, level: "info", attrs, dims: bakedDims }, noop).catch(noop);
|
|
890
|
-
},
|
|
891
|
-
warn(name, attrs) {
|
|
892
|
-
void withSpan({ dataset, name, level: "warn", attrs, dims: bakedDims }, noop).catch(noop);
|
|
893
|
-
},
|
|
894
|
-
error(name, attrs) {
|
|
895
|
-
const err = attrs?.err instanceof Error ? attrs.err : void 0;
|
|
896
|
-
const cleanAttrs = attrs ? { ...attrs } : void 0;
|
|
897
|
-
if (cleanAttrs) delete cleanAttrs.err;
|
|
898
|
-
void withSpan(
|
|
899
|
-
{ dataset, name, level: "error", attrs: cleanAttrs, dims: bakedDims, err },
|
|
900
|
-
noop
|
|
901
|
-
).catch(noop);
|
|
902
|
-
},
|
|
903
|
-
async span(name, attrs, fn, opts) {
|
|
904
|
-
return withSpan({ dataset, name, attrs, dims: bakedDims, onError: opts?.onError }, fn);
|
|
905
|
-
},
|
|
906
|
-
timer(name, attrs) {
|
|
907
|
-
const startMs = Date.now();
|
|
908
|
-
return {
|
|
909
|
-
[Symbol.dispose]() {
|
|
910
|
-
const endMs = Date.now();
|
|
911
|
-
void withSpan({ dataset, name, attrs, dims: bakedDims, startMs, endMs }, noop).catch(
|
|
912
|
-
noop
|
|
913
|
-
);
|
|
914
|
-
}
|
|
915
|
-
};
|
|
916
|
-
},
|
|
917
|
-
set(dims) {
|
|
918
|
-
for (const [k, v] of Object.entries(dims)) {
|
|
919
|
-
pinDimension(k, v);
|
|
920
|
-
}
|
|
921
|
-
},
|
|
922
|
-
extend(dims) {
|
|
923
|
-
return createLogger(dataset, { ...bakedDims, ...dims });
|
|
924
|
-
},
|
|
925
|
-
tracked(name, fn) {
|
|
926
|
-
return ((...args) => logger.span(name, {}, () => fn(...args)));
|
|
927
|
-
}
|
|
928
|
-
};
|
|
929
|
-
return logger;
|
|
930
|
-
}
|
|
931
|
-
function buildNoopLoggers() {
|
|
932
|
-
const noopLogger = {
|
|
933
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
934
|
-
info() {
|
|
935
|
-
},
|
|
936
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
937
|
-
warn() {
|
|
938
|
-
},
|
|
939
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
940
|
-
error() {
|
|
941
|
-
},
|
|
942
|
-
async span(_name, _attrs, fn, _opts) {
|
|
943
|
-
return fn();
|
|
944
|
-
},
|
|
945
|
-
timer() {
|
|
946
|
-
return { [Symbol.dispose]() {
|
|
947
|
-
} };
|
|
948
|
-
},
|
|
949
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
950
|
-
set() {
|
|
951
|
-
},
|
|
952
|
-
extend() {
|
|
953
|
-
return noopLogger;
|
|
954
|
-
},
|
|
955
|
-
tracked(_name, fn) {
|
|
956
|
-
return fn;
|
|
957
|
-
}
|
|
958
|
-
};
|
|
959
|
-
const result = {};
|
|
960
|
-
for (const ds of SPANS_DATASETS) {
|
|
961
|
-
result[ds.name] = noopLogger;
|
|
962
|
-
}
|
|
963
|
-
return result;
|
|
964
|
-
}
|
|
965
|
-
|
|
966
643
|
// src/sdk/server/instrumented-fetch.ts
|
|
967
644
|
function createInstrumentedFetch(signal) {
|
|
968
645
|
return async (input, init) => {
|
|
@@ -986,49 +663,7 @@ function mergeSignals(a, b) {
|
|
|
986
663
|
return AbortSignal.any([a, b]);
|
|
987
664
|
}
|
|
988
665
|
|
|
989
|
-
// src/sdk/store.ts
|
|
990
|
-
var MemoryKVStore = class {
|
|
991
|
-
data = /* @__PURE__ */ new Map();
|
|
992
|
-
/** Retrieve a value by key. Returns undefined if not found or expired. */
|
|
993
|
-
get(key) {
|
|
994
|
-
const entry = this.data.get(key);
|
|
995
|
-
if (!entry) return Promise.resolve(void 0);
|
|
996
|
-
if (entry.expiry !== void 0 && Date.now() > entry.expiry) {
|
|
997
|
-
this.data.delete(key);
|
|
998
|
-
return Promise.resolve(void 0);
|
|
999
|
-
}
|
|
1000
|
-
return Promise.resolve(entry.value);
|
|
1001
|
-
}
|
|
1002
|
-
/** Store a value. Optionally set a TTL in seconds. */
|
|
1003
|
-
set(key, value, opts) {
|
|
1004
|
-
const expiry = opts?.ttl !== void 0 ? Date.now() + opts.ttl * 1e3 : void 0;
|
|
1005
|
-
this.data.set(key, { value, expiry });
|
|
1006
|
-
return Promise.resolve();
|
|
1007
|
-
}
|
|
1008
|
-
/** Delete a key. */
|
|
1009
|
-
delete(key) {
|
|
1010
|
-
this.data.delete(key);
|
|
1011
|
-
return Promise.resolve();
|
|
1012
|
-
}
|
|
1013
|
-
/** List keys, optionally filtered by prefix. Excludes expired entries. */
|
|
1014
|
-
list(prefix) {
|
|
1015
|
-
const now = Date.now();
|
|
1016
|
-
const keys = [];
|
|
1017
|
-
for (const [key, entry] of this.data) {
|
|
1018
|
-
if (entry.expiry !== void 0 && now > entry.expiry) {
|
|
1019
|
-
this.data.delete(key);
|
|
1020
|
-
continue;
|
|
1021
|
-
}
|
|
1022
|
-
if (prefix === void 0 || key.startsWith(prefix)) {
|
|
1023
|
-
keys.push(key);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
return Promise.resolve(keys);
|
|
1027
|
-
}
|
|
1028
|
-
};
|
|
1029
|
-
|
|
1030
666
|
export {
|
|
1031
|
-
StepCache,
|
|
1032
667
|
toJobRecord,
|
|
1033
668
|
fromJobRecord,
|
|
1034
669
|
abortJob,
|
|
@@ -1039,21 +674,10 @@ export {
|
|
|
1039
674
|
isYieldMessage,
|
|
1040
675
|
accumulateAskedTopUp,
|
|
1041
676
|
UNCAPPABLE_ASK_TOTAL,
|
|
677
|
+
isJobRetentionStore,
|
|
1042
678
|
isReceiptIssuingStore,
|
|
1043
679
|
isStreamableJobStore,
|
|
1044
680
|
isStaleJobReapable,
|
|
1045
681
|
MemoryJobStore,
|
|
1046
|
-
|
|
1047
|
-
createStdoutLogger,
|
|
1048
|
-
createNoopLogger,
|
|
1049
|
-
randomTraceId,
|
|
1050
|
-
withTraceContext,
|
|
1051
|
-
currentContext,
|
|
1052
|
-
pinDimension,
|
|
1053
|
-
setEmitter,
|
|
1054
|
-
withSpan,
|
|
1055
|
-
loggers,
|
|
1056
|
-
initLoggers,
|
|
1057
|
-
createInstrumentedFetch,
|
|
1058
|
-
MemoryKVStore
|
|
682
|
+
createInstrumentedFetch
|
|
1059
683
|
};
|
|
@@ -140,6 +140,7 @@ var PayoutReporter = class {
|
|
|
140
140
|
ownsBatchStore;
|
|
141
141
|
intervalMs;
|
|
142
142
|
now;
|
|
143
|
+
lastX402SnapshotAt = 0;
|
|
143
144
|
x402;
|
|
144
145
|
tempo;
|
|
145
146
|
timer = null;
|
|
@@ -572,6 +573,8 @@ var PayoutReporter = class {
|
|
|
572
573
|
async snapshotX402() {
|
|
573
574
|
const ctx = this.x402;
|
|
574
575
|
if (!ctx) return;
|
|
576
|
+
const snapshotAt = Math.max(this.now(), this.lastX402SnapshotAt + 1);
|
|
577
|
+
this.lastX402SnapshotAt = snapshotAt;
|
|
575
578
|
try {
|
|
576
579
|
const pools = [];
|
|
577
580
|
const wedged = [];
|
|
@@ -627,7 +630,7 @@ var PayoutReporter = class {
|
|
|
627
630
|
items: pools.length,
|
|
628
631
|
pools,
|
|
629
632
|
wedged,
|
|
630
|
-
snapshotAt
|
|
633
|
+
snapshotAt
|
|
631
634
|
});
|
|
632
635
|
} catch (err) {
|
|
633
636
|
warn("payout_pending_snapshot_failed", { rail: "x402", error: message(err) });
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createX402FacilitatorAuthHeaders,
|
|
3
|
+
settleWithFacilitator,
|
|
4
|
+
verifyWithFacilitator
|
|
5
|
+
} from "./chunk-BQ2NMWKE.js";
|
|
6
|
+
import {
|
|
7
|
+
buildPaymentRequirements,
|
|
8
|
+
decodePayment,
|
|
9
|
+
encodeSettleResponseHeader,
|
|
10
|
+
exactEvmAuthorization
|
|
11
|
+
} from "./chunk-Z4BNLUZF.js";
|
|
12
|
+
import {
|
|
13
|
+
usdcToMsats
|
|
14
|
+
} from "./chunk-5URG56JJ.js";
|
|
15
|
+
import {
|
|
16
|
+
callerLoggers
|
|
17
|
+
} from "./chunk-66HGCPBU.js";
|
|
18
|
+
|
|
19
|
+
// src/lib/x402/verify.ts
|
|
20
|
+
async function verifyX402Payment(paymentHeader, config, requiredUsdcMicro, resource, btcUsdRate, exactVersions = { v1: true, v2: true }) {
|
|
21
|
+
return callerLoggers.x402.span(
|
|
22
|
+
"x402.verify_payment",
|
|
23
|
+
{
|
|
24
|
+
resource,
|
|
25
|
+
required_usdc_micro: Number(requiredUsdcMicro),
|
|
26
|
+
facilitator_url: config.facilitator
|
|
27
|
+
},
|
|
28
|
+
async () => {
|
|
29
|
+
let payload;
|
|
30
|
+
try {
|
|
31
|
+
payload = decodePayment(paymentHeader);
|
|
32
|
+
} catch {
|
|
33
|
+
return { verified: false, amountMsats: 0, invalidReason: "decode_failed" };
|
|
34
|
+
}
|
|
35
|
+
if (payload.x402Version === 1 && !exactVersions.v1 || payload.x402Version === 2 && !exactVersions.v2) {
|
|
36
|
+
return { verified: false, amountMsats: 0, invalidReason: "unsupported_version" };
|
|
37
|
+
}
|
|
38
|
+
const requirementOpts = { x402Config: config, requiredUsdcMicro, resource };
|
|
39
|
+
const requirements = payload.x402Version === 1 ? buildPaymentRequirements({ ...requirementOpts, version: 1 }) : buildPaymentRequirements({ ...requirementOpts, version: 2 });
|
|
40
|
+
const createAuthHeaders = createX402FacilitatorAuthHeaders(config);
|
|
41
|
+
const verifyRes = await verifyWithFacilitator(
|
|
42
|
+
payload,
|
|
43
|
+
requirements,
|
|
44
|
+
config,
|
|
45
|
+
createAuthHeaders
|
|
46
|
+
);
|
|
47
|
+
if (!verifyRes.isValid) {
|
|
48
|
+
return {
|
|
49
|
+
verified: false,
|
|
50
|
+
amountMsats: 0,
|
|
51
|
+
invalidReason: verifyRes.invalidReason ?? "verify_failed"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const settleRes = await settleWithFacilitator(
|
|
55
|
+
payload,
|
|
56
|
+
requirements,
|
|
57
|
+
config,
|
|
58
|
+
createAuthHeaders
|
|
59
|
+
);
|
|
60
|
+
if (!settleRes.success) {
|
|
61
|
+
return {
|
|
62
|
+
verified: false,
|
|
63
|
+
amountMsats: 0,
|
|
64
|
+
invalidReason: settleRes.errorReason ?? "settle_failed"
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const amountUsdcMicro = Number.parseInt(exactEvmAuthorization(payload).value, 10);
|
|
68
|
+
const amountMsats = btcUsdRate > 0 ? usdcToMsats(amountUsdcMicro / 1e6, btcUsdRate) : 0;
|
|
69
|
+
callerLoggers.x402.info("x402.verify_payment.result", {
|
|
70
|
+
verified: true,
|
|
71
|
+
tx_hash: settleRes.transaction,
|
|
72
|
+
amount_msats: amountMsats
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
verified: true,
|
|
76
|
+
amountMsats,
|
|
77
|
+
amountUsdcMicro,
|
|
78
|
+
txHash: settleRes.transaction,
|
|
79
|
+
settleResponseHeader: encodeSettleResponseHeader(settleRes)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
verifyX402Payment
|
|
87
|
+
};
|