forked from lnbits/myextension
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlnurl.py
160 lines (143 loc) · 4.99 KB
/
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Maybe your extension needs some LNURL stuff.
# Here is a very simple example of how to do it.
# Feel free to delete this file if you don't need it.
from http import HTTPStatus
from fastapi import Depends, Query, Request
from . import myextension_ext
from .crud import get_myextension
from lnbits.core.services import create_invoice, pay_invoice
from loguru import logger
from typing import Optional
from .crud import update_myextension
from .models import MyExtension
import shortuuid
#################################################
########### A very simple LNURLpay ##############
# https://github.com/lnurl/luds/blob/luds/06.md #
#################################################
#################################################
@myextension_ext.get(
"/api/v1/lnurl/pay/{myextension_id}",
status_code=HTTPStatus.OK,
name="myextension.api_lnurl_pay",
)
async def api_lnurl_pay(
request: Request,
myextension_id: str,
):
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
return {
"callback": str(
request.url_for(
"myextension.api_lnurl_pay_callback", myextension_id=myextension_id
)
),
"maxSendable": myextension.lnurlpayamount * 1000,
"minSendable": myextension.lnurlpayamount * 1000,
"metadata": '[["text/plain", "' + myextension.name + '"]]',
"tag": "payRequest",
}
@myextension_ext.get(
"/api/v1/lnurl/pay/cb/{myextension_id}",
status_code=HTTPStatus.OK,
name="myextension.api_lnurl_pay_callback",
)
async def api_lnurl_pay_cb(
request: Request,
myextension_id: str,
amount: int = Query(...),
):
myextension = await get_myextension(myextension_id)
logger.debug(myextension)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
payment_hash, payment_request = await create_invoice(
wallet_id=myextension.wallet,
amount=int(amount / 1000),
memo=myextension.name,
unhashed_description=f'[["text/plain", "{myextension.name}"]]'.encode(),
extra={
"tag": "MyExtension",
"myextensionId": myextension_id,
"extra": request.query_params.get("amount"),
},
)
return {
"pr": payment_request,
"routes": [],
"successAction": {"tag": "message", "message": f"Paid {myextension.name}"},
}
#################################################
######## A very simple LNURLwithdraw ############
# https://github.com/lnurl/luds/blob/luds/03.md #
#################################################
## withdraws are unique, removing 'tickerhash' ##
## here and crud.py will allow muliple pulls ####
#################################################
@myextension_ext.get(
"/api/v1/lnurl/withdraw/{myextension_id}/{tickerhash}",
status_code=HTTPStatus.OK,
name="myextension.api_lnurl_withdraw",
)
async def api_lnurl_withdraw(
request: Request,
myextension_id: str,
tickerhash: str,
):
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
k1 = shortuuid.uuid(name=myextension.id + str(myextension.ticker))
if k1 != tickerhash:
return {"status": "ERROR", "reason": "LNURLw already used"}
return {
"tag": "withdrawRequest",
"callback": str(
request.url_for(
"myextension.api_lnurl_withdraw_callback", myextension_id=myextension_id
)
),
"k1": k1,
"defaultDescription": myextension.name,
"maxWithdrawable": myextension.lnurlwithdrawamount * 1000,
"minWithdrawable": myextension.lnurlwithdrawamount * 1000,
}
@myextension_ext.get(
"/api/v1/lnurl/withdraw/cb/{myextension_id}",
status_code=HTTPStatus.OK,
name="myextension.api_lnurl_withdraw_callback",
)
async def api_lnurl_withdraw_cb(
request: Request,
myextension_id: str,
pr: Optional[str] = None,
k1: Optional[str] = None,
):
assert k1, "k1 is required"
assert pr, "pr is required"
logger.debug("cunt")
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
k1Check = shortuuid.uuid(name=myextension.id + str(myextension.ticker))
if k1Check != k1:
return {"status": "ERROR", "reason": "Wrong k1 check provided"}
await update_myextension(
myextension_id=myextension_id, ticker=myextension.ticker + 1
)
logger.debug(myextension.wallet)
logger.debug(pr)
logger.debug(int(myextension.lnurlwithdrawamount * 1000))
await pay_invoice(
wallet_id=myextension.wallet,
payment_request=pr,
max_sat=int(myextension.lnurlwithdrawamount * 1000),
extra={
"tag": "MyExtension",
"myextensionId": myextension_id,
"lnurlwithdraw": True,
},
)
return {"status": "OK"}