32 Commits
Author SHA1 Message Date
zeekay f050efbaf0 Merge branch 'main' of github-zeekay:luxfi/bridge
# Conflicts:
#	cmd/bridge/admin_routes_test.go
#	cmd/bridge/api.go
#	cmd/bridge/estate_test.go
#	cmd/bridge/main.go
#	cmd/bridge/swaps_handler_test.go
#	internal/broadcast/client.go
#	internal/depositcheck/client.go
#	internal/txassembler/rpc_provider.go
#	pkg/bridge/package.json
#	pkg/bridge/src/app/styles/theme.css
2026-09-01 20:07:24 -07:00
zeekay c817afd5c0 bridge: the operator surface gets its own listener
The swap list answered anonymously with every swap id, the MPC signature
minted for it and the signed destination tx, on the port the Ingress
publishes. /metrics named the release wallets and reported which of them
could not sign. The deposit poll turned an anonymous request into a
source-chain RPC call with caller-chosen arguments.

All three move to a second listener, BRIDGE_ADMIN_ADDR, along with the
swap mutators, which still need BRIDGE_ADMIN_ROUTES on top. The edge
routes a port, so a port is the thing that can be left unrouted: k8s
publishes 8080 and gives the operator surface 8081, and the ServiceMonitor
scrapes there. A swap read by id keeps the swap's progress and drops the
signature and the raw tx; the list on the operator port carries both.

The legacy proxy exposed the same list twice. `/api/swaps/*` matched the
empty remainder and so forwarded GET /api/swaps to the backend's list;
`+` requires a sub-path. `/v1/bridge/swaps/*` forwarded arbitrary
sub-paths into /swaps/… after the prefix strip — the backend mounts its
swap router at /api/swaps, so that path space holds no routes and the
forwarder only ever produced a 404.
2026-09-01 19:39:22 -07:00
zeekay b36c67dd96 the face is Zen, and it ships from @hanzo/font
One family. Font stacks name Zen and fall back to the native faces, tokens
name the role rather than a face, and the packages that used to supply a
face now point at @hanzo/font.

Self-hosted @font-face blocks are removed rather than renamed: rewriting the
family in one would leave a src pointing at a file this repo no longer ships.
@hanzo/font carries the binaries and declares the faces, so the local copies
go with the declaration that used them.

Comments naming a face we no longer use are deleted, not reworded.
2026-09-01 08:19:35 -07:00
venuswhispersandzeekay b24ee7f0a2 fix(bridge): BTC release confirmation gate + RBF rebuild on stale fee
Port of f3e25de from preserve/lux-bridge-golive onto main's
architecture. A BTC release now parks in
bridge_transfer_pending_confirmation on mempool admission and only
completes once mined; a release unconfirmed past --btc-confirm-timeout
(or fee-rejected at submit) is reset for re-sign at a bumped RBF
feerate — PreSign takes MinFeeRateSatPerVB as a floor over the live
estimate, and the paid rate persists on the swap (LastFeeRate) so each
rebuild strictly out-bids the last (BIP-125). Rebuild cycles share one
ceiling (default 5); past it the swap fails loudly. The broadcast
client answers confirmation status from the same mempool.space base it
posts to; /metrics gains bridge_btc_confirm_checks_total /
_timeouts_total / bridge_broadcast_rebuilds_total.
2026-08-07 22:19:29 -07:00
venuswhispersandzeekay 49bcf61703 feat(bridge): release-wallet signability monitoring + alert rules
Port of the wallet-health work from preserve/lux-bridge-golive onto
main's architecture: canary-sign poller (10m default) against every
minted release wallet, cached snapshot surfaced on /metrics as
bridge_release_wallet_signable / _sign_latency_ms / _last_check_age,
PrometheusRule + ServiceMonitor for the o11y stack, and the operator
runbook section (re-mint, don't retry). Catches the June key-share
desync failure mode before a real payout does.
2026-08-06 21:27:25 -07:00
zeekay 8234dcd552 kms.lux.cloud is the brand host; kms.lux.network is retired
Caught on a second pass: grep -I treats these as binary and skipped them, so the
first sweep reported clean while they still named a host that no longer resolves.
2026-08-05 08:08:17 -07:00
fd3bc75a29 bridge: sync latest — docs trim, tenant config, internal broadcast/substrate/txassembler fixes (#406)
Squash of the local main lineage onto the canonical origin/main. Net tree only
(62 files): stale docs pages removed, tenant config + tests updated, minor Go
fixes, refreshed opnet-watcher build. No third-party white-label branding in
code or history.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-07 12:39:25 -07:00
zeekay e25cf136bc docs(LLM): record v1.1.41 chain-support ground truth + authoritative gate + follow-ups
Corrects the stale 'Solana coming soon'/TODO comments: per-chain inbound/outbound
matrix, XRP native (testnet live, mainnet gated), the server-side withdrawal gate,
and the tracked mainnet-readiness follow-ups (admin auth, IDOR, depositcheck quorum).
2026-06-26 10:18:02 -07:00
Abhishek KrishnaandGitHub 56a583189a docs: refresh Nextra site + complete docs/*.md fold (closes #391) (#404)
* docs: fold loose docs/*.md into Nextra content/docs/ tree (issue #391)

The four MPC-migration .md files plus BRIDGE-STATUS / LOCAL-SETUP /
DEPLOYMENT / CI-CD-DOCKER-IMAGES were already deleted in 2b9f899 (v1.1.12).
The remaining loose docs at docs/ root (INTEGRATIONS, LUX-ID-INTEGRATION,
operator-runbook, operator-deploy-phase-1-4) were still current but lived
outside the Nextra page tree, so the site only ever served Home + Architecture.

Move them into docs/content/docs/*.mdx so the Nextra build can surface them:

  docs/INTEGRATIONS.md              -> docs/content/docs/integrations.mdx
  docs/LUX-ID-INTEGRATION.md        -> docs/content/docs/lux-id-integration.mdx
  docs/operator-runbook.md          -> docs/content/docs/operator-runbook.mdx
  docs/operator-deploy-phase-1-4.md -> docs/content/docs/operator-deploy.mdx

docs/LLM.md stays at docs/ root because it's the symlink target for
AGENTS.md (and any future CLAUDE.md / GEMINI.md), per the .gitignore.

Content of the moved files is unchanged in this commit.

* docs: wire content/docs/* into Nextra pages, refresh _meta + index (issue #391)

Add Nextra page wrappers for each moved doc so the site sidebar surfaces the
full set:

  docs/pages/integrations.mdx        -> imports content/docs/integrations.mdx
  docs/pages/lux-id-integration.mdx  -> imports content/docs/lux-id-integration.mdx
  docs/pages/operator-runbook.mdx    -> imports content/docs/operator-runbook.mdx
  docs/pages/operator-deploy.mdx     -> imports content/docs/operator-deploy.mdx

Refresh docs/pages/_meta.json to list the new pages in display order:
  Home -> Architecture -> Integrations -> Operator Runbook -> Deploy Guide
  -> Lux ID -> (External) LLM Knowledge Base, GitHub.

Refresh docs/pages/index.mdx:
  - replace the legacy "make up && make start-mpc-nodes" quickstart (predates
    the unified Go binary) with the docker run pattern for ghcr.io/luxfi/bridge.
  - point SDK consumers at pkg/bridge README + mountBridge.
  - call out the post-quantum-safe protocol options (pulsar, corona, magnetar)
    alongside the classical cggmp21/doerner/frost/bls set.
  - link docs/LLM.md as the canonical AI/onboarding source of truth.

Build verified: pnpm install && pnpm build prerenders 8 static pages
(index, docs, integrations, lux-id-integration, operator-runbook,
operator-deploy, plus _app and 404).

* docs: update README/LLM.md/REQUIREMENTS pointers for the new layout (issue #391)

The loose docs/*.md set at docs/ root was folded into docs/content/docs/*.mdx
in the previous two commits. Update the three places that still point at the
old paths or describe the old layout:

  - README.md: drop the direct link to docs/LUX-ID-INTEGRATION.md; point
    readers at the Nextra site (`pnpm --filter @luxfi/bridge-docs build`)
    and call out the new content/docs/ + pages/ split.
  - docs/LLM.md: refresh "Key Documentation Files" to list every
    content/docs/*.mdx page and explain why docs/LLM.md stays at root.
  - REQUIREMENTS.md: update the §4 tree comment and the §7 row 1.5 status
    note so they reflect the v1.1.13 fold.

No file content moves in this commit — pointers only.

* docs: regenerate docs/out static site for the 8-page Nextra build (issue #391)

`docs/out/` is the static export served at the GitHub Pages mirror. Rebuild
it with `pnpm --filter @luxfi/bridge-docs build` so the artifact contains
all six content pages (index, docs, integrations, lux-id-integration,
operator-runbook, operator-deploy) plus _app and 404.

No source code or docs content changes in this commit — build artefacts only.
2026-06-22 22:13:50 -07:00
zeekay 34f82eaa71 scrub branding + corona→corona (OSS brand hygiene) 2026-06-10 23:44:29 -07:00
zeekay 5bca705844 docs: bump Go reference 1.26.x → 1.26.4
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6;
this prose-doc catch-up keeps the runbook in lock-step with the
actual Dockerfile/go.mod pin.
2026-06-07 10:49:58 -07:00
zeekay 1f5dd99c12 brand: audit, rip non-lux references, add .well-known/bridge.json
Rule: luxfi/bridge ships ONLY the Lux brand. Foreign-org bridge tenants
(Hanzo, Zoo, Pars, SPC, ) live in their own repos as thin
shims that consume @luxfi/bridge plus their own brand package.

- rm manifests/tenants/{hanzo,zoo,pars,spc}.yaml (carried foreign-brand
  logos/colors/names into a Lux repo)
- REQUIREMENTS.md: drop  tenant goal, drop Phase 2
  Zoo-tenant stand-up + Hanzo-as-tenant deliverables, drop
  @zooai/brand / @hanzoai/brand publication tasks; scope tenant work
  to Lux only and embed target to luxfi/exchange
- docs/LLM.md (symlinked as CLAUDE.md/AGENTS.md/QWEN.md/GEMINI.md):
  drop @zooai/brand / @hanzoai/brand from the architecture legend;
  rewrite "Hanzo-side bridge" section as "foreign-brand tenants live
  in their own repos"
- add app/bridge/public/.well-known/bridge.json declaring brandId=lux,
  domain bridge.lux.network, peers [] (federation peers via runtime
  ConfigMap), capabilities [bridge, mpc], apiVersion 1
- add BRAND-AUDIT.md documenting findings + actions

Kept (not org brand): "Liquid <TOKEN>" wrapped-asset names are Lux's
own bridge token brand (Liquid BTC, Liquid ETH, ...), wrapper minted
on Lux C-Chain per manifests/schema.yaml. Kept (chain identity):
manifests/tenants/lux.yaml, manifests/chains/*, chain RPC config,
teleporter contracts.
2026-05-29 14:25:39 -07:00
zeekay 90e4d49c68 ops: production network configs + operator deploy doc (mainnet + testnet)
Operator-facing configuration assets from origin/whispers/bridgev2.
No code changes — purely declarative configs and ops docs.

  cmd/bridge/networks.mainnet.yaml (NEW, 270 LOC)
  cmd/bridge/networks.testnet.yaml (refresh, +186 LOC)
    Per-network deposit + release wallet configuration for the
    cmd/bridge daemon. mainnet config is the first production-ready
    file in tree.

  compose.mainnet.yml (NEW, +78 LOC)
  compose.testnet.yml (refresh, +56 LOC)
    Compose stacks for the standalone mainnet/testnet deployments
    — Postgres + bridge-server + bridge-ui, MPC/KMS/IAM env blocks
    set per environment.

  docs/operator-deploy-phase-1-4.md (NEW, 168 LOC)
    Phase 1.4 deploy runbook: what cmd/bridge expects from
    BridgeVM, mpcd, KMS, and IAM at boot, and how to wire them in
    a real prod cluster. Pairs with REQUIREMENTS.md §13 to bridge
    spec → deploy.

Build + cmd/bridge tests (5.0s) clean.

NOT included in this PR (saved for follow-ups):
  - k8s/bridge-deployment.yaml — 199 LOC delta; review separately
    so deployment edits aren't bundled with new config files
  - REQUIREMENTS.md R6 spec refresh — track in its own doc PR
  - app/bridge/src/bridge.config.ts Lux mainnet/testnet wagmi
    additions — small but a tenant-frontend change, separate slice
2026-05-28 20:20:00 -07:00
zeekay 7282219e12 merge: pull main (CI/docker/docs cleanup, brand-neutral)
# Conflicts:
#	.dockerignore
#	app/bridge/package.json
#	compose.local.yml
#	pkg/bridge/src/app/hooks/useTransfers.ts
#	pnpm-lock.yaml
2026-05-28 01:07:23 -07:00
venuswhispers b1241c9fda feat: added mpc sign option 2026-05-27 14:49:55 +02:00
zeekay 8f075365ae chore: brand-neutral cleanup — remove cross-tenant references 2026-05-25 15:12:52 -07:00
zeekay 3eac448d43 docs(LLM): ZAP serialization — canonical at ~/work/zap, @zap-proto npm, no capnp-es
User directive (2026-05-24): 'no capnp-es must be zap-es ... keep all
zap brand neutral in ~/work/zap, zap-proto github etc ... should be
npm @zap-proto matching'.

Audit confirmed:
  - The bridge has ZERO capnp-es references (every wire call is JSON
    over HTTP via fetch). Bridge is clean.
  - Canonical ZAP repo is ~/work/zap (not ~/work/lux/zap or
    ~/work/hanzo/zap — those are forks slated for consolidation upstream).
  - TS implementation lives at ~/work/zap/zap-js (package name
    @zap-proto/zap). It already exists as pure TS — no source file
    imports capnp-es, despite the dep being listed in package.json
    (stale entry, removal queued for next ZAP TS publish).
  - WASM binding: @zap-proto/wasm at ~/work/zap/zap-wasm.
  - npm @zap-proto/* scope is the canonical brand-neutral home.

This commit just adds a doc section so the next dev (or me, next
session) doesn't accidentally  ERR_PNPM_ADDING_TO_ROOT  Running this command will add the dependency to the workspace root, which might not be what you want - if you really meant it, make it explicit by running this command again with the -w flag (or --workspace-root). If you don't want to see this warning anymore, you may set the ignore-workspace-root-check setting to true. when a future bridge
surface needs binary RPC. The rule is:
  use @zap-proto/zap (pure TS, no third-party Cap'n Proto dep)
  do NOT publish @luxfi/zap-* or @hanzoai/zap-* (forks the wire format)
  source-of-truth for wire format: ~/work/zap/README.md +
                                   ~/work/zap/zap-js/src/protocol.ts
2026-05-24 01:22:25 -07:00
zeekay 37ebba25e4 docs: generic integration patterns (Go side) 2026-05-24 01:13:52 -07:00
zeekay 8a8942ca89 feat(app/server): brand-neutral env + classes; drop NATS/Consul; m-chain via lux/mpc HTTP
User directive: 'drop LUX_ keep it brand neutral do not use nats/consul
must use standalone ~/work/lux/mpc with our native ~/work/lux/consensus
or b/m-chains'.

This commit lands all three asks.

────────────────────────────────────────────────────────────────────────
 Brand neutralization
────────────────────────────────────────────────────────────────────────
Env vars renamed (LUX_* → BRIDGE_*):
  LUX_IAM_ISSUER           → BRIDGE_IAM_ISSUER
  LUX_KMS_URL              → BRIDGE_KMS_URL
  LUX_KMS_ORG              → BRIDGE_KMS_ORG
  LUX_KMS_CLIENT_ID        → BRIDGE_IAM_CLIENT_ID
  LUX_KMS_CLIENT_SECRET    → BRIDGE_IAM_CLIENT_SECRET
  LUX_MPC_URL              → BRIDGE_MPC_URL
  (+ BRIDGE_MPC_WALLET_ID new — default wallet for native sign)

Client classes renamed (Lux* → brand-neutral):
  LuxIAMClient   → IAMClient
  LuxKMSClient   → KMSSecretClient   (avoids collision w/ AWS SDK's KMSClient)
  LuxMPCClient   → MPCClient

Audience strings renamed (lux-* → bare service name):
  'lux-kms' → 'kms'
  'lux-mpc' → 'mpc'

File renames:
  src/clients/lux-iam.ts  → src/clients/iam.ts
  src/clients/lux-kms.ts  → src/clients/kms.ts
  src/clients/lux-mpc.ts  → src/clients/mpc.ts
  (+ matching __tests__/ files)

────────────────────────────────────────────────────────────────────────
 NATS + Consul: gone
────────────────────────────────────────────────────────────────────────
Deletions:
  - app/server/src/services/mpc-service.ts      (498 LOC NATS+Consul wrapper)
  - app/server/src/utils/trigger-keygen.ts      (dev script, NATS)
  - app/server/src/scripts/trigger-keygen.ts    (dev script, NATS)
  - app/server/src/scripts/test-signing.ts      (dev script, NATS)
  - app/server/src/types/nats.d.ts              (vendored type stubs)
  - consul + nats sections of app/server/src/types/index.d.ts
  - nats + consul devDependencies in app/server/package.json
  - NATS + Consul + Vault containers in compose.local.yml

Rewritten:
  - app/server/src/domain/mpc-bridge.ts (497 → 197 LOC)
      Preserves the public surface (bridgeMPC.initialize() /
      .generateMPCSignature() / .completeSwap() / .getHealthStatus())
      so domain/mpc-modern.ts callers stay untouched. Internally:
        - One MPCClient HTTP call replaces the NATS publish + subscribe
          pub/sub dance. mpcd handles the threshold round atomically.
        - Consul KV completion marker replaced with Prisma's
          Swap.metadata_sequence_number update (single source of truth).
        - Lazy IAM + MPCClient construction so the bridge boots cleanly
          when BRIDGE_MPC_URL / BRIDGE_IAM_* are unset (standalone mode).
          Sign calls return a clear error rather than crashing the
          process.
  - app/server/src/server.ts startup: no more mpcService.initialize();
      bridgeMPC.initialize() now soft-fails (logger.warn) on missing
      env. /health endpoint reads through bridgeMPC.getHealthStatus()
      which reports { online: 0, total: 0, standalone: true } when
      MPCClient isn't configured.
  - compose.local.yml: replaces 6-service NATS/Consul/Vault topology
      with bare 3-service (iam + iam-db + bridge postgres). Out-of-band
      mpcd + KMS instructions documented in the file header.

────────────────────────────────────────────────────────────────────────
 docs/LLM.md
────────────────────────────────────────────────────────────────────────
All LUX_* env mentions retargeted to BRIDGE_*. The 'Native Lux services'
section now describes the HTTP-only, env-neutral integration pattern.
Standalone mode section unchanged in shape but with refreshed env names.

────────────────────────────────────────────────────────────────────────
 Tests + typecheck
────────────────────────────────────────────────────────────────────────
  SDK pkg/bridge:    58 / 58
  Server app/server: 123 / 123 (no regression — same set as v1.1.21
                                with renamed env vars)
  Typecheck:         clean on both packages

────────────────────────────────────────────────────────────────────────
 Net effect
────────────────────────────────────────────────────────────────────────
Bridge backend is now genuinely brand-neutral:
  - No 'LUX_' in any env var (the BRIDGE_ prefix is service-scoped, not
    brand-scoped; same prefix the SDK uses for runtime config)
  - No NATS, no Consul anywhere in the codebase or compose files
  - Native m-chain signing goes through HTTP to mpcd (the canonical
    ~/work/lux/mpc daemon, github.com/luxfi/mpc), one round-trip per
    sign, with the same wire protocol as ~/work/lux/kms/pkg/mpc/client.go
  - Standalone mode preserved: when BRIDGE_MPC_URL is unset, the bridge
    runs without crashing; sign calls return a clear error
2026-05-23 20:06:36 -07:00
zeekay fb59395f4b feat: standalone compose + LLM.md standalone audit + Hanzo non-existence note
User asked 'make sure that bridge can work standalone? ~/work/hanzo/teleport
and ~/work/hanzo/bridge' — both Hanzo paths confirmed not to exist; the
canonical Lux bridge is split across ~/work/lux/teleport (Warp 2.0
protocol, LP-021v2 / LP-7330) and ~/work/lux/bridge (UI + SDK + shim
server, this repo).

This commit answers the 'standalone' part:

compose.standalone.yml — bare three-service topology:
  - postgres (state)
  - bridge-server (API, optional LUX_* env stubs commented)
  - bridge-ui (Vite SPA via ghcr.io/luxfi/bridge image with BRIDGE_* env)

  NO Casdoor, NO Vault, NO NATS, NO Consul, NO 3-node MPC cluster.
  Every external Lux service is OPTIONAL at runtime — the backend
  graceful-degrades when the corresponding env block is unset and picks
  the integration up when it appears.

docs/LLM.md gains:
  - 'Standalone mode' section: docker compose recipe, what's
    intentionally NOT in standalone compose + why (one-line per service)
  - 'Hanzo-side bridge / teleport — does not exist' subsection: makes
    explicit that there is no ~/work/hanzo/teleport / ~/work/hanzo/bridge.
    If a Hanzo-branded tenant is needed, the right play is a Hanzo
    tenant build under app/ (mirror of app/bridge/) consuming @luxfi/bridge
    + @hanzoai/brand. SDK is the integration point; tenants are thin.

Verification: bridge backend already swallows MPC / IAM / NATS init
failures (logger.warn instead of fatal). Only Postgres is a hard dep,
which compose.standalone.yml provides. Full SQLite-only mode would
require a Prisma provider swap + per-table audit; that's a separate
session and standalone compose covers the immediate ask.

No code-runtime changes — the existing graceful-degradation paths in
app/server already supported this topology; this commit just makes
the recipe explicit + documented.
2026-05-23 18:59:25 -07:00
zeekay a16981d8e1 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 a5f9a05008 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 5ced993961 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 3cd44cbe9c 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 5809006fc3 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 45e08a1 ('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 84810b8 ('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 ee958f516f 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 a4facf7845 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
@/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 bad4b54386 bridge: scrub Avalabs IP brand refs 2026-05-05 16:22:42 -07:00
zeekay 669f68438a 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