Partner reference backend
A zero-runtime-dependency Bun reference for a complete partner edge. It has three persistent credential domains plus a one-shot webhook-test process in the runtime domain, so the real least-privilege boundary is executable without inventing a fourth credential.
| Command | Responsibility | Only Chia secret |
|---|---|---|
bun run start |
scheduled catalog, verified asset mirror, local display projection, consented handoff creation | runtime key |
bun run webhook-receiver |
zero-side-effect ownership proof, exact-byte signature verification, synthetic-only dedupe receipts | webhook secret(s) |
bun run test-webhooks |
request all three synthetic shapes in the selected environment | that environment's runtime key |
bun run finance |
sandbox fixture pagination; immutable production Finance-release synchronization | finance key |
Every command refuses environment variables from another credential domain. test-webhooks intentionally reuses the selected environment's runtime key, persists no secret, and exits.
The fixture's partner_id demonstrates the generic tenant contract, not an integration-specific brand field. Accept only the v2 2–32 character grammar ^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$, preserve the value exactly, and never derive infrastructure or authorization from it.
Run the complete sandbox reference#
The install commands assume you are inside the extracted, verified integration bundle and have its pinned Bun toolchain.
Install the locked dependency graph before starting any reference process. In the delivered bundle, this lockfile is generated against the exact verified SDK tarball under sdk/; in the repository it resolves the adjacent SDK source for development.
cd examples/partner-reference-backend
bun install --frozen-lockfile --ignore-scripts
Terminal 1 — catalog:
cd examples/partner-reference-backend
cp .env.serve.example .env.serve
# Set only CHIA_ENVIRONMENT, CHIA_API_ORIGIN, CHIA_ASSET_ORIGIN, CHIA_RUNTIME_KEY, CHIA_CARE_ORIGIN,
# and optional local PORT/PARTNER_STATE_DIR.
env -i PATH="$PATH" sh -c 'set -a; . ./.env.serve; set +a; bun run start'
Open http://localhost:8787/demo while this sandbox process is running. The reference serves the official clean web renderer from the same origin. It uses the mobile-safe projection, contains no third-party dependency or telemetry, and never exposes the runtime key or authenticated Chia asset URL. The route is intentionally absent in production mode.
Terminal 2 — webhook receiver:
cd examples/partner-reference-backend
cp .env.receiver.example .env.receiver
# Set only CHIA_ENVIRONMENT and CHIA_WEBHOOK_SECRET_CURRENT.
env -i PATH="$PATH" sh -c 'set -a; . ./.env.receiver; set +a; bun run webhook-receiver'
Point the exact registered public HTTPS route at local /webhooks/chia, then inspect the mobile-safe catalog projection:
curl --fail-with-body --silent --show-error \
-H 'X-Demo-Service-State: CA' \
-H "X-Demo-State-Observed-At: $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
http://localhost:8787/catalog | jq
Terminal 3 — all three webhook tests:
cd examples/partner-reference-backend
cp .env.webhook-test.example .env.webhook-test
env -i PATH="$PATH" sh -c 'set -a; . ./.env.webhook-test; set +a; bun run test-webhooks'
Terminal 4 — finance:
cd examples/partner-reference-backend
cp .env.finance.example .env.finance
env -i PATH="$PATH" sh -c 'set -a; . ./.env.finance; set +a; bun run finance'
Expected webhook-test output names all three types as accepted. Acceptance is not delivery proof: confirm the receiver processed all three through the test: true no-side-effect branch.
After the demo returns share_or_neutral, exercise affirmative consent without any identity field. Persist and reuse the UUID only for an uncertain retry of this byte-identical body:
curl --fail-with-body --silent --show-error \
-X POST http://localhost:8787/handoff-session \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $PERSISTED_RANDOM_UUID_V4" \
-H 'X-Demo-Service-State: AZ' \
-H "X-Demo-State-Observed-At: $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--data '{"catalog_item_id":"cat_…","disclosure_version":"hnd_…","consent_attestation":{"affirmed":true,"affirmed_at":"2026-07-22T15:00:00Z"}}'
The demo response exposes only url and expires_at to mobile. The closed Chia response also contains opaque id, object, and the environment-matching livemode; neither response is logged or persisted. A production URL opens Chia's real <Partner> × Chia journey, where Chia collects payment as merchant of record.
What the reference proves#
- Catalog refresh is scheduled and coalesced, uses
ETag, skips unavailable-item asset URLs, verifies each available asset through a commit/abort streaming sink, and atomically swaps the complete in-memory snapshot. - The mirror uses the response
Cache-Controldeadline plus the earliest marketing, regulatory, or handoffvalid_until; request-time checks, an exact-expiry sweep, and cache lifetimes bounded by remaining validity prevent a refresh failure from keeping a card or asset live. A304extends only HTTP freshness and there is no stale-on-error window. /catalogapplies partner-local state evidence and emits onlyhidden,neutral_only, orshare_or_neutral; Chia never receives that evidence.- The official projection is deep-frozen, binds the exact catalog version,
presentation digest and disclosure version, removes the authenticated asset URL, preserves every required block, and exposes its earliest freshness boundary. The included /demo re-resolves before action and on restore, renders disclosure inline, joins double taps into one request, and reuses the exact attempt after an ambiguous failure.
/handoff-sessionrechecks the local share gate, disclosure version, closed body, content size/type, and caller-retained UUID before making the environment-matching call; it forwards no user/account/device/contact/state ID.- Mobile sees random partner-owned image paths, never authenticated Chia asset URLs.
- The receiver handles Chia's exact unsigned ownership challenge in a separate 4 KiB, no-store, zero-side-effect branch; signed events remain capped at 128 KiB and are verified for signature/timestamp/header/envelope/environment before routing, with the test branch first.
- Partner API v2 events use the independently versioned
v1=…signature format and commit only a deduplicated no-op synthetic-test receipt. There are no live handlers, catalog jobs, or finance jobs to enqueue. - Finance exercises short-lived cursor traversal, restarts one expired cursor safely, and stores only synthetic sandbox fixtures or immutable Finance-authored production releases. It rejects release-body collisions, duplicate statement revisions, forks, and incomplete supersession chains.
- The test sender keeps idempotency keys in its own role-specific file store.
Production hardening delta#
The reference is an executable pattern, not a production deployment. Replace these demonstration choices:
| Reference choice | Production requirement |
|---|---|
| caller demo state headers | authenticated partner account service-state, derived server-side |
| in-memory published catalog | durable snapshot metadata plus atomic object/cache promotion |
| local private files | environment-isolated managed database/queue/object storage |
| file synthetic-event dedupe | unique no-side-effect receipt in one durable production transaction |
| one process per local command | separately deployed runtime, receiver, and finance identities; run test-webhooks as an ephemeral runtime-domain job |
| fixed operational console output only | redacted structured metrics/logs containing no business-resource IDs, URLs, payloads, or secrets |
| localhost health checks | authenticated service health and alerting without catalog/consumer data |
Also add bounded full-jitter retry budgets, graceful shutdown/drain, restore tests, concurrent refresh tests, catalog-expiry alarms, asset-integrity alarms, webhook failure/retry monitoring, rotation drills, and separate sandbox/production deployments.
Do not combine the runtime, receiver, and finance credential domains for convenience. Startup refusal is defense in depth; deployment IAM must ensure each persistent process can retrieve only its documented secret and the test job receives the runtime key only while it runs.
Validate#
From this directory:
bun run check
That builds the reference, runs the role/file-store tests, and cleans generated output. Run the repository-level contract checker separately from the bundle root.
From the integration-bundle root, run the cross-platform closed conformance fixture too:
python3 scripts/partner_contracts/check_renderer_conformance.py
The reference intentionally stops at the returned browser URL. In production, Chia's hosted application implements identity, intake, eligibility, checkout, payment, care, support, and fulfillment. The partner does not implement or receive those records.