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:
106
scripts/bitcoin-ln-node/get-lnbits-key.sh
Executable file
106
scripts/bitcoin-ln-node/get-lnbits-key.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# Timmy node — fetch LNbits admin API key
|
||||
# Run this after LNbits is up and has been configured.
|
||||
# Prints the LNBITS_API_KEY to add to Replit secrets.
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
LNBITS_LOCAL="http://127.0.0.1:5000"
|
||||
LNBITS_DATA_DIR="$HOME/.lnbits-data"
|
||||
|
||||
GREEN='\033[0;32m'; CYAN='\033[0;36m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
info() { echo -e "${CYAN}[keys]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[ok]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[warn]${NC} $*"; }
|
||||
die() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; }
|
||||
|
||||
# Check LNbits is up
|
||||
curl -sf "$LNBITS_LOCAL/api/v1/health" &>/dev/null \
|
||||
|| die "LNbits not reachable at $LNBITS_LOCAL. Run 'bash start.sh' first."
|
||||
|
||||
# ─── Try to get super user from env file ─────────────────────────────────────
|
||||
SUPER_USER=""
|
||||
if [[ -f "$LNBITS_DATA_DIR/.env" ]]; then
|
||||
SUPER_USER=$(grep LNBITS_SUPER_USER "$LNBITS_DATA_DIR/.env" | cut -d= -f2 | tr -d '"' || true)
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SECRETS_FILE="$SCRIPT_DIR/.node-secrets"
|
||||
[[ -f "$SECRETS_FILE" ]] && source "$SECRETS_FILE"
|
||||
SUPER_USER="${SUPER_USER:-${LNBITS_SUPER_USER:-}}"
|
||||
|
||||
if [[ -z "$SUPER_USER" ]]; then
|
||||
# LNbits auto-generates a superuser on first run — find it in the SQLite DB
|
||||
DB_FILE=$(find "$LNBITS_DATA_DIR" -name "*.sqlite3" 2>/dev/null | head -1 || true)
|
||||
if [[ -n "$DB_FILE" ]] && command -v sqlite3 &>/dev/null; then
|
||||
SUPER_USER=$(sqlite3 "$DB_FILE" "SELECT id FROM accounts WHERE is_super_user=1 LIMIT 1;" 2>/dev/null || true)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$SUPER_USER" ]]; then
|
||||
# Last resort: check LNbits log for the first-run superuser line
|
||||
LOG_FILE="$HOME/Library/Logs/timmy-node/lnbits.log"
|
||||
if [[ -f "$LOG_FILE" ]]; then
|
||||
SUPER_USER=$(grep -oE "super user id: [a-f0-9]+" "$LOG_FILE" | tail -1 | awk '{print $4}' || true)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$SUPER_USER" ]]; then
|
||||
warn "Could not auto-detect LNbits super user ID."
|
||||
echo ""
|
||||
echo " Visit: $LNBITS_LOCAL"
|
||||
echo " 1. Create a wallet"
|
||||
echo " 2. Go to Wallet → API Info"
|
||||
echo " 3. Copy the Admin key"
|
||||
echo ""
|
||||
echo " Then add to Replit:"
|
||||
echo " LNBITS_URL = http://bore.pub:<PORT>"
|
||||
echo " LNBITS_API_KEY = <admin-key>"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
info "Super user: $SUPER_USER"
|
||||
|
||||
# Create a wallet for Timmy via superuser API
|
||||
WALLET_RESPONSE=$(curl -sf -X POST "$LNBITS_LOCAL/api/v1/wallet" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $SUPER_USER" \
|
||||
-d '{"name":"Timmy"}' 2>/dev/null || true)
|
||||
|
||||
if [[ -n "$WALLET_RESPONSE" ]]; then
|
||||
ADMIN_KEY=$(echo "$WALLET_RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('adminkey',''))" 2>/dev/null || true)
|
||||
INKEY=$(echo "$WALLET_RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('inkey',''))" 2>/dev/null || true)
|
||||
WALLET_ID=$(echo "$WALLET_RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true)
|
||||
|
||||
if [[ -n "$ADMIN_KEY" ]]; then
|
||||
ok "Timmy wallet created (ID: $WALLET_ID)"
|
||||
echo ""
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN} Add these to Replit secrets:${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo " LNBITS_URL = http://bore.pub:<PORT> ← from expose.sh"
|
||||
echo " LNBITS_API_KEY = $ADMIN_KEY"
|
||||
echo ""
|
||||
echo " Invoice key (read-only): $INKEY"
|
||||
echo ""
|
||||
# Save to secrets file
|
||||
cat >> "$SECRETS_FILE" <<EOF
|
||||
LNBITS_WALLET_ID="$WALLET_ID"
|
||||
LNBITS_ADMIN_KEY="$ADMIN_KEY"
|
||||
LNBITS_INVOICE_KEY="$INKEY"
|
||||
EOF
|
||||
ok "Keys saved to $SECRETS_FILE"
|
||||
return 0 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fallback: just print the wallet URL
|
||||
warn "Could not create wallet automatically."
|
||||
echo ""
|
||||
echo " Visit $LNBITS_LOCAL in your browser:"
|
||||
echo " 1. Create an account / wallet named 'Timmy'"
|
||||
echo " 2. Wallet → API Info → copy Admin key"
|
||||
echo " 3. Add to Replit: LNBITS_API_KEY = <admin key>"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user