diff options
| author | Adam Soltys <[email protected]> | 2026-08-02 08:30:09 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-02 08:30:09 -0700 |
| commit | 239f1fd498b4511d8c6a1f4ae4c8cc3b5aeb7b5f (patch) | |
| tree | 3fa3dc694e56d4243c259f9da0dcc5686a1e06a5 | |
| parent | b524be4331cbcb6ff68c27894b6e8143b556b85f (diff) | |
| download | coinos-server-239f1fd498b4511d8c6a1f4ae4c8cc3b5aeb7b5f.tar.gz coinos-server-239f1fd498b4511d8c6a1f4ae4c8cc3b5aeb7b5f.zip | |
LNURL: fall back to the v3 names registrar for unknown users
An address at this domain may now belong to a coinos v3 wallet rather
than a local account. When the username isn't ours, ask the names
registrar and pass its payRequest through unchanged — its callback is
absolute, so the payer talks to it directly from there.
Co-Authored-By: Claude Fable 5 <[email protected]>
| -rw-r--r-- | routes/lnurl.ts | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/routes/lnurl.ts b/routes/lnurl.ts index c96a9160..ab9b64f1 100644 --- a/routes/lnurl.ts +++ b/routes/lnurl.ts @@ -13,6 +13,8 @@ import { PaymentType } from "$lib/types"; const { URL } = process.env; const host = URL.split("/").at(-1); const fiveMinutes = 1000 * 60 * 5; +// v3 payment addresses (coinos v3 / halwallet) are registered here. +const NAMES_URL = process.env.NAMES_URL || "https://names.coinos.io"; export default { async encode(req, res) { @@ -67,7 +69,25 @@ export default { .toLowerCase(), ); - if (!user) fail(`User ${username} not found`); + // Not one of ours? It may be a v3 payment address, which lives at this + // same domain but is served by the names registrar. Hand its response + // through unchanged — the callback it returns is absolute, so the payer + // talks to the registrar directly from here on. + if (!user) { + const name = username.toLowerCase().replace(/\s/g, ""); + try { + const r = await fetch( + `${NAMES_URL}/.well-known/lnurlp/${encodeURIComponent(name)}?domain=${host}`, + ); + if (r.ok) { + const body: any = await r.json(); + if (body?.tag === "payRequest") return res.send(body); + } + } catch (e) { + warn("names lookup failed for", name, (e as any).message); + } + fail(`User ${username} not found`); + } const { id: uid } = user; const metadata = JSON.stringify([ |
