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
+17 -9
View File
@@ -123,18 +123,15 @@ class LndRestWallet(Wallet):
if r.is_error or r.json().get("payment_error"):
error_message = r.json().get("payment_error") or r.text
return PaymentResponse(False, None, 0, None, error_message)
return PaymentResponse(False, None, None, None, error_message)
data = r.json()
payment_hash = data["payment_hash"]
checking_id = payment_hash
checking_id = base64.b64decode(data["payment_hash"]).hex()
fee_msat = int(data["payment_route"]["total_fees_msat"])
preimage = base64.b64decode(data["payment_preimage"]).hex()
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
checking_id = checking_id.replace("_", "/")
async with httpx.AsyncClient(verify=self.cert) as client:
r = await client.get(
url=f"{self.endpoint}/v1/invoice/{checking_id}", headers=self.auth
@@ -151,10 +148,18 @@ class LndRestWallet(Wallet):
"""
This routine checks the payment status using routerpc.TrackPaymentV2.
"""
# convert checking_id from hex to base64 and some LND magic
try:
checking_id = base64.urlsafe_b64encode(bytes.fromhex(checking_id)).decode(
"ascii"
)
except ValueError:
return PaymentStatus(None)
url = f"{self.endpoint}/v2/router/track/{checking_id}"
# check payment.status:
# https://api.lightning.community/rest/index.html?python#peersynctype
# https://api.lightning.community/?python=#paymentpaymentstatus
statuses = {
"UNKNOWN": None,
"IN_FLIGHT": None,
@@ -178,7 +183,11 @@ class LndRestWallet(Wallet):
return PaymentStatus(None)
payment = line.get("result")
if payment is not None and payment.get("status"):
return PaymentStatus(statuses[payment["status"]])
return PaymentStatus(
paid=statuses[payment["status"]],
fee_msat=payment.get("fee_msat"),
preimage=payment.get("payment_preimage"),
)
else:
return PaymentStatus(None)
except:
@@ -187,10 +196,9 @@ class LndRestWallet(Wallet):
return PaymentStatus(None)
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
url = self.endpoint + "/v1/invoices/subscribe"
while True:
try:
url = self.endpoint + "/v1/invoices/subscribe"
async with httpx.AsyncClient(
timeout=None, headers=self.auth, verify=self.cert
) as client: