@probemesh/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +160 -0
  3. package/dist/chunk-257Y7LN2.js +827 -0
  4. package/dist/chunk-257Y7LN2.js.map +1 -0
  5. package/dist/chunk-2ASMVLG4.js +56 -0
  6. package/dist/chunk-2ASMVLG4.js.map +1 -0
  7. package/dist/chunk-2KWGHJYP.js +285 -0
  8. package/dist/chunk-2KWGHJYP.js.map +1 -0
  9. package/dist/chunk-3H7UGVI6.js +1117 -0
  10. package/dist/chunk-3H7UGVI6.js.map +1 -0
  11. package/dist/chunk-5Q3PDYIA.js +657 -0
  12. package/dist/chunk-5Q3PDYIA.js.map +1 -0
  13. package/dist/chunk-CXZOO3U4.js +550 -0
  14. package/dist/chunk-CXZOO3U4.js.map +1 -0
  15. package/dist/chunk-FRFBK4SY.js +270 -0
  16. package/dist/chunk-FRFBK4SY.js.map +1 -0
  17. package/dist/chunk-HJK52QJF.js +994 -0
  18. package/dist/chunk-HJK52QJF.js.map +1 -0
  19. package/dist/chunk-HNBDX7IU.js +705 -0
  20. package/dist/chunk-HNBDX7IU.js.map +1 -0
  21. package/dist/chunk-NYTV263W.js +116 -0
  22. package/dist/chunk-NYTV263W.js.map +1 -0
  23. package/dist/chunk-PXG54XOG.js +595 -0
  24. package/dist/chunk-PXG54XOG.js.map +1 -0
  25. package/dist/chunk-TDOBAMYM.js +607 -0
  26. package/dist/chunk-TDOBAMYM.js.map +1 -0
  27. package/dist/chunk-TV42EZSI.js +2157 -0
  28. package/dist/chunk-TV42EZSI.js.map +1 -0
  29. package/dist/chunk-UU2ZG7P7.js +408 -0
  30. package/dist/chunk-UU2ZG7P7.js.map +1 -0
  31. package/dist/chunk-WKN7QOCA.js +977 -0
  32. package/dist/chunk-WKN7QOCA.js.map +1 -0
  33. package/dist/chunk-ZJOLPBJJ.js +1091 -0
  34. package/dist/chunk-ZJOLPBJJ.js.map +1 -0
  35. package/dist/cli/audit-trail-export.cjs +1193 -0
  36. package/dist/cli/audit-trail-export.cjs.map +1 -0
  37. package/dist/cli/audit-trail-export.d.cts +1 -0
  38. package/dist/cli/audit-trail-export.d.ts +1 -0
  39. package/dist/cli/audit-trail-export.js +24 -0
  40. package/dist/cli/audit-trail-export.js.map +1 -0
  41. package/dist/cli/catalog-check.cjs +2687 -0
  42. package/dist/cli/catalog-check.cjs.map +1 -0
  43. package/dist/cli/catalog-check.d.cts +1 -0
  44. package/dist/cli/catalog-check.d.ts +1 -0
  45. package/dist/cli/catalog-check.js +26 -0
  46. package/dist/cli/catalog-check.js.map +1 -0
  47. package/dist/cli/probemesh-init.cjs +1049 -0
  48. package/dist/cli/probemesh-init.cjs.map +1 -0
  49. package/dist/cli/probemesh-init.d.cts +1 -0
  50. package/dist/cli/probemesh-init.d.ts +1 -0
  51. package/dist/cli/probemesh-init.js +22 -0
  52. package/dist/cli/probemesh-init.js.map +1 -0
  53. package/dist/cli/provider-conformance.cjs +6180 -0
  54. package/dist/cli/provider-conformance.cjs.map +1 -0
  55. package/dist/cli/provider-conformance.d.cts +1 -0
  56. package/dist/cli/provider-conformance.d.ts +1 -0
  57. package/dist/cli/provider-conformance.js +29 -0
  58. package/dist/cli/provider-conformance.js.map +1 -0
  59. package/dist/cli/provider-dossier-check.cjs +2978 -0
  60. package/dist/cli/provider-dossier-check.cjs.map +1 -0
  61. package/dist/cli/provider-dossier-check.d.cts +1 -0
  62. package/dist/cli/provider-dossier-check.d.ts +1 -0
  63. package/dist/cli/provider-dossier-check.js +27 -0
  64. package/dist/cli/provider-dossier-check.js.map +1 -0
  65. package/dist/cli/provider-dossier.cjs +1753 -0
  66. package/dist/cli/provider-dossier.cjs.map +1 -0
  67. package/dist/cli/provider-dossier.d.cts +1 -0
  68. package/dist/cli/provider-dossier.d.ts +1 -0
  69. package/dist/cli/provider-dossier.js +26 -0
  70. package/dist/cli/provider-dossier.js.map +1 -0
  71. package/dist/cli/x402-accept.cjs +6009 -0
  72. package/dist/cli/x402-accept.cjs.map +1 -0
  73. package/dist/cli/x402-accept.d.cts +1 -0
  74. package/dist/cli/x402-accept.d.ts +1 -0
  75. package/dist/cli/x402-accept.js +28 -0
  76. package/dist/cli/x402-accept.js.map +1 -0
  77. package/dist/index.cjs +13671 -0
  78. package/dist/index.cjs.map +1 -0
  79. package/dist/index.d.cts +2026 -0
  80. package/dist/index.d.ts +2026 -0
  81. package/dist/index.js +2560 -0
  82. package/dist/index.js.map +1 -0
  83. package/package.json +111 -0
package/dist/index.js ADDED
@@ -0,0 +1,2560 @@
1
+ import {
2
+ PROBEMESH_AUDIT_TRAIL_BUNDLE_SCHEMA_VERSION,
3
+ assertProbeMeshAuditTrailBundle,
4
+ createProbeMeshAuditTrailBundle,
5
+ createProbeMeshAuditTrailCollector,
6
+ formatProbeMeshAuditTrailBundle,
7
+ runProbeMeshAuditTrailExportCli,
8
+ summarizeProbeMeshAuditTrailBundle,
9
+ validateProbeMeshAuditTrailBundle
10
+ } from "./chunk-HNBDX7IU.js";
11
+ import {
12
+ runProviderCatalogPolicyCli
13
+ } from "./chunk-FRFBK4SY.js";
14
+ import {
15
+ getProbeMeshIntegrationTemplate,
16
+ listProbeMeshIntegrationTemplates,
17
+ renderProbeMeshIntegrationTemplate,
18
+ runProbeMeshInitCli
19
+ } from "./chunk-HJK52QJF.js";
20
+ import {
21
+ assertJsonSchemaLikeValue,
22
+ createProviderConformanceReport,
23
+ formatProviderConformanceReport,
24
+ runProviderConformance,
25
+ runProviderConformanceCli,
26
+ validateJsonSchemaLikeValue
27
+ } from "./chunk-WKN7QOCA.js";
28
+ import {
29
+ createHostedCatalogPolicyFromOnboardingDossiers,
30
+ createProviderCatalogFromOnboardingDossiers,
31
+ createProviderOnboardingDossierImportReport,
32
+ evaluateProviderOnboardingDossiers,
33
+ formatProviderOnboardingDossierImportReport,
34
+ parseProviderOnboardingDossierJson,
35
+ runProviderDossierCheckCli
36
+ } from "./chunk-PXG54XOG.js";
37
+ import {
38
+ runProviderOnboardingDossierCli
39
+ } from "./chunk-2KWGHJYP.js";
40
+ import {
41
+ PROVIDER_ONBOARDING_DOSSIER_SCHEMA_VERSION,
42
+ assertProviderOnboardingDossier,
43
+ createProviderOnboardingDossier,
44
+ formatProviderOnboardingDossier,
45
+ validateProviderOnboardingDossier
46
+ } from "./chunk-TDOBAMYM.js";
47
+ import {
48
+ PROVIDER_CONFORMANCE_ARTIFACT_SCHEMA_VERSION,
49
+ assertProviderConformanceArtifact,
50
+ createProviderConformanceArtifact,
51
+ formatProviderConformanceArtifact,
52
+ validateProviderConformanceArtifact
53
+ } from "./chunk-UU2ZG7P7.js";
54
+ import {
55
+ createX402ProviderAcceptanceReport,
56
+ evaluateX402ProviderAcceptanceGate,
57
+ formatX402ProviderAcceptanceReport,
58
+ runX402ProviderAcceptance,
59
+ runX402ProviderAcceptanceCli,
60
+ summarizeX402AcceptanceResult
61
+ } from "./chunk-257Y7LN2.js";
62
+ import {
63
+ createHostedRouter,
64
+ createProbeMesh,
65
+ startHostedRouter
66
+ } from "./chunk-TV42EZSI.js";
67
+ import {
68
+ PROBEMESH_CALL_AUDIT_ARTIFACT_SCHEMA_VERSION,
69
+ assertProbeMeshCallAuditArtifact,
70
+ createProbeMeshCallAuditArtifact,
71
+ formatProbeMeshCallAuditArtifact,
72
+ validateProbeMeshCallAuditArtifact
73
+ } from "./chunk-5Q3PDYIA.js";
74
+ import {
75
+ PROVIDER_CATALOG_POLICY_BUNDLE_SCHEMA_VERSION,
76
+ assertProviderCatalogPolicyBundle,
77
+ createProviderCatalogPolicyBundle,
78
+ formatProviderCatalogPolicyBundle,
79
+ validateProviderCatalogPolicyBundle,
80
+ verifyProviderCatalogPolicyBundleRuntime
81
+ } from "./chunk-CXZOO3U4.js";
82
+ import {
83
+ PROVIDER_CATALOG_SCHEMA_VERSION,
84
+ assertProviderCatalog,
85
+ createProviderCatalog,
86
+ createProviderCatalogPolicyReport,
87
+ evaluateProviderCatalogPolicy,
88
+ findProviderCatalogMatches,
89
+ formatProviderCatalogPolicyReport,
90
+ parseProviderCatalogArtifactJson,
91
+ summarizeProviderCatalog,
92
+ validateProviderCatalog
93
+ } from "./chunk-ZJOLPBJJ.js";
94
+ import {
95
+ PROVIDER_CATALOG_ARTIFACT_SCHEMA_VERSION,
96
+ assertProviderCatalogArtifact,
97
+ assertProviderManifest,
98
+ createProviderCatalogArtifact,
99
+ formatProviderCatalogArtifact,
100
+ getProviderPaymentOptions,
101
+ mergePaymentPreferences,
102
+ resolveProviderPaymentOption,
103
+ validatePaymentStrategy,
104
+ validateProviderCatalogArtifact,
105
+ validateProviderManifest
106
+ } from "./chunk-3H7UGVI6.js";
107
+ import {
108
+ redactX402Secrets
109
+ } from "./chunk-NYTV263W.js";
110
+ import {
111
+ ProbeMeshError,
112
+ isProbeMeshError
113
+ } from "./chunk-2ASMVLG4.js";
114
+
115
+ // src/adapters/priceLookup.ts
116
+ var DEFAULT_PRICES_USD = {
117
+ BTC: 64000.25,
118
+ ETH: 3200.12,
119
+ SOL: 145.33
120
+ };
121
+ function createPriceLookupAdapter(options = {}) {
122
+ const id = options.id ?? "demo-price-provider";
123
+ const displayName = options.displayName ?? "Demo Price Provider";
124
+ const prices = options.prices ?? DEFAULT_PRICES_USD;
125
+ return {
126
+ id,
127
+ displayName,
128
+ mode: "local",
129
+ capabilities: ["price-lookup"],
130
+ pricing: {
131
+ unit: "call",
132
+ amountUsd: 0.01,
133
+ currency: "USD"
134
+ },
135
+ call(request, context) {
136
+ const input = parsePriceLookupInput(request.input, request.capability, id);
137
+ const symbol = input.symbol.toUpperCase();
138
+ const currency = (input.currency ?? "USD").toUpperCase();
139
+ if (currency !== "USD") {
140
+ throw new ProbeMeshError({
141
+ code: "invalid_provider_response",
142
+ message: `Demo price adapter only supports USD prices, received "${currency}".`,
143
+ capability: request.capability,
144
+ provider: id,
145
+ callId: context.callId
146
+ });
147
+ }
148
+ const price = prices[symbol];
149
+ if (price === void 0) {
150
+ throw new ProbeMeshError({
151
+ code: "provider_unavailable",
152
+ message: `Demo price adapter has no mock price for "${symbol}".`,
153
+ capability: request.capability,
154
+ provider: id,
155
+ callId: context.callId
156
+ });
157
+ }
158
+ return {
159
+ data: {
160
+ symbol,
161
+ currency,
162
+ price,
163
+ asOf: context.startedAt.toISOString(),
164
+ source: id
165
+ },
166
+ cost: {
167
+ amountUsd: 0.01,
168
+ currency: "USD",
169
+ unit: "call"
170
+ },
171
+ receiptRefs: [
172
+ {
173
+ type: "provider_delivery",
174
+ provider: id,
175
+ status: "recorded",
176
+ ref: `${context.callId}:provider_delivery`,
177
+ timestamp: context.startedAt.toISOString()
178
+ }
179
+ ]
180
+ };
181
+ }
182
+ };
183
+ }
184
+ function parsePriceLookupInput(input, capability, provider) {
185
+ if (!input || typeof input !== "object") {
186
+ throw new ProbeMeshError({
187
+ code: "invalid_provider_response",
188
+ message: "price-lookup input must be an object.",
189
+ capability,
190
+ provider
191
+ });
192
+ }
193
+ const candidate = input;
194
+ if (!candidate.symbol || typeof candidate.symbol !== "string") {
195
+ throw new ProbeMeshError({
196
+ code: "invalid_provider_response",
197
+ message: "price-lookup input requires a string symbol.",
198
+ capability,
199
+ provider
200
+ });
201
+ }
202
+ if (candidate.currency !== void 0 && typeof candidate.currency !== "string") {
203
+ throw new ProbeMeshError({
204
+ code: "invalid_provider_response",
205
+ message: "price-lookup currency must be a string when provided.",
206
+ capability,
207
+ provider
208
+ });
209
+ }
210
+ return {
211
+ symbol: candidate.symbol,
212
+ currency: candidate.currency
213
+ };
214
+ }
215
+
216
+ // src/demo/mockPaymentProtocol.ts
217
+ function createMockPaymentProtocol(options = {}) {
218
+ const mode = options.mode ?? "mock-payment";
219
+ let prepareAttempts = 0;
220
+ return {
221
+ mode,
222
+ prepare({ manifest, request, context }) {
223
+ prepareAttempts += 1;
224
+ if (options.failPrepare || options.failPrepareOnce && prepareAttempts === 1) {
225
+ throw new ProbeMeshError({
226
+ code: "payment_failed",
227
+ message: `Mock payment authorization failed for provider "${manifest.id}".`,
228
+ capability: request.capability,
229
+ provider: manifest.id,
230
+ callId: context.callId
231
+ });
232
+ }
233
+ const paymentAttemptId = options.paymentAttemptId ?? `${context.callId}:mock_payment_attempt`;
234
+ return {
235
+ mode: manifest.protocolMode,
236
+ headers: {
237
+ "x-mock-payment-intent": context.callId
238
+ },
239
+ metadata: {
240
+ authorized: true,
241
+ paymentAttemptId
242
+ },
243
+ receiptRefs: [
244
+ {
245
+ type: "payment_proof",
246
+ provider: manifest.id,
247
+ status: "recorded",
248
+ ref: `${context.callId}:mock_payment_authorized`,
249
+ timestamp: context.startedAt.toISOString()
250
+ }
251
+ ],
252
+ safety: {
253
+ paymentAttemptId,
254
+ paymentStatus: "authorized",
255
+ moneyMayHaveMoved: true
256
+ }
257
+ };
258
+ },
259
+ settle({ manifest, request, context }) {
260
+ if (options.failSettle) {
261
+ throw new ProbeMeshError({
262
+ code: "payment_failed",
263
+ message: `Mock payment settlement failed for provider "${manifest.id}".`,
264
+ capability: request.capability,
265
+ provider: manifest.id,
266
+ callId: context.callId
267
+ });
268
+ }
269
+ return {
270
+ mode: manifest.protocolMode,
271
+ metadata: {
272
+ settled: true
273
+ },
274
+ receiptRefs: options.omitDeliveryReceipt ? [] : [
275
+ {
276
+ type: "provider_delivery",
277
+ provider: manifest.id,
278
+ status: "recorded",
279
+ ref: `${context.callId}:mock_delivery_recorded`,
280
+ timestamp: context.startedAt.toISOString()
281
+ }
282
+ ],
283
+ safety: {
284
+ settlementStatus: "settled",
285
+ deliveryStatus: options.omitDeliveryReceipt ? "missing" : "delivered",
286
+ moneyMayHaveMoved: true
287
+ }
288
+ };
289
+ }
290
+ };
291
+ }
292
+
293
+ // src/providerKit/adapter.ts
294
+ function createAdapterFromManifest(manifest, handlers, options = {}) {
295
+ assertProviderManifest(manifest);
296
+ assertHandlers(manifest, handlers);
297
+ assertProtocolAdapters(options.protocolAdapters, manifest);
298
+ return {
299
+ id: manifest.id,
300
+ displayName: manifest.displayName,
301
+ mode: manifest.protocolMode,
302
+ capabilities: [...manifest.capabilities],
303
+ pricing: manifest.pricing,
304
+ ...manifest.paymentOptions !== void 0 ? { paymentOptions: [...manifest.paymentOptions] } : {},
305
+ async call(request, context) {
306
+ const handler = handlers[request.capability];
307
+ if (!handler) {
308
+ throw new ProbeMeshError({
309
+ code: "provider_unavailable",
310
+ message: `Provider manifest "${manifest.id}" does not expose handler for capability "${request.capability}".`,
311
+ capability: request.capability,
312
+ provider: manifest.id,
313
+ callId: context.callId
314
+ });
315
+ }
316
+ const protocolMode = context.paymentSelection?.protocolMode ?? manifest.protocolMode;
317
+ const protocolAdapter = findProtocolAdapter(
318
+ manifest,
319
+ options.protocolAdapters,
320
+ protocolMode
321
+ );
322
+ const preparation = protocolAdapter?.prepare ? await prepareProtocol(protocolAdapter, manifest, request, context, protocolMode) : void 0;
323
+ const preparationReceiptRefs = preparation?.receiptRefs ?? [];
324
+ const preparationSafety = protocolAdapter ? mergeSafety(preparationReceiptRefs, preparation?.safety) : void 0;
325
+ const protocolExecution = protocolAdapter ? {
326
+ mode: protocolMode,
327
+ preparation,
328
+ receiptRefs: [...preparationReceiptRefs],
329
+ safety: preparationSafety
330
+ } : void 0;
331
+ const handlerContext = protocolExecution ? {
332
+ ...context,
333
+ protocol: protocolExecution
334
+ } : context;
335
+ const result = await callHandler({
336
+ handler,
337
+ manifest,
338
+ request,
339
+ handlerContext,
340
+ preparation,
341
+ preparationSafety,
342
+ preparationReceiptRefs
343
+ });
344
+ const settlement = protocolAdapter?.settle ? await settleProtocol({
345
+ protocolAdapter,
346
+ manifest,
347
+ request,
348
+ handlerContext,
349
+ result,
350
+ preparation,
351
+ preparationSafety,
352
+ preparationReceiptRefs,
353
+ protocolMode
354
+ }) : void 0;
355
+ const protocolReceiptRefs = [
356
+ ...preparationReceiptRefs,
357
+ ...settlement?.receiptRefs ?? []
358
+ ];
359
+ const mergedReceiptRefs = [
360
+ ...result.receiptRefs ?? [],
361
+ ...protocolReceiptRefs
362
+ ];
363
+ const safety = protocolAdapter ? mergeSafety(
364
+ mergedReceiptRefs,
365
+ preparation?.safety,
366
+ result.safety,
367
+ settlement?.safety
368
+ ) : result.safety;
369
+ if (protocolExecution) {
370
+ protocolExecution.settlement = settlement;
371
+ protocolExecution.receiptRefs = protocolReceiptRefs;
372
+ protocolExecution.safety = safety;
373
+ }
374
+ if (!result || typeof result !== "object" || Array.isArray(result) || result.receiptRefs !== void 0 && !Array.isArray(result.receiptRefs)) {
375
+ return result;
376
+ }
377
+ return {
378
+ ...result,
379
+ receiptRefs: mergedReceiptRefs,
380
+ safety
381
+ };
382
+ }
383
+ };
384
+ }
385
+ async function prepareProtocol(protocolAdapter, manifest, request, context, protocolMode = manifest.protocolMode) {
386
+ try {
387
+ return await protocolAdapter.prepare?.({
388
+ manifest: manifestForProtocol(manifest, protocolMode),
389
+ request,
390
+ context
391
+ });
392
+ } catch (error) {
393
+ if (isProbeMeshError(error) && error.code !== "payment_failed") {
394
+ throw error;
395
+ }
396
+ throw new ProbeMeshError({
397
+ code: "payment_failed",
398
+ message: `Protocol "${protocolAdapter.mode}" failed while preparing payment for provider "${manifest.id}".`,
399
+ capability: request.capability,
400
+ provider: manifest.id,
401
+ callId: context.callId,
402
+ safety: mergeSafety([], {
403
+ paymentStatus: "failed",
404
+ settlementStatus: "not_attempted",
405
+ deliveryStatus: "not_attempted",
406
+ moneyMayHaveMoved: false
407
+ }),
408
+ cause: error
409
+ });
410
+ }
411
+ }
412
+ async function callHandler({
413
+ handler,
414
+ manifest,
415
+ request,
416
+ handlerContext,
417
+ preparation,
418
+ preparationSafety,
419
+ preparationReceiptRefs
420
+ }) {
421
+ try {
422
+ return await handler(request, handlerContext);
423
+ } catch (error) {
424
+ const errorReceiptRefs = isProbeMeshError(error) ? error.receiptRefs ?? [] : [];
425
+ const receiptRefs = [...preparationReceiptRefs, ...errorReceiptRefs];
426
+ const safety = mergeSafety(
427
+ receiptRefs,
428
+ preparation?.safety,
429
+ preparationSafety,
430
+ isProbeMeshError(error) ? error.safety : void 0,
431
+ {
432
+ deliveryStatus: "failed"
433
+ }
434
+ );
435
+ if (!paymentWasAttempted(safety, receiptRefs)) {
436
+ if (isProbeMeshError(error) && (receiptRefs.length > 0 || preparationSafety)) {
437
+ throw new ProbeMeshError({
438
+ code: error.code,
439
+ message: error.message,
440
+ capability: error.capability,
441
+ provider: error.provider,
442
+ callId: error.callId,
443
+ receiptRefs,
444
+ safety,
445
+ cause: error
446
+ });
447
+ }
448
+ throw error;
449
+ }
450
+ throw new ProbeMeshError({
451
+ code: isProbeMeshError(error) && error.code === "timeout_after_payment" ? "timeout_after_payment" : "charged_but_no_result",
452
+ message: error instanceof Error ? error.message : `Provider "${manifest.id}" failed after payment was prepared.`,
453
+ capability: request.capability,
454
+ provider: manifest.id,
455
+ callId: handlerContext.callId,
456
+ receiptRefs,
457
+ safety,
458
+ cause: error
459
+ });
460
+ }
461
+ }
462
+ async function settleProtocol({
463
+ protocolAdapter,
464
+ manifest,
465
+ request,
466
+ handlerContext,
467
+ result,
468
+ preparation,
469
+ preparationSafety,
470
+ preparationReceiptRefs,
471
+ protocolMode
472
+ }) {
473
+ try {
474
+ return await protocolAdapter.settle?.({
475
+ manifest: manifestForProtocol(manifest, protocolMode ?? manifest.protocolMode),
476
+ request,
477
+ context: handlerContext,
478
+ result,
479
+ preparation
480
+ });
481
+ } catch (error) {
482
+ const resultReceiptRefs = Array.isArray(result.receiptRefs) ? result.receiptRefs : [];
483
+ const receiptRefs = [...resultReceiptRefs, ...preparationReceiptRefs];
484
+ const hasDeliveryEvidence = receiptRefs.some(
485
+ (receiptRef) => receiptRef.type === "provider_delivery"
486
+ );
487
+ const safety = mergeSafety(
488
+ receiptRefs,
489
+ preparation?.safety,
490
+ preparationSafety,
491
+ result.safety,
492
+ {
493
+ settlementStatus: "failed",
494
+ deliveryStatus: hasDeliveryEvidence ? "delivered" : "missing"
495
+ }
496
+ );
497
+ throw new ProbeMeshError({
498
+ code: "payment_failed",
499
+ message: `Protocol "${protocolAdapter.mode}" failed while settling payment for provider "${manifest.id}".`,
500
+ capability: request.capability,
501
+ provider: manifest.id,
502
+ callId: handlerContext.callId,
503
+ receiptRefs,
504
+ safety,
505
+ cause: error
506
+ });
507
+ }
508
+ }
509
+ function mergeSafety(receiptRefs, ...partials) {
510
+ const safety = {
511
+ paymentStatus: "not_attempted",
512
+ settlementStatus: "not_attempted",
513
+ deliveryStatus: "not_attempted",
514
+ moneyMayHaveMoved: false
515
+ };
516
+ applyReceiptDerivedSafety(safety, receiptRefs);
517
+ for (const partial of partials) {
518
+ if (!partial) {
519
+ continue;
520
+ }
521
+ Object.assign(safety, partial);
522
+ }
523
+ if (safety.paymentStatus === "authorized" || safety.settlementStatus === "settled") {
524
+ safety.moneyMayHaveMoved = true;
525
+ }
526
+ return safety;
527
+ }
528
+ function applyReceiptDerivedSafety(safety, receiptRefs) {
529
+ if (receiptRefs.some((receiptRef) => receiptRef.type === "payment_proof")) {
530
+ safety.paymentStatus = "authorized";
531
+ safety.moneyMayHaveMoved = true;
532
+ }
533
+ if (receiptRefs.some(
534
+ (receiptRef) => receiptRef.type === "settlement_confirmation"
535
+ )) {
536
+ safety.settlementStatus = "settled";
537
+ }
538
+ if (receiptRefs.some((receiptRef) => receiptRef.type === "provider_delivery")) {
539
+ safety.deliveryStatus = "delivered";
540
+ }
541
+ }
542
+ function paymentWasAttempted(safety, receiptRefs) {
543
+ return safety.paymentStatus !== "not_attempted" || safety.moneyMayHaveMoved || receiptRefs.some((receiptRef) => receiptRef.type === "payment_proof");
544
+ }
545
+ function findProtocolAdapter(manifest, protocolAdapters, protocolMode = manifest.protocolMode) {
546
+ return protocolAdapters?.find(
547
+ (protocolAdapter) => protocolAdapter.mode === protocolMode
548
+ );
549
+ }
550
+ function manifestForProtocol(manifest, protocolMode) {
551
+ return protocolMode === manifest.protocolMode ? manifest : {
552
+ ...manifest,
553
+ protocolMode
554
+ };
555
+ }
556
+ function assertProtocolAdapters(protocolAdapters, manifest) {
557
+ if (protocolAdapters === void 0) {
558
+ return;
559
+ }
560
+ if (!Array.isArray(protocolAdapters) || protocolAdapters.some(
561
+ (protocolAdapter) => !protocolAdapter || typeof protocolAdapter !== "object" || typeof protocolAdapter.mode !== "string" || protocolAdapter.mode.length === 0
562
+ )) {
563
+ throw new ProbeMeshError({
564
+ code: "invalid_request",
565
+ message: `Provider manifest "${manifest.id}" requires protocolAdapters to be an array of protocol adapter objects.`,
566
+ provider: manifest.id
567
+ });
568
+ }
569
+ }
570
+ function assertHandlers(manifest, handlers) {
571
+ if (!handlers || typeof handlers !== "object" || Array.isArray(handlers)) {
572
+ throw new ProbeMeshError({
573
+ code: "invalid_request",
574
+ message: `Provider manifest "${manifest.id}" requires a handlers object.`,
575
+ provider: manifest.id
576
+ });
577
+ }
578
+ const missingCapabilities = manifest.capabilities.filter(
579
+ (capability) => typeof handlers[capability] !== "function"
580
+ );
581
+ if (missingCapabilities.length > 0) {
582
+ throw new ProbeMeshError({
583
+ code: "invalid_request",
584
+ message: `Provider manifest "${manifest.id}" is missing handlers for capabilities: ${missingCapabilities.join(
585
+ ", "
586
+ )}.`,
587
+ provider: manifest.id
588
+ });
589
+ }
590
+ }
591
+
592
+ // src/demo/paidPriceLookupProvider.ts
593
+ var DEFAULT_PAID_PRICES_USD = {
594
+ BTC: 64000.25,
595
+ ETH: 3200.12,
596
+ SOL: 145.33
597
+ };
598
+ function createPaidPriceLookupProvider(options = {}) {
599
+ const id = options.id ?? "paid-price-provider";
600
+ const displayName = options.displayName ?? "Paid Price Provider";
601
+ const amountUsd = options.amountUsd ?? 0.01;
602
+ const prices = options.prices ?? DEFAULT_PAID_PRICES_USD;
603
+ const failureMode = options.failureMode ?? "none";
604
+ const mockPaymentOptions = {
605
+ ...options.mockPayment,
606
+ omitDeliveryReceipt: options.mockPayment?.omitDeliveryReceipt || failureMode === "missing_delivery_receipt"
607
+ };
608
+ const manifest = createPaidPriceLookupManifest({
609
+ id,
610
+ displayName,
611
+ amountUsd
612
+ });
613
+ return createAdapterFromManifest(
614
+ manifest,
615
+ {
616
+ "price-lookup": (request, context) => {
617
+ const input = parsePriceLookupInput2(request.input, id, context.callId);
618
+ const symbol = input.symbol.toUpperCase();
619
+ const currency = (input.currency ?? "USD").toUpperCase();
620
+ if (failureMode === "timeout_after_payment") {
621
+ throw new ProbeMeshError({
622
+ code: "timeout_after_payment",
623
+ message: `Paid price lookup demo timed out after payment authorization for provider "${id}".`,
624
+ capability: request.capability,
625
+ provider: id,
626
+ callId: context.callId
627
+ });
628
+ }
629
+ if (currency !== "USD") {
630
+ throw new ProbeMeshError({
631
+ code: "invalid_provider_response",
632
+ message: `Paid price lookup demo only supports USD prices, received "${currency}".`,
633
+ capability: request.capability,
634
+ provider: id,
635
+ callId: context.callId
636
+ });
637
+ }
638
+ const price = prices[symbol];
639
+ if (price === void 0) {
640
+ throw new ProbeMeshError({
641
+ code: "provider_unavailable",
642
+ message: `Paid price lookup demo has no mock price for "${symbol}".`,
643
+ capability: request.capability,
644
+ provider: id,
645
+ callId: context.callId
646
+ });
647
+ }
648
+ return {
649
+ data: {
650
+ symbol,
651
+ currency,
652
+ price,
653
+ asOf: context.startedAt.toISOString(),
654
+ source: id,
655
+ protocolMode: context.protocol?.mode,
656
+ paymentAuthorized: context.protocol?.preparation?.metadata?.authorized === true
657
+ }
658
+ };
659
+ }
660
+ },
661
+ {
662
+ protocolAdapters: [createMockPaymentProtocol(mockPaymentOptions)]
663
+ }
664
+ );
665
+ }
666
+ function createPaidPriceLookupManifest(options) {
667
+ return {
668
+ id: options.id,
669
+ displayName: options.displayName,
670
+ capabilities: ["price-lookup"],
671
+ protocolMode: "mock-payment",
672
+ pricing: {
673
+ unit: "call",
674
+ amountUsd: options.amountUsd,
675
+ currency: "USD"
676
+ },
677
+ inputSchema: {
678
+ type: "object",
679
+ properties: {
680
+ symbol: {
681
+ type: "string"
682
+ },
683
+ currency: {
684
+ type: "string"
685
+ }
686
+ },
687
+ required: ["symbol"]
688
+ },
689
+ outputSchema: {
690
+ type: "object",
691
+ properties: {
692
+ symbol: {
693
+ type: "string"
694
+ },
695
+ currency: {
696
+ type: "string"
697
+ },
698
+ price: {
699
+ type: "number"
700
+ },
701
+ paymentAuthorized: {
702
+ type: "boolean"
703
+ }
704
+ },
705
+ required: ["symbol", "currency", "price", "paymentAuthorized"]
706
+ },
707
+ receipts: {
708
+ payment: true,
709
+ delivery: true,
710
+ responseEvidence: false
711
+ },
712
+ limits: {
713
+ maxRequestsPerMinute: 60
714
+ }
715
+ };
716
+ }
717
+ function parsePriceLookupInput2(input, provider, callId) {
718
+ if (!input || typeof input !== "object") {
719
+ throw new ProbeMeshError({
720
+ code: "invalid_provider_response",
721
+ message: "price-lookup input must be an object.",
722
+ capability: "price-lookup",
723
+ provider,
724
+ callId
725
+ });
726
+ }
727
+ const candidate = input;
728
+ if (typeof candidate.symbol !== "string" || candidate.symbol.length === 0) {
729
+ throw new ProbeMeshError({
730
+ code: "invalid_provider_response",
731
+ message: "price-lookup input requires a string symbol.",
732
+ capability: "price-lookup",
733
+ provider,
734
+ callId
735
+ });
736
+ }
737
+ if (candidate.currency !== void 0 && typeof candidate.currency !== "string") {
738
+ throw new ProbeMeshError({
739
+ code: "invalid_provider_response",
740
+ message: "price-lookup currency must be a string when provided.",
741
+ capability: "price-lookup",
742
+ provider,
743
+ callId
744
+ });
745
+ }
746
+ return {
747
+ symbol: candidate.symbol,
748
+ currency: candidate.currency
749
+ };
750
+ }
751
+
752
+ // src/protocols/apiKeyProtocol.ts
753
+ var DEFAULT_MODE = "api-key";
754
+ var DEFAULT_HEADER_NAME = "x-api-key";
755
+ var DEFAULT_AUTHORIZATION_HEADER = "authorization";
756
+ var DEFAULT_AUTHORIZATION_SCHEME = "Bearer";
757
+ function createApiKeyProtocol(options = {}) {
758
+ assertApiKeyProtocolOptions(options);
759
+ const mode = options.mode ?? DEFAULT_MODE;
760
+ return {
761
+ mode,
762
+ async prepare({ manifest, request, context }) {
763
+ if (options.providerId && options.providerId !== manifest.id) {
764
+ throw new ProbeMeshError({
765
+ code: "invalid_request",
766
+ message: `API key protocol is configured for provider "${options.providerId}", but manifest "${manifest.id}" was used.`,
767
+ capability: request.capability,
768
+ provider: manifest.id,
769
+ callId: context.callId,
770
+ safety: noPaymentSafety()
771
+ });
772
+ }
773
+ const apiKey = await resolveApiKey(options);
774
+ if (!apiKey) {
775
+ throw new ProbeMeshError({
776
+ code: "unauthorized",
777
+ message: `API key is required for provider "${manifest.id}".`,
778
+ capability: request.capability,
779
+ provider: manifest.id,
780
+ callId: context.callId,
781
+ safety: noPaymentSafety()
782
+ });
783
+ }
784
+ const placement = options.placement ?? "header";
785
+ const headerName = headerNameForPlacement(options, placement);
786
+ const headers = {
787
+ [headerName]: headerValueForPlacement(options, placement, apiKey)
788
+ };
789
+ const preparation = {
790
+ mode: manifest.protocolMode,
791
+ metadata: {
792
+ authorized: true,
793
+ credentialPresent: true,
794
+ placement,
795
+ headerName,
796
+ providerId: manifest.id
797
+ },
798
+ receiptRefs: [
799
+ {
800
+ type: "authorization_decision",
801
+ provider: manifest.id,
802
+ status: "recorded",
803
+ ref: `${context.callId}:api_key_authorized`,
804
+ timestamp: context.startedAt.toISOString()
805
+ }
806
+ ],
807
+ safety: noPaymentPreparationSafety()
808
+ };
809
+ Object.defineProperty(preparation, "headers", {
810
+ value: Object.freeze(headers),
811
+ enumerable: false,
812
+ configurable: false,
813
+ writable: false
814
+ });
815
+ return preparation;
816
+ }
817
+ };
818
+ }
819
+ function assertApiKeyProtocolOptions(options) {
820
+ if (options.providerId !== void 0 && (typeof options.providerId !== "string" || options.providerId.length === 0)) {
821
+ throw new ProbeMeshError({
822
+ code: "invalid_request",
823
+ message: "API key protocol providerId must be a non-empty string when provided."
824
+ });
825
+ }
826
+ if (options.apiKey !== void 0 && (typeof options.apiKey !== "string" || options.apiKey.length === 0)) {
827
+ throw new ProbeMeshError({
828
+ code: "invalid_request",
829
+ message: "API key protocol apiKey must be a non-empty string when provided."
830
+ });
831
+ }
832
+ if (options.resolveApiKey !== void 0 && typeof options.resolveApiKey !== "function") {
833
+ throw new ProbeMeshError({
834
+ code: "invalid_request",
835
+ message: "API key protocol resolveApiKey must be a function when provided."
836
+ });
837
+ }
838
+ if (options.placement !== void 0 && options.placement !== "header" && options.placement !== "authorization") {
839
+ throw new ProbeMeshError({
840
+ code: "invalid_request",
841
+ message: 'API key protocol placement must be "header" or "authorization".'
842
+ });
843
+ }
844
+ if (options.headerName !== void 0 && (typeof options.headerName !== "string" || options.headerName.length === 0)) {
845
+ throw new ProbeMeshError({
846
+ code: "invalid_request",
847
+ message: "API key protocol headerName must be a non-empty string when provided."
848
+ });
849
+ }
850
+ if (options.authorizationScheme !== void 0 && (typeof options.authorizationScheme !== "string" || options.authorizationScheme.length === 0)) {
851
+ throw new ProbeMeshError({
852
+ code: "invalid_request",
853
+ message: "API key protocol authorizationScheme must be a non-empty string when provided."
854
+ });
855
+ }
856
+ }
857
+ async function resolveApiKey(options) {
858
+ return options.apiKey ?? await options.resolveApiKey?.();
859
+ }
860
+ function headerNameForPlacement(options, placement) {
861
+ if (placement === "authorization") {
862
+ return options.headerName ?? DEFAULT_AUTHORIZATION_HEADER;
863
+ }
864
+ return options.headerName ?? DEFAULT_HEADER_NAME;
865
+ }
866
+ function headerValueForPlacement(options, placement, apiKey) {
867
+ if (placement === "authorization") {
868
+ return `${options.authorizationScheme ?? DEFAULT_AUTHORIZATION_SCHEME} ${apiKey}`;
869
+ }
870
+ return apiKey;
871
+ }
872
+ function noPaymentSafety() {
873
+ return {
874
+ paymentStatus: "not_attempted",
875
+ settlementStatus: "not_attempted",
876
+ deliveryStatus: "not_attempted",
877
+ moneyMayHaveMoved: false
878
+ };
879
+ }
880
+ function noPaymentPreparationSafety() {
881
+ return {
882
+ paymentStatus: "not_attempted",
883
+ settlementStatus: "not_attempted",
884
+ moneyMayHaveMoved: false
885
+ };
886
+ }
887
+
888
+ // src/protocols/x402Evm.ts
889
+ import { x402Client } from "@x402/core/client";
890
+ import {
891
+ registerExactEvmScheme
892
+ } from "@x402/evm/exact/client";
893
+ import {
894
+ getDefaultAsset,
895
+ toClientEvmSigner
896
+ } from "@x402/evm";
897
+ import { createPublicClient, http } from "viem";
898
+ import { privateKeyToAccount } from "viem/accounts";
899
+ var DEFAULT_NETWORK = "eip155:84532";
900
+ var DEFAULT_AMOUNT = "10000";
901
+ var DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator";
902
+ var REQUIRED_TESTNET_ENV = [
903
+ "PROBEMESH_X402_EVM_PRIVATE_KEY",
904
+ "PROBEMESH_X402_PAY_TO",
905
+ "PROBEMESH_X402_ASSET"
906
+ ];
907
+ var OPTIONAL_TESTNET_ENV = [
908
+ "PROBEMESH_X402_FACILITATOR_URL",
909
+ "PROBEMESH_X402_RPC_URL",
910
+ "PROBEMESH_X402_NETWORK",
911
+ "PROBEMESH_X402_AMOUNT",
912
+ "PROBEMESH_X402_ASSET_NAME",
913
+ "PROBEMESH_X402_ASSET_VERSION"
914
+ ];
915
+ function resolveX402EvmTestnetConfig(options = {}) {
916
+ assertTestnetConfigOptions(options);
917
+ const env = options.env ?? process.env;
918
+ const defaultNetwork = options.defaultNetwork ?? DEFAULT_NETWORK;
919
+ const defaultAmount = options.defaultAmount ?? DEFAULT_AMOUNT;
920
+ const defaultFacilitatorUrl = options.defaultFacilitatorUrl ?? DEFAULT_FACILITATOR_URL;
921
+ const missingEnv = REQUIRED_TESTNET_ENV.filter((name) => !env[name]);
922
+ if (missingEnv.length > 0) {
923
+ return {
924
+ ok: false,
925
+ skip: {
926
+ reason: "Missing opt-in live x402 EVM environment variables.",
927
+ missingEnv,
928
+ requiredEnv: [...REQUIRED_TESTNET_ENV],
929
+ optionalEnv: [...OPTIONAL_TESTNET_ENV],
930
+ defaults: {
931
+ network: defaultNetwork,
932
+ amount: defaultAmount,
933
+ facilitatorUrl: defaultFacilitatorUrl
934
+ }
935
+ }
936
+ };
937
+ }
938
+ const network = requireEvmNetwork(
939
+ env.PROBEMESH_X402_NETWORK ?? defaultNetwork,
940
+ "PROBEMESH_X402_NETWORK"
941
+ );
942
+ const amount = requirePositiveIntegerString(
943
+ env.PROBEMESH_X402_AMOUNT ?? defaultAmount,
944
+ "PROBEMESH_X402_AMOUNT"
945
+ );
946
+ const facilitatorUrl = requireHttpUrl(
947
+ env.PROBEMESH_X402_FACILITATOR_URL ?? defaultFacilitatorUrl,
948
+ "PROBEMESH_X402_FACILITATOR_URL"
949
+ );
950
+ const rpcUrl = env.PROBEMESH_X402_RPC_URL ? requireHttpUrl(env.PROBEMESH_X402_RPC_URL, "PROBEMESH_X402_RPC_URL") : void 0;
951
+ const privateKey = requirePrivateKey(
952
+ env.PROBEMESH_X402_EVM_PRIVATE_KEY,
953
+ "PROBEMESH_X402_EVM_PRIVATE_KEY"
954
+ );
955
+ const asset = requireEvmAddress(
956
+ env.PROBEMESH_X402_ASSET,
957
+ "PROBEMESH_X402_ASSET"
958
+ );
959
+ const payTo = requireEvmAddress(
960
+ env.PROBEMESH_X402_PAY_TO,
961
+ "PROBEMESH_X402_PAY_TO"
962
+ );
963
+ const assetMetadata = resolveTestnetAssetMetadata({
964
+ network,
965
+ asset,
966
+ env
967
+ });
968
+ const config = {
969
+ privateKey,
970
+ network,
971
+ rpcUrl,
972
+ facilitatorUrl,
973
+ amount,
974
+ asset,
975
+ payTo,
976
+ assetMetadata
977
+ };
978
+ return {
979
+ ok: true,
980
+ config,
981
+ summary: {
982
+ network,
983
+ rpcConfigured: typeof rpcUrl === "string",
984
+ facilitatorUrl,
985
+ amount,
986
+ asset,
987
+ payTo,
988
+ assetMetadata,
989
+ privateKeyConfigured: true
990
+ }
991
+ };
992
+ }
993
+ function createX402EvmSigner(options = {}) {
994
+ assertX402EvmSignerOptions(options);
995
+ const signer = resolveClientEvmSigner(options);
996
+ const networks = resolveNetworks(options);
997
+ const client = new x402Client();
998
+ registerExactEvmScheme(client, {
999
+ signer,
1000
+ networks,
1001
+ schemeOptions: options.schemeOptions
1002
+ });
1003
+ return async (input) => {
1004
+ try {
1005
+ const paymentPayload = await client.createPaymentPayload(
1006
+ input.paymentRequired
1007
+ );
1008
+ return {
1009
+ paymentPayload,
1010
+ payer: signer.address,
1011
+ metadata: {
1012
+ signer: "evm",
1013
+ scheme: "exact",
1014
+ address: signer.address,
1015
+ networks,
1016
+ rpcConfigured: typeof options.rpcUrl === "string"
1017
+ }
1018
+ };
1019
+ } catch (error) {
1020
+ throw new ProbeMeshError({
1021
+ code: "payment_failed",
1022
+ message: `x402 EVM signer failed to create a payment payload for provider "${input.providerId}".`,
1023
+ capability: input.capability,
1024
+ provider: input.providerId,
1025
+ callId: input.callId,
1026
+ safety: {
1027
+ paymentStatus: "failed",
1028
+ settlementStatus: "not_attempted",
1029
+ deliveryStatus: "not_attempted",
1030
+ moneyMayHaveMoved: false
1031
+ },
1032
+ cause: error
1033
+ });
1034
+ }
1035
+ };
1036
+ }
1037
+ function createX402HttpFacilitator(options = {}) {
1038
+ assertX402HttpFacilitatorOptions(options);
1039
+ const baseUrl = (options.url ?? DEFAULT_FACILITATOR_URL).replace(/\/+$/, "");
1040
+ const timeoutMs = options.timeoutMs;
1041
+ return {
1042
+ async verify(input) {
1043
+ const response = await postFacilitatorJson({
1044
+ baseUrl,
1045
+ path: "verify",
1046
+ timeoutMs,
1047
+ createAuthHeaders: options.createAuthHeaders,
1048
+ body: {
1049
+ x402Version: input.paymentPayload.x402Version,
1050
+ paymentPayload: input.paymentPayload,
1051
+ paymentRequirements: input.paymentRequirements
1052
+ },
1053
+ providerId: input.providerId,
1054
+ capability: input.capability,
1055
+ callId: input.callId,
1056
+ unsafeAfterPayment: false
1057
+ });
1058
+ return response;
1059
+ },
1060
+ async settle(input) {
1061
+ const response = await postFacilitatorJson({
1062
+ baseUrl,
1063
+ path: "settle",
1064
+ timeoutMs,
1065
+ createAuthHeaders: options.createAuthHeaders,
1066
+ body: {
1067
+ x402Version: input.paymentPayload.x402Version,
1068
+ paymentPayload: input.paymentPayload,
1069
+ paymentRequirements: input.paymentRequirements
1070
+ },
1071
+ providerId: input.providerId,
1072
+ capability: input.capability,
1073
+ callId: input.callId,
1074
+ unsafeAfterPayment: true
1075
+ });
1076
+ return response;
1077
+ }
1078
+ };
1079
+ }
1080
+ function resolveClientEvmSigner(options) {
1081
+ const signer = options.signer ?? (options.privateKey ? privateKeyToAccount(options.privateKey) : void 0);
1082
+ if (!signer) {
1083
+ throw new ProbeMeshError({
1084
+ code: "invalid_request",
1085
+ message: "x402 EVM signer requires either privateKey or signer."
1086
+ });
1087
+ }
1088
+ if (options.rpcUrl) {
1089
+ const publicClient = createPublicClient({
1090
+ transport: http(options.rpcUrl)
1091
+ });
1092
+ return toClientEvmSigner(signer, publicClient);
1093
+ }
1094
+ return signer;
1095
+ }
1096
+ function resolveNetworks(options) {
1097
+ if (options.networks !== void 0) {
1098
+ return options.networks;
1099
+ }
1100
+ return [options.network ?? DEFAULT_NETWORK];
1101
+ }
1102
+ function assertX402EvmSignerOptions(options) {
1103
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
1104
+ throw new ProbeMeshError({
1105
+ code: "invalid_request",
1106
+ message: "x402 EVM signer options must be an object."
1107
+ });
1108
+ }
1109
+ if (options.privateKey !== void 0 && (typeof options.privateKey !== "string" || !options.privateKey.startsWith("0x") || options.privateKey.length !== 66)) {
1110
+ throw new ProbeMeshError({
1111
+ code: "invalid_request",
1112
+ message: "x402 EVM signer privateKey must be a 32-byte 0x-prefixed hex string."
1113
+ });
1114
+ }
1115
+ if (options.signer !== void 0) {
1116
+ assertClientSigner(options.signer);
1117
+ }
1118
+ if (options.privateKey !== void 0 && options.signer !== void 0) {
1119
+ throw new ProbeMeshError({
1120
+ code: "invalid_request",
1121
+ message: "x402 EVM signer accepts either privateKey or signer, not both."
1122
+ });
1123
+ }
1124
+ if (options.network !== void 0 && !isValidEvmNetwork(options.network)) {
1125
+ throw new ProbeMeshError({
1126
+ code: "invalid_request",
1127
+ message: "x402 EVM signer network must use CAIP-2 eip155:<chainId> format."
1128
+ });
1129
+ }
1130
+ if (options.networks !== void 0 && (!Array.isArray(options.networks) || options.networks.length === 0 || options.networks.some((network) => !isValidEvmNetwork(network)))) {
1131
+ throw new ProbeMeshError({
1132
+ code: "invalid_request",
1133
+ message: "x402 EVM signer networks must be a non-empty array of CAIP-2 eip155:<chainId> values."
1134
+ });
1135
+ }
1136
+ if (options.network !== void 0 && options.networks !== void 0) {
1137
+ throw new ProbeMeshError({
1138
+ code: "invalid_request",
1139
+ message: "x402 EVM signer accepts either network or networks, not both."
1140
+ });
1141
+ }
1142
+ if (options.rpcUrl !== void 0 && (typeof options.rpcUrl !== "string" || options.rpcUrl.length === 0)) {
1143
+ throw new ProbeMeshError({
1144
+ code: "invalid_request",
1145
+ message: "x402 EVM signer rpcUrl must be a non-empty string when provided."
1146
+ });
1147
+ }
1148
+ }
1149
+ function assertX402HttpFacilitatorOptions(options) {
1150
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
1151
+ throw new ProbeMeshError({
1152
+ code: "invalid_request",
1153
+ message: "x402 HTTP facilitator options must be an object."
1154
+ });
1155
+ }
1156
+ if (options.url !== void 0 && (typeof options.url !== "string" || options.url.length === 0)) {
1157
+ throw new ProbeMeshError({
1158
+ code: "invalid_request",
1159
+ message: "x402 HTTP facilitator url must be a non-empty string when provided."
1160
+ });
1161
+ }
1162
+ if (options.createAuthHeaders !== void 0 && typeof options.createAuthHeaders !== "function") {
1163
+ throw new ProbeMeshError({
1164
+ code: "invalid_request",
1165
+ message: "x402 HTTP facilitator createAuthHeaders must be a function when provided."
1166
+ });
1167
+ }
1168
+ if (options.timeoutMs !== void 0 && (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0)) {
1169
+ throw new ProbeMeshError({
1170
+ code: "invalid_request",
1171
+ message: "x402 HTTP facilitator timeoutMs must be a positive number when provided."
1172
+ });
1173
+ }
1174
+ }
1175
+ async function postFacilitatorJson(options) {
1176
+ const controller = new AbortController();
1177
+ const timeout = options.timeoutMs !== void 0 ? setTimeout(() => controller.abort(), options.timeoutMs) : void 0;
1178
+ try {
1179
+ const authHeaders = await resolveFacilitatorAuthHeaders(
1180
+ options.createAuthHeaders,
1181
+ options.path
1182
+ );
1183
+ const response = await fetch(`${options.baseUrl}/${options.path}`, {
1184
+ method: "POST",
1185
+ headers: {
1186
+ "content-type": "application/json",
1187
+ ...authHeaders
1188
+ },
1189
+ redirect: "follow",
1190
+ body: JSON.stringify(toJsonSafe(options.body)),
1191
+ signal: controller.signal
1192
+ });
1193
+ const responseText = await response.text();
1194
+ const responseBody = parseFacilitatorJson(
1195
+ responseText,
1196
+ options.path,
1197
+ options.providerId,
1198
+ options.capability,
1199
+ options.callId,
1200
+ options.unsafeAfterPayment
1201
+ );
1202
+ if (!response.ok && !isFacilitatorLifecycleResult(responseBody)) {
1203
+ throw facilitatorRequestError({
1204
+ path: options.path,
1205
+ providerId: options.providerId,
1206
+ capability: options.capability,
1207
+ callId: options.callId,
1208
+ unsafeAfterPayment: options.unsafeAfterPayment,
1209
+ message: `x402 HTTP facilitator ${options.path} request failed with HTTP ${response.status}.`
1210
+ });
1211
+ }
1212
+ return responseBody;
1213
+ } catch (error) {
1214
+ if (error instanceof ProbeMeshError) {
1215
+ throw error;
1216
+ }
1217
+ if (isAbortError(error)) {
1218
+ throw facilitatorRequestError({
1219
+ path: options.path,
1220
+ providerId: options.providerId,
1221
+ capability: options.capability,
1222
+ callId: options.callId,
1223
+ unsafeAfterPayment: options.unsafeAfterPayment,
1224
+ message: `x402 HTTP facilitator ${options.path} request timed out after ${options.timeoutMs}ms.`
1225
+ });
1226
+ }
1227
+ throw facilitatorRequestError({
1228
+ path: options.path,
1229
+ providerId: options.providerId,
1230
+ capability: options.capability,
1231
+ callId: options.callId,
1232
+ unsafeAfterPayment: options.unsafeAfterPayment,
1233
+ message: `x402 HTTP facilitator ${options.path} request failed.`
1234
+ });
1235
+ } finally {
1236
+ if (timeout) {
1237
+ clearTimeout(timeout);
1238
+ }
1239
+ }
1240
+ }
1241
+ async function resolveFacilitatorAuthHeaders(createAuthHeaders, path) {
1242
+ if (!createAuthHeaders) {
1243
+ return {};
1244
+ }
1245
+ const headers = await createAuthHeaders();
1246
+ const selected = headers[path] ?? {};
1247
+ if (!selected || typeof selected !== "object" || Array.isArray(selected) || Object.entries(selected).some(
1248
+ ([key, value]) => typeof key !== "string" || key.length === 0 || typeof value !== "string"
1249
+ )) {
1250
+ throw new ProbeMeshError({
1251
+ code: "invalid_request",
1252
+ message: "x402 HTTP facilitator auth headers must be records of string values."
1253
+ });
1254
+ }
1255
+ return selected;
1256
+ }
1257
+ function parseFacilitatorJson(responseText, path, providerId, capability, callId, unsafeAfterPayment) {
1258
+ try {
1259
+ return responseText ? JSON.parse(responseText) : {};
1260
+ } catch {
1261
+ throw facilitatorRequestError({
1262
+ path,
1263
+ providerId,
1264
+ capability,
1265
+ callId,
1266
+ unsafeAfterPayment,
1267
+ message: `x402 HTTP facilitator ${path} response was not valid JSON.`
1268
+ });
1269
+ }
1270
+ }
1271
+ function isFacilitatorLifecycleResult(value) {
1272
+ return !!value && typeof value === "object" && !Array.isArray(value) && ("isValid" in value || "success" in value);
1273
+ }
1274
+ function facilitatorRequestError(options) {
1275
+ return new ProbeMeshError({
1276
+ code: "payment_failed",
1277
+ message: options.message,
1278
+ capability: options.capability,
1279
+ provider: options.providerId,
1280
+ callId: options.callId,
1281
+ safety: options.unsafeAfterPayment ? {
1282
+ paymentStatus: "authorized",
1283
+ settlementStatus: "failed",
1284
+ deliveryStatus: "missing",
1285
+ moneyMayHaveMoved: true
1286
+ } : {
1287
+ paymentStatus: "failed",
1288
+ settlementStatus: "not_attempted",
1289
+ deliveryStatus: "not_attempted",
1290
+ moneyMayHaveMoved: false
1291
+ }
1292
+ });
1293
+ }
1294
+ function toJsonSafe(value) {
1295
+ if (typeof value === "bigint") {
1296
+ return value.toString();
1297
+ }
1298
+ if (Array.isArray(value)) {
1299
+ return value.map((entry) => toJsonSafe(entry));
1300
+ }
1301
+ if (value && typeof value === "object") {
1302
+ return Object.fromEntries(
1303
+ Object.entries(value).map(([key, entry]) => [key, toJsonSafe(entry)])
1304
+ );
1305
+ }
1306
+ return value;
1307
+ }
1308
+ function isAbortError(error) {
1309
+ return !!error && typeof error === "object" && "name" in error && error.name === "AbortError";
1310
+ }
1311
+ function assertTestnetConfigOptions(options) {
1312
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
1313
+ throw new ProbeMeshError({
1314
+ code: "invalid_request",
1315
+ message: "x402 EVM testnet config options must be an object."
1316
+ });
1317
+ }
1318
+ if (options.env !== void 0 && (!options.env || typeof options.env !== "object" || Array.isArray(options.env))) {
1319
+ throw new ProbeMeshError({
1320
+ code: "invalid_request",
1321
+ message: "x402 EVM testnet config env must be an object when provided."
1322
+ });
1323
+ }
1324
+ if (options.defaultNetwork !== void 0 && !isValidEvmNetwork(options.defaultNetwork)) {
1325
+ throw new ProbeMeshError({
1326
+ code: "invalid_request",
1327
+ message: "x402 EVM testnet defaultNetwork must use CAIP-2 eip155:<chainId> format."
1328
+ });
1329
+ }
1330
+ if (options.defaultAmount !== void 0) {
1331
+ requirePositiveIntegerString(
1332
+ options.defaultAmount,
1333
+ "x402 EVM testnet defaultAmount"
1334
+ );
1335
+ }
1336
+ if (options.defaultFacilitatorUrl !== void 0) {
1337
+ requireHttpUrl(
1338
+ options.defaultFacilitatorUrl,
1339
+ "x402 EVM testnet defaultFacilitatorUrl"
1340
+ );
1341
+ }
1342
+ }
1343
+ function assertClientSigner(signer) {
1344
+ if (!signer || typeof signer !== "object" || Array.isArray(signer) || typeof signer.address !== "string" || !signer.address.startsWith("0x") || typeof signer.signTypedData !== "function") {
1345
+ throw new ProbeMeshError({
1346
+ code: "invalid_request",
1347
+ message: "x402 EVM signer signer must expose address and signTypedData(...)."
1348
+ });
1349
+ }
1350
+ }
1351
+ function isValidEvmNetwork(network) {
1352
+ return typeof network === "string" && /^eip155:[1-9][0-9]*$/.test(network);
1353
+ }
1354
+ function requireEvmNetwork(value, field) {
1355
+ if (!isValidEvmNetwork(value)) {
1356
+ throw new ProbeMeshError({
1357
+ code: "invalid_request",
1358
+ message: `${field} must use CAIP-2 eip155:<chainId> format.`
1359
+ });
1360
+ }
1361
+ return value;
1362
+ }
1363
+ function requirePrivateKey(value, field) {
1364
+ if (typeof value !== "string" || !value.startsWith("0x") || value.length !== 66 || !/^0x[0-9a-fA-F]{64}$/.test(value)) {
1365
+ throw new ProbeMeshError({
1366
+ code: "invalid_request",
1367
+ message: `${field} must be a 32-byte 0x-prefixed hex string.`
1368
+ });
1369
+ }
1370
+ return value;
1371
+ }
1372
+ function requireEvmAddress(value, field) {
1373
+ if (typeof value !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(value)) {
1374
+ throw new ProbeMeshError({
1375
+ code: "invalid_request",
1376
+ message: `${field} must be a 20-byte 0x-prefixed EVM address.`
1377
+ });
1378
+ }
1379
+ return value;
1380
+ }
1381
+ function requirePositiveIntegerString(value, field) {
1382
+ if (typeof value !== "string" || !/^[1-9][0-9]*$/.test(value)) {
1383
+ throw new ProbeMeshError({
1384
+ code: "invalid_request",
1385
+ message: `${field} must be a positive integer string.`
1386
+ });
1387
+ }
1388
+ return value;
1389
+ }
1390
+ function requireHttpUrl(value, field) {
1391
+ if (typeof value !== "string" || value.length === 0) {
1392
+ throw new ProbeMeshError({
1393
+ code: "invalid_request",
1394
+ message: `${field} must be a non-empty HTTP(S) URL.`
1395
+ });
1396
+ }
1397
+ try {
1398
+ const url = new URL(value);
1399
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
1400
+ throw new Error("invalid protocol");
1401
+ }
1402
+ } catch {
1403
+ throw new ProbeMeshError({
1404
+ code: "invalid_request",
1405
+ message: `${field} must be a valid HTTP(S) URL.`
1406
+ });
1407
+ }
1408
+ return value;
1409
+ }
1410
+ function resolveTestnetAssetMetadata(options) {
1411
+ const configuredName = options.env.PROBEMESH_X402_ASSET_NAME;
1412
+ const configuredVersion = options.env.PROBEMESH_X402_ASSET_VERSION;
1413
+ if (configuredName !== void 0 && configuredName.length === 0) {
1414
+ throw new ProbeMeshError({
1415
+ code: "invalid_request",
1416
+ message: "PROBEMESH_X402_ASSET_NAME must be non-empty when provided."
1417
+ });
1418
+ }
1419
+ if (configuredVersion !== void 0 && configuredVersion.length === 0) {
1420
+ throw new ProbeMeshError({
1421
+ code: "invalid_request",
1422
+ message: "PROBEMESH_X402_ASSET_VERSION must be non-empty when provided."
1423
+ });
1424
+ }
1425
+ if (configuredName && configuredVersion) {
1426
+ return {
1427
+ name: configuredName,
1428
+ version: configuredVersion
1429
+ };
1430
+ }
1431
+ try {
1432
+ const defaultAsset = getDefaultAsset(options.network);
1433
+ if (defaultAsset.address.toLowerCase() === options.asset.toLowerCase()) {
1434
+ return {
1435
+ name: configuredName ?? defaultAsset.name,
1436
+ version: configuredVersion ?? defaultAsset.version
1437
+ };
1438
+ }
1439
+ } catch {
1440
+ }
1441
+ return {
1442
+ name: configuredName ?? "USDC",
1443
+ version: configuredVersion ?? "2"
1444
+ };
1445
+ }
1446
+
1447
+ // src/protocols/x402Protocol.ts
1448
+ import {
1449
+ decodePaymentRequiredHeader,
1450
+ decodePaymentSignatureHeader,
1451
+ encodePaymentRequiredHeader,
1452
+ encodePaymentResponseHeader,
1453
+ encodePaymentSignatureHeader
1454
+ } from "@x402/core/http";
1455
+ var DEFAULT_MODE2 = "x402";
1456
+ var DEFAULT_PAYER = "local-x402-agent";
1457
+ var DEFAULT_NETWORK2 = "eip155:84532";
1458
+ var DEFAULT_ASSET = "USDC";
1459
+ var DEFAULT_AMOUNT2 = "10000";
1460
+ var DEFAULT_PAY_TO = "probemesh-local-x402-provider";
1461
+ var DEFAULT_TIMEOUT_SECONDS = 60;
1462
+ var PAYMENT_REQUIRED_HEADER = "PAYMENT-REQUIRED";
1463
+ var PAYMENT_SIGNATURE_HEADER = "PAYMENT-SIGNATURE";
1464
+ var PAYMENT_RESPONSE_HEADER = "PAYMENT-RESPONSE";
1465
+ function createX402Protocol(options = {}) {
1466
+ assertX402ProtocolOptions(options);
1467
+ const mode = options.mode ?? X402_PROTOCOL_DEFAULT_MODE;
1468
+ const signer = options.signer ?? createX402LocalSigner({
1469
+ payer: options.payer,
1470
+ paymentId: options.paymentId
1471
+ });
1472
+ const facilitator = options.facilitator ?? createX402LocalFacilitator();
1473
+ return {
1474
+ mode,
1475
+ async prepare({ manifest, request, context }) {
1476
+ assertProviderMatches(
1477
+ options.providerId,
1478
+ manifest.id,
1479
+ request.capability,
1480
+ context.callId
1481
+ );
1482
+ const paymentRequired = await resolvePaymentRequired({
1483
+ options,
1484
+ manifest,
1485
+ request,
1486
+ context
1487
+ });
1488
+ const paymentRequirements = paymentRequired.accepts[0];
1489
+ const paymentId = options.paymentId ?? `${context.callId}:x402_payment`;
1490
+ const payer = options.payer ?? DEFAULT_PAYER;
1491
+ const signerResult = await signer({
1492
+ paymentRequired,
1493
+ paymentRequirements,
1494
+ manifest,
1495
+ request,
1496
+ context,
1497
+ providerId: manifest.id,
1498
+ capability: request.capability,
1499
+ callId: context.callId,
1500
+ paymentId,
1501
+ payer
1502
+ });
1503
+ assertSignerResult(signerResult, request.capability, manifest.id, context.callId);
1504
+ assertPaymentPayload(
1505
+ signerResult.paymentPayload,
1506
+ paymentRequirements,
1507
+ request.capability,
1508
+ manifest.id,
1509
+ context.callId
1510
+ );
1511
+ const verifyResult = await facilitator.verify({
1512
+ paymentPayload: signerResult.paymentPayload,
1513
+ paymentRequirements,
1514
+ paymentRequired,
1515
+ manifest,
1516
+ request,
1517
+ context,
1518
+ providerId: manifest.id,
1519
+ capability: request.capability,
1520
+ callId: context.callId
1521
+ });
1522
+ assertVerifyResult(
1523
+ verifyResult,
1524
+ request.capability,
1525
+ manifest.id,
1526
+ context.callId
1527
+ );
1528
+ if (!verifyResult.isValid) {
1529
+ throw new ProbeMeshError({
1530
+ code: "payment_failed",
1531
+ message: verifyResult.invalidMessage ?? `x402 facilitator rejected payment for provider "${manifest.id}".`,
1532
+ capability: request.capability,
1533
+ provider: manifest.id,
1534
+ callId: context.callId,
1535
+ safety: failedPaymentSafety()
1536
+ });
1537
+ }
1538
+ const headers = {
1539
+ [PAYMENT_REQUIRED_HEADER]: encodePaymentRequiredHeader(paymentRequired),
1540
+ [PAYMENT_SIGNATURE_HEADER]: encodePaymentSignatureHeader(
1541
+ signerResult.paymentPayload
1542
+ )
1543
+ };
1544
+ const resolvedPayer = verifyResult.payer ?? signerResult.payer ?? getPayloadString(signerResult.paymentPayload, "payer") ?? payer;
1545
+ const paymentAttemptId = `${paymentId}:attempt`;
1546
+ const preparation = {
1547
+ mode: manifest.protocolMode,
1548
+ metadata: {
1549
+ authorized: true,
1550
+ verified: true,
1551
+ x402Version: 2,
1552
+ paymentId,
1553
+ paymentAttemptId,
1554
+ payer: resolvedPayer,
1555
+ network: paymentRequirements.network,
1556
+ asset: paymentRequirements.asset,
1557
+ amount: paymentRequirements.amount,
1558
+ paymentRequired,
1559
+ selectedPaymentRequirements: paymentRequirements,
1560
+ verifyResponse: verifyResult,
1561
+ signerMetadata: signerResult.metadata,
1562
+ paymentRequiredHeader: PAYMENT_REQUIRED_HEADER,
1563
+ paymentSignatureHeader: PAYMENT_SIGNATURE_HEADER
1564
+ },
1565
+ receiptRefs: [
1566
+ {
1567
+ type: "payment_proof",
1568
+ provider: manifest.id,
1569
+ status: "recorded",
1570
+ ref: `${context.callId}:x402_payment_proof`,
1571
+ timestamp: context.startedAt.toISOString()
1572
+ }
1573
+ ],
1574
+ safety: {
1575
+ paymentAttemptId,
1576
+ paymentStatus: "authorized",
1577
+ settlementStatus: "not_attempted",
1578
+ deliveryStatus: "not_attempted",
1579
+ moneyMayHaveMoved: true
1580
+ }
1581
+ };
1582
+ defineNonEnumerableHeaders(preparation, headers);
1583
+ return preparation;
1584
+ },
1585
+ async settle({ manifest, request, context, result, preparation }) {
1586
+ assertProviderMatches(
1587
+ options.providerId,
1588
+ manifest.id,
1589
+ request.capability,
1590
+ context.callId
1591
+ );
1592
+ const preparedPayment = decodePreparedPayment(
1593
+ preparation,
1594
+ request.capability,
1595
+ manifest.id,
1596
+ context.callId
1597
+ );
1598
+ const settleResult = await facilitator.settle({
1599
+ ...preparedPayment,
1600
+ result,
1601
+ manifest,
1602
+ request,
1603
+ context,
1604
+ providerId: manifest.id,
1605
+ capability: request.capability,
1606
+ callId: context.callId
1607
+ });
1608
+ assertSettleResult(
1609
+ settleResult,
1610
+ request.capability,
1611
+ manifest.id,
1612
+ context.callId
1613
+ );
1614
+ const paymentId = getPayloadString(preparedPayment.paymentPayload, "paymentId") ?? `${context.callId}:x402_payment`;
1615
+ const paymentAttemptId = `${paymentId}:attempt`;
1616
+ const hasDeliveryReceipt = Array.isArray(result.receiptRefs) && result.receiptRefs.some(
1617
+ (receiptRef) => receiptRef.type === "provider_delivery"
1618
+ );
1619
+ if (!settleResult.success) {
1620
+ throw new ProbeMeshError({
1621
+ code: "payment_failed",
1622
+ message: settleResult.errorMessage ?? `x402 facilitator failed settlement for provider "${manifest.id}".`,
1623
+ capability: request.capability,
1624
+ provider: manifest.id,
1625
+ callId: context.callId,
1626
+ safety: {
1627
+ paymentAttemptId,
1628
+ paymentStatus: "authorized",
1629
+ settlementStatus: "failed",
1630
+ deliveryStatus: hasDeliveryReceipt ? "delivered" : "missing",
1631
+ moneyMayHaveMoved: true
1632
+ }
1633
+ });
1634
+ }
1635
+ const headers = {
1636
+ [PAYMENT_RESPONSE_HEADER]: encodePaymentResponseHeader(settleResult)
1637
+ };
1638
+ const settlement = {
1639
+ mode: manifest.protocolMode,
1640
+ metadata: {
1641
+ settled: true,
1642
+ x402Version: 2,
1643
+ paymentId,
1644
+ paymentAttemptId,
1645
+ settlementResponse: settleResult,
1646
+ paymentResponseHeader: PAYMENT_RESPONSE_HEADER
1647
+ },
1648
+ receiptRefs: [
1649
+ {
1650
+ type: "settlement_confirmation",
1651
+ provider: manifest.id,
1652
+ status: "recorded",
1653
+ ref: `${context.callId}:x402_settlement_confirmed`,
1654
+ timestamp: context.startedAt.toISOString()
1655
+ }
1656
+ ],
1657
+ safety: {
1658
+ paymentAttemptId,
1659
+ paymentStatus: "authorized",
1660
+ settlementStatus: "settled",
1661
+ deliveryStatus: hasDeliveryReceipt ? "delivered" : "missing",
1662
+ moneyMayHaveMoved: true
1663
+ }
1664
+ };
1665
+ defineNonEnumerableHeaders(settlement, headers);
1666
+ return settlement;
1667
+ }
1668
+ };
1669
+ }
1670
+ function createX402LocalSigner(options = {}) {
1671
+ assertLocalSignerOptions(options);
1672
+ return (input) => {
1673
+ if (options.failSign) {
1674
+ throw new ProbeMeshError({
1675
+ code: "payment_failed",
1676
+ message: `x402 local signer failed for provider "${input.providerId}".`,
1677
+ capability: input.capability,
1678
+ provider: input.providerId,
1679
+ callId: input.callId,
1680
+ safety: noPaymentSafety2()
1681
+ });
1682
+ }
1683
+ const payer = options.payer ?? input.payer;
1684
+ const paymentId = options.paymentId ?? input.paymentId;
1685
+ const issuedAt = input.context.startedAt.toISOString();
1686
+ const paymentPayload = {
1687
+ x402Version: 2,
1688
+ resource: input.paymentRequired.resource,
1689
+ accepted: input.paymentRequirements,
1690
+ payload: {
1691
+ ...options.payload ?? {},
1692
+ kind: "probemesh-local-x402-signature",
1693
+ payer,
1694
+ provider: input.providerId,
1695
+ callId: input.callId,
1696
+ paymentId,
1697
+ issuedAt,
1698
+ signature: `local-x402:${input.providerId}:${input.callId}:${paymentId}`
1699
+ },
1700
+ extensions: input.paymentRequired.extensions
1701
+ };
1702
+ return {
1703
+ payer,
1704
+ paymentPayload,
1705
+ metadata: {
1706
+ signer: "local",
1707
+ paymentId
1708
+ }
1709
+ };
1710
+ };
1711
+ }
1712
+ function createX402LocalFacilitator(options = {}) {
1713
+ assertLocalFacilitatorOptions(options);
1714
+ return {
1715
+ verify(input) {
1716
+ const payer = options.payer ?? getPayloadString(input.paymentPayload, "payer") ?? DEFAULT_PAYER;
1717
+ if (options.failVerify) {
1718
+ return {
1719
+ isValid: false,
1720
+ invalidReason: options.invalidReason ?? "local_verify_failed",
1721
+ invalidMessage: options.invalidMessage ?? `x402 local facilitator rejected payment for provider "${input.providerId}".`,
1722
+ payer,
1723
+ extra: {
1724
+ provider: input.providerId,
1725
+ callId: input.callId
1726
+ }
1727
+ };
1728
+ }
1729
+ if (input.paymentPayload.x402Version !== 2) {
1730
+ return {
1731
+ isValid: false,
1732
+ invalidReason: "unsupported_x402_version",
1733
+ invalidMessage: "x402 local facilitator only accepts V2 payloads.",
1734
+ payer
1735
+ };
1736
+ }
1737
+ if (!paymentRequirementsMatch(
1738
+ input.paymentPayload.accepted,
1739
+ input.paymentRequirements
1740
+ )) {
1741
+ return {
1742
+ isValid: false,
1743
+ invalidReason: "requirements_mismatch",
1744
+ invalidMessage: "x402 payment payload does not match the selected payment requirements.",
1745
+ payer
1746
+ };
1747
+ }
1748
+ return {
1749
+ isValid: true,
1750
+ payer,
1751
+ extra: {
1752
+ provider: input.providerId,
1753
+ callId: input.callId,
1754
+ paymentId: getPayloadString(input.paymentPayload, "paymentId")
1755
+ }
1756
+ };
1757
+ },
1758
+ settle(input) {
1759
+ const payer = options.payer ?? getPayloadString(input.paymentPayload, "payer") ?? DEFAULT_PAYER;
1760
+ const transaction = options.transaction ?? `${input.callId}:x402_local_settlement`;
1761
+ const baseResponse = {
1762
+ payer,
1763
+ transaction,
1764
+ network: input.paymentRequirements.network,
1765
+ amount: input.paymentRequirements.amount,
1766
+ extra: {
1767
+ provider: input.providerId,
1768
+ callId: input.callId,
1769
+ paymentId: getPayloadString(input.paymentPayload, "paymentId")
1770
+ }
1771
+ };
1772
+ if (options.failSettle) {
1773
+ return {
1774
+ ...baseResponse,
1775
+ success: false,
1776
+ errorReason: options.errorReason ?? "local_settle_failed",
1777
+ errorMessage: options.errorMessage ?? `x402 local facilitator failed settlement for provider "${input.providerId}".`
1778
+ };
1779
+ }
1780
+ return {
1781
+ ...baseResponse,
1782
+ success: true
1783
+ };
1784
+ }
1785
+ };
1786
+ }
1787
+ async function resolvePaymentRequired(options) {
1788
+ const defaultPaymentRequired = createDefaultPaymentRequired({
1789
+ providerId: options.manifest.id,
1790
+ capability: options.request.capability,
1791
+ config: options.options.paymentRequired
1792
+ });
1793
+ const paymentRequired = options.options.resolvePaymentRequired ? await options.options.resolvePaymentRequired({
1794
+ manifest: options.manifest,
1795
+ request: options.request,
1796
+ context: options.context
1797
+ }) : defaultPaymentRequired;
1798
+ assertPaymentRequired(paymentRequired);
1799
+ return paymentRequired;
1800
+ }
1801
+ function decodePreparedPayment(preparation, capability, provider, callId) {
1802
+ const paymentRequiredHeader = preparation?.headers?.[PAYMENT_REQUIRED_HEADER];
1803
+ const paymentSignatureHeader = preparation?.headers?.[PAYMENT_SIGNATURE_HEADER];
1804
+ if (!paymentRequiredHeader || !paymentSignatureHeader) {
1805
+ throw new ProbeMeshError({
1806
+ code: "payment_failed",
1807
+ message: `x402 prepared payment headers are missing for provider "${provider}".`,
1808
+ capability,
1809
+ provider,
1810
+ callId,
1811
+ safety: {
1812
+ paymentStatus: "authorized",
1813
+ settlementStatus: "failed",
1814
+ deliveryStatus: "missing",
1815
+ moneyMayHaveMoved: true
1816
+ }
1817
+ });
1818
+ }
1819
+ const paymentRequired = decodePaymentRequiredHeader(paymentRequiredHeader);
1820
+ const paymentPayload = decodePaymentSignatureHeader(paymentSignatureHeader);
1821
+ assertPaymentRequired(paymentRequired);
1822
+ assertPaymentPayload(
1823
+ paymentPayload,
1824
+ paymentPayload.accepted,
1825
+ capability,
1826
+ provider,
1827
+ callId
1828
+ );
1829
+ return {
1830
+ paymentRequired,
1831
+ paymentPayload,
1832
+ paymentRequirements: paymentPayload.accepted
1833
+ };
1834
+ }
1835
+ function assertSignerResult(signerResult, capability, provider, callId) {
1836
+ if (!signerResult || typeof signerResult !== "object" || Array.isArray(signerResult)) {
1837
+ throw new ProbeMeshError({
1838
+ code: "payment_failed",
1839
+ message: `x402 signer returned an invalid result for provider "${provider}".`,
1840
+ capability,
1841
+ provider,
1842
+ callId,
1843
+ safety: failedPaymentSafety()
1844
+ });
1845
+ }
1846
+ }
1847
+ function assertPaymentPayload(paymentPayload, paymentRequirements, capability, provider, callId) {
1848
+ if (!paymentPayload || typeof paymentPayload !== "object" || Array.isArray(paymentPayload)) {
1849
+ throw new ProbeMeshError({
1850
+ code: "payment_failed",
1851
+ message: `x402 signer returned an invalid payment payload for provider "${provider}".`,
1852
+ capability,
1853
+ provider,
1854
+ callId,
1855
+ safety: failedPaymentSafety()
1856
+ });
1857
+ }
1858
+ if (paymentPayload.x402Version !== 2) {
1859
+ throw new ProbeMeshError({
1860
+ code: "payment_failed",
1861
+ message: "x402 payment payload x402Version must be 2.",
1862
+ capability,
1863
+ provider,
1864
+ callId,
1865
+ safety: failedPaymentSafety()
1866
+ });
1867
+ }
1868
+ if (!paymentPayload.accepted || typeof paymentPayload.accepted !== "object" || Array.isArray(paymentPayload.accepted)) {
1869
+ throw new ProbeMeshError({
1870
+ code: "payment_failed",
1871
+ message: "x402 payment payload accepted requirements must be an object.",
1872
+ capability,
1873
+ provider,
1874
+ callId,
1875
+ safety: failedPaymentSafety()
1876
+ });
1877
+ }
1878
+ if (!paymentPayload.payload || typeof paymentPayload.payload !== "object" || Array.isArray(paymentPayload.payload)) {
1879
+ throw new ProbeMeshError({
1880
+ code: "payment_failed",
1881
+ message: "x402 payment payload payload must be an object.",
1882
+ capability,
1883
+ provider,
1884
+ callId,
1885
+ safety: failedPaymentSafety()
1886
+ });
1887
+ }
1888
+ if (!paymentRequirementsMatch(paymentPayload.accepted, paymentRequirements)) {
1889
+ throw new ProbeMeshError({
1890
+ code: "payment_failed",
1891
+ message: "x402 payment payload does not match the selected payment requirements.",
1892
+ capability,
1893
+ provider,
1894
+ callId,
1895
+ safety: failedPaymentSafety()
1896
+ });
1897
+ }
1898
+ }
1899
+ function assertVerifyResult(verifyResult, capability, provider, callId) {
1900
+ if (!verifyResult || typeof verifyResult !== "object" || Array.isArray(verifyResult) || typeof verifyResult.isValid !== "boolean") {
1901
+ throw new ProbeMeshError({
1902
+ code: "payment_failed",
1903
+ message: `x402 facilitator returned an invalid verify response for provider "${provider}".`,
1904
+ capability,
1905
+ provider,
1906
+ callId,
1907
+ safety: failedPaymentSafety()
1908
+ });
1909
+ }
1910
+ }
1911
+ function assertSettleResult(settleResult, capability, provider, callId) {
1912
+ if (!settleResult || typeof settleResult !== "object" || Array.isArray(settleResult) || typeof settleResult.success !== "boolean" || typeof settleResult.transaction !== "string" || settleResult.transaction.length === 0 || typeof settleResult.network !== "string" || settleResult.network.length === 0) {
1913
+ throw new ProbeMeshError({
1914
+ code: "payment_failed",
1915
+ message: `x402 facilitator returned an invalid settlement response for provider "${provider}".`,
1916
+ capability,
1917
+ provider,
1918
+ callId,
1919
+ safety: {
1920
+ paymentStatus: "authorized",
1921
+ settlementStatus: "failed",
1922
+ deliveryStatus: "missing",
1923
+ moneyMayHaveMoved: true
1924
+ }
1925
+ });
1926
+ }
1927
+ }
1928
+ function createDefaultPaymentRequired(options) {
1929
+ const config = options.config ?? {};
1930
+ const accepts = config.accepts ?? [
1931
+ {
1932
+ scheme: config.scheme ?? "exact",
1933
+ network: normalizeNetwork(config.network ?? DEFAULT_NETWORK2),
1934
+ asset: config.asset ?? DEFAULT_ASSET,
1935
+ amount: config.amount ?? DEFAULT_AMOUNT2,
1936
+ payTo: config.payTo ?? DEFAULT_PAY_TO,
1937
+ maxTimeoutSeconds: config.maxTimeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS,
1938
+ extra: config.extra ?? {}
1939
+ }
1940
+ ];
1941
+ return {
1942
+ x402Version: config.x402Version ?? 2,
1943
+ error: config.error,
1944
+ resource: normalizeResourceInfo(
1945
+ config.resource,
1946
+ options.providerId,
1947
+ options.capability
1948
+ ),
1949
+ accepts,
1950
+ extensions: config.extensions
1951
+ };
1952
+ }
1953
+ function assertPaymentRequired(paymentRequired) {
1954
+ if (!paymentRequired || typeof paymentRequired !== "object" || Array.isArray(paymentRequired)) {
1955
+ throw new ProbeMeshError({
1956
+ code: "invalid_request",
1957
+ message: "x402 paymentRequired must be an object."
1958
+ });
1959
+ }
1960
+ if (paymentRequired.x402Version !== 2) {
1961
+ throw new ProbeMeshError({
1962
+ code: "invalid_request",
1963
+ message: "x402 paymentRequired.x402Version must be 2."
1964
+ });
1965
+ }
1966
+ if (!paymentRequired.resource || typeof paymentRequired.resource !== "object" || typeof paymentRequired.resource.url !== "string" || paymentRequired.resource.url.length === 0) {
1967
+ throw new ProbeMeshError({
1968
+ code: "invalid_request",
1969
+ message: "x402 paymentRequired.resource.url must be a non-empty string."
1970
+ });
1971
+ }
1972
+ if (!Array.isArray(paymentRequired.accepts) || paymentRequired.accepts.length === 0) {
1973
+ throw new ProbeMeshError({
1974
+ code: "invalid_request",
1975
+ message: "x402 paymentRequired.accepts must include at least one option."
1976
+ });
1977
+ }
1978
+ for (const requirements of paymentRequired.accepts) {
1979
+ assertPaymentRequirements(requirements);
1980
+ }
1981
+ }
1982
+ function assertPaymentRequirements(requirements) {
1983
+ if (!requirements || typeof requirements !== "object") {
1984
+ throw new ProbeMeshError({
1985
+ code: "invalid_request",
1986
+ message: "x402 payment requirements must be an object."
1987
+ });
1988
+ }
1989
+ for (const field of ["scheme", "network", "asset", "amount", "payTo"]) {
1990
+ const value = requirements[field];
1991
+ if (typeof value !== "string" || value.length === 0) {
1992
+ throw new ProbeMeshError({
1993
+ code: "invalid_request",
1994
+ message: `x402 payment requirements ${field} must be a non-empty string.`
1995
+ });
1996
+ }
1997
+ }
1998
+ if (typeof requirements.maxTimeoutSeconds !== "number" || !Number.isFinite(requirements.maxTimeoutSeconds) || requirements.maxTimeoutSeconds <= 0) {
1999
+ throw new ProbeMeshError({
2000
+ code: "invalid_request",
2001
+ message: "x402 payment requirements maxTimeoutSeconds must be a positive number."
2002
+ });
2003
+ }
2004
+ if (!requirements.extra || typeof requirements.extra !== "object" || Array.isArray(requirements.extra)) {
2005
+ throw new ProbeMeshError({
2006
+ code: "invalid_request",
2007
+ message: "x402 payment requirements extra must be an object."
2008
+ });
2009
+ }
2010
+ }
2011
+ function assertX402ProtocolOptions(options) {
2012
+ validateOptionalString(options.mode, "mode");
2013
+ validateOptionalString(options.providerId, "providerId");
2014
+ validateOptionalString(options.payer, "payer");
2015
+ validateOptionalString(options.paymentId, "paymentId");
2016
+ if (options.paymentRequired !== void 0 && (!options.paymentRequired || typeof options.paymentRequired !== "object" || Array.isArray(options.paymentRequired))) {
2017
+ throw new ProbeMeshError({
2018
+ code: "invalid_request",
2019
+ message: "x402 paymentRequired config must be an object when provided."
2020
+ });
2021
+ }
2022
+ if (options.resolvePaymentRequired !== void 0 && typeof options.resolvePaymentRequired !== "function") {
2023
+ throw new ProbeMeshError({
2024
+ code: "invalid_request",
2025
+ message: "x402 resolvePaymentRequired must be a function when provided."
2026
+ });
2027
+ }
2028
+ if (options.signer !== void 0 && typeof options.signer !== "function") {
2029
+ throw new ProbeMeshError({
2030
+ code: "invalid_request",
2031
+ message: "x402 signer must be a function when provided."
2032
+ });
2033
+ }
2034
+ if (options.facilitator !== void 0 && (!options.facilitator || typeof options.facilitator !== "object" || typeof options.facilitator.verify !== "function" || typeof options.facilitator.settle !== "function")) {
2035
+ throw new ProbeMeshError({
2036
+ code: "invalid_request",
2037
+ message: "x402 facilitator must expose verify(...) and settle(...) functions."
2038
+ });
2039
+ }
2040
+ }
2041
+ function assertLocalSignerOptions(options) {
2042
+ validateOptionalString(options.payer, "local signer payer");
2043
+ validateOptionalString(options.paymentId, "local signer paymentId");
2044
+ if (options.failSign !== void 0 && typeof options.failSign !== "boolean") {
2045
+ throw new ProbeMeshError({
2046
+ code: "invalid_request",
2047
+ message: "x402 local signer failSign must be a boolean when provided."
2048
+ });
2049
+ }
2050
+ if (options.payload !== void 0 && (!options.payload || typeof options.payload !== "object" || Array.isArray(options.payload))) {
2051
+ throw new ProbeMeshError({
2052
+ code: "invalid_request",
2053
+ message: "x402 local signer payload must be an object when provided."
2054
+ });
2055
+ }
2056
+ }
2057
+ function assertLocalFacilitatorOptions(options) {
2058
+ validateOptionalString(options.payer, "local facilitator payer");
2059
+ validateOptionalString(options.invalidReason, "local facilitator invalidReason");
2060
+ validateOptionalString(options.invalidMessage, "local facilitator invalidMessage");
2061
+ validateOptionalString(options.errorReason, "local facilitator errorReason");
2062
+ validateOptionalString(options.errorMessage, "local facilitator errorMessage");
2063
+ validateOptionalString(options.transaction, "local facilitator transaction");
2064
+ if (options.failVerify !== void 0 && typeof options.failVerify !== "boolean") {
2065
+ throw new ProbeMeshError({
2066
+ code: "invalid_request",
2067
+ message: "x402 local facilitator failVerify must be a boolean when provided."
2068
+ });
2069
+ }
2070
+ if (options.failSettle !== void 0 && typeof options.failSettle !== "boolean") {
2071
+ throw new ProbeMeshError({
2072
+ code: "invalid_request",
2073
+ message: "x402 local facilitator failSettle must be a boolean when provided."
2074
+ });
2075
+ }
2076
+ }
2077
+ function normalizeResourceInfo(resource, providerId, capability) {
2078
+ if (typeof resource === "string") {
2079
+ return {
2080
+ url: resource,
2081
+ description: `ProbeMesh x402 payment for ${capability}.`,
2082
+ mimeType: "application/json",
2083
+ serviceName: providerId
2084
+ };
2085
+ }
2086
+ return {
2087
+ url: resource?.url ?? `probemesh://${providerId}/${capability}`,
2088
+ description: resource?.description ?? `ProbeMesh x402 payment for ${capability}.`,
2089
+ mimeType: resource?.mimeType ?? "application/json",
2090
+ serviceName: resource?.serviceName ?? providerId,
2091
+ tags: resource?.tags,
2092
+ iconUrl: resource?.iconUrl
2093
+ };
2094
+ }
2095
+ function normalizeNetwork(network) {
2096
+ if (!network.includes(":")) {
2097
+ throw new ProbeMeshError({
2098
+ code: "invalid_request",
2099
+ message: "x402 payment requirements network must use CAIP-2 format."
2100
+ });
2101
+ }
2102
+ return network;
2103
+ }
2104
+ function defineNonEnumerableHeaders(target, headers) {
2105
+ Object.defineProperty(target, "headers", {
2106
+ value: Object.freeze(headers),
2107
+ enumerable: false,
2108
+ configurable: false,
2109
+ writable: false
2110
+ });
2111
+ }
2112
+ function assertProviderMatches(configuredProviderId, manifestProviderId, capability, callId) {
2113
+ if (!configuredProviderId || configuredProviderId === manifestProviderId) {
2114
+ return;
2115
+ }
2116
+ throw new ProbeMeshError({
2117
+ code: "invalid_request",
2118
+ message: `x402 protocol is configured for provider "${configuredProviderId}", but manifest "${manifestProviderId}" was used.`,
2119
+ capability,
2120
+ provider: manifestProviderId,
2121
+ callId
2122
+ });
2123
+ }
2124
+ function paymentRequirementsMatch(left, right) {
2125
+ return left.scheme === right.scheme && left.network === right.network && left.asset === right.asset && left.amount === right.amount && left.payTo === right.payTo;
2126
+ }
2127
+ function getPayloadString(paymentPayload, field) {
2128
+ const value = paymentPayload.payload[field];
2129
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2130
+ }
2131
+ function validateOptionalString(value, field) {
2132
+ if (value !== void 0 && (typeof value !== "string" || value.length === 0)) {
2133
+ throw new ProbeMeshError({
2134
+ code: "invalid_request",
2135
+ message: `x402 ${field} must be a non-empty string when provided.`
2136
+ });
2137
+ }
2138
+ }
2139
+ function noPaymentSafety2() {
2140
+ return failedPaymentSafety();
2141
+ }
2142
+ function failedPaymentSafety() {
2143
+ return {
2144
+ paymentStatus: "failed",
2145
+ settlementStatus: "not_attempted",
2146
+ deliveryStatus: "not_attempted",
2147
+ moneyMayHaveMoved: false
2148
+ };
2149
+ }
2150
+ var X402_PROTOCOL_DEFAULT_MODE = DEFAULT_MODE2;
2151
+
2152
+ // src/protocols/x402SandboxProtocol.ts
2153
+ var DEFAULT_MODE3 = "x402";
2154
+ var DEFAULT_PAYER2 = "sandbox-agent";
2155
+ var DEFAULT_NETWORK3 = "eip155:84532";
2156
+ var DEFAULT_ASSET2 = "USDC";
2157
+ var DEFAULT_AMOUNT3 = "10000";
2158
+ var DEFAULT_PAY_TO2 = "sandbox-provider-wallet";
2159
+ var PAYMENT_REQUIRED_HEADER2 = "PAYMENT-REQUIRED";
2160
+ var PAYMENT_SIGNATURE_HEADER2 = "PAYMENT-SIGNATURE";
2161
+ var PAYMENT_RESPONSE_HEADER2 = "PAYMENT-RESPONSE";
2162
+ function createX402SandboxProtocol(options = {}) {
2163
+ assertX402SandboxProtocolOptions(options);
2164
+ const mode = options.mode ?? DEFAULT_MODE3;
2165
+ return {
2166
+ mode,
2167
+ prepare({ manifest, request, context }) {
2168
+ if (options.failPrepare) {
2169
+ throw new ProbeMeshError({
2170
+ code: "payment_failed",
2171
+ message: `x402 sandbox payment authorization failed for provider "${manifest.id}".`,
2172
+ capability: request.capability,
2173
+ provider: manifest.id,
2174
+ callId: context.callId,
2175
+ safety: failedPaymentSafety2()
2176
+ });
2177
+ }
2178
+ assertProviderMatches2(options.providerId, manifest.id, request.capability, context.callId);
2179
+ const paymentRequired = createPaymentRequirement({
2180
+ providerId: manifest.id,
2181
+ capability: request.capability,
2182
+ options
2183
+ });
2184
+ const paymentId = options.paymentId ?? `${context.callId}:x402_payment`;
2185
+ const payer = options.payer ?? DEFAULT_PAYER2;
2186
+ const paymentAttemptId = `${paymentId}:attempt`;
2187
+ const paymentPayload = createPaymentPayload({
2188
+ paymentRequired,
2189
+ providerId: manifest.id,
2190
+ callId: context.callId,
2191
+ paymentId,
2192
+ payer,
2193
+ issuedAt: context.startedAt.toISOString()
2194
+ });
2195
+ const headers = {
2196
+ [PAYMENT_REQUIRED_HEADER2]: encodeBase64Json(paymentRequired),
2197
+ [PAYMENT_SIGNATURE_HEADER2]: encodeBase64Json(paymentPayload)
2198
+ };
2199
+ const preparation = {
2200
+ mode: manifest.protocolMode,
2201
+ metadata: {
2202
+ authorized: true,
2203
+ x402Version: 2,
2204
+ paymentId,
2205
+ paymentAttemptId,
2206
+ payer,
2207
+ network: paymentRequired.network,
2208
+ asset: paymentRequired.asset,
2209
+ amount: paymentRequired.amount,
2210
+ paymentRequired,
2211
+ paymentPayload,
2212
+ paymentRequiredHeader: PAYMENT_REQUIRED_HEADER2,
2213
+ paymentSignatureHeader: PAYMENT_SIGNATURE_HEADER2
2214
+ },
2215
+ receiptRefs: [
2216
+ {
2217
+ type: "payment_proof",
2218
+ provider: manifest.id,
2219
+ status: "recorded",
2220
+ ref: `${context.callId}:x402_payment_proof`,
2221
+ timestamp: context.startedAt.toISOString()
2222
+ }
2223
+ ],
2224
+ safety: {
2225
+ paymentAttemptId,
2226
+ paymentStatus: "authorized",
2227
+ settlementStatus: "not_attempted",
2228
+ deliveryStatus: "not_attempted",
2229
+ moneyMayHaveMoved: true
2230
+ }
2231
+ };
2232
+ defineNonEnumerableHeaders2(preparation, headers);
2233
+ return preparation;
2234
+ },
2235
+ settle({ manifest, request, context, result, preparation }) {
2236
+ assertProviderMatches2(options.providerId, manifest.id, request.capability, context.callId);
2237
+ const paymentAttemptId = getMetadataString(
2238
+ preparation?.metadata?.paymentAttemptId,
2239
+ `${context.callId}:x402_payment:attempt`
2240
+ );
2241
+ const paymentId = getMetadataString(
2242
+ preparation?.metadata?.paymentId,
2243
+ `${context.callId}:x402_payment`
2244
+ );
2245
+ const payer = getMetadataString(preparation?.metadata?.payer, DEFAULT_PAYER2);
2246
+ const network = getMetadataString(
2247
+ preparation?.metadata?.network,
2248
+ DEFAULT_NETWORK3
2249
+ );
2250
+ const asset = getMetadataString(preparation?.metadata?.asset, DEFAULT_ASSET2);
2251
+ const amount = getMetadataString(
2252
+ preparation?.metadata?.amount,
2253
+ DEFAULT_AMOUNT3
2254
+ );
2255
+ const hasDeliveryReceipt = Array.isArray(result.receiptRefs) && result.receiptRefs.some(
2256
+ (receiptRef) => receiptRef.type === "provider_delivery"
2257
+ );
2258
+ if (options.failSettle) {
2259
+ throw new ProbeMeshError({
2260
+ code: "payment_failed",
2261
+ message: `x402 sandbox settlement failed for provider "${manifest.id}".`,
2262
+ capability: request.capability,
2263
+ provider: manifest.id,
2264
+ callId: context.callId,
2265
+ safety: {
2266
+ paymentAttemptId,
2267
+ paymentStatus: "authorized",
2268
+ settlementStatus: "failed",
2269
+ deliveryStatus: "missing",
2270
+ moneyMayHaveMoved: true
2271
+ }
2272
+ });
2273
+ }
2274
+ const settlementResponse = {
2275
+ x402Version: 2,
2276
+ success: true,
2277
+ provider: manifest.id,
2278
+ payer,
2279
+ paymentId,
2280
+ paymentAttemptId,
2281
+ network,
2282
+ asset,
2283
+ amount,
2284
+ settledAt: context.startedAt.toISOString(),
2285
+ sandboxSettlementId: `${context.callId}:x402_settlement`
2286
+ };
2287
+ const headers = {
2288
+ [PAYMENT_RESPONSE_HEADER2]: encodeBase64Json(settlementResponse)
2289
+ };
2290
+ const settlement = {
2291
+ mode: manifest.protocolMode,
2292
+ metadata: {
2293
+ settled: true,
2294
+ x402Version: 2,
2295
+ paymentId,
2296
+ paymentAttemptId,
2297
+ settlementResponse,
2298
+ paymentResponseHeader: PAYMENT_RESPONSE_HEADER2
2299
+ },
2300
+ receiptRefs: [
2301
+ {
2302
+ type: "settlement_confirmation",
2303
+ provider: manifest.id,
2304
+ status: "recorded",
2305
+ ref: `${context.callId}:x402_settlement_confirmed`,
2306
+ timestamp: context.startedAt.toISOString()
2307
+ }
2308
+ ],
2309
+ safety: {
2310
+ paymentAttemptId,
2311
+ paymentStatus: "authorized",
2312
+ settlementStatus: "settled",
2313
+ deliveryStatus: hasDeliveryReceipt ? "delivered" : "missing",
2314
+ moneyMayHaveMoved: true
2315
+ }
2316
+ };
2317
+ defineNonEnumerableHeaders2(settlement, headers);
2318
+ return settlement;
2319
+ }
2320
+ };
2321
+ }
2322
+ function assertX402SandboxProtocolOptions(options) {
2323
+ validateOptionalString2(options.mode, "mode");
2324
+ validateOptionalString2(options.providerId, "providerId");
2325
+ validateOptionalString2(options.paymentId, "paymentId");
2326
+ validateOptionalString2(options.payer, "payer");
2327
+ if (options.paymentRequired !== void 0 && (!options.paymentRequired || typeof options.paymentRequired !== "object" || Array.isArray(options.paymentRequired))) {
2328
+ throw new ProbeMeshError({
2329
+ code: "invalid_request",
2330
+ message: "x402 sandbox paymentRequired must be an object when provided."
2331
+ });
2332
+ }
2333
+ if (options.failPrepare !== void 0 && typeof options.failPrepare !== "boolean") {
2334
+ throw new ProbeMeshError({
2335
+ code: "invalid_request",
2336
+ message: "x402 sandbox failPrepare must be a boolean when provided."
2337
+ });
2338
+ }
2339
+ if (options.failSettle !== void 0 && typeof options.failSettle !== "boolean") {
2340
+ throw new ProbeMeshError({
2341
+ code: "invalid_request",
2342
+ message: "x402 sandbox failSettle must be a boolean when provided."
2343
+ });
2344
+ }
2345
+ }
2346
+ function validateOptionalString2(value, field) {
2347
+ if (value !== void 0 && (typeof value !== "string" || value.length === 0)) {
2348
+ throw new ProbeMeshError({
2349
+ code: "invalid_request",
2350
+ message: `x402 sandbox ${field} must be a non-empty string when provided.`
2351
+ });
2352
+ }
2353
+ }
2354
+ function assertProviderMatches2(configuredProviderId, manifestProviderId, capability, callId) {
2355
+ if (!configuredProviderId || configuredProviderId === manifestProviderId) {
2356
+ return;
2357
+ }
2358
+ throw new ProbeMeshError({
2359
+ code: "invalid_request",
2360
+ message: `x402 sandbox protocol is configured for provider "${configuredProviderId}", but manifest "${manifestProviderId}" was used.`,
2361
+ capability,
2362
+ provider: manifestProviderId,
2363
+ callId
2364
+ });
2365
+ }
2366
+ function createPaymentRequirement(options) {
2367
+ const overrides = options.options.paymentRequired ?? {};
2368
+ return {
2369
+ x402Version: 2,
2370
+ scheme: overrides.scheme ?? "exact",
2371
+ network: overrides.network ?? DEFAULT_NETWORK3,
2372
+ asset: overrides.asset ?? DEFAULT_ASSET2,
2373
+ amount: overrides.amount ?? DEFAULT_AMOUNT3,
2374
+ payTo: overrides.payTo ?? DEFAULT_PAY_TO2,
2375
+ resource: overrides.resource ?? `probemesh://${options.providerId}/${options.capability}`,
2376
+ description: overrides.description ?? `ProbeMesh x402 sandbox payment for ${options.capability}.`,
2377
+ maxTimeoutSeconds: overrides.maxTimeoutSeconds ?? 60,
2378
+ extra: overrides.extra
2379
+ };
2380
+ }
2381
+ function createPaymentPayload(options) {
2382
+ return {
2383
+ x402Version: 2,
2384
+ scheme: options.paymentRequired.scheme,
2385
+ network: options.paymentRequired.network,
2386
+ asset: options.paymentRequired.asset,
2387
+ amount: options.paymentRequired.amount,
2388
+ payTo: options.paymentRequired.payTo,
2389
+ resource: options.paymentRequired.resource,
2390
+ payer: options.payer,
2391
+ provider: options.providerId,
2392
+ callId: options.callId,
2393
+ paymentId: options.paymentId,
2394
+ issuedAt: options.issuedAt,
2395
+ sandboxSignature: `sandbox:${options.providerId}:${options.paymentId}`
2396
+ };
2397
+ }
2398
+ function defineNonEnumerableHeaders2(target, headers) {
2399
+ Object.defineProperty(target, "headers", {
2400
+ value: Object.freeze(headers),
2401
+ enumerable: false,
2402
+ configurable: false,
2403
+ writable: false
2404
+ });
2405
+ }
2406
+ function encodeBase64Json(value) {
2407
+ return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
2408
+ }
2409
+ function getMetadataString(value, fallback) {
2410
+ return typeof value === "string" && value.length > 0 ? value : fallback;
2411
+ }
2412
+ function failedPaymentSafety2() {
2413
+ return {
2414
+ paymentStatus: "failed",
2415
+ settlementStatus: "not_attempted",
2416
+ deliveryStatus: "not_attempted",
2417
+ moneyMayHaveMoved: false
2418
+ };
2419
+ }
2420
+
2421
+ // src/receipts.ts
2422
+ function getReceiptRefs(source, type) {
2423
+ const receiptRefs = readReceiptRefs(source);
2424
+ if (type === void 0) {
2425
+ return [...receiptRefs];
2426
+ }
2427
+ return receiptRefs.filter((receiptRef) => receiptRef.type === type);
2428
+ }
2429
+ function findReceiptRef(source, type) {
2430
+ return getReceiptRefs(source, type)[0];
2431
+ }
2432
+ function hasReceipt(source, type) {
2433
+ return findReceiptRef(source, type) !== void 0;
2434
+ }
2435
+ function summarizeReceipts(source) {
2436
+ const receiptRefs = readReceiptRefs(source);
2437
+ const types = [];
2438
+ const providers = [];
2439
+ const byType = {};
2440
+ for (const receiptRef of receiptRefs) {
2441
+ if (!types.includes(receiptRef.type)) {
2442
+ types.push(receiptRef.type);
2443
+ }
2444
+ if (!providers.includes(receiptRef.provider)) {
2445
+ providers.push(receiptRef.provider);
2446
+ }
2447
+ byType[receiptRef.type] = (byType[receiptRef.type] ?? 0) + 1;
2448
+ }
2449
+ return {
2450
+ total: receiptRefs.length,
2451
+ types,
2452
+ providers,
2453
+ byType,
2454
+ hasPaymentProof: hasReceipt(receiptRefs, "payment_proof"),
2455
+ hasProviderDelivery: hasReceipt(receiptRefs, "provider_delivery")
2456
+ };
2457
+ }
2458
+ function readReceiptRefs(source) {
2459
+ return Array.isArray(source) ? source : source.receiptRefs;
2460
+ }
2461
+ export {
2462
+ PROBEMESH_AUDIT_TRAIL_BUNDLE_SCHEMA_VERSION,
2463
+ PROBEMESH_CALL_AUDIT_ARTIFACT_SCHEMA_VERSION,
2464
+ PROVIDER_CATALOG_ARTIFACT_SCHEMA_VERSION,
2465
+ PROVIDER_CATALOG_POLICY_BUNDLE_SCHEMA_VERSION,
2466
+ PROVIDER_CATALOG_SCHEMA_VERSION,
2467
+ PROVIDER_CONFORMANCE_ARTIFACT_SCHEMA_VERSION,
2468
+ PROVIDER_ONBOARDING_DOSSIER_SCHEMA_VERSION,
2469
+ ProbeMeshError,
2470
+ assertJsonSchemaLikeValue,
2471
+ assertProbeMeshAuditTrailBundle,
2472
+ assertProbeMeshCallAuditArtifact,
2473
+ assertProviderCatalog,
2474
+ assertProviderCatalogArtifact,
2475
+ assertProviderCatalogPolicyBundle,
2476
+ assertProviderConformanceArtifact,
2477
+ assertProviderManifest,
2478
+ assertProviderOnboardingDossier,
2479
+ createAdapterFromManifest,
2480
+ createApiKeyProtocol,
2481
+ createHostedCatalogPolicyFromOnboardingDossiers,
2482
+ createHostedRouter,
2483
+ createMockPaymentProtocol,
2484
+ createPaidPriceLookupProvider,
2485
+ createPriceLookupAdapter,
2486
+ createProbeMesh,
2487
+ createProbeMeshAuditTrailBundle,
2488
+ createProbeMeshAuditTrailCollector,
2489
+ createProbeMeshCallAuditArtifact,
2490
+ createProviderCatalog,
2491
+ createProviderCatalogArtifact,
2492
+ createProviderCatalogFromOnboardingDossiers,
2493
+ createProviderCatalogPolicyBundle,
2494
+ createProviderCatalogPolicyReport,
2495
+ createProviderConformanceArtifact,
2496
+ createProviderConformanceReport,
2497
+ createProviderOnboardingDossier,
2498
+ createProviderOnboardingDossierImportReport,
2499
+ createX402EvmSigner,
2500
+ createX402HttpFacilitator,
2501
+ createX402LocalFacilitator,
2502
+ createX402LocalSigner,
2503
+ createX402Protocol,
2504
+ createX402ProviderAcceptanceReport,
2505
+ createX402SandboxProtocol,
2506
+ evaluateProviderCatalogPolicy,
2507
+ evaluateProviderOnboardingDossiers,
2508
+ evaluateX402ProviderAcceptanceGate,
2509
+ findProviderCatalogMatches,
2510
+ findReceiptRef,
2511
+ formatProbeMeshAuditTrailBundle,
2512
+ formatProbeMeshCallAuditArtifact,
2513
+ formatProviderCatalogArtifact,
2514
+ formatProviderCatalogPolicyBundle,
2515
+ formatProviderCatalogPolicyReport,
2516
+ formatProviderConformanceArtifact,
2517
+ formatProviderConformanceReport,
2518
+ formatProviderOnboardingDossier,
2519
+ formatProviderOnboardingDossierImportReport,
2520
+ formatX402ProviderAcceptanceReport,
2521
+ getProbeMeshIntegrationTemplate,
2522
+ getProviderPaymentOptions,
2523
+ getReceiptRefs,
2524
+ hasReceipt,
2525
+ isProbeMeshError,
2526
+ listProbeMeshIntegrationTemplates,
2527
+ mergePaymentPreferences,
2528
+ parseProviderCatalogArtifactJson,
2529
+ parseProviderOnboardingDossierJson,
2530
+ redactX402Secrets,
2531
+ renderProbeMeshIntegrationTemplate,
2532
+ resolveProviderPaymentOption,
2533
+ resolveX402EvmTestnetConfig,
2534
+ runProbeMeshAuditTrailExportCli,
2535
+ runProbeMeshInitCli,
2536
+ runProviderCatalogPolicyCli,
2537
+ runProviderConformance,
2538
+ runProviderConformanceCli,
2539
+ runProviderDossierCheckCli,
2540
+ runProviderOnboardingDossierCli,
2541
+ runX402ProviderAcceptance,
2542
+ runX402ProviderAcceptanceCli,
2543
+ startHostedRouter,
2544
+ summarizeProbeMeshAuditTrailBundle,
2545
+ summarizeProviderCatalog,
2546
+ summarizeReceipts,
2547
+ summarizeX402AcceptanceResult,
2548
+ validateJsonSchemaLikeValue,
2549
+ validatePaymentStrategy,
2550
+ validateProbeMeshAuditTrailBundle,
2551
+ validateProbeMeshCallAuditArtifact,
2552
+ validateProviderCatalog,
2553
+ validateProviderCatalogArtifact,
2554
+ validateProviderCatalogPolicyBundle,
2555
+ validateProviderConformanceArtifact,
2556
+ validateProviderManifest,
2557
+ validateProviderOnboardingDossier,
2558
+ verifyProviderCatalogPolicyBundleRuntime
2559
+ };
2560
+ //# sourceMappingURL=index.js.map