@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.d.ts
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 };
|
package/dist/index.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(
|
|
13939
|
-
const cause =
|
|
13940
|
-
return { cause, message: String(
|
|
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);
|
|
@@ -13984,7 +13985,13 @@ async function parseBody(response, url2) {
|
|
|
13984
13985
|
try {
|
|
13985
13986
|
const payload = await response.json();
|
|
13986
13987
|
const parsed = OpenApiParsedSchema.safeParse(payload);
|
|
13987
|
-
if (!parsed.success)
|
|
13988
|
+
if (!parsed.success) {
|
|
13989
|
+
return {
|
|
13990
|
+
parseFailure: true,
|
|
13991
|
+
fetchedUrl: url2,
|
|
13992
|
+
issues: parsed.error.issues.map((i) => ({ path: i.path, message: i.message }))
|
|
13993
|
+
};
|
|
13994
|
+
}
|
|
13988
13995
|
return { raw: payload, ...parsed.data, fetchedUrl: url2 };
|
|
13989
13996
|
} catch {
|
|
13990
13997
|
return null;
|
|
@@ -14003,6 +14010,9 @@ function getOpenAPI(origin, headers, signal, specificationOverrideUrl) {
|
|
|
14003
14010
|
}
|
|
14004
14011
|
|
|
14005
14012
|
// src/core/source/wellknown/index.ts
|
|
14013
|
+
import { ok, err, ResultAsync as ResultAsync5 } from "neverthrow";
|
|
14014
|
+
|
|
14015
|
+
// src/core/source/wellknown/x402.ts
|
|
14006
14016
|
import { okAsync as okAsync2, ResultAsync as ResultAsync3 } from "neverthrow";
|
|
14007
14017
|
function toWellKnownParsed(origin, doc) {
|
|
14008
14018
|
const routes = doc.resources.flatMap((entry) => {
|
|
@@ -14029,12 +14039,17 @@ async function parseBody2(response, origin, url2) {
|
|
|
14029
14039
|
if (!doc.success) return null;
|
|
14030
14040
|
const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed(origin, doc.data));
|
|
14031
14041
|
if (!parsed.success) return null;
|
|
14032
|
-
return {
|
|
14042
|
+
return {
|
|
14043
|
+
raw: payload,
|
|
14044
|
+
...parsed.data,
|
|
14045
|
+
protocol: "x402",
|
|
14046
|
+
fetchedUrl: url2
|
|
14047
|
+
};
|
|
14033
14048
|
} catch {
|
|
14034
14049
|
return null;
|
|
14035
14050
|
}
|
|
14036
14051
|
}
|
|
14037
|
-
function
|
|
14052
|
+
function getX402WellKnown(origin, headers, signal) {
|
|
14038
14053
|
const url2 = `${origin}/.well-known/x402`;
|
|
14039
14054
|
return fetchSafe(url2, {
|
|
14040
14055
|
method: "GET",
|
|
@@ -14046,6 +14061,127 @@ function getWellKnown(origin, headers, signal) {
|
|
|
14046
14061
|
});
|
|
14047
14062
|
}
|
|
14048
14063
|
|
|
14064
|
+
// src/core/source/wellknown/mpp.ts
|
|
14065
|
+
import { okAsync as okAsync3, ResultAsync as ResultAsync4 } from "neverthrow";
|
|
14066
|
+
var MppEndpointSchema = external_exports.object({
|
|
14067
|
+
method: external_exports.string(),
|
|
14068
|
+
path: external_exports.string(),
|
|
14069
|
+
description: external_exports.string().optional(),
|
|
14070
|
+
payment: external_exports.object({
|
|
14071
|
+
intent: external_exports.string().optional(),
|
|
14072
|
+
method: external_exports.string().optional(),
|
|
14073
|
+
amount: external_exports.string().optional(),
|
|
14074
|
+
currency: external_exports.string().optional()
|
|
14075
|
+
}).optional()
|
|
14076
|
+
});
|
|
14077
|
+
var MppWellKnownDocSchema = external_exports.object({
|
|
14078
|
+
version: external_exports.number().optional(),
|
|
14079
|
+
name: external_exports.string().optional(),
|
|
14080
|
+
description: external_exports.string().optional(),
|
|
14081
|
+
categories: external_exports.array(external_exports.string()).optional(),
|
|
14082
|
+
methods: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
14083
|
+
endpoints: external_exports.array(MppEndpointSchema).default([]),
|
|
14084
|
+
docs: external_exports.object({
|
|
14085
|
+
homepage: external_exports.string().optional(),
|
|
14086
|
+
apiReference: external_exports.string().optional()
|
|
14087
|
+
}).optional()
|
|
14088
|
+
});
|
|
14089
|
+
var MPP_DECIMALS = 6;
|
|
14090
|
+
function formatMppAmount(raw) {
|
|
14091
|
+
if (!raw) return void 0;
|
|
14092
|
+
const n = Number(raw);
|
|
14093
|
+
if (!Number.isFinite(n)) return void 0;
|
|
14094
|
+
return `$${(n / 10 ** MPP_DECIMALS).toFixed(MPP_DECIMALS)}`;
|
|
14095
|
+
}
|
|
14096
|
+
function toWellKnownParsed2(doc) {
|
|
14097
|
+
const routes = doc.endpoints.flatMap((entry) => {
|
|
14098
|
+
const method = parseMethod(entry.method);
|
|
14099
|
+
if (!method) return [];
|
|
14100
|
+
const path = normalizePath(entry.path);
|
|
14101
|
+
if (!path) return [];
|
|
14102
|
+
const price = formatMppAmount(entry.payment?.amount);
|
|
14103
|
+
return [{ path, method, ...price ? { price } : {} }];
|
|
14104
|
+
});
|
|
14105
|
+
return {
|
|
14106
|
+
routes,
|
|
14107
|
+
...doc.description ? { instructions: doc.description } : {}
|
|
14108
|
+
};
|
|
14109
|
+
}
|
|
14110
|
+
async function parseBody3(response, url2) {
|
|
14111
|
+
try {
|
|
14112
|
+
const payload = await response.json();
|
|
14113
|
+
const doc = MppWellKnownDocSchema.safeParse(payload);
|
|
14114
|
+
if (!doc.success) return null;
|
|
14115
|
+
const parsed = WellKnownParsedSchema.safeParse(toWellKnownParsed2(doc.data));
|
|
14116
|
+
if (!parsed.success) return null;
|
|
14117
|
+
return {
|
|
14118
|
+
raw: payload,
|
|
14119
|
+
...parsed.data,
|
|
14120
|
+
...doc.data.name ? { title: doc.data.name } : {},
|
|
14121
|
+
...doc.data.description ? { description: doc.data.description } : {},
|
|
14122
|
+
protocol: "mpp",
|
|
14123
|
+
fetchedUrl: url2
|
|
14124
|
+
};
|
|
14125
|
+
} catch {
|
|
14126
|
+
return null;
|
|
14127
|
+
}
|
|
14128
|
+
}
|
|
14129
|
+
function getMppWellKnown(origin, headers, signal) {
|
|
14130
|
+
const url2 = `${origin}/.well-known/mpp`;
|
|
14131
|
+
return fetchSafe(url2, {
|
|
14132
|
+
method: "GET",
|
|
14133
|
+
headers: { Accept: "application/json", ...headers },
|
|
14134
|
+
signal
|
|
14135
|
+
}).andThen((response) => {
|
|
14136
|
+
if (!response.ok) return okAsync3(null);
|
|
14137
|
+
return ResultAsync4.fromSafePromise(parseBody3(response, url2));
|
|
14138
|
+
});
|
|
14139
|
+
}
|
|
14140
|
+
|
|
14141
|
+
// src/core/source/wellknown/index.ts
|
|
14142
|
+
function mergeError(a, b) {
|
|
14143
|
+
return {
|
|
14144
|
+
cause: a.cause === "network" || b.cause === "network" ? "network" : "timeout",
|
|
14145
|
+
message: `x402: ${a.message} | mpp: ${b.message}`
|
|
14146
|
+
};
|
|
14147
|
+
}
|
|
14148
|
+
function merge2(x402, mpp) {
|
|
14149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14150
|
+
const routes = [...x402.routes, ...mpp.routes].filter((r) => {
|
|
14151
|
+
const key = `${r.method} ${r.path}`;
|
|
14152
|
+
if (seen.has(key)) return false;
|
|
14153
|
+
seen.add(key);
|
|
14154
|
+
return true;
|
|
14155
|
+
});
|
|
14156
|
+
return {
|
|
14157
|
+
raw: { ...mpp.raw, ...x402.raw },
|
|
14158
|
+
routes,
|
|
14159
|
+
protocol: "x402+mpp",
|
|
14160
|
+
// Prefer x402 instructions; fall back to mpp
|
|
14161
|
+
...x402.instructions || mpp.instructions ? { instructions: x402.instructions ?? mpp.instructions } : {},
|
|
14162
|
+
fetchedUrl: x402.fetchedUrl
|
|
14163
|
+
};
|
|
14164
|
+
}
|
|
14165
|
+
function getWellKnown(origin, headers, signal) {
|
|
14166
|
+
return new ResultAsync5(
|
|
14167
|
+
Promise.all([
|
|
14168
|
+
getX402WellKnown(origin, headers, signal),
|
|
14169
|
+
getMppWellKnown(origin, headers, signal)
|
|
14170
|
+
]).then(([x402Result, mppResult]) => {
|
|
14171
|
+
const x402 = x402Result.isOk() ? x402Result.value : null;
|
|
14172
|
+
const mpp = mppResult.isOk() ? mppResult.value : null;
|
|
14173
|
+
if (x402 && mpp) return ok(merge2(x402, mpp));
|
|
14174
|
+
if (x402) return ok(x402);
|
|
14175
|
+
if (mpp) return ok(mpp);
|
|
14176
|
+
if (x402Result.isErr() && mppResult.isErr())
|
|
14177
|
+
return err(mergeError(x402Result.error, mppResult.error));
|
|
14178
|
+
if (x402Result.isErr()) return err(x402Result.error);
|
|
14179
|
+
if (mppResult.isErr()) return err(mppResult.error);
|
|
14180
|
+
return ok(null);
|
|
14181
|
+
})
|
|
14182
|
+
);
|
|
14183
|
+
}
|
|
14184
|
+
|
|
14049
14185
|
// src/core/layers/l2.ts
|
|
14050
14186
|
function formatPrice(pricing) {
|
|
14051
14187
|
if (pricing.pricingMode === "fixed") return `$${pricing.price}`;
|
|
@@ -14071,15 +14207,27 @@ function checkL2ForOpenAPI(openApi) {
|
|
|
14071
14207
|
source: "openapi"
|
|
14072
14208
|
};
|
|
14073
14209
|
}
|
|
14210
|
+
var WELL_KNOWN_PROTOCOLS = {
|
|
14211
|
+
x402: ["x402"],
|
|
14212
|
+
mpp: ["mpp"],
|
|
14213
|
+
"x402+mpp": ["x402", "mpp"]
|
|
14214
|
+
};
|
|
14074
14215
|
function checkL2ForWellknown(wellKnown) {
|
|
14216
|
+
const protocols = WELL_KNOWN_PROTOCOLS[wellKnown.protocol];
|
|
14075
14217
|
const routes = wellKnown.routes.map((route) => ({
|
|
14076
14218
|
path: route.path,
|
|
14077
14219
|
method: route.method,
|
|
14078
14220
|
summary: `${route.method} ${route.path}`,
|
|
14079
14221
|
authMode: "paid",
|
|
14080
|
-
protocols
|
|
14222
|
+
protocols,
|
|
14223
|
+
...route.price ? { price: route.price } : {}
|
|
14081
14224
|
}));
|
|
14082
|
-
return {
|
|
14225
|
+
return {
|
|
14226
|
+
...wellKnown.title ? { title: wellKnown.title } : {},
|
|
14227
|
+
...wellKnown.description ? { description: wellKnown.description } : {},
|
|
14228
|
+
routes,
|
|
14229
|
+
source: `well-known/${wellKnown.protocol}`
|
|
14230
|
+
};
|
|
14083
14231
|
}
|
|
14084
14232
|
|
|
14085
14233
|
// src/core/layers/l4.ts
|
|
@@ -14091,7 +14239,7 @@ function checkL4ForOpenAPI(openApi) {
|
|
|
14091
14239
|
}
|
|
14092
14240
|
function checkL4ForWellknown(wellKnown) {
|
|
14093
14241
|
if (wellKnown.instructions) {
|
|
14094
|
-
return { guidance: wellKnown.instructions, source:
|
|
14242
|
+
return { guidance: wellKnown.instructions, source: `well-known/${wellKnown.protocol}` };
|
|
14095
14243
|
}
|
|
14096
14244
|
return null;
|
|
14097
14245
|
}
|
|
@@ -14109,8 +14257,41 @@ var GuidanceMode = /* @__PURE__ */ ((GuidanceMode2) => {
|
|
|
14109
14257
|
return GuidanceMode2;
|
|
14110
14258
|
})(GuidanceMode || {});
|
|
14111
14259
|
|
|
14260
|
+
// src/core/types/sources.ts
|
|
14261
|
+
function isOpenApiSource(raw) {
|
|
14262
|
+
return raw !== null && !("parseFailure" in raw);
|
|
14263
|
+
}
|
|
14264
|
+
|
|
14112
14265
|
// src/runtime/discover.ts
|
|
14113
14266
|
var GUIDANCE_AUTO_INCLUDE_MAX_TOKENS_LENGTH = 1e3;
|
|
14267
|
+
function extractFromWellknown(raw) {
|
|
14268
|
+
if (Array.isArray(raw["ownershipProofs"])) {
|
|
14269
|
+
const proofs = raw["ownershipProofs"].filter(
|
|
14270
|
+
(p) => typeof p === "string"
|
|
14271
|
+
);
|
|
14272
|
+
if (proofs.length > 0) return proofs;
|
|
14273
|
+
}
|
|
14274
|
+
return void 0;
|
|
14275
|
+
}
|
|
14276
|
+
function extractFromOpenapi(raw) {
|
|
14277
|
+
const xDiscovery = raw["x-discovery"];
|
|
14278
|
+
if (xDiscovery && typeof xDiscovery === "object" && !Array.isArray(xDiscovery)) {
|
|
14279
|
+
const proofs = xDiscovery["ownershipProofs"];
|
|
14280
|
+
if (Array.isArray(proofs)) {
|
|
14281
|
+
const filtered = proofs.filter((p) => typeof p === "string");
|
|
14282
|
+
if (filtered.length > 0) return filtered;
|
|
14283
|
+
}
|
|
14284
|
+
}
|
|
14285
|
+
const legacy = raw["x-agentcash-provenance"];
|
|
14286
|
+
if (legacy && typeof legacy === "object" && !Array.isArray(legacy)) {
|
|
14287
|
+
const proofs = legacy["ownershipProofs"];
|
|
14288
|
+
if (Array.isArray(proofs)) {
|
|
14289
|
+
const filtered = proofs.filter((p) => typeof p === "string");
|
|
14290
|
+
if (filtered.length > 0) return filtered;
|
|
14291
|
+
}
|
|
14292
|
+
}
|
|
14293
|
+
return void 0;
|
|
14294
|
+
}
|
|
14114
14295
|
function withGuidance(base, l4, guidanceMode) {
|
|
14115
14296
|
if (guidanceMode === "never" /* Never */) return { ...base, guidanceAvailable: !!l4 };
|
|
14116
14297
|
if (!l4) return { ...base, guidanceAvailable: false };
|
|
@@ -14129,10 +14310,12 @@ async function discoverOriginSchema(options) {
|
|
|
14129
14310
|
options.signal,
|
|
14130
14311
|
options.specificationOverrideUrl
|
|
14131
14312
|
);
|
|
14132
|
-
const
|
|
14313
|
+
const openApiRaw = openApiResult.isOk() ? openApiResult.value : null;
|
|
14314
|
+
const openApi = isOpenApiSource(openApiRaw) ? openApiRaw : null;
|
|
14133
14315
|
if (openApi) {
|
|
14134
14316
|
const l22 = checkL2ForOpenAPI(openApi);
|
|
14135
14317
|
const l42 = checkL4ForOpenAPI(openApi);
|
|
14318
|
+
const ownershipProofs2 = extractFromOpenapi(openApi.raw);
|
|
14136
14319
|
const base2 = {
|
|
14137
14320
|
found: true,
|
|
14138
14321
|
origin,
|
|
@@ -14144,7 +14327,8 @@ async function discoverOriginSchema(options) {
|
|
|
14144
14327
|
...l22.version ? { version: l22.version } : {}
|
|
14145
14328
|
}
|
|
14146
14329
|
} : {},
|
|
14147
|
-
endpoints: l22.routes
|
|
14330
|
+
endpoints: l22.routes,
|
|
14331
|
+
...ownershipProofs2 ? { ownershipProofs: ownershipProofs2 } : {}
|
|
14148
14332
|
};
|
|
14149
14333
|
return withGuidance(base2, l42, guidanceMode);
|
|
14150
14334
|
}
|
|
@@ -14161,17 +14345,25 @@ async function discoverOriginSchema(options) {
|
|
|
14161
14345
|
if (!wellKnown) return { found: false, origin, cause: "not_found" };
|
|
14162
14346
|
const l2 = checkL2ForWellknown(wellKnown);
|
|
14163
14347
|
const l4 = checkL4ForWellknown(wellKnown);
|
|
14348
|
+
const ownershipProofs = extractFromWellknown(wellKnown.raw);
|
|
14164
14349
|
const base = {
|
|
14165
14350
|
found: true,
|
|
14166
14351
|
origin,
|
|
14167
|
-
source:
|
|
14168
|
-
|
|
14352
|
+
source: l2.source,
|
|
14353
|
+
...l2.title ? {
|
|
14354
|
+
info: {
|
|
14355
|
+
title: l2.title,
|
|
14356
|
+
...l2.description ? { description: l2.description } : {}
|
|
14357
|
+
}
|
|
14358
|
+
} : {},
|
|
14359
|
+
endpoints: l2.routes,
|
|
14360
|
+
...ownershipProofs ? { ownershipProofs } : {}
|
|
14169
14361
|
};
|
|
14170
14362
|
return withGuidance(base, l4, guidanceMode);
|
|
14171
14363
|
}
|
|
14172
14364
|
|
|
14173
14365
|
// src/core/source/probe/index.ts
|
|
14174
|
-
import { ResultAsync as
|
|
14366
|
+
import { ResultAsync as ResultAsync6 } from "neverthrow";
|
|
14175
14367
|
|
|
14176
14368
|
// src/core/protocols/x402/v1/schema.ts
|
|
14177
14369
|
function extractSchemas(accepts) {
|
|
@@ -14621,8 +14813,8 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
|
|
|
14621
14813
|
...hasBody ? { body: JSON.stringify(inputBody) } : {},
|
|
14622
14814
|
signal
|
|
14623
14815
|
}).andThen((response) => {
|
|
14624
|
-
if (!isUsableStatus(response.status)) return
|
|
14625
|
-
return
|
|
14816
|
+
if (!isUsableStatus(response.status)) return ResultAsync6.fromSafePromise(Promise.resolve(null));
|
|
14817
|
+
return ResultAsync6.fromSafePromise(
|
|
14626
14818
|
(async () => {
|
|
14627
14819
|
let authHint = response.status === 402 ? "paid" : "unprotected";
|
|
14628
14820
|
let paymentRequiredBody;
|
|
@@ -14653,7 +14845,7 @@ function probeMethod(url2, method, path, headers, signal, inputBody) {
|
|
|
14653
14845
|
}
|
|
14654
14846
|
function getProbe(url2, headers, signal, inputBody) {
|
|
14655
14847
|
const path = normalizePath(new URL(url2).pathname || "/");
|
|
14656
|
-
return
|
|
14848
|
+
return ResultAsync6.fromSafePromise(
|
|
14657
14849
|
Promise.all(
|
|
14658
14850
|
[...HTTP_METHODS].map(
|
|
14659
14851
|
(method) => probeMethod(url2, method, path, headers, signal, inputBody).match(
|
|
@@ -14666,6 +14858,20 @@ function getProbe(url2, headers, signal, inputBody) {
|
|
|
14666
14858
|
}
|
|
14667
14859
|
|
|
14668
14860
|
// src/core/protocols/mpp/index.ts
|
|
14861
|
+
import { Result } from "neverthrow";
|
|
14862
|
+
function parseBase64Json(encoded) {
|
|
14863
|
+
return Result.fromThrowable(
|
|
14864
|
+
() => {
|
|
14865
|
+
const decoded = typeof Buffer !== "undefined" ? Buffer.from(encoded, "base64").toString("utf8") : atob(encoded);
|
|
14866
|
+
const parsed = JSON.parse(decoded);
|
|
14867
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
14868
|
+
throw new Error("not an object");
|
|
14869
|
+
}
|
|
14870
|
+
return parsed;
|
|
14871
|
+
},
|
|
14872
|
+
(e) => e
|
|
14873
|
+
)();
|
|
14874
|
+
}
|
|
14669
14875
|
var TEMPO_DEFAULT_CHAIN_ID = 4217;
|
|
14670
14876
|
function parseAuthParams(segment) {
|
|
14671
14877
|
const params = {};
|
|
@@ -14688,14 +14894,9 @@ function extractPaymentOptions4(wwwAuthenticate) {
|
|
|
14688
14894
|
const description = params["description"];
|
|
14689
14895
|
const requestStr = params["request"];
|
|
14690
14896
|
if (!paymentMethod || !intent || !realm || !requestStr) continue;
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
|
|
14695
|
-
request = parsed;
|
|
14696
|
-
} catch {
|
|
14697
|
-
continue;
|
|
14698
|
-
}
|
|
14897
|
+
const requestResult = parseBase64Json(requestStr);
|
|
14898
|
+
if (requestResult.isErr()) continue;
|
|
14899
|
+
const request = requestResult.value;
|
|
14699
14900
|
const asset = typeof request["currency"] === "string" ? request["currency"] : void 0;
|
|
14700
14901
|
const amountRaw = request["amount"];
|
|
14701
14902
|
const amount = typeof amountRaw === "string" ? amountRaw : typeof amountRaw === "number" ? String(amountRaw) : void 0;
|
|
@@ -14934,7 +15135,8 @@ async function checkEndpointSchema(options) {
|
|
|
14934
15135
|
return { found: false, origin, path, cause: "not_found" };
|
|
14935
15136
|
}
|
|
14936
15137
|
const openApiResult = await getOpenAPI(origin, options.headers, options.signal);
|
|
14937
|
-
const
|
|
15138
|
+
const openApiRaw = openApiResult.isOk() ? openApiResult.value : null;
|
|
15139
|
+
const openApi = isOpenApiSource(openApiRaw) ? openApiRaw : null;
|
|
14938
15140
|
if (openApi) {
|
|
14939
15141
|
const advisories2 = getAdvisoriesForOpenAPI(openApi, path);
|
|
14940
15142
|
if (advisories2.length > 0) return { found: true, origin, path, advisories: advisories2 };
|
|
@@ -15045,6 +15247,7 @@ var AUDIT_CODES = {
|
|
|
15045
15247
|
OPENAPI_NOT_FOUND: "OPENAPI_NOT_FOUND",
|
|
15046
15248
|
WELLKNOWN_NOT_FOUND: "WELLKNOWN_NOT_FOUND",
|
|
15047
15249
|
// ─── OpenAPI quality ─────────────────────────────────────────────────────────
|
|
15250
|
+
OPENAPI_PARSE_ERROR: "OPENAPI_PARSE_ERROR",
|
|
15048
15251
|
OPENAPI_NO_ROUTES: "OPENAPI_NO_ROUTES",
|
|
15049
15252
|
// ─── L2 route-list checks ────────────────────────────────────────────────────
|
|
15050
15253
|
L2_NO_ROUTES: "L2_NO_ROUTES",
|
|
@@ -15532,6 +15735,9 @@ function validatePaymentRequiredDetailed(payload, options = {}) {
|
|
|
15532
15735
|
}
|
|
15533
15736
|
|
|
15534
15737
|
// src/audit/warnings/sources.ts
|
|
15738
|
+
function isOpenApiParseFailure(value) {
|
|
15739
|
+
return value !== null && "parseFailure" in value;
|
|
15740
|
+
}
|
|
15535
15741
|
function getWarningsForOpenAPI(openApi) {
|
|
15536
15742
|
if (openApi === null) {
|
|
15537
15743
|
return [
|
|
@@ -15543,6 +15749,18 @@ function getWarningsForOpenAPI(openApi) {
|
|
|
15543
15749
|
}
|
|
15544
15750
|
];
|
|
15545
15751
|
}
|
|
15752
|
+
if (isOpenApiParseFailure(openApi)) {
|
|
15753
|
+
const details = openApi.issues.map((i) => ` ${i.path.map(String).join(".")}: ${i.message}`).join("\n");
|
|
15754
|
+
return [
|
|
15755
|
+
{
|
|
15756
|
+
code: AUDIT_CODES.OPENAPI_PARSE_ERROR,
|
|
15757
|
+
severity: "warn",
|
|
15758
|
+
message: `OpenAPI spec found at ${openApi.fetchedUrl} but failed schema validation:
|
|
15759
|
+
${details}`,
|
|
15760
|
+
hint: "Fix the schema issues above so discovery can read the spec."
|
|
15761
|
+
}
|
|
15762
|
+
];
|
|
15763
|
+
}
|
|
15546
15764
|
const warnings = [];
|
|
15547
15765
|
if (openApi.routes.length === 0) {
|
|
15548
15766
|
warnings.push({
|
|
@@ -15683,6 +15901,7 @@ export {
|
|
|
15683
15901
|
getL3,
|
|
15684
15902
|
getL3ForOpenAPI,
|
|
15685
15903
|
getL3ForProbe,
|
|
15904
|
+
getMppWellKnown,
|
|
15686
15905
|
getOpenAPI,
|
|
15687
15906
|
getProbe,
|
|
15688
15907
|
getWarningsFor402Body,
|
|
@@ -15693,5 +15912,7 @@ export {
|
|
|
15693
15912
|
getWarningsForOpenAPI,
|
|
15694
15913
|
getWarningsForWellKnown,
|
|
15695
15914
|
getWellKnown,
|
|
15915
|
+
getX402WellKnown,
|
|
15916
|
+
isOpenApiParseFailure,
|
|
15696
15917
|
validatePaymentRequiredDetailed
|
|
15697
15918
|
};
|
package/dist/schemas.cjs
CHANGED
|
@@ -13864,7 +13864,8 @@ var WellKnownParsedSchema = external_exports.object({
|
|
|
13864
13864
|
routes: external_exports.array(
|
|
13865
13865
|
external_exports.object({
|
|
13866
13866
|
path: external_exports.string(),
|
|
13867
|
-
method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"])
|
|
13867
|
+
method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"]),
|
|
13868
|
+
price: external_exports.string().optional()
|
|
13868
13869
|
})
|
|
13869
13870
|
),
|
|
13870
13871
|
instructions: external_exports.string().optional()
|
package/dist/schemas.d.cts
CHANGED
package/dist/schemas.d.ts
CHANGED
package/dist/schemas.js
CHANGED
|
@@ -13839,7 +13839,8 @@ var WellKnownParsedSchema = external_exports.object({
|
|
|
13839
13839
|
routes: external_exports.array(
|
|
13840
13840
|
external_exports.object({
|
|
13841
13841
|
path: external_exports.string(),
|
|
13842
|
-
method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"])
|
|
13842
|
+
method: external_exports.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"]),
|
|
13843
|
+
price: external_exports.string().optional()
|
|
13843
13844
|
})
|
|
13844
13845
|
),
|
|
13845
13846
|
instructions: external_exports.string().optional()
|