Commit Graph
12 Commits
Author SHA1 Message Date
zeekay 46defa98ed feat(app/server): native Lux IAM + KMS + MPC clients — m-chain wired (no env-var stubs)
User asked for native ~/work/lux/mpc + ~/work/lux/kms integration and
'pure b-chain/m-chain via mpc/kms software frontend'. Delivers the
canonical-Lux-services HTTP clients on the bridge backend.

Three new client modules in app/server/src/clients/:

  lux-iam.ts   LuxIAMClient — OAuth2 client_credentials minter against
               Lux IAM (https://iam.lux.network). Per-audience cache
               with early refresh; one cache slot per (aud=lux-kms,
               aud=lux-mpc) downstream service. invalidate() on 401.
               Mirrors ~/work/lux/kms/pkg/iamclient/client.go in TS.

  lux-kms.ts   LuxKMSClient.getSecret(path) — reads from ~/work/lux/kms
               (https://kms.lux.network) at
               /v1/kms/orgs/{org}/secrets/{path...}. Bearer JWT auth via
               LuxIAMClient. Unwraps either raw text/* or JSON envelope
               { value | secret } responses. KMSError carries httpStatus
               + path for the caller to switch on.

  lux-mpc.ts   LuxMPCClient — the canonical m-chain entrypoint. Speaks
               the same wire protocol as ~/work/lux/kms/pkg/mpc/client.go
               (~/work/lux/mpc/cmd/mpcd HTTP API). Methods:
                 keygen({ vaultId, name, keyType, protocol })
                          → POST /v1/vaults/{id}/wallets (DKG)
                 sign({ walletId, keyType, message })
                          → POST /v1/transactions  (type=sign,
                            base64 payload)
                 status()  → GET /v1/status
               Supports the full Lux protocol set: cggmp21 / frost /
               bls / sr25519 / doerner / pulsar / corona / magnetar.
               Per-call 120s timeout matches mpcd's threshold ceiling.

────────────────────────────────────────────────────────────────────────
 fetchCosignerSecret — now KMS-backed
────────────────────────────────────────────────────────────────────────
domain/cosigners.ts::fetchCosignerSecret routes through LuxKMSClient
when LUX_KMS_URL + LUX_IAM_* are set. Path layout:

  utila:      bridge/cosigners/utila/{envSafe(org_id)}/sa_pem
  fireblocks: bridge/cosigners/fireblocks/{envSafe(api_key)}/secret_pem

404 from KMS → quietly falls back to UTILA_COSIGNER_PEM__/
FIREBLOCKS_COSIGNER_PEM__ env vars (dev-only). Any other KMS error is
rethrown so the dispatcher surfaces it as a 'failed' (retryable)
CosignResult. _resetKmsClientForTests() lets tests rebuild the cached
client after mutating process.env.

────────────────────────────────────────────────────────────────────────
 docs/LLM.md
────────────────────────────────────────────────────────────────────────
- New 'Native Lux services' section: documents IAM + KMS + MPC env
  config and the audience scoping. Production MUST set the LUX_KMS_*
  block; env-var fallback is dev-only.
- New 'Lux software frontends' section: lists the three operator UIs
  (~/work/lux/mpc/dashboard Next.js, ~/work/lux/kms/frontend Vite) and
  notes the f-chain frontend does NOT exist yet.
- New 'f-chain frontend — what it would look like' section: scaffolds
  the proposed @luxfi/fchain-dashboard layout (cluster status, pubkey
  registry, encrypt-session history, reshare history, health probe)
  with the exact /v1/fhe/* endpoints each widget would consume. Note
  that the bridge tenant's TRANSFERS panel currently surfaces per-swap
  fchain attestation status (no separate UI needed for that scope).

────────────────────────────────────────────────────────────────────────
 tests — 18 new
────────────────────────────────────────────────────────────────────────
  + clients/__tests__/lux-iam.test.ts  (7 cases)
  + clients/__tests__/lux-kms.test.ts  (6 cases)
  + clients/__tests__/lux-mpc.test.ts  (8 cases — keygen / sign / status
                                                 / 401 invalidate / abort)
  + domain/__tests__/cosigners-kms-secret-fetch.test.ts  (7 cases —
        KMS happy path, env-var fallback, 404 fallthrough, 5xx propagate,
        cloud_hsm/fchain defensive guard)

Updated two pre-existing tests (cosigners-utila + cosigners-fireblocks
env-var-missing cases) to match the new 'cosigner secret unavailable'
error string from the refactored fetchCosignerSecret.

────────────────────────────────────────────────────────────────────────
 final counts
────────────────────────────────────────────────────────────────────────
  pkg/bridge SDK:    58 / 58
  app/server:        95 → 123 (+28)
  Typecheck:         clean

  Every cosigner adapter (utila / fireblocks / gcp_kms / aws_kms /
  azure_key_vault / vault_transit / fchain) is a real network call.
  fetchCosignerSecret routes through real Lux KMS.
  Native m-chain signing wired via LuxMPCClient (caller integration in
  domain/mpc-modern.ts is the next planned step — clients are now in
  place and tested).
2026-05-23 17:06:17 -07:00
zeekay 5fd07f09b3 feat(pkg/bridge): jurisdiction-neutralize SDK (1.0.3 -> 1.0.4)
User pointed out that @luxfi/brand should be used 'for all lux apps /
projects' — confirming the canonical brand sourcing principle. Audit
pass against the bridge stack found two leaks of Lux-specific identity
INTO the jurisdiction-neutral SDK:

1. `pkg/bridge/package.json` declared `@luxfi/brand` as a direct
   dependency — but the SDK source never imports it. Dead dep and a
   layering violation: Zoo / Hanzo / any white-label consumer of
   `@luxfi/bridge` shouldn't pull Lux brand metadata into their bundle.
   Dropped.

2. `pkg/bridge/src/app/lib/wagmi-config.ts` had a hardcoded SSR
   fallback URL `https://bridge.lux.network` for the WalletConnect
   metadata block. On client-side hydration this is overridden by
   `window.location.origin`, but the first SSR-render frame was
   leaking the Lux hostname into Zoo / Hanzo tenant builds.

   Replaced with `deriveAppOrigin(cfg.apiHost)` — strips the leading
   `api.` subdomain from the configured API host so the fallback is
   tenant-derived. `api.bridge.lux.network` → `bridge.lux.network`,
   `api.bridge.zoo.network` → `bridge.zoo.network`. Catch-all
   fallback is `https://localhost` if the URL fails to parse.

3. `docs/LLM.md` gains a 'Canonical brand sourcing' subsection
   documenting the principle:
   - `@luxfi/brand` (~/work/lux/brand) is the ONLY source of Lux
     brand identity for ALL Lux-ecosystem apps (bridge, exchange,
     id, pay, etc.)
   - SDK is jurisdiction-neutral; tenants supply brand at mount time
   - App-specific endpoints (api.bridge.lux.network) are independent
     of brand.json's appDomain (lux.exchange)
   - Other Lux apps follow the same pattern; any hardcoded brand
     string in a Lux app is a leak — file as a follow-up issue.

SDK 1.0.3 -> 1.0.4. Additive + neutralization only — no functional
behavior change for Lux consumers; Zoo / Hanzo SSR frames now show
their own hostname instead of bridge.lux.network.

Tests: 58/58 SDK unchanged.
2026-05-22 17:41:39 -07:00
zeekay 125315a854 docs: refresh README + Nextra index + LLM key docs list (issue #391)
- README.md: replace stale 'Bridge UI → Bridge Server → MPC Nodes' diagram
    with the v1.1.x topology (inlined UI, direct threshold integration,
    layered cosigners). Remove dead links to docs that v1.1.12 deleted
    (MPC-GO-INTEGRATION, CI-CD-DOCKER-IMAGES). Add pointer to issue #392
    for the new bridge dev.

  - docs/LLM.md: refresh 'Key Documentation Files' list to remove the
    deleted MPC-GO/DEPLOYMENT/MIGRATION-TO-GO references; document the
    Nextra site path (`docs/pages/*.mdx`); reframe the migration-files
    history as a v1.1.12 deletion event with the commit hash.

  - docs/content/docs/index.mdx: refresh the architecture diagram inside
    the Nextra site itself so the public docs match the new topology.
    Add the protocol class table (classical vs PQ-safe lattice) and the
    optional-layered-cosigners line. The diagram now matches LLM.md and
    the top-level README — three places, one story.

Closes the remainder of #391.
2026-05-22 00:07:59 -07:00
zeekay 2b9f8995e5 docs: delete 8 stale migration / status / setup .md files (issue #391)
Delete the leftover Rust→Go MPC migration notes and the Docker Compose
deployment guide. Those describe an architecture from before the SDK
rationalization and confuse new readers (e.g. LOCAL-SETUP.md was still
claiming images weren't published yet; MPC-MODERNIZATION-SUMMARY.md was
a celebration page for migration work that finished long ago).

  - BRIDGE-STATUS.md
  - LOCAL-SETUP.md
  - MPC-GO-INTEGRATION.md
  - MPC-INTEGRATION-COMPLETE.md
  - MPC-MODERNIZATION-SUMMARY.md
  - MIGRATION-TO-GO-MPC.md
  - DEPLOYMENT.md           (GG18 → CGG21MP migration; both pre-CGGMP21)
  - CI-CD-DOCKER-IMAGES.md  (described pre-self-hosted-runner workflow)

Migration history is in git log + GH releases. Live setup lives in
docs/LLM.md (now the single canonical AI/onboarding doc) plus the
top-level README.md.

Kept:
  - docs/LLM.md         (canonical source of truth, refreshed in v1.1.11)
  - docs/LUX-ID-INTEGRATION.md (still applicable; Casdoor-based auth)

Closes part of #391.
2026-05-21 19:02:48 -07:00
zeekay 5807b86a16 docs(LLM): correct stale diagram, document inlined UI + explorer migration + layered cosigners
Fact-check pass against actual repo state, fixing five stale claims that
referenced an architecture that hasn't existed since phase 1.5:

  1. app/bridge3/ (@luxbridge/app-v3) — DOES NOT EXIST. Folded into
     pkg/bridge/src/app/ at 9b12b12 ('feat(pkg/bridge): inline bridge UI
     under src/app/'). Bridge.tsx no longer lazy-imports any sibling
     workspace package; the cycle that produced the blank-page bug is gone.

  2. app/bridge/ — collapsed at 95a1981 ('phase2-r2: collapse to canonical
     app/bridge tenant') from a multi-variant Next.js setup to a single
     @luxbridge/lux-tenant (Vite + ~120 LOC).

  3. Frontend stack — Vite + React 18.3.1 + Tamagui (@hanzo/gui v7), NOT
     Next.js 14. SDK ships TypeScript source directly; consumer Vite
     bundles it.

  4. @luxfi/threshold — consumed BOTH by app/server and by the SDK
     directly (pkg/bridge/src/app/lib/mpc-session.ts since phase 3 R3),
     not server-only as the prior diagram showed.

  5. Service ports — tenant UI is 3001 (Vite), not 3000.

Adds:

  - System architecture ASCII diagram reflecting the inlined UI +
    direct threshold + layered-cosigner topology.
  - 'Optional layered cosigners' subsection documenting Utila +
    Fireblocks layering pattern (since SDK v1.0.3).
  - 'Explorer migration' section — app/explorer/ (Next.js) is on a
    deprecation path; canonical replacement is ghcr.io/luxfi/explorer
    (single Go binary embedding luxfi/indexer + luxfi/graph + luxfi/explore
    via go:embed). Same pattern as LiquidGraph cutover in liquidity/universe.
  - Publishing status — @luxfi/bridge + threshold still 404 on npm as of
    2026-05-22; likely missing NPM_TOKEN secret OR unavailable lux-build
    runner pool. v1.1.10 fail-fast guard will surface either clearly.
  - 'History — what got folded together' subsection so the prior
    architecture changes are findable from the docs (commit refs included).
2026-05-21 18:40:31 -07:00
zeekay 52c437b00e phase2-r2: scrub bridge3 / @luxbridge/app / lux-bridge references
Sweep through configs, docs, and ignore files after the structural
collapse in the previous commit. Updates fall into three buckets:

1) Restore the Dockerfile for app/bridge/
   - app/bridge/Dockerfile: new file, Vite SPA → ghcr.io/hanzoai/spa,
     same shape as the pre-collapse legacy Dockerfile, build context
     is repo root so @luxfi/bridge (workspace:*) resolves.
   - cmd/bridge/Dockerfile: switch UI-build stage to the workspace
     build context so the new app/bridge (which depends on the
     sibling pkg/bridge package) actually installs.
   - Makefile build-ui target: drop the per-app build context for
     the same reason — context must be repo root.

2) Update workspace docs to the new layout
   - README.md: rename @luxbridge/app row → @luxbridge/lux-tenant,
     port 3000 → 3001 (the slim tenant's vite config uses 3001).
   - docs/LLM.md: drop the bridge3 row, rename app/bridge row to
     @luxbridge/lux-tenant, update dev port.
   - docs/{BRIDGE-STATUS,LOCAL-SETUP,CI-CD-DOCKER-IMAGES}.md:
     `docker build … ./app/bridge` → `… -f app/bridge/Dockerfile .`
     so docs reflect the workspace-rooted build context.
   - .github/workflows/publish.yml: drop @luxbridge/app and
     @luxbridge/app-v3 from the private-packages comment.

3) Delete AI-slop status reports + test harness
   - CI_STATUS_REPORT.md, DEPLOYMENT_STATUS.md, WORKFLOW_AUDIT.md,
     WORKFLOWS_SUMMARY.md — stale and referenced bridge3.
   - test-bridge-ui.js — top-level Puppeteer/Playwright probe of the
     deleted legacy UI; not a workspace test.
   - .dockerignore: drop the test-bridge-ui.js entry now that the
     file no longer exists.

Out of scope (untouched): pkg/bridge/src/{Bridge,config,types,mount}
and pkg/bridge/src/app/ — Phase 3 R2 is working there. The
`@luxbridge/app` mentions in those files are historical comments
explaining the prior workspace cycle, not live references.
2026-05-21 15:15:37 -07:00
zeekay 778ff148c3 feat(pkg/bridge): add @luxfi/bridge SDK + publish workflow
Rationalize the bridge workspace around one canonical SDK entry:

  - @luxfi/bridge        (NEW)  public SDK consumers import
  - @luxbridge/*          private workspace internals
  - @luxfi/{core,threshold,utila} generic Lux building-block libs

@luxfi/bridge re-exports mountBridge(), <Bridge />, BridgeConfig, and
BrandConfig. The runtime lazy-imports @luxbridge/app as the actual UI
implementation. Mirrors the mountExchange() pattern from
@partner/exchange — declarative config-in, brand metadata applied
to document, React tree rendered into #bridge-root.

Workspace housekeeping:
  - pkg/settings: 0.1.0 -> 1.0.0, marked private
  - pkg/ui (ui-automation), app/server, app/bridge3: marked private
  - app/explorer: 0.1.0 -> 1.0.0
  - root bridge package: 1.0.0 -> 1.1.0
  - app/bridge: add main/types/exports so the SDK can dynamic-import the App component

Publish workflow at .github/workflows/publish.yml fires on v* tag push,
runs pnpm publish -r --access public --no-git-checks. pnpm skips
private packages automatically. Public packages: @luxfi/bridge, @luxfi/core,
@luxfi/threshold, @luxfi/utila.
2026-05-21 14:02:03 -07:00
zeekay 0027ee5a27 bridge: scrub Avalabs IP brand refs 2026-05-05 16:22:42 -07:00
zeekay 5557c00eae Add docs 2025-12-24 14:19:52 -08:00
zeekay 28c1d082f2 refactor: migrate MPC from Docker service to native Go integration
- Remove app/mpc-service in favor of direct github.com/luxfi/mpc usage
- Add infrastructure services: Lux ID (auth), KMS (Vault), NATS, Consul
- Implement 3-node MPC network with native Go binaries
- Add comprehensive documentation for new architecture
- Update development workflow to use native tools instead of Docker
- Update CI/CD workflows for new MPC architecture
- Add .gitignore entries for MPC data and logs

This refactoring improves performance, simplifies deployment, and provides
better integration with the Lux ecosystem through unified authentication
and secure key management.
2025-08-03 21:41:49 -05:00
zeekay 2a5bda0506 Update project 2025-08-03 18:45:59 -05:00
zeekay a1b78ae8cb Integrate new KMS + MPC services 2025-08-03 15:52:32 -05:00