refactor: add some dev files and black original code
Original server code has been moved to __init__ file, so we can work on `lnbits` as a package.
This commit is contained in:
@@ -0,0 +1,636 @@
|
||||
from flask import Flask, render_template
|
||||
from flask import Flask, redirect
|
||||
from flask import request
|
||||
from flask import jsonify
|
||||
from flask import Flask, g
|
||||
from random import seed
|
||||
from random import random
|
||||
from flask import json
|
||||
import re
|
||||
import os
|
||||
import sqlite3
|
||||
import base64
|
||||
import lnurl
|
||||
import requests
|
||||
import hashlib
|
||||
import time
|
||||
import json
|
||||
import bech32
|
||||
|
||||
# DATABASE = 'database.db'
|
||||
|
||||
INVOICE_KEY = "YOUR-LNTXBOT-INVOICE-KEY" # In the lntxbot bot on telegram type "/api"
|
||||
ADMIN_KEY = "YOUR-LNTXBOT-ADMIN-KEY"
|
||||
API_ENDPOINT = "YOUR-LNTXBOT-API-BASE-URL"
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
DEFAULT_PATH = "database.sqlite3"
|
||||
|
||||
|
||||
def db_connect(db_path=DEFAULT_PATH):
|
||||
con = sqlite3.connect(db_path)
|
||||
return con
|
||||
|
||||
|
||||
def encrypt_string(hash_string):
|
||||
sha_signature = hashlib.sha256(hash_string.encode()).hexdigest()
|
||||
return sha_signature
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def home():
|
||||
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/deletewallet")
|
||||
def deletewallet():
|
||||
|
||||
thewal = request.args.get("wal")
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE hash = '" + str(thewal) + "'")
|
||||
rowss = cur.fetchall()
|
||||
|
||||
if len(rowss) > 0:
|
||||
|
||||
cur.close()
|
||||
print(rowss)
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("UPDATE wallets SET user = '" + "del" + rowss[0][4] + "' WHERE hash = '" + rowss[0][0] + "'")
|
||||
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("UPDATE wallets SET adminkey = '" + "del" + rowss[0][5] + "' WHERE hash = '" + rowss[0][0] + "'")
|
||||
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("UPDATE wallets SET inkey = '" + "del" + rowss[0][6] + "' WHERE hash = '" + rowss[0][0] + "'")
|
||||
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE user = '" + rowss[0][4] + "'")
|
||||
rowsss = cur.fetchall()
|
||||
|
||||
if len(rowsss) > 0:
|
||||
cur.close()
|
||||
return render_template("deletewallet.html", theid=rowsss[0][4], thewal=rowsss[0][0])
|
||||
else:
|
||||
return render_template("index.html")
|
||||
|
||||
else:
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/lnurlwallet")
|
||||
def lnurlwallet():
|
||||
|
||||
# put in a function
|
||||
thestr = request.args.get("lightning")
|
||||
lnurll = lnurl.decode(thestr)
|
||||
r = requests.get(url=lnurll)
|
||||
|
||||
data = r.json()
|
||||
|
||||
callback = data["callback"]
|
||||
maxwithdraw = data["maxWithdrawable"]
|
||||
withdraw = int(maxwithdraw / 1000)
|
||||
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)
|
||||
|
||||
dataa = rr.json()
|
||||
|
||||
# get callback
|
||||
|
||||
pay_req = dataa["pay_req"]
|
||||
payment_hash = dataa["payment_hash"]
|
||||
|
||||
invurl = callback + "&k1=" + k1 + "&pr=" + pay_req
|
||||
|
||||
rrr = requests.get(url=invurl)
|
||||
dataaa = rrr.json()
|
||||
|
||||
print(dataaa)
|
||||
print("poo")
|
||||
|
||||
if dataaa["status"] == "OK":
|
||||
|
||||
data = ""
|
||||
while data == "":
|
||||
r = requests.post(url=API_ENDPOINT + "/invoicestatus/" + str(payment_hash), headers=headers)
|
||||
data = r.json()
|
||||
print(r.json())
|
||||
|
||||
adminkey = encrypt_string(payment_hash)[0:20]
|
||||
inkey = encrypt_string(adminkey)[0:20]
|
||||
thewal = encrypt_string(inkey)[0:20]
|
||||
theid = encrypt_string(thewal)[0:20]
|
||||
thenme = "Bitcoin LN Wallet"
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("INSERT INTO accounts (userhash) VALUES ('" + theid + "')")
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
adminkey = encrypt_string(theid)
|
||||
inkey = encrypt_string(adminkey)
|
||||
|
||||
cur.execute(
|
||||
"INSERT INTO wallets (hash, balance, transactions, name, user, adminkey, inkey) VALUES ('"
|
||||
+ thewal
|
||||
+ "',',0,"
|
||||
+ str(withdraw)
|
||||
+ "','0','"
|
||||
+ thenme
|
||||
+ "','"
|
||||
+ theid
|
||||
+ "','"
|
||||
+ adminkey
|
||||
+ "','"
|
||||
+ inkey
|
||||
+ "')"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE user = '" + str(theid) + "'")
|
||||
rows = cur.fetchall()
|
||||
con.commit()
|
||||
cur.close()
|
||||
return render_template(
|
||||
"lnurlwallet.html",
|
||||
len=len("1"),
|
||||
walnme=thenme,
|
||||
walbal=str(withdraw),
|
||||
theid=theid,
|
||||
thewal=thewal,
|
||||
adminkey=adminkey,
|
||||
inkey=inkey,
|
||||
)
|
||||
else:
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/wallet")
|
||||
def wallet():
|
||||
|
||||
theid = request.args.get("usr")
|
||||
thewal = request.args.get("wal")
|
||||
theamt = request.args.get("amt")
|
||||
thenme = request.args.get("nme")
|
||||
|
||||
if not thewal:
|
||||
return render_template("index.html")
|
||||
else:
|
||||
# Checks if the user exists in "accounts"
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from accounts WHERE userhash = '" + str(theid) + "'")
|
||||
rows = cur.fetchall()
|
||||
|
||||
if len(rows) > 0:
|
||||
cur.close()
|
||||
|
||||
# Yes, check the user has a wallet
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE user = '" + str(theid) + "'")
|
||||
rowss = cur.fetchall()
|
||||
|
||||
if len(rowss) > 0:
|
||||
cur.close()
|
||||
|
||||
# Checks if the current wallet exists
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE hash = '" + str(thewal) + "'")
|
||||
rowsss = cur.fetchall()
|
||||
|
||||
if len(rowsss) > 0:
|
||||
cur.close()
|
||||
walb = rowsss[0][1].split(",")[-1]
|
||||
return render_template(
|
||||
"wallet.html",
|
||||
thearr=rowss,
|
||||
len=len(rowss),
|
||||
walnme=rowsss[0][3],
|
||||
user=theid,
|
||||
walbal=walb,
|
||||
theid=theid,
|
||||
thewal=thewal,
|
||||
transactions=rowsss[0][2],
|
||||
adminkey=rowsss[0][5],
|
||||
inkey=rowsss[0][6],
|
||||
)
|
||||
else:
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
adminkey = encrypt_string(thewal)
|
||||
inkey = encrypt_string(adminkey)
|
||||
|
||||
cur.execute(
|
||||
"INSERT INTO wallets (hash, balance, transactions, name, user, adminkey, inkey) VALUES ('"
|
||||
+ thewal
|
||||
+ "',',0','0','"
|
||||
+ thenme
|
||||
+ "','"
|
||||
+ theid
|
||||
+ "','"
|
||||
+ adminkey
|
||||
+ "','"
|
||||
+ inkey
|
||||
+ "')"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE user = '" + str(theid) + "'")
|
||||
rowss = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
return render_template(
|
||||
"wallet.html",
|
||||
thearr=rowss,
|
||||
len=len(rowss),
|
||||
walnme=thenme,
|
||||
walbal="0",
|
||||
theid=theid,
|
||||
thewal=thewal,
|
||||
adminkey=adminkey,
|
||||
inkey=inkey,
|
||||
)
|
||||
else:
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
adminkey = encrypt_string(theid)
|
||||
inkey = encrypt_string(adminkey)
|
||||
|
||||
cur.execute(
|
||||
"INSERT INTO wallets (hash, balance, transactions, name, user, adminkey, inkey) VALUES ('"
|
||||
+ thewal
|
||||
+ "',',0','0','"
|
||||
+ thenme
|
||||
+ "','"
|
||||
+ theid
|
||||
+ "','"
|
||||
+ adminkey
|
||||
+ "','"
|
||||
+ inkey
|
||||
+ "')"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
return render_template(
|
||||
"wallet.html",
|
||||
len=len("1"),
|
||||
walnme=thenme,
|
||||
walbal="0",
|
||||
theid=theid,
|
||||
thewal=thewal,
|
||||
adminkey=adminkey,
|
||||
inkey=inkey,
|
||||
)
|
||||
|
||||
else:
|
||||
cur.close()
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("INSERT INTO accounts (userhash) VALUES ('" + theid + "')")
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
adminkey = encrypt_string(theid)
|
||||
inkey = encrypt_string(adminkey)
|
||||
|
||||
cur.execute(
|
||||
"INSERT INTO wallets (hash, balance, transactions, name, user, adminkey, inkey) VALUES ('"
|
||||
+ thewal
|
||||
+ "',',0','0','"
|
||||
+ thenme
|
||||
+ "','"
|
||||
+ theid
|
||||
+ "','"
|
||||
+ adminkey
|
||||
+ "','"
|
||||
+ inkey
|
||||
+ "')"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(thewal)
|
||||
cur.execute("select * from wallets WHERE user = '" + str(theid) + "'")
|
||||
rows = cur.fetchall()
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
return render_template(
|
||||
"wallet.html",
|
||||
len=len("1"),
|
||||
walnme=thenme,
|
||||
walbal="0",
|
||||
theid=theid,
|
||||
thewal=thewal,
|
||||
adminkey=adminkey,
|
||||
inkey=inkey,
|
||||
)
|
||||
|
||||
|
||||
# API requests
|
||||
@app.route("/v1/invoices", methods=["GET", "POST"])
|
||||
def api_invoices():
|
||||
if request.headers["Content-Type"] == "application/json":
|
||||
|
||||
postedjson = request.json
|
||||
print(postedjson)
|
||||
|
||||
if "value" in postedjson:
|
||||
if postedjson["value"].isdigit() == True:
|
||||
if "memo" in postedjson:
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute(
|
||||
"select * from wallets WHERE inkey = '" + request.headers["Grpc-Metadata-macaroon"] + "'"
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
|
||||
if len(rows) > 0:
|
||||
cur.close()
|
||||
|
||||
dataj = {"amt": postedjson["value"], "memo": postedjson["memo"]}
|
||||
headers = {"Authorization": "Basic %s" % INVOICE_KEY}
|
||||
r = requests.post(url=API_ENDPOINT + "/addinvoice", json=dataj, headers=headers)
|
||||
|
||||
data = r.json()
|
||||
|
||||
pay_req = data["pay_req"]
|
||||
payment_hash = data["payment_hash"]
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute(
|
||||
"INSERT INTO apipayments (payhash, amount, wallet, paid, inkey, memo) VALUES ('"
|
||||
+ payment_hash
|
||||
+ "','"
|
||||
+ postedjson["value"]
|
||||
+ "','"
|
||||
+ rows[0][0]
|
||||
+ "','0','"
|
||||
+ request.headers["Grpc-Metadata-macaroon"]
|
||||
+ "','"
|
||||
+ postedjson["memo"]
|
||||
+ "')"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
return jsonify({"pay_req": pay_req, "payment_hash": payment_hash}), 200
|
||||
|
||||
else:
|
||||
return jsonify({"ERROR": "NO KEY"}), 200
|
||||
else:
|
||||
return jsonify({"ERROR": "NO MEMO"}), 200
|
||||
else:
|
||||
return jsonify({"ERROR": "VALUE MUST BE A NUMMBER"}), 200
|
||||
else:
|
||||
return jsonify({"ERROR": "NO VALUE"}), 200
|
||||
else:
|
||||
return jsonify({"ERROR": "MUST BE JSON"}), 200
|
||||
|
||||
|
||||
# API requests
|
||||
@app.route("/v1/channels/transactions", methods=["GET", "POST"])
|
||||
def api_transactions():
|
||||
if request.headers["Content-Type"] == "application/json":
|
||||
postedjson = request.json
|
||||
print(postedjson)
|
||||
print(postedjson["payment_request"])
|
||||
|
||||
if "payment_request" in postedjson:
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
print(request.headers["Grpc-Metadata-macaroon"])
|
||||
print()
|
||||
cur.execute("select * from wallets WHERE adminkey = '" + request.headers["Grpc-Metadata-macaroon"] + "'")
|
||||
rows = cur.fetchall()
|
||||
if len(rows) > 0:
|
||||
cur.close()
|
||||
|
||||
s = postedjson["payment_request"]
|
||||
result = re.search("lnbc(.*)1p", s)
|
||||
tempp = result.group(1)
|
||||
|
||||
alpha = ""
|
||||
num = ""
|
||||
|
||||
for i in range(len(tempp)):
|
||||
if tempp[i].isdigit():
|
||||
num = num + tempp[i]
|
||||
else:
|
||||
alpha += tempp[i]
|
||||
sats = ""
|
||||
if alpha == "n":
|
||||
sats = int(num) / 10
|
||||
elif alpha == "u":
|
||||
sats = int(num) * 100
|
||||
elif alpha == "m":
|
||||
sats = int(num) * 100000
|
||||
|
||||
print(sats)
|
||||
print(alpha)
|
||||
print(num)
|
||||
|
||||
dataj = {"invoice": postedjson["payment_request"]}
|
||||
headers = {"Authorization": "Basic %s" % ADMIN_KEY}
|
||||
r = requests.post(url=API_ENDPOINT + "/payinvoice", json=dataj, headers=headers)
|
||||
data = r.json()
|
||||
print(data)
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute(
|
||||
"INSERT INTO apipayments (payhash, amount, wallet, paid, adminkey, memo) VALUES ('"
|
||||
+ data["decoded"]["payment_hash"]
|
||||
+ "','"
|
||||
+ str(-int(data["decoded"]["num_satoshis"]))
|
||||
+ "','"
|
||||
+ rows[0][0]
|
||||
+ "','1','"
|
||||
+ request.headers["Grpc-Metadata-macaroon"]
|
||||
+ "','"
|
||||
+ data["decoded"]["description"]
|
||||
+ "')"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
cur.execute("select * from apipayments WHERE payhash = '" + data["decoded"]["payment_hash"] + "'")
|
||||
rowss = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
data["decoded"]["num_satoshis"]
|
||||
|
||||
lastamt = rows[0][1].split(",")
|
||||
newamt = int(lastamt[-1]) - int(data["decoded"]["num_satoshis"])
|
||||
updamt = rows[0][1] + "," + str(newamt)
|
||||
thetime = time.time()
|
||||
transactions = (
|
||||
rows[0][2] + "!" + rowss[0][5] + "," + str(thetime) + "," + str(rowss[0][1]) + "," + str(newamt)
|
||||
)
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute(
|
||||
"UPDATE wallets SET balance = '"
|
||||
+ updamt
|
||||
+ "', transactions = '"
|
||||
+ transactions
|
||||
+ "' WHERE hash = '"
|
||||
+ rows[0][0]
|
||||
+ "'"
|
||||
)
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
return jsonify({"PAID": "TRUE"}), 200
|
||||
else:
|
||||
return jsonify({"ERROR": "BAD AUTH"}), 200
|
||||
return jsonify({"ERROR": "NO PAY REQ"}), 200
|
||||
|
||||
return jsonify({"ERROR": "MUST BE JSON"}), 200
|
||||
|
||||
|
||||
@app.route("/v1/invoice/<payhash>", methods=["GET"])
|
||||
def api_checkinvoice(payhash):
|
||||
|
||||
if request.headers["Content-Type"] == "application/json":
|
||||
|
||||
print(request.headers["Grpc-Metadata-macaroon"])
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
cur.execute("select * from apipayments WHERE payhash = '" + payhash + "'")
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
print(payhash)
|
||||
if request.headers["Grpc-Metadata-macaroon"] == rows[0][4]:
|
||||
|
||||
if rows[0][3] == "0":
|
||||
print(rows[0][3])
|
||||
print("did it work?")
|
||||
headers = {"Authorization": "Basic %s" % INVOICE_KEY}
|
||||
r = requests.post(url=API_ENDPOINT + "/invoicestatus/" + payhash, headers=headers)
|
||||
data = r.json()
|
||||
print(r.json())
|
||||
print("no")
|
||||
if data == "":
|
||||
return jsonify({"PAID": "FALSE"}), 400
|
||||
else:
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("select * from wallets WHERE hash = '" + rows[0][2] + "'")
|
||||
|
||||
rowsss = cur.fetchall()
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
lastamt = rowsss[0][1].split(",")
|
||||
newamt = int(lastamt[-1]) + int(rows[0][1])
|
||||
updamt = rowsss[0][1] + "," + str(newamt)
|
||||
|
||||
thetime = time.time()
|
||||
transactions = (
|
||||
rowsss[0][2] + "!" + rows[0][5] + "," + str(thetime) + "," + str(rows[0][1]) + "," + str(newamt)
|
||||
)
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute(
|
||||
"UPDATE wallets SET balance = '"
|
||||
+ updamt
|
||||
+ "', transactions = '"
|
||||
+ transactions
|
||||
+ "' WHERE hash = '"
|
||||
+ rows[0][2]
|
||||
+ "'"
|
||||
)
|
||||
|
||||
con.commit()
|
||||
cur.close()
|
||||
|
||||
con = db_connect()
|
||||
cur = con.cursor()
|
||||
|
||||
cur.execute("UPDATE apipayments SET paid = '1' WHERE payhash = '" + payhash + "'")
|
||||
|
||||
con.commit()
|
||||
cur.close()
|
||||
return jsonify({"PAID": "TRUE"}), 200
|
||||
else:
|
||||
return jsonify({"PAID": "TRUE"}), 200
|
||||
else:
|
||||
return jsonify({"ERROR": "WRONG KEY"}), 400
|
||||
|
||||
else:
|
||||
return jsonify({"ERROR": "NEEDS TO BE JSON"}), 400
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True, host="0.0.0.0")
|
||||
Reference in New Issue
Block a user