Browse Source

add spark backend and fix c-lightning.

aiosqlite
fiatjaf 4 years ago
parent
commit
0de08dda0b
  1. 5
      docs/guide/wallets.md
  2. 1
      lnbits/wallets/__init__.py
  3. 24
      lnbits/wallets/clightning.py
  4. 86
      lnbits/wallets/spark.py

5
docs/guide/wallets.md

@ -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)

1
lnbits/wallets/__init__.py

@ -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

24
lnbits/wallets/clightning.py

@ -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

@ -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")
Loading…
Cancel
Save