@dvmkit/sdk 0.1.2-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.
Files changed (45) hide show
  1. package/README.md +14 -0
  2. package/dist/chunk-2K7E3N2D.js +1709 -0
  3. package/dist/{chunk-N4VTG3KH.js → chunk-3ZHMQCYP.js} +645 -3027
  4. package/dist/{chunk-TKA6ZP4M.js → chunk-4B56DEEV.js} +50 -426
  5. package/dist/chunk-BIFLRKMO.js +87 -0
  6. package/dist/chunk-BQ2NMWKE.js +160 -0
  7. package/dist/{chunk-LDTWX7JW.js → chunk-BTZY7VPH.js} +13 -1
  8. package/dist/{chunk-FJDCFHW5.js → chunk-C6JHBLMW.js} +3 -81
  9. package/dist/{chunk-EXHBXA4U.js → chunk-DBCLBYHP.js} +13 -1
  10. package/dist/chunk-EPNDZ5DH.js +1010 -0
  11. package/dist/{chunk-P4RUVDU7.js → chunk-H2MEFVH6.js} +12 -141
  12. package/dist/chunk-KXZUCCEY.js +142 -0
  13. package/dist/{chunk-6JZIX5WW.js → chunk-LLXV32HA.js} +82 -5
  14. package/dist/{chunk-LWUR4CGG.js → chunk-MLRCSJYX.js} +11 -3
  15. package/dist/{chunk-2ABMGUDS.js → chunk-NFRM5QYP.js} +83 -10
  16. package/dist/chunk-RW5LP57K.js +44 -0
  17. package/dist/chunk-YDIYXGYL.js +384 -0
  18. package/dist/{chunk-JGGI65I3.js → chunk-Z4BNLUZF.js} +1 -150
  19. package/dist/{credit-ledger-ED6JXKVD.js → credit-ledger-2DFQHNLB.js} +2 -2
  20. package/dist/{credit-menu-BM4qCD5U.d.ts → credit-menu-C7zAJElJ.d.ts} +1632 -1946
  21. package/dist/{fx-C-liI3oY.d.ts → fx-BF_SG2i0.d.ts} +1 -1
  22. package/dist/index.d.ts +7 -6
  23. package/dist/index.js +8 -4
  24. package/dist/internal/caller.d.ts +10429 -0
  25. package/dist/internal/caller.js +9957 -0
  26. package/dist/internal/index.d.ts +2 -10816
  27. package/dist/internal/index.js +2 -10130
  28. package/dist/internal/server.d.ts +404 -0
  29. package/dist/internal/server.js +202 -0
  30. package/dist/job-store-Bn23V3QU.d.ts +576 -0
  31. package/dist/lightning-backend-C04nH94l.d.ts +367 -0
  32. package/dist/{memory-credit-ledger-XJ5VQEVP.js → memory-credit-ledger-OP24Z2KO.js} +3 -3
  33. package/dist/{postgres-job-store-J5F4GUWU.js → postgres-job-store-TAONYLIF.js} +1 -1
  34. package/dist/{revenue-reporter-JIKUPXOK.js → revenue-reporter-XXSU5KVB.js} +1 -1
  35. package/dist/server/index.d.ts +27 -11
  36. package/dist/server/index.js +93 -69
  37. package/dist/{job-store-C53VQ5uu.d.ts → step-cache-3cT4Shk0.d.ts} +31 -585
  38. package/dist/{tempo-session-store-DALMRIWN.js → tempo-session-store-2JNOKJGX.js} +2 -2
  39. package/dist/testing/index.d.ts +16 -4
  40. package/dist/testing/index.js +7 -3
  41. package/dist/{usd-gLcJB1ps.d.ts → usd-BnuXoFl5.d.ts} +1 -1
  42. package/dist/wallet-CJC8lwxx.d.ts +29 -0
  43. package/dist/{x402-FTG2GRAQ.js → x402-T2C5MX3T.js} +6 -3
  44. package/package.json +6 -2
  45. package/dist/{chunk-RU7SXHLO.js → chunk-UP2F5RRT.js} +3 -3
@@ -1,42 +1,11 @@
1
1
  import {
2
- initCallerLoggers
3
- } from "./chunk-66HGCPBU.js";
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) return Promise.reject(new Error(`appendOutgoing: job ${jobId} not found`));
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) return Promise.reject(new Error(`recordInbound: job ${jobId} not found`));
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
- createConsoleLogger,
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
  };
@@ -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
+ };