Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions app/backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ def get_cloudflare_config():

DNS_RESOLVER_LIFETIME = float(os.environ.get("DNS_RESOLVER_LIFETIME", "10"))
DNS_RESOLVER_TIMEOUT = float(os.environ.get("DNS_RESOLVER_TIMEOUT", "10"))
DNS_RESOLVER_NAMESERVERS = [
server
for server in os.environ.get("DNS_RESOLVER_NAMESERVERS", "").replace(",", " ").split()
if server
]

# BIP353 lookup outcomes that should fall through to the LNURL path in pay_address:
# no record (404), lookup failed (502), lookup timed out (504).
BIP353_LNURL_FALLBACK_STATUSES = frozenset({404, 502, 504})

LNURL_MIN_SENDABLE_MSAT = int(os.environ.get("LNURL_MIN_SENDABLE_MSAT", "1000"))
LNURL_MAX_SENDABLE_MSAT = int(os.environ.get("LNURL_MAX_SENDABLE_MSAT", "1000000000"))
Expand Down Expand Up @@ -1376,8 +1385,11 @@ def _extract_offer_from_txt_record(txt_value: str) -> Optional[str]:


def _new_resolver() -> dns.resolver.Resolver:
# Default to the host's own resolver (/etc/resolv.conf). Some runtimes only
# permit DNS via the resolver they configure, so pinning one here fails there.
resolver = dns.resolver.Resolver()
resolver.nameservers = ["1.1.1.1", "8.8.8.8"]
if DNS_RESOLVER_NAMESERVERS:
resolver.nameservers = DNS_RESOLVER_NAMESERVERS
resolver.lifetime = DNS_RESOLVER_LIFETIME
resolver.timeout = DNS_RESOLVER_TIMEOUT
return resolver
Expand Down Expand Up @@ -2836,9 +2848,11 @@ async def pay_address(payload: PayAddressRequest, request: StarletteRequest) ->
return PayOfferResponse(resolved_offer=normalized_offer, raw_output=raw_output)

except HTTPException as exc:
message = str(exc.detail)

if "No BIP353 TXT record found" not in message:
# A Lightning Address is indistinguishable from a BIP353 address here, so
# fall through to LNURL whenever the offer lookup found nothing to pay --
# whether the record was absent (404) or the lookup never completed
# (502/504). Anything else is the caller's error and still propagates.
if exc.status_code not in BIP353_LNURL_FALLBACK_STATUSES:
raise

lnurl_result = await _resolve_lnurl_invoice(
Expand Down
3 changes: 3 additions & 0 deletions app/docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ services:
CONFIG_JSON_PATH: /data/config.json
SECRETS_JSON_PATH: /data/config/secrets.json
CORS_ORIGINS: "*"
# Optional. BIP353 lookups use the container's own resolver (the `dns:`
# entries below). Set this to override it with an explicit list instead.
# DNS_RESOLVER_NAMESERVERS: "1.1.1.1 8.8.8.8"
dns:
- 1.1.1.1
- 8.8.8.8
Expand Down
Loading