From 824a8fa7c8fbd4fc477697be32d65c3b5a5a2087 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Sun, 24 Dec 2023 14:23:21 +0100 Subject: [PATCH] refactor __init__ functions of Wallets (funding sources) - better error messages when a conf variable is not provided - unify approaches among different source files --- lnbits/wallets/alby.py | 9 +++---- lnbits/wallets/cliche.py | 5 ++-- lnbits/wallets/corelightning.py | 8 +++++-- lnbits/wallets/corelightningrest.py | 27 +++++++++++++-------- lnbits/wallets/eclair.py | 12 ++++++---- lnbits/wallets/lnbits.py | 12 +++++++--- lnbits/wallets/lndgrpc.py | 29 ++++++++++++++-------- lnbits/wallets/lndrest.py | 37 ++++++++++++++++------------- lnbits/wallets/lnpay.py | 19 +++++++++++---- lnbits/wallets/lntips.py | 14 ++++++++--- lnbits/wallets/opennode.py | 16 +++++++++---- lnbits/wallets/spark.py | 12 ++++++---- 12 files changed, 131 insertions(+), 69 deletions(-) diff --git a/lnbits/wallets/alby.py b/lnbits/wallets/alby.py index e0eaab41b..d2f240d7d 100644 --- a/lnbits/wallets/alby.py +++ b/lnbits/wallets/alby.py @@ -20,11 +20,12 @@ class AlbyWallet(Wallet): """https://guides.getalby.com/alby-wallet-api/reference/api-reference""" def __init__(self): + if not settings.alby_api_endpoint: + raise ValueError("cannot initialize AlbyWallet: missing alby_api_endpoint") + if not settings.alby_access_token: + raise ValueError("cannot initialize AlbyWallet: missing alby_access_token") + endpoint = settings.alby_api_endpoint - - if not endpoint or not settings.alby_access_token: - raise Exception("cannot initialize getalby") - self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint self.auth = { "Authorization": "Bearer " + settings.alby_access_token, diff --git a/lnbits/wallets/cliche.py b/lnbits/wallets/cliche.py index 36894d0ee..d42e92059 100644 --- a/lnbits/wallets/cliche.py +++ b/lnbits/wallets/cliche.py @@ -21,9 +21,10 @@ class ClicheWallet(Wallet): """https://github.com/fiatjaf/cliche""" def __init__(self): + if not settings.cliche_endpoint: + raise ValueError("cannot initialize ClicheWallet: missing cliche_endpoint") + self.endpoint = settings.cliche_endpoint - if not self.endpoint: - raise Exception("cannot initialize cliche") async def status(self) -> StatusResponse: try: diff --git a/lnbits/wallets/corelightning.py b/lnbits/wallets/corelightning.py index 7e8385c7b..d9cdff810 100644 --- a/lnbits/wallets/corelightning.py +++ b/lnbits/wallets/corelightning.py @@ -29,9 +29,13 @@ class CoreLightningWallet(Wallet): __node_cls__ = CoreLightningNode def __init__(self): - self.rpc = settings.corelightning_rpc or settings.clightning_rpc - self.ln = LightningRpc(self.rpc) + rpc = settings.corelightning_rpc or settings.clightning_rpc + if not rpc: + raise ValueError( + "cannot initialize CoreLightningWallet: missing corelightning_rpc" + ) + self.ln = LightningRpc(rpc) # check if description_hash is supported (from corelightning>=v0.11.0) command = self.ln.help("invoice")["help"][0]["command"] # type: ignore self.supports_description_hash = "deschashonly" in command diff --git a/lnbits/wallets/corelightningrest.py b/lnbits/wallets/corelightningrest.py index 461ba726e..def252b08 100644 --- a/lnbits/wallets/corelightningrest.py +++ b/lnbits/wallets/corelightningrest.py @@ -23,23 +23,30 @@ from .macaroon import load_macaroon class CoreLightningRestWallet(Wallet): def __init__(self): - macaroon = settings.corelightning_rest_macaroon - assert macaroon, "missing cln-rest macaroon" - - self.macaroon = load_macaroon(macaroon) + if not settings.corelightning_rest_url: + raise ValueError( + "cannot initialize CoreLightningRestWallet: " + "missing corelightning_rest_url" + ) + if not settings.corelightning_rest_macaroon: + raise ValueError( + "cannot initialize CoreLightningRestWallet: " + "missing corelightning_rest_macaroon" + ) + macaroon = load_macaroon(settings.corelightning_rest_macaroon) + if not macaroon: + raise ValueError( + "cannot initialize CoreLightningRestWallet: " + "invalid corelightning_rest_macaroon provided" + ) url = settings.corelightning_rest_url - if not url: - raise Exception("missing url for corelightning-rest") - if not macaroon: - raise Exception("missing macaroon for corelightning-rest") - self.url = url[:-1] if url.endswith("/") else url self.url = ( f"https://{self.url}" if not self.url.startswith("http") else self.url ) headers = { - "macaroon": self.macaroon, + "macaroon": macaroon, "encodingtype": "hex", "accept": "application/json", "User-Agent": settings.user_agent, diff --git a/lnbits/wallets/eclair.py b/lnbits/wallets/eclair.py index b96ee043b..3e196a165 100644 --- a/lnbits/wallets/eclair.py +++ b/lnbits/wallets/eclair.py @@ -30,15 +30,17 @@ class UnknownError(Exception): class EclairWallet(Wallet): def __init__(self): - url = settings.eclair_url - passw = settings.eclair_pass - if not url or not passw: - raise Exception("cannot initialize eclair") + if not settings.eclair_url: + raise ValueError("cannot initialize EclairWallet: missing eclair_url") + if not settings.eclair_pass: + raise ValueError("cannot initialize EclairWallet: missing eclair_pass") + url = settings.eclair_url self.url = url[:-1] if url.endswith("/") else url self.ws_url = f"ws://{urllib.parse.urlsplit(self.url).netloc}/ws" - encodedAuth = base64.b64encode(f":{passw}".encode()) + password = settings.eclair_pass + encodedAuth = base64.b64encode(f":{password}".encode()) auth = str(encodedAuth, "utf-8") self.headers = { "Authorization": f"Basic {auth}", diff --git a/lnbits/wallets/lnbits.py b/lnbits/wallets/lnbits.py index 7e05526f7..ffe083845 100644 --- a/lnbits/wallets/lnbits.py +++ b/lnbits/wallets/lnbits.py @@ -20,14 +20,20 @@ class LNbitsWallet(Wallet): """https://github.com/lnbits/lnbits""" def __init__(self): - self.endpoint = settings.lnbits_endpoint + if not settings.lnbits_endpoint: + raise ValueError("cannot initialize LNbitsWallet: missing lnbits_endpoint") key = ( settings.lnbits_key or settings.lnbits_admin_key or settings.lnbits_invoice_key ) - if not self.endpoint or not key: - raise Exception("cannot initialize lnbits wallet") + if not key: + raise ValueError( + "cannot initialize LNbitsWallet: " + "missing lnbits_key or lnbits_admin_key or lnbits_invoice_key" + ) + endpoint = settings.lnbits_endpoint + self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint self.headers = {"X-Api-Key": key, "User-Agent": settings.user_agent} self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.headers) diff --git a/lnbits/wallets/lndgrpc.py b/lnbits/wallets/lndgrpc.py index df385117b..4b76defb1 100644 --- a/lnbits/wallets/lndgrpc.py +++ b/lnbits/wallets/lndgrpc.py @@ -58,7 +58,16 @@ environ["GRPC_SSL_CIPHER_SUITES"] = "HIGH+ECDSA" class LndWallet(Wallet): def __init__(self): - endpoint = settings.lnd_grpc_endpoint + if not settings.lnd_grpc_endpoint: + raise ValueError("cannot initialize LndWallet: missing lnd_grpc_endpoint") + if not settings.lnd_grpc_port: + raise ValueError("cannot initialize LndWallet: missing lnd_grpc_port") + + cert_path = settings.lnd_grpc_cert or settings.lnd_cert + if not cert_path: + raise ValueError( + "cannot initialize LndWallet: missing lnd_grpc_cert or lnd_cert" + ) macaroon = ( settings.lnd_grpc_macaroon @@ -67,24 +76,24 @@ class LndWallet(Wallet): or settings.lnd_grpc_invoice_macaroon or settings.lnd_invoice_macaroon ) - encrypted_macaroon = settings.lnd_grpc_macaroon_encrypted if encrypted_macaroon: macaroon = AESCipher(description="macaroon decryption").decrypt( encrypted_macaroon ) + if not macaroon: + raise ValueError( + "cannot initialize LndWallet: " + "missing lnd_grpc_macaroon or lnd_grpc_admin_macaroon or " + "lnd_admin_macaroon or lnd_grpc_invoice_macaroon or " + "lnd_invoice_macaroon or lnd_grpc_macaroon_encrypted" + ) - cert_path = settings.lnd_grpc_cert or settings.lnd_cert - if not endpoint or not macaroon or not cert_path or not settings.lnd_grpc_port: - raise Exception("cannot initialize lndrest") - + endpoint = settings.lnd_grpc_endpoint self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint self.port = int(settings.lnd_grpc_port) - self.cert_path = settings.lnd_grpc_cert or settings.lnd_cert - self.macaroon = load_macaroon(macaroon) - self.cert_path = cert_path - cert = open(self.cert_path, "rb").read() + cert = open(cert_path, "rb").read() creds = grpc.ssl_channel_credentials(cert) auth_creds = grpc.metadata_call_credentials(self.metadata_callback) composite_creds = grpc.composite_channel_credentials(creds, auth_creds) diff --git a/lnbits/wallets/lndrest.py b/lnbits/wallets/lndrest.py index d50b548e1..056734752 100644 --- a/lnbits/wallets/lndrest.py +++ b/lnbits/wallets/lndrest.py @@ -27,8 +27,10 @@ class LndRestWallet(Wallet): __node_cls__ = LndRestNode def __init__(self): - endpoint = settings.lnd_rest_endpoint - cert = settings.lnd_rest_cert + if not settings.lnd_rest_endpoint: + raise ValueError( + "cannot initialize LndRestWallet: missing lnd_rest_endpoint" + ) macaroon = ( settings.lnd_rest_macaroon @@ -37,43 +39,44 @@ class LndRestWallet(Wallet): or settings.lnd_invoice_macaroon or settings.lnd_rest_invoice_macaroon ) - encrypted_macaroon = settings.lnd_rest_macaroon_encrypted if encrypted_macaroon: macaroon = AESCipher(description="macaroon decryption").decrypt( encrypted_macaroon ) - - if not endpoint: - raise Exception("cannot initialize lndrest: no endpoint") - if not macaroon: - raise Exception("cannot initialize lndrest: no macaroon") - - if not cert: - logger.warning( - "no certificate for lndrest provided, this only works if you have a" - " publicly issued certificate" + raise ValueError( + "cannot initialize LndRestWallet: " + "missing lnd_rest_macaroon or lnd_admin_macaroon or " + "lnd_rest_admin_macaroon or lnd_invoice_macaroon or " + "lnd_rest_invoice_macaroon or lnd_rest_macaroon_encrypted" ) + if not settings.lnd_rest_cert: + logger.warning( + "No certificate for LndRestWallet provided! " + "This only works if you have a publicly issued certificate." + ) + + endpoint = settings.lnd_rest_endpoint endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint endpoint = ( f"https://{endpoint}" if not endpoint.startswith("http") else endpoint ) self.endpoint = endpoint - self.macaroon = load_macaroon(macaroon) # if no cert provided it should be public so we set verify to True # and it will still check for validity of certificate and fail if its not valid # even on startup - self.cert = cert or True + cert = settings.lnd_rest_cert or True + macaroon = load_macaroon(macaroon) headers = { - "Grpc-Metadata-macaroon": self.macaroon, + "Grpc-Metadata-macaroon": macaroon, "User-Agent": settings.user_agent, } self.client = httpx.AsyncClient( - base_url=self.endpoint, headers=headers, verify=self.cert + base_url=self.endpoint, headers=headers, verify=cert ) async def cleanup(self): diff --git a/lnbits/wallets/lnpay.py b/lnbits/wallets/lnpay.py index 7640668ba..b0210ffb9 100644 --- a/lnbits/wallets/lnpay.py +++ b/lnbits/wallets/lnpay.py @@ -20,13 +20,22 @@ class LNPayWallet(Wallet): """https://docs.lnpay.co/""" def __init__(self): - endpoint = settings.lnpay_api_endpoint + if not settings.lnpay_api_endpoint: + raise ValueError( + "cannot initialize LNPayWallet: missing lnpay_api_endpoint" + ) + if not settings.lnpay_api_key: + raise ValueError("cannot initialize LNPayWallet: missing lnpay_api_key") + wallet_key = settings.lnpay_wallet_key or settings.lnpay_admin_key - - if not endpoint or not wallet_key or not settings.lnpay_api_key: - raise Exception("cannot initialize lnpay") - + if not wallet_key: + raise ValueError( + "cannot initialize LNPayWallet: " + "missing lnpay_wallet_key or lnpay_admin_key" + ) self.wallet_key = wallet_key + + endpoint = settings.lnpay_api_endpoint self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint headers = { "X-Api-Key": settings.lnpay_api_key, diff --git a/lnbits/wallets/lntips.py b/lnbits/wallets/lntips.py index 9760162f1..c492916c4 100644 --- a/lnbits/wallets/lntips.py +++ b/lnbits/wallets/lntips.py @@ -20,14 +20,22 @@ from .base import ( class LnTipsWallet(Wallet): def __init__(self): - endpoint = settings.lntips_api_endpoint + if not settings.lntips_api_endpoint: + raise ValueError( + "cannot initialize LnTipsWallet: missing lntips_api_endpoint" + ) key = ( settings.lntips_api_key or settings.lntips_admin_key or settings.lntips_invoice_key ) - if not endpoint or not key: - raise Exception("cannot initialize lntxbod") + if not key: + raise ValueError( + "cannot initialize LnTipsWallet: " + "missing lntips_api_key or lntips_admin_key or lntips_invoice_key" + ) + + endpoint = settings.lntips_api_endpoint self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint headers = { "Authorization": f"Basic {key}", diff --git a/lnbits/wallets/opennode.py b/lnbits/wallets/opennode.py index f0be68382..a263fcbaf 100644 --- a/lnbits/wallets/opennode.py +++ b/lnbits/wallets/opennode.py @@ -20,15 +20,23 @@ class OpenNodeWallet(Wallet): """https://developers.opennode.com/""" def __init__(self): - endpoint = settings.opennode_api_endpoint - self.key = ( + if not settings.opennode_api_endpoint: + raise ValueError( + "cannot initialize OpenNodeWallet: missing opennode_api_endpoint" + ) + key = ( settings.opennode_key or settings.opennode_admin_key or settings.opennode_invoice_key ) - if not endpoint or not self.key: - raise Exception("cannot initialize opennode") + if not key: + raise ValueError( + "cannot initialize OpenNodeWallet: " + "missing opennode_key or opennode_admin_key or opennode_invoice_key" + ) + self.key = key + endpoint = settings.opennode_api_endpoint self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint headers = { "Authorization": self.key, diff --git a/lnbits/wallets/spark.py b/lnbits/wallets/spark.py index 09002be14..c39bfdc31 100644 --- a/lnbits/wallets/spark.py +++ b/lnbits/wallets/spark.py @@ -28,12 +28,16 @@ class UnknownError(Exception): class SparkWallet(Wallet): def __init__(self): - assert settings.spark_url, "spark url does not exist" - self.url = settings.spark_url.replace("/rpc", "") + if not settings.spark_url: + raise ValueError("cannot initialize SparkWallet: missing spark_url") + if not settings.spark_token: + raise ValueError("cannot initialize SparkWallet: missing spark_token") + + url = settings.spark_url.replace("/rpc", "") self.token = settings.spark_token - assert self.token, "spark wallet token does not exist" + headers = {"X-Access": self.token, "User-Agent": settings.user_agent} - self.client = httpx.AsyncClient(base_url=self.url, headers=headers) + self.client = httpx.AsyncClient(base_url=url, headers=headers) async def cleanup(self): try: