Tracks Gitea issue token-gated-economy #19. ## Problem LNbits 0.12 (released late 2024) removed the superuser wallet creation API (POST /api/v1/wallet with X-Api-Key: <superuser-id>). The existing script would silently fall through to generic manual instructions with no explanation, leaving operators confused. ## Changes to scripts/bitcoin-ln-node/get-lnbits-key.sh 1. **Version detection** — calls GET /api/v1/health and parses `server_version` from the JSON response via python3. Version is printed at the start. If the endpoint is unreachable the script dies with a clear message. If the version field is absent (unexpected future change) it defaults to "0.12.0" (modern path) with a warning. 2. **Version-branched flow** - >= 0.12: skips superuser API entirely; prints a numbered 5-step walk-through to the Admin UI at /admin, then always prints the export template. - < 0.12: runs the existing superuser detection (env file → secrets file → lnbits.log grep) and wallet creation API. Falls back to manual instructions on failure, same as before. 3. **SQLite fallback removed** — the `sqlite3 "$DB_FILE" "SELECT id FROM accounts WHERE is_super_user=1"` block targeted the wrong schema on 0.12+ and is redundant given the version branch. Deleted entirely. 4. **Export template always printed** — `print_export_template()` helper is called in every exit path (both version branches, all fallbacks). Template always shows: export LNBITS_URL="http://bore.pub:<PORT>" export LNBITS_API_KEY="..." ## Verified - bash -n: syntax OK - version_gte() passes all edge cases (0.12.0 == 0.12.0, 0.12.3 > 0.12.0, 1.0.0 > 0.12.0, 0.11.9 < 0.12.0, 0.9.0 < 0.12.0) - >= 0.12 output path confirmed via bash simulation - sqlite3/SQLite strings absent from final file - Script exits 0 in all manual-instruction paths (not an error) ## No changes to setup.sh (out of scope per task spec)
177 lines
7.0 KiB
Bash
Executable File
177 lines
7.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Timmy node — fetch LNbits admin API key
|
|
#
|
|
# Run this after LNbits is up and your LND wallet is initialised.
|
|
# Prints LNBITS_URL and LNBITS_API_KEY to paste into Replit secrets.
|
|
#
|
|
# Compatibility:
|
|
# LNbits < 0.12 — auto-creates a wallet via superuser API
|
|
# LNbits >= 0.12 — superuser API removed; walks you through the Admin UI
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
LNBITS_LOCAL="http://127.0.0.1:5000"
|
|
LNBITS_DATA_DIR="$HOME/.lnbits-data"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
SECRETS_FILE="$SCRIPT_DIR/.node-secrets"
|
|
|
|
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; }
|
|
|
|
# ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
|
|
# Return 0 (true) if $1 >= $2 (semantic version comparison)
|
|
version_gte() { printf '%s\n%s\n' "$2" "$1" | sort -V -C; }
|
|
|
|
# Print the export template the operator needs to paste into Replit Secrets
|
|
print_export_template() {
|
|
local api_key="${1:-<paste-admin-key-here>}"
|
|
echo ""
|
|
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${GREEN} Paste these into Replit Secrets:${NC}"
|
|
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo ""
|
|
echo " export LNBITS_URL=\"http://bore.pub:<PORT>\" ← bore port from expose.sh"
|
|
echo " export LNBITS_API_KEY=\"${api_key}\""
|
|
echo ""
|
|
}
|
|
|
|
# ─── Step 1: Confirm LNbits is reachable ─────────────────────────────────────
|
|
|
|
info "Checking LNbits at $LNBITS_LOCAL …"
|
|
HEALTH_JSON="$(curl -sf --max-time 6 "$LNBITS_LOCAL/api/v1/health" 2>/dev/null)" \
|
|
|| die "LNbits is not reachable at $LNBITS_LOCAL. Start it first:
|
|
bash $(dirname "$SCRIPT_DIR")/start.sh (or your launch script)"
|
|
|
|
# ─── Step 2: Detect LNbits version ───────────────────────────────────────────
|
|
|
|
LNBITS_VERSION=""
|
|
if command -v python3 &>/dev/null; then
|
|
LNBITS_VERSION="$(echo "$HEALTH_JSON" \
|
|
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('server_version',''))" \
|
|
2>/dev/null || true)"
|
|
fi
|
|
|
|
if [[ -z "$LNBITS_VERSION" ]]; then
|
|
warn "Could not parse server_version from health endpoint — assuming modern LNbits (>= 0.12)."
|
|
LNBITS_VERSION="0.12.0"
|
|
fi
|
|
|
|
info "LNbits version: ${LNBITS_VERSION}"
|
|
|
|
# ─── Step 3: Version-branched key retrieval ───────────────────────────────────
|
|
|
|
if version_gte "$LNBITS_VERSION" "0.12.0"; then
|
|
# ── LNbits >= 0.12 ─────────────────────────────────────────────────────────
|
|
# The superuser wallet API (POST /api/v1/wallet with X-Api-Key: <superuser>)
|
|
# was removed in 0.12. Use the Admin UI instead.
|
|
|
|
echo ""
|
|
warn "LNbits ${LNBITS_VERSION} — superuser API removed. Use the Admin UI:"
|
|
echo ""
|
|
echo " 1. Open the LNbits Admin UI in your browser:"
|
|
echo " ${LNBITS_LOCAL}/admin"
|
|
echo ""
|
|
echo " 2. In the Admin UI sidebar, click Users → Create User"
|
|
echo " Name: Timmy"
|
|
echo " This creates a new user with a default wallet."
|
|
echo ""
|
|
echo " 3. Click on the Timmy user → open their wallet."
|
|
echo ""
|
|
echo " 4. In the wallet page, click the key icon (API Info)."
|
|
echo " Copy the Admin key (not the Invoice key)."
|
|
echo ""
|
|
echo " 5. Paste the Admin key into Replit Secrets as LNBITS_API_KEY."
|
|
echo ""
|
|
print_export_template
|
|
|
|
else
|
|
# ── LNbits < 0.12 ──────────────────────────────────────────────────────────
|
|
# Superuser API available — try to auto-create a Timmy wallet.
|
|
|
|
info "LNbits ${LNBITS_VERSION} — attempting automatic wallet creation…"
|
|
|
|
# Locate the super user ID (env file or secrets 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
|
|
|
|
[[ -f "$SECRETS_FILE" ]] && source "$SECRETS_FILE"
|
|
SUPER_USER="${SUPER_USER:-${LNBITS_SUPER_USER:-}}"
|
|
|
|
if [[ -z "$SUPER_USER" ]]; then
|
|
# Last resort: grep the startup 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 locate LNbits super user ID automatically."
|
|
echo ""
|
|
echo " Visit ${LNBITS_LOCAL} and:"
|
|
echo " 1. Create a wallet"
|
|
echo " 2. Go to Wallet → API Info"
|
|
echo " 3. Copy the Admin key"
|
|
echo ""
|
|
print_export_template
|
|
exit 0
|
|
fi
|
|
|
|
info "Super user ID: ${SUPER_USER}"
|
|
|
|
# Create the Timmy wallet 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 " Invoice key (read-only): ${INKEY}"
|
|
|
|
# Append to secrets file so future runs can skip this step
|
|
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}"
|
|
print_export_template "$ADMIN_KEY"
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# Wallet API call failed even though super user was found
|
|
warn "Wallet creation API call failed."
|
|
echo ""
|
|
echo " Visit ${LNBITS_LOCAL} and:"
|
|
echo " 1. Create a wallet named 'Timmy'"
|
|
echo " 2. Wallet → API Info → copy Admin key"
|
|
echo ""
|
|
print_export_template
|
|
|
|
fi
|
|
|
|
exit 0
|