mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-09 20:12:34 +02:00
add holdinvoice func. to the lnd rest wallet
This commit is contained in:
@@ -320,3 +320,84 @@ class LndRestWallet(Wallet):
|
||||
" seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
|
||||
async def create_hold_invoice(
|
||||
self,
|
||||
amount: int,
|
||||
rhash: bytes,
|
||||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
data: Dict = {
|
||||
"value": amount,
|
||||
"private": True,
|
||||
"hash": base64.b64encode(rhash).decode("ascii"),
|
||||
}
|
||||
if description_hash:
|
||||
data["description_hash"] = base64.b64encode(description_hash).decode(
|
||||
"ascii"
|
||||
)
|
||||
elif unhashed_description:
|
||||
data["description_hash"] = base64.b64encode(
|
||||
hashlib.sha256(unhashed_description).digest()
|
||||
).decode("ascii")
|
||||
else:
|
||||
data["memo"] = memo or ""
|
||||
|
||||
r = await self.client.post(url="/v2/invoices/hodl", json=data)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
|
||||
payment_request = data["payment_request"]
|
||||
payment_hash = base64.b64encode(rhash).decode("ascii")
|
||||
checking_id = payment_hash
|
||||
|
||||
return InvoiceResponse(True, checking_id, payment_request, None)
|
||||
|
||||
async def settle_hold_invoice(self, preimage: str) -> PaymentResponse:
|
||||
data: Dict = {"preimage": base64.b64encode(preimage).decode("ascii")}
|
||||
r = await self.client.post(url="/v2/invoices/settle", json=data)
|
||||
r.raise_for_status()
|
||||
|
||||
return PaymentResponse(True, None, None, None, None)
|
||||
|
||||
async def cancel_hold_invoice(self, payment_hash: str) -> PaymentResponse:
|
||||
data: Dict = {"payment_hash": base64.b64encode(payment_hash).decode("ascii")}
|
||||
r = await self.client.post(url="/v2/invoices/cancel", json=data)
|
||||
r.raise_for_status()
|
||||
|
||||
return PaymentResponse(True, None, None, None, None)
|
||||
|
||||
async def hold_invoices_stream(self, payment_hash: str, webhook: str):
|
||||
try:
|
||||
rhash_hex = bytes.fromhex(payment_hash)
|
||||
rhash = base64.urlsafe_b64encode(rhash_hex)
|
||||
url = f"{self.endpoint}/v2/invoices/subscribe/{rhash.decode()}"
|
||||
async with self.client.stream("GET", url, timeout=None) as r:
|
||||
async for line in r.aiter_lines():
|
||||
try:
|
||||
inv = json.loads(line)["result"]
|
||||
if inv["state"] not in ["ACCEPTED", "CANCELED"]:
|
||||
continue
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
# dispatch webhook
|
||||
inv["payment_hash"] = payment_hash
|
||||
await LndRestWallet.dispatch_hold_webhook(webhook, inv)
|
||||
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
f"lost connection to lnd hold invoices stream: '{exc}', retrying in 5 seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
|
||||
async def dispatch_hold_webhook(self, webhook, inv):
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
logger.debug("sending hold webhook", webhook, str(inv))
|
||||
await client.post(webhook, json=inv, timeout=40) # type: ignore
|
||||
except (httpx.ConnectError, httpx.RequestError):
|
||||
logger.debug("error sending hold webhook")
|
||||
|
Reference in New Issue
Block a user