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.
This commit is contained in:
97
scripts/bitcoin-ln-node/expose.sh
Executable file
97
scripts/bitcoin-ln-node/expose.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user