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:
Eneko Illarramendi 2019-12-13 17:56:19 +01:00
parent 37d96345c9
commit 3d3632a06f
13 changed files with 731 additions and 514 deletions

14
.editorconfig Normal file
View File

@ -0,0 +1,14 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.py]
indent_size = 4
indent_style = space

2
.env.example Normal file
View File

@ -0,0 +1,2 @@
FLASK_APP=lnbits
FLASK_ENV=development

15
.gitignore vendored Executable file
View File

@ -0,0 +1,15 @@
.DS_Store
._*
__pycache__
*.py[cod]
*$py.class
.mypy_cache
.vscode
*.egg
*.egg-info
.coverage
.pytest_cache
htmlcov
Pipfile.lock

29
DEV.md Normal file
View File

@ -0,0 +1,29 @@
For developers
==============
LNbits uses [Flask](http://flask.pocoo.org/).
Feel free to contribute to the project.
Application dependencies
------------------------
The application uses [Pipenv][pipenv] to manage Python packages.
While in development, you will need to install all dependencies:
$ pipenv shell
$ pipenv install --dev
Running the server
------------------
$ flask run
There is an environment variable called `FLASK_ENV` that has to be set to `development`
if you want to run Flask in debug mode with autoreload
Style guide
-----------
Tab size is 4 spaces. Maximum line length is 120. You should run `black` before commiting any change.
$ black lnbits
[pipenv]: https://docs.pipenv.org/#install-pipenv-today

636
LNbits/__init__.py Normal file
View File

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

View File

@ -1,3 +0,0 @@
lnurl==0.1.0
Flask==1.1.1
requests==2.21.0

View File

@ -1,511 +0,0 @@
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')

20
Pipfile Normal file
View File

@ -0,0 +1,20 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[requires]
python_version = "3.7"
[packages]
lnurl = "*"
flask = "*"
requests = "*"
[dev-packages]
black = "==19.10b0"
flake8 = "*"
flake8-mypy = "*"
pytest = "*"
pytest-cov = "*"
pytest-sugar = "*"

2
pyproject.toml Normal file
View File

@ -0,0 +1,2 @@
[tool.black]
line-length = 120

13
requirements.txt Normal file
View File

@ -0,0 +1,13 @@
bech32==1.1.0
certifi==2019.11.28
chardet==3.0.4
click==7.0
flask==1.1.1
idna==2.8
itsdangerous==1.1.0
jinja2==2.10.3
lnurl==0.1.1
markupsafe==1.1.1
requests==2.22.0
urllib3==1.25.7
werkzeug==0.16.0

0
tests/__init__.py Normal file
View File