Browse Source

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.
fee_issues
Eneko Illarramendi 5 years ago
parent
commit
3d3632a06f
  1. 14
      .editorconfig
  2. 2
      .env.example
  3. 15
      .gitignore
  4. 29
      DEV.md
  5. 636
      LNbits/__init__.py
  6. BIN
      LNbits/__pycache__/lnurlreq.cpython-37.pyc
  7. 3
      LNbits/requirements.txt
  8. 511
      LNbits/server.py
  9. 20
      Pipfile
  10. 0
      database.sqlite3
  11. 2
      pyproject.toml
  12. 13
      requirements.txt
  13. 0
      tests/__init__.py

14
.editorconfig

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

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

15
.gitignore

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

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

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

BIN
LNbits/__pycache__/lnurlreq.cpython-37.pyc

Binary file not shown.

3
LNbits/requirements.txt

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

511
LNbits/server.py

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

@ -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 = "*"

0
LNbits/database.sqlite3 → database.sqlite3

2
pyproject.toml

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

13
requirements.txt

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

Loading…
Cancel
Save