Wallets refactor (#1729)

* feat: cleanup function for wallet

* update eclair implementation

* update lnd implementation

* update lnbits implementation

* update lnpay implementation

* update lnbits implementation

* update opennode implementation

* update spark implementation

* use base_url for clients

* fix lnpay

* fix opennode

* fix lntips

* test real invoice creation

* add small delay to test

* test paid invoice stream

* fix lnbits

* fix lndrest

* fix spark

fix spark

* check node balance in test

* increase balance check delay

* check balance in pay test aswell

* make sure get_payment_status is called

* fix lndrest

* revert unnecessary changes
This commit is contained in:
jackstar12
2023-06-19 12:12:00 +02:00
committed by GitHub
parent 49411e58cc
commit e6499104c0
11 changed files with 259 additions and 262 deletions
+51 -62
View File
@@ -64,14 +64,17 @@ class LndRestWallet(Wallet):
self.cert = cert or True
self.auth = {"Grpc-Metadata-macaroon": self.macaroon}
self.client = httpx.AsyncClient(
base_url=self.endpoint, headers=self.auth, verify=self.cert
)
async def cleanup(self):
await self.client.aclose()
async def status(self) -> StatusResponse:
try:
async with httpx.AsyncClient(verify=self.cert) as client:
r = await client.get(
f"{self.endpoint}/v1/balance/channels", headers=self.auth
)
r.raise_for_status()
r = await self.client.get("/v1/balance/channels")
r.raise_for_status()
except (httpx.ConnectError, httpx.RequestError) as exc:
return StatusResponse(f"Unable to connect to {self.endpoint}. {exc}", 0)
@@ -104,10 +107,7 @@ class LndRestWallet(Wallet):
hashlib.sha256(unhashed_description).digest()
).decode("ascii")
async with httpx.AsyncClient(verify=self.cert) as client:
r = await client.post(
url=f"{self.endpoint}/v1/invoices", headers=self.auth, json=data
)
r = await self.client.post(url="/v1/invoices", json=data)
if r.is_error:
error_message = r.text
@@ -125,17 +125,15 @@ class LndRestWallet(Wallet):
return InvoiceResponse(True, checking_id, payment_request, None)
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
async with httpx.AsyncClient(verify=self.cert) as client:
# set the fee limit for the payment
lnrpcFeeLimit = dict()
lnrpcFeeLimit["fixed_msat"] = f"{fee_limit_msat}"
# set the fee limit for the payment
lnrpcFeeLimit = dict()
lnrpcFeeLimit["fixed_msat"] = f"{fee_limit_msat}"
r = await client.post(
url=f"{self.endpoint}/v1/channels/transactions",
headers=self.auth,
json={"payment_request": bolt11, "fee_limit": lnrpcFeeLimit},
timeout=None,
)
r = await self.client.post(
url="/v1/channels/transactions",
json={"payment_request": bolt11, "fee_limit": lnrpcFeeLimit},
timeout=None,
)
if r.is_error or r.json().get("payment_error"):
error_message = r.json().get("payment_error") or r.text
@@ -148,10 +146,7 @@ class LndRestWallet(Wallet):
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
async with httpx.AsyncClient(verify=self.cert) as client:
r = await client.get(
url=f"{self.endpoint}/v1/invoice/{checking_id}", headers=self.auth
)
r = await self.client.get(url=f"/v1/invoice/{checking_id}")
if r.is_error or not r.json().get("settled"):
# this must also work when checking_id is not a hex recognizable by lnd
@@ -172,7 +167,7 @@ class LndRestWallet(Wallet):
except ValueError:
return PaymentStatus(None)
url = f"{self.endpoint}/v2/router/track/{checking_id}"
url = f"/v2/router/track/{checking_id}"
# check payment.status:
# https://api.lightning.community/?python=#paymentpaymentstatus
@@ -183,52 +178,46 @@ class LndRestWallet(Wallet):
"FAILED": False,
}
async with httpx.AsyncClient(
timeout=None, headers=self.auth, verify=self.cert
) as client:
async with client.stream("GET", url) as r:
async for json_line in r.aiter_lines():
try:
line = json.loads(json_line)
if line.get("error"):
logger.error(
line["error"]["message"]
if "message" in line["error"]
else line["error"]
)
return PaymentStatus(None)
payment = line.get("result")
if payment is not None and payment.get("status"):
return PaymentStatus(
paid=statuses[payment["status"]],
fee_msat=payment.get("fee_msat"),
preimage=payment.get("payment_preimage"),
)
else:
return PaymentStatus(None)
except:
continue
async with self.client.stream("GET", url, timeout=None) as r:
async for json_line in r.aiter_lines():
try:
line = json.loads(json_line)
if line.get("error"):
logger.error(
line["error"]["message"]
if "message" in line["error"]
else line["error"]
)
return PaymentStatus(None)
payment = line.get("result")
if payment is not None and payment.get("status"):
return PaymentStatus(
paid=statuses[payment["status"]],
fee_msat=payment.get("fee_msat"),
preimage=payment.get("payment_preimage"),
)
else:
return PaymentStatus(None)
except:
continue
return PaymentStatus(None)
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True:
try:
url = self.endpoint + "/v1/invoices/subscribe"
async with httpx.AsyncClient(
timeout=None, headers=self.auth, verify=self.cert
) as client:
async with client.stream("GET", url) as r:
async for line in r.aiter_lines():
try:
inv = json.loads(line)["result"]
if not inv["settled"]:
continue
except:
url = "/v1/invoices/subscribe"
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 not inv["settled"]:
continue
except:
continue
payment_hash = base64.b64decode(inv["r_hash"]).hex()
yield payment_hash
payment_hash = base64.b64decode(inv["r_hash"]).hex()
yield payment_hash
except Exception as exc:
logger.error(
f"lost connection to lnd invoices stream: '{exc}', retrying in 5 seconds"