mirror of https://github.com/lukechilds/lnbits.git
Browse Source
Original server code has been moved to __init__ file, so we can work on `lnbits` as a package.fee_issues
13 changed files with 731 additions and 514 deletions
@ -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 |
@ -0,0 +1,2 @@ |
|||||
|
FLASK_APP=lnbits |
||||
|
FLASK_ENV=development |
@ -0,0 +1,15 @@ |
|||||
|
.DS_Store |
||||
|
._* |
||||
|
|
||||
|
__pycache__ |
||||
|
*.py[cod] |
||||
|
*$py.class |
||||
|
.mypy_cache |
||||
|
.vscode |
||||
|
|
||||
|
*.egg |
||||
|
*.egg-info |
||||
|
.coverage |
||||
|
.pytest_cache |
||||
|
htmlcov |
||||
|
Pipfile.lock |
@ -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 |
@ -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") |
Binary file not shown.
@ -1,3 +0,0 @@ |
|||||
lnurl==0.1.0 |
|
||||
Flask==1.1.1 |
|
||||
requests==2.21.0 |
|
@ -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') |
|
@ -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,0 +1,2 @@ |
|||||
|
[tool.black] |
||||
|
line-length = 120 |
@ -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 |
Loading…
Reference in new issue