Backend: Unstuck outgoing payments (#857)

* first attempts

* lndrest works

* fix details

* optional fee update

* use base64.urlsafe_b64encode

* return paymentstatus

* CLN: return pending for pending invoices

* grpc wip

* lndgrpc works

* cln: return pending for pending invoices really this time

* retry wallet out of exception

* wip eclair

* take all routines into try except

* cliche: return error

* rename payment.check_pending() to payment.check_status()

* rename payment.check_pending() to payment.check_status()

* eclair: works

* eclair: better error check

* opennode: works

* check payment.checking_id istead of payment.ok

* payment.ok check as well

* cln: works?

* cln: works

* lntxbot: works

* lnbits/wallets/lnpay.py

* cln: error handling

* make format

* lndhub full detail update

* spark: wip

* error to False

* wallets: return clean PaymentResponse

* opennode: strict error

* cliche: works

* lnbits: works

* cln: dont throw error

* preimage not error

* fix cln

* do not add duplicate payments

* revert cln

* extra safety for cln

* undo crud changes until tests work

* tasks: better logging and 0.5s sleep for regular status check

* 0.1 s

* check if wallet exists

* lnbits unhashed description

* remove sleep

* revert app.py

* cleanup

* add check

* clean error

* readd app.py

* fix eclaid
This commit is contained in:
calle
2022-08-30 13:28:58 +02:00
committed by GitHub
parent 78a98ca97d
commit 2ee10e28c5
18 changed files with 384 additions and 194 deletions
+21 -8
View File
@@ -62,10 +62,10 @@ class LNbitsWallet(Wallet):
data: Dict = {"out": False, "amount": amount}
if description_hash:
data["description_hash"] = description_hash.hex()
elif unhashed_description:
data["description_hash"] = hashlib.sha256(unhashed_description).hexdigest()
else:
data["memo"] = memo or ""
if unhashed_description:
data["unhashed_description"] = unhashed_description.hex()
data["memo"] = memo or ""
async with httpx.AsyncClient() as client:
r = await client.post(
@@ -94,15 +94,25 @@ class LNbitsWallet(Wallet):
json={"out": True, "bolt11": bolt11},
timeout=None,
)
ok, checking_id, fee_msat, error_message = not r.is_error, None, 0, None
ok, checking_id, fee_msat, preimage, error_message = (
not r.is_error,
None,
None,
None,
None,
)
if r.is_error:
error_message = r.json()["detail"]
return PaymentResponse(None, None, None, None, error_message)
else:
data = r.json()
checking_id = data["checking_id"]
checking_id = data["payment_hash"]
return PaymentResponse(ok, checking_id, fee_msat, error_message)
# we do this to get the fee and preimage
payment: PaymentStatus = await self.get_payment_status(checking_id)
return PaymentResponse(ok, checking_id, payment.fee_msat, payment.preimage)
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
try:
@@ -125,8 +135,11 @@ class LNbitsWallet(Wallet):
if r.is_error:
return PaymentStatus(None)
data = r.json()
if "paid" not in data and "details" not in data:
return PaymentStatus(None)
return PaymentStatus(r.json()["paid"])
return PaymentStatus(data["paid"], data["details"]["fee"], data["preimage"])
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
url = f"{self.endpoint}/api/v1/payments/sse"