@agentcash/discovery 1.2.0 → 1.3.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.
package/dist/cli.cjs CHANGED
@@ -13872,7 +13872,8 @@ var WellKnownParsedSchema = external_exports.object({
13872
13872
  routes: external_exports.array(
13873
13873
  external_exports.object({
13874
13874
  path: external_exports.string(),
13875
- method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"])
13875
+ method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"]),
13876
+ price: external_exports.string().optional()
13876
13877
  })
13877
13878
  ),
13878
13879
  instructions: external_exports.string().optional()
@@ -13965,9 +13966,9 @@ function toAbsoluteUrl(origin, value) {
13965
13966
 
13966
13967
  // src/core/source/fetch.ts
13967
13968
  var import_neverthrow = require("neverthrow");
13968
- function toFetchError(err) {
13969
- const cause = err instanceof DOMException && (err.name === "TimeoutError" || err.name === "AbortError") ? "timeout" : "network";
13970
- return { cause, message: String(err) };
13969
+ function toFetchError(err2) {
13970
+ const cause = err2 instanceof DOMException && (err2.name === "TimeoutError" || err2.name === "AbortError") ? "timeout" : "network";
13971
+ return { cause, message: String(err2) };
13971
13972
  }
13972
13973
  function fetchSafe(url2, init) {
13973
13974
  return import_neverthrow.ResultAsync.fromPromise(fetch(url2, init), toFetchError);
@@ -14033,6 +14034,9 @@ function getOpenAPI(origin, headers, signal, specificationOverrideUrl) {
14033
14034
  }
14034
14035
 
14035
14036
  // src/core/source/wellknown/index.ts
14037
+ var import_neverthrow5 = require("neverthrow");
14038
+
14039
+ // src/core/source/wellknown/x402.ts
14036
14040
  var import_neverthrow3 = require("neverthrow");
14037
14041
  function toWellKnownParsed(origin, doc) {
14038
14042
  const routes = doc.resources.flatMap((entry) => {
@@ -14059,12 +14063,17 @@ async function parseBody2(response, origin, url2) {
14059
14063
  if (!doc.success) return null;
14060
14064
  const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed(origin, doc.data));
14061
14065
  if (!parsed.success) return null;
14062
- return { raw: payload, ...parsed.data, fetchedUrl: url2 };
14066
+ return {
14067
+ raw: payload,
14068
+ ...parsed.data,
14069
+ protocol: "x402",
14070
+ fetchedUrl: url2
14071
+ };
14063
14072
  } catch {
14064
14073
  return null;
14065
14074
  }
14066
14075
  }
14067
- function getWellKnown(origin, headers, signal) {
14076
+ function getX402WellKnown(origin, headers, signal) {
14068
14077
  const url2 = `${origin}/.well-known/x402`;
14069
14078
  return fetchSafe(url2, {
14070
14079
  method: "GET",
@@ -14076,6 +14085,127 @@ function getWellKnown(origin, headers, signal) {
14076
14085
  });
14077
14086
  }
14078
14087
 
14088
+ // src/core/source/wellknown/mpp.ts
14089
+ var import_neverthrow4 = require("neverthrow");
14090
+ var MppEndpointSchema = external_exports.object({
14091
+ method: external_exports.string(),
14092
+ path: external_exports.string(),
14093
+ description: external_exports.string().optional(),
14094
+ payment: external_exports.object({
14095
+ intent: external_exports.string().optional(),
14096
+ method: external_exports.string().optional(),
14097
+ amount: external_exports.string().optional(),
14098
+ currency: external_exports.string().optional()
14099
+ }).optional()
14100
+ });
14101
+ var MppWellKnownDocSchema = external_exports.object({
14102
+ version: external_exports.number().optional(),
14103
+ name: external_exports.string().optional(),
14104
+ description: external_exports.string().optional(),
14105
+ categories: external_exports.array(external_exports.string()).optional(),
14106
+ methods: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
14107
+ endpoints: external_exports.array(MppEndpointSchema).default([]),
14108
+ docs: external_exports.object({
14109
+ homepage: external_exports.string().optional(),
14110
+ apiReference: external_exports.string().optional()
14111
+ }).optional()
14112
+ });
14113
+ var MPP_DECIMALS = 6;
14114
+ function formatMppAmount(raw) {
14115
+ if (!raw) return void 0;
14116
+ const n = Number(raw);
14117
+ if (!Number.isFinite(n)) return void 0;
14118
+ return `$${(n / 10 ** MPP_DECIMALS).toFixed(MPP_DECIMALS)}`;
14119
+ }
14120
+ function toWellKnownParsed2(doc) {
14121
+ const routes = doc.endpoints.flatMap((entry) => {
14122
+ const method = parseMethod(entry.method);
14123
+ if (!method) return [];
14124
+ const path = normalizePath(entry.path);
14125
+ if (!path) return [];
14126
+ const price = formatMppAmount(entry.payment?.amount);
14127
+ return [{ path, method, ...price ? { price } : {} }];
14128
+ });
14129
+ return {
14130
+ routes,
14131
+ ...doc.description ? { instructions: doc.description } : {}
14132
+ };
14133
+ }
14134
+ async function parseBody3(response, url2) {
14135
+ try {
14136
+ const payload = await response.json();
14137
+ const doc = MppWellKnownDocSchema.safeParse(payload);
14138
+ if (!doc.success) return null;
14139
+ const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed2(doc.data));
14140
+ if (!parsed.success) return null;
14141
+ return {
14142
+ raw: payload,
14143
+ ...parsed.data,
14144
+ ...doc.data.name ? { title: doc.data.name } : {},
14145
+ ...doc.data.description ? { description: doc.data.description } : {},
14146
+ protocol: "mpp",
14147
+ fetchedUrl: url2
14148
+ };
14149
+ } catch {
14150
+ return null;
14151
+ }
14152
+ }
14153
+ function getMppWellKnown(origin, headers, signal) {
14154
+ const url2 = `${origin}/.well-known/mpp`;
14155
+ return fetchSafe(url2, {
14156
+ method: "GET",
14157
+ headers: { Accept: "application/json", ...headers },
14158
+ signal
14159
+ }).andThen((response) => {
14160
+ if (!response.ok) return (0, import_neverthrow4.okAsync)(null);
14161
+ return import_neverthrow4.ResultAsync.fromSafePromise(parseBody3(response, url2));
14162
+ });
14163
+ }
14164
+
14165
+ // src/core/source/wellknown/index.ts
14166
+ function mergeError(a, b) {
14167
+ return {
14168
+ cause: a.cause === "network" || b.cause === "network" ? "network" : "timeout",
14169
+ message: `x402: ${a.message} | mpp: ${b.message}`
14170
+ };
14171
+ }
14172
+ function merge2(x402, mpp) {
14173
+ const seen = /* @__PURE__ */ new Set();
14174
+ const routes = [...x402.routes, ...mpp.routes].filter((r) => {
14175
+ const key = `${r.method} ${r.path}`;
14176
+ if (seen.has(key)) return false;
14177
+ seen.add(key);
14178
+ return true;
14179
+ });
14180
+ return {
14181
+ raw: { ...mpp.raw, ...x402.raw },
14182
+ routes,
14183
+ protocol: "x402+mpp",
14184
+ // Prefer x402 instructions; fall back to mpp
14185
+ ...x402.instructions || mpp.instructions ? { instructions: x402.instructions ?? mpp.instructions } : {},
14186
+ fetchedUrl: x402.fetchedUrl
14187
+ };
14188
+ }
14189
+ function getWellKnown(origin, headers, signal) {
14190
+ return new import_neverthrow5.ResultAsync(
14191
+ Promise.all([
14192
+ getX402WellKnown(origin, headers, signal),
14193
+ getMppWellKnown(origin, headers, signal)
14194
+ ]).then(([x402Result, mppResult]) => {
14195
+ const x402 = x402Result.isOk() ? x402Result.value : null;
14196
+ const mpp = mppResult.isOk() ? mppResult.value : null;
14197
+ if (x402 && mpp) return (0, import_neverthrow5.ok)(merge2(x402, mpp));
14198
+ if (x402) return (0, import_neverthrow5.ok)(x402);
14199
+ if (mpp) return (0, import_neverthrow5.ok)(mpp);
14200
+ if (x402Result.isErr() && mppResult.isErr())
14201
+ return (0, import_neverthrow5.err)(mergeError(x402Result.error, mppResult.error));
14202
+ if (x402Result.isErr()) return (0, import_neverthrow5.err)(x402Result.error);
14203
+ if (mppResult.isErr()) return (0, import_neverthrow5.err)(mppResult.error);
14204
+ return (0, import_neverthrow5.ok)(null);
14205
+ })
14206
+ );
14207
+ }
14208
+
14079
14209
  // src/core/layers/l2.ts
14080
14210
  function formatPrice(pricing) {
14081
14211
  if (pricing.pricingMode === "fixed") return `$${pricing.price}`;
@@ -14101,15 +14231,27 @@ function checkL2ForOpenAPI(openApi) {
14101
14231
  source: "openapi"
14102
14232
  };
14103
14233
  }
14234
+ var WELL_KNOWN_PROTOCOLS = {
14235
+ x402: ["x402"],
14236
+ mpp: ["mpp"],
14237
+ "x402+mpp": ["x402", "mpp"]
14238
+ };
14104
14239
  function checkL2ForWellknown(wellKnown) {
14240
+ const protocols = WELL_KNOWN_PROTOCOLS[wellKnown.protocol];
14105
14241
  const routes = wellKnown.routes.map((route) => ({
14106
14242
  path: route.path,
14107
14243
  method: route.method,
14108
14244
  summary: `${route.method} ${route.path}`,
14109
14245
  authMode: "paid",
14110
- protocols: ["x402"]
14246
+ protocols,
14247
+ ...route.price ? { price: route.price } : {}
14111
14248
  }));
14112
- return { routes, source: "well-known/x402" };
14249
+ return {
14250
+ ...wellKnown.title ? { title: wellKnown.title } : {},
14251
+ ...wellKnown.description ? { description: wellKnown.description } : {},
14252
+ routes,
14253
+ source: `well-known/${wellKnown.protocol}`
14254
+ };
14113
14255
  }
14114
14256
 
14115
14257
  // src/core/layers/l4.ts
@@ -14121,7 +14263,7 @@ function checkL4ForOpenAPI(openApi) {
14121
14263
  }
14122
14264
  function checkL4ForWellknown(wellKnown) {
14123
14265
  if (wellKnown.instructions) {
14124
- return { guidance: wellKnown.instructions, source: "well-known/x402" };
14266
+ return { guidance: wellKnown.instructions, source: `well-known/${wellKnown.protocol}` };
14125
14267
  }
14126
14268
  return null;
14127
14269
  }
@@ -15073,7 +15215,7 @@ function getWarningsForL4(l4) {
15073
15215
  }
15074
15216
 
15075
15217
  // src/core/source/probe/index.ts
15076
- var import_neverthrow4 = require("neverthrow");
15218
+ var import_neverthrow6 = require("neverthrow");
15077
15219
 
15078
15220
  // src/core/protocols/x402/index.ts
15079
15221
  function parseVersion(payload) {
@@ -15169,8 +15311,8 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
15169
15311
  ...hasBody ? { body: JSON.stringify(inputBody) } : {},
15170
15312
  signal
15171
15313
  }).andThen((response) => {
15172
- if (!isUsableStatus(response.status)) return import_neverthrow4.ResultAsync.fromSafePromise(Promise.resolve(null));
15173
- return import_neverthrow4.ResultAsync.fromSafePromise(
15314
+ if (!isUsableStatus(response.status)) return import_neverthrow6.ResultAsync.fromSafePromise(Promise.resolve(null));
15315
+ return import_neverthrow6.ResultAsync.fromSafePromise(
15174
15316
  (async () => {
15175
15317
  let authHint = response.status === 402 ? "paid" : "unprotected";
15176
15318
  let paymentRequiredBody;
@@ -15201,7 +15343,7 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
15201
15343
  }
15202
15344
  function getProbe(url2, headers, signal, inputBody) {
15203
15345
  const path = normalizePath(new URL(url2).pathname || "/");
15204
- return import_neverthrow4.ResultAsync.fromSafePromise(
15346
+ return import_neverthrow6.ResultAsync.fromSafePromise(
15205
15347
  Promise.all(
15206
15348
  [...HTTP_METHODS].map(
15207
15349
  (method) => probeMethod(url2, method, path, headers, signal, inputBody).match(
@@ -15214,6 +15356,20 @@ function getProbe(url2, headers, signal, inputBody) {
15214
15356
  }
15215
15357
 
15216
15358
  // src/core/protocols/mpp/index.ts
15359
+ var import_neverthrow7 = require("neverthrow");
15360
+ function parseBase64Json(encoded) {
15361
+ return import_neverthrow7.Result.fromThrowable(
15362
+ () => {
15363
+ const decoded = typeof Buffer !== "undefined" ? Buffer.from(encoded, "base64").toString("utf8") : atob(encoded);
15364
+ const parsed = JSON.parse(decoded);
15365
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
15366
+ throw new Error("not an object");
15367
+ }
15368
+ return parsed;
15369
+ },
15370
+ (e) => e
15371
+ )();
15372
+ }
15217
15373
  var TEMPO_DEFAULT_CHAIN_ID = 4217;
15218
15374
  function parseAuthParams2(segment) {
15219
15375
  const params = {};
@@ -15236,14 +15392,9 @@ function extractPaymentOptions4(wwwAuthenticate) {
15236
15392
  const description = params["description"];
15237
15393
  const requestStr = params["request"];
15238
15394
  if (!paymentMethod || !intent || !realm || !requestStr) continue;
15239
- let request;
15240
- try {
15241
- const parsed = JSON.parse(requestStr);
15242
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
15243
- request = parsed;
15244
- } catch {
15245
- continue;
15246
- }
15395
+ const requestResult = parseBase64Json(requestStr);
15396
+ if (requestResult.isErr()) continue;
15397
+ const request = requestResult.value;
15247
15398
  const asset = typeof request["currency"] === "string" ? request["currency"] : void 0;
15248
15399
  const amountRaw = request["amount"];
15249
15400
  const amount = typeof amountRaw === "string" ? amountRaw : typeof amountRaw === "number" ? String(amountRaw) : void 0;
@@ -15617,12 +15768,14 @@ ${l4.guidance}`);
15617
15768
  warnings.push(...l3WarningArrays.flat());
15618
15769
  if (flags.json) {
15619
15770
  const meta3 = { origin, specUrl: wellKnown.fetchedUrl };
15771
+ if (l2.title) meta3.title = l2.title;
15772
+ if (l2.description) meta3.description = l2.description;
15620
15773
  if (l4 && flags.verbose) meta3.guidance = l4.guidance;
15621
15774
  console.log(
15622
15775
  JSON.stringify(
15623
15776
  {
15624
15777
  ok: true,
15625
- selectedStage: "well-known/x402",
15778
+ selectedStage: l2.source,
15626
15779
  resources: l2.routes.map(routeToResource),
15627
15780
  warnings,
15628
15781
  trace: [],
@@ -15634,12 +15787,15 @@ ${l4.guidance}`);
15634
15787
  );
15635
15788
  return 0;
15636
15789
  }
15637
- console.log(`Source: well-known/x402`);
15790
+ console.log(`Source: ${l2.source}`);
15638
15791
  console.log(`Spec: ${wellKnown.fetchedUrl}`);
15792
+ if (l2.title) console.log(`API: ${l2.title}`);
15639
15793
  console.log(`Routes: ${l2.routes.length}
15640
15794
  `);
15641
15795
  for (const route of l2.routes) {
15642
- console.log(` ${route.method.padEnd(7)} ${route.path} paid [x402]`);
15796
+ const price = route.price ? ` ${route.price}` : "";
15797
+ const protocols = route.protocols?.length ? ` [${route.protocols.join(", ")}]` : "";
15798
+ console.log(` ${route.method.padEnd(7)} ${route.path} paid${price}${protocols}`);
15643
15799
  }
15644
15800
  } else {
15645
15801
  if (flags.json) {
package/dist/cli.js CHANGED
@@ -13842,7 +13842,8 @@ var WellKnownParsedSchema = external_exports.object({
13842
13842
  routes: external_exports.array(
13843
13843
  external_exports.object({
13844
13844
  path: external_exports.string(),
13845
- method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"])
13845
+ method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"]),
13846
+ price: external_exports.string().optional()
13846
13847
  })
13847
13848
  ),
13848
13849
  instructions: external_exports.string().optional()
@@ -13935,9 +13936,9 @@ function toAbsoluteUrl(origin, value) {
13935
13936
 
13936
13937
  // src/core/source/fetch.ts
13937
13938
  import { ResultAsync } from "neverthrow";
13938
- function toFetchError(err) {
13939
- const cause = err instanceof DOMException && (err.name === "TimeoutError" || err.name === "AbortError") ? "timeout" : "network";
13940
- return { cause, message: String(err) };
13939
+ function toFetchError(err2) {
13940
+ const cause = err2 instanceof DOMException && (err2.name === "TimeoutError" || err2.name === "AbortError") ? "timeout" : "network";
13941
+ return { cause, message: String(err2) };
13941
13942
  }
13942
13943
  function fetchSafe(url2, init) {
13943
13944
  return ResultAsync.fromPromise(fetch(url2, init), toFetchError);
@@ -14003,6 +14004,9 @@ function getOpenAPI(origin, headers, signal, specificationOverrideUrl) {
14003
14004
  }
14004
14005
 
14005
14006
  // src/core/source/wellknown/index.ts
14007
+ import { ok, err, ResultAsync as ResultAsync5 } from "neverthrow";
14008
+
14009
+ // src/core/source/wellknown/x402.ts
14006
14010
  import { okAsync as okAsync2, ResultAsync as ResultAsync3 } from "neverthrow";
14007
14011
  function toWellKnownParsed(origin, doc) {
14008
14012
  const routes = doc.resources.flatMap((entry) => {
@@ -14029,12 +14033,17 @@ async function parseBody2(response, origin, url2) {
14029
14033
  if (!doc.success) return null;
14030
14034
  const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed(origin, doc.data));
14031
14035
  if (!parsed.success) return null;
14032
- return { raw: payload, ...parsed.data, fetchedUrl: url2 };
14036
+ return {
14037
+ raw: payload,
14038
+ ...parsed.data,
14039
+ protocol: "x402",
14040
+ fetchedUrl: url2
14041
+ };
14033
14042
  } catch {
14034
14043
  return null;
14035
14044
  }
14036
14045
  }
14037
- function getWellKnown(origin, headers, signal) {
14046
+ function getX402WellKnown(origin, headers, signal) {
14038
14047
  const url2 = `${origin}/.well-known/x402`;
14039
14048
  return fetchSafe(url2, {
14040
14049
  method: "GET",
@@ -14046,6 +14055,127 @@ function getWellKnown(origin, headers, signal) {
14046
14055
  });
14047
14056
  }
14048
14057
 
14058
+ // src/core/source/wellknown/mpp.ts
14059
+ import { okAsync as okAsync3, ResultAsync as ResultAsync4 } from "neverthrow";
14060
+ var MppEndpointSchema = external_exports.object({
14061
+ method: external_exports.string(),
14062
+ path: external_exports.string(),
14063
+ description: external_exports.string().optional(),
14064
+ payment: external_exports.object({
14065
+ intent: external_exports.string().optional(),
14066
+ method: external_exports.string().optional(),
14067
+ amount: external_exports.string().optional(),
14068
+ currency: external_exports.string().optional()
14069
+ }).optional()
14070
+ });
14071
+ var MppWellKnownDocSchema = external_exports.object({
14072
+ version: external_exports.number().optional(),
14073
+ name: external_exports.string().optional(),
14074
+ description: external_exports.string().optional(),
14075
+ categories: external_exports.array(external_exports.string()).optional(),
14076
+ methods: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
14077
+ endpoints: external_exports.array(MppEndpointSchema).default([]),
14078
+ docs: external_exports.object({
14079
+ homepage: external_exports.string().optional(),
14080
+ apiReference: external_exports.string().optional()
14081
+ }).optional()
14082
+ });
14083
+ var MPP_DECIMALS = 6;
14084
+ function formatMppAmount(raw) {
14085
+ if (!raw) return void 0;
14086
+ const n = Number(raw);
14087
+ if (!Number.isFinite(n)) return void 0;
14088
+ return `$${(n / 10 ** MPP_DECIMALS).toFixed(MPP_DECIMALS)}`;
14089
+ }
14090
+ function toWellKnownParsed2(doc) {
14091
+ const routes = doc.endpoints.flatMap((entry) => {
14092
+ const method = parseMethod(entry.method);
14093
+ if (!method) return [];
14094
+ const path = normalizePath(entry.path);
14095
+ if (!path) return [];
14096
+ const price = formatMppAmount(entry.payment?.amount);
14097
+ return [{ path, method, ...price ? { price } : {} }];
14098
+ });
14099
+ return {
14100
+ routes,
14101
+ ...doc.description ? { instructions: doc.description } : {}
14102
+ };
14103
+ }
14104
+ async function parseBody3(response, url2) {
14105
+ try {
14106
+ const payload = await response.json();
14107
+ const doc = MppWellKnownDocSchema.safeParse(payload);
14108
+ if (!doc.success) return null;
14109
+ const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed2(doc.data));
14110
+ if (!parsed.success) return null;
14111
+ return {
14112
+ raw: payload,
14113
+ ...parsed.data,
14114
+ ...doc.data.name ? { title: doc.data.name } : {},
14115
+ ...doc.data.description ? { description: doc.data.description } : {},
14116
+ protocol: "mpp",
14117
+ fetchedUrl: url2
14118
+ };
14119
+ } catch {
14120
+ return null;
14121
+ }
14122
+ }
14123
+ function getMppWellKnown(origin, headers, signal) {
14124
+ const url2 = `${origin}/.well-known/mpp`;
14125
+ return fetchSafe(url2, {
14126
+ method: "GET",
14127
+ headers: { Accept: "application/json", ...headers },
14128
+ signal
14129
+ }).andThen((response) => {
14130
+ if (!response.ok) return okAsync3(null);
14131
+ return ResultAsync4.fromSafePromise(parseBody3(response, url2));
14132
+ });
14133
+ }
14134
+
14135
+ // src/core/source/wellknown/index.ts
14136
+ function mergeError(a, b) {
14137
+ return {
14138
+ cause: a.cause === "network" || b.cause === "network" ? "network" : "timeout",
14139
+ message: `x402: ${a.message} | mpp: ${b.message}`
14140
+ };
14141
+ }
14142
+ function merge2(x402, mpp) {
14143
+ const seen = /* @__PURE__ */ new Set();
14144
+ const routes = [...x402.routes, ...mpp.routes].filter((r) => {
14145
+ const key = `${r.method} ${r.path}`;
14146
+ if (seen.has(key)) return false;
14147
+ seen.add(key);
14148
+ return true;
14149
+ });
14150
+ return {
14151
+ raw: { ...mpp.raw, ...x402.raw },
14152
+ routes,
14153
+ protocol: "x402+mpp",
14154
+ // Prefer x402 instructions; fall back to mpp
14155
+ ...x402.instructions || mpp.instructions ? { instructions: x402.instructions ?? mpp.instructions } : {},
14156
+ fetchedUrl: x402.fetchedUrl
14157
+ };
14158
+ }
14159
+ function getWellKnown(origin, headers, signal) {
14160
+ return new ResultAsync5(
14161
+ Promise.all([
14162
+ getX402WellKnown(origin, headers, signal),
14163
+ getMppWellKnown(origin, headers, signal)
14164
+ ]).then(([x402Result, mppResult]) => {
14165
+ const x402 = x402Result.isOk() ? x402Result.value : null;
14166
+ const mpp = mppResult.isOk() ? mppResult.value : null;
14167
+ if (x402 && mpp) return ok(merge2(x402, mpp));
14168
+ if (x402) return ok(x402);
14169
+ if (mpp) return ok(mpp);
14170
+ if (x402Result.isErr() && mppResult.isErr())
14171
+ return err(mergeError(x402Result.error, mppResult.error));
14172
+ if (x402Result.isErr()) return err(x402Result.error);
14173
+ if (mppResult.isErr()) return err(mppResult.error);
14174
+ return ok(null);
14175
+ })
14176
+ );
14177
+ }
14178
+
14049
14179
  // src/core/layers/l2.ts
14050
14180
  function formatPrice(pricing) {
14051
14181
  if (pricing.pricingMode === "fixed") return `$${pricing.price}`;
@@ -14071,15 +14201,27 @@ function checkL2ForOpenAPI(openApi) {
14071
14201
  source: "openapi"
14072
14202
  };
14073
14203
  }
14204
+ var WELL_KNOWN_PROTOCOLS = {
14205
+ x402: ["x402"],
14206
+ mpp: ["mpp"],
14207
+ "x402+mpp": ["x402", "mpp"]
14208
+ };
14074
14209
  function checkL2ForWellknown(wellKnown) {
14210
+ const protocols = WELL_KNOWN_PROTOCOLS[wellKnown.protocol];
14075
14211
  const routes = wellKnown.routes.map((route) => ({
14076
14212
  path: route.path,
14077
14213
  method: route.method,
14078
14214
  summary: `${route.method} ${route.path}`,
14079
14215
  authMode: "paid",
14080
- protocols: ["x402"]
14216
+ protocols,
14217
+ ...route.price ? { price: route.price } : {}
14081
14218
  }));
14082
- return { routes, source: "well-known/x402" };
14219
+ return {
14220
+ ...wellKnown.title ? { title: wellKnown.title } : {},
14221
+ ...wellKnown.description ? { description: wellKnown.description } : {},
14222
+ routes,
14223
+ source: `well-known/${wellKnown.protocol}`
14224
+ };
14083
14225
  }
14084
14226
 
14085
14227
  // src/core/layers/l4.ts
@@ -14091,7 +14233,7 @@ function checkL4ForOpenAPI(openApi) {
14091
14233
  }
14092
14234
  function checkL4ForWellknown(wellKnown) {
14093
14235
  if (wellKnown.instructions) {
14094
- return { guidance: wellKnown.instructions, source: "well-known/x402" };
14236
+ return { guidance: wellKnown.instructions, source: `well-known/${wellKnown.protocol}` };
14095
14237
  }
14096
14238
  return null;
14097
14239
  }
@@ -15043,7 +15185,7 @@ function getWarningsForL4(l4) {
15043
15185
  }
15044
15186
 
15045
15187
  // src/core/source/probe/index.ts
15046
- import { ResultAsync as ResultAsync4 } from "neverthrow";
15188
+ import { ResultAsync as ResultAsync6 } from "neverthrow";
15047
15189
 
15048
15190
  // src/core/protocols/x402/index.ts
15049
15191
  function parseVersion(payload) {
@@ -15139,8 +15281,8 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
15139
15281
  ...hasBody ? { body: JSON.stringify(inputBody) } : {},
15140
15282
  signal
15141
15283
  }).andThen((response) => {
15142
- if (!isUsableStatus(response.status)) return ResultAsync4.fromSafePromise(Promise.resolve(null));
15143
- return ResultAsync4.fromSafePromise(
15284
+ if (!isUsableStatus(response.status)) return ResultAsync6.fromSafePromise(Promise.resolve(null));
15285
+ return ResultAsync6.fromSafePromise(
15144
15286
  (async () => {
15145
15287
  let authHint = response.status === 402 ? "paid" : "unprotected";
15146
15288
  let paymentRequiredBody;
@@ -15171,7 +15313,7 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
15171
15313
  }
15172
15314
  function getProbe(url2, headers, signal, inputBody) {
15173
15315
  const path = normalizePath(new URL(url2).pathname || "/");
15174
- return ResultAsync4.fromSafePromise(
15316
+ return ResultAsync6.fromSafePromise(
15175
15317
  Promise.all(
15176
15318
  [...HTTP_METHODS].map(
15177
15319
  (method) => probeMethod(url2, method, path, headers, signal, inputBody).match(
@@ -15184,6 +15326,20 @@ function getProbe(url2, headers, signal, inputBody) {
15184
15326
  }
15185
15327
 
15186
15328
  // src/core/protocols/mpp/index.ts
15329
+ import { Result } from "neverthrow";
15330
+ function parseBase64Json(encoded) {
15331
+ return Result.fromThrowable(
15332
+ () => {
15333
+ const decoded = typeof Buffer !== "undefined" ? Buffer.from(encoded, "base64").toString("utf8") : atob(encoded);
15334
+ const parsed = JSON.parse(decoded);
15335
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
15336
+ throw new Error("not an object");
15337
+ }
15338
+ return parsed;
15339
+ },
15340
+ (e) => e
15341
+ )();
15342
+ }
15187
15343
  var TEMPO_DEFAULT_CHAIN_ID = 4217;
15188
15344
  function parseAuthParams2(segment) {
15189
15345
  const params = {};
@@ -15206,14 +15362,9 @@ function extractPaymentOptions4(wwwAuthenticate) {
15206
15362
  const description = params["description"];
15207
15363
  const requestStr = params["request"];
15208
15364
  if (!paymentMethod || !intent || !realm || !requestStr) continue;
15209
- let request;
15210
- try {
15211
- const parsed = JSON.parse(requestStr);
15212
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
15213
- request = parsed;
15214
- } catch {
15215
- continue;
15216
- }
15365
+ const requestResult = parseBase64Json(requestStr);
15366
+ if (requestResult.isErr()) continue;
15367
+ const request = requestResult.value;
15217
15368
  const asset = typeof request["currency"] === "string" ? request["currency"] : void 0;
15218
15369
  const amountRaw = request["amount"];
15219
15370
  const amount = typeof amountRaw === "string" ? amountRaw : typeof amountRaw === "number" ? String(amountRaw) : void 0;
@@ -15587,12 +15738,14 @@ ${l4.guidance}`);
15587
15738
  warnings.push(...l3WarningArrays.flat());
15588
15739
  if (flags.json) {
15589
15740
  const meta3 = { origin, specUrl: wellKnown.fetchedUrl };
15741
+ if (l2.title) meta3.title = l2.title;
15742
+ if (l2.description) meta3.description = l2.description;
15590
15743
  if (l4 && flags.verbose) meta3.guidance = l4.guidance;
15591
15744
  console.log(
15592
15745
  JSON.stringify(
15593
15746
  {
15594
15747
  ok: true,
15595
- selectedStage: "well-known/x402",
15748
+ selectedStage: l2.source,
15596
15749
  resources: l2.routes.map(routeToResource),
15597
15750
  warnings,
15598
15751
  trace: [],
@@ -15604,12 +15757,15 @@ ${l4.guidance}`);
15604
15757
  );
15605
15758
  return 0;
15606
15759
  }
15607
- console.log(`Source: well-known/x402`);
15760
+ console.log(`Source: ${l2.source}`);
15608
15761
  console.log(`Spec: ${wellKnown.fetchedUrl}`);
15762
+ if (l2.title) console.log(`API: ${l2.title}`);
15609
15763
  console.log(`Routes: ${l2.routes.length}
15610
15764
  `);
15611
15765
  for (const route of l2.routes) {
15612
- console.log(` ${route.method.padEnd(7)} ${route.path} paid [x402]`);
15766
+ const price = route.price ? ` ${route.price}` : "";
15767
+ const protocols = route.protocols?.length ? ` [${route.protocols.join(", ")}]` : "";
15768
+ console.log(` ${route.method.padEnd(7)} ${route.path} paid${price}${protocols}`);
15613
15769
  }
15614
15770
  } else {
15615
15771
  if (flags.json) {