Bazaar: seller-side discovery metadata helpers (and list Lens's own endpoints) - #154
Open
DevTobis wants to merge 1 commit into
Open
Bazaar: seller-side discovery metadata helpers (and list Lens's own endpoints)#154DevTobis wants to merge 1 commit into
DevTobis wants to merge 1 commit into
Conversation
The buyer is software. An agent choosing between two price feeds cannot open your docs - it has only what the listing declares, and ranking (Miracle656#129) can only rank on what is declared. So description is the first positional argument of every param constructor, and a declaration missing one does not validate. It is not a warning you can ship past. src/bazaar/declare.ts: - param.string/number/integer/boolean/enumOf, with example and default, emitting JSON Schema fragments - declareHttpResource and declareMcpTool, assembling the resource block, accepts (CAIP-2 network filled from the listing network) and the extensions.bazaar declaration, picking queryParams vs body/bodyType from the HTTP method - validateDeclaration, which runs the catalog's own validateListing so local and remote cannot drift, then adds the seller-side rules the catalog cannot enforce: missing or too-short parameter descriptions, a weak resource description, a routeTemplate naming an undeclared param, and a listing with no price - assertDeclaration, the throwing form, so a bad listing fails the boot instead of silently never appearing in the Bazaar src/bazaar/lensListings.ts declares the routes middleware/x402.ts already gates - /price, /candles, /pools, /price/twap - plus the MCP face of the price feed, each through assertDeclaration at module load. 23 tests in src/__tests__/bazaarDeclare.test.ts, and a walkthrough in docs/x402/bazaar-seller-guide.md.
|
@DevTobis Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #134
Summary
Seller-side helpers for declaring Bazaar discovery metadata, plus Lens's own gated routes declared with them.
The design decision that matters
The issue's core point is that per-parameter descriptions must be first-class, not an afterthought. I made that structural rather than aspirational:
descriptionis the first positional argument of everyparam.*constructor. You cannot forget it by accident — the signature is the enforcement.assetA: stringand no prose caps search quality for everyone in the catalog, not just for its own seller.What's here
src/bazaar/declare.tsparam.string / number / integer / boolean / enumOf, each takingdescriptionfirst and optionalrequired(default true),exampleanddefault. Anexampleis worth more to an agent than another sentence of prose, so it is a first-class option.declareHttpResourceanddeclareMcpTool— assemble the resource block,accepts, and theextensions.bazaardeclaration with proper JSON Schema (additionalProperties: false, arequiredlist built from the flags). The HTTP builder picksqueryParamsvsbody+bodyTypefrom the method, so you never have to remember which slot a POST uses. The CAIP-2networkonacceptsis filled from the listing's network unless you set it explicitly.validateDeclaration/assertDeclaration.src/bazaar/lensListings.ts— the dogfood./price/:assetA/:assetB,/candles/:assetA/:assetB,/pools,/price/twap/:assetA/:assetB(the routessrc/middleware/x402.tsactually gates), plus the MCP face of the price feed. Each goes throughassertDeclarationat module load.docs/x402/bazaar-seller-guide.md, 23 tests, and a changeset.Validation reuses the catalog's own validator
validateDeclarationcallsvalidateListingfromsrc/bazaar/validation.tsunder the hood rather than reimplementing it. That matters: local and remote cannot drift apart, and the problems come back in the catalog's own{ field, code, message }shape — a seller sees the same field path and code locally that the catalog would have soft-dropped them with. Then it adds the rules the catalog cannot enforce, because by the time a listing reaches the catalog the metadata is all it has:missing_param_descriptionparam_description_too_shortweak_resource_descriptionundeclared_route_paramrouteTemplatenames a:paramabsent frompathParams— an agent knows the URL shape but not what goes in the slotmissing_acceptsassertDeclarationis the throwing form, listing every problem with its field path. Called at module load, a malformed listing fails the boot rather than quietly never appearing in the Bazaar — which is the failure mode worth designing against, because nothing tells you it happened.Acceptance criteria
/poolsis 7 lines;/pricewith two described path params is 15.validateDeclaration/assertDeclaration, reusingvalidateListing.declareHttpResource,declareMcpTool.src/bazaar/lensListings.ts.On "appear in the catalog", and on the timing question
Two places where I want to be straight rather than tick a box.
The listings are built and validated, but nothing registers them yet. Automatic cataloging from the discovery extension is #130, and the registration path it will use (
registerBazaarResource, and emitting the extension on the 402 payment path) is that issue's surface. I did not want to half-build #130 inside #134 and leave two partial implementations to reconcile —lensListings()is a pure function returning validatedRegisterBazaarResourceInput[], which is exactly the input #130 needs, so it should be a short step. Say if you would rather I wire it here instead."Say in the PR how long it actually took someone who had not seen it before." I can't honestly answer that — I built the helpers, so I am the worst possible measurement. What I can report: declaring the four Lens routes against the finished API took a few minutes each, and the helpers caught two real mistakes in my own dogfooding that would otherwise have shipped — a
routeTemplatenaming:assetBbefore I had declared it, and a first-draft/poolsdescription too thin to rank on. That is the mechanism working, but it is not the user study the criterion asks for. Worth handing to someone who hasn't seen it and recording the real number.Verification
npx vitest run src/__tests__/bazaarDeclare.test.ts— 23 passednpx tsc --noEmit— no errors from any file in this changeOne pre-existing failure, not from this change:
tests/mcp.test.tsfails withCannot find package '@modelcontextprotocol/sdk/server/index.js', andsrc/mcp/server.tsproduces 4 typecheck errors for the same reason. The package is declared inpackage.jsonbut is not present innode_modules. I confirmed it by stashing this branch and re-running on cleanmain— identical failure. Left alone deliberately rather than bundling an unrelated dependency fix into this PR.