-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathviews_lnurl.py
137 lines (123 loc) · 3.95 KB
/
views_lnurl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from http import HTTPStatus
from fastapi import APIRouter, Query, Request
from lnbits.core.services import create_invoice
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
from .crud import (
create_bitcoinswitch_payment,
delete_bitcoinswitch_payment,
get_bitcoinswitch,
get_bitcoinswitch_payment,
update_bitcoinswitch_payment,
)
bitcoinswitch_lnurl_router = APIRouter(prefix="/api/v1/lnurl")
@bitcoinswitch_lnurl_router.get(
"{bitcoinswitch_id}",
status_code=HTTPStatus.OK,
name="bitcoinswitch.lnurl_params",
)
async def lnurl_params(
request: Request,
bitcoinswitch_id: str,
pin: str,
amount: str,
duration: str,
variable: bool = Query(None),
comment: bool = Query(None),
):
switch = await get_bitcoinswitch(bitcoinswitch_id)
if not switch:
return {
"status": "ERROR",
"reason": f"bitcoinswitch {bitcoinswitch_id} not found on this server",
}
price_msat = int(
(
await fiat_amount_as_satoshis(float(amount), switch.currency)
if switch.currency != "sat"
else float(amount)
)
* 1000
)
# Check they're not trying to trick the switch!
check = False
for _switch in switch.switches:
if (
_switch.pin == int(pin)
and _switch.duration == int(duration)
and bool(_switch.variable) == bool(variable)
and bool(_switch.comment) == bool(comment)
):
check = True
continue
if not check:
return {"status": "ERROR", "reason": "Extra params wrong"}
bitcoinswitch_payment = await create_bitcoinswitch_payment(
bitcoinswitch_id=switch.id,
payload=duration,
amount_msat=price_msat,
pin=int(pin),
payment_hash="not yet set",
)
if not bitcoinswitch_payment:
return {"status": "ERROR", "reason": "Could not create payment."}
url = str(
request.url_for(
"bitcoinswitch.lnurl_callback", payment_id=bitcoinswitch_payment.id
)
)
resp = {
"tag": "payRequest",
"callback": f"{url}?variable={variable}",
"minSendable": price_msat,
"maxSendable": price_msat,
"metadata": switch.lnurlpay_metadata,
}
if comment:
resp["commentAllowed"] = 1500
if variable is True:
resp["maxSendable"] = price_msat * 360
return resp
@bitcoinswitch_lnurl_router.get(
"/cb/{payment_id}",
status_code=HTTPStatus.OK,
name="bitcoinswitch.lnurl_callback",
)
async def lnurl_callback(
payment_id: str,
variable: bool = Query(None),
amount: int = Query(None),
comment: str = Query(None),
):
bitcoinswitch_payment = await get_bitcoinswitch_payment(payment_id)
if not bitcoinswitch_payment:
return {"status": "ERROR", "reason": "bitcoinswitchpayment not found."}
switch = await get_bitcoinswitch(bitcoinswitch_payment.bitcoinswitch_id)
if not switch:
await delete_bitcoinswitch_payment(payment_id)
return {"status": "ERROR", "reason": "bitcoinswitch not found."}
if not amount:
return {"status": "ERROR", "reason": "No amount"}
payment = await create_invoice(
wallet_id=switch.wallet,
amount=int(amount / 1000),
memo=f"{switch.title} ({bitcoinswitch_payment.payload} ms)",
unhashed_description=switch.lnurlpay_metadata.encode(),
extra={
"tag": "Switch",
"pin": str(bitcoinswitch_payment.pin),
"amount": str(int(amount)),
"comment": comment,
"variable": variable,
"id": payment_id,
},
)
bitcoinswitch_payment.payment_hash = payment.payment_hash
await update_bitcoinswitch_payment(bitcoinswitch_payment)
return {
"pr": payment.bolt11,
"successAction": {
"tag": "message",
"message": f"{int(amount / 1000)}sats sent",
},
"routes": [],
}