feat(e2e): standin Suite 5+6 — Rust provider-stack alongside Deno#123
Merged
Conversation
Adds end-to-end coverage for the Rust provider-stack standin (https://github.com/Moonlight-Protocol/provider-stack) as a first-class service in local-dev. The standin runs ON THE SAME stack as the Deno provider-platform, on a separate port, with distinct keys, distinct DB, and distinct OTEL service name — so both can be exercised in the same infra cycle. What landed ----------- Infra (the standin becomes a first-class service): - lib/master-seed.ts: new ROLES.STANDIN_PP role (deterministic per master seed). Distinct from ROLES.PP so the standin's chain identity doesn't collide with the Deno PP. - setup-keys.sh: emits STANDIN_PP_PK / STANDIN_PP_SK to `.local-dev-keys` for downstream consumers. - infra-up.sh: new section 5b spawns the Rust standin alongside the Deno provider (`$BASE_DIR/provider-stack/target/release/provider-stack`, port 3011, OTEL_SERVICE_NAME=provider-platform-standin, dedicated DB `provider_stack_db` auto-created on the existing postgres). Best-effort: skipped with a warning if the binary or keys aren't there yet. - infra-up.sh: pinned `stellar container start local` to `--image-tag-override v639-b1103.1-latest` (the working tag from PR #120 — the rolling `:testing` tag has been rejecting WASM uploads with HostError(Context, InternalError) since 2026-06-15). #120 pinned the docker-compose paths; this pins the CLI path used by up.sh. - down.sh: also stops `.standin.pid` so a re-up doesn't leak the previous standin process onto port 3011. Test (the new Suites 5 + 6): - lifecycle/standin-verify.ts (new): mirror of testnet-verify.ts pointed at :3011 with PP derived from ROLES.STANDIN_PP. Single-PP: no /dashboard/pp/register step (the standin's PP is env-pinned at boot). The rest of the flow (deploy → council → join → approve → on-chain add_provider → watcher promote ACTIVE → deposit/send/withdraw) is byte-identical to testnet-verify.ts. - lifecycle/standin-verify-otel-local.ts (new): wraps the OTEL verifier with `providerServiceOverride: "provider-platform-standin"` so it queries the standin's traces specifically (without disturbing the existing Deno-side verify). - lib/verify-otel-local.ts: new optional `providerServiceOverride` option. Threaded only by the standin verify wrapper; unused on the Deno path. - lib/client/config.ts + bundle.ts + register-entity.ts: optional `urlShape: "multi-pp" | "single-pp"` (default multi-pp). When single-pp, bundle URLs become `/api/v1/provider/entity/bundles` and the entity-register endpoint becomes `/api/v1/provider/entities` — matching the standin's single-PP route shape. Defaulting to multi-pp keeps every existing Deno-targeted call site unchanged. - testnet/events-capture/harness.ts + subscribe.ts: per-script config (ppRole, perSuiteSecret, urlShape) lets the standin script use ROLES.STANDIN_PP, skip the per-suite KDF (the standin's PP is fixed at boot, not per-suite-derived), and use the single-PP WS URL + /dashboard/pp (singular) sanity check. - testnet/run-local.sh: new Suite 5 (lifecycle → standin via events-capture) + Suite 6 (OTEL verify standin), `standin` alias, extends `all` to run all six. Validation ---------- `./testnet/run-local.sh standin` run 15 times from a stable infra. Every run green: perPp:GBKVLUPENRSLQCHPCBJM4HGPIJP43LWIURGWQNBJAQ5JXIVKVHKCV7FR: 12/12 network: 5/5 OTEL: 23 passed, 0 failed Same env-pinned PP across every run, no flakes.
1 task
pselle
added a commit
that referenced
this pull request
Jul 7, 2026
## Summary - The `.local-dev-keys` snapshot committed on `main` predates #123 (Rust provider-stack standin), which added a `STANDIN_PP` role to `setup-keys.sh`'s `ROLES` map - All keys derive deterministically from the shared local-dev master seed (`lib/master-seed.ts`), and `up.sh` regenerates this file on every run — this PR just brings the checked-in copy back in sync with what `setup-keys.sh` actually outputs today - No values changed for any pre-existing role (`ADMIN`, `PP`, `OPEX`, `PAY_ADMIN`, `PAY_SERVICE`, `ALICE`, `BOB`); only the new `STANDIN_PP_PK`/`STANDIN_PP_SK` pair and the regeneration timestamp are added ## Test plan - [x] Diffed against a fresh `./setup-keys.sh` run — output matches this file exactly (modulo timestamp) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds end-to-end coverage for the Rust provider-stack standin as a first-class service in local-dev. The standin runs on the same infra cycle as the Deno provider-platform — separate port, separate DB, separate OTEL service name — so a single
./up.shbrings both up and a single./testnet/run-local.sh allexercises both end to end.What changed
Infra — the standin becomes a first-class service
lib/master-seed.ts: newROLES.STANDIN_PProle. Deterministic per master seed; distinct fromROLES.PPso the standin's chain identity doesn't collide with the Deno PP.setup-keys.sh: emitsSTANDIN_PP_PK/STANDIN_PP_SKto.local-dev-keys.infra-up.sh: new section 5b spawns the Rust standin alongside the Deno provider —$BASE_DIR/provider-stack/target/release/provider-stack, port 3011,OTEL_SERVICE_NAME=provider-platform-standin, dedicatedprovider_stack_dbauto-created on the existing postgres. Best-effort: skipped with a warning if the binary or keys aren't there yet.infra-up.sh: pinnedstellar container start localto--image-tag-override v639-b1103.1-latest— the rolling:testingtag has been rejecting all WASM uploads withHostError(Context, InternalError)since 2026-06-15. PR fix(ci): pin stellar/quickstart to v639-b1103.1-latest (node regression) #120 pinned the docker-compose paths; this pins the CLI path used byup.sh.down.sh: also stops.standin.pidso a re-up doesn't leak the previous standin onto port 3011.Test — new Suites 5 + 6
lifecycle/standin-verify.ts(new): mirror oftestnet-verify.tspointed at :3011 with PP derived fromROLES.STANDIN_PP. Single-PP: no/dashboard/pp/registerstep (the standin's PP is env-pinned at boot). The rest of the flow (deploy → council → join → approve → on-chainadd_provider→ watcher promote ACTIVE → deposit/send/withdraw) is byte-identical.lifecycle/standin-verify-otel-local.ts(new): wraps the OTEL verifier withproviderServiceOverride: "provider-platform-standin"so it queries the standin's traces specifically.lib/verify-otel-local.ts: new optionalproviderServiceOverrideoption. Used only by the standin wrapper; Deno path unchanged.lib/client/{config,bundle,register-entity}.ts: optionalurlShape: "multi-pp" | "single-pp"(defaultmulti-pp). Whensingle-pp, bundle URLs become/api/v1/provider/entity/bundlesand the entity-register endpoint becomes/api/v1/provider/entities— matching the standin's single-PP route shape. Defaulting to multi-pp keeps every existing Deno call site behaviour-identical.testnet/events-capture/{harness,subscribe}.ts: per-script config (ppRole,perSuiteSecret,urlShape) lets the standin script useROLES.STANDIN_PP, skip the per-suite KDF (the standin's PP is fixed at boot, not per-suite-derived), and use the single-PP WS URL +/dashboard/pp(singular) sanity check.testnet/run-local.sh: new Suite 5 (lifecycle → standin via events-capture) + Suite 6 (OTEL verify standin),standinalias, extendsallto run all six.Validation
./testnet/run-local.sh standin— 15 consecutive runs, every assertion green:Same env-pinned PP (
GBKV…CV7FR) on every run, no flakes.Test plan
./down.sh && ./up.sh && ./setup-c.sh./testnet/run-local.sh standin— Suite 5+6 alone, both green./testnet/run-local.sh all— Deno (1-4) + standin (5-6) all six greenstandinseveral times against the same stack — verify stable