aboutsummaryrefslogtreecommitdiffstats
path: root/routes/lnurl.ts
Commit message (Collapse)AuthorAgeFilesLines
* Evicted accounts can't receive or log in; limit errors say what's happeningAdam Soltys11 days1-2/+6
| | | | | | | | | | | An evicted account no longer gets lightning-address invoices (stops a scam page's address from minting new ones) or a login token. A send over the server limit now says withdrawals are temporarily limited instead of a generic "Problem sending payment" that read as a frozen account. (Already live since the 2026-10-01 restart.) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
* lnurl: budget unauthenticated invoice generation per recipientAdam Soltys2026-09-291-5/+34
| | | | | | | | | | | | | GET /pay/:user/:amount and the lnurl callback create a CLN invoice and an entry in the recipient's invoice list for anyone holding the link, which a scanner on rotating IPs can do without tripping per-IP limits. Cap fresh invoices at 120 per recipient per hour (reused invoices don't count). Also fail cleanly for unknown usernames and skip invoice ids whose records no longer exist, instead of throwing on the null and breaking the pay page. Throttle the resulting lnurlp warnings per username. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* lnurl: expire payRequest callback ids after seven daysAdam Soltys2026-09-161-3/+8
| | | | | | | | | A callback id is read once, minutes after the metadata request, and never again, but the pointer keys were written without an expiry and had grown to roughly 45% of all keys in the main database. Let the set helper take a TTL and apply one to both lnurl pointer keys. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* payments: never lose a settled deposit to an oversized memo (S9/S10)Adam Soltys2026-08-071-1/+4
| | | | | | | | | | | | | | credit() ran fail("memo too long") on memos >5000 chars, but it runs AFTER settlement: an incoming lightning/bolt12 deposit has already advanced pay_index, and an internal send has already debited the sender. The throw was only logged, replay() hit the same throw, and the sats sat in the house wallet uncredited. The memo is attacker-controllable and was uncapped via the lnurl comment param and the bolt12 payer_note. Truncate the memo in credit() instead of throwing (a clipped note is harmless), and cap the lnurl comment to the advertised 512 at ingress. Co-Authored-By: Claude Opus 4.8 <[email protected]>
* lnurl: defer to the v3 registrar for names it has claimedAdam Soltys2026-08-041-15/+53
| | | | | | | | | | | | | | Serving local accounts unconditionally sent migrated names (whose legacy user record still exists) back to the old account, and left v3-only custom names 500ing — only npub1* names had a Cloudflare redirect. Resolution order is now: registrar-claimed -> registrar (response handed through, cached 60s, fail-open to local if the registrar is down), else local account, else 404. The migrated flag stays out of it: register.ts stamps it on essentially every account. No loop: we defer only for names the registrar HAS, and it never queries us for those. Co-Authored-By: Claude Fable 5 <[email protected]>
* lnurl: serve local accounts directly instead of deferring to v3 registrarAdam Soltys2026-08-041-19/+9
| | | | | | | | | | | | | | | | | A recent change made this coinos.io lnurlp endpoint defer any migrated-flagged account to the v3 names registrar and 404 when the registrar didn't have the name. But registration stamps that flag on essentially every account and never syncs names to the registrar, so this broke lightning-address resolution for nearly all accounts. The v3 registrar is the front for v3 accounts and falls back to this endpoint, so this endpoint is the fallback target: it must serve its own accounts directly and must not defer back (which also avoids a loop once the registrar's fallback is live). Serve the local account; 404 only when no local account exists. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dpqu6wizYe1c1g4k5Gd8JK
* Let a migrated account hand its address to coinos v3Adam Soltys2026-08-031-4/+4
| | | | | | | | | | | | A `migrated` flag on the user, settable through /user and visible on the public user endpoint. It changes exactly one thing: lnurlp for that username defers to the names registrar, so payments to [email protected] arrive in the person's v3 wallet. The account itself is untouched — same username, same history, still usable here — which is why this is a flag and not a rename or a shutdown. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* LNURL: fall back to the v3 names registrar for unknown usersAdam Soltys2026-08-021-1/+21
| | | | | | | | | 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]>
* lnurl: SSRF-guard user-supplied URL fetches + validate zap eventsAdam Soltys2026-06-151-5/+9
| | | | | | | | | | | | | | | | The /lnurl/proxy, /decode and /encode handlers fetched an arbitrary user-supplied URL via got() and returned the body — an unauthenticated SSRF reaching internal services. Route those fetches through a new safeGot() that rejects hosts resolving to loopback/private/link-local/ CGNAT/metadata ranges, re-validates on each redirect hop, restricts the scheme to http(s), and caps timeout + response size. Also validate the NIP-57 zap request (kind 9734 + signature) before storing it, instead of trusting the client-supplied event. These endpoints can't be removed — they back lightning-address/LNURL parsing and resolution in the wallet UI. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* lnurl proxyAdam Soltys2026-03-271-0/+12
|
* fix lnurl description_hash mismatchAdam Soltys2026-02-251-2/+6
| | | | Co-Authored-By: Claude Opus 4.6 <[email protected]>
* consult archive for older paymentsAdam Soltys2026-01-301-2/+2
|
* rotate server keyAdam Soltys2025-09-291-3/+3
|
* only record invoice if amount is definedAdam Soltys2025-07-311-2/+4
|
* always define minSendable and maxSendableAdam Soltys2025-07-311-3/+3
|
* leave minSendable undefined if no amountAdam Soltys2025-07-311-1/+1
|
* respect null tipsAdam Soltys2025-07-191-2/+15
|
* record prompt setting for lnurl invoicesAdam Soltys2025-07-191-49/+4
|
* record lnurl invoiceAdam Soltys2025-07-161-12/+19
|
* fix lnurl logicAdam Soltys2025-07-101-1/+2
|
* handle empty amountsAdam Soltys2025-07-081-1/+1
|
* include tip in lnurlAdam Soltys2025-07-081-2/+3
|
* fix variable nameAdam Soltys2025-07-081-3/+3
|
* invoice seekAdam Soltys2025-07-081-7/+15
|
* mark self-generated invoicesAdam Soltys2025-06-231-4/+12
|
* lnurl pay endpoint for latest invoiceAdam Soltys2025-05-061-1/+41
|
* fund routesAdam Soltys2025-03-151-47/+47
|
* strip spaces from lnurlAdam Soltys2025-02-261-2/+2
|
* payment typesAdam Soltys2025-02-261-4/+11
|
* use lnurl comment if providedAdam Soltys2025-01-241-2/+2
|
* pubkey challengeAdam Soltys2025-01-091-2/+2
|
* lnurlwAdam Soltys2024-12-241-4/+47
|
* stifle lnurlp warningsAdam Soltys2024-12-181-2/+7
|
* strip equalsAdam Soltys2024-12-131-1/+1
|
* better lnurl errorAdam Soltys2024-12-061-1/+4
|
* sanitize lnurl usernameAdam Soltys2024-12-061-1/+3
|
* add pr to lnurl verify responseAdam Soltys2024-12-051-2/+2
|
* add null preimage to lnurl verify responseAdam Soltys2024-12-051-7/+7
|
* biome lintAdam Soltys2024-10-311-24/+24
|
* atomic payment reversalAdam Soltys2024-10-161-1/+2
|
* refactor nwcAdam Soltys2024-09-181-2/+2
|
* fix some ts issuesAdam Soltys2024-08-261-18/+21
|
* typescriptAdam Soltys2024-08-261-0/+135