add spark backend and fix c-lightning.

This commit is contained in:
fiatjaf 2020-08-29 12:23:01 -03:00
parent a79ec8f4a4
commit 0de08dda0b
4 changed files with 107 additions and 9 deletions

View file

@ -21,6 +21,11 @@ Using this wallet requires the installation of the `pylightning` Python package.
- `LNBITS_BACKEND_WALLET_CLASS`: **CLightningWallet** - `LNBITS_BACKEND_WALLET_CLASS`: **CLightningWallet**
- `CLIGHTNING_RPC`: /file/path/lightning-rpc - `CLIGHTNING_RPC`: /file/path/lightning-rpc
### Spark (c-lightning)
- `LNBITS_BACKEND_WALLET_CLASS`: **SparkWallet**
- `SPARK_URL`: http://10.147.17.230:9737/rpc
- `SPARK_TOKEN`: secret_access_key
### LND (gRPC) ### LND (gRPC)

View file

@ -7,3 +7,4 @@ from .opennode import OpenNodeWallet
from .lnpay import LNPayWallet from .lnpay import LNPayWallet
from .lnbits import LNbitsWallet from .lnbits import LNbitsWallet
from .lndrest import LndRestWallet from .lndrest import LndRestWallet
from .spark import SparkWallet

View file

@ -28,20 +28,26 @@ class CLightningWallet(Wallet):
def pay_invoice(self, bolt11: str) -> PaymentResponse: def pay_invoice(self, bolt11: str) -> PaymentResponse:
r = self.l1.pay(bolt11) r = self.l1.pay(bolt11)
ok, checking_id, fee_msat, error_message = True, None, 0, None ok, checking_id, fee_msat, error_message = True, r["payment_hash"], r["msatoshi_sent"] - r["msatoshi"], None
return PaymentResponse(ok, checking_id, fee_msat, error_message) return PaymentResponse(ok, checking_id, fee_msat, error_message)
def get_invoice_status(self, checking_id: str) -> PaymentStatus: def get_invoice_status(self, checking_id: str) -> PaymentStatus:
r = self.l1.listinvoices(checking_id) r = self.l1.listinvoices(checking_id)
if r["invoices"][0]["status"] == "unpaid": if not r["invoices"]:
return PaymentStatus(False) return PaymentStatus(False)
return PaymentStatus(True) if r["invoices"][0]["label"] == checking_id:
return PaymentStatus(r["pays"][0]["status"] == "paid")
raise KeyError("supplied an invalid checking_id")
def get_payment_status(self, checking_id: str) -> PaymentStatus: def get_payment_status(self, checking_id: str) -> PaymentStatus:
r = self.l1.listsendpays(checking_id) r = self.l1.listpays(payment_hash=checking_id)
if not r.ok: if not r["pays"]:
return PaymentStatus(False)
if r["pays"][0]["payment_hash"] == checking_id:
status = r["pays"][0]["status"]
if status == "complete":
return PaymentStatus(True)
elif status == "failed":
return PaymentStatus(False)
return PaymentStatus(None) return PaymentStatus(None)
payments = [p for p in r.json()["payments"] if p["payment_hash"] == checking_id] raise KeyError("supplied an invalid checking_id")
payment = payments[0] if payments else None
statuses = {"UNKNOWN": None, "IN_FLIGHT": None, "SUCCEEDED": True, "FAILED": False}
return PaymentStatus(statuses[payment["status"]] if payment else None)

86
lnbits/wallets/spark.py Normal file
View file

@ -0,0 +1,86 @@
import random
import requests
from os import getenv
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
class SparkError(Exception):
pass
class UnknownError(Exception):
pass
class SparkWallet(Wallet):
def __init__(self):
self.url = getenv("SPARK_URL")
self.token = getenv("SPARK_TOKEN")
def __getattr__(self, key):
def call(*args, **kwargs):
if args and kwargs:
raise TypeError(f"must supply either named arguments or a list of arguments, not both: {args} {kwargs}")
elif args:
params = args
elif kwargs:
params = kwargs
r = requests.post(self.url, headers={"X-Access": self.token}, json={"method": key, "params": params})
try:
data = r.json()
except:
raise UnknownError(r.text)
if not r.ok:
raise SparkError(data["message"])
return data
return call
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse:
label = "lbs{}".format(random.random())
print(description_hash, len(description_hash))
try:
if description_hash:
r = self.invoicewithdescriptionhash(
msatoshi=amount * 1000, label=label, description_hash=description_hash.hex(),
)
else:
r = self.invoice(msatoshi=amount * 1000, label=label, description=memo, exposeprivatechannels=True)
ok, checking_id, payment_request, error_message = True, label, r["bolt11"], None
except (SparkError, UnknownError) as e:
ok, checking_id, payment_request, error_message = False, None, None, str(e)
return InvoiceResponse(ok, checking_id, payment_request, error_message)
def pay_invoice(self, bolt11: str) -> PaymentResponse:
try:
r = self.pay(bolt11)
ok, checking_id, fee_msat, error_message = True, r["payment_hash"], r["msatoshi_sent"] - r["msatoshi"], None
except (SparkError, UnknownError) as e:
ok, checking_id, fee_msat, error_message = False, None, None, str(e)
return PaymentResponse(ok, checking_id, fee_msat, error_message)
def get_invoice_status(self, checking_id: str) -> PaymentStatus:
r = self.listinvoices(label=checking_id)
if not r or not r.get("invoices"):
return PaymentStatus(None)
if r["invoices"][0]["status"] == "unpaid":
return PaymentStatus(False)
return PaymentStatus(True)
def get_payment_status(self, checking_id: str) -> PaymentStatus:
r = self.listpays(payment_hash=checking_id)
if not r["pays"]:
return PaymentStatus(False)
if r["pays"][0]["payment_hash"] == checking_id:
status = r["pays"][0]["status"]
if status == "complete":
return PaymentStatus(True)
elif status == "failed":
return PaymentStatus(False)
return PaymentStatus(None)
raise KeyError("supplied an invalid checking_id")