mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-11 04:52:34 +02:00
add holdinvoice func. to the lnd rest wallet
This commit is contained in:
@@ -320,3 +320,84 @@ class LndRestWallet(Wallet):
|
|||||||
" seconds"
|
" seconds"
|
||||||
)
|
)
|
||||||
await asyncio.sleep(5)
|
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