11import json
2+ from http import HTTPStatus
23
34from fastapi import APIRouter , Query , Request
5+ from fastapi .exceptions import HTTPException
6+ from fastapi .responses import HTMLResponse
47from lnbits .core .services import create_invoice
5- from lnurl import (
6- CallbackUrl ,
7- LightningInvoice ,
8- LnurlErrorResponse ,
9- LnurlPayActionResponse ,
10- LnurlPayMetadata ,
11- LnurlPayResponse ,
12- MilliSatoshi ,
13- )
14- from pydantic import parse_obj_as
8+ from lnurl .types import LnurlPayMetadata
159
1610from .crud import get_copilot
1711
1812copilot_lnurl_router = APIRouter ()
1913
2014
21- @copilot_lnurl_router .get ("/lnurl/{cp_id}" , name = "copilot.lnurl_response" )
22- async def lnurl_response (
23- req : Request , cp_id : str
24- ) -> LnurlPayResponse | LnurlErrorResponse :
15+ @copilot_lnurl_router .get (
16+ "/lnurl/{cp_id}" , response_class = HTMLResponse , name = "copilot. lnurl_response"
17+ )
18+ async def lnurl_response ( req : Request , cp_id : str ) :
2519 cp = await get_copilot (cp_id )
2620 if not cp :
27- return LnurlErrorResponse (reason = "Copilot not found." )
28-
29- callback_url = parse_obj_as (
30- CallbackUrl , str (req .url_for ("copilot.lnurl_callback" , cp_id = cp_id ))
31- )
21+ raise HTTPException (
22+ status_code = HTTPStatus .NOT_FOUND , detail = "Copilot not found"
23+ )
3224
33- pay_response = LnurlPayResponse (
34- callback = callback_url ,
35- metadata = LnurlPayMetadata (json .dumps ([["text/plain" , str (cp .lnurl_title )]])),
36- minSendable = MilliSatoshi (10000 ),
37- maxSendable = MilliSatoshi (50000000 ),
38- )
25+ pay_response = {
26+ "tag" : "payRequest" ,
27+ "callback" : str (req .url_for ("copilot.lnurl_callback" , cp_id = cp_id )),
28+ "metadata" : LnurlPayMetadata (json .dumps ([["text/plain" , str (cp .lnurl_title )]])),
29+ "maxSendable" : 50000000 ,
30+ "minSendable" : 10000 ,
31+ }
3932
4033 if cp .show_message :
41- pay_response .commentAllowed = 300
42-
43- return pay_response
34+ pay_response ["commentAllowed" ] = 300
35+ return json .dumps (pay_response )
4436
4537
4638@copilot_lnurl_router .get ("/lnurl/cb/{cp_id}" , name = "copilot.lnurl_callback" )
4739async def lnurl_callback (
4840 cp_id : str , amount : str = Query (None ), comment : str = Query (None )
49- ) -> LnurlPayActionResponse | LnurlErrorResponse :
41+ ):
5042 cp = await get_copilot (cp_id )
5143 if not cp :
52- return LnurlErrorResponse (reason = "Copilot not found." )
53-
44+ raise HTTPException (
45+ status_code = HTTPStatus .NOT_FOUND , detail = "Copilot not found"
46+ )
5447 amount_received = int (amount )
55- amount_rounded = round ( amount_received / 1000 )
48+
5649 if amount_received < 10000 :
57- return LnurlErrorResponse (
58- reason = f"Amount { amount_rounded } is smaller than minimum 10 sats."
50+ raise HTTPException (
51+ status_code = HTTPStatus .FORBIDDEN ,
52+ detail = (
53+ "Amount {round(amount_received / 1000)} "
54+ "is smaller than minimum 10 sats."
55+ ),
5956 )
6057 elif amount_received / 1000 > 10000000 :
61- return LnurlErrorResponse (
62- reason = f"Amount { amount_rounded } is greater than maximum 10000000 sats."
58+ raise HTTPException (
59+ status_code = HTTPStatus .FORBIDDEN ,
60+ detail = (
61+ "Amount {round(amount_received / 1000)} "
62+ "is greater than maximum 50000."
63+ ),
6364 )
64-
65+ comment = ""
6566 if comment :
66- if len (comment ) > 300 :
67- return LnurlErrorResponse (
68- reason = (
69- f"Got a comment with { len (comment )} characters, "
67+ if len (comment or "" ) > 300 :
68+ raise HTTPException (
69+ status_code = HTTPStatus .FORBIDDEN ,
70+ detail = (
71+ "Got a comment with {len(comment)} characters, "
7072 "but can only accept 300"
71- )
73+ ),
7274 )
73-
75+ if len (comment ) < 1 :
76+ comment = "none"
77+ assert cp .wallet , "Copilot wallet not found"
7478 payment = await create_invoice (
7579 wallet_id = cp .wallet ,
7680 amount = int (amount_received / 1000 ),
@@ -80,6 +84,4 @@ async def lnurl_callback(
8084 ).encode (),
8185 extra = {"tag" : "copilot" , "copilotid" : cp .id , "comment" : comment },
8286 )
83-
84- invoice = parse_obj_as (LightningInvoice , payment .bolt11 )
85- return LnurlPayActionResponse (pr = invoice )
87+ return {"pr" : payment .bolt11 , "routes" : []}
0 commit comments