Skip to content

Commit 904884c

Browse files
authored
Merge pull request #142 from jimasuen/main
Added functionality to pay LNURL and lightning addresses
2 parents d1c93ad + 9dfd5fb commit 904884c

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

pylnbits/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
- Decode an invoice (new)
1313
- Get invoices (incoming or outgoing) (new)
1414
- Get invoice(s) by memo (incoming or outgoing (new)
15+
- Pay LNURL
16+
- Pay lightning address
1517
- `user_manager.py`: For managing multiple users on LNBits, calls Rest API methods from LNbits User Manager Extension
1618
1719
- GET users

pylnbits/user_wallet.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import json
22
import logging
33

4+
import hashlib
5+
46
from aiohttp.client import ClientSession
57
from lnurl import Lnurl
68

@@ -40,6 +42,7 @@ def __init__(self, config, session: ClientSession = None):
4042
self._config = config
4143
self._invoice_headers = config.invoice_headers()
4244
self._admin_headers = config.admin_headers()
45+
self._headers = config.headers()
4346
self._lnbits_url = config.lnbits_url
4447
self.paypath = "/api/v1/payments"
4548
self.walletpath = "/api/v1/wallet"
@@ -301,4 +304,75 @@ async def get_bolt11(self, email: str, amount: int):
301304

302305
except Exception as e:
303306
print("Exception as: ", str(e))
304-
return e
307+
return e
308+
309+
#Pay LNURL
310+
async def pay_lnurl(self, lnurl_str: str, amount: int, comment: str, description: str):
311+
"""
312+
Success state
313+
{'success_action': None,
314+
'payment_hash': '2dac7....',
315+
'checking_id': '2dac7....'}
316+
"""
317+
try:
318+
#convert amount to millisats
319+
amount = amount * 1000
320+
321+
decoded = await self.get_decoded(lnurl_str)
322+
323+
if "domain" in decoded:
324+
domain = decoded["domain"]
325+
res = await get_url(self._session, path=domain, headers=self._headers)
326+
327+
if "callback" in res and "metadata" in res:
328+
callback = res["callback"]
329+
metadata_hash = hashlib.sha256(res["metadata"].encode()).hexdigest()
330+
result = await self.process_lnresponse(metadata_hash, callback, amount, comment, description)
331+
return result
332+
else:
333+
return None
334+
else:
335+
return None
336+
except Exception as e:
337+
print("Exception as: ", str(e))
338+
return e
339+
340+
#Pay LN Address
341+
async def pay_lnaddress(self, email: str, amount: int, comment: str, description: str):
342+
"""
343+
Success state
344+
345+
{'success_action': {'tag': 'message', 'message': 'Thanks, sats received!'},
346+
'payment_hash': '67nn.....',
347+
'checking_id': '67nn.....'}
348+
"""
349+
try:
350+
#convert amount to millisats
351+
amount = amount * 1000
352+
353+
ln_str = self.get_payurl(email)
354+
res = await get_url(self._session, path=ln_str, headers=self._headers)
355+
356+
if "callback" in res and "metadata" in res:
357+
callback = res["callback"]
358+
metadata_hash = hashlib.sha256(res["metadata"].encode()).hexdigest()
359+
result = await self.process_lnresponse(metadata_hash, callback, amount, comment, description)
360+
return result
361+
else:
362+
return None
363+
except Exception as e:
364+
print("Exception as: ", str(e))
365+
return e
366+
367+
368+
#Process LNURL response
369+
async def process_lnresponse(self, metadata_hash: str, callback: str, amount: int, comment: str, description: str):
370+
try:
371+
path = self._lnbits_url + self.paypath + "/lnurl"
372+
body = {"description_hash": metadata_hash, "callback": callback, "amount": amount, "comment": comment, "description": description}
373+
j = json.dumps(body)
374+
res = await post_url(self._session, path=path, headers=self._admin_headers, body=j)
375+
return res
376+
except Exception as e:
377+
print("Exception as: ", str(e))
378+
return e

0 commit comments

Comments
 (0)