102 lines
3.9 KiB
Bash
102 lines
3.9 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# =============================================================================
|
||
|
|
# Timmy node — start all services
|
||
|
|
# Safe to run multiple times; won't double-start a running service.
|
||
|
|
# =============================================================================
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
SECRETS_FILE="$SCRIPT_DIR/.node-secrets"
|
||
|
|
LND_DIR="$HOME/.lnd"
|
||
|
|
LOG_DIR="$HOME/Library/Logs/timmy-node"
|
||
|
|
LAUNCHD_DIR="$HOME/Library/LaunchAgents"
|
||
|
|
LNCLI="/opt/homebrew/bin/lncli"
|
||
|
|
|
||
|
|
[[ -f "$SECRETS_FILE" ]] && source "$SECRETS_FILE"
|
||
|
|
mkdir -p "$LOG_DIR"
|
||
|
|
|
||
|
|
GREEN='\033[0;32m'; CYAN='\033[0;36m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||
|
|
info() { echo -e "${CYAN}[start]${NC} $*"; }
|
||
|
|
ok() { echo -e "${GREEN}[ok]${NC} $*"; }
|
||
|
|
warn() { echo -e "${YELLOW}[warn]${NC} $*"; }
|
||
|
|
|
||
|
|
start_launchagent() {
|
||
|
|
local label="$1"
|
||
|
|
local plist="$LAUNCHD_DIR/$label.plist"
|
||
|
|
if ! launchctl list | grep -q "$label"; then
|
||
|
|
launchctl load -w "$plist" 2>/dev/null && ok "$label started." || warn "Could not load $label."
|
||
|
|
else
|
||
|
|
ok "$label is already loaded."
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# ─── Bitcoin Core ─────────────────────────────────────────────────────────────
|
||
|
|
info "Starting Bitcoin Core…"
|
||
|
|
start_launchagent "com.timmy.bitcoind"
|
||
|
|
|
||
|
|
# Wait for RPC to be ready (up to 60s)
|
||
|
|
info "Waiting for bitcoind RPC (up to 60s)…"
|
||
|
|
BTC_ARGS=()
|
||
|
|
[[ -n "${RPC_USER:-}" ]] && BTC_ARGS+=(-rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS")
|
||
|
|
for i in $(seq 1 12); do
|
||
|
|
if /opt/homebrew/bin/bitcoin-cli "${BTC_ARGS[@]}" getblockchaininfo &>/dev/null 2>&1; then
|
||
|
|
ok "bitcoind RPC ready."
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
[[ $i -eq 12 ]] && warn "bitcoind RPC not ready after 60s — it may still be starting." || sleep 5
|
||
|
|
done
|
||
|
|
|
||
|
|
# ─── LND ──────────────────────────────────────────────────────────────────────
|
||
|
|
info "Starting LND…"
|
||
|
|
start_launchagent "com.timmy.lnd"
|
||
|
|
|
||
|
|
# Wait for LND to be ready (up to 60s)
|
||
|
|
info "Waiting for LND (up to 60s)…"
|
||
|
|
for i in $(seq 1 12); do
|
||
|
|
LND_STATE=$("$LNCLI" --lnddir="$LND_DIR" state 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('state','?'))" 2>/dev/null || echo "?")
|
||
|
|
case "$LND_STATE" in
|
||
|
|
RPC_ACTIVE|SERVER_ACTIVE)
|
||
|
|
ok "LND is up (state: $LND_STATE)."
|
||
|
|
break
|
||
|
|
;;
|
||
|
|
WALLET_NOT_CREATED)
|
||
|
|
warn "LND wallet needs to be created:"
|
||
|
|
echo " lncli --lnddir=$LND_DIR create"
|
||
|
|
echo " Use password from $SECRETS_FILE"
|
||
|
|
break
|
||
|
|
;;
|
||
|
|
LOCKED)
|
||
|
|
info "LND wallet is locked — unlocking…"
|
||
|
|
if [[ -f "$LND_DIR/.wallet-password" ]]; then
|
||
|
|
"$LNCLI" --lnddir="$LND_DIR" unlock --stdin < "$LND_DIR/.wallet-password" 2>/dev/null && ok "Wallet unlocked." || warn "Auto-unlock failed — run: lncli --lnddir=$LND_DIR unlock"
|
||
|
|
else
|
||
|
|
warn "No wallet-password file found. Run: lncli --lnddir=$LND_DIR unlock"
|
||
|
|
fi
|
||
|
|
break
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
[[ $i -eq 12 ]] && warn "LND not ready after 60s (state: $LND_STATE)" || sleep 5
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
|
||
|
|
# ─── LNbits ───────────────────────────────────────────────────────────────────
|
||
|
|
info "Starting LNbits…"
|
||
|
|
start_launchagent "com.timmy.lnbits"
|
||
|
|
|
||
|
|
info "Waiting for LNbits HTTP (up to 30s)…"
|
||
|
|
for i in $(seq 1 6); do
|
||
|
|
if curl -sf "http://127.0.0.1:5000/api/v1/health" &>/dev/null; then
|
||
|
|
ok "LNbits is up at http://127.0.0.1:5000"
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
[[ $i -eq 6 ]] && warn "LNbits not responding after 30s — check $LOG_DIR/lnbits.err" || sleep 5
|
||
|
|
done
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
ok "All services started. Run 'bash $SCRIPT_DIR/status.sh' for a full health check."
|
||
|
|
echo ""
|
||
|
|
echo " To expose LNbits to Replit, run:"
|
||
|
|
echo " bash $SCRIPT_DIR/expose.sh"
|
||
|
|
echo ""
|