@lemmaoracle/x402 0.1.14 → 0.1.15

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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Lemma wrapper around the upstream x402 paymentMiddleware — v0.2
3
+ *
4
+ * v0.2 changes (vs v0.1 in lemma/#222):
5
+ * 1. Inject Bazaar extension input into the 402 challenge's accepts[].extra
6
+ * so the CDP facilitator auto-indexes the route on first settle.
7
+ * 2. Parse the settle response's EXTENSION-RESPONSES header and emit a
8
+ * structured BazaarStatusEvent for observability (independent of settle
9
+ * outcome — discovery failures never break payment).
10
+ * 3. Validate the "discoverable implies metadata" contract at construction
11
+ * time (assertDiscoverableConfigured).
12
+ *
13
+ * Rationale:
14
+ * - outputs/bazaar-listings/handoff-2026-05-20-register-on-first-settle.md
15
+ * - lemma/#222 residual TODO 1/3
16
+ */
17
+ import type { MiddlewareHandler } from "hono";
18
+ import { type LemmaRouteConfig } from "./routeConfig.js";
19
+ /**
20
+ * Context variables set by the Bazaar middleware so downstream handlers and
21
+ * settle hooks can read them without re-deriving from config.
22
+ */
23
+ export interface BazaarContextVariables {
24
+ "lemma:bazaar:discoverable": boolean;
25
+ "lemma:bazaar:schema": string | undefined;
26
+ "lemma:bazaar:category": LemmaRouteConfig["bazaarCategory"] | undefined;
27
+ "lemma:bazaar:subTags": readonly string[] | undefined;
28
+ }
29
+ /**
30
+ * Drop-in payment middleware for Bazaar-discoverable routes.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * app.use(
35
+ * "/v1/suites/inference/attest",
36
+ * bazaarPaymentMiddleware({
37
+ * accepts: [
38
+ * // standard x402 PaymentOption (recipient, amount, network, ...)
39
+ * ],
40
+ * discoverable: true,
41
+ * schema: "inference-attestation-v1",
42
+ * bazaarCategory: "Inference",
43
+ * bazaarDescription:
44
+ * "For AI agents running their own inference, generate a Groth16 attestation proving which model produced which output, anchored on Base mainnet. Lemma never sees raw data.",
45
+ * bazaarSubTags: ["verifiable-ai", "audit-trail", "claim-check"],
46
+ * bazaarInputSchemaRef: "https://schemas.lemma.frame00.com/bazaar/product-b-input.json",
47
+ * bazaarOutputSchemaRef: "https://schemas.lemma.frame00.com/bazaar/product-b-output.json",
48
+ * })
49
+ * );
50
+ * ```
51
+ */
52
+ export declare const bazaarPaymentMiddleware: (config: LemmaRouteConfig) => MiddlewareHandler;
53
+ //# sourceMappingURL=bazaar-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bazaar-middleware.d.ts","sourceRoot":"","sources":["../src/bazaar-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAW,iBAAiB,EAAQ,MAAM,MAAM,CAAC;AAG7D,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,2BAA2B,EAAE,OAAO,CAAC;IACrC,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,uBAAuB,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC;IACxE,sBAAsB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACvD;AA+DD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,uBAAuB,GAClC,QAAQ,gBAAgB,KACvB,iBAyDF,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { paymentMiddlewareFromConfig as upstreamPaymentMiddleware } from "@x402/hono";
2
+ import { assertDiscoverableConfigured, } from "./routeConfig.js";
3
+ import { getBazaarStatusEmitter, parseBazaarStatus, } from "./bazaar-status-emitter.js";
4
+ const buildBazaarExtensionInput = (config) => {
5
+ // assertDiscoverableConfigured has already guaranteed these are present
6
+ // when discoverable: true; non-null assertions are safe here.
7
+ return {
8
+ name: config.schema,
9
+ description: config.bazaarDescription,
10
+ category: config.bazaarCategory,
11
+ tags: config.bazaarSubTags ?? [],
12
+ inputSchema: config.bazaarInputSchemaRef,
13
+ outputSchema: config.bazaarOutputSchemaRef,
14
+ };
15
+ };
16
+ /**
17
+ * Merge the Bazaar extension input into the upstream config's accepts[].extra.
18
+ * Preserves any other extension already present (forward-compat with future
19
+ * extensions like KYT, sanctions, etc.).
20
+ */
21
+ const injectBazaarExtensionInput = (config) => {
22
+ const bazaar = buildBazaarExtensionInput(config);
23
+ // `accepts` may be undefined or an array per upstream type; we merge into
24
+ // the first element (the active payment scheme).
25
+ const acceptsRaw = config.accepts;
26
+ const accepts = Array.isArray(acceptsRaw) && acceptsRaw.length > 0
27
+ ? acceptsRaw
28
+ : [{}];
29
+ const head = accepts[0] ?? {};
30
+ return {
31
+ ...config,
32
+ accepts: [
33
+ {
34
+ ...head,
35
+ extra: { ...head.extra, bazaar },
36
+ },
37
+ ...accepts.slice(1),
38
+ ],
39
+ };
40
+ };
41
+ /**
42
+ * Drop-in payment middleware for Bazaar-discoverable routes.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * app.use(
47
+ * "/v1/suites/inference/attest",
48
+ * bazaarPaymentMiddleware({
49
+ * accepts: [
50
+ * // standard x402 PaymentOption (recipient, amount, network, ...)
51
+ * ],
52
+ * discoverable: true,
53
+ * schema: "inference-attestation-v1",
54
+ * bazaarCategory: "Inference",
55
+ * bazaarDescription:
56
+ * "For AI agents running their own inference, generate a Groth16 attestation proving which model produced which output, anchored on Base mainnet. Lemma never sees raw data.",
57
+ * bazaarSubTags: ["verifiable-ai", "audit-trail", "claim-check"],
58
+ * bazaarInputSchemaRef: "https://schemas.lemma.frame00.com/bazaar/product-b-input.json",
59
+ * bazaarOutputSchemaRef: "https://schemas.lemma.frame00.com/bazaar/product-b-output.json",
60
+ * })
61
+ * );
62
+ * ```
63
+ */
64
+ export const bazaarPaymentMiddleware = (config) => {
65
+ // Construction-time validation: fail fast if discoverable: true is missing
66
+ // any of its required companion fields. Throws synchronously.
67
+ assertDiscoverableConfigured(config);
68
+ const enrichedConfig = config.discoverable
69
+ ? injectBazaarExtensionInput(config)
70
+ : config;
71
+ const upstream = upstreamPaymentMiddleware(enrichedConfig);
72
+ return async (c, next) => {
73
+ if (config.discoverable) {
74
+ c.set("lemma:bazaar:discoverable", true);
75
+ c.set("lemma:bazaar:schema", config.schema);
76
+ c.set("lemma:bazaar:category", config.bazaarCategory);
77
+ c.set("lemma:bazaar:subTags", config.bazaarSubTags);
78
+ }
79
+ await upstream(c, next);
80
+ if (config.discoverable && c.res) {
81
+ // CDP returns Bazaar metadata processing status in EXTENSION-RESPONSES.
82
+ // The header is absent for non-CDP facilitators (e.g. x402.org), in
83
+ // which case we skip emission silently.
84
+ const headerValue = c.res.headers.get("EXTENSION-RESPONSES");
85
+ if (headerValue) {
86
+ getBazaarStatusEmitter().emit({
87
+ routePath: c.req.path,
88
+ schema: config.schema,
89
+ category: config.bazaarCategory,
90
+ status: parseBazaarStatus(headerValue),
91
+ rawHeader: headerValue,
92
+ observedAt: new Date().toISOString(),
93
+ });
94
+ }
95
+ // Always surface Bazaar metadata to clients via response headers for
96
+ // transparent downstream consumption (`agentic.market` curated tooling).
97
+ if (config.schema)
98
+ c.header("X-Lemma-Bazaar-Schema", config.schema);
99
+ if (config.bazaarCategory) {
100
+ c.header("X-Lemma-Bazaar-Category", config.bazaarCategory);
101
+ }
102
+ }
103
+ };
104
+ };
105
+ //# sourceMappingURL=bazaar-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bazaar-middleware.js","sourceRoot":"","sources":["../src/bazaar-middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bazaar-middleware.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bazaar-middleware.test.d.ts","sourceRoot":"","sources":["../src/bazaar-middleware.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Unit tests for bazaarPaymentMiddleware v0.2.
3
+ *
4
+ * Mocks @x402/hono's paymentMiddlewareFromConfig so we never call the real
5
+ * upstream during unit tests. The mock echoes the (potentially enriched)
6
+ * config into a response header so tests can inspect what was injected.
7
+ */
8
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
9
+ import { Hono } from "hono";
10
+ vi.mock("@x402/hono", () => ({
11
+ paymentMiddlewareFromConfig: vi.fn((config) => {
12
+ return async (c, next) => {
13
+ c.header("X-Test-Injected-Bazaar", JSON.stringify(config
14
+ .accepts?.[0]?.extra?.bazaar ?? null));
15
+ await next();
16
+ };
17
+ }),
18
+ }));
19
+ import { bazaarPaymentMiddleware } from "./bazaar-middleware.js";
20
+ import { setBazaarStatusEmitterForTesting, } from "./bazaar-status-emitter.js";
21
+ const baseConfig = {
22
+ recipient: "0x000000000000000000000000000000000000dEaD",
23
+ amount: "70000",
24
+ network: "base",
25
+ };
26
+ describe("bazaarPaymentMiddleware (v0.2)", () => {
27
+ const emitted = [];
28
+ beforeEach(() => {
29
+ emitted.length = 0;
30
+ setBazaarStatusEmitterForTesting({
31
+ emit: (e) => emitted.push(e),
32
+ });
33
+ });
34
+ afterEach(() => {
35
+ setBazaarStatusEmitterForTesting(undefined);
36
+ });
37
+ it("does not inject bazaar extension when discoverable is false", async () => {
38
+ const app = new Hono();
39
+ app.use("/foo", bazaarPaymentMiddleware({
40
+ ...baseConfig,
41
+ discoverable: false,
42
+ }));
43
+ app.get("/foo", (c) => c.text("ok"));
44
+ const res = await app.request("/foo");
45
+ expect(res.status).toBe(200);
46
+ expect(res.headers.get("X-Test-Injected-Bazaar")).toBe("null");
47
+ });
48
+ it("throws at construction time when discoverable: true is missing required fields", () => {
49
+ expect(() => bazaarPaymentMiddleware({
50
+ ...baseConfig,
51
+ discoverable: true,
52
+ // missing: schema, bazaarCategory, bazaarDescription
53
+ })).toThrow(/discoverable: true requires/);
54
+ });
55
+ it("throws when bazaarDescription exceeds 256 chars", () => {
56
+ expect(() => bazaarPaymentMiddleware({
57
+ ...baseConfig,
58
+ discoverable: true,
59
+ schema: "test-v1",
60
+ bazaarCategory: "Inference",
61
+ bazaarDescription: "x".repeat(257),
62
+ })).toThrow(/exceeds 256 chars/);
63
+ });
64
+ it("injects bazaar extension input into accepts[0].extra when discoverable", async () => {
65
+ const app = new Hono();
66
+ app.use("/attest", bazaarPaymentMiddleware({
67
+ ...baseConfig,
68
+ discoverable: true,
69
+ schema: "inference-attestation-v1",
70
+ bazaarCategory: "Inference",
71
+ bazaarDescription: "For AI agents that need per-call attestations.",
72
+ bazaarSubTags: ["verifiable-ai", "claim-check"],
73
+ bazaarInputSchemaRef: "https://schemas.lemma.frame00.com/bazaar/product-b-input.json",
74
+ bazaarOutputSchemaRef: "https://schemas.lemma.frame00.com/bazaar/product-b-output.json",
75
+ }));
76
+ app.post("/attest", (c) => c.json({ ok: true }));
77
+ const res = await app.request("/attest", { method: "POST" });
78
+ expect(res.status).toBe(200);
79
+ const injected = JSON.parse(res.headers.get("X-Test-Injected-Bazaar") ?? "null");
80
+ expect(injected).toEqual({
81
+ name: "inference-attestation-v1",
82
+ description: "For AI agents that need per-call attestations.",
83
+ category: "Inference",
84
+ tags: ["verifiable-ai", "claim-check"],
85
+ inputSchema: "https://schemas.lemma.frame00.com/bazaar/product-b-input.json",
86
+ outputSchema: "https://schemas.lemma.frame00.com/bazaar/product-b-output.json",
87
+ });
88
+ });
89
+ it("emits accepted status when EXTENSION-RESPONSES header is present", async () => {
90
+ const app = new Hono();
91
+ app.use("/attest", bazaarPaymentMiddleware({
92
+ ...baseConfig,
93
+ discoverable: true,
94
+ schema: "inference-attestation-v1",
95
+ bazaarCategory: "Inference",
96
+ bazaarDescription: "x",
97
+ }));
98
+ app.post("/attest", (c) => {
99
+ c.header("EXTENSION-RESPONSES", "status=accepted");
100
+ return c.json({ ok: true });
101
+ });
102
+ await app.request("/attest", { method: "POST" });
103
+ expect(emitted).toHaveLength(1);
104
+ expect(emitted[0]?.status).toBe("accepted");
105
+ expect(emitted[0]?.routePath).toBe("/attest");
106
+ expect(emitted[0]?.schema).toBe("inference-attestation-v1");
107
+ });
108
+ it("emits rejected status without affecting the 200 response (payment-independent)", async () => {
109
+ const app = new Hono();
110
+ app.use("/attest", bazaarPaymentMiddleware({
111
+ ...baseConfig,
112
+ discoverable: true,
113
+ schema: "inference-attestation-v1",
114
+ bazaarCategory: "Inference",
115
+ bazaarDescription: "x",
116
+ }));
117
+ app.post("/attest", (c) => {
118
+ c.header("EXTENSION-RESPONSES", "status=rejected");
119
+ return c.json({ ok: true });
120
+ });
121
+ const res = await app.request("/attest", { method: "POST" });
122
+ expect(res.status).toBe(200);
123
+ expect(emitted[0]?.status).toBe("rejected");
124
+ });
125
+ it("does not emit when EXTENSION-RESPONSES header is absent", async () => {
126
+ const app = new Hono();
127
+ app.use("/attest", bazaarPaymentMiddleware({
128
+ ...baseConfig,
129
+ discoverable: true,
130
+ schema: "inference-attestation-v1",
131
+ bazaarCategory: "Inference",
132
+ bazaarDescription: "x",
133
+ }));
134
+ app.post("/attest", (c) => c.json({ ok: true }));
135
+ await app.request("/attest", { method: "POST" });
136
+ expect(emitted).toHaveLength(0);
137
+ });
138
+ it("returns 'unknown' status for forward-compat header values", async () => {
139
+ const app = new Hono();
140
+ app.use("/attest", bazaarPaymentMiddleware({
141
+ ...baseConfig,
142
+ discoverable: true,
143
+ schema: "x-v1",
144
+ bazaarCategory: "Inference",
145
+ bazaarDescription: "x",
146
+ }));
147
+ app.post("/attest", (c) => {
148
+ c.header("EXTENSION-RESPONSES", "status=quantum-superposition");
149
+ return c.json({ ok: true });
150
+ });
151
+ await app.request("/attest", { method: "POST" });
152
+ expect(emitted[0]?.status).toBe("unknown");
153
+ expect(emitted[0]?.rawHeader).toBe("status=quantum-superposition");
154
+ });
155
+ });
156
+ //# sourceMappingURL=bazaar-middleware.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bazaar-middleware.test.js","sourceRoot":"","sources":["../src/bazaar-middleware.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Bazaar status emitter — abstract observability sink for the
3
+ * `EXTENSION-RESPONSES` outcome returned by the CDP facilitator on settle.
4
+ *
5
+ * Default: console.info (JSON-line, log-aggregation-friendly).
6
+ * Override via env LEMMA_BAZAAR_EMITTER:
7
+ * - "console" (default)
8
+ * - "noop" (silent — useful in tests)
9
+ * - "datadog" (TODO(W2): wire to Datadog metrics agent if/when available)
10
+ *
11
+ * Discovery failures are observability events, not payment events — they
12
+ * never break settle. See bazaar-middleware.ts for the emission site.
13
+ */
14
+ export interface BazaarStatusEvent {
15
+ routePath: string;
16
+ schema: string | undefined;
17
+ category: string | undefined;
18
+ /** "accepted" | "processing" | "rejected" | "unknown" */
19
+ status: "accepted" | "processing" | "rejected" | "unknown";
20
+ rawHeader: string;
21
+ observedAt: string;
22
+ }
23
+ export interface BazaarStatusEmitter {
24
+ emit(event: BazaarStatusEvent): void;
25
+ }
26
+ export declare const getBazaarStatusEmitter: () => BazaarStatusEmitter;
27
+ /**
28
+ * Test-only setter. Lets unit tests inject a mock emitter and restore later
29
+ * by passing `undefined`.
30
+ */
31
+ export declare const setBazaarStatusEmitterForTesting: (emitter: BazaarStatusEmitter | undefined) => void;
32
+ /**
33
+ * Parse the EXTENSION-RESPONSES header into a typed status.
34
+ *
35
+ * CDP's exact header format is not exhaustively documented; we look for
36
+ * `status=<value>` and fall back to "unknown" for forward-compat. The raw
37
+ * header is always preserved on the emitted event so downstream alerting
38
+ * can react to undocumented variants.
39
+ */
40
+ export declare const parseBazaarStatus: (headerValue: string) => BazaarStatusEvent["status"];
41
+ //# sourceMappingURL=bazaar-status-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bazaar-status-emitter.d.ts","sourceRoot":"","sources":["../src/bazaar-status-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,yDAAyD;IACzD,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACtC;AA+CD,eAAO,MAAM,sBAAsB,QAAO,mBAuBzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,GAC3C,SAAS,mBAAmB,GAAG,SAAS,KACvC,IAEF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC5B,aAAa,MAAM,KAClB,iBAAiB,CAAC,QAAQ,CAgB5B,CAAC"}
@@ -0,0 +1,92 @@
1
+ class ConsoleEmitter {
2
+ emit(event) {
3
+ // Single line, JSON-parseable for log aggregation.
4
+ console.info(JSON.stringify({
5
+ ts: event.observedAt,
6
+ level: "info",
7
+ msg: "bazaar_extension_response",
8
+ route: event.routePath,
9
+ schema: event.schema,
10
+ category: event.category,
11
+ status: event.status,
12
+ raw: event.rawHeader,
13
+ }));
14
+ }
15
+ }
16
+ class NoopEmitter {
17
+ emit() {
18
+ /* intentionally empty */
19
+ }
20
+ }
21
+ /**
22
+ * Lazy singleton. Reads env at first call so tests can override before init.
23
+ */
24
+ let cached;
25
+ /**
26
+ * Resolve the `LEMMA_BAZAAR_EMITTER` env var across Node, Workers, and
27
+ * browser-like environments without taking a type-level dependency on
28
+ * `@types/node`.
29
+ */
30
+ const readEmitterEnv = () => {
31
+ const proc = globalThis.process;
32
+ const fromProcess = proc?.env?.["LEMMA_BAZAAR_EMITTER"];
33
+ if (typeof fromProcess === "string" && fromProcess.length > 0)
34
+ return fromProcess;
35
+ const fromGlobal = globalThis.LEMMA_BAZAAR_EMITTER;
36
+ if (typeof fromGlobal === "string" && fromGlobal.length > 0)
37
+ return fromGlobal;
38
+ return undefined;
39
+ };
40
+ export const getBazaarStatusEmitter = () => {
41
+ if (cached)
42
+ return cached;
43
+ const envValue = readEmitterEnv();
44
+ switch (envValue) {
45
+ case "noop":
46
+ cached = new NoopEmitter();
47
+ break;
48
+ case "console":
49
+ case undefined:
50
+ cached = new ConsoleEmitter();
51
+ break;
52
+ default:
53
+ // Unknown emitter name — log once and fall back to console so we never
54
+ // silently drop observability data due to a typo.
55
+ console.warn(`[lemma:bazaar] unknown LEMMA_BAZAAR_EMITTER="${envValue}", falling back to console`);
56
+ cached = new ConsoleEmitter();
57
+ }
58
+ return cached;
59
+ };
60
+ /**
61
+ * Test-only setter. Lets unit tests inject a mock emitter and restore later
62
+ * by passing `undefined`.
63
+ */
64
+ export const setBazaarStatusEmitterForTesting = (emitter) => {
65
+ cached = emitter;
66
+ };
67
+ /**
68
+ * Parse the EXTENSION-RESPONSES header into a typed status.
69
+ *
70
+ * CDP's exact header format is not exhaustively documented; we look for
71
+ * `status=<value>` and fall back to "unknown" for forward-compat. The raw
72
+ * header is always preserved on the emitted event so downstream alerting
73
+ * can react to undocumented variants.
74
+ */
75
+ export const parseBazaarStatus = (headerValue) => {
76
+ const match = /(?:^|[\s,;])status\s*=\s*"?([a-z_-]+)"?/i.exec(headerValue);
77
+ if (!match || !match[1])
78
+ return "unknown";
79
+ switch (match[1].toLowerCase()) {
80
+ case "accepted":
81
+ return "accepted";
82
+ case "processing":
83
+ case "pending":
84
+ return "processing";
85
+ case "rejected":
86
+ case "failed":
87
+ return "rejected";
88
+ default:
89
+ return "unknown";
90
+ }
91
+ };
92
+ //# sourceMappingURL=bazaar-status-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bazaar-status-emitter.js","sourceRoot":"","sources":["../src/bazaar-status-emitter.ts"],"names":[],"mappings":"AA2BA,MAAM,cAAc;IAClB,IAAI,CAAC,KAAwB;QAC3B,mDAAmD;QACnD,OAAO,CAAC,IAAI,CACV,IAAI,CAAC,SAAS,CAAC;YACb,EAAE,EAAE,KAAK,CAAC,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,2BAA2B;YAChC,KAAK,EAAE,KAAK,CAAC,SAAS;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,EAAE,KAAK,CAAC,SAAS;SACrB,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAED,MAAM,WAAW;IACf,IAAI;QACF,yBAAyB;IAC3B,CAAC;CACF;AAED;;GAEG;AACH,IAAI,MAAuC,CAAC;AAE5C;;;;GAIG;AACH,MAAM,cAAc,GAAG,GAAuB,EAAE;IAC9C,MAAM,IAAI,GAAI,UAAyE,CAAC,OAAO,CAAC;IAChG,MAAM,WAAW,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC;IACxD,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IAElF,MAAM,UAAU,GAAI,UAAgD,CAAC,oBAAoB,CAAC;IAC1F,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAE/E,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAwB,EAAE;IAC9D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAElC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,MAAM;YACT,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC3B,MAAM;QACR,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACZ,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YAC9B,MAAM;QACR;YACE,uEAAuE;YACvE,kDAAkD;YAClD,OAAO,CAAC,IAAI,CACV,gDAAgD,QAAQ,4BAA4B,CACrF,CAAC;YACF,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,OAAwC,EAClC,EAAE;IACR,MAAM,GAAG,OAAO,CAAC;AACnB,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,WAAmB,EACU,EAAE;IAC/B,MAAM,KAAK,GAAG,0CAA0C,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAE1C,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/B,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,YAAY,CAAC;QAClB,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC;QACtB,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -25,7 +25,13 @@ export { x402ResourceServer } from "./lemma-server.js";
25
25
  export { paymentMiddleware } from "./lemma-discovery.js";
26
26
  export { ExactEvmScheme } from "@x402/evm/exact/server";
27
27
  export { x402Client } from "@x402/core/client";
28
+ export { bazaarPaymentMiddleware } from "./bazaar-middleware.js";
29
+ export { isLemmaRouteConfig, assertDiscoverableConfigured } from "./routeConfig.js";
30
+ export { getBazaarStatusEmitter, parseBazaarStatus, setBazaarStatusEmitterForTesting, } from "./bazaar-status-emitter.js";
28
31
  export type { Network, PaymentRequirements, PaymentPayload } from "@x402/core/types";
29
32
  export type { FacilitatorConfig } from "@x402/core/server";
30
33
  export type { LemmaConfig } from "./lemma-config.js";
34
+ export type { LemmaRouteConfig } from "./routeConfig.js";
35
+ export type { BazaarContextVariables } from "./bazaar-middleware.js";
36
+ export type { BazaarStatusEvent, BazaarStatusEmitter, } from "./bazaar-status-emitter.js";
31
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,YAAY,EAAE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACrF,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAW/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EAAE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACrF,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -28,4 +28,16 @@ export { paymentMiddleware } from "./lemma-discovery.js";
28
28
  // Additional x402 re-exports
29
29
  export { ExactEvmScheme } from "@x402/evm/exact/server";
30
30
  export { x402Client } from "@x402/core/client";
31
+ // Bazaar discoverability extension (x402 Bazaar Discovery Layer) — v0.2
32
+ //
33
+ // v0.2 surface changes vs lemma/#222:
34
+ // + assertDiscoverableConfigured (runtime contract check, throws on misconfig)
35
+ // + BazaarStatusEvent / Emitter (observability for CDP EXTENSION-RESPONSES)
36
+ // - registerBazaarRouteOnFirstSettle (removed — superseded by emitter pipeline;
37
+ // see packages/x402/src/README.md "Bazaar Discovery" section)
38
+ //
39
+ // See also: outputs/bazaar-listings/handoff-2026-05-20-register-on-first-settle.md
40
+ export { bazaarPaymentMiddleware } from "./bazaar-middleware.js";
41
+ export { isLemmaRouteConfig, assertDiscoverableConfigured } from "./routeConfig.js";
42
+ export { getBazaarStatusEmitter, parseBazaarStatus, setBazaarStatusEmitterForTesting, } from "./bazaar-status-emitter.js";
31
43
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,kDAAkD;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,mEAAmE;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,6BAA6B;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,kDAAkD;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,mEAAmE;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,6BAA6B;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,wEAAwE;AACxE,EAAE;AACF,sCAAsC;AACtC,kFAAkF;AAClF,gFAAgF;AAChF,kFAAkF;AAClF,kEAAkE;AAClE,EAAE;AACF,mFAAmF;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Lemma extension of @x402/core/server RouteConfig — v0.2
3
+ *
4
+ * v0.2 additions:
5
+ * - bazaarDescription (1-sentence semantic-search-friendly description)
6
+ * - bazaarInputSchemaRef (absolute URL of input JSON Schema)
7
+ * - bazaarOutputSchemaRef (absolute URL of output JSON Schema)
8
+ *
9
+ * These three feed into the 402 challenge response's accepts[].extra.bazaar
10
+ * payload that the CDP facilitator consumes for Discovery Layer indexing.
11
+ *
12
+ * Rationale:
13
+ * - CDP auto-indexes routes that settle with discoverable: true. The
14
+ * metadata it needs (description / category / tags / inputSchema /
15
+ * outputSchema) all travel through the 402 challenge extension input.
16
+ * - See outputs/bazaar-listings/handoff-2026-05-20-register-on-first-settle.md
17
+ * §1.2 for the primary-source derivation.
18
+ */
19
+ import type { RouteConfig as BaseRouteConfig } from "@x402/core/server";
20
+ export interface LemmaRouteConfig extends BaseRouteConfig {
21
+ /**
22
+ * When true, the route is auto-registered in x402 Bazaar after the first
23
+ * successful settle via the CDP facilitator.
24
+ *
25
+ * Important: only the CDP facilitator (api.cdp.coinbase.com/platform/v2/x402)
26
+ * triggers indexing. The x402.org community facilitator does NOT index to
27
+ * the CDP Discovery Layer. See packages/x402/src/README.md.
28
+ *
29
+ * When set true, `schema`, `bazaarCategory`, and `bazaarDescription` are
30
+ * all required at runtime; the middleware throws at construction time if
31
+ * any is missing. (Compile-time strict union enforcement is deferred to
32
+ * v0.3.)
33
+ *
34
+ * Setting `discoverable: false` (or omitting it) leaves the route priced
35
+ * but invisible to the public Discovery Layer — no Bazaar metadata is
36
+ * injected into the 402 challenge.
37
+ */
38
+ discoverable?: boolean;
39
+ /**
40
+ * Schema identifier surfaced as Bazaar extension input `name`.
41
+ * Convention: kebab-case + version suffix, e.g.
42
+ * "agent-identity-authority-v1"
43
+ * "inference-attestation-v1"
44
+ * "compliance-bundle-v1"
45
+ * "seal-identity-v1"
46
+ */
47
+ schema?: string;
48
+ /**
49
+ * Bazaar category. One of the 7 official categories.
50
+ */
51
+ bazaarCategory?: "Inference" | "Data" | "Media" | "Search" | "Social" | "Infrastructure" | "Trading";
52
+ /**
53
+ * Free-form sub-tags surfaced as semantic-search hints on Bazaar.
54
+ * Each tag must match /^[a-z0-9-]+$/.
55
+ */
56
+ bazaarSubTags?: readonly string[];
57
+ /**
58
+ * 1-sentence human-readable description injected into the 402 challenge
59
+ * extension input. Surfaced verbatim on Bazaar Discovery Layer search.
60
+ *
61
+ * Best practices (lemma-internal):
62
+ * - Start with "For AI agents that need to {verb} {noun}, ..." for
63
+ * semantic-search alignment.
64
+ * - <= 256 chars.
65
+ * - Mention the value prop (zero-knowledge, no raw data, etc.) in the
66
+ * first 80 chars where possible.
67
+ *
68
+ * Required when discoverable: true.
69
+ */
70
+ bazaarDescription?: string;
71
+ /**
72
+ * Absolute URL of the input JSON Schema (Draft 2020-12). Referenced from
73
+ * the 402 extension input so callers can validate before paying.
74
+ *
75
+ * Production convention:
76
+ * https://schemas.lemma.frame00.com/suites/product-<a|b|c|d>-input.json
77
+ */
78
+ bazaarInputSchemaRef?: string;
79
+ /**
80
+ * Absolute URL of the output JSON Schema (Draft 2020-12).
81
+ */
82
+ bazaarOutputSchemaRef?: string;
83
+ }
84
+ /**
85
+ * Type guard: narrows an arbitrary x402 config to a LemmaRouteConfig.
86
+ */
87
+ export declare const isLemmaRouteConfig: (config: BaseRouteConfig) => config is LemmaRouteConfig;
88
+ /**
89
+ * Runtime validation for v0.2's "discoverable implies metadata" contract.
90
+ *
91
+ * Called by bazaarPaymentMiddleware at construction time. Throws synchronously
92
+ * on misconfiguration so the failure surfaces at deploy time, not on first
93
+ * incoming request.
94
+ */
95
+ export declare const assertDiscoverableConfigured: (config: LemmaRouteConfig) => void;
96
+ //# sourceMappingURL=routeConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeConfig.d.ts","sourceRoot":"","sources":["../src/routeConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAExE,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,cAAc,CAAC,EACX,WAAW,GACX,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,gBAAgB,GAChB,SAAS,CAAC;IAEd;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAIlC;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,eAAe,KACtB,MAAM,IAAI,gBAOsB,CAAC;AAEpC;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GAAI,QAAQ,gBAAgB,KAAG,IAqBvE,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Type guard: narrows an arbitrary x402 config to a LemmaRouteConfig.
3
+ */
4
+ export const isLemmaRouteConfig = (config) => "discoverable" in config ||
5
+ "schema" in config ||
6
+ "bazaarCategory" in config ||
7
+ "bazaarSubTags" in config ||
8
+ "bazaarDescription" in config ||
9
+ "bazaarInputSchemaRef" in config ||
10
+ "bazaarOutputSchemaRef" in config;
11
+ /**
12
+ * Runtime validation for v0.2's "discoverable implies metadata" contract.
13
+ *
14
+ * Called by bazaarPaymentMiddleware at construction time. Throws synchronously
15
+ * on misconfiguration so the failure surfaces at deploy time, not on first
16
+ * incoming request.
17
+ */
18
+ export const assertDiscoverableConfigured = (config) => {
19
+ if (!config.discoverable)
20
+ return;
21
+ const missing = [];
22
+ if (!config.schema)
23
+ missing.push("schema");
24
+ if (!config.bazaarCategory)
25
+ missing.push("bazaarCategory");
26
+ if (!config.bazaarDescription)
27
+ missing.push("bazaarDescription");
28
+ if (missing.length > 0) {
29
+ throw new Error(`[LemmaRouteConfig] discoverable: true requires ${missing.join(", ")}. ` +
30
+ `See packages/x402/src/README.md for the discoverable contract.`);
31
+ }
32
+ if (config.bazaarDescription && config.bazaarDescription.length > 256) {
33
+ throw new Error(`[LemmaRouteConfig] bazaarDescription exceeds 256 chars (got ${config.bazaarDescription.length}). ` +
34
+ `Bazaar search hits favour concise descriptions; trim before deploy.`);
35
+ }
36
+ };
37
+ //# sourceMappingURL=routeConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeConfig.js","sourceRoot":"","sources":["../src/routeConfig.ts"],"names":[],"mappings":"AAoGA;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAuB,EACK,EAAE,CAC9B,cAAc,IAAI,MAAM;IACxB,QAAQ,IAAI,MAAM;IAClB,gBAAgB,IAAI,MAAM;IAC1B,eAAe,IAAI,MAAM;IACzB,mBAAmB,IAAI,MAAM;IAC7B,sBAAsB,IAAI,MAAM;IAChC,uBAAuB,IAAI,MAAM,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,MAAwB,EAAQ,EAAE;IAC7E,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,OAAO;IAEjC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,cAAc;QAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3D,IAAI,CAAC,MAAM,CAAC,iBAAiB;QAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAEjE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,kDAAkD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACtE,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CACb,+DAA+D,MAAM,CAAC,iBAAiB,CAAC,MAAM,KAAK;YACjG,qEAAqE,CACxE,CAAC;IACJ,CAAC;AACH,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lemmaoracle/x402",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Drop-in replacement for @x402/* with automatic Lemma discovery and proof submission",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -57,6 +57,6 @@
57
57
  "wrangler": "^3.101.0"
58
58
  },
59
59
  "peerDependencies": {
60
- "@lemmaoracle/sdk": "^0.0.32"
60
+ "@lemmaoracle/sdk": "^0.0.33"
61
61
  }
62
62
  }