- 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.
18 KiB
Lux Bridge - AI Assistant Knowledge Base
Project: Lux Bridge Organization: Lux Network
Project Overview
The Lux Bridge is a decentralized cross-chain bridge infrastructure that enables secure, trustless asset transfers between multiple blockchain networks using Multi-Party Computation (MPC) technology. It serves as the primary interoperability layer for the Lux ecosystem, connecting 15+ blockchain networks.
Package layout — public vs internal
Two scopes, one canonical SDK entrypoint. Downstream consumers (Lux, Hanzo,
Zoo, Liquidity, any white-label) import @luxfi/bridge and nothing else.
| Path | npm name | Scope | Published |
|---|---|---|---|
pkg/bridge/ |
@luxfi/bridge |
public SDK | pending — see §Publishing |
pkg/core/ |
@luxfi/core |
public shared types | yes (last 10.0.5, 2025-05-09) |
pkg/threshold/ |
@luxfi/threshold |
public MPC SDK | pending — see §Publishing |
pkg/utila/ |
@luxfi/utila |
public utila client | yes (last 3.0.0, 2024-11-21) |
pkg/settings/ |
@luxbridge/settings |
private workspace | no |
pkg/ui/ |
@luxbridge/ui-automation |
private workspace | no |
app/bridge/ |
@luxbridge/lux-tenant |
private workspace | no |
app/explorer/ |
@luxbridge/explorer |
private workspace; migration to ghcr.io/luxfi/explorer planned — see §Explorer migration |
no |
app/server/ |
@luxbridge/server |
private workspace | no |
Rules:
@luxfi/bridgeis the ONLY package consumers import. It re-exportsmountBridge,Bridge, and the config/brand types. Internals are hidden.@luxbridge/*packages are workspace-only. They are not published and must not be imported by anything outside this repo.@luxfi/{core,threshold,utila}are generic Lux building-block libraries — bridge-agnostic, may be reused elsewhere in the Lux ecosystem.
History — what got folded together
app/bridge3/(formerly@luxbridge/app-v3) was folded intopkg/bridge/src/app/at commitabed909("feat(pkg/bridge): inline bridge UI under src/app/", phase 1.5). The old lazy-loaded workspace cycle that produced the blank-page bug is gone.Bridge.tsxno longer references any sibling workspace package.app/bridge/was collapsed to a single canonical tenant build at6bc55b2("phase2-r2: collapse to canonical app/bridge tenant"). It is now@luxbridge/lux-tenant(~120 LOC:bridge.config.ts,main.tsx,index.html+ Vite config), not the multi-variant Next.js app shown in stale diagrams.
SDK mount pattern
import { mountBridge } from '@luxfi/bridge'
mountBridge({
config: {
apiHost: 'https://api.bridge.lux.network',
env: 'mainnet',
brand: { name: 'Lux Bridge', primaryColor: '#0066ff' },
},
})
Mirrors mountExchange from @partner/exchange. One declarative entry,
build-time brand config, no hostname detection inside the SDK.
Publishing
.github/workflows/publish.yml fires on v* tag push, runs on the
self-hosted lux-build runner. Runs pnpm publish -r --access public --no-git-checks — pnpm walks the workspace, skips private: true
packages, and publishes any @luxfi/* package whose version is not yet
on npmjs.org. Bump versions in PRs; tag once merged.
Status as of 2026-05-22: the workflow is wired and hardened (fail-fast
on missing NPM_TOKEN/NODE_AUTH_TOKEN; token baked into the
NPM_CONFIG_USERCONFIG path because pnpm doesn't expand ${VAR} in
.npmrc) but @luxfi/bridge and @luxfi/threshold are still 404 on
npmjs.org. Confirmed by @luxfi/core 10.0.5 and @luxfi/utila 3.0.0
both pre-dating every v1.1.x tag — no v1.1.x release has ever shipped
to npm. Most likely missing NPM_TOKEN secret on the luxfi/bridge repo
(Settings → Secrets and variables → Actions) OR an unavailable
lux-build runner pool. The v1.1.10 fail-fast guard will surface either
clearly on the next run.
Explorer migration
app/explorer/ (@luxbridge/explorer, Next.js standalone) is on a
deprecation path. The canonical replacement is ghcr.io/luxfi/explorer
— a single Go binary at ~/work/lux/explorer that:
- Indexes EVM chains via
luxfi/indexer - Exposes per-chain GraphQL via
luxfi/graph - Serves the embedded SPA from
luxfi/exploreviago:embed
Routes (served from one binary, port-flexible):
| Path | Purpose |
|---|---|
/ |
SPA (embedded; SPA-routing fallback) |
/envs.js |
Runtime window.ENV = {…} |
/v1/indexer/{slug}/* |
Per-chain explorer REST API |
/v1/graph/{slug}/{subgraph}/graphql |
Per-chain, per-subgraph GraphQL |
/v1/explorer/realtime |
WebSocket realtime hub |
Migration plan: deploy luxfi/explorer alongside app/explorer/,
hostname-cutover (bridge-explorer.lux.network) on K8s, delete the
Next.js app after one-week soak. Same pattern as the
graphprotocol/graph-node → LiquidGraph cutover in
liquidity/universe (in-flight 2026-04-22; see
~/work/liquidity/universe/CLAUDE.md § Explorer / indexer).
The bridge backend (app/server/) does not depend on app/explorer/;
the migration is UI-only.
Architecture Summary
Core Technology Stack
- SDK:
@luxfi/bridge— TypeScript source-published; React 18 + Tamagui (@hanzo/guiv7 +@hanzogui/*peer-optional primitives); wagmi 2 + viem 2@tanstack/react-query5 for wallet;@luxfi/thresholdfor native MPC threshold sign sessions
- Tenant apps: Vite + React 18.3.1 (
app/bridge/=@luxbridge/lux-tenant,app/explorer/=@luxbridge/explorer) - Backend: Node.js + Express + Prisma (
app/server/= bridge API atapi.bridge.lux.network) - MPC Framework: 2-of-3 threshold signature scheme using
github.com/luxfi/mpc(Go); client-side session helper via@luxfi/threshold(TS) - Smart Contracts: Solidity (OpenZeppelin), deployed on multiple chains
- Infrastructure: Docker, Kubernetes, PostgreSQL, NATS, Consul, Vault (KMS)
- Authentication: Lux ID (Casdoor) for unified auth
- Runtime config:
window.__ENV(templated fromBRIDGE_*env at container boot by nginx docker-entrypoint) with build-timeimport.meta.env.VITE_*fallback. One image, N envs.
System Architecture
┌──────────────────────────────────┐
Tenant app │ @luxfi/bridge (pkg/bridge/) │
(app/bridge/, │ exports: Bridge, mountBridge, │
app/explorer/, │ BridgeConfig, types │
zoo/bridge/, …) │ │
imports SDK + │ Bridge UI is INLINED at │
brand: │ pkg/bridge/src/app/ │
@luxfi/bridge ─▶ │ (no @luxbridge/app-v3, no │
@luxfi/brand │ workspace cycle, no lazy load) │
(or @zooai/brand,│ │
@hanzoai/brand) │ Direct deps: │
│ @hanzo/gui, @luxfi/threshold, │
│ wagmi, viem, react-query │
└─────────────┬────────────────────┘
│
┌────────────────┴─────────────────┐
▼ ▼
┌───────────────────────┐ ┌──────────────────────┐
│ app/server │ │ @luxfi/threshold │
│ Bridge API │ │ MPC threshold SDK │
│ Express + Prisma │ │ (consumed by BOTH │
│ api.bridge.lux.network│ │ SDK + server) │
└──────────┬────────────┘ └──────────┬───────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌──────────────────┐
│ b-chain │ │ m-chain (public │
│ Lux primary network │ │ MPC, m-chain) │
│ consensus + state │ │ │
└─────────────────────┘ │ + optional │
│ private cluster │
│ (treasury fees) │
│ │
│ + optional │
│ layered cosign: │
│ Utila │
│ Fireblocks │
└──────────────────┘
MPC Network Configuration
- Node Count: 3 nodes (2-of-3 threshold) on m-chain (public MPC)
- Ports:
- HTTP API: 6000-6002
- gRPC: 9090-9092
- NATS: 4223
- Consul: 8501
- Security: TLS 1.3, mutual authentication, HSM integration
- Protocols:
cggmp21(default),frost,bls,doerner(classical);pulsar(MLWE),corona(RLWE),magnetar(lattice research variant) — PQ-safe, leaderless, permissionless-safe by design.
Optional layered cosigners (since SDK v1.0.3)
External MPC custodians can be layered ON TOP of the native threshold network as additional cosigners. The bridge backend enforces 2-of-2 (native + layered) before releasing settlement. Use when tenants are already on Utila or Fireblocks for institutional custody and need regulated-cosigner gating without giving up the native threshold property.
Browser SDK declares config only; the secret half (Utila JWT / Fireblocks
secret key) lives on app/server/ (sourced from KMS at boot). No secret
material is ever shipped in the page bundle.
mountBridge({
config: {
apiHost: 'https://api.bridge.lux.network',
env: 'mainnet',
mpc: {
publicUrl: 'https://mpc.lux.network',
protocol: 'cggmp21',
// optional — layered cosigner #1
utila: { orgId: 'tenant-x', clientId: 'lux-bridge' },
// optional — layered cosigner #2 (both may be enabled together)
fireblocks: { apiKey: 'pub-key-id', vaultAccountId: '0' },
},
},
})
Per-swap, the SDK forwards a cosigners[] array of public identifiers
(orgId, clientId, apiKey, vault ids) to POST /api/swaps. The
backend pairs each entry with a KMS-held secret and completes the cosign
on behalf of the tenant.
Supported Networks & Assets
Blockchain Networks (15+)
Layer 1: Lux, Ethereum, BSC, Polygon, Fantom Layer 2: Arbitrum, Optimism, zkSync Era, Polygon zkEVM, Base, Blast Other: TON, Solana (coming soon), Cosmos (via IBC)
Supported Assets
Stablecoins: USDT, USDC, DAI, ZUSD Native Tokens: LUX, ETH, BNB, MATIC Wrapped Assets: ZETH, ZBNB, ZPOL, ZTON (ERC20B standard)
Key Smart Contracts
Core Contracts
Bridge.sol- Main bridge contract with deposit/withdraw logicLuxVault.sol- Asset vault for Lux NetworkETHVault.sol- Ethereum vault contractZooVault.sol- Multi-asset aggregated vaultLERC4626.sol- Tokenized vault shares
Wrapped Token Contracts (ERC20B)
All wrapped tokens follow the ERC20B standard with mint/burn capabilities:
- Location:
/contracts/contracts/zoo/ - Examples: Z.sol, ZETH.sol, ZUSD.sol, ZBNB.sol
API Endpoints
REST API (Port 5000)
GET /api/v1/status- Bridge operational statusGET /api/v1/chains- Supported blockchainsGET /api/v1/assets- Supported tokensPOST /api/v1/quote- Get transfer quotePOST /api/v1/transfer- Initiate transferGET /api/v1/transfer/{id}- Transfer status
WebSocket API
- Subscribe to transfer updates
- Real-time status notifications
- Event streaming for bridge operations
Essential Commands
Development
# Clone and install
git clone https://github.com/luxfi/bridge
cd bridge
pnpm install
# Install MPC tools
make install-mpc
# Start infrastructure
make up
# Start MPC nodes
make start-mpc-nodes
# Start services
cd app/bridge && pnpm dev # UI on :3001
cd app/server && pnpm dev # API on :5000
Infrastructure Management
# Infrastructure
make up # Start all infra services
make down # Stop all services
make logs # View aggregated logs
# MPC Operations
make start-mpc-nodes # Start 3-node MPC network
make stop-mpc-nodes # Stop MPC nodes
make generate-mpc-keys # Generate new MPC keys
lux-mpc-cli status # Check MPC status
# Development
pnpm dev # Start development servers
pnpm build # Build for production
pnpm test # Run test suite
pnpm lint # Run linters
# Deployment
make deploy-testnet # Deploy to testnet
make deploy-mainnet # Deploy to mainnet
Architecture
The bridge uses a multi-layered architecture:
- Presentation Layer: React/Next.js UI for user interaction
- API Layer: Node.js server handling business logic
- MPC Layer: Distributed nodes for threshold signatures
- Blockchain Layer: Smart contracts on multiple chains
- Infrastructure Layer: Supporting services (DB, messaging, KMS)
Data Flow
- User initiates transfer on source chain
- Bridge contract locks assets in vault
- Event emitted and detected by MPC nodes
- MPC nodes reach consensus and generate signature
- Signed message relayed to destination chain
- Destination contract mints wrapped tokens
- User receives tokens on destination chain
Key Technologies
- Multi-Party Computation (MPC): Distributed key management
- Threshold Signatures: 2-of-3 security model
- Smart Contracts: Solidity with OpenZeppelin
- Message Queue: NATS for inter-node communication
- Service Discovery: Consul for dynamic configuration
- Key Management: HashiCorp Vault
- Authentication: Casdoor (Lux ID)
- Database: PostgreSQL for state management
- Container Orchestration: Docker/Kubernetes
Development Workflow
Local Development
- Start infrastructure:
make up - Initialize MPC network:
make start-mpc-nodes - Deploy contracts:
cd contracts && npx hardhat deploy - Start API server:
cd app/server && pnpm dev - Start tenant UI:
cd app/bridge && pnpm dev(Vite on :3001) - SDK dev: edit
pkg/bridge/src/— tenant Vite picks up changes live through the workspace symlink. No publish needed for local iteration.
Testing
- Unit tests:
pnpm test:unit - Integration tests:
pnpm test:integration - Contract tests:
cd contracts && npx hardhat test - E2E tests:
pnpm test:e2e
Deployment
- Build artifacts:
pnpm build - Deploy contracts:
make deploy-{network} - Update configuration
- Deploy services via CI/CD
- Verify deployment:
make verify-deployment
Configuration
Environment Variables
# Network
NETWORK=mainnet|testnet|local
CHAIN_ID=31337
# Database
DATABASE_URL=postgresql://user:pass@localhost:5433/bridge
# MPC
MPC_NODE_COUNT=3
MPC_THRESHOLD=2
# KMS (Vault)
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=<token>
# Authentication (Lux ID)
CASDOOR_ENDPOINT=http://localhost:8000
Service Ports
- Bridge UI (tenant
app/bridge/): 3001 (Vite dev/preview server) - Bridge API (
app/server/): 5000 (Express) - Bridge explorer (
app/explorer/, legacy): 3002 (Next.js) - Bridge explorer (
ghcr.io/luxfi/explorer, replacement): port-flexible - MPC Nodes: 6000-6002 (HTTP), 9090-9092 (gRPC)
- PostgreSQL: 5433 (bridge), 5434 (auth)
- Vault (KMS): 8200
- Lux ID: 8000
- NATS: 4223
- Consul: 8501
Security Best Practices
- Never commit secrets - Use environment variables
- Validate all inputs - Prevent injection attacks
- Use secure communication - TLS 1.3 everywhere
- Implement rate limiting - Prevent DDoS
- Regular security audits - Contract and code reviews
- Monitor everything - Logs, metrics, alerts
- Incident response plan - Be prepared for emergencies
Monitoring & Debugging
Health Checks
- Bridge API:
curl http://localhost:5000/health - MPC Nodes:
curl http://localhost:6000/health - Infrastructure:
http://localhost:8501/ui(Consul)
Debugging Commands
# Check MPC status
lux-mpc-cli status --url http://localhost:6000
# View logs
tail -f logs/mpc-node-*.log
# Database queries
psql $DATABASE_URL -c "SELECT * FROM transfers WHERE status='pending';"
# NATS monitoring
nats-top -s localhost:4223
Documentation
Comprehensive Documentation Site (Nextra)
- Location:
~/work/lux/bridge/docs/(Next.js + Nextra) - Pages:
docs/pages/*.mdx - Build:
cd docs && pnpm install && pnpm build - Dev:
cd docs && pnpm dev→ http://localhost:3000
Key Documentation Files
docs/LLM.md— this file, canonical AI/onboarding doc (single source of truth)docs/LUX-ID-INTEGRATION.md— Casdoor-based unified auth integrationpkg/bridge/README.md— consumer-facing SDK docs (mountBridge,BridgeConfig)- Top-level
README.md— quick-start + architecture pointer (kept consistent with this file)
The legacy migration .md files (BRIDGE-STATUS, LOCAL-SETUP, the four MPC
migration notes, DEPLOYMENT, CI-CD-DOCKER-IMAGES) were deleted in v1.1.12
(commit b04e805, issue #391) — they described an architecture from
before the SDK rationalization and confused new readers. Migration
history lives in git log and the GH release notes.
Context for All AI Assistants
This file (LLM.md) is symlinked as:
AGENTS.mdCLAUDE.mdQWEN.mdGEMINI.md
All files reference the same knowledge base. Updates here propagate to all AI systems.
Rules for AI Assistants
- ALWAYS update LLM.md with significant discoveries
- NEVER commit symlinked files (AGENTS.md, CLAUDE.md, etc.) - they're in .gitignore
- NEVER create random summary files - update THIS file
Note: This file serves as the single source of truth for all AI assistants working on this project.