diff --git a/.env.example b/.env.example index 4cb673f..e84d2ec 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,6 @@ FLASK_APP=lnbits FLASK_ENV=development + +LNTXBOT_API_ENDPOINT=https://lntxbot.bigsun.xyz/ +LNTXBOT_ADMIN_KEY=LNTXBOT_ADMIN_KEY +LNTXBOT_INVOICE_KEY=LNTXBOT_INVOICE_KEY diff --git a/.gitignore b/.gitignore index 3df213b..23ee9c3 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ Pipfile.lock *.pyo *.pyc *.env +.env venv database.sqlite3 diff --git a/LNbits/__init__.py b/LNbits/__init__.py index f4d57d6..fc51303 100644 --- a/LNbits/__init__.py +++ b/LNbits/__init__.py @@ -7,7 +7,7 @@ from flask import Flask, jsonify, render_template, request from . import bolt11 from .db import Database from .helpers import encrypt -from .settings import INVOICE_KEY, ADMIN_KEY, API_ENDPOINT, DATABASE_PATH, LNBITS_PATH +from .settings import DATABASE_PATH, LNBITS_PATH, WALLET app = Flask(__name__) @@ -70,10 +70,7 @@ def lnurlwallet(): k1 = data["k1"] # get invoice - dataj = {"amt": str(withdraw)} - headers = {"Authorization": "Basic %s" % INVOICE_KEY} - rr = requests.post(url=API_ENDPOINT + "/addinvoice", json=dataj, headers=headers) - + rr = WALLET.create_invoice(withdraw) dataa = rr.json() # get callback @@ -93,7 +90,7 @@ def lnurlwallet(): data = "" while data == "": - r = requests.post(url=API_ENDPOINT + "/invoicestatus/" + str(payment_hash), headers=headers) + r = WALLET.get_invoice_status(payment_hash) data = r.json() print(r.json()) @@ -264,11 +261,7 @@ def api_invoices(): if not wallet_row: return jsonify({"ERROR": "NO KEY"}), 200 - r = requests.post( - url=f"{API_ENDPOINT}/addinvoice", - json={"amt": postedjson["value"], "memo": postedjson["memo"]}, - headers={"Authorization": f"Basic {INVOICE_KEY}"}, - ) + r = WALLET.create_invoice(postedjson["value"], postedjson["memo"]) data = r.json() pay_req = data["pay_req"] @@ -349,11 +342,8 @@ def api_transactions(): return jsonify({"ERROR": "INSUFFICIENT BALANCE"}), 403 # actually send the payment - r = requests.post( - url=f"{API_ENDPOINT}/payinvoice", - json={"invoice": data["payment_request"]}, - headers={"Authorization": f"Basic {ADMIN_KEY}"}, - ) + r = WALLET.pay_invoice(data["payment_request"]) + if not r.ok: return jsonify({"ERROR": "UNEXPECTED PAYMENT ERROR"}), 500 @@ -395,8 +385,8 @@ def api_checkinvoice(payhash): if not payment_row[0]: # pending return jsonify({"PAID": "TRUE"}), 200 - headers = {"Authorization": f"Basic {INVOICE_KEY}"} - r = requests.post(url=f"{API_ENDPOINT}/invoicestatus/{payhash}", headers=headers) + r = WALLET.get_invoice_status(payhash) + if not r.ok: return jsonify({"PAID": "FALSE"}), 400 diff --git a/LNbits/settings.py b/LNbits/settings.py index 86ad5fe..23310ad 100644 --- a/LNbits/settings.py +++ b/LNbits/settings.py @@ -1,8 +1,16 @@ import os -INVOICE_KEY = os.getenv("INVOICE_KEY") -ADMIN_KEY = os.getenv("ADMIN_KEY") -API_ENDPOINT = os.getenv("API_ENDPOINT") +from .wallets import LntxbotWallet # OR LndHubWallet + + +WALLET = LntxbotWallet( + endpoint=os.getenv("LNTXBOT_API_ENDPOINT"), + admin_key=os.getenv("LNTXBOT_ADMIN_KEY"), + invoice_key=os.getenv("LNTXBOT_INVOICE_KEY"), +) + +# OR +# WALLET = LndHubWallet(uri=os.getenv("LNDHUB_URI")) LNBITS_PATH = os.path.dirname(os.path.realpath(__file__)) -DATABASE_PATH= os.getenv("DATABASE_PATH") or os.path.join(LNBITS_PATH, "data", "database.sqlite3") +DATABASE_PATH = os.getenv("DATABASE_PATH") or os.path.join(LNBITS_PATH, "data", "database.sqlite3") diff --git a/LNbits/wallets.py b/LNbits/wallets.py new file mode 100644 index 0000000..5779720 --- /dev/null +++ b/LNbits/wallets.py @@ -0,0 +1,45 @@ +import requests + +from abc import ABC, abstractmethod +from requests import Response + + +class WalletResponse(Response): + """TODO: normalize different wallet responses + """ + + +class Wallet(ABC): + @abstractmethod + def create_invoice(self, amount: int, memo: str = "") -> WalletResponse: + pass + + @abstractmethod + def pay_invoice(self, bolt11: str) -> WalletResponse: + pass + + def get_invoice_status(self, payment_hash: str) -> WalletResponse: + pass + + +class LndHubWallet(Wallet): + def __init__(self, *, uri: str): + raise NotImplementedError + + +class LntxbotWallet(Wallet): + def __init__(self, *, endpoint: str, admin_key: str, invoice_key: str) -> WalletResponse: + self.endpoint = endpoint + self.auth_admin = {"Authorization": f"Basic {admin_key}"} + self.auth_invoice = {"Authorization": f"Basic {invoice_key}"} + + def create_invoice(self, amount: int, memo: str = "") -> WalletResponse: + return requests.post( + url=f"{self.endpoint}/addinvoice", headers=self.auth_invoice, json={"amt": amount, "memo": memo} + ) + + def pay_invoice(self, bolt11: str) -> WalletResponse: + return requests.post(url=f"{self.endpoint}/payinvoice", headers=self.auth_admin, json={"invoice": bolt11}) + + def get_invoice_status(self, payment_hash: str) -> Response: + return requests.post(url=f"{self.endpoint}/invoicestatus/{payment_hash}", headers=self.auth_invoice)