diff --git a/scripts/container-doctor.sh b/scripts/container-doctor.sh index e16795af..dc5dd35a 100755 --- a/scripts/container-doctor.sh +++ b/scripts/container-doctor.sh @@ -16,6 +16,8 @@ # 7. Containers stuck with exit code 127 (binary not found) # 8. Stopped core containers (rootless restart policy workaround) # 9. Missing rootless port listeners while Podman still shows published ports +# 10. Nginx Proxy Manager public hosts not mirrored into host nginx +# 11. BTCPay stores producing unpayable Lightning invoices (route hints off) # # Safe to run multiple times (idempotent). Never blocks deploy (exit 0 always). # @@ -566,6 +568,32 @@ fix_npm_public_hosts() { return 1 } +# ── Fix 12: BTCPay Lightning route hints ───────────────────── +# A BTCPay store whose LND node has only private (unannounced) channels +# produces BOLT11 invoices that external wallets cannot route to unless the +# store's lightningPrivateRouteHints flag is on — payers see "no way to pay +# this invoice" (observed on shorty-s 2026-07-10 with a Blink payer). Route +# hints are a no-op with public channels and essential with private ones, so +# the doctor enforces the flag on every store. BTCPay reads store blobs from +# Postgres per request; no restart needed. +fix_btcpay_route_hints() { + local state + state=$(podman_rootless inspect archy-btcpay-db --format '{{.State.Status}}' 2>/dev/null || echo "missing") + [ "$state" = "running" ] || return 1 + + local count + count=$(podman_rootless exec archy-btcpay-db psql -U btcpay -d btcpay -t -A -c \ + "SELECT count(*) FROM \"Stores\" WHERE (\"StoreBlob\"->>'lightningPrivateRouteHints') = 'false';" 2>/dev/null) + [ -n "$count" ] && [ "$count" -gt 0 ] 2>/dev/null || return 1 + + if podman_rootless exec archy-btcpay-db psql -U btcpay -d btcpay -q -c \ + "UPDATE \"Stores\" SET \"StoreBlob\" = jsonb_set(\"StoreBlob\", '{lightningPrivateRouteHints}', 'true'::jsonb) WHERE (\"StoreBlob\"->>'lightningPrivateRouteHints') = 'false';" >/dev/null 2>&1; then + log "Enabled Lightning route hints on $count BTCPay store(s) (private-channel invoices were unpayable)" + return 0 + fi + return 1 +} + # ── Main ───────────────────────────────────────────────────── # If remote host provided, run via SSH @@ -596,6 +624,7 @@ run_fix "netns-egress" fix_rootless_netns_egress run_fix "stopped-core" fix_stopped_core_containers run_fix "rootless-ports" fix_missing_rootless_ports run_fix "npm-public-hosts" fix_npm_public_hosts +run_fix "btcpay-route-hints" fix_btcpay_route_hints echo "" if [ $FIXES_APPLIED -gt 0 ]; then