@agentcash/discovery 1.2.0 → 1.4.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 +213 -28
- package/dist/cli.js +213 -28
- package/dist/index.cjs +251 -27
- package/dist/index.d.cts +38 -5
- package/dist/index.d.ts +38 -5
- package/dist/index.js +248 -27
- package/dist/schemas.cjs +2 -1
- package/dist/schemas.d.cts +1 -0
- package/dist/schemas.d.ts +1 -0
- package/dist/schemas.js +2 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
getL3: () => getL3,
|
|
45
45
|
getL3ForOpenAPI: () => getL3ForOpenAPI,
|
|
46
46
|
getL3ForProbe: () => getL3ForProbe,
|
|
47
|
+
getMppWellKnown: () => getMppWellKnown,
|
|
47
48
|
getOpenAPI: () => getOpenAPI,
|
|
48
49
|
getProbe: () => getProbe,
|
|
49
50
|
getWarningsFor402Body: () => getWarningsFor402Body,
|
|
@@ -54,6 +55,8 @@ __export(index_exports, {
|
|
|
54
55
|
getWarningsForOpenAPI: () => getWarningsForOpenAPI,
|
|
55
56
|
getWarningsForWellKnown: () => getWarningsForWellKnown,
|
|
56
57
|
getWellKnown: () => getWellKnown,
|
|
58
|
+
getX402WellKnown: () => getX402WellKnown,
|
|
59
|
+
isOpenApiParseFailure: () => isOpenApiParseFailure,
|
|
57
60
|
validatePaymentRequiredDetailed: () => validatePaymentRequiredDetailed
|
|
58
61
|
});
|
|
59
62
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -13896,7 +13899,8 @@ var WellKnownParsedSchema = external_exports.object({
|
|
|
13896
13899
|
routes: external_exports.array(
|
|
13897
13900
|
external_exports.object({
|
|
13898
13901
|
path: external_exports.string(),
|
|
13899
|
-
method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"])
|
|
13902
|
+
method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"]),
|
|
13903
|
+
price: external_exports.string().optional()
|
|
13900
13904
|
})
|
|
13901
13905
|
),
|
|
13902
13906
|
instructions: external_exports.string().optional()
|
|
@@ -13989,9 +13993,9 @@ function toAbsoluteUrl(origin, value) {
|
|
|
13989
13993
|
|
|
13990
13994
|
// src/core/source/fetch.ts
|
|
13991
13995
|
var import_neverthrow = require("neverthrow");
|
|
13992
|
-
function toFetchError(
|
|
13993
|
-
const cause =
|
|
13994
|
-
return { cause, message: String(
|
|
13996
|
+
function toFetchError(err2) {
|
|
13997
|
+
const cause = err2 instanceof DOMException && (err2.name === "TimeoutError" || err2.name === "AbortError") ? "timeout" : "network";
|
|
13998
|
+
return { cause, message: String(err2) };
|
|
13995
13999
|
}
|
|
13996
14000
|
function fetchSafe(url2, init) {
|
|
13997
14001
|
return import_neverthrow.ResultAsync.fromPromise(fetch(url2, init), toFetchError);
|
|
@@ -14038,7 +14042,13 @@ async function parseBody(response, url2) {
|
|
|
14038
14042
|
try {
|
|
14039
14043
|
const payload = await response.json();
|
|
14040
14044
|
const parsed = OpenApiParsedSchema.safeParse(payload);
|
|
14041
|
-
if (!parsed.success)
|
|
14045
|
+
if (!parsed.success) {
|
|
14046
|
+
return {
|
|
14047
|
+
parseFailure: true,
|
|
14048
|
+
fetchedUrl: url2,
|
|
14049
|
+
issues: parsed.error.issues.map((i) => ({ path: i.path, message: i.message }))
|
|
14050
|
+
};
|
|
14051
|
+
}
|
|
14042
14052
|
return { raw: payload, ...parsed.data, fetchedUrl: url2 };
|
|
14043
14053
|
} catch {
|
|
14044
14054
|
return null;
|
|
@@ -14057,6 +14067,9 @@ function getOpenAPI(origin, headers, signal, specificationOverrideUrl) {
|
|
|
14057
14067
|
}
|
|
14058
14068
|
|
|
14059
14069
|
// src/core/source/wellknown/index.ts
|
|
14070
|
+
var import_neverthrow5 = require("neverthrow");
|
|
14071
|
+
|
|
14072
|
+
// src/core/source/wellknown/x402.ts
|
|
14060
14073
|
var import_neverthrow3 = require("neverthrow");
|
|
14061
14074
|
function toWellKnownParsed(origin, doc) {
|
|
14062
14075
|
const routes = doc.resources.flatMap((entry) => {
|
|
@@ -14083,12 +14096,17 @@ async function parseBody2(response, origin, url2) {
|
|
|
14083
14096
|
if (!doc.success) return null;
|
|
14084
14097
|
const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed(origin, doc.data));
|
|
14085
14098
|
if (!parsed.success) return null;
|
|
14086
|
-
return {
|
|
14099
|
+
return {
|
|
14100
|
+
raw: payload,
|
|
14101
|
+
...parsed.data,
|
|
14102
|
+
protocol: "x402",
|
|
14103
|
+
fetchedUrl: url2
|
|
14104
|
+
};
|
|
14087
14105
|
} catch {
|
|
14088
14106
|
return null;
|
|
14089
14107
|
}
|
|
14090
14108
|
}
|
|
14091
|
-
function
|
|
14109
|
+
function getX402WellKnown(origin, headers, signal) {
|
|
14092
14110
|
const url2 = `${origin}/.well-known/x402`;
|
|
14093
14111
|
return fetchSafe(url2, {
|
|
14094
14112
|
method: "GET",
|
|
@@ -14100,6 +14118,127 @@ function getWellKnown(origin, headers, signal) {
|
|
|
14100
14118
|
});
|
|
14101
14119
|
}
|
|
14102
14120
|
|
|
14121
|
+
// src/core/source/wellknown/mpp.ts
|
|
14122
|
+
var import_neverthrow4 = require("neverthrow");
|
|
14123
|
+
var MppEndpointSchema = external_exports.object({
|
|
14124
|
+
method: external_exports.string(),
|
|
14125
|
+
path: external_exports.string(),
|
|
14126
|
+
description: external_exports.string().optional(),
|
|
14127
|
+
payment: external_exports.object({
|
|
14128
|
+
intent: external_exports.string().optional(),
|
|
14129
|
+
method: external_exports.string().optional(),
|
|
14130
|
+
amount: external_exports.string().optional(),
|
|
14131
|
+
currency: external_exports.string().optional()
|
|
14132
|
+
}).optional()
|
|
14133
|
+
});
|
|
14134
|
+
var MppWellKnownDocSchema = external_exports.object({
|
|
14135
|
+
version: external_exports.number().optional(),
|
|
14136
|
+
name: external_exports.string().optional(),
|
|
14137
|
+
description: external_exports.string().optional(),
|
|
14138
|
+
categories: external_exports.array(external_exports.string()).optional(),
|
|
14139
|
+
methods: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
14140
|
+
endpoints: external_exports.array(MppEndpointSchema).default([]),
|
|
14141
|
+
docs: external_exports.object({
|
|
14142
|
+
homepage: external_exports.string().optional(),
|
|
14143
|
+
apiReference: external_exports.string().optional()
|
|
14144
|
+
}).optional()
|
|
14145
|
+
});
|
|
14146
|
+
var MPP_DECIMALS = 6;
|
|
14147
|
+
function formatMppAmount(raw) {
|
|
14148
|
+
if (!raw) return void 0;
|
|
14149
|
+
const n = Number(raw);
|
|
14150
|
+
if (!Number.isFinite(n)) return void 0;
|
|
14151
|
+
return `$${(n / 10 ** MPP_DECIMALS).toFixed(MPP_DECIMALS)}`;
|
|
14152
|
+
}
|
|
14153
|
+
function toWellKnownParsed2(doc) {
|
|
14154
|
+
const routes = doc.endpoints.flatMap((entry) => {
|
|
14155
|
+
const method = parseMethod(entry.method);
|
|
14156
|
+
if (!method) return [];
|
|
14157
|
+
const path = normalizePath(entry.path);
|
|
14158
|
+
if (!path) return [];
|
|
14159
|
+
const price = formatMppAmount(entry.payment?.amount);
|
|
14160
|
+
return [{ path, method, ...price ? { price } : {} }];
|
|
14161
|
+
});
|
|
14162
|
+
return {
|
|
14163
|
+
routes,
|
|
14164
|
+
...doc.description ? { instructions: doc.description } : {}
|
|
14165
|
+
};
|
|
14166
|
+
}
|
|
14167
|
+
async function parseBody3(response, url2) {
|
|
14168
|
+
try {
|
|
14169
|
+
const payload = await response.json();
|
|
14170
|
+
const doc = MppWellKnownDocSchema.safeParse(payload);
|
|
14171
|
+
if (!doc.success) return null;
|
|
14172
|
+
const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed2(doc.data));
|
|
14173
|
+
if (!parsed.success) return null;
|
|
14174
|
+
return {
|
|
14175
|
+
raw: payload,
|
|
14176
|
+
...parsed.data,
|
|
14177
|
+
...doc.data.name ? { title: doc.data.name } : {},
|
|
14178
|
+
...doc.data.description ? { description: doc.data.description } : {},
|
|
14179
|
+
protocol: "mpp",
|
|
14180
|
+
fetchedUrl: url2
|
|
14181
|
+
};
|
|
14182
|
+
} catch {
|
|
14183
|
+
return null;
|
|
14184
|
+
}
|
|
14185
|
+
}
|
|
14186
|
+
function getMppWellKnown(origin, headers, signal) {
|
|
14187
|
+
const url2 = `${origin}/.well-known/mpp`;
|
|
14188
|
+
return fetchSafe(url2, {
|
|
14189
|
+
method: "GET",
|
|
14190
|
+
headers: { Accept: "application/json", ...headers },
|
|
14191
|
+
signal
|
|
14192
|
+
}).andThen((response) => {
|
|
14193
|
+
if (!response.ok) return (0, import_neverthrow4.okAsync)(null);
|
|
14194
|
+
return import_neverthrow4.ResultAsync.fromSafePromise(parseBody3(response, url2));
|
|
14195
|
+
});
|
|
14196
|
+
}
|
|
14197
|
+
|
|
14198
|
+
// src/core/source/wellknown/index.ts
|
|
14199
|
+
function mergeError(a, b) {
|
|
14200
|
+
return {
|
|
14201
|
+
cause: a.cause === "network" || b.cause === "network" ? "network" : "timeout",
|
|
14202
|
+
message: `x402: ${a.message} | mpp: ${b.message}`
|
|
14203
|
+
};
|
|
14204
|
+
}
|
|
14205
|
+
function merge2(x402, mpp) {
|
|
14206
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14207
|
+
const routes = [...x402.routes, ...mpp.routes].filter((r) => {
|
|
14208
|
+
const key = `${r.method} ${r.path}`;
|
|
14209
|
+
if (seen.has(key)) return false;
|
|
14210
|
+
seen.add(key);
|
|
14211
|
+
return true;
|
|
14212
|
+
});
|
|
14213
|
+
return {
|
|
14214
|
+
raw: { ...mpp.raw, ...x402.raw },
|
|
14215
|
+
routes,
|
|
14216
|
+
protocol: "x402+mpp",
|
|
14217
|
+
// Prefer x402 instructions; fall back to mpp
|
|
14218
|
+
...x402.instructions || mpp.instructions ? { instructions: x402.instructions ?? mpp.instructions } : {},
|
|
14219
|
+
fetchedUrl: x402.fetchedUrl
|
|
14220
|
+
};
|
|
14221
|
+
}
|
|
14222
|
+
function getWellKnown(origin, headers, signal) {
|
|
14223
|
+
return new import_neverthrow5.ResultAsync(
|
|
14224
|
+
Promise.all([
|
|
14225
|
+
getX402WellKnown(origin, headers, signal),
|
|
14226
|
+
getMppWellKnown(origin, headers, signal)
|
|
14227
|
+
]).then(([x402Result, mppResult]) => {
|
|
14228
|
+
const x402 = x402Result.isOk() ? x402Result.value : null;
|
|
14229
|
+
const mpp = mppResult.isOk() ? mppResult.value : null;
|
|
14230
|
+
if (x402 && mpp) return (0, import_neverthrow5.ok)(merge2(x402, mpp));
|
|
14231
|
+
if (x402) return (0, import_neverthrow5.ok)(x402);
|
|
14232
|
+
if (mpp) return (0, import_neverthrow5.ok)(mpp);
|
|
14233
|
+
if (x402Result.isErr() && mppResult.isErr())
|
|
14234
|
+
return (0, import_neverthrow5.err)(mergeError(x402Result.error, mppResult.error));
|
|
14235
|
+
if (x402Result.isErr()) return (0, import_neverthrow5.err)(x402Result.error);
|
|
14236
|
+
if (mppResult.isErr()) return (0, import_neverthrow5.err)(mppResult.error);
|
|
14237
|
+
return (0, import_neverthrow5.ok)(null);
|
|
14238
|
+
})
|
|
14239
|
+
);
|
|
14240
|
+
}
|
|
14241
|
+
|
|
14103
14242
|
// src/core/layers/l2.ts
|
|
14104
14243
|
function formatPrice(pricing) {
|
|
14105
14244
|
if (pricing.pricingMode === "fixed") return `$${pricing.price}`;
|
|
@@ -14125,15 +14264,27 @@ function checkL2ForOpenAPI(openApi) {
|
|
|
14125
14264
|
source: "openapi"
|
|
14126
14265
|
};
|
|
14127
14266
|
}
|
|
14267
|
+
var WELL_KNOWN_PROTOCOLS = {
|
|
14268
|
+
x402: ["x402"],
|
|
14269
|
+
mpp: ["mpp"],
|
|
14270
|
+
"x402+mpp": ["x402", "mpp"]
|
|
14271
|
+
};
|
|
14128
14272
|
function checkL2ForWellknown(wellKnown) {
|
|
14273
|
+
const protocols = WELL_KNOWN_PROTOCOLS[wellKnown.protocol];
|
|
14129
14274
|
const routes = wellKnown.routes.map((route) => ({
|
|
14130
14275
|
path: route.path,
|
|
14131
14276
|
method: route.method,
|
|
14132
14277
|
summary: `${route.method} ${route.path}`,
|
|
14133
14278
|
authMode: "paid",
|
|
14134
|
-
protocols
|
|
14279
|
+
protocols,
|
|
14280
|
+
...route.price ? { price: route.price } : {}
|
|
14135
14281
|
}));
|
|
14136
|
-
return {
|
|
14282
|
+
return {
|
|
14283
|
+
...wellKnown.title ? { title: wellKnown.title } : {},
|
|
14284
|
+
...wellKnown.description ? { description: wellKnown.description } : {},
|
|
14285
|
+
routes,
|
|
14286
|
+
source: `well-known/${wellKnown.protocol}`
|
|
14287
|
+
};
|
|
14137
14288
|
}
|
|
14138
14289
|
|
|
14139
14290
|
// src/core/layers/l4.ts
|
|
@@ -14145,7 +14296,7 @@ function checkL4ForOpenAPI(openApi) {
|
|
|
14145
14296
|
}
|
|
14146
14297
|
function checkL4ForWellknown(wellKnown) {
|
|
14147
14298
|
if (wellKnown.instructions) {
|
|
14148
|
-
return { guidance: wellKnown.instructions, source:
|
|
14299
|
+
return { guidance: wellKnown.instructions, source: `well-known/${wellKnown.protocol}` };
|
|
14149
14300
|
}
|
|
14150
14301
|
return null;
|
|
14151
14302
|
}
|
|
@@ -14163,8 +14314,41 @@ var GuidanceMode = /* @__PURE__ */ ((GuidanceMode2) => {
|
|
|
14163
14314
|
return GuidanceMode2;
|
|
14164
14315
|
})(GuidanceMode || {});
|
|
14165
14316
|
|
|
14317
|
+
// src/core/types/sources.ts
|
|
14318
|
+
function isOpenApiSource(raw) {
|
|
14319
|
+
return raw !== null && !("parseFailure" in raw);
|
|
14320
|
+
}
|
|
14321
|
+
|
|
14166
14322
|
// src/runtime/discover.ts
|
|
14167
14323
|
var GUIDANCE_AUTO_INCLUDE_MAX_TOKENS_LENGTH = 1e3;
|
|
14324
|
+
function extractFromWellknown(raw) {
|
|
14325
|
+
if (Array.isArray(raw["ownershipProofs"])) {
|
|
14326
|
+
const proofs = raw["ownershipProofs"].filter(
|
|
14327
|
+
(p) => typeof p === "string"
|
|
14328
|
+
);
|
|
14329
|
+
if (proofs.length > 0) return proofs;
|
|
14330
|
+
}
|
|
14331
|
+
return void 0;
|
|
14332
|
+
}
|
|
14333
|
+
function extractFromOpenapi(raw) {
|
|
14334
|
+
const xDiscovery = raw["x-discovery"];
|
|
14335
|
+
if (xDiscovery && typeof xDiscovery === "object" && !Array.isArray(xDiscovery)) {
|
|
14336
|
+
const proofs = xDiscovery["ownershipProofs"];
|
|
14337
|
+
if (Array.isArray(proofs)) {
|
|
14338
|
+
const filtered = proofs.filter((p) => typeof p === "string");
|
|
14339
|
+
if (filtered.length > 0) return filtered;
|
|
14340
|
+
}
|
|
14341
|
+
}
|
|
14342
|
+
const legacy = raw["x-agentcash-provenance"];
|
|
14343
|
+
if (legacy && typeof legacy === "object" && !Array.isArray(legacy)) {
|
|
14344
|
+
const proofs = legacy["ownershipProofs"];
|
|
14345
|
+
if (Array.isArray(proofs)) {
|
|
14346
|
+
const filtered = proofs.filter((p) => typeof p === "string");
|
|
14347
|
+
if (filtered.length > 0) return filtered;
|
|
14348
|
+
}
|
|
14349
|
+
}
|
|
14350
|
+
return void 0;
|
|
14351
|
+
}
|
|
14168
14352
|
function withGuidance(base, l4, guidanceMode) {
|
|
14169
14353
|
if (guidanceMode === "never" /* Never */) return { ...base, guidanceAvailable: !!l4 };
|
|
14170
14354
|
if (!l4) return { ...base, guidanceAvailable: false };
|
|
@@ -14183,10 +14367,12 @@ async function discoverOriginSchema(options) {
|
|
|
14183
14367
|
options.signal,
|
|
14184
14368
|
options.specificationOverrideUrl
|
|
14185
14369
|
);
|
|
14186
|
-
const
|
|
14370
|
+
const openApiRaw = openApiResult.isOk() ? openApiResult.value : null;
|
|
14371
|
+
const openApi = isOpenApiSource(openApiRaw) ? openApiRaw : null;
|
|
14187
14372
|
if (openApi) {
|
|
14188
14373
|
const l22 = checkL2ForOpenAPI(openApi);
|
|
14189
14374
|
const l42 = checkL4ForOpenAPI(openApi);
|
|
14375
|
+
const ownershipProofs2 = extractFromOpenapi(openApi.raw);
|
|
14190
14376
|
const base2 = {
|
|
14191
14377
|
found: true,
|
|
14192
14378
|
origin,
|
|
@@ -14198,7 +14384,8 @@ async function discoverOriginSchema(options) {
|
|
|
14198
14384
|
...l22.version ? { version: l22.version } : {}
|
|
14199
14385
|
}
|
|
14200
14386
|
} : {},
|
|
14201
|
-
endpoints: l22.routes
|
|
14387
|
+
endpoints: l22.routes,
|
|
14388
|
+
...ownershipProofs2 ? { ownershipProofs: ownershipProofs2 } : {}
|
|
14202
14389
|
};
|
|
14203
14390
|
return withGuidance(base2, l42, guidanceMode);
|
|
14204
14391
|
}
|
|
@@ -14215,17 +14402,25 @@ async function discoverOriginSchema(options) {
|
|
|
14215
14402
|
if (!wellKnown) return { found: false, origin, cause: "not_found" };
|
|
14216
14403
|
const l2 = checkL2ForWellknown(wellKnown);
|
|
14217
14404
|
const l4 = checkL4ForWellknown(wellKnown);
|
|
14405
|
+
const ownershipProofs = extractFromWellknown(wellKnown.raw);
|
|
14218
14406
|
const base = {
|
|
14219
14407
|
found: true,
|
|
14220
14408
|
origin,
|
|
14221
|
-
source:
|
|
14222
|
-
|
|
14409
|
+
source: l2.source,
|
|
14410
|
+
...l2.title ? {
|
|
14411
|
+
info: {
|
|
14412
|
+
title: l2.title,
|
|
14413
|
+
...l2.description ? { description: l2.description } : {}
|
|
14414
|
+
}
|
|
14415
|
+
} : {},
|
|
14416
|
+
endpoints: l2.routes,
|
|
14417
|
+
...ownershipProofs ? { ownershipProofs } : {}
|
|
14223
14418
|
};
|
|
14224
14419
|
return withGuidance(base, l4, guidanceMode);
|
|
14225
14420
|
}
|
|
14226
14421
|
|
|
14227
14422
|
// src/core/source/probe/index.ts
|
|
14228
|
-
var
|
|
14423
|
+
var import_neverthrow6 = require("neverthrow");
|
|
14229
14424
|
|
|
14230
14425
|
// src/core/protocols/x402/v1/schema.ts
|
|
14231
14426
|
function extractSchemas(accepts) {
|
|
@@ -14675,8 +14870,8 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
|
|
|
14675
14870
|
...hasBody ? { body: JSON.stringify(inputBody) } : {},
|
|
14676
14871
|
signal
|
|
14677
14872
|
}).andThen((response) => {
|
|
14678
|
-
if (!isUsableStatus(response.status)) return
|
|
14679
|
-
return
|
|
14873
|
+
if (!isUsableStatus(response.status)) return import_neverthrow6.ResultAsync.fromSafePromise(Promise.resolve(null));
|
|
14874
|
+
return import_neverthrow6.ResultAsync.fromSafePromise(
|
|
14680
14875
|
(async () => {
|
|
14681
14876
|
let authHint = response.status === 402 ? "paid" : "unprotected";
|
|
14682
14877
|
let paymentRequiredBody;
|
|
@@ -14707,7 +14902,7 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
|
|
|
14707
14902
|
}
|
|
14708
14903
|
function getProbe(url2, headers, signal, inputBody) {
|
|
14709
14904
|
const path = normalizePath(new URL(url2).pathname || "/");
|
|
14710
|
-
return
|
|
14905
|
+
return import_neverthrow6.ResultAsync.fromSafePromise(
|
|
14711
14906
|
Promise.all(
|
|
14712
14907
|
[...HTTP_METHODS].map(
|
|
14713
14908
|
(method) => probeMethod(url2, method, path, headers, signal, inputBody).match(
|
|
@@ -14720,6 +14915,20 @@ function getProbe(url2, headers, signal, inputBody) {
|
|
|
14720
14915
|
}
|
|
14721
14916
|
|
|
14722
14917
|
// src/core/protocols/mpp/index.ts
|
|
14918
|
+
var import_neverthrow7 = require("neverthrow");
|
|
14919
|
+
function parseBase64Json(encoded) {
|
|
14920
|
+
return import_neverthrow7.Result.fromThrowable(
|
|
14921
|
+
() => {
|
|
14922
|
+
const decoded = typeof Buffer !== "undefined" ? Buffer.from(encoded, "base64").toString("utf8") : atob(encoded);
|
|
14923
|
+
const parsed = JSON.parse(decoded);
|
|
14924
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
14925
|
+
throw new Error("not an object");
|
|
14926
|
+
}
|
|
14927
|
+
return parsed;
|
|
14928
|
+
},
|
|
14929
|
+
(e) => e
|
|
14930
|
+
)();
|
|
14931
|
+
}
|
|
14723
14932
|
var TEMPO_DEFAULT_CHAIN_ID = 4217;
|
|
14724
14933
|
function parseAuthParams(segment) {
|
|
14725
14934
|
const params = {};
|
|
@@ -14742,14 +14951,9 @@ function extractPaymentOptions4(wwwAuthenticate) {
|
|
|
14742
14951
|
const description = params["description"];
|
|
14743
14952
|
const requestStr = params["request"];
|
|
14744
14953
|
if (!paymentMethod || !intent || !realm || !requestStr) continue;
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
|
|
14749
|
-
request = parsed;
|
|
14750
|
-
} catch {
|
|
14751
|
-
continue;
|
|
14752
|
-
}
|
|
14954
|
+
const requestResult = parseBase64Json(requestStr);
|
|
14955
|
+
if (requestResult.isErr()) continue;
|
|
14956
|
+
const request = requestResult.value;
|
|
14753
14957
|
const asset = typeof request["currency"] === "string" ? request["currency"] : void 0;
|
|
14754
14958
|
const amountRaw = request["amount"];
|
|
14755
14959
|
const amount = typeof amountRaw === "string" ? amountRaw : typeof amountRaw === "number" ? String(amountRaw) : void 0;
|
|
@@ -14988,7 +15192,8 @@ async function checkEndpointSchema(options) {
|
|
|
14988
15192
|
return { found: false, origin, path, cause: "not_found" };
|
|
14989
15193
|
}
|
|
14990
15194
|
const openApiResult = await getOpenAPI(origin, options.headers, options.signal);
|
|
14991
|
-
const
|
|
15195
|
+
const openApiRaw = openApiResult.isOk() ? openApiResult.value : null;
|
|
15196
|
+
const openApi = isOpenApiSource(openApiRaw) ? openApiRaw : null;
|
|
14992
15197
|
if (openApi) {
|
|
14993
15198
|
const advisories2 = getAdvisoriesForOpenAPI(openApi, path);
|
|
14994
15199
|
if (advisories2.length > 0) return { found: true, origin, path, advisories: advisories2 };
|
|
@@ -15099,6 +15304,7 @@ var AUDIT_CODES = {
|
|
|
15099
15304
|
OPENAPI_NOT_FOUND: "OPENAPI_NOT_FOUND",
|
|
15100
15305
|
WELLKNOWN_NOT_FOUND: "WELLKNOWN_NOT_FOUND",
|
|
15101
15306
|
// ─── OpenAPI quality ─────────────────────────────────────────────────────────
|
|
15307
|
+
OPENAPI_PARSE_ERROR: "OPENAPI_PARSE_ERROR",
|
|
15102
15308
|
OPENAPI_NO_ROUTES: "OPENAPI_NO_ROUTES",
|
|
15103
15309
|
// ─── L2 route-list checks ────────────────────────────────────────────────────
|
|
15104
15310
|
L2_NO_ROUTES: "L2_NO_ROUTES",
|
|
@@ -15586,6 +15792,9 @@ function validatePaymentRequiredDetailed(payload, options = {}) {
|
|
|
15586
15792
|
}
|
|
15587
15793
|
|
|
15588
15794
|
// src/audit/warnings/sources.ts
|
|
15795
|
+
function isOpenApiParseFailure(value) {
|
|
15796
|
+
return value !== null && "parseFailure" in value;
|
|
15797
|
+
}
|
|
15589
15798
|
function getWarningsForOpenAPI(openApi) {
|
|
15590
15799
|
if (openApi === null) {
|
|
15591
15800
|
return [
|
|
@@ -15597,6 +15806,18 @@ function getWarningsForOpenAPI(openApi) {
|
|
|
15597
15806
|
}
|
|
15598
15807
|
];
|
|
15599
15808
|
}
|
|
15809
|
+
if (isOpenApiParseFailure(openApi)) {
|
|
15810
|
+
const details = openApi.issues.map((i) => ` ${i.path.map(String).join(".")}: ${i.message}`).join("\n");
|
|
15811
|
+
return [
|
|
15812
|
+
{
|
|
15813
|
+
code: AUDIT_CODES.OPENAPI_PARSE_ERROR,
|
|
15814
|
+
severity: "warn",
|
|
15815
|
+
message: `OpenAPI spec found at ${openApi.fetchedUrl} but failed schema validation:
|
|
15816
|
+
${details}`,
|
|
15817
|
+
hint: "Fix the schema issues above so discovery can read the spec."
|
|
15818
|
+
}
|
|
15819
|
+
];
|
|
15820
|
+
}
|
|
15600
15821
|
const warnings = [];
|
|
15601
15822
|
if (openApi.routes.length === 0) {
|
|
15602
15823
|
warnings.push({
|
|
@@ -15738,6 +15959,7 @@ function getWarningsForL4(l4) {
|
|
|
15738
15959
|
getL3,
|
|
15739
15960
|
getL3ForOpenAPI,
|
|
15740
15961
|
getL3ForProbe,
|
|
15962
|
+
getMppWellKnown,
|
|
15741
15963
|
getOpenAPI,
|
|
15742
15964
|
getProbe,
|
|
15743
15965
|
getWarningsFor402Body,
|
|
@@ -15748,5 +15970,7 @@ function getWarningsForL4(l4) {
|
|
|
15748
15970
|
getWarningsForOpenAPI,
|
|
15749
15971
|
getWarningsForWellKnown,
|
|
15750
15972
|
getWellKnown,
|
|
15973
|
+
getX402WellKnown,
|
|
15974
|
+
isOpenApiParseFailure,
|
|
15751
15975
|
validatePaymentRequiredDetailed
|
|
15752
15976
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -78,6 +78,15 @@ interface OpenApiSource {
|
|
|
78
78
|
guidance?: string;
|
|
79
79
|
fetchedUrl: string;
|
|
80
80
|
}
|
|
81
|
+
/** Returned when the spec was fetched successfully but failed schema validation. */
|
|
82
|
+
interface OpenApiParseFailure {
|
|
83
|
+
parseFailure: true;
|
|
84
|
+
fetchedUrl: string;
|
|
85
|
+
issues: Array<{
|
|
86
|
+
path: (string | number | symbol)[];
|
|
87
|
+
message: string;
|
|
88
|
+
}>;
|
|
89
|
+
}
|
|
81
90
|
interface OpenApiRoute {
|
|
82
91
|
path: string;
|
|
83
92
|
method: HttpMethod;
|
|
@@ -89,12 +98,18 @@ interface OpenApiRoute {
|
|
|
89
98
|
interface WellKnownSource {
|
|
90
99
|
raw: Record<string, unknown>;
|
|
91
100
|
routes: WellKnownRoute[];
|
|
101
|
+
title?: string;
|
|
102
|
+
description?: string;
|
|
92
103
|
instructions?: string;
|
|
93
104
|
fetchedUrl: string;
|
|
105
|
+
/** Which well-known document(s) this source was built from. */
|
|
106
|
+
protocol: 'x402' | 'mpp' | 'x402+mpp';
|
|
94
107
|
}
|
|
95
108
|
interface WellKnownRoute {
|
|
96
109
|
path: string;
|
|
97
110
|
method: HttpMethod;
|
|
111
|
+
/** Raw price hint from the well-known document (e.g. MPP `payment.amount`). */
|
|
112
|
+
price?: string;
|
|
98
113
|
}
|
|
99
114
|
interface ProbeResult {
|
|
100
115
|
path: string;
|
|
@@ -111,7 +126,7 @@ interface L2Result {
|
|
|
111
126
|
description?: string;
|
|
112
127
|
version?: string;
|
|
113
128
|
routes: L2Route[];
|
|
114
|
-
source: 'openapi' | 'well-known/x402' | null;
|
|
129
|
+
source: 'openapi' | 'well-known/x402' | 'well-known/mpp' | 'well-known/x402+mpp' | null;
|
|
115
130
|
}
|
|
116
131
|
interface L2Route {
|
|
117
132
|
path: string;
|
|
@@ -145,7 +160,7 @@ interface L3Result {
|
|
|
145
160
|
}
|
|
146
161
|
interface L4Result {
|
|
147
162
|
guidance: string;
|
|
148
|
-
source: 'openapi' | 'well-known/x402';
|
|
163
|
+
source: 'openapi' | 'well-known/x402' | 'well-known/mpp' | 'well-known/x402+mpp';
|
|
149
164
|
}
|
|
150
165
|
|
|
151
166
|
declare enum GuidanceMode {
|
|
@@ -182,6 +197,8 @@ interface DiscoverOriginSchemaSuccess {
|
|
|
182
197
|
guidanceTokens?: number;
|
|
183
198
|
/** Guidance text. Included when short enough (auto mode) or guidance='always'. */
|
|
184
199
|
guidance?: string;
|
|
200
|
+
/** Ownership proof strings collected from the discovery document, if any. */
|
|
201
|
+
ownershipProofs?: string[];
|
|
185
202
|
}
|
|
186
203
|
interface DiscoverOriginSchemaNotFound {
|
|
187
204
|
found: false;
|
|
@@ -239,10 +256,23 @@ interface FetchError {
|
|
|
239
256
|
message: string;
|
|
240
257
|
}
|
|
241
258
|
|
|
242
|
-
declare function getOpenAPI(origin: string, headers?: Record<string, string>, signal?: AbortSignal, specificationOverrideUrl?: string): ResultAsync<OpenApiSource | null, FetchError>;
|
|
259
|
+
declare function getOpenAPI(origin: string, headers?: Record<string, string>, signal?: AbortSignal, specificationOverrideUrl?: string): ResultAsync<OpenApiSource | OpenApiParseFailure | null, FetchError>;
|
|
243
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Fetches both `/.well-known/x402` and `/.well-known/mpp` in parallel and merges results.
|
|
263
|
+
*
|
|
264
|
+
* In practice these are mutually exclusive, but if both exist their routes are combined
|
|
265
|
+
* (deduplicated by method+path). x402 wins on instruction/fetchedUrl conflicts.
|
|
266
|
+
*
|
|
267
|
+
* Individual leg failures are treated as "not found" for that leg so valid data from
|
|
268
|
+
* the other is never suppressed. Returns Err(FetchError) only when both legs hard-fail.
|
|
269
|
+
*/
|
|
244
270
|
declare function getWellKnown(origin: string, headers?: Record<string, string>, signal?: AbortSignal): ResultAsync<WellKnownSource | null, FetchError>;
|
|
245
271
|
|
|
272
|
+
declare function getX402WellKnown(origin: string, headers?: Record<string, string>, signal?: AbortSignal): ResultAsync<WellKnownSource | null, FetchError>;
|
|
273
|
+
|
|
274
|
+
declare function getMppWellKnown(origin: string, headers?: Record<string, string>, signal?: AbortSignal): ResultAsync<WellKnownSource | null, FetchError>;
|
|
275
|
+
|
|
246
276
|
declare function getProbe(url: string, headers?: Record<string, string>, signal?: AbortSignal, inputBody?: Record<string, unknown>): ResultAsync<ProbeResult[], FetchError>;
|
|
247
277
|
|
|
248
278
|
declare function checkL2ForOpenAPI(openApi: OpenApiSource): L2Result;
|
|
@@ -354,6 +384,7 @@ declare function validatePaymentRequiredDetailed(payload: unknown, options?: Val
|
|
|
354
384
|
declare const AUDIT_CODES: {
|
|
355
385
|
readonly OPENAPI_NOT_FOUND: "OPENAPI_NOT_FOUND";
|
|
356
386
|
readonly WELLKNOWN_NOT_FOUND: "WELLKNOWN_NOT_FOUND";
|
|
387
|
+
readonly OPENAPI_PARSE_ERROR: "OPENAPI_PARSE_ERROR";
|
|
357
388
|
readonly OPENAPI_NO_ROUTES: "OPENAPI_NO_ROUTES";
|
|
358
389
|
readonly L2_NO_ROUTES: "L2_NO_ROUTES";
|
|
359
390
|
readonly L2_ROUTE_COUNT_HIGH: "L2_ROUTE_COUNT_HIGH";
|
|
@@ -394,7 +425,9 @@ interface AuditWarning {
|
|
|
394
425
|
path?: string;
|
|
395
426
|
}
|
|
396
427
|
|
|
397
|
-
|
|
428
|
+
/** Type guard: true when the value is a parse-failure sentinel (spec fetched but invalid). */
|
|
429
|
+
declare function isOpenApiParseFailure(value: OpenApiSource | OpenApiParseFailure | null): value is OpenApiParseFailure;
|
|
430
|
+
declare function getWarningsForOpenAPI(openApi: OpenApiSource | OpenApiParseFailure | null): AuditWarning[];
|
|
398
431
|
declare function getWarningsForWellKnown(wellKnown: WellKnownSource | null): AuditWarning[];
|
|
399
432
|
|
|
400
433
|
declare function getWarningsForL2(l2: L2Result): AuditWarning[];
|
|
@@ -424,4 +457,4 @@ declare function getWarningsForL4(l4: L4Result | null): AuditWarning[];
|
|
|
424
457
|
*/
|
|
425
458
|
declare function getWarningsForMppHeader(wwwAuthenticate: string | null | undefined): AuditWarning[];
|
|
426
459
|
|
|
427
|
-
export { AUDIT_CODES, type AuditCode, type AuditSeverity, type AuditWarning, type AuthMode, type CheckEndpointNotFound, type CheckEndpointOptions, type CheckEndpointResult, type CheckEndpointSuccess, type DiscoverOriginSchemaNotFound, type DiscoverOriginSchemaOptions, type DiscoverOriginSchemaResult, type DiscoverOriginSchemaSuccess, type EndpointMethodAdvisory, GuidanceMode, type HttpMethod, type L2Result, type L2Route, type L3Result, type L4Result, type MetadataPreview, type MppPaymentOption, type NormalizedAccept, type NormalizedPaymentRequired, type OpenApiRoute, type OpenApiSource, type PaymentOption, type PricingMode, type ProbeResult, type TrustTier, VALIDATION_CODES, type ValidatePaymentRequiredDetailedResult, type ValidatePaymentRequiredOptions, type ValidationIssue, type ValidationSeverity, type ValidationStage, type ValidationSummary, type WellKnownRoute, type WellKnownSource, type X402PaymentOption, type X402V1PaymentOption, type X402V2PaymentOption, attachProbePayload, checkEndpointSchema, checkL2ForOpenAPI, checkL2ForWellknown, checkL4ForOpenAPI, checkL4ForWellknown, discoverOriginSchema, evaluateMetadataCompleteness, getL3, getL3ForOpenAPI, getL3ForProbe, getOpenAPI, getProbe, getWarningsFor402Body, getWarningsForL2, getWarningsForL3, getWarningsForL4, getWarningsForMppHeader, getWarningsForOpenAPI, getWarningsForWellKnown, getWellKnown, validatePaymentRequiredDetailed };
|
|
460
|
+
export { AUDIT_CODES, type AuditCode, type AuditSeverity, type AuditWarning, type AuthMode, type CheckEndpointNotFound, type CheckEndpointOptions, type CheckEndpointResult, type CheckEndpointSuccess, type DiscoverOriginSchemaNotFound, type DiscoverOriginSchemaOptions, type DiscoverOriginSchemaResult, type DiscoverOriginSchemaSuccess, type EndpointMethodAdvisory, GuidanceMode, type HttpMethod, type L2Result, type L2Route, type L3Result, type L4Result, type MetadataPreview, type MppPaymentOption, type NormalizedAccept, type NormalizedPaymentRequired, type OpenApiParseFailure, type OpenApiRoute, type OpenApiSource, type PaymentOption, type PricingMode, type ProbeResult, type TrustTier, VALIDATION_CODES, type ValidatePaymentRequiredDetailedResult, type ValidatePaymentRequiredOptions, type ValidationIssue, type ValidationSeverity, type ValidationStage, type ValidationSummary, type WellKnownRoute, type WellKnownSource, type X402PaymentOption, type X402V1PaymentOption, type X402V2PaymentOption, attachProbePayload, checkEndpointSchema, checkL2ForOpenAPI, checkL2ForWellknown, checkL4ForOpenAPI, checkL4ForWellknown, discoverOriginSchema, evaluateMetadataCompleteness, getL3, getL3ForOpenAPI, getL3ForProbe, getMppWellKnown, getOpenAPI, getProbe, getWarningsFor402Body, getWarningsForL2, getWarningsForL3, getWarningsForL4, getWarningsForMppHeader, getWarningsForOpenAPI, getWarningsForWellKnown, getWellKnown, getX402WellKnown, isOpenApiParseFailure, validatePaymentRequiredDetailed };
|