mirror of
https://github.com/luxfi/bridge.git
synced 2026-09-24 00:26:46 +00:00
chore: updated env
This commit is contained in:
+322
@@ -0,0 +1,322 @@
|
||||
# Lux Bridge — Project Requirements
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Repository | `github.com/luxfi/bridge` |
|
||||
| Owner | Lux Industries, Inc. |
|
||||
| Author of doc | (to be filled) |
|
||||
| Date | 2026-05-21 |
|
||||
| Status | Draft for review |
|
||||
| Supersedes | `requirements.txt` (working notes) |
|
||||
|
||||
---
|
||||
|
||||
## 1. Background & Context
|
||||
|
||||
`bridge.lux.network` is Lux's cross-chain bridge UI. Historically it was a monolithic frontend bound to an older JavaScript API + standalone MPC service. Both have been replaced:
|
||||
|
||||
- The **API backend** is now `app/server/` (Express + Prisma) and is already live at `api.bridge.lux.network`.
|
||||
- The **MPC layer** is now provided by `pkg/threshold/` (`@luxfi/threshold` SDK), deployed in two modes:
|
||||
- **Private MPC** — Lux treasury cluster, collects fees. Config under `config/mpc/config.yaml`.
|
||||
- **Public MPC** — `m-chain`, validator-powered, permissionless, deployed via `k8s/mpc-deployment.yaml`.
|
||||
- The **frontend** is being repackaged as a publishable white-label SDK `@luxfi/bridge` (`pkg/bridge/`). Each tenant (Lux, Zoo, Hanzo, ) consumes the SDK from a minimal `main.tsx` plus its own `@<org>/brand` package.
|
||||
|
||||
This document is the authoritative project requirements set. It supersedes the rough-draft `requirements.txt` in the repo root, which captured the original Slack transcript from the project sponsor.
|
||||
|
||||
## 2. Goals
|
||||
|
||||
1. Restore a working bridge at `bridge.lux.network`, backed by `app/server/` (talking to b-chain) and `@luxfi/threshold` MPC (m-chain + private cluster).
|
||||
2. Ship `@luxfi/bridge` v1.x as a publicly-installable npm package that any host can embed, with brand + config injected at mount time.
|
||||
3. Provide two reference tenant repos consuming the SDK:
|
||||
- `github.com/luxfi/bridge` tenant app (Lux brand) — currently `app/bridge3/`.
|
||||
- `github.com/zooai/bridge` tenant app (Zoo brand) — currently in flux (see §10 Uncommitted State).
|
||||
4. Embed the bridge inside `luxfi/exchange` and `zooai/exchange` using the same SDK.
|
||||
5. Support as a third tenant operating its own backend (centralized MPC) — proves the SDK is genuinely backend-agnostic.
|
||||
|
||||
## 3. Non-Goals
|
||||
|
||||
The following are **explicitly out of scope** for this initiative and must not creep in:
|
||||
|
||||
- Rewriting `app/server/` routes, schema, or Prisma layer beyond what's needed for chain rewiring.
|
||||
- Building new branding configs *before* data flow from b-chain to UI is proven end-to-end.
|
||||
- Optimizing for 's standalone-backend use case before Lux's hosted case works.
|
||||
- Changes to `@luxfi/threshold` MPC SDK internals — that package is owned upstream and is consumed as-is.
|
||||
- Replacing wallet adapters or chain libraries inside `@luxbridge/app-v3` beyond what wiring requires.
|
||||
- Deprecating the legacy `app/bridge/` (`@luxbridge/app` v2.0.0) in this initiative — leave it untouched. It is not on the SDK consumption path.
|
||||
|
||||
## 4. Glossary — Lux Chains
|
||||
|
||||
These names appear throughout the source transcript; for record:
|
||||
|
||||
| Chain | Role | Used by bridge? |
|
||||
|---|---|---|
|
||||
| **b-chain** | Lux primary network validators. Hosts bridge API backend (consensus + state). | Yes — primary backend chain. |
|
||||
| **m-chain** | Public/permissionless MPC chain, powered by validators. | Yes — public threshold signing. |
|
||||
| **t-chain** | Threshold layer (referenced in `@luxfi/threshold`). | Yes — MPC SDK target. |
|
||||
| **f-chain** | FHE chain (`github.com/luxfhe`, "first OSS torus threshold FHE"). | Not in scope for v1. |
|
||||
| **o-chain** | Oracle chain, watches external networks. | Optional (helper). |
|
||||
| **r-chain** | Relay chain, submits tx on other networks. | Optional (helper). |
|
||||
|
||||
## 5. Current State (verified 2026-05-21)
|
||||
|
||||
### 5.1 Repo layout (relevant subset)
|
||||
|
||||
```
|
||||
bridge/
|
||||
├── app/
|
||||
│ ├── bridge/ @luxbridge/app v2.0.0 — LEGACY. Vite, ~80 deps. Not on SDK path.
|
||||
│ ├── bridge3/ @luxbridge/app-v3 v1.0.0 — REFERENCE FRONTEND. Remix/Vite v3.
|
||||
│ └── server/ Bridge API (Express + Prisma). Live at api.bridge.lux.network.
|
||||
├── pkg/
|
||||
│ ├── bridge/ @luxfi/bridge — PUBLIC SDK (this is what consumers import).
|
||||
│ │ ├── src/
|
||||
│ │ │ ├── index.ts Public entry (exports Bridge, mountBridge, types, config helpers).
|
||||
│ │ │ ├── Bridge.tsx React component; lazy-imports @luxbridge/app-v3.
|
||||
│ │ │ ├── mount.ts Imperative DOM-mount helper.
|
||||
│ │ │ ├── config.ts getConfig/setConfig/applyBrandMetadata.
|
||||
│ │ │ ├── types.ts BridgeConfig, BrandConfig, MountBridgeOptions.
|
||||
│ │ │ └── luxbridge-app.d.ts Workspace dep type shim.
|
||||
│ │ ├── package.json v1.0.0, scope public, registry npmjs.org.
|
||||
│ │ └── README.md Consumer-facing docs (currently inaccurate — see §10).
|
||||
│ └── threshold/ @luxfi/threshold — MPC SDK. Consumed by app/server.
|
||||
├── docs/
|
||||
│ ├── BRIDGE-STATUS.md STALE — points devs at app/bridge (legacy).
|
||||
│ ├── LOCAL-SETUP.md STALE — same issue.
|
||||
│ ├── MPC-GO-INTEGRATION.md
|
||||
│ ├── MIGRATION-TO-GO-MPC.md
|
||||
│ ├── MPC-INTEGRATION-COMPLETE.md
|
||||
│ ├── MPC-MODERNIZATION-SUMMARY.md
|
||||
│ ├── CI-CD-DOCKER-IMAGES.md
|
||||
│ ├── DEPLOYMENT.md
|
||||
│ ├── LUX-ID-INTEGRATION.md
|
||||
│ └── LLM.md
|
||||
├── config/mpc/config.yaml Private MPC cluster config.
|
||||
├── k8s/mpc-deployment.yaml Public MPC (m-chain) deployment manifests.
|
||||
├── REQUIREMENTS.md This document.
|
||||
└── requirements.txt Original sponsor transcript (working notes).
|
||||
```
|
||||
|
||||
### 5.2 Component status (per sponsor's confirmation)
|
||||
|
||||
| Component | Status | Location |
|
||||
|---|---|---|
|
||||
| Lux primary network (validators) | Live | `github.com/luxfi/node`, `luxfi/chains` |
|
||||
| Bridge API server (b-chain backend) | Live | `app/server/` |
|
||||
| Public MPC (m-chain) | Live | `pkg/threshold/` SDK + `k8s/mpc-deployment.yaml` |
|
||||
| Private MPC (treasury fees) | Live | same code, separate cluster, `config/mpc/config.yaml` |
|
||||
| r-chain relay (optional helper) | Live (in repo) | `app/server/cmd/`, hooks |
|
||||
| o-chain oracle (optional helper) | Live (in repo) | upstream `github.com/luxfi/bridge` |
|
||||
| Liquidity backend wire-up | Later | After Lux/Zoo tenants ship |
|
||||
| `@luxfi/bridge` SDK (`pkg/bridge/`) | Partial — uncommitted local edits | This repo |
|
||||
| Lux tenant app (`app/bridge3/`) | Reference / dogfood | Will become `github.com/luxfi/bridge` tenant repo |
|
||||
| Zoo tenant app | Uncommitted deletion in tree | Needs reconciliation (see §10) |
|
||||
|
||||
### 5.3 SDK API surface (current, exact)
|
||||
|
||||
From `pkg/bridge/src/index.ts`:
|
||||
|
||||
```ts
|
||||
export { Bridge } from './Bridge'
|
||||
export type { BridgeProps } from './Bridge'
|
||||
export { mountBridge } from './mount'
|
||||
export { applyBrandMetadata, getConfig, setConfig } from './config'
|
||||
export type { BrandConfig, BridgeConfig, MountBridgeOptions } from './types'
|
||||
```
|
||||
|
||||
`BridgeConfig`:
|
||||
|
||||
```ts
|
||||
interface BridgeConfig {
|
||||
apiHost: string // e.g. "https://api.bridge.lux.network"
|
||||
env: string // "mainnet" | "testnet" | custom slug
|
||||
brand?: BrandConfig // White-label overrides
|
||||
clientId?: string // Lux ID OIDC
|
||||
iamOrg?: string // Lux ID org slug
|
||||
}
|
||||
```
|
||||
|
||||
`BrandConfig`:
|
||||
|
||||
```ts
|
||||
interface BrandConfig {
|
||||
name: string // Display name → document.title
|
||||
logoUrl?: string // SVG preferred
|
||||
faviconUrl?: string // Applied to <link rel="icon">
|
||||
primaryColor?: string // → --brand-primary
|
||||
secondaryColor?: string // → --brand-secondary
|
||||
supportEmail?: string // Footer
|
||||
docsUrl?: string // Footer
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 Internal workspace deps
|
||||
|
||||
`pkg/bridge/package.json` declares:
|
||||
|
||||
```json
|
||||
"dependencies": {
|
||||
"@luxbridge/app-v3": "workspace:*",
|
||||
"@luxbridge/settings": "workspace:*",
|
||||
"@luxfi/brand": "^1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
`@luxbridge/app-v3` resolves to `app/bridge3/`. `@luxbridge/settings` is the network + asset registry (private, unpublished). `@luxfi/brand` is the Lux brand defaults package (separate npm package, already published `^1.0.0`).
|
||||
|
||||
## 6. Target Architecture
|
||||
|
||||
```
|
||||
+---------------------------+
|
||||
| @luxfi/bridge (pkg/) |
|
||||
Tenant app (~20 LOC) --> | exports: |
|
||||
imports SDK + brand | Bridge, mountBridge |
|
||||
e.g.: | BridgeConfig, … |
|
||||
@luxfi/bridge | internally lazy-loads: |
|
||||
@luxfi/brand --> | @luxbridge/app-v3 |
|
||||
@zooai/brand | @luxbridge/settings |
|
||||
@hanzoai/brand +---------------------------+
|
||||
|
|
||||
v
|
||||
+---------------------------+
|
||||
| app/server (Express + |
|
||||
| Prisma) — Bridge API |
|
||||
| api.bridge.lux.network |
|
||||
+---------------------------+
|
||||
|
|
||||
+--------------------+--------------------+
|
||||
v v
|
||||
+--------------------+ +--------------------+
|
||||
| b-chain (Lux | | @luxfi/threshold |
|
||||
| primary network) | | MPC SDK |
|
||||
| consensus + state | +--------------------+
|
||||
+--------------------+ |
|
||||
+----------------+----------------+
|
||||
v v
|
||||
+------------------+ +------------------+
|
||||
| m-chain | | Private cluster |
|
||||
| (public MPC) | | (treasury fees) |
|
||||
+------------------+ +------------------+
|
||||
```
|
||||
|
||||
**One canonical SDK name. One mount function. One config shape.** All chain-awareness lives behind `apiHost` + `env` — tenants do not pass chain configs.
|
||||
|
||||
## 7. Phase 1 — Wire & Restore (URGENT)
|
||||
|
||||
**Outcome:** `bridge.lux.network` is back up, serving `@luxfi/bridge` SDK pointed at the live `app/server/` API, talking to b-chain and m-chain. Lux testnet → mainnet flow works end-to-end.
|
||||
|
||||
**Deliverables**
|
||||
|
||||
| # | Task | Files |
|
||||
|---|---|---|
|
||||
| 1.1 | Verify `@luxbridge/app-v3` (`app/bridge3/`) compiles and runs against `apiHost: api.bridge.lux.network` in `env: mainnet`. | `app/bridge3/.env.example`, `app/bridge3/vite.config.ts` |
|
||||
| 1.2 | Commit the in-flight SDK edits (`Bridge.tsx`, `package.json`, `luxbridge-app.d.ts`, `tsconfig.json`) once 1.1 is green. | `pkg/bridge/src/Bridge.tsx`, `pkg/bridge/package.json`, `pkg/bridge/src/luxbridge-app.d.ts`, `pkg/bridge/tsconfig.json` |
|
||||
| 1.3 | Run the SDK end-to-end against Lux testnet. Confirm: deposit quote, swap, withdrawal, MPC signature path. | manual + e2e |
|
||||
| 1.4 | Deploy the Lux tenant app to `bridge.lux.network`. | tenant deploy pipeline |
|
||||
| 1.5 | Refresh `docs/BRIDGE-STATUS.md` and `docs/LOCAL-SETUP.md` to point at `app/bridge3/` (not legacy `app/bridge/`). | `docs/BRIDGE-STATUS.md`, `docs/LOCAL-SETUP.md` |
|
||||
| 1.6 | Fix `pkg/bridge/README.md` mismatches: (a) architecture diagram still says `@luxbridge/app` but code imports `@luxbridge/app-v3`; (b) document the exported `applyBrandMetadata`, `getConfig`, `setConfig`. | `pkg/bridge/README.md` |
|
||||
|
||||
**Acceptance criteria**
|
||||
|
||||
- A user can reach `bridge.lux.network`, connect a wallet, get a quote on Lux testnet, and complete a bridge transaction signed by an m-chain MPC quorum.
|
||||
- Internal devs can run `pnpm dev` from `app/bridge3/` against local `app/server/` and complete the same flow.
|
||||
- Treasury fee collection through the private MPC cluster fires on a real transfer.
|
||||
- `pkg/bridge/README.md` matches reality and is enough for an external dev to install + mount.
|
||||
|
||||
## 8. Phase 2 — Multi-Tenant Embed
|
||||
|
||||
**Outcome:** the SDK is consumed unchanged from at least two host apps (`luxfi/exchange` web, `zooai/exchange` web) and one standalone Zoo tenant.
|
||||
|
||||
**Deliverables**
|
||||
|
||||
| # | Task | Notes |
|
||||
|---|---|---|
|
||||
| 2.1 | Reconcile the uncommitted deletion of `zoo/bridge` proxy code with the SDK-consumer pattern. | See §10. Target shape: `src/main.tsx`, `package.json`, `vite.config.ts`, `Dockerfile`, `k8s/`, `LLM.md`. |
|
||||
| 2.2 | Publish `@zooai/brand` and `@zooai/logo` if not yet published; confirm `@hanzoai/brand` if needed. | Out-of-tree, coordinate with brand owners. |
|
||||
| 2.3 | Add an `@luxfi/bridge` mount inside `luxfi/exchange/apps/web/src/main.tsx` (mirroring the existing `@luxfi/exchange` SDK pattern). | Cross-repo. |
|
||||
| 2.4 | Same for `zooai/exchange/apps/web/src/main.tsx`. | Cross-repo. |
|
||||
| 2.5 | Confirm `BrandConfig` covers everything the Zoo + Hanzo tenants need without code changes inside `pkg/bridge/`. If anything must be hardcoded, surface it as a new optional `BrandConfig` field with semver-minor bump. | Drives any v1.1.x of the SDK. |
|
||||
|
||||
**Acceptance criteria**
|
||||
|
||||
- Two tenant repos exist (`github.com/luxfi/bridge` and `github.com/zooai/bridge`) and each is a thin shell (≤30 LOC of bridge wiring, excluding build/CI files).
|
||||
- The same `@luxfi/bridge` version installed in each renders the brand-correct UI from `BrandConfig` alone.
|
||||
- No tenant repo contains bridge UI logic, route logic, or wallet logic. All such changes land upstream in `pkg/bridge/`.
|
||||
|
||||
## 9. Phase 3 — White-Label SDK Publication
|
||||
|
||||
**Outcome:** `@luxfi/bridge` is published to the public npm registry and (or any third party) can adopt it with their own backend.
|
||||
|
||||
**Deliverables**
|
||||
|
||||
| # | Task | Notes |
|
||||
|---|---|---|
|
||||
| 3.1 | Switch `pkg/bridge/package.json` `main`/`types` from `src/*.ts` to compiled `dist/*.js` + `.d.ts` outputs. Add a real `build` step that emits both. | Currently `build` is `tsc --noEmit`. |
|
||||
| 3.2 | Externalize React, react-dom, `@luxfi/brand` from the published bundle. | Already peer-deps. |
|
||||
| 3.3 | Verify `@luxbridge/app-v3` and `@luxbridge/settings` are either (a) inlined into the published SDK bundle, or (b) published as `@luxfi/*` packages. They cannot be left as `workspace:*` in a published artifact. | Decision needed (see §11 Open Questions). |
|
||||
| 3.4 | Publish `@luxfi/bridge` v1.0.0 → npm under the `@luxfi` scope (public access). | `pnpm pub` from `pkg/bridge/`. |
|
||||
| 3.5 | Document standalone-backend mode for : how to point `apiHost` at a non-Lux endpoint, what server API contract `app/server/` exposes, what's pluggable. | New doc: `docs/STANDALONE-BACKEND.md`. |
|
||||
| 3.6 | Confirm can render their own securities (AAPL, etc.) via the existing tokens/assets registry (`@luxbridge/settings`) without forking. If not, add an injection point. | May surface a `tokens?` field on `BridgeConfig`. |
|
||||
|
||||
**Acceptance criteria**
|
||||
|
||||
- `npm install @luxfi/bridge` from a fresh project succeeds; the Quick Start in `pkg/bridge/README.md` produces a running bridge in <5 minutes.
|
||||
- A third party can stand up a bridge with their own `apiHost` and `BrandConfig` without modifying SDK source.
|
||||
- A new `docs/STANDALONE-BACKEND.md` clearly describes the path.
|
||||
|
||||
## 10. Uncommitted Working-Tree State
|
||||
|
||||
Two distinct sets of uncommitted changes exist at the time of writing (`git status`):
|
||||
|
||||
### 10.1 Sponsor's deletion of `zoo/bridge` overlay dirs
|
||||
|
||||
Quoted from `client-prompt.jpg`:
|
||||
|
||||
> I deleted the `bridge-proxy` Go code from `zoo/bridge` and the `lux-shim`/`zoo/bridge/app` overlay dirs in the working tree but **haven't committed**. That cleanup needs to be reconciled with the actual SDK-consumer pattern.
|
||||
|
||||
Resolution: this deletion is correct in direction (those overlays are obsolete) but must land alongside a real Zoo tenant repo of the shape described in Phase 2.1. **Do not commit the deletion in isolation** — pair it with the new tenant shell.
|
||||
|
||||
### 10.2 In-flight SDK edits in `pkg/bridge/`
|
||||
|
||||
Per `git status`, four files modified:
|
||||
|
||||
- `pkg/bridge/package.json`
|
||||
- `pkg/bridge/src/Bridge.tsx`
|
||||
- `pkg/bridge/src/luxbridge-app.d.ts`
|
||||
- `pkg/bridge/tsconfig.json`
|
||||
|
||||
These are local edits to the SDK that have not been committed. **Action:** review diff, run typecheck (`pnpm tc` in `pkg/bridge/`), confirm wiring against `app/bridge3/`, then commit as part of Phase 1.2.
|
||||
|
||||
## 11. Risks & Open Questions
|
||||
|
||||
| # | Item | Risk / impact | Owner |
|
||||
|---|---|---|---|
|
||||
| R1 | `@luxbridge/app-v3` is consumed via `workspace:*`. Publishing `@luxfi/bridge` to npm will fail or break consumers unless this is resolved. | Blocks Phase 3. | SDK |
|
||||
| R2 | Stale dev docs (`BRIDGE-STATUS.md`, `LOCAL-SETUP.md`) still tell new devs to use `app/bridge/` (legacy). New contributors will wire the wrong app. | Wasted onboarding cycles. | Docs / Phase 1.5 |
|
||||
| R3 | `pkg/bridge/README.md` advertises `applyBrandMetadata`/`getConfig`/`setConfig` only implicitly. External adopters may not know these helpers exist. | Adoption friction. | Phase 1.6 |
|
||||
| R4 | Legacy `app/bridge/` (`@luxbridge/app` v2.0.0) is still in the tree with 80+ deps and a large `pnpm.overrides` block. Drift risk: someone may "fix" it instead of using the SDK path. | Maintenance burden. | Decide post-Phase 2: archive or delete. |
|
||||
| R5 | 's securities (AAPL, etc.) may require asset-registry injection points the current `@luxbridge/settings` does not expose. | Could force a SDK breaking change. | Investigate during Phase 3.6. |
|
||||
| R6 | OIDC fields `clientId` / `iamOrg` on `BridgeConfig` are not exercised in `app/bridge3/` examples; behavior under non-Lux tenants is unverified. | Auth break for Zoo/Hanzo. | Phase 2 e2e. |
|
||||
|
||||
**Open questions for sponsor:**
|
||||
|
||||
1. For R1 — should `@luxbridge/app-v3` and `@luxbridge/settings` be published as public `@luxfi/*` packages, or inlined into the `@luxfi/bridge` build artifact?
|
||||
2. Is Hanzo a tenant in this round, or only Lux + Zoo + (later) ? Sponsor transcript mentions Hanzo tooling but no tenant repo plan.
|
||||
3. Target date for `bridge.lux.network` restoration? (Phase 1 acceptance.)
|
||||
4. Should the legacy `app/bridge/` directory be deleted in this initiative or left in place?
|
||||
|
||||
## 12. Out-of-Tree References
|
||||
|
||||
| Resource | URL / location |
|
||||
|---|---|
|
||||
| Lux node + primary network | `github.com/luxfi/node`, `github.com/luxfi/chains` |
|
||||
| Bridge API + UI repo (canonical home) | `github.com/luxfi/bridge` |
|
||||
| `@luxfi/threshold` (T-Chain SDK) | `pkg/threshold/` |
|
||||
| Public MPC k8s deployment | `k8s/mpc-deployment.yaml` |
|
||||
| Private MPC config | `config/mpc/config.yaml` |
|
||||
| Bridge API docker image | `ghcr.io/luxbridge/bridge-server` |
|
||||
| Exchange SDK pattern (precedent) | `github.com/luxfi/exchange`, `github.com/zooai/exchange` |
|
||||
| FHE chain (not in scope v1) | `github.com/luxfhe` |
|
||||
|
||||
---
|
||||
|
||||
*End of document. Edit history should be tracked via git.*
|
||||
+2
-2
@@ -30,7 +30,7 @@ services:
|
||||
- POSTGRES_PASSWORD=${CASDOOR_DB_PASSWORD:-changeme}
|
||||
- POSTGRES_DB=casdoor
|
||||
volumes:
|
||||
- lux-id-db-data:/var/lib/postgresql/data
|
||||
- lux-id-db-data:/var/lib/postgresql
|
||||
ports:
|
||||
- "5434:5432"
|
||||
networks:
|
||||
@@ -106,7 +106,7 @@ services:
|
||||
- POSTGRES_PASSWORD=bridge
|
||||
- POSTGRES_DB=bridge
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
- postgres-data:/var/lib/postgresql
|
||||
- ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
ports:
|
||||
- "5433:5432"
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# Lux MPC Network Configuration
|
||||
network:
|
||||
name: bridge-mpc
|
||||
threshold: 3
|
||||
total_nodes: 5
|
||||
|
||||
nodes:
|
||||
- id: mpc-node-0
|
||||
port: 6000
|
||||
grpc_port: 9090
|
||||
- id: mpc-node-1
|
||||
port: 6001
|
||||
grpc_port: 9091
|
||||
- id: mpc-node-2
|
||||
port: 6002
|
||||
grpc_port: 9092
|
||||
- id: mpc-node-3
|
||||
port: 6003
|
||||
grpc_port: 9093
|
||||
- id: mpc-node-4
|
||||
port: 6004
|
||||
grpc_port: 9094
|
||||
|
||||
nats:
|
||||
url: nats://localhost:4223
|
||||
subject_prefix: bridge.mpc
|
||||
|
||||
consul:
|
||||
url: http://localhost:8501
|
||||
service_name: bridge-mpc
|
||||
|
||||
kms:
|
||||
url: http://localhost:8200
|
||||
token: myroot
|
||||
project_id: mpc-bridge
|
||||
secret_path: /mpc
|
||||
|
||||
auth:
|
||||
provider: luxid
|
||||
luxid_url: http://localhost:8000
|
||||
client_id: mpc-bridge
|
||||
client_secret: mpc-bridge-secret
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"node0": "7008dc06-5700-4ebd-b246-d863d406d674",
|
||||
"node1": "868e5954-30a9-4b7e-8740-9324fc5339b0",
|
||||
"node2": "83ee0acc-4a14-4bf2-878e-2d19a166123e"
|
||||
}
|
||||
@@ -1,55 +1,80 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "==================================="
|
||||
echo "Installing Lux MPC Tools"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
# Check if Go is installed
|
||||
if ! command -v go &> /dev/null; then
|
||||
echo "❌ Go is not installed. Please install Go 1.22 or later."
|
||||
echo "❌ Go is not installed. Please install Go 1.26 or later."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Go is installed: $(go version)"
|
||||
echo ""
|
||||
|
||||
# Install MPC CLI tools
|
||||
echo "Installing MPC CLI tools..."
|
||||
echo ""
|
||||
MPC_MODULE="github.com/luxfi/mpc"
|
||||
MPC_VERSION="${MPC_VERSION:-latest}"
|
||||
GOBIN_DIR="$(go env GOPATH)/bin"
|
||||
mkdir -p "$GOBIN_DIR"
|
||||
|
||||
# Install the main MPC CLI
|
||||
echo "Installing lux-mpc..."
|
||||
go install github.com/luxfi/mpc/cmd/lux-mpc@latest
|
||||
# Upstream renamed cmd/lux-mpc → cmd/mpcd and cmd/lux-mpc-cli → cmd/mpc, and
|
||||
# its go.mod contains replace directives — so `go install pkg@version` won't
|
||||
# work. We resolve the requested version through the module cache, copy the
|
||||
# source to a writable scratch dir, refresh go.sum (the upstream sum can
|
||||
# drift when replace-target tags are republished), then `go build -o` into
|
||||
# $GOBIN with the daemon/CLI names the rest of the bridge scripts expect.
|
||||
|
||||
# Install the MPC bridge tool
|
||||
echo "Installing lux-mpc-bridge..."
|
||||
go install github.com/luxfi/mpc/cmd/lux-mpc-bridge@latest
|
||||
WORKDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORKDIR"' EXIT
|
||||
|
||||
# Install the MPC CLI client
|
||||
echo "Installing lux-mpc-cli..."
|
||||
go install github.com/luxfi/mpc/cmd/lux-mpc-cli@latest
|
||||
echo "Resolving $MPC_MODULE@$MPC_VERSION ..."
|
||||
cd "$WORKDIR"
|
||||
go mod init bridge-mpc-installer >/dev/null
|
||||
go mod download -x "$MPC_MODULE@$MPC_VERSION" 2>&1 | tail -1
|
||||
|
||||
# Find the resolved version in the module cache (handles MPC_VERSION=latest).
|
||||
RESOLVED_VERSION="$(go list -m -f '{{.Version}}' "$MPC_MODULE@$MPC_VERSION")"
|
||||
SRC="$(go env GOMODCACHE)/${MPC_MODULE}@${RESOLVED_VERSION}"
|
||||
echo "Resolved version: $RESOLVED_VERSION"
|
||||
|
||||
BUILD_DIR="$WORKDIR/build"
|
||||
cp -r "$SRC" "$BUILD_DIR"
|
||||
chmod -R u+w "$BUILD_DIR"
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
# Drop the workspace file — upstream's go.work references sibling modules
|
||||
# (../threshold, e2e) that aren't shipped in the module zip.
|
||||
rm -f go.work go.work.sum
|
||||
# Refresh go.sum against the current proxy contents (the committed sum can
|
||||
# mismatch when replace-target tags get republished).
|
||||
rm -f go.sum
|
||||
GOWORK=off go mod tidy >/dev/null 2>&1
|
||||
|
||||
echo "Building mpcd (daemon)..."
|
||||
GOWORK=off go build -o "$GOBIN_DIR/mpcd" ./cmd/mpcd
|
||||
|
||||
echo "Building mpc (CLI)..."
|
||||
GOWORK=off go build -o "$GOBIN_DIR/mpc" ./cmd/mpc
|
||||
|
||||
# Bridge scripts call these by their pre-rename names; keep them working
|
||||
# via symlinks rather than touching every call site.
|
||||
ln -sf "$GOBIN_DIR/mpcd" "$GOBIN_DIR/lux-mpc"
|
||||
ln -sf "$GOBIN_DIR/mpc" "$GOBIN_DIR/lux-mpc-cli"
|
||||
|
||||
# Check installations
|
||||
echo ""
|
||||
echo "Verifying installations..."
|
||||
echo ""
|
||||
|
||||
# Check if binaries are in PATH
|
||||
if command -v lux-mpc &> /dev/null; then
|
||||
echo "✅ lux-mpc installed: $(which lux-mpc)"
|
||||
echo "✅ lux-mpc installed: $(which lux-mpc) -> $(readlink -f "$(which lux-mpc)")"
|
||||
else
|
||||
echo "⚠️ lux-mpc installed but not in PATH. Add $(go env GOPATH)/bin to your PATH."
|
||||
fi
|
||||
|
||||
if command -v lux-mpc-bridge &> /dev/null; then
|
||||
echo "✅ lux-mpc-bridge installed: $(which lux-mpc-bridge)"
|
||||
else
|
||||
echo "⚠️ lux-mpc-bridge installed but not in PATH."
|
||||
echo "⚠️ lux-mpc installed but not in PATH. Add $GOBIN_DIR to your PATH."
|
||||
fi
|
||||
|
||||
if command -v lux-mpc-cli &> /dev/null; then
|
||||
echo "✅ lux-mpc-cli installed: $(which lux-mpc-cli)"
|
||||
echo "✅ lux-mpc-cli installed: $(which lux-mpc-cli) -> $(readlink -f "$(which lux-mpc-cli)")"
|
||||
else
|
||||
echo "⚠️ lux-mpc-cli installed but not in PATH."
|
||||
fi
|
||||
@@ -60,12 +85,11 @@ echo "Installation Complete!"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
echo "If tools are not in your PATH, add this to your shell profile:"
|
||||
echo " export PATH=\"\$PATH:\$(go env GOPATH)/bin\""
|
||||
echo " export PATH=\"\$PATH:$GOBIN_DIR\""
|
||||
echo ""
|
||||
echo "Available commands:"
|
||||
echo " lux-mpc - Main MPC node daemon"
|
||||
echo " lux-mpc-bridge - MPC bridge tool"
|
||||
echo " lux-mpc-cli - CLI client for MPC operations"
|
||||
echo " lux-mpc - Main MPC node daemon (symlink to mpcd)"
|
||||
echo " lux-mpc-cli - CLI client for MPC operations (symlink to mpc)"
|
||||
echo ""
|
||||
echo "To start a local MPC network:"
|
||||
echo " ./scripts/start-mpc-network.sh"
|
||||
echo " ./scripts/start-mpc-network.sh"
|
||||
|
||||
+73
-158
@@ -1,178 +1,93 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "==================================="
|
||||
echo "Starting Lux MPC Network"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
# Check if MPC tools are installed
|
||||
if ! command -v lux-mpc &> /dev/null; then
|
||||
echo "❌ lux-mpc not found. Please run ./scripts/install-mpc-tools.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configuration
|
||||
if ! command -v lux-mpc-cli &> /dev/null; then
|
||||
echo "❌ lux-mpc-cli not found. Please run ./scripts/install-mpc-tools.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MPC_DATA_DIR="${MPC_DATA_DIR:-./data/mpc}"
|
||||
MPC_CONFIG_DIR="${MPC_CONFIG_DIR:-./config/mpc}"
|
||||
NATS_URL="${NATS_URL:-nats://localhost:4223}"
|
||||
CONSUL_URL="${CONSUL_URL:-http://localhost:8501}"
|
||||
KMS_URL="${KMS_URL:-http://localhost:8200}"
|
||||
KMS_TOKEN="${KMS_TOKEN:-myroot}"
|
||||
LUXID_URL="${LUXID_URL:-http://localhost:8000}"
|
||||
# ZapDB encryption password — read by mpcd's hsm/env provider. Same constant
|
||||
# as the previous implementation's badger_password so on-disk state stays
|
||||
# decryptable across the migration.
|
||||
export MPC_PASSWORD="${MPC_PASSWORD:-12345678901234567890123456789012}"
|
||||
|
||||
# Create directories
|
||||
echo "Creating directories..."
|
||||
mkdir -p "$MPC_DATA_DIR"/{node0,node1,node2}
|
||||
mkdir -p "$MPC_CONFIG_DIR"
|
||||
mkdir -p logs
|
||||
# Node layout — same external HTTP API ports as the legacy script (6000-6002)
|
||||
# so existing bridge consumers don't need to change endpoints. The :9090-9092
|
||||
# range moves from "gRPC" to mpcd's ZAP P2P transport.
|
||||
NODES=(node0 node1 node2)
|
||||
P2P_PORTS=(9090 9091 9092)
|
||||
API_PORTS=(6000 6001 6002)
|
||||
DASH_PORTS=(8081 8082 8083)
|
||||
THRESHOLD=2
|
||||
|
||||
# Generate MPC configuration if not exists
|
||||
if [ ! -f "$MPC_CONFIG_DIR/config.yaml" ]; then
|
||||
echo "Generating MPC configuration..."
|
||||
cat > "$MPC_CONFIG_DIR/config.yaml" << EOF
|
||||
# Lux MPC Network Configuration
|
||||
network:
|
||||
name: bridge-mpc
|
||||
threshold: 2
|
||||
total_nodes: 3
|
||||
mkdir -p "$MPC_CONFIG_DIR" logs
|
||||
for n in "${NODES[@]}"; do
|
||||
mkdir -p "$MPC_DATA_DIR/$n/data" "$MPC_DATA_DIR/$n/keys"
|
||||
done
|
||||
|
||||
nodes:
|
||||
- id: mpc-node-0
|
||||
port: 6000
|
||||
grpc_port: 9090
|
||||
- id: mpc-node-1
|
||||
port: 6001
|
||||
grpc_port: 9091
|
||||
- id: mpc-node-2
|
||||
port: 6002
|
||||
grpc_port: 9092
|
||||
# Per-node Ed25519 identities are generated by mpcd itself on first start
|
||||
# (cmd/mpcd/main.go:loadOrGenerateIdentity), written to
|
||||
# <keys>/<node>_identity.json with the {node_id, public_key, private_key}
|
||||
# shape it expects. Peer pubkeys are then exchanged at the ZAP transport
|
||||
# layer — no need to pre-share. The lux-mpc-cli generate-identity output
|
||||
# uses a different schema and would be clobbered, so we don't pre-generate.
|
||||
|
||||
nats:
|
||||
url: ${NATS_URL}
|
||||
subject_prefix: bridge.mpc
|
||||
|
||||
consul:
|
||||
url: ${CONSUL_URL}
|
||||
service_name: bridge-mpc
|
||||
|
||||
kms:
|
||||
url: ${KMS_URL}
|
||||
token: ${KMS_TOKEN}
|
||||
project_id: mpc-bridge
|
||||
secret_path: /mpc
|
||||
|
||||
auth:
|
||||
provider: luxid
|
||||
luxid_url: ${LUXID_URL}
|
||||
client_id: mpc-bridge
|
||||
client_secret: mpc-bridge-secret
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Generate peer configuration if not exists
|
||||
if [ ! -f "$MPC_CONFIG_DIR/peers.json" ]; then
|
||||
echo "Generating peer configuration..."
|
||||
lux-mpc-cli generate-peers --number 3 --output "$MPC_CONFIG_DIR/peers.json"
|
||||
fi
|
||||
|
||||
# Function to start a node
|
||||
start_node() {
|
||||
local node_id=$1
|
||||
local port=$2
|
||||
local grpc_port=$3
|
||||
|
||||
echo "Starting $node_id on port $port (gRPC: $grpc_port)..."
|
||||
|
||||
# Set environment variables
|
||||
export NODE_ID="$node_id"
|
||||
export NODE_PORT="$port"
|
||||
export GRPC_PORT="$grpc_port"
|
||||
export NATS_URL="$NATS_URL"
|
||||
export CONSUL_URL="$CONSUL_URL"
|
||||
export DATA_DIR="$MPC_DATA_DIR/$node_id"
|
||||
export CONFIG_PATH="$MPC_CONFIG_DIR/config.yaml"
|
||||
export PEERS_PATH="$MPC_CONFIG_DIR/peers.json"
|
||||
export LOG_LEVEL="${LOG_LEVEL:-info}"
|
||||
|
||||
# KMS configuration
|
||||
export KMS_URL="$KMS_URL"
|
||||
export KMS_TOKEN="$KMS_TOKEN"
|
||||
export KMS_PROJECT_ID="mpc-bridge"
|
||||
export KMS_SECRET_PATH="/mpc"
|
||||
|
||||
# Lux ID configuration
|
||||
export LUXID_URL="$LUXID_URL"
|
||||
export LUXID_CLIENT_ID="mpc-$node_id"
|
||||
export LUXID_CLIENT_SECRET="mpc-secret"
|
||||
|
||||
# Create node-specific config
|
||||
cat > "$DATA_DIR/config.yaml" << EOF
|
||||
nats:
|
||||
url: ${NATS_URL}
|
||||
consul:
|
||||
address: localhost:8500
|
||||
|
||||
mpc_threshold: 2
|
||||
environment: local
|
||||
badger_password: "12345678901234567890123456789012"
|
||||
event_initiator_pubkey: "c3f3511cd2f849fd61e81ea62a842fd33367ee8fb5b867bb900877c7fb72ce3b"
|
||||
max_concurrent_keygen: 2
|
||||
db_path: "${DATA_DIR}"
|
||||
backup_enabled: true
|
||||
backup_period_seconds: 300
|
||||
backup_dir: ${DATA_DIR}/backups
|
||||
local idx=$1
|
||||
local name=${NODES[$idx]}
|
||||
local p2p=${P2P_PORTS[$idx]}
|
||||
local api=${API_PORTS[$idx]}
|
||||
local dash=${DASH_PORTS[$idx]}
|
||||
|
||||
# Node specific settings
|
||||
node_name: "${node_id}"
|
||||
http_port: ${port}
|
||||
grpc_port: ${grpc_port}
|
||||
EOF
|
||||
|
||||
# Create identity directory and copy all identity files
|
||||
mkdir -p "$DATA_DIR/identity"
|
||||
# Copy all identity files from all nodes
|
||||
for i in 0 1 2; do
|
||||
cp "$MPC_DATA_DIR/node$i/node${i}_identity.json" "$DATA_DIR/identity/" 2>/dev/null || true
|
||||
local peer_args=()
|
||||
for j in "${!NODES[@]}"; do
|
||||
[ "$j" = "$idx" ] && continue
|
||||
peer_args+=(--peer "${NODES[$j]}@127.0.0.1:${P2P_PORTS[$j]}")
|
||||
done
|
||||
# Copy only this node's private key
|
||||
cp "$MPC_DATA_DIR/$node_id/${node_id}_private.key" "$DATA_DIR/identity/" 2>/dev/null || true
|
||||
|
||||
# Copy peers.json to node directory
|
||||
cp "$MPC_CONFIG_DIR/peers.json" "$DATA_DIR/peers.json"
|
||||
|
||||
# Start the node
|
||||
LOG_FILE="$(pwd)/logs/$node_id.log"
|
||||
cd "$DATA_DIR" && lux-mpc start --name "$node_id" > "$LOG_FILE" 2>&1 &
|
||||
|
||||
echo "$node_id started with PID $!"
|
||||
|
||||
echo "Starting $name (P2P :$p2p, API :$api, dashboard :$dash)..."
|
||||
local log_file="$(pwd)/logs/${name}.log"
|
||||
|
||||
nohup lux-mpc start \
|
||||
--node-id "$name" \
|
||||
--listen ":$p2p" \
|
||||
--api ":$api" \
|
||||
--api-listen ":$dash" \
|
||||
--data "$MPC_DATA_DIR/$name/data" \
|
||||
--keys "$MPC_DATA_DIR/$name/keys" \
|
||||
--threshold "$THRESHOLD" \
|
||||
--log-level "${LOG_LEVEL:-info}" \
|
||||
--kms-zap-listen "" \
|
||||
--threshold-listen "" \
|
||||
"${peer_args[@]}" \
|
||||
> "$log_file" 2>&1 &
|
||||
|
||||
echo "$name started with PID $!"
|
||||
}
|
||||
|
||||
# Check if infrastructure is running
|
||||
echo "Checking infrastructure services..."
|
||||
if ! nc -z localhost 4223 2>/dev/null; then
|
||||
echo "⚠️ NATS not running on port 4223. Make sure to run 'make up' first."
|
||||
fi
|
||||
|
||||
if ! nc -z localhost 8501 2>/dev/null; then
|
||||
echo "⚠️ Consul not running on port 8501. Make sure to run 'make up' first."
|
||||
fi
|
||||
|
||||
if ! nc -z localhost 8200 2>/dev/null; then
|
||||
echo "⚠️ KMS not running on port 8200. Make sure to run 'make up' first."
|
||||
fi
|
||||
|
||||
if ! nc -z localhost 8000 2>/dev/null; then
|
||||
echo "⚠️ Lux ID not running on port 8000. Make sure to run 'make up' first."
|
||||
fi
|
||||
|
||||
nc -z localhost 4223 2>/dev/null || echo "⚠️ NATS not running on :4223 — only required for legacy mode; consensus-mode mpcd doesn't use it."
|
||||
nc -z localhost 8501 2>/dev/null || echo "⚠️ Consul not running on :8501 — only required for legacy mode; consensus-mode mpcd doesn't use it."
|
||||
nc -z localhost 8200 2>/dev/null || echo "⚠️ KMS not running on :8200 — required if bridge server uses real KMS."
|
||||
nc -z localhost 8000 2>/dev/null || echo "⚠️ Lux ID not running on :8000 — required if bridge server uses real auth."
|
||||
echo ""
|
||||
|
||||
# Start all nodes
|
||||
start_node "node0" 6000 9090
|
||||
sleep 2
|
||||
start_node "node1" 6001 9091
|
||||
sleep 2
|
||||
start_node "node2" 6002 9092
|
||||
for i in "${!NODES[@]}"; do
|
||||
start_node "$i"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "==================================="
|
||||
@@ -180,17 +95,17 @@ echo "MPC Network Started!"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
echo "Nodes:"
|
||||
echo " - node0: HTTP=6000, gRPC=9090"
|
||||
echo " - node1: HTTP=6001, gRPC=9091"
|
||||
echo " - node2: HTTP=6002, gRPC=9092"
|
||||
for i in "${!NODES[@]}"; do
|
||||
echo " - ${NODES[$i]}: API=http://localhost:${API_PORTS[$i]}, P2P=:${P2P_PORTS[$i]}, dashboard=:${DASH_PORTS[$i]}"
|
||||
done
|
||||
echo ""
|
||||
echo "Logs:"
|
||||
echo " - logs/node0.log"
|
||||
echo " - logs/node1.log"
|
||||
echo " - logs/node2.log"
|
||||
for n in "${NODES[@]}"; do
|
||||
echo " - logs/${n}.log"
|
||||
done
|
||||
echo ""
|
||||
echo "To check status:"
|
||||
echo " lux-mpc-cli status --url http://localhost:6000"
|
||||
echo "To check health:"
|
||||
echo " curl http://localhost:${API_PORTS[0]}/healthz"
|
||||
echo ""
|
||||
echo "To stop the network:"
|
||||
echo " ./scripts/stop-mpc-network.sh"
|
||||
echo " ./scripts/stop-mpc-network.sh"
|
||||
|
||||
@@ -5,15 +5,16 @@ echo "Stopping Lux MPC Network"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
# Kill all lux-mpc processes
|
||||
# Kill all MPC node processes — match both the lux-mpc symlink and the
|
||||
# underlying mpcd binary, in case someone launched the daemon directly.
|
||||
echo "Stopping MPC nodes..."
|
||||
pkill -f "lux-mpc start" || true
|
||||
pkill -f "(lux-mpc|mpcd) start" || true
|
||||
|
||||
# Give processes time to shut down gracefully
|
||||
sleep 2
|
||||
|
||||
# Force kill if still running
|
||||
pkill -9 -f "lux-mpc start" 2>/dev/null || true
|
||||
pkill -9 -f "(lux-mpc|mpcd) start" 2>/dev/null || true
|
||||
|
||||
echo "✅ MPC nodes stopped"
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user