Skip to content

feat(bazaar): automatic cataloging from discovery extension on settlement (#130) - #528

Merged
Miracle656 merged 1 commit into
Divinity-Labs:mainfrom
sparkysolutions10-pixel:feat/bazaar-automatic-cataloging-130
Oct 19, 2026
Merged

Miracle656 merged 1 commit into
Divinity-Labs:mainfrom
sparkysolutions10-pixel:feat/bazaar-automatic-cataloging-130

Conversation

@sparkysolutions10-pixel

Copy link
Copy Markdown
Contributor

Closes #130

Summary of Changes

  • Hooks automatic resource cataloging into POST /settle upon successful payment settlement.
  • Validates listing metadata against the Bazaar schema via submitCatalogListing without requiring any separate seller actions.
  • Automatically reports cataloging acceptance/drop reasons back to sellers via the EXTENSION-RESPONSES HTTP response header.
  • Fully insulated: errors or failures during catalog indexing will never delay or fail the settlement transaction.
  • Keeps verify side-effect free, performing cataloging strictly on settle where payment is demonstrated.
  • Tested thoroughly in src/__tests__/facilitatorSettle.test.ts.

Miracle656 added a commit that referenced this pull request Oct 19, 2026
…xtension

A resource server that pays through /settle and sends a bazaar/discovery
extension now gets listed from that same call, instead of needing a second
request to declare itself. Per-field results go back in the
EXTENSION-RESPONSES header.

Safe by construction, which I checked rather than assumed: the block runs
after the payment has been submitted, so nothing in it can change whether
money moved, and `submitCatalogListing` already rate-limits per `payTo` and
runs `validateListing` over exactly this input — so the untrusted extension
body is validated by the one function that owns that, not waved through.

Three things tightened while merging:

- **The catch was completely silent.** Swallowing is right — cataloguing must
  never turn a successful settlement into a failed response — but with no log
  at all, a catalog broken for a week would only be noticeable as listings
  that never appear. Now `req.log.warn` with the error and network.
- **`as any` replaced** with `RegisterBazaarResourceInput` from
  `src/bazaar/types`, plus a comment saying the shape is deliberately not
  re-checked here because `submitCatalogListing` validates it.
- **The comment claimed cataloguing cannot "fail or delay settlement".** The
  first half is true, the second is not: the call is awaited, so it can delay
  the response. It has to be awaited, because the result goes back in a header
  and a caller cannot be told which fields were dropped after the response has
  gone. Comment now says what the code does — the payment is already
  submitted, so the only cost is response latency.

Also documented why both `extensions.bazaar` and a flattened `discovery` key
are accepted.

Verified on the merge result: `tsc --noEmit` silent, 887 tests pass across 82
suites, nothing red.

Closes #130

Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
@Miracle656
Miracle656 merged commit dfce4d4 into Divinity-Labs:main Oct 19, 2026
@Miracle656

Copy link
Copy Markdown
Collaborator

Merged. #130 is unassigned, so this is yours.

I checked the safety of it rather than taking the comment's word, and it holds up: the block runs after the payment has been submitted, so nothing in it can change whether money moved; and submitCatalogListing already rate-limits per payTo and runs validateListing over exactly the input you hand it. So the untrusted extension body is validated — by the one function that owns that job — rather than waved through. Reusing that entry point instead of writing a second validation path is the right call and it's why this is a 22-line change.

Three things I tightened while merging

1. The catch was completely silent.

} catch {
  // Failure in cataloging must never fail or delay settlement (#130)
}

Swallowing is correct — cataloguing must never turn a successful settlement into a failed response. But with no log at all, a catalog broken for a week is only observable as listings that mysteriously never appear, which is the hardest kind of bug to notice and the hardest to diagnose once noticed. Now req.log.warn({ err, network }, ...). Swallow the failure, not the evidence.

2. The comment overclaimed. It said cataloguing cannot "fail or delay settlement". The first half is true; the second isn't — the call is awaited, so it does delay the response. It also has to be awaited, because the result goes back in the EXTENSION-RESPONSES header and you cannot tell a caller which fields were dropped after the response has already gone. So I kept the await and corrected the comment instead: the payment is already submitted, the only cost is response latency. Worth being precise about, because the next person reading "cannot delay settlement" might move the call off the request path and silently lose the header.

3. bazaarExtension as any → RegisterBazaarResourceInput from src/bazaar/types, with a comment noting the shape is deliberately not re-checked here because submitCatalogListing validates it. Same behaviour, but now the reason the cast is safe is written down rather than needing to be rediscovered.

I also documented why both extensions.bazaar and a flattened discovery key are accepted — that dual shape is the kind of thing that looks like an accident six months later.

Verified on the merge result rather than your branch: tsc --noEmit silent, 887 tests across 82 suites, nothing red.

Correction to what I said on #532

I told you there to land #532 first and rebase this onto it. That was right when both looked close, but #532 now needs real rework — the spend ceiling reads a caller-supplied amount instead of the signed XDR, and the allow-list can be satisfied with an Origin header — so holding this behind it would have been for nothing. This went first instead. #532 will need a rebase onto current main; src/routes/facilitator.ts and facilitatorSettle.test.ts both moved.

Closes #130.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bazaar: automatic cataloging from the discovery extension

2 participants