v0.4.0
0.4.0 (2026-09-10)
The production release of the backend: one library for hosts that mint in-process, one
service that runs from environment alone as a function or a container, and a runbook by
role. Migration notes: docs/upgrading.md; operations:
docs/operations/production.md.
⚠ Breaking changes
- Package rename:
@blinkbitcoin/esign-serveris now@blinkbitcoin/esign-node
(packages/esign-node), platform-named likeesign-react/esign-react-native.
No aliases: update every import, including the/docusign,/expressand/knex
subpaths. (#83, 97e55a3) - The service is a package and its image is renamed:
examples/full-service-demo
is nowpackages/esign-service(@blinkbitcoin/esign-service, published); the image
ghcr.io/blinkbitcoin/esign-apiis nowghcr.io/blinkbitcoin/esign-service. (#83) - The service is no longer an Express app.
createApp()is gone; the entry points
arecreateESignApp(env, deps)(Fetch) andstartServer(env)on
@blinkbitcoin/esign-service/node. The container command isnode dist/node.js,
migrations arenode dist/node.js migrate(wasdist/migrate.js).express,
helmet,corsandexpress-rate-limitare no longer dependencies. (#86, 302ab25) ESIGN_ENV=productionreplacesNODE_ENV=productionas the production switch
(GraphQL introspection off; demo DocuSign hosts and the mock provider refused unless
ESIGN_ALLOW_DEMO=true; a client's own prefill refused unless
ESIGN_ALLOW_CLIENT_PREFILL=true). The image setsESIGN_ENV=productionitself; a
non-container deployment that relied onNODE_ENVmust set it. (#84, #86)- Boot checks moved earlier and changed shape:
DOCUSIGN_HMAC_KEYand
DOCUSIGN_TEMPLATE_IDare required only when envelope orchestration is on; a mint
requiresDOCUSIGN_WEBFORM_IDandDOCUSIGN_RETURN_URLat provider selection;
validateSecurityConfig()isvalidateConfig(env, { runtime }). (#84, #86)
Features
- node: production guard (
ESIGN_ENV,ESIGN_ALLOW_DEMO), hosted-form boot checks
(HOSTED_FORM_SETTINGS, incl. the return URL that used to fail silently), private key
fromDOCUSIGN_PRIVATE_KEY_BASE64/DOCUSIGN_PRIVATE_KEY_FILE,
hostedFormProviderFromEnv, and two presets that serve the mint, the return-URL
bridge and/health:createHostedFormRouter(Express) andcreateHostedFormApp
(Fetch), with aprefillhook so the host computes locked terms from its own data;
a hook rejects withErrors.validationError→ 400. (#84, e621645) - service: one deployable for the mint and the full envelope orchestration,
capability by environment: the mint is always on,DATABASE_URLadds/graphql,
POST /webhook/esignand the Knex store. Entries for Node (the image, in-memory rate
limits,TRUST_PROXY), Vercel and Cloudflare Workers (mint only). Session
verification viaSESSION_JWKS_URLorSESSION_HS256_SECRET(JWT_SECRETstays an
alias). Locked terms via aTERMS_URLcallback (TERMS_SHARED_SECRET,
TERMS_TIMEOUT_MS; plaintext refused in production unless private or
TERMS_ALLOW_INSECURE=true). Deploy templates for Compose, Kubernetes, Vercel,
Cloudflare and NixOS ship in the package;/healthreports the capabilities that
are on. (#86, 302ab25) - demo: the mint-only demo builds, ships a Dockerfile and uses the hosted-form router (#85) (aad60ca)