zeekay 5358d73653 feat(app/server): cosigner backend scaffold + 16 wire-shape validation tests (issue #386)
Lands the server-side foundation for the layered cosigner feature that
shipped in @luxfi/bridge v1.0.3. The SDK already forwards public-id-only
cosigners[] arrays on POST /api/swaps; this commit:

  - Adds domain/cosigners.ts — public types match SDK wire shape EXACTLY
    (snake_case, no drift); validator rejects secret-like fields up
    front (api_secret, private_key, jwt, token, etc.); dispatch
    entrypoint runs cosigners in parallel and surfaces per-step result.

  - Adds /api/swaps POST validation — the validator runs BEFORE the
    swap is persisted; a malformed cosigners[] returns 400 with a
    precise reason, never reaches the DB.

  - Threads cosigners through SwapData.handleSwapCreation as a logged
    pass-through. TODO comment marks where the new dev needs to:
      a. add Prisma schema for CosignerStep (or Swap.metadata JSON);
      b. call dispatchCosigners(...) after native MPC sign completes;
      c. gate broadcasting on all listed cosigners returning approved.

  - Adds vitest to @luxbridge/server + 16 unit tests covering happy
    paths (utila / fireblocks / both) AND rejections (unknown kind,
    missing required fields, every secret-like leak vector, index
    reporting in error messages).

What is wired:
  ✅ Wire-shape validation (reject secrets, accept valid intents)
  ✅ Pass-through through handleSwapCreation
  ✅ KMS-lookup interface with env-var fallback for local dev
  ✅ Dispatch entrypoint + parallel cosigner execution
  ✅ runUtila + runFireblocks STUB implementations with full TODO map

What is stubbed (issue #386 follow-ups):
  ⏳ Actual KMS round-trip in fetchCosignerSecret
  ⏳ @luxfi/utila transaction-approval flow (not the existing primary-
     signer mode in domain/utila.ts)
  ⏳ fireblocks-sdk install + FireblocksSDK client + raw-sign flow
  ⏳ Prisma persistence + state-machine gating

Tests: 16/16 cosigner tests passing on @luxbridge/server. Bridge SDK
53/53 still passing. Pre-existing workspace-dep typecheck errors on
server (@luxfi/utila not built in this worktree) are unchanged by this
commit.
2026-05-22 00:04:39 -07:00
2024-01-08 22:05:19 +01:00
2025-12-24 14:19:52 -08:00
2025-12-24 14:19:52 -08:00
2026-03-27 19:44:20 -07:00
2025-12-31 22:21:30 -08:00
2025-08-03 15:52:32 -05:00

Lux Bridge

Bridge monorepo for Lux Network — a decentralized cross-chain bridge using Multi-Party Computation (MPC) for secure asset transfers.

Embed the bridge SDK

To embed bridge.lux.network in another app, install @luxfi/bridge:

pnpm add @luxfi/bridge react react-dom
import { mountBridge } from '@luxfi/bridge'

mountBridge({
  config: {
    apiHost: 'https://api.bridge.lux.network',
    env: 'mainnet',
    brand: { name: 'Lux Bridge', primaryColor: '#0066ff' },
  },
})

@luxfi/bridge is the only package consumers import. All @luxbridge/* packages are internal workspace deps and are never published.

Package scopes

Scope Visibility Role
@luxfi/bridge public (npm) Canonical SDK — embed bridge UI into a host app.
@luxfi/core public (npm) Shared types (Asset, Network, Contract, ...).
@luxfi/threshold public (npm) T-Chain MPC threshold-signature SDK.
@luxfi/utila public (npm) Utila protobuf client.
@luxbridge/lux-tenant private (workspace) Slim Vite SPA for bridge.lux.network — consumes @luxfi/bridge.
@luxbridge/settings private (workspace) Network + asset registry.
@luxbridge/explorer private (workspace) On-chain explorer UI.
@luxbridge/server private (workspace) Bridge API daemon.
@luxbridge/ui-automation private (workspace) Selenium UI test harness.

One canonical SDK name. One mount function. One config shape.

Prerequisites

  • Node.js v20+
  • pnpm v9.15.0+
  • Go 1.22+ (for MPC tools)
  • Docker (for infrastructure services)

Quick Start

1. Install Dependencies

# Install pnpm if needed
npm install -g pnpm

# Install project dependencies
pnpm install

# Install MPC tools via Go
make install-mpc

2. Start Infrastructure

# Start infrastructure services (Lux ID, KMS, databases, etc.)
make up

This starts:

  • Lux ID (Casdoor) - Port 8000 - Unified authentication
  • KMS (Vault) - Port 8200 - Key management
  • NATS - Port 4223 - Messaging
  • Consul - Port 8501 - Service discovery
  • PostgreSQL - Port 5433 - Bridge database
  • Lux ID DB - Port 5434 - Auth database

3. Start MPC Network

# Start 3-node MPC network
make start-mpc-nodes

This runs MPC nodes on:

  • Node 0: HTTP 6000, gRPC 9090
  • Node 1: HTTP 6001, gRPC 9091
  • Node 2: HTTP 6002, gRPC 9092

4. Start Application Services

In separate terminals:

# Terminal 1: Bridge API Server
cd app/server && pnpm dev

# Terminal 2: Bridge UI
cd app/bridge && pnpm dev

5. Access Services

Architecture

Bridge UI → Bridge Server → MPC Nodes → Blockchain Networks
                               ↓
                    KMS + Lux ID + Consul

Key Features

  • MPC Security: 2-of-3 threshold signatures
  • Multi-Chain: Support for EVM and non-EVM chains
  • Unified Auth: Lux ID (Casdoor) integration
  • Key Management: Secure key storage in KMS
  • Service Discovery: Consul for dynamic configuration

Development

# Run tests
pnpm test

# Check MPC status
lux-mpc-cli status --url http://localhost:6000

# View logs
tail -f logs/mpc-node-0.log

# Stop services
make stop-mpc-nodes  # Stop MPC
make down           # Stop infrastructure

Documentation

Tips

Since "pnpm" is a finger twister, many people alias it to "pn". For example, with bash, put alias pn='pnpm' in .bashrc.

S
Description
▼ Bridge, powered by trustless MPC network and privacy focused Teleport protocol.
Readme BSD-3-Clause
260 MiB
Languages
TypeScript 52.2%
Go 40.9%
Solidity 2.8%
JavaScript 1.8%
Shell 1.4%
Other 0.8%