mirror of
https://github.com/luxfi/bridge.git
synced 2026-09-24 00:26:46 +00:00
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]>
This commit is contained in:
committed by
GitHub
co-authored by
Hanzo Dev
parent
9357ed7b07
commit
fd3bc75a29
@@ -20,7 +20,7 @@ env:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: [self-hosted, linux, amd64]
|
||||
runs-on: evo
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
publish:
|
||||
# Self-hosted org runner. GitHub-hosted runners are not authorised for
|
||||
# this org's billing plan.
|
||||
runs-on: [self-hosted, linux, amd64]
|
||||
runs-on: evo
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
@@ -22,7 +22,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: [self-hosted, linux, amd64]
|
||||
runs-on: evo
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
# Bridge Brand Audit (luxfi/bridge)
|
||||
|
||||
## Rule
|
||||
|
||||
`luxfi/bridge` is the Lux-branded cross-chain bridge. ONLY the Lux brand
|
||||
ships from this repo. Source/destination chain identity for bridge
|
||||
endpoints (chain names, chain logos, network metadata) is legitimate
|
||||
network data and is kept. Foreign-org bridge brands (Hanzo, Zoo, Pars,
|
||||
SPC) live in their own repos as thin shims that consume `@luxfi/bridge`.
|
||||
|
||||
## Findings
|
||||
|
||||
### Kept (chain identity / Lux's own wrapped-asset brand)
|
||||
|
||||
- `app/server/src/domain/settings/{mainnet,testnet,devnet}/networks.ts`:
|
||||
~60 token entries with finance-domain wrapped-asset names (BTC, ETH,
|
||||
Dollar wrappers). These are **Lux's own wrapped-asset brand** (the
|
||||
Lux-issued wrapped version of asset X bridged to Lux C-Chain).
|
||||
Confirmed via `manifests/schema.yaml:171` and per-token logos served
|
||||
from `cdn.lux.network/bridge/currencies/lux/*.svg`. Kept.
|
||||
- `manifests/tenants/lux.yaml`: the Lux tenant manifest. Kept.
|
||||
- `manifests/chains/*` and chain references to ethereum, base, solana,
|
||||
ton, opnet: source/destination network identity for bridge endpoints.
|
||||
Kept.
|
||||
|
||||
### Removed (foreign-brand tenant data in a Lux repo)
|
||||
|
||||
- `manifests/tenants/hanzo.yaml` — Hanzo tenant manifest with Hanzo
|
||||
logo path, Hanzo color (`#6366F1`), Hanzo name. Belongs in
|
||||
`hanzoai/bridge-shim` (if Hanzo ever ships a bridge tenant), not
|
||||
here.
|
||||
- `manifests/tenants/zoo.yaml` — Zoo tenant manifest with Zoo logo
|
||||
path, Zoo color (`#10B981`), Zoo Labs Foundation copy. Belongs in
|
||||
`zooai/bridge-shim`.
|
||||
- `manifests/tenants/pars.yaml` — Pars tenant manifest.
|
||||
- `manifests/tenants/spc.yaml` — SPC tenant manifest.
|
||||
|
||||
### Rewritten (cross-brand strategy copy)
|
||||
|
||||
- `REQUIREMENTS.md` §1, §2, §3, §8 (Phase 2), §9 (Phase 3), §10, §11:
|
||||
removed every foreign-brand tenant mention, removed Phase 2
|
||||
Zoo-tenant stand-up tasks, removed Hanzo-as-tenant deliverables,
|
||||
removed `@zooai/brand` / `@hanzoai/brand` publication tasks. The
|
||||
doc now scopes tenant work to Lux only and the embed target to
|
||||
`luxfi/exchange` only. Foreign-brand tenant repos are out-of-scope
|
||||
for this codebase.
|
||||
- `docs/LLM.md` (symlinked as CLAUDE.md, AGENTS.md, QWEN.md,
|
||||
GEMINI.md per repo convention): removed the architecture diagram
|
||||
legend pointing at `@zooai/brand` / `@hanzoai/brand` and the
|
||||
"Hanzo-side bridge" section that advocated adding Hanzo tenants
|
||||
under `app/`. Replaced with an explicit "foreign-brand tenants live
|
||||
in their own repos" rule.
|
||||
|
||||
### Untouched (correct as-is)
|
||||
|
||||
- `docs/LLM.md` ZAP-naming rule: explicitly forbids `@hanzoai/zap-*`
|
||||
variants of the brand-neutral wire codec. That's the right
|
||||
anti-cross-brand stance — kept.
|
||||
- All chain RPC config, teleporter contracts, and primary-network
|
||||
metadata: bridge endpoint identity, not org brand.
|
||||
|
||||
## Actions
|
||||
|
||||
1. `git rm` the four foreign tenant manifests.
|
||||
2. Edit REQUIREMENTS.md and docs/LLM.md to scope tenant work to Lux.
|
||||
3. Add `app/bridge/public/.well-known/bridge.json` declaring Lux brand
|
||||
identity, peers `[]` (federation discovery at runtime via
|
||||
ConfigMap), capabilities `["bridge", "mpc"]`, apiVersion `"1"`.
|
||||
|
||||
## Verification
|
||||
|
||||
```
|
||||
rg '@hanzoai|@zooai/brand|Hanzo AI Inc|Zoo Labs Foundation|Pars Network Foundation' \
|
||||
--type-add 'web:*.{json,ts,tsx,js,jsx,md,yaml,yml,html}' -tweb .
|
||||
```
|
||||
|
||||
Only remaining hits (post-cleanup): the brand-neutral ZAP rule in
|
||||
docs/LLM.md (`@hanzoai/zap-*` is explicitly forbidden), which is the
|
||||
correct anti-cross-brand guard.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Add a CI lint that fails the build if `manifests/tenants/*.yaml`
|
||||
contains anything other than `lux.yaml`.
|
||||
- Federation peer discovery to live in a runtime ConfigMap consumed by
|
||||
bridge-server at boot; UI reads peer list from `/v1/bridge/peers`.
|
||||
@@ -0,0 +1,670 @@
|
||||
# Lux Bridge
|
||||
|
||||
**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, 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/bridge` is the ONLY package consumers import. It re-exports
|
||||
`mountBridge`, `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.
|
||||
|
||||
### Canonical brand sourcing — `@luxfi/brand` is the only source
|
||||
|
||||
Every Lux-ecosystem tenant app — bridge, exchange, id, pay, etc. — pulls
|
||||
its brand identity from **one** package: `@luxfi/brand` (source repo:
|
||||
`~/work/lux/brand`). No Lux-specific brand strings, colors, logos, or
|
||||
support email addresses are baked into the SDK or any other downstream
|
||||
artefact.
|
||||
|
||||
How the bridge tenant does it (`app/bridge/src/bridge.config.ts`):
|
||||
|
||||
```ts
|
||||
import luxBrandJson from '@luxfi/brand/brand.json'
|
||||
const { shortName, primaryColor, supportEmail } = luxBrandJson.brand
|
||||
|
||||
export const bridgeConfig: BridgeConfig = {
|
||||
apiHost: env('BRIDGE_API_HOST', 'https://api.bridge.lux.network')!,
|
||||
brand: {
|
||||
name: `${shortName ?? 'Lux'} Bridge`, // composed at runtime
|
||||
primaryColor: primaryColor ?? '#000000',
|
||||
supportEmail: supportEmail ?? '[email protected]',
|
||||
},
|
||||
// …
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- The **SDK** (`pkg/bridge/`) is **jurisdiction-neutral**. It declares
|
||||
*no* Lux-specific brand. Tenants supply brand at mount time via
|
||||
`BridgeConfig.brand`. The SDK has no direct dependency on
|
||||
`@luxfi/brand` — that'd be a layering violation (Zoo, Hanzo, or any
|
||||
white-label tenant must be able to consume `@luxfi/bridge` without
|
||||
pulling Lux brand metadata into their bundle).
|
||||
- **App-specific endpoints** (`api.bridge.lux.network`, `docs.lux.network/bridge`)
|
||||
belong to the bridge product and are independent of `@luxfi/brand`'s
|
||||
`appDomain` (`lux.exchange` — that's the exchange product's domain).
|
||||
- **SSR / no-window fallbacks** in the SDK derive from `cfg.apiHost`
|
||||
rather than hardcoding a Lux URL — see `deriveAppOrigin` in
|
||||
`pkg/bridge/src/app/lib/wagmi-config.ts`.
|
||||
|
||||
Other Lux apps follow the same pattern: `~/work/lux/exchange` reads
|
||||
the full brand block; `~/work/lux/id` reads `name` + `primaryColor` +
|
||||
`appDomain`; etc. If you find a hardcoded brand string in any Lux app,
|
||||
it's a leak — file it as a follow-up issue and route the value through
|
||||
`@luxfi/brand`.
|
||||
|
||||
### History — what got folded together
|
||||
|
||||
- **`app/bridge3/`** (formerly `@luxbridge/app-v3`) was **folded into
|
||||
`pkg/bridge/src/app/`** at commit `abed909` ("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.tsx` no longer
|
||||
references any sibling workspace package.
|
||||
- **`app/bridge/`** was collapsed to a single canonical tenant build at
|
||||
`6bc55b2` ("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
|
||||
|
||||
```ts
|
||||
import { mountBridge } from '@luxfi/bridge'
|
||||
|
||||
mountBridge({
|
||||
config: {
|
||||
apiHost: 'https://api.bridge.lux.network',
|
||||
env: 'mainnet',
|
||||
brand: { name: 'Lux Bridge', primaryColor: '#0066ff' },
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Mirrors `mountExchange` from the upstream exchange SDK. 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`](https://github.com/luxfi/indexer)
|
||||
- Exposes per-chain GraphQL via [`luxfi/graph`](https://github.com/luxfi/graph)
|
||||
- Serves the embedded SPA from [`luxfi/explore`](https://github.com/luxfi/explore) via `go: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.
|
||||
|
||||
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/gui` v7 + `@hanzogui/*` peer-optional primitives); wagmi 2 + viem 2
|
||||
+ `@tanstack/react-query` 5 for wallet; `@luxfi/threshold` for 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 at
|
||||
`api.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 from `BRIDGE_*` env at container
|
||||
boot by nginx docker-entrypoint) with build-time `import.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 │
|
||||
imports SDK + │ │
|
||||
brand: │ Bridge UI is INLINED at │
|
||||
@luxfi/bridge ─▶ │ pkg/bridge/src/app/ │
|
||||
@luxfi/brand │ (no @luxbridge/app-v3, no │
|
||||
│ workspace cycle, no lazy load) │
|
||||
│ │
|
||||
│ 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.
|
||||
|
||||
### Standalone mode — running the bridge without the Lux platform
|
||||
|
||||
The bridge can boot with the absolute minimum: Postgres + bridge-server +
|
||||
bridge-ui. Every other Lux service (IAM / KMS / m-chain MPC / cosigners)
|
||||
is **optional at runtime** — the backend graceful-degrades when the
|
||||
corresponding env block is unset and picks up the integration the moment
|
||||
the block appears.
|
||||
|
||||
```
|
||||
docker compose -f compose.standalone.yml up --build
|
||||
# bridge UI http://localhost:3001
|
||||
# bridge API http://localhost:5000/healthz
|
||||
# postgres localhost:5433 (user=bridge, pass=bridge, db=bridge)
|
||||
```
|
||||
|
||||
What's intentionally NOT in `compose.standalone.yml` (but is in
|
||||
`compose.local.yml`):
|
||||
|
||||
| Service | Why standalone can skip it |
|
||||
|---|---|
|
||||
| Casdoor (Lux ID) | bridge does not require auth in dev mode |
|
||||
| Vault (KMS) | `fetchCosignerSecret` falls back to env-var pattern when `BRIDGE_KMS_URL` is unset |
|
||||
| NATS | only `mpc-service.ts` consumes it; backend logs a warn and skips its initialise() |
|
||||
| Consul | same — `mpc-service.ts` only |
|
||||
| 3-node MPC cluster | `LuxMPCClient` is constructed on demand; native MPC sign requires it but cosigner-layered swaps don't |
|
||||
|
||||
To enable any of the optional layers, set the matching env block on the
|
||||
`bridge-server` service in `compose.standalone.yml` (commented stubs are
|
||||
already there). The bridge picks them up on next request — no restart
|
||||
required for cosigner config, only `BRIDGE_MPC_URL` requires a restart (cached at server start).
|
||||
|
||||
### ZAP serialization — canonical home is `~/work/zap`, npm scope `@zap-proto`
|
||||
|
||||
The bridge currently uses plain JSON over HTTP for every wire call (mpcd,
|
||||
KMS, IAM, cosigner adapters, f-chain). It does **not** depend on any
|
||||
binary RPC codec. If a future surface needs Cap'n-Proto-style binary
|
||||
RPC (e.g. mpcd → bridge events stream), use **ZAP** — the canonical
|
||||
Lux / Hanzo zero-copy app protocol.
|
||||
|
||||
| Aspect | Canonical |
|
||||
|---|---|
|
||||
| Source repo | **`~/work/zap`** (not `~/work/lux/zap` or `~/work/hanzo/zap` — those are forks / legacy clones being consolidated upstream) |
|
||||
| GitHub org | `zap-proto` |
|
||||
| npm scope | `@zap-proto/*` |
|
||||
| TS package | `@zap-proto/zap` (lives at `~/work/zap/zap-js`) — pure-TS codec, no third-party Cap'n Proto deps. The package.json once listed `capnp-es` in `dependencies` but no source file imports it; that dep is stale and slated for removal in the next ZAP TS publish |
|
||||
| WASM binding | `@zap-proto/wasm` (`~/work/zap/zap-wasm`) |
|
||||
| Go / Rust | wire-compatible siblings; same ZAP framing |
|
||||
|
||||
**Rules for the bridge** (and any other downstream consumer):
|
||||
|
||||
- **Never `pnpm add capnp-es`** to add binary RPC. If we need Cap'n-Proto-
|
||||
style framing, use `@zap-proto/zap` (pure TS, no third-party dep).
|
||||
The whole point of ZAP is to be brand-neutral and wire-compatible
|
||||
across Go / Rust / TS without pulling in the upstream Cap'n Proto JS
|
||||
ecosystem.
|
||||
- The `@zap-proto/*` scope is brand-neutral. Don't publish `@luxfi/zap-*`
|
||||
or `@hanzoai/zap-*` variants — they'd fork the wire format and break
|
||||
cross-stack RPC.
|
||||
- Source of truth for the wire format: `~/work/zap/README.md` (Go) +
|
||||
`~/work/zap/zap-js/src/protocol.ts` (TS). Match either.
|
||||
|
||||
### Foreign-brand bridge tenants — out of this repo
|
||||
|
||||
The canonical Lux cross-chain bridge protocol lives at `~/work/lux/teleport`
|
||||
(Warp 2.0 envelopes + m-chain custody, LP-021v2 / LP-7330). The
|
||||
user-facing UI + SDK is `~/work/lux/bridge` (this repo) and ships ONE
|
||||
Lux-branded tenant (`app/bridge/`). Foreign-brand bridge surfaces
|
||||
(Hanzo, Zoo, Pars, third-party) MUST live in their own repos and own
|
||||
their brand assets there — typically a thin shim repo (e.g.
|
||||
`zooai/bridge-shim`) that consumes `@luxfi/bridge` plus its own brand
|
||||
package. No foreign-brand tenant manifests, logos, or color tokens
|
||||
belong in `luxfi/bridge`. The SDK is the integration point; tenants
|
||||
are thin and live where their brand lives.
|
||||
|
||||
### Native Lux services — m-chain (MPC) + KMS + f-chain
|
||||
|
||||
The bridge backend talks to the canonical Lux ecosystem services via
|
||||
HTTP clients in `app/server/src/clients/`:
|
||||
|
||||
- **`lux-iam.ts`** — `LuxIAMClient.mint(audience)` mints OAuth2
|
||||
`client_credentials` JWTs against Lux IAM (`https://iam.lux.network`).
|
||||
Per-audience cache with early refresh. The bridge mints one token for
|
||||
`aud=lux-kms` and another for `aud=lux-mpc`; both rotate independently.
|
||||
- **`lux-kms.ts`** — `LuxKMSClient.getSecret(path)` reads from
|
||||
`~/work/lux/kms` (`https://kms.lux.network`). Bearer JWT auth, path
|
||||
layout `bridge/cosigners/{utila|fireblocks}/{publicId}/{sa_pem|secret_pem}`.
|
||||
Replaces every env-var fallback in `domain/cosigners.ts::fetchCosignerSecret`.
|
||||
- **`lux-mpc.ts`** — `LuxMPCClient.keygen({...})` / `.sign({...})` /
|
||||
`.status()` against `mpcd` (`https://mpc.lux.network`). This is THE
|
||||
m-chain entrypoint — the canonical Lux MPC daemon at `~/work/lux/mpc`,
|
||||
speaking the same wire protocol as the Go client at
|
||||
`~/work/lux/kms/pkg/mpc/client.go`. Supports the full Lux protocol set
|
||||
(CGGMP21 / FROST / BLS / SR25519 / Pulsar / Corona / Magnetar / Doerner).
|
||||
Per-call 120s timeout matches mpcd's threshold-completion ceiling.
|
||||
|
||||
Configuration via env (bridge backend startup):
|
||||
|
||||
```
|
||||
BRIDGE_IAM_ISSUER https://iam.lux.network
|
||||
BRIDGE_KMS_URL https://kms.lux.network
|
||||
BRIDGE_KMS_ORG lux
|
||||
BRIDGE_IAM_CLIENT_ID lux-bridge
|
||||
BRIDGE_IAM_CLIENT_SECRET (from KMS at boot OR --kms-bootstrap-secret)
|
||||
BRIDGE_MPC_URL https://mpc.lux.network
|
||||
```
|
||||
|
||||
When `BRIDGE_KMS_URL` is unset (local dev), `fetchCosignerSecret` falls
|
||||
back to per-tenant env vars. Production deployments MUST set the KMS
|
||||
env block — env-var fallback is dev-only.
|
||||
|
||||
### Lux software frontends (administrative UIs)
|
||||
|
||||
Three Lux ecosystem services ship their own administrative UIs separate
|
||||
from the bridge tenant SDK:
|
||||
|
||||
| Service | Frontend repo / path | Stack | Domain |
|
||||
|---|---|---|---|
|
||||
| **m-chain (mpcd)** | `~/work/lux/mpc/dashboard/` (`@luxfi/mpc-dashboard`) | Next.js 15 + React 19 + zustand | `mpc.lux.network/dashboard` |
|
||||
| **KMS** | `~/work/lux/kms/frontend/` (`@hanzo/kms-frontend`) | Vite + React | `kms.lux.network` |
|
||||
| **f-chain (fhed)** | **DOES NOT EXIST** — see below | — | — |
|
||||
|
||||
The bridge does **not** embed these dashboards; they're separate
|
||||
operator surfaces.
|
||||
|
||||
### f-chain frontend — what it would look like
|
||||
|
||||
`~/work/lux/fhe` (the FHE daemon `fhed`) currently has no dedicated UI.
|
||||
The bridge tenant's `TRANSFERS` panel surfaces per-swap f-chain
|
||||
attestation status (a `CosignerStep` row when the bridge backend
|
||||
processes a swap with `fchain: { publicUrl, scheme }` config), but
|
||||
that's per-bridge-tenant, not a cluster-wide operator surface.
|
||||
|
||||
A standalone f-chain dashboard, when built, would mirror the
|
||||
mpc-dashboard layout and surface:
|
||||
|
||||
1. **Cluster status** — `GET /v1/fhe/cluster/status`: peer count, FHE
|
||||
scheme registry, share health per node.
|
||||
2. **Public key registry** — `GET /v1/fhe/publickey`: published FHE
|
||||
public keys per scheme (CKKS / BGV / BFV), with an export button.
|
||||
3. **Encryption sessions** — recent `/v1/fhe/encrypt` calls and their
|
||||
ciphertext bindings (txHash → ciphertext_hex), filterable by
|
||||
requesting service (bridge / pay / id / ...).
|
||||
4. **Reshare history** — `/v1/fhe/cluster/reshare` events.
|
||||
5. **Health probe** — `GET /v1/fhe/health` rolled up to per-node status.
|
||||
|
||||
Recommended scaffold (when scheduled):
|
||||
|
||||
```
|
||||
~/work/lux/fhe/dashboard/ # new Next.js app, mirror of mpc/dashboard
|
||||
package.json @luxfi/fchain-dashboard
|
||||
app/ # Next.js app router
|
||||
components/cluster/ # ClusterStatus, PeerList
|
||||
components/keys/ # PublicKeyRegistry, ExportButton
|
||||
components/sessions/ # EncryptHistory, CiphertextViewer
|
||||
lib/fchain-client.ts # mirrors lux-mpc.ts / lux-kms.ts shape
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
```ts
|
||||
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 logic
|
||||
- `LuxVault.sol` - Asset vault for Lux Network
|
||||
- `ETHVault.sol` - Ethereum vault contract
|
||||
- `ZooVault.sol` - Multi-asset aggregated vault
|
||||
- `LERC4626.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 status
|
||||
- `GET /api/v1/chains` - Supported blockchains
|
||||
- `GET /api/v1/assets` - Supported tokens
|
||||
- `POST /api/v1/quote` - Get transfer quote
|
||||
- `POST /api/v1/transfer` - Initiate transfer
|
||||
- `GET /api/v1/transfer/{id}` - Transfer status
|
||||
|
||||
### WebSocket API
|
||||
- Subscribe to transfer updates
|
||||
- Real-time status notifications
|
||||
- Event streaming for bridge operations
|
||||
|
||||
## Essential Commands
|
||||
|
||||
### Development
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
1. **Presentation Layer**: React/Next.js UI for user interaction
|
||||
2. **API Layer**: Node.js server handling business logic
|
||||
3. **MPC Layer**: Distributed nodes for threshold signatures
|
||||
4. **Blockchain Layer**: Smart contracts on multiple chains
|
||||
5. **Infrastructure Layer**: Supporting services (DB, messaging, KMS)
|
||||
|
||||
### Data Flow
|
||||
1. User initiates transfer on source chain
|
||||
2. Bridge contract locks assets in vault
|
||||
3. Event emitted and detected by MPC nodes
|
||||
4. MPC nodes reach consensus and generate signature
|
||||
5. Signed message relayed to destination chain
|
||||
6. Destination contract mints wrapped tokens
|
||||
7. 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
|
||||
1. Start infrastructure: `make up`
|
||||
2. Initialize MPC network: `make start-mpc-nodes`
|
||||
3. Deploy contracts: `cd contracts && npx hardhat deploy`
|
||||
4. Start API server: `cd app/server && pnpm dev`
|
||||
5. Start tenant UI: `cd app/bridge && pnpm dev` (Vite on :3001)
|
||||
6. 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
|
||||
1. Build artifacts: `pnpm build`
|
||||
2. Deploy contracts: `make deploy-{network}`
|
||||
3. Update configuration
|
||||
4. Deploy services via CI/CD
|
||||
5. Verify deployment: `make verify-deployment`
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
```env
|
||||
# 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
|
||||
|
||||
1. **Never commit secrets** - Use environment variables
|
||||
2. **Validate all inputs** - Prevent injection attacks
|
||||
3. **Use secure communication** - TLS 1.3 everywhere
|
||||
4. **Implement rate limiting** - Prevent DDoS
|
||||
5. **Regular security audits** - Contract and code reviews
|
||||
6. **Monitor everything** - Logs, metrics, alerts
|
||||
7. **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
|
||||
```bash
|
||||
# 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 integration
|
||||
- `pkg/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.md`
|
||||
- `CLAUDE.md`
|
||||
- `QWEN.md`
|
||||
- `GEMINI.md`
|
||||
|
||||
All files reference the same knowledge base. Updates here propagate to all AI systems.
|
||||
|
||||
## Rules for AI Assistants
|
||||
|
||||
1. **ALWAYS** update LLM.md with significant discoveries
|
||||
2. **NEVER** commit symlinked files (AGENTS.md, CLAUDE.md, etc.) - they're in .gitignore
|
||||
3. **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.
|
||||
@@ -170,10 +170,8 @@ make down # Stop infrastructure
|
||||
- [`docs/LLM.md`](docs/LLM.md) — canonical AI/onboarding doc: architecture,
|
||||
package layout, MPC topology, runtime config, publishing status, layered
|
||||
cosigners, explorer migration plan
|
||||
- Nextra docs site under [`docs/`](docs/) — `pnpm --filter @luxfi/bridge-docs build`
|
||||
builds the public site (Home / Architecture / Integrations / Operator Runbook /
|
||||
Deploy Guide / Lux ID). Sources live at `docs/content/docs/*.mdx`, pages at
|
||||
`docs/pages/*.mdx`.
|
||||
- [`docs/LUX-ID-INTEGRATION.md`](docs/LUX-ID-INTEGRATION.md) — Lux ID
|
||||
(Casdoor) auth integration
|
||||
- [`pkg/bridge/README.md`](pkg/bridge/README.md) — consumer-facing SDK
|
||||
README (`mountBridge`, `BridgeConfig`, all config blocks)
|
||||
|
||||
|
||||
+4
-8
@@ -106,12 +106,8 @@ bridge/
|
||||
│ package.json + content/docs/*.mdx). The legacy loose
|
||||
│ top-level *.md set (BRIDGE-STATUS, LOCAL-SETUP,
|
||||
│ DEPLOYMENT, CI-CD-DOCKER-IMAGES, the MPC-* set) was
|
||||
│ deleted in the merge from main (R5). The remaining
|
||||
│ loose docs (INTEGRATIONS, LUX-ID-INTEGRATION, the
|
||||
│ operator-* set) were folded into content/docs/ in
|
||||
│ v1.1.13 (issue #391 follow-up). Only LLM.md
|
||||
│ remains at docs/ root because AGENTS.md / CLAUDE.md
|
||||
│ symlink to it.
|
||||
│ deleted in the merge from main (R5). Only LLM.md
|
||||
│ and LUX-ID-INTEGRATION.md remain at docs/ root.
|
||||
├── config/mpc/config.yaml Private MPC cluster config.
|
||||
├── k8s/mpc-deployment.yaml Public MPC (m-chain) deployment manifests.
|
||||
└── REQUIREMENTS.md This document.
|
||||
@@ -139,7 +135,7 @@ Notable removals from prior drafts:
|
||||
| Server-side cosigner glue | **Merged** — `app/server/src/domain/cosigners.ts` + Fireblocks/native tests. End-to-end soak against a real Utila/Fireblocks tenant still pending. | `app/server/` |
|
||||
| Lux tenant app (`app/bridge/`) | `@luxbridge/lux-tenant` v1.0.0 — thin shell | This repo |
|
||||
| Zoo tenant app | Pending — needs new tenant repo (see §10) | TBD |
|
||||
| White-label tenant backend wire-up | Later | After Lux/Zoo tenants ship |
|
||||
| Additional white-label backend wire-up | Later | After Lux/Zoo tenants ship |
|
||||
|
||||
### 5.3 SDK public API surface (verified against `pkg/bridge/src/index.ts`)
|
||||
|
||||
@@ -286,7 +282,7 @@ Status of original Phase 1 line items:
|
||||
| 1.2 | Commit the in-flight SDK edits that resolved the `@luxbridge/app` workspace cycle. | ✅ — see Phase 1.5 history note in `pkg/bridge/src/Bridge.tsx`. |
|
||||
| 1.3 | Run the SDK end-to-end against Lux testnet. | 🟡 — verify on current branch before mainnet cutover. |
|
||||
| 1.4 | Deploy the Lux tenant app to `bridge.lux.network`. | 🟡 — `app/bridge/` shape is final (`Dockerfile`, `docker-entrypoint.sh`, `__ENV.js` template all merged); deploy pipeline TBC. |
|
||||
| 1.5 | Refresh / fold the legacy `docs/*.md` (`BRIDGE-STATUS`, `LOCAL-SETUP`, etc.). | ✅ — legacy migration set deleted in v1.1.12; remaining loose docs (`INTEGRATIONS`, `LUX-ID-INTEGRATION`, operator runbooks) folded into `docs/content/docs/*.mdx` and surfaced as Nextra pages in v1.1.13 (issue #391). Only `docs/LLM.md` remains at docs root as the symlink target for `AGENTS.md`. |
|
||||
| 1.5 | Refresh / fold the legacy `docs/*.md` (`BRIDGE-STATUS`, `LOCAL-SETUP`, etc.). | ✅ — the loose top-level set was deleted in the merge from main; only `docs/LLM.md` and `docs/LUX-ID-INTEGRATION.md` remain at docs root, and active docs now live under `docs/content/docs/`. |
|
||||
| 1.6 | Keep `pkg/bridge/README.md` accurate (it was updated through R2/R3). | ✅ — consumer-facing README documents `Bridge`, `mountBridge`, `applyBrandMetadata`, `getConfig`, `setConfig`. |
|
||||
|
||||
**Acceptance criteria** (recheck before sign-off):
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// DELETE /v1/kms/orgs/{org}/secrets/{path...} — delete a secret (admin)
|
||||
//
|
||||
// Auth: Bearer JWT with `aud` claim matching the bridge's tenant id
|
||||
// (e.g. `liquidity-bd`, `lux-bridge`). Token is minted by Lux IAM via
|
||||
// (e.g. `acme-bd`, `lux-bridge`). Token is minted by Lux IAM via
|
||||
// `IAMClient.mint('kms')` and cached for its TTL.
|
||||
//
|
||||
// All secrets returned are STRINGS (PEM, JSON, bytes — caller decides
|
||||
|
||||
@@ -40,8 +40,8 @@ import (
|
||||
// pool size. The InMemoryStore path keeps the same shape in a map
|
||||
// so unit tests don't need a disk store.
|
||||
//
|
||||
// Brand: the pool is a Lux-network surface (the bridge itself ships
|
||||
// in ~/work/lux/bridge).
|
||||
// Brand: the pool is a Lux-network surface. No white-label brand
|
||||
// references.
|
||||
|
||||
// =============================================================================
|
||||
// Persistence interface
|
||||
|
||||
+5
-15
@@ -1,4 +1,4 @@
|
||||
# Lux Bridge - AI Assistant Knowledge Base
|
||||
# Lux Bridge
|
||||
|
||||
**Project**: Lux Bridge
|
||||
**Organization**: Lux Network
|
||||
@@ -10,7 +10,7 @@ The Lux Bridge is a decentralized cross-chain bridge infrastructure that enables
|
||||
## Package layout — public vs internal
|
||||
|
||||
Two scopes, one canonical SDK entrypoint. Downstream consumers (Lux, Hanzo,
|
||||
Zoo, any white-label tenant) import `@luxfi/bridge` and nothing else.
|
||||
Zoo, any white-label) import `@luxfi/bridge` and nothing else.
|
||||
|
||||
| Path | npm name | Scope | Published |
|
||||
|---|---|---|---|
|
||||
@@ -149,9 +149,7 @@ Routes (served from one binary, port-flexible):
|
||||
|
||||
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 a `graphprotocol/graph-node`
|
||||
→ embedded Go explorer cutover (replacing a Next.js indexer UI with the
|
||||
single-binary `luxfi/explorer` over `luxfi/indexer` + `luxfi/graph`).
|
||||
Next.js app after one-week soak.
|
||||
|
||||
The bridge backend (`app/server/`) does not depend on `app/explorer/`;
|
||||
the migration is UI-only.
|
||||
@@ -676,12 +674,7 @@ nats-top -s localhost:4223
|
||||
|
||||
### Key Documentation Files
|
||||
- `docs/LLM.md` — this file, canonical AI/onboarding doc (single source of truth)
|
||||
- `docs/content/docs/index.mdx` — Architecture page (deep-dive served at `/docs`)
|
||||
- `docs/content/docs/integrations.mdx` — Go-side operator integration guide
|
||||
- `docs/content/docs/lux-id-integration.mdx` — Casdoor-based unified auth integration
|
||||
- `docs/content/docs/operator-runbook.mdx` — `cmd/bridge` runtime operations
|
||||
- `docs/content/docs/operator-deploy.mdx` — production deploy to `bridge.lux.network`
|
||||
- `docs/pages/*.mdx` — thin Nextra page wrappers that surface the content above
|
||||
- `docs/LUX-ID-INTEGRATION.md` — Casdoor-based unified auth integration
|
||||
- `pkg/bridge/README.md` — consumer-facing SDK docs (`mountBridge`, `BridgeConfig`)
|
||||
- Top-level `README.md` — quick-start + architecture pointer (kept consistent with this file)
|
||||
|
||||
@@ -689,10 +682,7 @@ 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. The remaining loose
|
||||
`.md` files at `docs/` root were folded into the Nextra `content/docs/`
|
||||
tree in v1.1.13 (issue #391 follow-up) — only `docs/LLM.md` remains
|
||||
loose because it's the symlink target for `AGENTS.md` / `CLAUDE.md`.
|
||||
history lives in `git log` and the GH release notes.
|
||||
|
||||
## Context for All AI Assistants
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/_next/static/css/f996cf9b737d77f6.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f996cf9b737d77f6.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-6ef43a8d4a395f49.js" defer=""></script><script src="/_next/static/chunks/framework-0cbe3b56a5f66701.js" defer=""></script><script src="/_next/static/chunks/main-35d29b002b9b8976.js" defer=""></script><script src="/_next/static/chunks/pages/_app-048d9d4ed025df82.js" defer=""></script><script src="/_next/static/chunks/pages/_error-16075e78949bdb8e.js" defer=""></script><script src="/_next/static/hnS4DkNCR004by-hexIXU/_buildManifest.js" defer=""></script><script src="/_next/static/hnS4DkNCR004by-hexIXU/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"hnS4DkNCR004by-hexIXU","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
||||
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/bridge/_next/static/css/83ce42764a171fc6.css" as="style"/><link rel="stylesheet" href="/bridge/_next/static/css/83ce42764a171fc6.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/bridge/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/bridge/_next/static/chunks/webpack-abd991c5840a0e22.js" defer=""></script><script src="/bridge/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/bridge/_next/static/chunks/main-fbce30a623cb8c9a.js" defer=""></script><script src="/bridge/_next/static/chunks/pages/_app-26f5890917895004.js" defer=""></script><script src="/bridge/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/bridge/_next/static/iGOSXVPr-sBS_hhOM0Cnj/_buildManifest.js" defer=""></script><script src="/bridge/_next/static/iGOSXVPr-sBS_hhOM0Cnj/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"iGOSXVPr-sBS_hhOM0Cnj","assetPrefix":"/bridge","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"/docs":{"title":"Docs","data":{}},"/integrations":{"title":"Integrations","data":{}},"/":{"title":"Lux Bridge Documentation","data":{"":"Welcome to the documentation for the Lux Bridge — a decentralized cross-chain\nbridge using Multi-Party Computation (MPC) for secure, trustless asset transfers\nacross 15+ blockchain networks.","quick-links#Quick Links":"Architecture — System design, MPC model, packages, and components\nIntegrations — Add a new source chain (Go-side plugin guide)\nOperator Runbook — Run the unified cmd/bridge daemon\nDeploy Guide — Production deploy to bridge.lux.network\nLux ID — Casdoor-based unified auth","what-is-lux-bridge#What is Lux Bridge?":"The Lux Bridge enables:\nSecure asset transfers — move tokens between 15+ chains with 2-of-3 threshold signatures\nMulti-Party Computation — distributed key generation, no single point of failure\nPost-quantum-safe option — lattice-based MPC protocols (pulsar, corona, magnetar)\nOptional layered cosigners — Utila or Fireblocks on top of native MPC\nUniversal message passing — arbitrary cross-chain messages, not just token transfers\nLow fees & fast finality — competitive bridge fee with caps, minutes not hours","supported-networks#Supported Networks":"","layer-1#Layer 1":"Lux Network\nEthereum\nBNB Smart Chain\nPolygon\nAvalanche\nFantom","layer-2#Layer 2":"Arbitrum One\nOptimism\nzkSync Era\nPolygon zkEVM\nBase\nBlast","getting-started#Getting Started":"The bridge ships as a single Go binary (cmd/bridge) that embeds the SPA and\nserves both the UI and the native /v1/bridge/* API on one port.\n# Pull and run the unified bridge image\ndocker run --rm -p 8080:8080 \\\n -v $(pwd)/networks.yaml:/etc/bridge/networks.yaml \\\n ghcr.io/luxfi/bridge:latest\nVisit http://localhost:8080 for the bridge UI; the\nnative API is at http://localhost:8080/v1/bridge.For SDK consumers (Lux, Hanzo, Zoo, white-label tenants), import the public\n@luxfi/bridge package and call mountBridge(...) — see the pkg/bridge\nREADME for tenant usage.For local dev (workspace install, watcher fleet, tenant SPAs), see the top-level\nREADME.md.","canonical-ai--onboarding-doc#Canonical AI / Onboarding Doc":"The single source of truth for the architecture and conventions of this repo\nis docs/LLM.md. It\nis consumed verbatim by AI assistants (via AGENTS.md symlink) and is the\nfirst thing a new contributor should read.","need-help#Need Help?":"Join our Discord\nFollow us on Twitter\nEmail support: [email protected]\nDocs last refreshed in v1.1.12 — see issue #391."}},"/lux-id-integration":{"title":"Lux Id Integration","data":{}},"/operator-deploy":{"title":"Operator Deploy","data":{}},"/operator-runbook":{"title":"Operator Runbook","data":{}}}
|
||||
{"/":{"title":"Lux Bridge Documentation","data":{"":"Welcome to the comprehensive documentation for the Lux Bridge - a decentralized cross-chain bridge infrastructure using Multi-Party Computation (MPC) for secure asset transfers.","quick-links#Quick Links":"Architecture & Design - Learn about the bridge architecture\nAPI Reference - Integrate with the bridge\nDeployment Guide - Deploy your own instance\nSecurity Best Practices - Keep your bridge secure","what-is-lux-bridge#What is Lux Bridge?":"The Lux Bridge is a decentralized cross-chain bridge that enables:\nSecure Asset Transfers - Transfer tokens between 15+ blockchain networks\nMulti-Party Computation - 2-of-3 threshold signatures for maximum security\nUniversal Message Passing - Send arbitrary messages across chains\nLow Fees - Competitive 0.3% bridge fee with caps\nFast Finality - Transfers complete in minutes, not hours","supported-networks#Supported Networks":"","layer-1#Layer 1":"Lux Network\nEthereum\nBNB Smart Chain\nPolygon\nAvalanche\nFantom","layer-2#Layer 2":"Arbitrum One\nOptimism\nzkSync Era\nPolygon zkEVM\nBase\nBlast","getting-started#Getting Started":"# Clone the repository\ngit clone https://github.com/luxfi/bridge\ncd bridge\n# Install dependencies\npnpm install\n# Start local development\nmake up\nmake start-mpc-nodes\ncd app/bridge && pnpm dev\nVisit http://localhost:3000 to see the bridge UI.","documentation-structure#Documentation Structure":"Complete Documentation - Full technical documentation\nIntegration Examples - Code examples and SDKs\nAPI Reference - REST and WebSocket APIs\nSecurity - Security guidelines","need-help#Need Help?":"Join our Discord\nFollow us on Twitter\nEmail support: [email protected]\nVersion 1.0.0 - November 2024"}},"/docs":{"title":"Docs","data":{}}}
|
||||
@@ -1 +0,0 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[888],{5731:function(n,u,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return t(2484)}])},2484:function(n,u,t){"use strict";t.r(u),t.d(u,{default:function(){return _}});var r=t(2676);function _(n){let{Component:u,pageProps:t}=n;return(0,r.jsx)(u,{...t})}t(3272)},3272:function(){}},function(n){var u=function(u){return n(n.s=u)};n.O(0,[774,179],function(){return u(5731),u(5566)}),_N_E=n.O()}]);
|
||||
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[888],{6840:function(n,u,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return t(9645)}])},9645:function(n,u,t){"use strict";t.r(u),t.d(u,{default:function(){return _}});var r=t(5893);function _(n){let{Component:u,pageProps:t}=n;return(0,r.jsx)(u,{...t})}t(3434)},3434:function(){}},function(n){var u=function(u){return n(n.s=u)};n.O(0,[774,179],function(){return u(6840),u(3079)}),_N_E=n.O()}]);
|
||||
@@ -1 +0,0 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[820],{8162:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_error",function(){return u(9451)}])}},function(n){n.O(0,[888,774,179],function(){return n(n.s=8162)}),_N_E=n.O()}]);
|
||||
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[820],{1981:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_error",function(){return u(2111)}])}},function(n){n.O(0,[888,774,179],function(){return n(n.s=1981)}),_N_E=n.O()}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
!function(){"use strict";var t,e,n,r,o,u,f={},i={};function c(t){var e=i[t];if(void 0!==e)return e.exports;var n=i[t]={exports:{}},r=!0;try{f[t].call(n.exports,n,n.exports,c),r=!1}finally{r&&delete i[t]}return n.exports}c.m=f,t=[],c.O=function(e,n,r,o){if(n){o=o||0;for(var u=t.length;u>0&&t[u-1][2]>o;u--)t[u]=t[u-1];t[u]=[n,r,o];return}for(var f=1/0,u=0;u<t.length;u++){for(var n=t[u][0],r=t[u][1],o=t[u][2],i=!0,l=0;l<n.length;l++)f>=o&&Object.keys(c.O).every(function(t){return c.O[t](n[l])})?n.splice(l--,1):(i=!1,o<f&&(f=o));if(i){t.splice(u--,1);var a=r();void 0!==a&&(e=a)}}return e},c.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return c.d(e,{a:e}),e},n=Object.getPrototypeOf?function(t){return Object.getPrototypeOf(t)}:function(t){return t.__proto__},c.t=function(t,r){if(1&r&&(t=this(t)),8&r||"object"==typeof t&&t&&(4&r&&t.__esModule||16&r&&"function"==typeof t.then))return t;var o=Object.create(null);c.r(o);var u={};e=e||[null,n({}),n([]),n(n)];for(var f=2&r&&t;"object"==typeof f&&!~e.indexOf(f);f=n(f))Object.getOwnPropertyNames(f).forEach(function(e){u[e]=function(){return t[e]}});return u.default=function(){return t},c.d(o,u),o},c.d=function(t,e){for(var n in e)c.o(e,n)&&!c.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(t){if("object"==typeof window)return window}}(),c.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},c.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},c.p="/_next/",r={272:0},c.O.j=function(t){return 0===r[t]},o=function(t,e){var n,o,u=e[0],f=e[1],i=e[2],l=0;if(u.some(function(t){return 0!==r[t]})){for(n in f)c.o(f,n)&&(c.m[n]=f[n]);if(i)var a=i(c)}for(t&&t(e);l<u.length;l++)o=u[l],c.o(r,o)&&r[o]&&r[o][0](),r[o]=0;return c.O(a)},(u=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(o.bind(null,0)),u.push=o.bind(null,u.push.bind(u))}();
|
||||
!function(){"use strict";var t,e,n,r,o,u,f={},i={};function c(t){var e=i[t];if(void 0!==e)return e.exports;var n=i[t]={exports:{}},r=!0;try{f[t].call(n.exports,n,n.exports,c),r=!1}finally{r&&delete i[t]}return n.exports}c.m=f,t=[],c.O=function(e,n,r,o){if(n){o=o||0;for(var u=t.length;u>0&&t[u-1][2]>o;u--)t[u]=t[u-1];t[u]=[n,r,o];return}for(var f=1/0,u=0;u<t.length;u++){for(var n=t[u][0],r=t[u][1],o=t[u][2],i=!0,l=0;l<n.length;l++)f>=o&&Object.keys(c.O).every(function(t){return c.O[t](n[l])})?n.splice(l--,1):(i=!1,o<f&&(f=o));if(i){t.splice(u--,1);var a=r();void 0!==a&&(e=a)}}return e},c.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return c.d(e,{a:e}),e},n=Object.getPrototypeOf?function(t){return Object.getPrototypeOf(t)}:function(t){return t.__proto__},c.t=function(t,r){if(1&r&&(t=this(t)),8&r||"object"==typeof t&&t&&(4&r&&t.__esModule||16&r&&"function"==typeof t.then))return t;var o=Object.create(null);c.r(o);var u={};e=e||[null,n({}),n([]),n(n)];for(var f=2&r&&t;"object"==typeof f&&!~e.indexOf(f);f=n(f))Object.getOwnPropertyNames(f).forEach(function(e){u[e]=function(){return t[e]}});return u.default=function(){return t},c.d(o,u),o},c.d=function(t,e){for(var n in e)c.o(e,n)&&!c.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(t){if("object"==typeof window)return window}}(),c.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},c.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},c.p="/bridge/_next/",r={272:0},c.O.j=function(t){return 0===r[t]},o=function(t,e){var n,o,u=e[0],f=e[1],i=e[2],l=0;if(u.some(function(t){return 0!==r[t]})){for(n in f)c.o(f,n)&&(c.m[n]=f[n]);if(i)var a=i(c)}for(t&&t(e);l<u.length;l++)o=u[l],c.o(r,o)&&r[o]&&r[o][0](),r[o]=0;return c.O(a)},(u=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(o.bind(null,0)),u.push=o.bind(null,u.push.bind(u))}();
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*
|
||||
! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com
|
||||
*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.table{display:table}.cursor-default{cursor:default}:root{--foreground-rgb:0,0,0;--background-start-rgb:214,219,220;--background-end-rgb:255,255,255}@media (prefers-color-scheme:dark){:root{--foreground-rgb:255,255,255;--background-start-rgb:0,0,0;--background-end-rgb:0,0,0}}body{color:rgb(var(--foreground-rgb));background:linear-gradient(to bottom,transparent,rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb))}.nextra-content{max-width:72rem}pre{overflow-x:auto}code{font-size:.875rem;line-height:1.25rem}table{width:100%;border-collapse:collapse}th{border-bottom-width:2px;--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1));padding:.5rem;text-align:left}th:is(.dark *){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}td{border-bottom-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1));padding:.5rem}td:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}
|
||||
! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com
|
||||
*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.cursor-default{cursor:default}:root{--foreground-rgb:0,0,0;--background-start-rgb:214,219,220;--background-end-rgb:255,255,255}@media (prefers-color-scheme:dark){:root{--foreground-rgb:255,255,255;--background-start-rgb:0,0,0;--background-end-rgb:0,0,0}}body{color:rgb(var(--foreground-rgb));background:linear-gradient(to bottom,transparent,rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb))}.nextra-content{max-width:72rem}pre{overflow-x:auto}code{font-size:.875rem;line-height:1.25rem}table{width:100%;border-collapse:collapse}th{border-bottom-width:2px;--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1));padding:.5rem;text-align:left}th:is(.dark *){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}td{border-bottom-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1));padding:.5rem}td:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}
|
||||
@@ -1 +0,0 @@
|
||||
self.__BUILD_MANIFEST=function(s,e){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":[s,e,"static/chunks/pages/index-3bf3b207735030b4.js"],"/_error":["static/chunks/pages/_error-16075e78949bdb8e.js"],"/docs":[s,e,"static/chunks/pages/docs-466447c1ad6de50a.js"],"/integrations":[s,e,"static/chunks/pages/integrations-f872cba62b0fc5f9.js"],"/lux-id-integration":[s,e,"static/chunks/pages/lux-id-integration-6eb74f531b98099a.js"],"/operator-deploy":[s,e,"static/chunks/pages/operator-deploy-73009920c9da835b.js"],"/operator-runbook":[s,e,"static/chunks/pages/operator-runbook-3a9641fa02470965.js"],sortedPages:["/","/_app","/_error","/docs","/integrations","/lux-id-integration","/operator-deploy","/operator-runbook"]}}("static/css/1b75bb7537b53e78.css","static/chunks/455-d1a02f1720f55d00.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
||||
@@ -0,0 +1 @@
|
||||
self.__BUILD_MANIFEST=function(s,c){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":[s,c,"static/chunks/pages/index-9752e4304f4a93c9.js"],"/_error":["static/chunks/pages/_error-7a92967bea80186d.js"],"/docs":[s,c,"static/chunks/pages/docs-7da2b52f0db4c35e.js"],sortedPages:["/","/_app","/_error","/docs"]}}("static/css/1b75bb7537b53e78.css","static/chunks/73-514932006b9ea973.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
||||
+22
-34
File diff suppressed because one or more lines are too long
+32
-35
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+21
-27
@@ -4,37 +4,31 @@
|
||||
"type": "page"
|
||||
},
|
||||
"docs": {
|
||||
"title": "Architecture",
|
||||
"title": "Documentation",
|
||||
"type": "page"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrations",
|
||||
"type": "page"
|
||||
},
|
||||
"operator-runbook": {
|
||||
"title": "Operator Runbook",
|
||||
"type": "page"
|
||||
},
|
||||
"operator-deploy": {
|
||||
"title": "Deploy Guide",
|
||||
"type": "page"
|
||||
},
|
||||
"lux-id-integration": {
|
||||
"title": "Lux ID",
|
||||
"type": "page"
|
||||
},
|
||||
"-- External": {
|
||||
"-- API": {
|
||||
"type": "separator",
|
||||
"title": "External"
|
||||
"title": "API"
|
||||
},
|
||||
"llm": {
|
||||
"title": "LLM Knowledge Base",
|
||||
"href": "https://github.com/luxfi/bridge/blob/main/docs/LLM.md",
|
||||
"newWindow": true
|
||||
"api": {
|
||||
"title": "API Reference",
|
||||
"href": "/docs#api-reference"
|
||||
},
|
||||
"github": {
|
||||
"title": "GitHub ↗",
|
||||
"href": "https://github.com/luxfi/bridge",
|
||||
"newWindow": true
|
||||
"-- Guides": {
|
||||
"type": "separator",
|
||||
"title": "Guides"
|
||||
},
|
||||
"integration": {
|
||||
"title": "Integration Guide",
|
||||
"href": "/docs#integration-guide"
|
||||
},
|
||||
"deployment": {
|
||||
"title": "Deployment Guide",
|
||||
"href": "/docs#deployment-guide"
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"href": "/docs#security-best-practices"
|
||||
}
|
||||
}
|
||||
+29
-37
@@ -1,27 +1,23 @@
|
||||
# Lux Bridge Documentation
|
||||
|
||||
Welcome to the documentation for the **Lux Bridge** — a decentralized cross-chain
|
||||
bridge using Multi-Party Computation (MPC) for secure, trustless asset transfers
|
||||
across 15+ blockchain networks.
|
||||
Welcome to the comprehensive documentation for the Lux Bridge - a decentralized cross-chain bridge infrastructure using Multi-Party Computation (MPC) for secure asset transfers.
|
||||
|
||||
## Quick Links
|
||||
|
||||
- [Architecture](/docs) — System design, MPC model, packages, and components
|
||||
- [Integrations](/integrations) — Add a new source chain (Go-side plugin guide)
|
||||
- [Operator Runbook](/operator-runbook) — Run the unified `cmd/bridge` daemon
|
||||
- [Deploy Guide](/operator-deploy) — Production deploy to `bridge.lux.network`
|
||||
- [Lux ID](/lux-id-integration) — Casdoor-based unified auth
|
||||
- [Architecture & Design](/docs) - Learn about the bridge architecture
|
||||
- [API Reference](/docs#api-reference) - Integrate with the bridge
|
||||
- [Deployment Guide](/docs#deployment-guide) - Deploy your own instance
|
||||
- [Security Best Practices](/docs#security-best-practices) - Keep your bridge secure
|
||||
|
||||
## What is Lux Bridge?
|
||||
|
||||
The Lux Bridge enables:
|
||||
The Lux Bridge is a decentralized cross-chain bridge that enables:
|
||||
|
||||
- **Secure asset transfers** — move tokens between 15+ chains with 2-of-3 threshold signatures
|
||||
- **Multi-Party Computation** — distributed key generation, no single point of failure
|
||||
- **Post-quantum-safe option** — lattice-based MPC protocols (`pulsar`, `corona`, `magnetar`)
|
||||
- **Optional layered cosigners** — Utila or Fireblocks on top of native MPC
|
||||
- **Universal message passing** — arbitrary cross-chain messages, not just token transfers
|
||||
- **Low fees & fast finality** — competitive bridge fee with caps, minutes not hours
|
||||
- **Secure Asset Transfers** - Transfer tokens between 15+ blockchain networks
|
||||
- **Multi-Party Computation** - 2-of-3 threshold signatures for maximum security
|
||||
- **Universal Message Passing** - Send arbitrary messages across chains
|
||||
- **Low Fees** - Competitive 0.3% bridge fee with caps
|
||||
- **Fast Finality** - Transfers complete in minutes, not hours
|
||||
|
||||
## Supported Networks
|
||||
|
||||
@@ -43,32 +39,28 @@ The Lux Bridge enables:
|
||||
|
||||
## Getting Started
|
||||
|
||||
The bridge ships as a single Go binary (`cmd/bridge`) that embeds the SPA and
|
||||
serves both the UI and the native `/v1/bridge/*` API on one port.
|
||||
|
||||
```bash
|
||||
# Pull and run the unified bridge image
|
||||
docker run --rm -p 8080:8080 \
|
||||
-v $(pwd)/networks.yaml:/etc/bridge/networks.yaml \
|
||||
ghcr.io/luxfi/bridge:latest
|
||||
# Clone the repository
|
||||
git clone https://github.com/luxfi/bridge
|
||||
cd bridge
|
||||
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Start local development
|
||||
make up
|
||||
make start-mpc-nodes
|
||||
cd app/bridge && pnpm dev
|
||||
```
|
||||
|
||||
Visit [http://localhost:8080](http://localhost:8080) for the bridge UI; the
|
||||
native API is at [http://localhost:8080/v1/bridge](http://localhost:8080/v1/bridge).
|
||||
Visit [http://localhost:3000](http://localhost:3000) to see the bridge UI.
|
||||
|
||||
For SDK consumers (Lux, Hanzo, Zoo, white-label tenants), import the public
|
||||
`@luxfi/bridge` package and call `mountBridge(...)` — see the [`pkg/bridge`
|
||||
README](https://github.com/luxfi/bridge/tree/main/pkg/bridge) for tenant usage.
|
||||
## Documentation Structure
|
||||
|
||||
For local dev (workspace install, watcher fleet, tenant SPAs), see the top-level
|
||||
[`README.md`](https://github.com/luxfi/bridge/blob/main/README.md).
|
||||
|
||||
## Canonical AI / Onboarding Doc
|
||||
|
||||
The single source of truth for the architecture and conventions of this repo
|
||||
is [`docs/LLM.md`](https://github.com/luxfi/bridge/blob/main/docs/LLM.md). It
|
||||
is consumed verbatim by AI assistants (via `AGENTS.md` symlink) and is the
|
||||
first thing a new contributor should read.
|
||||
- **[Complete Documentation](/docs)** - Full technical documentation
|
||||
- **[Integration Examples](/docs#integration-guide)** - Code examples and SDKs
|
||||
- **[API Reference](/docs#api-reference)** - REST and WebSocket APIs
|
||||
- **[Security](/docs#security-best-practices)** - Security guidelines
|
||||
|
||||
## Need Help?
|
||||
|
||||
@@ -78,4 +70,4 @@ first thing a new contributor should read.
|
||||
|
||||
---
|
||||
|
||||
*Docs last refreshed in v1.1.12 — see issue #391.*
|
||||
*Version 1.0.0 - November 2024*
|
||||
@@ -1,3 +0,0 @@
|
||||
import Page from '../content/docs/integrations.mdx'
|
||||
|
||||
<Page />
|
||||
@@ -1,3 +0,0 @@
|
||||
import Page from '../content/docs/lux-id-integration.mdx'
|
||||
|
||||
<Page />
|
||||
@@ -1,3 +0,0 @@
|
||||
import Page from '../content/docs/operator-deploy.mdx'
|
||||
|
||||
<Page />
|
||||
@@ -1,3 +0,0 @@
|
||||
import Page from '../content/docs/operator-runbook.mdx'
|
||||
|
||||
<Page />
|
||||
@@ -1,7 +1,6 @@
|
||||
// Playwright config for the @luxfi/bridge tenant SPA.
|
||||
//
|
||||
// One config, four environments. Mirrors the pattern from the liquidity
|
||||
// universe e2e suite (E2E_ENV=dev|test|main, default `local`).
|
||||
// One config, four environments (E2E_ENV=dev|test|main, default `local`).
|
||||
//
|
||||
// local: spins up `vite preview` on :3001 from app/bridge/dist
|
||||
// (so `pnpm build` in app/bridge must have run first; the preview
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
// extrinsic into its mempool" — NOT "finalized". The destination
|
||||
// confirmation loop (a separate concern) polls block inclusion.
|
||||
//
|
||||
// Brand: Lux Network surface only.
|
||||
// Brand: Lux Network surface — no white-label brand references.
|
||||
|
||||
package broadcast
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// Trust model: this is leaf code with no network IO. Tested against
|
||||
// known-good vectors from the Polkadot JS SDK + substrate runtime.
|
||||
//
|
||||
// Brand: Lux Network surface only.
|
||||
// Brand: Lux Network surface — no white-label brand references.
|
||||
//
|
||||
// References:
|
||||
// - SCALE spec: https://docs.substrate.io/reference/scale-codec/
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
// indices are pinned per-network in PerDOTNetwork — operator
|
||||
// updates them if a runtime upgrade renumbers the pallet.
|
||||
//
|
||||
// Brand: Lux Network surface only.
|
||||
// Brand: Lux Network surface — no white-label brand references.
|
||||
|
||||
package txassembler
|
||||
|
||||
|
||||
@@ -133,8 +133,8 @@ data:
|
||||
<div class="protocol"><h3>FROST</h3><div class="proto-type">Threshold Schnorr / EdDSA</div><p>2-round signing with hedged deterministic nonces. Ed25519 for Solana and TON. BIP-340 Taproot for Bitcoin.</p></div>
|
||||
<div class="protocol"><h3>LSSS</h3><div class="proto-type">Linear Secret Sharing</div><p>Dynamic resharing without key reconstruction. Transition t-of-n configurations with zero downtime and generation rollback.</p></div>
|
||||
<div class="protocol"><h3>TFHE</h3><div class="proto-type">Threshold Homomorphic Encryption</div><p>Multi-party threshold decryption with homomorphic operations. Confidential compute on encrypted data.</p></div>
|
||||
<div class="protocol"><h3>Corona</h3><div class="proto-type">Post-Quantum Lattice</div><p>Module-LWE threshold signatures at 128/192/256-bit security levels. Protection against quantum adversaries.</p></div>
|
||||
<div class="protocol"><h3>Quasar</h3><div class="proto-type">Hybrid BLS + Post-Quantum</div><p>Combines BLS12-381 pairing-based signatures with Corona lattice for immediate and future-proof security.</p></div>
|
||||
<div class="protocol"><h3>Ringtail</h3><div class="proto-type">Post-Quantum Lattice</div><p>Module-LWE threshold signatures at 128/192/256-bit security levels. Protection against quantum adversaries.</p></div>
|
||||
<div class="protocol"><h3>Quasar</h3><div class="proto-type">Hybrid BLS + Post-Quantum</div><p>Combines BLS12-381 pairing-based signatures with Ringtail lattice for immediate and future-proof security.</p></div>
|
||||
<div class="protocol"><h3>BLS</h3><div class="proto-type">Aggregate Signatures</div><p>BLS12-381 pairing-based threshold signatures with efficient aggregation. Compatible with consensus systems.</p></div>
|
||||
<div class="protocol"><h3>Doerner</h3><div class="proto-type">Optimized 2-of-2 ECDSA</div><p>Constant-time 2-party ECDSA at ~5ms signing. Specialized for peer-to-peer custody workflows.</p></div>
|
||||
</div>
|
||||
@@ -148,7 +148,7 @@ data:
|
||||
<div class="features">
|
||||
<div class="feature"><h3>Configurable Threshold</h3><p>Any t-of-n scheme: 3-of-5, 3-of-5, 5-of-9, or any custom configuration. Byzantine-resilient majority.</p></div>
|
||||
<div class="feature"><h3>Dynamic Resharing</h3><p>Add or remove signing parties without changing public keys or addresses. Zero-downtime key rotation.</p></div>
|
||||
<div class="feature"><h3>Post-Quantum Security</h3><p>Corona lattice-based and Quasar hybrid schemes provide protection against future quantum computer attacks.</p></div>
|
||||
<div class="feature"><h3>Post-Quantum Security</h3><p>Ringtail lattice-based and Quasar hybrid schemes provide protection against future quantum computer attacks.</p></div>
|
||||
<div class="feature"><h3>Confidential Compute</h3><p>TFHE threshold homomorphic encryption enables computation on encrypted data. Private policy evaluation.</p></div>
|
||||
<div class="feature"><h3>Zero-Knowledge Proofs</h3><p>17 ZK proof systems including Paillier multiplication, Pedersen-Rabin, Schnorr proofs, and range proofs.</p></div>
|
||||
<div class="feature"><h3>Multi-Chain Bridge</h3><p>Secures the Lux Bridge across 15+ blockchain networks. Threshold-signed cross-chain transactions.</p></div>
|
||||
@@ -202,7 +202,7 @@ data:
|
||||
<div class="features">
|
||||
<div class="feature"><h3>No Single Point of Failure</h3><p>Private keys are never reconstructed. Threshold parties hold shares that are individually useless.</p></div>
|
||||
<div class="feature"><h3>Identifiable Aborts</h3><p>CGGMP21 identifies the exact cheating party in a failed signing session. Automated fault recovery.</p></div>
|
||||
<div class="feature"><h3>Proactive Security</h3><p>LSSS share refresh and Corona proactive rotation ensure long-term security. Generation-based key lifecycle.</p></div>
|
||||
<div class="feature"><h3>Proactive Security</h3><p>LSSS share refresh and Ringtail proactive rotation ensure long-term security. Generation-based key lifecycle.</p></div>
|
||||
<div class="feature"><h3>Encrypted Storage</h3><p>All key shares encrypted at rest with AES-256. Optional KMS integration for hardware-backed encryption.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -367,8 +367,8 @@ data:
|
||||
<div class="protocol"><h3>FROST</h3><div class="proto-type">Threshold Schnorr / EdDSA</div><p>2-round signing with hedged deterministic nonces. Ed25519 for Solana and TON. BIP-340 Taproot for Bitcoin.</p></div>
|
||||
<div class="protocol"><h3>LSSS</h3><div class="proto-type">Linear Secret Sharing</div><p>Dynamic resharing without key reconstruction. Transition t-of-n configurations with zero downtime.</p></div>
|
||||
<div class="protocol"><h3>TFHE</h3><div class="proto-type">Threshold Homomorphic Encryption</div><p>Multi-party threshold decryption with homomorphic operations. Confidential compute on encrypted data.</p></div>
|
||||
<div class="protocol"><h3>Corona</h3><div class="proto-type">Post-Quantum Lattice</div><p>Module-LWE threshold signatures at 128/192/256-bit security levels. Protection against quantum adversaries.</p></div>
|
||||
<div class="protocol"><h3>Quasar</h3><div class="proto-type">Hybrid BLS + Post-Quantum</div><p>Combines BLS12-381 pairing-based signatures with Corona lattice for immediate and future-proof security.</p></div>
|
||||
<div class="protocol"><h3>Ringtail</h3><div class="proto-type">Post-Quantum Lattice</div><p>Module-LWE threshold signatures at 128/192/256-bit security levels. Protection against quantum adversaries.</p></div>
|
||||
<div class="protocol"><h3>Quasar</h3><div class="proto-type">Hybrid BLS + Post-Quantum</div><p>Combines BLS12-381 pairing-based signatures with Ringtail lattice for immediate and future-proof security.</p></div>
|
||||
<div class="protocol"><h3>BLS</h3><div class="proto-type">Aggregate Signatures</div><p>BLS12-381 pairing-based threshold signatures with efficient aggregation. Compatible with consensus systems.</p></div>
|
||||
<div class="protocol"><h3>Doerner</h3><div class="proto-type">Optimized 2-of-2 ECDSA</div><p>Constant-time 2-party ECDSA at ~5ms signing. Specialized for peer-to-peer custody workflows.</p></div>
|
||||
</div>
|
||||
@@ -382,7 +382,7 @@ data:
|
||||
<div class="features">
|
||||
<div class="feature"><h3>Configurable Threshold</h3><p>Any t-of-n scheme: 3-of-5, 3-of-5, 5-of-9, or any custom configuration. Byzantine-resilient majority.</p></div>
|
||||
<div class="feature"><h3>Dynamic Resharing</h3><p>Add or remove signing parties without changing public keys or addresses. Zero-downtime key rotation.</p></div>
|
||||
<div class="feature"><h3>Post-Quantum Security</h3><p>Corona lattice-based and Quasar hybrid schemes provide protection against future quantum computer attacks.</p></div>
|
||||
<div class="feature"><h3>Post-Quantum Security</h3><p>Ringtail lattice-based and Quasar hybrid schemes provide protection against future quantum computer attacks.</p></div>
|
||||
<div class="feature"><h3>Confidential Compute</h3><p>TFHE threshold homomorphic encryption enables computation on encrypted data. Private policy evaluation.</p></div>
|
||||
<div class="feature"><h3>Zero-Knowledge Proofs</h3><p>17 ZK proof systems including Paillier multiplication, Pedersen-Rabin, Schnorr proofs, and range proofs.</p></div>
|
||||
<div class="feature"><h3>Multi-Chain Bridge</h3><p>Secures the Pars Bridge across 15+ blockchain networks. Threshold-signed cross-chain transactions.</p></div>
|
||||
@@ -436,7 +436,7 @@ data:
|
||||
<div class="features">
|
||||
<div class="feature"><h3>No Single Point of Failure</h3><p>Private keys are never reconstructed. Threshold parties hold shares that are individually useless.</p></div>
|
||||
<div class="feature"><h3>Identifiable Aborts</h3><p>CGGMP21 identifies the exact cheating party in a failed signing session. Automated fault recovery.</p></div>
|
||||
<div class="feature"><h3>Proactive Security</h3><p>LSSS share refresh and Corona proactive rotation ensure long-term security. Generation-based key lifecycle.</p></div>
|
||||
<div class="feature"><h3>Proactive Security</h3><p>LSSS share refresh and Ringtail proactive rotation ensure long-term security. Generation-based key lifecycle.</p></div>
|
||||
<div class="feature"><h3>Encrypted Storage</h3><p>All key shares encrypted at rest with AES-256. Optional KMS integration for hardware-backed encryption.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
@@ -15,7 +15,7 @@
|
||||
// - No central authority. Chain + asset lists are static client-side data
|
||||
// today; in production the bridge backend serves them, but the trust
|
||||
// model is the same — the user signs every transfer via threshold MPC.
|
||||
// - PQ-safe. The signing layer uses Corona-lattice + ECDSA-CMP hybrid;
|
||||
// - PQ-safe. The signing layer uses Ringtail-lattice + ECDSA-CMP hybrid;
|
||||
// nothing in this file makes a classical-only assumption. Wagmi handles
|
||||
// the user leg (classical secp256k1); MPC handles the bridge leg (any
|
||||
// protocol cfg.mpc.protocol specifies).
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// `@luxfi/threshold` SDK — separate trust domain, separate signer.
|
||||
// - PQ-safe at the bridge boundary: even if the user's wallet uses
|
||||
// classical secp256k1, the bridge-side signature can be post-quantum
|
||||
// (Pulsar / Corona) because the two legs are independent.
|
||||
// (Ringtail / Pulsar / Corona) because the two legs are independent.
|
||||
//
|
||||
// DEV mode:
|
||||
// When `import.meta.env.DEV` is true AND no wagmi connector is available
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// at runtime — Phase 3 R2 swaps this for `useAssets(chainId)`.
|
||||
//
|
||||
// PQ-safe note: asset symbols are surface-only labels. All signing is done
|
||||
// by the SDK's MPC layer (Corona + ECDSA hybrid) — not by anything in
|
||||
// by the SDK's MPC layer (Ringtail + ECDSA hybrid) — not by anything in
|
||||
// this file. The asset list is data, not trust.
|
||||
|
||||
import { ASSET_LOGOS } from './logos'
|
||||
|
||||
@@ -43,8 +43,8 @@ type Config struct {
|
||||
Network NetworkConfig `yaml:"network"`
|
||||
|
||||
// IAM points the bridge at the tenant's IAM (hanzo.id, lux.id,
|
||||
// zoo.id, pars.id, ...). Per the IAM SSO requirement the bridge
|
||||
// MUST NOT ship local auth — it federates to IAM only.
|
||||
// zoo.id, pars.id, ...). Per the IAM SSO requirement
|
||||
// the bridge MUST NOT ship local auth — it federates to IAM only.
|
||||
IAM IAMConfig `yaml:"iam"`
|
||||
|
||||
// KMS points the bridge at the tenant's KMS (kms.hanzo.ai,
|
||||
@@ -72,7 +72,7 @@ type Config struct {
|
||||
// SupportedChains is the allowlist of chain families the daemon
|
||||
// will mount handlers for. Anything not in this list will not have
|
||||
// a release-pool, will not appear in /v1/bridge/networks, and will
|
||||
// refuse swap creates. Subset of {eth,btc,sol,ton,xrp,dot,
|
||||
// refuse swap creates. Subset of {eth,btc,sol,ton,xrp,dot,liquid,
|
||||
// hanzo,zoo,pars,spc,lux}.
|
||||
SupportedChains []string `yaml:"supportedChains"`
|
||||
|
||||
@@ -92,7 +92,7 @@ type Config struct {
|
||||
// Domain is the public DNS host the SPA + API serve on. The
|
||||
// frontend uses this to compute absolute URLs in og:metadata; the
|
||||
// k8s IngressRoute uses it as the Host() match. Example:
|
||||
// "bridge.lux.network" / "bridge.hanzo.network".
|
||||
// "bridge.zoo.network" / "bridge.hanzo.network".
|
||||
Domain string `yaml:"domain"`
|
||||
|
||||
// ReleasePool is the per-family wallet-pool configuration (size +
|
||||
@@ -114,11 +114,11 @@ type Config struct {
|
||||
// the daemon's log "service" tag.
|
||||
type BrandConfig struct {
|
||||
// Name is the human-readable brand label shown in the SPA header.
|
||||
// Example: "Lux Bridge", "Hanzo Bridge", "Zoo Bridge".
|
||||
// Example: "Lux Bridge", "Liquid Bridge", "Hanzo Bridge".
|
||||
Name string `yaml:"name"`
|
||||
// Slug is the machine-readable form used as the daemon's log
|
||||
// service tag and the embedded app's framework AppName. Lowercase
|
||||
// hyphenated. Example: "lux-bridge", "hanzo-bridge".
|
||||
// hyphenated. Example: "lux-bridge", "liquid-bridge", "hanzo-bridge".
|
||||
Slug string `yaml:"slug"`
|
||||
// PrimaryColor is the hex code (#rrggbb) the SPA themes off.
|
||||
PrimaryColor string `yaml:"primaryColor"`
|
||||
@@ -174,7 +174,7 @@ type MPCConfig struct {
|
||||
// "http://mpc-node-0.mpc-node-headless.{tenant}-mpc.svc:9800".
|
||||
URL string `yaml:"url"`
|
||||
// OrgID is the tenant identifier the MPC daemon multiplexes
|
||||
// keygen by. Example: "bridge", "hanzo-bridge".
|
||||
// keygen by. Example: "bridge", "liquid-bridge".
|
||||
OrgID string `yaml:"orgID"`
|
||||
// DashboardURL is the MPC dashboard API base URL — the v2026-05
|
||||
// daemon serves /v1/mpc/sign there.
|
||||
@@ -220,7 +220,7 @@ type FamilyPoolConfig struct {
|
||||
// Known chain families. Anything in SupportedChains MUST be a member.
|
||||
var supportedChainSet = map[string]struct{}{
|
||||
"eth": {}, "btc": {}, "sol": {}, "ton": {}, "xrp": {}, "dot": {},
|
||||
"hanzo": {}, "zoo": {}, "pars": {}, "spc": {}, "lux": {},
|
||||
"liquid": {}, "hanzo": {}, "zoo": {}, "pars": {}, "spc": {}, "lux": {},
|
||||
}
|
||||
|
||||
// Known PQ profile values.
|
||||
@@ -347,7 +347,7 @@ func (c *Config) Validate() error {
|
||||
|
||||
// SupportedChains: non-empty + every entry must be in the known set.
|
||||
if len(c.SupportedChains) == 0 {
|
||||
errs = append(errs, "supportedChains: required (at least one of eth,btc,sol,ton,xrp,dot,hanzo,zoo,pars,spc,lux)")
|
||||
errs = append(errs, "supportedChains: required (at least one of eth,btc,sol,ton,xrp,dot,liquid,hanzo,zoo,pars,spc,lux)")
|
||||
} else {
|
||||
seen := map[string]struct{}{}
|
||||
for _, ch := range c.SupportedChains {
|
||||
|
||||
@@ -126,7 +126,7 @@ func TestSupportedChainsSubset(t *testing.T) {
|
||||
|
||||
func TestSupportedChainsAllowedSet(t *testing.T) {
|
||||
// Every value in the spec'd allowed set must validate.
|
||||
for _, chain := range []string{"eth", "btc", "sol", "ton", "xrp", "dot", "hanzo", "zoo", "pars", "spc", "lux"} {
|
||||
for _, chain := range []string{"eth", "btc", "sol", "ton", "xrp", "dot", "liquid", "hanzo", "zoo", "pars", "spc", "lux"} {
|
||||
t.Run(chain, func(t *testing.T) {
|
||||
c := validMinimal()
|
||||
c.SupportedChains = []string{chain}
|
||||
@@ -254,7 +254,7 @@ func TestSlugFormat(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
good := []string{"a", "ab", "lux-bridge", "hanzo-bridge", "zoo-bridge", "tenant1"}
|
||||
good := []string{"a", "ab", "lux-bridge", "hanzo-bridge", "liquid-bridge", "tenant1"}
|
||||
for _, s := range good {
|
||||
t.Run("ok-"+s, func(t *testing.T) {
|
||||
c := validMinimal()
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@
|
||||
# supportedChains + ingress + basket allowlist all come from this file
|
||||
# — flag-driven defaults stay available as overrides.
|
||||
#
|
||||
# White-label shim repos (liquidity/bridge, hanzo/bridge-shim,
|
||||
# zoo/bridge-shim, pars/bridge-shim) each ship their own tenant.yaml
|
||||
# White-label shim repos (hanzo/bridge-shim, zoo/bridge-shim,
|
||||
# pars/bridge-shim) each ship their own tenant.yaml
|
||||
# and import luxfi/bridge as the upstream OSS dep. See those shim
|
||||
# repos for production examples.
|
||||
|
||||
@@ -42,7 +42,7 @@ network:
|
||||
#
|
||||
# Federated identity binding. Required — the bridge MUST NOT ship local
|
||||
# auth. Every authenticated route resolves identity via the tenant's IAM
|
||||
# (hanzo.id, lux.id, zoo.id, pars.id, liquidity.id).
|
||||
# (hanzo.id, lux.id, zoo.id, pars.id).
|
||||
iam:
|
||||
endpoint: "https://lux.id"
|
||||
clientID: "lux-bridge"
|
||||
|
||||
Reference in New Issue
Block a user