fix pyright lnbits/wallets
Co-authored-by: dni ⚡ <office@dnilabs.com>
This commit is contained in:
parent
0607cb1d6e
commit
9c8a79eb9b
|
@ -22,6 +22,8 @@ class ClicheWallet(Wallet):
|
|||
|
||||
def __init__(self):
|
||||
self.endpoint = settings.cliche_endpoint
|
||||
if not self.endpoint:
|
||||
raise Exception("cannot initialize cliche")
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
try:
|
||||
|
@ -36,7 +38,7 @@ class ClicheWallet(Wallet):
|
|||
data = json.loads(r)
|
||||
except:
|
||||
return StatusResponse(
|
||||
f"Failed to connect to {self.endpoint}, got: '{r.text[:200]}...'", 0
|
||||
f"Failed to connect to {self.endpoint}, got: '{r[:200]}...'", 0
|
||||
)
|
||||
|
||||
return StatusResponse(None, data["result"]["wallets"][0]["balance"])
|
||||
|
@ -89,6 +91,13 @@ class ClicheWallet(Wallet):
|
|||
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
||||
ws = create_connection(self.endpoint)
|
||||
ws.send(f"pay-invoice --invoice {bolt11}")
|
||||
checking_id, fee_msat, preimage, error_message, payment_ok = (
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
for _ in range(2):
|
||||
r = ws.recv()
|
||||
data = json.loads(r)
|
||||
|
@ -151,9 +160,9 @@ class ClicheWallet(Wallet):
|
|||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||
while True:
|
||||
try:
|
||||
ws = await create_connection(self.endpoint)
|
||||
ws = create_connection(self.endpoint)
|
||||
while True:
|
||||
r = await ws.recv()
|
||||
r = ws.recv()
|
||||
data = json.loads(r)
|
||||
print(data)
|
||||
try:
|
||||
|
|
|
@ -7,10 +7,7 @@ from typing import AsyncGenerator, Dict, Optional
|
|||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
|
||||
# TODO: https://github.com/lnbits/lnbits/issues/764
|
||||
# mypy https://github.com/aaugustin/websockets/issues/940
|
||||
from websockets import connect # type: ignore
|
||||
from websockets.client import connect
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
|
@ -34,11 +31,13 @@ class UnknownError(Exception):
|
|||
class EclairWallet(Wallet):
|
||||
def __init__(self):
|
||||
url = settings.eclair_url
|
||||
self.url = url[:-1] if url.endswith("/") else url
|
||||
passw = settings.eclair_pass
|
||||
if not url or not passw:
|
||||
raise Exception("cannot initialize eclair")
|
||||
|
||||
self.url = url[:-1] if url.endswith("/") else url
|
||||
self.ws_url = f"ws://{urllib.parse.urlsplit(self.url).netloc}/ws"
|
||||
|
||||
passw = settings.eclair_pass
|
||||
encodedAuth = base64.b64encode(f":{passw}".encode())
|
||||
auth = str(encodedAuth, "utf-8")
|
||||
self.auth = {"Authorization": f"Basic {auth}"}
|
||||
|
@ -71,7 +70,11 @@ class EclairWallet(Wallet):
|
|||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
|
||||
data: Dict = {"amountMsat": amount * 1000}
|
||||
data: Dict = {
|
||||
"amountMsat": amount * 1000,
|
||||
"description_hash": b"",
|
||||
"description": memo,
|
||||
}
|
||||
if kwargs.get("expiry"):
|
||||
data["expireIn"] = kwargs["expiry"]
|
||||
|
||||
|
@ -79,8 +82,6 @@ class EclairWallet(Wallet):
|
|||
data["descriptionHash"] = description_hash.hex()
|
||||
elif unhashed_description:
|
||||
data["descriptionHash"] = hashlib.sha256(unhashed_description).hexdigest()
|
||||
else:
|
||||
data["description"] = memo or ""
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
|
@ -149,6 +150,7 @@ class EclairWallet(Wallet):
|
|||
}
|
||||
|
||||
data = r.json()[-1]
|
||||
fee_msat = 0
|
||||
if data["status"]["type"] == "sent":
|
||||
fee_msat = -data["status"]["feesPaid"]
|
||||
preimage = data["status"]["paymentPreimage"]
|
||||
|
@ -223,10 +225,10 @@ class EclairWallet(Wallet):
|
|||
) as ws:
|
||||
while True:
|
||||
message = await ws.recv()
|
||||
message = json.loads(message)
|
||||
message_json = json.loads(message)
|
||||
|
||||
if message and message["type"] == "payment-received":
|
||||
yield message["paymentHash"]
|
||||
if message_json and message_json["type"] == "payment-received":
|
||||
yield message_json["paymentHash"]
|
||||
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
|
|
|
@ -45,19 +45,18 @@ class FakeWallet(Wallet):
|
|||
) -> InvoiceResponse:
|
||||
data: Dict = {
|
||||
"out": False,
|
||||
"amount": amount,
|
||||
"amount": amount * 1000,
|
||||
"currency": "bc",
|
||||
"privkey": self.privkey,
|
||||
"memo": None,
|
||||
"description_hash": None,
|
||||
"memo": memo,
|
||||
"description_hash": b"",
|
||||
"description": "",
|
||||
"fallback": None,
|
||||
"expires": None,
|
||||
"expires": kwargs.get("expiry"),
|
||||
"timestamp": datetime.now().timestamp(),
|
||||
"route": None,
|
||||
"tags_set": [],
|
||||
}
|
||||
data["expires"] = kwargs.get("expiry")
|
||||
data["amount"] = amount * 1000
|
||||
data["timestamp"] = datetime.now().timestamp()
|
||||
if description_hash:
|
||||
data["tags_set"] = ["h"]
|
||||
data["description_hash"] = description_hash
|
||||
|
@ -69,7 +68,7 @@ class FakeWallet(Wallet):
|
|||
data["memo"] = memo
|
||||
data["description"] = memo
|
||||
randomHash = (
|
||||
data["privkey"][:6]
|
||||
self.privkey[:6]
|
||||
+ hashlib.sha256(str(random.getrandbits(256)).encode()).hexdigest()[6:]
|
||||
)
|
||||
data["paymenthash"] = randomHash
|
||||
|
@ -78,12 +77,10 @@ class FakeWallet(Wallet):
|
|||
|
||||
return InvoiceResponse(True, checking_id, payment_request)
|
||||
|
||||
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
||||
async def pay_invoice(self, bolt11: str, _: int) -> PaymentResponse:
|
||||
invoice = decode(bolt11)
|
||||
if (
|
||||
hasattr(invoice, "checking_id")
|
||||
and invoice.checking_id[:6] == self.privkey[:6] # type: ignore
|
||||
):
|
||||
|
||||
if invoice.checking_id and invoice.checking_id[:6] == self.privkey[:6]:
|
||||
await self.queue.put(invoice)
|
||||
return PaymentResponse(True, invoice.payment_hash, 0)
|
||||
else:
|
||||
|
@ -91,10 +88,10 @@ class FakeWallet(Wallet):
|
|||
ok=False, error_message="Only internal invoices can be used!"
|
||||
)
|
||||
|
||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
async def get_invoice_status(self, _: str) -> PaymentStatus:
|
||||
return PaymentStatus(None)
|
||||
|
||||
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
async def get_payment_status(self, _: str) -> PaymentStatus:
|
||||
return PaymentStatus(None)
|
||||
|
||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||
|
|
|
@ -21,12 +21,13 @@ class LNbitsWallet(Wallet):
|
|||
|
||||
def __init__(self):
|
||||
self.endpoint = settings.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")
|
||||
self.key = {"X-Api-Key": key}
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
|
@ -60,7 +61,7 @@ class LNbitsWallet(Wallet):
|
|||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
data: Dict = {"out": False, "amount": amount}
|
||||
data: Dict = {"out": False, "amount": amount, "memo": memo or ""}
|
||||
if kwargs.get("expiry"):
|
||||
data["expiry"] = kwargs["expiry"]
|
||||
if description_hash:
|
||||
|
@ -68,8 +69,6 @@ class LNbitsWallet(Wallet):
|
|||
if unhashed_description:
|
||||
data["unhashed_description"] = unhashed_description.hex()
|
||||
|
||||
data["memo"] = memo or ""
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
url=f"{self.endpoint}/api/v1/payments", headers=self.key, json=data
|
||||
|
|
|
@ -105,9 +105,6 @@ class LndWallet(Wallet):
|
|||
)
|
||||
|
||||
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
|
||||
|
||||
macaroon = (
|
||||
settings.lnd_grpc_macaroon
|
||||
|
@ -122,8 +119,17 @@ class LndWallet(Wallet):
|
|||
macaroon = AESCipher(description="macaroon decryption").decrypt(
|
||||
encrypted_macaroon
|
||||
)
|
||||
self.macaroon = load_macaroon(macaroon)
|
||||
|
||||
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")
|
||||
|
||||
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()
|
||||
creds = grpc.ssl_channel_credentials(cert)
|
||||
auth_creds = grpc.metadata_call_credentials(self.metadata_callback)
|
||||
|
@ -140,8 +146,6 @@ class LndWallet(Wallet):
|
|||
async def status(self) -> StatusResponse:
|
||||
try:
|
||||
resp = await self.rpc.ChannelBalance(ln.ChannelBalanceRequest())
|
||||
except RpcError as exc:
|
||||
return StatusResponse(str(exc._details), 0)
|
||||
except Exception as exc:
|
||||
return StatusResponse(str(exc), 0)
|
||||
|
||||
|
@ -155,20 +159,23 @@ class LndWallet(Wallet):
|
|||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
params: Dict = {"value": amount, "private": True}
|
||||
data: Dict = {
|
||||
"description_hash": b"",
|
||||
"value": amount,
|
||||
"private": True,
|
||||
"memo": memo or "",
|
||||
}
|
||||
if kwargs.get("expiry"):
|
||||
params["expiry"] = kwargs["expiry"]
|
||||
data["expiry"] = kwargs["expiry"]
|
||||
if description_hash:
|
||||
params["description_hash"] = description_hash
|
||||
data["description_hash"] = description_hash
|
||||
elif unhashed_description:
|
||||
params["description_hash"] = hashlib.sha256(
|
||||
data["description_hash"] = hashlib.sha256(
|
||||
unhashed_description
|
||||
).digest() # as bytes directly
|
||||
else:
|
||||
params["memo"] = memo or ""
|
||||
|
||||
try:
|
||||
req = ln.Invoice(**params)
|
||||
req = ln.Invoice(**data)
|
||||
resp = await self.rpc.AddInvoice(req)
|
||||
except Exception as exc:
|
||||
error_message = str(exc)
|
||||
|
@ -188,8 +195,6 @@ class LndWallet(Wallet):
|
|||
)
|
||||
try:
|
||||
resp = await self.routerpc.SendPaymentV2(req).read()
|
||||
except RpcError as exc:
|
||||
return PaymentResponse(False, None, None, None, exc._details)
|
||||
except Exception as exc:
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
|
||||
|
|
|
@ -43,6 +43,15 @@ class LndRestWallet(Wallet):
|
|||
macaroon = AESCipher(description="macaroon decryption").decrypt(
|
||||
encrypted_macaroon
|
||||
)
|
||||
|
||||
if not endpoint or not macaroon or not settings.lnd_rest_cert:
|
||||
raise Exception("cannot initialize lndrest")
|
||||
|
||||
endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
endpoint = (
|
||||
"https://" + endpoint if not endpoint.startswith("http") else endpoint
|
||||
)
|
||||
self.endpoint = endpoint
|
||||
self.macaroon = load_macaroon(macaroon)
|
||||
|
||||
self.auth = {"Grpc-Metadata-macaroon": self.macaroon}
|
||||
|
@ -74,7 +83,7 @@ class LndRestWallet(Wallet):
|
|||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
data: Dict = {"value": amount, "private": True}
|
||||
data: Dict = {"value": amount, "private": True, "memo": memo or ""}
|
||||
if kwargs.get("expiry"):
|
||||
data["expiry"] = kwargs["expiry"]
|
||||
if description_hash:
|
||||
|
@ -85,8 +94,6 @@ class LndRestWallet(Wallet):
|
|||
data["description_hash"] = base64.b64encode(
|
||||
hashlib.sha256(unhashed_description).digest()
|
||||
).decode("ascii")
|
||||
else:
|
||||
data["memo"] = memo or ""
|
||||
|
||||
async with httpx.AsyncClient(verify=self.cert) as client:
|
||||
r = await client.post(
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
from http import HTTPStatus
|
||||
from typing import AsyncGenerator, Dict, Optional
|
||||
|
||||
import httpx
|
||||
from fastapi.exceptions import HTTPException
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
|
@ -24,8 +20,13 @@ class LNPayWallet(Wallet):
|
|||
|
||||
def __init__(self):
|
||||
endpoint = settings.lnpay_api_endpoint
|
||||
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")
|
||||
|
||||
self.wallet_key = wallet_key
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.wallet_key = settings.lnpay_wallet_key or settings.lnpay_admin_key
|
||||
self.auth = {"X-Api-Key": settings.lnpay_api_key}
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
|
@ -54,7 +55,6 @@ class LNPayWallet(Wallet):
|
|||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
data: Dict = {"num_satoshis": f"{amount}"}
|
||||
if description_hash:
|
||||
|
@ -133,27 +133,27 @@ class LNPayWallet(Wallet):
|
|||
value = await self.queue.get()
|
||||
yield value
|
||||
|
||||
async def webhook_listener(self):
|
||||
text: str = await request.get_data()
|
||||
try:
|
||||
data = json.loads(text)
|
||||
except json.decoder.JSONDecodeError:
|
||||
logger.error(f"got something wrong on lnpay webhook endpoint: {text[:200]}")
|
||||
data = None
|
||||
if (
|
||||
type(data) is not dict
|
||||
or "event" not in data
|
||||
or data["event"].get("name") != "wallet_receive"
|
||||
):
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
# async def webhook_listener(self):
|
||||
# text: str = await request.get_data()
|
||||
# try:
|
||||
# data = json.loads(text)
|
||||
# except json.decoder.JSONDecodeError:
|
||||
# logger.error(f"got something wrong on lnpay webhook endpoint: {text[:200]}")
|
||||
# data = None
|
||||
# if (
|
||||
# type(data) is not dict
|
||||
# or "event" not in data
|
||||
# or data["event"].get("name") != "wallet_receive"
|
||||
# ):
|
||||
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
||||
lntx_id = data["data"]["wtx"]["lnTx"]["id"]
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.get(
|
||||
f"{self.endpoint}/lntx/{lntx_id}?fields=settled", headers=self.auth
|
||||
)
|
||||
data = r.json()
|
||||
if data["settled"]:
|
||||
await self.queue.put(lntx_id)
|
||||
# lntx_id = data["data"]["wtx"]["lnTx"]["id"]
|
||||
# async with httpx.AsyncClient() as client:
|
||||
# r = await client.get(
|
||||
# f"{self.endpoint}/lntx/{lntx_id}?fields=settled", headers=self.auth
|
||||
# )
|
||||
# data = r.json()
|
||||
# if data["settled"]:
|
||||
# await self.queue.put(lntx_id)
|
||||
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
|
|
@ -21,13 +21,14 @@ from .base import (
|
|||
class LnTipsWallet(Wallet):
|
||||
def __init__(self):
|
||||
endpoint = settings.lntips_api_endpoint
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else 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")
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.auth = {"Authorization": f"Basic {key}"}
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
|
@ -53,15 +54,12 @@ class LnTipsWallet(Wallet):
|
|||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
data: Dict = {"amount": amount}
|
||||
data: Dict = {"amount": amount, "description_hash": "", "memo": memo or ""}
|
||||
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 ""
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import asyncio
|
||||
import hmac
|
||||
from http import HTTPStatus
|
||||
|
||||
# import hmac
|
||||
# from http import HTTPStatus
|
||||
from typing import AsyncGenerator, Optional
|
||||
|
||||
import httpx
|
||||
from fastapi.exceptions import HTTPException
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
|
@ -18,19 +17,24 @@ from .base import (
|
|||
Wallet,
|
||||
)
|
||||
|
||||
# from fastapi import Request, HTTPException
|
||||
# from loguru import logger
|
||||
|
||||
|
||||
class OpenNodeWallet(Wallet):
|
||||
"""https://developers.opennode.com/"""
|
||||
|
||||
def __init__(self):
|
||||
endpoint = settings.opennode_api_endpoint
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
|
||||
key = (
|
||||
settings.opennode_key
|
||||
or settings.opennode_admin_key
|
||||
or settings.opennode_invoice_key
|
||||
)
|
||||
if not endpoint or not key:
|
||||
raise Exception("cannot initialize opennode")
|
||||
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.auth = {"Authorization": key}
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
|
@ -54,7 +58,6 @@ class OpenNodeWallet(Wallet):
|
|||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
if description_hash or unhashed_description:
|
||||
raise Unsupported("description_hash")
|
||||
|
@ -139,17 +142,17 @@ class OpenNodeWallet(Wallet):
|
|||
value = await self.queue.get()
|
||||
yield value
|
||||
|
||||
async def webhook_listener(self):
|
||||
data = await request.form
|
||||
if "status" not in data or data["status"] != "paid":
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
# async def webhook_listener(self):
|
||||
# data = await request.form
|
||||
# if "status" not in data or data["status"] != "paid":
|
||||
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
||||
charge_id = data["id"]
|
||||
x = hmac.new(self.auth["Authorization"].encode("ascii"), digestmod="sha256")
|
||||
x.update(charge_id.encode("ascii"))
|
||||
if x.hexdigest() != data["hashed_order"]:
|
||||
logger.error("invalid webhook, not from opennode")
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
# charge_id = data["id"]
|
||||
# x = hmac.new(self.auth["Authorization"].encode("ascii"), digestmod="sha256")
|
||||
# x.update(charge_id.encode("ascii"))
|
||||
# if x.hexdigest() != data["hashed_order"]:
|
||||
# logger.error("invalid webhook, not from opennode")
|
||||
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
||||
await self.queue.put(charge_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
# await self.queue.put(charge_id)
|
||||
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
|
|
@ -28,6 +28,7 @@ class UnknownError(Exception):
|
|||
|
||||
class SparkWallet(Wallet):
|
||||
def __init__(self):
|
||||
assert settings.spark_url
|
||||
self.url = settings.spark_url.replace("/rpc", "")
|
||||
self.token = settings.spark_token
|
||||
|
||||
|
@ -46,6 +47,7 @@ class SparkWallet(Wallet):
|
|||
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
assert self.token
|
||||
r = await client.post(
|
||||
self.url + "/rpc",
|
||||
headers={"X-Access": self.token},
|
||||
|
@ -133,38 +135,49 @@ class SparkWallet(Wallet):
|
|||
bolt11=bolt11,
|
||||
maxfee=fee_limit_msat,
|
||||
)
|
||||
fee_msat = -int(r["msatoshi_sent"] - r["msatoshi"])
|
||||
preimage = r["payment_preimage"]
|
||||
return PaymentResponse(True, r["payment_hash"], fee_msat, preimage, None)
|
||||
|
||||
except (SparkError, UnknownError) as exc:
|
||||
listpays = await self.listpays(bolt11)
|
||||
if listpays:
|
||||
pays = listpays["pays"]
|
||||
if not listpays:
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
|
||||
if len(pays) == 0:
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
pays = listpays["pays"]
|
||||
|
||||
pay = pays[0]
|
||||
payment_hash = pay["payment_hash"]
|
||||
if len(pays) == 0:
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
|
||||
if len(pays) > 1:
|
||||
raise SparkError(
|
||||
f"listpays({payment_hash}) returned an unexpected response: {listpays}"
|
||||
)
|
||||
pay = pays[0]
|
||||
payment_hash = pay["payment_hash"]
|
||||
|
||||
if pay["status"] == "failed":
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
elif pay["status"] == "pending":
|
||||
return PaymentResponse(None, payment_hash, None, None, None)
|
||||
elif pay["status"] == "complete":
|
||||
r = pay
|
||||
r["payment_preimage"] = pay["preimage"]
|
||||
r["msatoshi"] = int(pay["amount_msat"][0:-4])
|
||||
r["msatoshi_sent"] = int(pay["amount_sent_msat"][0:-4])
|
||||
# this may result in an error if it was paid previously
|
||||
# our database won't allow the same payment_hash to be added twice
|
||||
# this is good
|
||||
if len(pays) > 1:
|
||||
raise SparkError(
|
||||
f"listpays({payment_hash}) returned an unexpected response: {listpays}"
|
||||
)
|
||||
|
||||
fee_msat = -int(r["msatoshi_sent"] - r["msatoshi"])
|
||||
preimage = r["payment_preimage"]
|
||||
return PaymentResponse(True, r["payment_hash"], fee_msat, preimage, None)
|
||||
if pay["status"] == "failed":
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
|
||||
elif pay["status"] == "pending":
|
||||
return PaymentResponse(None, payment_hash, None, None, None)
|
||||
|
||||
elif pay["status"] == "complete":
|
||||
r = pay
|
||||
r["payment_preimage"] = pay["preimage"]
|
||||
r["msatoshi"] = int(pay["amount_msat"][0:-4])
|
||||
r["msatoshi_sent"] = int(pay["amount_sent_msat"][0:-4])
|
||||
# this may result in an error if it was paid previously
|
||||
# our database won't allow the same payment_hash to be added twice
|
||||
# this is good
|
||||
fee_msat = -int(r["msatoshi_sent"] - r["msatoshi"])
|
||||
preimage = r["payment_preimage"]
|
||||
return PaymentResponse(
|
||||
True, r["payment_hash"], fee_msat, preimage, None
|
||||
)
|
||||
else:
|
||||
return PaymentResponse(False, None, None, None, str(exc))
|
||||
|
||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue
Block a user