Files
alexpaynex ca94c0a9e5 Add Bitcoin/LND/LNbits local node setup scripts and node diagnostics endpoint
- scripts/bitcoin-ln-node/setup.sh: one-shot installer for Bitcoin Core (pruned mainnet), LND, and LNbits on Apple Silicon Mac. Generates secrets, writes configs, installs launchd plists for auto-start.
- scripts/bitcoin-ln-node/start.sh: start all services via launchctl; waits for RPC readiness and auto-unlocks LND wallet.
- scripts/bitcoin-ln-node/stop.sh: graceful shutdown (lncli stop → bitcoin-cli stop).
- scripts/bitcoin-ln-node/status.sh: full health check (Bitcoin sync %, LND channels/balance, LNbits HTTP, bore tunnel). Supports --json mode for machine consumption.
- scripts/bitcoin-ln-node/expose.sh: opens bore tunnel from LNbits port 5000 to bore.pub for Replit access.
- scripts/bitcoin-ln-node/get-lnbits-key.sh: fetches LNbits admin API key and prints Replit secret values.
- artifacts/api-server/src/routes/node-diagnostics.ts: GET /api/admin/node-status (JSON) and /api/admin/node-status/html — Timmy self-diagnoses its LNbits/LND connectivity and reports issues.
2026-03-18 21:58:41 +00:00

98 lines
4.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# =============================================================================
# Timmy node — expose LNbits to Replit via bore tunnel
# Run this after LNbits is up. Keep this terminal open.
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LNBITS_LOCAL="http://127.0.0.1:5000"
GREEN='\033[0;32m'; CYAN='\033[0;36m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info() { echo -e "${CYAN}[expose]${NC} $*"; }
ok() { echo -e "${GREEN}[ok]${NC} $*"; }
warn() { echo -e "${YELLOW}[warn]${NC} $*"; }
die() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; }
# ─── Ensure LNbits is up ──────────────────────────────────────────────────────
info "Checking LNbits is reachable locally…"
if ! curl -sf "$LNBITS_LOCAL/api/v1/health" &>/dev/null; then
warn "LNbits not responding at $LNBITS_LOCAL"
warn "Waiting up to 30s…"
for i in $(seq 1 6); do
sleep 5
curl -sf "$LNBITS_LOCAL/api/v1/health" &>/dev/null && break
[[ $i -eq 6 ]] && die "LNbits still not up. Run 'bash $SCRIPT_DIR/start.sh' first."
done
fi
ok "LNbits is running locally."
# ─── Ensure bore is installed ─────────────────────────────────────────────────
if ! command -v bore &>/dev/null; then
info "Installing bore (tunnel tool)…"
if command -v cargo &>/dev/null; then
cargo install bore-cli
elif command -v brew &>/dev/null; then
brew install bore-cli 2>/dev/null || {
warn "bore not in Homebrew — installing via cargo…"
brew install rust 2>/dev/null && cargo install bore-cli
}
else
die "Neither cargo nor brew found. Install bore manually: https://github.com/ekzhang/bore"
fi
fi
# Kill any existing bore tunnel on port 5000
if EXISTING=$(pgrep -f "bore local.*5000" 2>/dev/null); then
info "Killing existing bore tunnel (PID $EXISTING)…"
kill "$EXISTING" 2>/dev/null || true
sleep 1
fi
# ─── Start bore ──────────────────────────────────────────────────────────────
info "Opening bore tunnel: local:5000 → bore.pub…"
echo ""
# bore prints the public address on startup — capture it
BORE_OUT=$(mktemp)
bore local 5000 --to bore.pub 2>&1 &
BORE_PID=$!
sleep 3
# Extract the assigned port from bore output
if BORE_LINE=$(bore local 5000 --to bore.pub --help 2>&1 | head -1); then true; fi
# Check if bore is still running
if ! kill -0 $BORE_PID 2>/dev/null; then
die "bore exited immediately. Check your internet connection."
fi
# bore prints: "listening at bore.pub:PORT"
# We need to find what port was assigned
BORE_PORT=$(ps aux | grep "bore local 5000" | grep -v grep | grep -oE '\-\-port [0-9]+' | awk '{print $2}' || true)
if [[ -z "$BORE_PORT" ]]; then
# Fallback: tail the bore process log
sleep 2
BORE_PORT=$(bore local 5000 --to bore.pub 2>&1 & sleep 3; pkill -f "bore local" 2>/dev/null || true)
fi
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN} Bore tunnel is LIVE (PID: $BORE_PID)${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo " LNbits is now reachable from Replit."
echo ""
echo " Set these secrets in Replit:"
echo " ┌──────────────────────────────────────────────────┐"
echo " │ LNBITS_URL = http://bore.pub:<PORT> │"
echo " │ LNBITS_API_KEY = <your-lnbits-admin-key> │"
echo " └──────────────────────────────────────────────────┘"
echo ""
echo " Get your API key: bash $SCRIPT_DIR/get-lnbits-key.sh"
echo ""
echo " Keep this terminal open. Ctrl+C to stop the tunnel."
echo ""
# Wait for bore to exit
wait $BORE_PID