mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-04 18:33:10 +02:00
test
add tests fix interface
This commit is contained in:
@@ -29,6 +29,7 @@ from lnbits.wallets.base import (
|
||||
PaymentResponse,
|
||||
PaymentStatus,
|
||||
PaymentSuccessStatus,
|
||||
UnsupportedError,
|
||||
)
|
||||
|
||||
from ..crud import (
|
||||
@@ -965,17 +966,15 @@ async def create_hold_invoice(
|
||||
invoice_memo = None if description_hash else memo
|
||||
|
||||
funding_source = get_funding_source()
|
||||
if funding_source.__class__.__name__ not in ["LndRestWallet", "LndWallet"]:
|
||||
raise InvoiceError(
|
||||
"Hold invoices are only supported with LND.", status="failed"
|
||||
try:
|
||||
res = await funding_source.create_hold_invoice(
|
||||
amount=amount,
|
||||
memo=invoice_memo,
|
||||
rhash=rhash,
|
||||
description_hash=description_hash,
|
||||
)
|
||||
|
||||
res = await funding_source.create_hold_invoice(
|
||||
amount=amount,
|
||||
memo=invoice_memo,
|
||||
rhash=rhash,
|
||||
description_hash=description_hash,
|
||||
)
|
||||
except UnsupportedError as exc:
|
||||
raise InvoiceError(str(exc), status="failed") from exc
|
||||
|
||||
if not res.ok:
|
||||
raise InvoiceError(
|
||||
@@ -1004,23 +1003,24 @@ async def create_hold_invoice(
|
||||
)
|
||||
|
||||
|
||||
# TODO: should return payment
|
||||
# TODO: update payment status to success
|
||||
async def settle_hold_invoice(
|
||||
*,
|
||||
preimage: str,
|
||||
) -> bool:
|
||||
if len(preimage) != 32:
|
||||
if len(bytes.fromhex(preimage)) != 32:
|
||||
raise InvoiceError(
|
||||
"Invalid preimage length. Must be 32 bytes",
|
||||
status="failed",
|
||||
)
|
||||
|
||||
funding_source = get_funding_source()
|
||||
if funding_source.__class__.__name__ not in ["LndRestWallet", "LndWallet"]:
|
||||
raise InvoiceError(
|
||||
"Hold invoices are only supported with LND.", status="failed"
|
||||
)
|
||||
|
||||
response = await funding_source.settle_hold_invoice(preimage=preimage)
|
||||
try:
|
||||
response = await funding_source.settle_hold_invoice(preimage=preimage)
|
||||
except UnsupportedError as exc:
|
||||
raise InvoiceError(str(exc), status="failed") from exc
|
||||
|
||||
if not response.ok:
|
||||
raise InvoiceError("Unexpected backend error.", status="failed")
|
||||
@@ -1028,32 +1028,38 @@ async def settle_hold_invoice(
|
||||
return True
|
||||
|
||||
|
||||
async def cancel_hold_invoice(payment_hash: str) -> bool:
|
||||
async def cancel_hold_invoice(payment_hash: str) -> Payment:
|
||||
payment = await get_standalone_payment(payment_hash, incoming=True)
|
||||
if not payment:
|
||||
raise InvoiceError("Payment not found.", status="failed")
|
||||
|
||||
funding_source = get_funding_source()
|
||||
if funding_source.__class__.__name__ not in ["LndRestWallet", "LndWallet"]:
|
||||
raise InvoiceError(
|
||||
"Hold invoices are only supported with LND.", status="failed"
|
||||
)
|
||||
response = await funding_source.cancel_hold_invoice(payment_hash=payment_hash)
|
||||
try:
|
||||
response = await funding_source.cancel_hold_invoice(payment_hash=payment_hash)
|
||||
except UnsupportedError as exc:
|
||||
raise InvoiceError(str(exc), status="failed") from exc
|
||||
if not response.ok:
|
||||
raise InvoiceError("Unexpected backend error.", status="failed")
|
||||
|
||||
return True
|
||||
raise InvoiceError(
|
||||
response.error_message or "Unexpected backend error.", status="failed"
|
||||
)
|
||||
payment.status = PaymentState.FAILED
|
||||
await update_payment(payment)
|
||||
return payment
|
||||
|
||||
|
||||
async def subscribe_hold_invoice(payment_hash: str) -> bool:
|
||||
payment = await get_standalone_payment(payment_hash, incoming=True)
|
||||
if not payment:
|
||||
raise InvoiceError("Payment not found.", status="failed")
|
||||
funding_source = get_funding_source()
|
||||
if funding_source.__class__.__name__ not in ["LndRestWallet", "LndWallet"]:
|
||||
raise InvoiceError(
|
||||
"Hold invoices are only supported with LND.", status="failed"
|
||||
)
|
||||
# if payment.webhook:
|
||||
# asyncio. create_task(
|
||||
# funding_source.hold_invoices_stream(
|
||||
# payment_hash=payment_hash, webhook=payment.webhook
|
||||
# )
|
||||
# )
|
||||
# funding_source = get_funding_source()
|
||||
try:
|
||||
# if payment.webhook:
|
||||
# asyncio. create_task(
|
||||
# funding_source.hold_invoices_stream(
|
||||
# payment_hash=payment_hash, webhook=payment.webhook
|
||||
# )
|
||||
# )
|
||||
pass
|
||||
except UnsupportedError as exc:
|
||||
raise InvoiceError(str(exc), status="failed") from exc
|
||||
return True
|
||||
|
@@ -346,9 +346,12 @@ class LndRestWallet(Wallet):
|
||||
else:
|
||||
data["memo"] = memo or ""
|
||||
|
||||
r = await self.client.post(url="/v2/invoices/hodl", json=data)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
try:
|
||||
r = await self.client.post(url="/v2/invoices/hodl", json=data)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
except httpx.HTTPStatusError as exc:
|
||||
return InvoiceResponse(False, None, None, exc.response.text)
|
||||
|
||||
payment_request = data["payment_request"]
|
||||
payment_hash = base64.b64encode(bytes.fromhex(rhash)).decode("ascii")
|
||||
@@ -357,20 +360,27 @@ class LndRestWallet(Wallet):
|
||||
return InvoiceResponse(True, checking_id, payment_request, None)
|
||||
|
||||
async def settle_hold_invoice(self, preimage: str) -> PaymentResponse:
|
||||
data: dict = {"preimage": base64.b64encode(preimage.encode()).decode("ascii")}
|
||||
r = await self.client.post(url="/v2/invoices/settle", json=data)
|
||||
r.raise_for_status()
|
||||
|
||||
return PaymentResponse(True, None, None, None, None)
|
||||
data: dict = {
|
||||
"preimage": base64.b64encode(bytes.fromhex(preimage)).decode("ascii")
|
||||
}
|
||||
try:
|
||||
r = await self.client.post(url="/v2/invoices/settle", json=data)
|
||||
r.raise_for_status()
|
||||
return PaymentResponse(True, None, None, None, None)
|
||||
except httpx.HTTPStatusError as exc:
|
||||
return PaymentResponse(False, None, None, None, exc.response.text)
|
||||
|
||||
async def cancel_hold_invoice(self, payment_hash: str) -> PaymentResponse:
|
||||
data: dict = {
|
||||
"payment_hash": base64.b64encode(payment_hash.encode()).decode("ascii")
|
||||
}
|
||||
r = await self.client.post(url="/v2/invoices/cancel", json=data)
|
||||
r.raise_for_status()
|
||||
|
||||
return PaymentResponse(True, None, None, None, None)
|
||||
rhash = bytes.fromhex(payment_hash)
|
||||
try:
|
||||
r = await self.client.post(
|
||||
url="/v2/invoices/cancel",
|
||||
json={"payment_hash": base64.b64encode(rhash).decode("ascii")},
|
||||
)
|
||||
r.raise_for_status()
|
||||
return PaymentResponse(True, None, None, None, None)
|
||||
except httpx.HTTPStatusError as exc:
|
||||
return PaymentResponse(False, None, None, None, exc.response.text)
|
||||
|
||||
async def hold_invoices_stream(self, payment_hash: str, webhook: str):
|
||||
try:
|
||||
|
59
tests/regtest/test_real_hold_invoice.py
Normal file
59
tests/regtest/test_real_hold_invoice.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from lnbits.core.services.payments import (
|
||||
cancel_hold_invoice,
|
||||
create_hold_invoice,
|
||||
settle_hold_invoice,
|
||||
)
|
||||
from lnbits.exceptions import InvoiceError
|
||||
|
||||
from ..helpers import funding_source, is_fake
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
@pytest.mark.skipif(is_fake, reason="this only works in regtest")
|
||||
@pytest.mark.skipif(
|
||||
funding_source.__class__.__name__ in ["LndRestWallet", "LndWallet"],
|
||||
reason="this should not raise for lnd",
|
||||
)
|
||||
async def test_pay_raise_unsupported():
|
||||
rhash = "0" * 32
|
||||
with pytest.raises(InvoiceError):
|
||||
await create_hold_invoice(
|
||||
wallet_id="fake_wallet_id",
|
||||
amount=1000,
|
||||
memo="fake_holdinvoice",
|
||||
rhash=rhash,
|
||||
)
|
||||
with pytest.raises(InvoiceError):
|
||||
await settle_hold_invoice(preimage=rhash)
|
||||
with pytest.raises(InvoiceError):
|
||||
await cancel_hold_invoice(rhash)
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
@pytest.mark.skipif(is_fake, reason="this only works in regtest")
|
||||
@pytest.mark.skipif(
|
||||
funding_source.__class__.__name__ not in ["LndRestWallet"],
|
||||
reason="this only works for lndrest",
|
||||
)
|
||||
async def test_pay_real_hold_invoice(from_wallet):
|
||||
|
||||
preimage = os.urandom(32)
|
||||
preimage_hash = hashlib.sha256(preimage).hexdigest()
|
||||
payment = await create_hold_invoice(
|
||||
wallet_id=from_wallet.id,
|
||||
amount=1000,
|
||||
memo="test_holdinvoice",
|
||||
rhash=preimage_hash,
|
||||
)
|
||||
assert payment.amount == 1000 * 1000
|
||||
assert payment.memo == "test_holdinvoice"
|
||||
assert payment.status == "pending"
|
||||
assert payment.wallet_id == from_wallet.id
|
||||
|
||||
payment = await cancel_hold_invoice(payment_hash=preimage_hash)
|
||||
assert payment.status == "failed"
|
Reference in New Issue
Block a user