Skip to content

feat: run a paid shop order on our own paykit server and locks with the staging homeserver - #24

Merged
ovitrif merged 5 commits into
mainfrom
feat/shop-order
Oct 10, 2026
Merged

ovitrif merged 5 commits into
mainfrom
feat/shop-order

Conversation

@ovitrif

@ovitrif ovitrif commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #23 (shop-mixed). Adds the shop-order profile: a Shop order paid end to end on our own Paykit Server, Lock Server, marketplace service and Shop, with Synonym's staging homeserver, relay, Shop indexer and Blocktank's staging regtest chain.

Description

  • ./shop-order fetches the Shop (feat: run the shop against upstream paykit and locks behind a switch pubky/pubky-marketplace#154, fbe3babb), the marketplace service (fix: accept upstream locks lock paths pubky/pubky-marketplace-service#98, 005b0707) and the Lock Server (pubky/locks v0.1.0-rc10, 01cfeca1) at exactly those commits, the ones the Android and iOS order-paid acceptance ran on, and builds each with its repository's Dockerfile next to shop-mixed's Paykit Server v0.1.0-rc11.
  • up makes every key on the first start and keeps it after, starts a quick tunnel per public URL, and fills each origin setting from those URLs. Postgres gets the refusal-audit logins the service requires and the Shop BFF tables.
  • Paykit trust is merged, never replaced. The staging driver rewrote [signed_services] on every start and dropped the Lock Server's signer, so Paykit refused every Locks invoice after a restart. Keys already trusted stay, the profile's Lock Server and service keys are added, and each start reads the list back.
  • ./shop-order lock creates a digital listing's Lock as the seller and prints its digitalLock. A seller-only provisioning page, added to the Shop only with SHOP_ORDER_PROVISIONING=1, publishes the listing's next revision with it through the Shop's normal path, which emits the service's listing.sync. Neither writes an order or a payment.
  • docs/shop-order.md holds the seller and buyer steps, the pass criteria and every setting.
  • The Shop is pinned at fbe3babb, where it was tested. feat: run the shop against upstream paykit and locks behind a switch pubky/pubky-marketplace#154 later moved to 84934516 for review changes to the seller-readiness source and the buyer key-record gate, with the Locks payment path unchanged; the pin moves after #154 merges.

QA Notes

Automated Checks

  • node --test marketplace/driver/trust.test.mjs: a Locks connect and a service start each add a key, two restarts follow, and all three keys remain.
  • Started on a QA box (Linux VM, Docker without BuildKit) at 5972825 with ./shop-order fetch and ./shop-order up: every image built from its pinned commit on the first attempt. ./shop-order health shows Paykit Server ready (database, Electrum, delivery, outbox), the Lock Server /readyz 200, the service /ready 200 and the Shop serving.
  • Paykit's trusted keys held the driver issuer, the Lock Server signer and the service key, unchanged after a driver restart.
  • From the public internet, each tunnel answered: Paykit /health/ready, Lock Server /readyz, service /ready, Shop /marketplace and the provisioning page. The Shop's runtime config carried locks-paykit, upstream and the live service and Lock Server URLs.

Manual Tests

  • Seller: Ring sign-in, Connect Locks, reload, Paykit setup; ./shop-order lock; publish revision 2 on the provisioning page; check the service's Lock snapshot.
  • Buyer: contact-first, Pay, Request payment in your wallet, one payment; the same order becomes paid with amount_matched and proof_submitted. The Android and iOS acceptance ran this on the same pinned commits outside this profile.

The staging driver rewrote [signed_services] from its template on each init, dropping the Lock Server signer and the service key added after it; every Locks invoice was then refused. Trust is now merged (keys kept, PAYKIT_TRUSTED_KEYS added) and read back after each write.
@ovitrif ovitrif self-assigned this Oct 10, 2026

@talosmachina talosmachina left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings. Makes the staging driver's init merge the Paykit Server's [signed_services] trust list with what the file already holds and with PAYKIT_TRUSTED_KEYS, then fail the start if a required key is missing. Reviewed 6be006c, full tier.

What I checked, and 4 candidates I ruled out

Read in full: marketplace/driver/trust.mjs, trust.test.mjs, init() and stagingConfig() in driver.mjs, the shop-mixed-driver and shop-mixed-paykit services in docker-compose.yml
Ran: node --test marketplace/driver/trust.test.mjs, 4 of 4 pass
CI: no checks report on this branch

Ruled out

  • Regex lead swallowing a blank line: with the m flag the leading \s* can take a preceding newline, but the replacement writes the captured lead back unchanged, so the file keeps its shape.
  • Non-staging config changed: written stays the template when STAGING is false, so the regtest [locks] trusted_public_key path is untouched.
  • PAYKIT_TRUSTED_KEYS not passed to shop-mixed-driver in compose: the description says the shop-order profile and its wiring come in the next commits on this branch, so it is not a gap in this change.
  • A stale key (rotated issuer) kept forever: merge-never-replace is the stated intent.

Merge confidence: 4/5, no CI runs on this repo and the test re-implements init rather than calling the one in driver.mjs.

…vers

The Lock Server v0.1.0-rc10, marketplace service 005b0707 and Shop fbe3babb (the commits the Android and iOS order-paid acceptance ran on), Postgres with the refusal-audit logins and Shop BFF tables, quick tunnels, fresh keys kept across reruns, the Paykit trust they need merged by the driver, and the seller's Lock and provisioning helpers.
… service, and fetch exact sources

COMPOSE_PROJECT_NAME from a QA lane no longer applies; health checks the service's /ready and fails on any unready service; fetch resets each owned checkout to its commit so tracked edits cannot survive.

@ovi-reviewer ovi-reviewer Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ✅ Approve

Review: diff 16 files.

Pins, the exact commits the Android and iOS acceptance ran on:

Proven at 5972825, with the profile built and started at 9b4e208 and every image from its pin:

  • strict readiness: Paykit ready, Lock Server /readyz, service /ready, Shop serving
  • Paykit keeps the driver, Lock Server and service keys after a driver restart, which is the restart regression those runs hit
  • all four tunnels answer from the public internet, with the Shop in locks-paykit upstream mode

Not proven:

  • The paid orders ran in a separate setup on the same commits, not through this profile.
  • The packaged seller, Lock, provisioning and buyer steps have not been run; they are listed under Manual Tests.

Since then:

  • 25b44cf only changes docs and keeps the same pins.
  • pubky/pubky-marketplace#154 later moved to 8493451 for review changes to seller readiness and the buyer key record, with the Locks prepare and register path unchanged; the pin stays at the tested commit.

Reviewed by claude-opus-5-5 via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest

@ovitrif
ovitrif requested review from a team, ben-kaufman and coreyphillips and removed request for a team, ben-kaufman and coreyphillips October 10, 2026 11:27
Base automatically changed from feat/shop-mixed to main October 10, 2026 12:31
@ovitrif
ovitrif merged commit 8570dc9 into main Oct 10, 2026
@ovitrif
ovitrif deleted the feat/shop-order branch October 10, 2026 12:32
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.

2 participants