aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-02 08:30:09 -0700
committerAdam Soltys <[email protected]>2026-08-02 08:30:09 -0700
commit239f1fd498b4511d8c6a1f4ae4c8cc3b5aeb7b5f (patch)
tree3fa3dc694e56d4243c259f9da0dcc5686a1e06a5
parentb524be4331cbcb6ff68c27894b6e8143b556b85f (diff)
downloadcoinos-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.ts22
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([