Skip to content

feat(demo): the mint-only demo builds, ships a Dockerfile and uses the hosted-form router - #85

Merged
blink-admin merged 3 commits into
mainfrom
feat/demo-mint-only-deployable
Sep 10, 2026
Merged

blink-admin merged 3 commits into
mainfrom
feat/demo-mint-only-deployable

Conversation

@grimen

@grimen grimen commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Stack 3/5 (base: feat/node-production). The mint-only demo becomes a deployable example.

  • Uses createHostedFormRouter with the quote-derived prefill hook; keeps the GraphQL mutation so both spellings are shown. Invalid units answer 400, a mint failure 502.
  • tsup build, node --env-file-if-exists=.env dev/start (the README's .env was never loaded before), SIGTERM/SIGINT drain.
  • Dockerfile modelled on the service's; CI builds and smokes the image (mint port-table offset) and does not publish it: the product is the package.
  • docker-build.sh takes DOCKERFILE, docker-smoke.sh takes a container port; server-demos-smoke.sh also hits the REST mint and /health.

@blink-admin
blink-admin added this pull request to stack #88 September 10, 2026 20:20
@grimen
grimen force-pushed the feat/demo-mint-only-deployable branch 2 times, most recently from 8574c46 to cbf6a3e Compare September 10, 2026 20:52
@grimen
grimen marked this pull request as ready for review September 10, 2026 22:03
@grimen
grimen requested a review from blink-admin September 10, 2026 22:06
@grimen
grimen force-pushed the feat/demo-mint-only-deployable branch from cbf6a3e to c23d79f Compare September 10, 2026 22:14
Base automatically changed from feat/node-production to main September 10, 2026 22:17
…sted-form router

Consumes the new @blinkbitcoin/esign-node presets from task 3:
hostedFormProviderFromEnv/hostedFormMint replace the demo's own DocuSign
registry in src/mint.ts, and createHostedFormRouter
(@blinkbitcoin/esign-node/express) mounts the REST spelling of the mint
(POST /webform/instance, GET /health, the return-URL bridge) alongside
the existing GraphQL mutation - both shown side by side. Its prefill hook
computes the locked amounts via quoteFor(unitsFrom(prefill)) in quote.ts,
so the client's number_of_units is intent, never trusted directly.

Adds a real build (tsup, ESM, produces dist/index.js), SIGTERM/SIGINT
shutdown in src/index.ts, a Dockerfile modelled on
packages/esign-service/Dockerfile (EXPOSE/HEALTHCHECK on 4100 per the
current port handling - the per-worktree port table has not landed on
this branch), and .env.example / README coverage of the production
guard, the private-key sources and the container run path.
scripts/ci/docker-build.sh takes DOCKERFILE (default
packages/esign-service/Dockerfile) and titles the image from $IMAGE, so it
builds any Dockerfile in the repo; docker-smoke.sh takes an optional
[container-port] (default 4000). e2e.yml's Docker job now also builds and
smokes examples/mint-only-demo/Dockerfile - proving that shape deploys -
with no version stamp, archive or artifact upload: it is a demo, not a
package Publish ships. New root Makefile targets docker-build-mint-only /
docker-smoke-mint-only mirror it locally.

scripts/e2e/server-demos-smoke.sh now also calls the mint-only demo's REST
mint (POST /webform/instance, including the anonymous-401 case) and
GET /health, alongside the GraphQL mutation it already exercised.
The prefill hook (src/server.ts) now catches quoteFor's RangeError and
throws Errors.validationError with its message, which
mintWebFormInstanceHttp (packages/esign-node, previous commit) maps to
400 - so POST /webform/instance with a non-numeric, negative, zero,
fractional, huge or missing number_of_units answers 400 with a message
instead of reading as a 502 provider/network failure. Mint failures still
answer 502 unchanged (tested separately).

src/quote.ts's unitsFrom doc comment now says plainly what the function
does: it only coerces the client's prefill to a number, it never
validates or rejects anything itself - quoteFor is still the one place
that enforces the range, and the caller (server.ts) is responsible for
turning quoteFor's RangeError into its own transport's error shape.

Also: examples/mint-only-demo/README.md's container section now links the
production runbook at docs/operations/production.md (arrives in the docs
PR; a dangling relative link is accepted for now) instead of the
already-existing packages/esign-service/README.md#deploy section.

Minor: src/index.ts's shutdown handler gets a shuttingDown re-entrancy
guard, so a second SIGTERM/SIGINT during an in-flight server.stop() is a
no-op instead of re-entering apollo.stop()/httpServer.close().
@blink-admin
blink-admin force-pushed the feat/demo-mint-only-deployable branch from c23d79f to 1c24ad4 Compare September 10, 2026 22:17
@blink-admin
blink-admin merged commit aad60ca into main Sep 10, 2026
1 check failed
@blink-admin
blink-admin deleted the feat/demo-mint-only-deployable branch September 10, 2026 22:18
@github-actions github-actions Bot mentioned this pull request Sep 10, 2026
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