From d466aab4451a89b2d69a2618f0a739b2e89903c5 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 10 Jul 2026 21:46:40 -0700 Subject: invoices: sell merchant-supplied preimages via a usePreimage queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merchants POST /preimages (auth) to pre-load 32-byte hex preimages into a FIFO queue; creating an invoice with usePreimage: true consumes the next one so the invoice's payment hash is sha256(preimage). Paying the invoice reveals the merchant-chosen secret to the buyer — via their own wallet on external settlements, and via GET /invoice/:id once settled — enabling backend-less digital download stores (encrypted files on static hosting, preimage + public string = decryption key). - GET /preimages lists the queue with payment hashes so the merchant can map files to future invoices; POST /preimages/delete clears it - empty queue fails invoice creation rather than issuing a random preimage the buyer would pay for but couldn't decrypt with - preimages cln rejects as already used are discarded and the next tried - consumed preimages persist at preimage:${payment_hash} (TTL = invoice expiry) and credit() prefers them as the settlement ref, so internal coinos-to-coinos payments reveal the real preimage instead of the sender's uid Co-Authored-By: Claude Fable 5 --- index.ts | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'index.ts') diff --git a/index.ts b/index.ts index 0a3bfd89..3a123e9e 100644 --- a/index.ts +++ b/index.ts @@ -18,6 +18,7 @@ import lnurl from "$routes/lnurl"; import locations from "$routes/locations"; import nostr from "$routes/nostr"; import payments from "$routes/payments"; +import preimages from "$routes/preimages"; import rates from "$routes/rates"; import shopify from "$routes/shopify"; import square from "$routes/square"; @@ -52,6 +53,10 @@ app.post("/invoice", optional, invoices.create); app.post("/invoice/:id", optional, invoices.update); app.post("/sign", auth, invoices.sign); +app.get("/preimages", auth, preimages.list); +app.post("/preimages", auth, preimages.add); +app.post("/preimages/delete", auth, preimages.clear); + app.get("/assetlinks.json", (_, res) => res.sendFile("assetlinks.json")); app.get("/nostr.json", nostr.identities); app.get("/profile/:profile", nostr.profile); -- cgit v1.2.3