Bridge Integration
MPC signing for cross-chain bridge transfers
The Lux Bridge uses MPC for threshold signing of cross-chain transfers. Each bridge transaction requires t-of-n MPC nodes to produce a valid signature before assets are released on the destination chain.
Transfer Flow
- User initiates transfer via Bridge UI at bridge.lux.network
- Bridge API validates the request and creates an intent document
- HSM co-signs the intent (if
--hsm-attestis enabled) - MPC nodes receive the signing request via the consensus transport
- Each participating node produces a threshold signature share
- Shares are aggregated into a valid ECDSA signature
- The bridge server broadcasts the signed transaction to the destination chain
- Bridge API updates the transfer status
Supported Protocols
| Protocol | Curve | Chains |
|---|---|---|
| CGGMP21 | secp256k1 | Ethereum, Lux, all EVM chains |
| FROST | secp256k1 | Bitcoin (Taproot) |
The native MPC threshold signature is the complete, permissionless signing path — it is sufficient on its own and requires no external custodian.
Layered External-Custodian Cosigning (optional, institutional)
Regulated and institutional flows can require an external custodian to co-sign on top of the native MPC signature. This is opt-in compatibility for tenants who must keep a regulated custodian (e.g. Utila or Fireblocks) in the approval path; it is not part of the public permissionless bridge.
| Vendor | Auth | Role |
|---|---|---|
| Utila | service-account PEM | external approval workflow |
| Fireblocks | RS256 JWT (API key + signed PEM) | external RAW-sign approval |
How it composes, per swap:
- The SDK declares the required cosigners by public identifier only
(
org_id,api_key, vault ids) — secret material never crosses the wire. - The native MPC network produces its threshold signature first.
- Each declared custodian independently attests to the same transaction hash.
- All listed must approve — any rejection fails the swap.
The custodian secret (Utila PEM, Fireblocks signing key) is fetched at dispatch
time from KMS, keyed by the public identifier — never stored in the swap
record and never sent by the client. The vendor set is an extensible family
(adding one is a new Kind + dispatcher branch).
Scope: external-custodian cosigning targets regulated/institutional custody.
The permissionless bridge runs on native MPC alone. The cosigner orchestration
is being decomplected into a standalone module so the permissionless bridge
carries none of it — see the architecture note on luxfi/cosigner.
Bridge Architecture
Bridge UI (Next.js)
-> Bridge API (Node.js, port 3000)
-> MPC Cluster (3 nodes, consensus mode)
-> node-0 (port 9651)
-> node-1 (port 9652)
-> node-2 (port 9653)
-> Destination chain RPCMPC Node Configuration for Bridge
mpcd start --mode consensus \
--node-id node0 \
--listen :9651 \
--api :9800 \
--data /data/mpc/node0 \
--threshold 2 \
--peer node1@10.0.0.2:9652 \
--peer node2@10.0.0.3:9653Security Properties
| Property | Guarantee |
|---|---|
| Key safety | Full private key never exists on any single node |
| Fault tolerance | 1 node can be offline (2-of-3 threshold) |
| Signing speed | Sub-second threshold signature generation |
| Audit trail | Every signing request logged with intent hash |
| HSM binding | Optional hardware attestation per signature share |
Kubernetes Deployment
The bridge MPC nodes run in the lux-bridge namespace with separate PostgreSQL and Valkey instances from the main MPC cluster:
lux-bridge namespace:
mpc-node-0, mpc-node-1, mpc-node-2
bridge-postgres
bridge-api
bridge-ui