#!/bin/bash # Archipelago Development Server Starter SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" FRONTEND_DIR="$PROJECT_ROOT/neode-ui" BACKEND_DIR="$PROJECT_ROOT/core" # Quietly kill a port — avoids EAGAIN by not piping through xargs kill_port() { local pids pids=$(lsof -ti:"$1" 2>/dev/null) || true if [ -n "$pids" ]; then echo "$pids" | while read -r pid; do kill -9 "$pid" 2>/dev/null || true done sleep 1 fi } cleanup_ports() { kill_port 5959 kill_port 8100 } ensure_deps() { cd "$FRONTEND_DIR" if [ ! -d "node_modules" ]; then echo " Installing dependencies..." npm install fi } if [ ! -d "$FRONTEND_DIR" ]; then echo "Frontend directory not found: $FRONTEND_DIR" exit 1 fi echo "" echo "Archipelago Dev Server" echo "" echo " 1) Mock backend (UI dev — fastest, no Docker/Podman needed)" echo " 2) Full stack (Rust backend + frontend)" echo " 3) Setup mode (first-time password setup — mock)" echo " 4) Onboarding mode (onboarding flow — mock)" echo " 5) Existing user (login screen — mock)" echo " 6) Boot mode (simulated 25s startup — mock)" echo " 7) Testnet stack (signet Bitcoin + LND + ThunderHub via Podman)" echo " 8) Manual instructions" echo "" read -p "Enter choice [1-8]: " choice case $choice in 1) echo "" echo "Starting frontend with mock backend..." cleanup_ports ensure_deps exec npm run dev:mock ;; 2) echo "" echo "Starting full stack (Rust backend + frontend)..." cleanup_ports if [ ! -d "$BACKEND_DIR" ]; then echo "Backend directory not found: $BACKEND_DIR" exit 1 fi cd "$BACKEND_DIR" if ! cargo check --bin archipelago > /tmp/archipelago-backend-check.log 2>&1; then echo "Backend build check failed. See /tmp/archipelago-backend-check.log" echo "Falling back to mock backend." ensure_deps exec npm run dev:mock fi echo " Starting Rust backend..." export ARCHIPELAGO_DATA_DIR=/tmp/archipelago-dev export ARCHIPELAGO_DEV_DATA_DIR=/tmp/archipelago-dev export ARCHIPELAGO_DEV_MODE=true export ARCHIPELAGO_BIND=127.0.0.1:5959 export ARCHIPELAGO_LOG_LEVEL=debug export ARCHIPELAGO_BITCOIN_SIMULATION=mock cargo run --bin archipelago > /tmp/archipelago-backend.log 2>&1 & BACKEND_PID=$! echo " Backend PID: $BACKEND_PID (logs: /tmp/archipelago-backend.log)" echo " Waiting for backend on port 5959..." for i in $(seq 1 60); do if lsof -ti:5959 >/dev/null 2>&1; then break; fi sleep 1 done if ! lsof -ti:5959 >/dev/null 2>&1; then echo "Backend did not start. Falling back to mock." kill "$BACKEND_PID" 2>/dev/null || true ensure_deps exec npm run dev:mock fi echo " Backend ready." trap "kill $BACKEND_PID 2>/dev/null" EXIT ensure_deps exec npm run dev ;; 3) echo "" echo "Starting setup mode..." cleanup_ports ensure_deps VITE_DEV_MODE=setup exec npm run dev:mock ;; 4) echo "" echo "Starting onboarding mode..." cleanup_ports ensure_deps VITE_DEV_MODE=onboarding exec npm run dev:mock ;; 5) echo "" echo "Starting existing user mode..." cleanup_ports ensure_deps VITE_DEV_MODE=existing exec npm run dev:mock ;; 6) echo "" echo "Starting boot mode (25s simulated startup)..." cleanup_ports ensure_deps VITE_DEV_MODE=boot exec npm run dev:mock ;; 7) echo "" echo "Starting testnet stack (signet) via Podman/Docker..." # Check for a working container runtime (binary exists AND daemon responds) RUNTIME="" COMPOSE="" if command -v docker &>/dev/null && docker ps &>/dev/null; then RUNTIME="docker" COMPOSE="docker compose" elif command -v podman &>/dev/null && podman ps &>/dev/null; then if command -v podman-compose &>/dev/null; then RUNTIME="podman" COMPOSE="podman-compose" else RUNTIME="podman" COMPOSE="podman compose" fi fi if [ -z "$RUNTIME" ]; then echo "" echo "No working container runtime detected." echo "" if command -v podman &>/dev/null; then echo "Podman is installed but the machine isn't running:" echo " podman machine start" elif command -v docker &>/dev/null; then echo "Docker is installed but the daemon isn't running." echo "Start Docker Desktop and try again." else echo "Install Docker Desktop or Podman:" echo " brew install --cask docker" echo " # or" echo " brew install podman podman-compose" echo " podman machine init && podman machine start" fi echo "" exit 1 fi echo " Using: $RUNTIME" cd "$PROJECT_ROOT" echo " Starting signet Bitcoin + LND + ThunderHub + Fedimint..." $COMPOSE -f docker-compose.testnet.yml up -d echo "" echo " Testnet stack starting. Services:" echo " ThunderHub: http://localhost:3010 (password: thunderhub)" echo " Fedimint Guardian: http://localhost:18175" echo " LND REST: http://localhost:8080" echo " Bitcoin RPC: localhost:38332" echo "" echo " Get signet coins: https://signetfaucet.com" echo "" echo " Also starting mock frontend..." cleanup_ports ensure_deps exec npm run dev:mock ;; 8) echo "" echo "Manual Instructions" echo "" echo "UI development (mock backend, no Docker):" echo " cd $FRONTEND_DIR" echo " npm install && npm run dev:mock" echo "" echo "Dev modes (prepend to command):" echo " VITE_DEV_MODE=setup First-time setup flow" echo " VITE_DEV_MODE=onboarding Onboarding flow" echo " VITE_DEV_MODE=existing Login screen" echo " VITE_DEV_MODE=boot Boot sequence" echo "" echo "Testnet stack (requires Podman or Docker):" echo " podman compose -f docker-compose.testnet.yml up -d" echo "" echo "Full stack (requires Rust toolchain):" echo " Terminal 1: cd $BACKEND_DIR && cargo run --bin archipelago" echo " Terminal 2: cd $FRONTEND_DIR && npm run dev" echo "" echo "Access: http://localhost:8100 (password: password123)" ;; *) echo "Invalid choice" exit 1 ;; esac