From d5395a81e5475af3a41c2715f58cab6b487a5795 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 17 May 2026 23:49:22 -0700 Subject: fix lnurl description_hash mismatch when sender provides a comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bolt11 description_hash is computed from the metadata JSON, which was being constructed with the sender's `comment` substituted into text/plain. Wallets verify description_hash against the metadata they received in the lnurl-pay response, so injecting the comment into the hash made the verification fail — the invoice would settle but description_hash verification would reject it as inconsistent. Keep metadata canonical ("Paying user@host") so the description_hash the wallet receives matches what they verify against. The comment is still preserved as the human-readable memo on the invoice record. Co-Authored-By: Claude Opus 4.7 (1M context) --- routes/lnurl.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/routes/lnurl.ts b/routes/lnurl.ts index f4357ff2..6b4e5deb 100644 --- a/routes/lnurl.ts +++ b/routes/lnurl.ts @@ -97,9 +97,8 @@ export default { let { username } = user; username = username.replace(/\s/g, "").toLowerCase(); - const memo = comment ?? `Paying ${username}@${host}`; let metadata = JSON.stringify([ - ["text/plain", memo], + ["text/plain", `Paying ${username}@${host}`], ["text/identifier", `${username}@${host}`], ]); @@ -124,6 +123,11 @@ export default { user, }); + if (comment) { + invoice.memo = comment; + await s(`invoice:${invoice.id}`, invoice); + } + return c.json({ pr: invoice.text, routes: [], -- cgit v1.2.3