diff --git a/README.md b/README.md index f9f5190..3d37dc4 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,174 @@ # Miden Multisig -This repository provides the infrastructure for managing multi-signature accounts on the Miden network. It houses three main components: - -- **miden-multisig-coordinator**: A backend coordinator server that manages multisig accounts, transaction proposals, and signature collection -- **coordinator-frontend**: A Next.js web frontend for interacting with the multisig coordinator -- **miden-multisig-client**: Client libraries for interacting with multisig accounts and the coordinator service +Multi-signature account management on the [Miden](https://miden.io) network. Multiple parties collectively control an account, requiring a configurable threshold of signatures to execute transactions. ## Status This project is under **active development**. The APIs, data structures, and workflows are subject to change. **Expect breaking changes** as we iterate on the design and implementation. -## Overview +## Architecture + +The frontend communicates directly with the [PSM (Private State Manager)](https://docs.openzeppelin.com) SDK for proposal coordination and state synchronization. The coordinator server is available as an optional backend for deployments that need centralized API access or audit trails. + +```text +Frontend (Next.js + WASM) + ├── WebClient (@miden-sdk/miden-sdk) ──────► Miden RPC Node + ├── MultisigClient (@openzeppelin/miden-multisig-client) ──► PSM Endpoint + └── Para Wallet (@getpara/react-sdk-lite) ──► External ECDSA wallets + +Coordinator Server (Rust/Axum) [optional] + ├── MultisigEngine ──► Miden RPC Node + └── MultisigStore ──► PostgreSQL +``` + +### Components + +- **coordinator-frontend** — Next.js web application. Runs a WASM-compiled Miden client in the browser, connects to PSM for proposal coordination, and supports multiple wallet types for signing. +- **coordinator-server** — Rust/Axum HTTP server that wraps the multisig engine. Provides a REST API for account creation, transaction proposals, and signature collection. See [`bin/coordinator-server/README.md`](bin/coordinator-server/README.md) for the full API reference. +- **miden-multisig-client** — Rust client library for multisig operations, used by the coordinator engine. + +### Wallet Support -The Miden MultiSig system enables multiple parties to collectively control an account, requiring a threshold of signatures to execute transactions. The coordinator server acts as a central point for: +The frontend supports three wallet sources for signing: -- Creating and managing multisig accounts -- Coordinating transaction proposals -- Collecting and verifying signatures from approvers -- Executing transactions once the signature threshold is met +| Source | Scheme | Description | +|--------|--------|-------------| +| **Local keys** | Falcon / ECDSA | Browser-generated keys stored in IndexedDB | +| **[Para](https://getpara.com)** | ECDSA | External EVM wallets (MetaMask, etc.) via Para SDK | +| **[Miden Wallet](https://github.com/demox-labs/miden-wallet)** | Falcon / ECDSA | Miden Wallet browser extension | ## Workspace Structure ```text . ├── bin/ -│ ├── coordinator-frontend/ # Web frontend application -│ └── coordinator-server/ # Coordinator server binary and configuration +│ ├── coordinator-frontend/ # Next.js web frontend (PSM SDK + WASM) +│ └── coordinator-server/ # Rust coordinator server (Axum + PostgreSQL) ├── crates/ │ ├── coordinator/ │ │ ├── domain/ # Core domain models and types │ │ ├── engine/ # Business logic and multisig engine -│ │ ├── store/ # Database layer and persistence +│ │ ├── store/ # PostgreSQL persistence (Diesel ORM) │ │ └── utils/ # Shared utilities -│ └── miden-multisig-client/ # Client library for multisig operations +│ └── miden-multisig-client/ # Rust client library for multisig operations ├── Dockerfile.coordinator # Docker image for coordinator server ├── Dockerfile.coordinator-frontend # Docker image for frontend -└── docker-compose.yml # Docker compose setup (frontend + server + PostgreSQL) +└── docker-compose.yml # Full stack: frontend + server + PostgreSQL ``` ## Quick Start with Docker -For local development and testing, you can quickly spin up the entire stack (frontend, coordinator server, and PostgreSQL) using make targets: - -### Start the Coordinator Server + Frontend application +Spin up the full stack (frontend, coordinator server, and PostgreSQL) locally: ```bash make docker-run-coordinator ``` -This will: - -- Build the Docker images for the frontend and coordinator server -- Start PostgreSQL database with the required schema (see [migrations](crates/coordinator/store/migrations)) -- Start the coordinator server listening on `http://localhost:59059` -- Start the frontend web application at `http://localhost:3000` +This builds the Docker images and starts: -The server exposes a REST API for multisig operations and includes a `/health` endpoint for monitoring. The frontend provides a user-friendly interface for managing multisig accounts and transactions. +| Service | URL | Description | +|---------|-----|-------------| +| Frontend | `http://localhost:3000` | Web UI | +| Coordinator Server | `http://localhost:59059` | REST API (+ `/health` endpoint) | +| PostgreSQL | `localhost:5432` | Database | -### Stop All Services +To stop and remove all containers: ```bash make docker-stop-coordinator ``` -This will stop and remove all containers. Note that the multisig client store and the PostgreSQL database are ephemeral (no persistent volumes), so all data will be lost when containers are stopped. +> **Note:** The PostgreSQL database is ephemeral (no persistent volumes). All data is lost when containers stop. + +## Configuration + +### Frontend Environment Variables + +The frontend is configured via `NEXT_PUBLIC_*` environment variables, set at build time. In Docker, these are defined in the `frontend` service in `docker-compose.yml`. + +| Variable | Description | Default | +|----------|-------------|---------| +| `NEXT_PUBLIC_PSM_ENDPOINT` | PSM service URL for proposal coordination | `https://psm-stg.openzeppelin.com` | +| `NEXT_PUBLIC_MIDEN_RPC_URL` | Miden node RPC endpoint | `https://rpc.devnet.miden.io` | +| `NEXT_PUBLIC_PARA_API_KEY` | [Para](https://getpara.com) wallet API key (enables Para wallet support) | _(empty — Para disabled)_ | +| `NEXT_PUBLIC_PARA_ENVIRONMENT` | Para environment (`development` or `production`) | `development` | +| `NEXT_PUBLIC_COORDINATOR_API_URL` | Coordinator server URL (internal, for server-side requests) | — | +| `NEXT_PUBLIC_EXTERNAL_COORDINATOR_API_URL` | Coordinator server URL (external, for browser requests) | — | + +> `VITE_PARA_API_KEY` is also accepted as a compatibility alias for `NEXT_PUBLIC_PARA_API_KEY`. + +### Coordinator Server Environment Variables + +The server reads `bin/coordinator-server/src/base_config.ron` as defaults and overrides values with environment variables prefixed `MIDENMULTISIG_`. Use `__` for nested keys. + +| Variable | Description | Default | +|----------|-------------|---------| +| `MIDENMULTISIG_APP__LISTEN` | Server bind address | `localhost:59059` | +| `MIDENMULTISIG_APP__NETWORK_ID_HRP` | Bech32 human-readable prefix | `mtst` | +| `MIDENMULTISIG_APP__CORS_ALLOWED_ORIGINS` | JSON array of allowed origins | `["*"]` | +| `MIDENMULTISIG_DB__DB_URL` | PostgreSQL connection string | `postgres://multisig:multisig_password@localhost:5432/multisig` | +| `MIDENMULTISIG_DB__MAX_CONN` | Connection pool size | `10` | +| `MIDENMULTISIG_MIDEN__NODE_URL` | Miden node RPC URL | `https://rpc.testnet.miden.io:443` | +| `MIDENMULTISIG_MIDEN__STORE_PATH` | Local Miden client store path | `./store` | +| `MIDENMULTISIG_MIDEN__KEYSTORE_PATH` | Keystore directory path | `./keystore` | +| `MIDENMULTISIG_MIDEN__TIMEOUT` | Request timeout | `30s` | +| `RUST_LOG` | Log level (`debug`, `info`, `warn`, `error`) | `info` | + +For full server configuration details, see [`bin/coordinator-server/README.md`](bin/coordinator-server/README.md). + +## Local Development + +### Prerequisites + +- **Rust** 1.90+ (see [`rust-toolchain.toml`](rust-toolchain.toml)) +- **Node.js** 18+ +- **PostgreSQL** 13+ (or use Docker) +- **Docker** (for containerized setup) + +### Development Tools + +```bash +# Check which tools are installed +make check-tools + +# Install all required dev tools (typos, nextest, taplo, machete) +make install-tools +``` + +### Frontend + +```bash +cd bin/coordinator-frontend +npm install +npm run dev +# → http://localhost:3000 +``` + +Create a `.env.local` file for local development: + +```bash +NEXT_PUBLIC_PSM_ENDPOINT=https://psm-stg.openzeppelin.com +NEXT_PUBLIC_MIDEN_RPC_URL=https://rpc.devnet.miden.io +NEXT_PUBLIC_PARA_API_KEY= +NEXT_PUBLIC_PARA_ENVIRONMENT=development +``` + +### Server -### Configuration +See the [database migrations section](crates/coordinator/store/README.md#database-migrations) for PostgreSQL setup, then: -The coordinator server is configured via environment variables in `docker-compose.yml`. Key settings include: +```bash +cargo run --release --bin miden-multisig-coordinator-server +``` -- **Application**: Listen address, network ID -- **Database**: PostgreSQL connection string and pool settings -- **Miden**: Node RPC URL, store path, keystore path +### Common Make Targets -For detailed configuration options, see `bin/coordinator-server/src/base_config.ron` and the environment variables in `docker-compose.yml`. +```bash +make build # Build all Rust crates (release) +make test # Run tests +make lint # Run all linters (clippy, fmt, taplo, typos, machete) +make check # Check all targets for errors +``` ## License diff --git a/bin/coordinator-frontend/README.md b/bin/coordinator-frontend/README.md index 63eef2c..f413833 100644 --- a/bin/coordinator-frontend/README.md +++ b/bin/coordinator-frontend/README.md @@ -1,57 +1,90 @@ ## Coordinator Frontend -The coordinator frontend is built with Next.js and connects to the multisig coordinator backend. This document focuses on the pieces you need to run and develop the UI locally. +Next.js web application for managing Miden multisig accounts. Uses the [PSM SDK](https://docs.openzeppelin.com) (`@openzeppelin/miden-multisig-client`) for proposal coordination and a WASM-compiled Miden client (`@miden-sdk/miden-sdk`) running in the browser. + +> [!NOTE] +> After v0.13.x testnet, the frontend only coordinates using [PSM](https://github.com/OpenZeppelin/private-state-manager.git). The coordinator server backend present in this repository is ignored even when running. ## Prerequisites - Node.js 18+ -- pnpm, npm, yarn, or bun -- Access to a running coordinator backend (local or remote) +- npm, pnpm, yarn, or bun -## Environment setup +## Environment Setup Create `.env.local` in the project root: ```bash +# Required +NEXT_PUBLIC_PSM_ENDPOINT=https://psm-stg.openzeppelin.com +NEXT_PUBLIC_MIDEN_RPC_URL=https://rpc.devnet.miden.io + +# Para wallet support (optional — enables external EVM wallet signing) +NEXT_PUBLIC_PARA_API_KEY= +NEXT_PUBLIC_PARA_ENVIRONMENT=development + +# Coordinator server (optional — only needed if running the coordinator backend) NEXT_PUBLIC_COORDINATOR_API_URL=http://localhost:59059 -NEXT_PUBLIC_MIDEN_NODE_ENDPOINT=https://rpc.testnet.miden.io:443 +NEXT_PUBLIC_EXTERNAL_COORDINATOR_API_URL=http://localhost:59059 ``` -Additional environment options are documented in [ENV_CONFIG.md](./ENV_CONFIG.md). +| Variable | Description | Default | +|----------|-------------|---------| +| `NEXT_PUBLIC_PSM_ENDPOINT` | PSM service URL | `https://psm-stg.openzeppelin.com` | +| `NEXT_PUBLIC_MIDEN_RPC_URL` | Miden node RPC endpoint | `https://rpc.devnet.miden.io` | +| `NEXT_PUBLIC_PARA_API_KEY` | Para wallet API key | _(empty — disabled)_ | +| `NEXT_PUBLIC_PARA_ENVIRONMENT` | Para environment (`development` / `production`) | `development` | -## Install dependencies +## Install Dependencies ```bash -pnpm install -# or npm install ``` -## Run the development server +## Run the Development Server ```bash -pnpm dev -# or npm run dev ``` -Open to view the app. Changes in `src` hot-reload automatically. +Open to view the app. Changes in `src/` hot-reload automatically. -## Available scripts +## Available Scripts ```bash -pnpm build # Create a production build -pnpm start # Serve the production build -pnpm lint # Run lint checks +npm run build # Create a production build (standalone output) +npm run start # Serve the production build +npm run lint # Run lint checks +``` + +## Project Structure + +```text +src/ +├── app/ # Next.js app router (pages and layouts) +│ ├── login/ # Account creation and loading flows +│ └── dashboard/ # Main dashboard (home, assets, transactions, settings) +├── components/ # Shared UI components (AppHeader, Providers) +├── contexts/ # MultisigContext — central state manager +├── hooks/ # useParaSession, useMidenWallet +├── interactions/ # Modal flows (send, receive, sign, approve) +├── lib/ # Core logic (initClient, multisigApi, procedures) +├── store/ # Redux store (wallet form state) +├── types/ # TypeScript type definitions +└── wallets/ # Wallet source types and abstractions ``` -## Project structure +### Key Files -- `src/app` – Next.js app directory for routes and UI -- `src/services` – API clients and async thunks -- `src/interactions` – Wallet interactions and modal flows -- `src/contexts` – React context providers +- **`src/contexts/MultisigContext.tsx`** — Central state manager. Initializes the WebClient and MultisigClient, manages account state, proposals, and signing operations. +- **`src/lib/initClient.ts`** — WebClient (WASM) and signer key initialization. +- **`src/lib/multisigApi.ts`** — MultisigClient creation and signer factory. +- **`src/config/psm.ts`** — PSM, Miden RPC, and Para configuration constants. +- **`src/hooks/useParaSession.ts`** — Para wallet connection and ECDSA key derivation. +- **`src/hooks/useMidenWallet.ts`** — Miden Wallet browser extension integration. ## Troubleshooting -If the UI fails to reach the coordinator API, confirm the values in `.env.local` and ensure the backend is reachable from your machine. +- **WASM loading fails** — Ensure `public/miden_client_web.wasm` exists. The webpack config in `next.config.mjs` copies it to the required locations during build. +- **Para wallet not showing** — Verify `NEXT_PUBLIC_PARA_API_KEY` is set. The Para modal only renders when an API key is present. +- **State issues after upgrade** — The app clears IndexedDB (`MidenClientDB`) on initialization. If you see stale data, try clearing browser storage manually.