add holdinvoice func. to the lnd rest wallet

This commit is contained in:
ziggie
2024-12-28 11:20:46 +01:00
committed by dni ⚡
parent 5440a9dbd7
commit d0d1d4642e

View File

@@ -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")