Skip to content

test(e2e-live): HMA-orchestrated trade-flow control plane - #16

Merged
vrogojin merged 3 commits into
masterfrom
feat/e2e-live-hma-trade-flow
May 4, 2026
Merged

vrogojin merged 3 commits into
masterfrom
feat/e2e-live-hma-trade-flow

Conversation

@vrogojin

@vrogojin vrogojin commented May 4, 2026

Copy link
Copy Markdown
Owner

Replaces #15 — PR-B merged via squash, which deleted the base branch and auto-closed #15. This PR has the same content rebased onto master.

Summary

Builds on PR #14 (now merged) by adding the trade-ops layer. Demonstrates the full Architecture-B path end-to-end against live testnet:

Test
  ├── sphere host spawn → HMA → escrow + 2 traders          (PR-B)
  └── sphere trader set-strategy / portfolio / list-… /     (this PR)
       create-intent / cancel-intent

Verified live (2026-05-04, 5/5 testnet services HEALTHY)

$ TRADER_E2E_SKIP_PREFLIGHT=1 npx vitest run --config vitest.e2e-live.config.ts \
    test/e2e-live/hma-trade-flow.e2e-live.test.ts
✓ HMA-orchestrated trade-flow control plane (live testnet) (~56s)

The full flow:

  1. sphere wallet init (controller bootstrap)
  2. Boot dist/host-manager.js (HMA)
  3. sphere host spawn × 3 (escrow + Alice + Bob)
  4. sphere trader set-strategy × 2 (configure trusted_escrows)
  5. sphere trader portfolio × 2 (read balances, expect empty)
  6. sphere trader list-intents (empty)
  7. sphere trader create-intent (Alice posts buy)
  8. sphere trader list-intents (verify CREATED, non-terminal)
  9. sphere trader cancel-intent
  10. sphere trader list-intents (verify CANCELLED)
  11. sphere host stop × 3 (parallel teardown)
  12. Manager teardown

Files

File Purpose
test/e2e-live/helpers/sphere-trader.ts (+317) Typed wrappers for every sphere trader subcommand
test/e2e-live/hma-trade-flow.e2e-live.test.ts (+250) Live test exercising the full trader CLI surface
src/cli/main.ts (modified) trader-ctl shim updated to match the same wire shape as sphere-cli's sphere trader … (volume_max, expiry_sec) — direct-docker tests no longer use the broken wire shape either
test/e2e-live/helpers/{scenario-helpers,contracts,sphere-trader,tenant-fixture.test}.ts, plus 4 e2e test files Cascading rename volumeTotal/volume_total/--volume-totalvolumeMax/volume_max/--volume-max for consistency with the trader's ACP wire field

Steelman

Steelman ran on this PR via the wire-shape changes already validated alongside sphere-cli's PR-D (closed/replaced as PR-D2 #8 — now merged). The cascading rename here is mechanical and verified by:

  • grep -rn "volumeTotal\|--volume-total\|volume_total" src/ test/ returns zero hits
  • 651 default tests still pass
  • Live e2e passes in 56s

Default suite

651 tests still pass. Live tests opt-in via npm run test:e2e-live only.

vrogojin added 3 commits May 4, 2026 08:25
Adds the trade-ops layer on top of PR-B's HMA-orchestrated lifecycle
foundation. Demonstrates the full Architecture-B path:

  Test
    ├── sphere host spawn → HMA → escrow + 2 traders          (PR-B)
    └── sphere trader set-strategy / portfolio / list-…       (this PR)

Files:

  test/e2e-live/helpers/sphere-trader.ts (~280 lines)
    Typed wrappers around `sphere trader …` subcommands:
    setStrategy, createIntent, cancelIntent, listIntents,
    listDeals, portfolio, status, waitForDealInState. All accept
    a tenant address (@NameTag, DIRECT://, or hex pubkey) and
    parse the AcpResultPayload JSON shape sphere-cli emits with
    --json. Throws on ok=false with the trader-side error_code +
    message so tests don't repeat the defensive parse.

  test/e2e-live/hma-trade-flow.e2e-live.test.ts (~250 lines)
    Live test: bootstraps controller wallet, boots HMA, spawns
    escrow + Alice + Bob via `sphere host spawn`, then drives
    each trader via `sphere trader …`:
      - set-strategy: configures trusted_escrows on each trader
      - portfolio: reads the (empty) initial balance
      - list-intents: reads the (empty) intent list

    The test is intentionally scoped to the read+config surface.
    Three known issues block the full create-intent / list-deals
    path; all are upstream sphere-cli bugs tracked as follow-ups:

      1. `sphere trader status` calls STATUS over ACP, but STATUS
         is a system-scoped command — the trader correctly rejects
         with UNAUTHORIZED ("System command STATUS can only be
         sent by the host manager"). Controllers should use
         `sphere host inspect <name>` instead. Skipped here.

      2. `sphere trader create-intent` sends `expiry_ms` over the
         wire but trader-service's ACP schema requires
         `expiry_sec`. INVALID_PARAM. One-line fix in sphere-cli.

      3. (Not encountered in this trimmed test but related:)
         `sphere trader create-intent` previously used
         `--volume-total` flag; now `--volume-max` matching the
         trader's `volume_max` ACP wire field. Helper updated.

    A separate file `hma-trade-settlement.e2e-live.test.ts` will
    cover the swap-completion flow (faucet-fund both traders,
    post matching intents, wait for COMPLETED on both sides,
    assert balances reflect the swap) once issues 1-2 are fixed
    in sphere-cli.

Verified live (2026-05-04 testnet, 5/5 services healthy):
  $ npm run test:e2e-live -- hma-trade-flow.e2e-live.test.ts
  ✓ drives the full trader CLI surface against HMA-spawned tenants
  Duration: 39s

Combined with PR-B's lifecycle test:
  ✓ both tests pass in 66s end-to-end

Default suite unaffected: 651 tests still pass.
Now that PR-D fixes sphere-cli's expiry_ms→expiry_sec wire mismatch
and removes the architecturally-broken `sphere trader status` (which
called a system-scoped command over ACP), the full
create-intent → list-intents → cancel-intent → verify-CANCELLED
flow works end-to-end against live testnet.

Verified: 48s (up from 40s with the +3 additional CLI round-trips).
Steelman round 1 on PR-D (sphere-cli #7) found that trader-service's
own `src/cli/main.ts` (the trader-ctl shim used by direct-docker e2e
tests) still emitted `volume_total` / `expiry_ms` on the wire — the
EXACT bugs PR-D fixes upstream. Without this commit, the canonical
sphere-cli would talk correctly to the trader but trader-service's
own tooling would still produce INVALID_PARAM rejections, leaving a
silent half-fix.

src/cli/main.ts:
  - Rename `--volume-total` flag → `--volume-max` (matches the
    trader's `volume_max` ACP wire field per acp-types.ts:23).
  - Convert `expiry_ms` wire param → `expiry_sec` via
    `Math.floor(n / 1000)` matching sphere-cli's fix.
  - CLI-layer guards: reject sub-1000ms expiry with a helpful
    message; reject expiries > 7 days. Mirrors the trader-side
    validation in trader-command-handler.ts:331-342.

Cascade: 7 other test/helper files referenced the old wire shape
and needed renaming for consistency:
  - test/e2e-live/helpers/scenario-helpers.ts (createMatchingIntents
    builder used by direct-docker tests)
  - test/e2e-live/helpers/contracts.ts (MatchingIntents interface)
  - test/e2e-live/helpers/sphere-trader.ts (IntentSummary response
    field; the trader's outbound list-intents response also uses
    `volume_max` per trader-command-handler.ts:143)
  - test/e2e-live/helpers/tenant-fixture.test.ts (unit-test
    assertions on trader-ctl argv)
  - test/e2e-live/negotiation-failures.e2e-live.test.ts
  - test/e2e-live/basic-roundtrip.e2e-live.test.ts
  - test/e2e-live/edge-cases.e2e-live.test.ts
  - test/e2e-live/multi-agent.e2e-live.test.ts

Verified:
  - Default suite: 651/651 tests pass (was 651, no regression)
  - Live e2e (hma-trade-flow): passes in 56s (full
    set-strategy + portfolio + list-intents + create-intent +
    cancel-intent + verify-CANCELLED flow)
  - Zero remaining `volumeTotal` / `--volume-total` / `volume_total`
    references in src/ or test/

Depends on sphere-cli PR #7 for the canonical CLI's matching fix.
@vrogojin
vrogojin merged commit c113a85 into master May 4, 2026
1 check passed
@vrogojin
vrogojin deleted the feat/e2e-live-hma-trade-flow branch May 4, 2026 06:26
@vrogojin
vrogojin restored the feat/e2e-live-hma-trade-flow branch July 15, 2026 14:13
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.

1 participant