From 750dd7dfbf232f2b221ae1ac6e33750168533c8f Mon Sep 17 00:00:00 2001 From: Arc <33088785+arcbtc@users.noreply.github.com> Date: Thu, 12 Dec 2019 23:04:35 +0000 Subject: [PATCH] Add files via upload --- LNbits/__pycache__/lnurlreq.cpython-37.pyc | Bin 0 -> 371 bytes LNbits/database.sqlite3 | Bin 0 -> 81920 bytes LNbits/server.py | 511 +++++++++++++++ LNbits/templates/deletewallet.html | 199 ++++++ LNbits/templates/index.html | 249 +++++++ LNbits/templates/lnurlwallet.html | 701 ++++++++++++++++++++ LNbits/templates/wallet.html | 717 +++++++++++++++++++++ 7 files changed, 2377 insertions(+) create mode 100644 LNbits/__pycache__/lnurlreq.cpython-37.pyc create mode 100644 LNbits/database.sqlite3 create mode 100644 LNbits/server.py create mode 100644 LNbits/templates/deletewallet.html create mode 100644 LNbits/templates/index.html create mode 100644 LNbits/templates/lnurlwallet.html create mode 100644 LNbits/templates/wallet.html diff --git a/LNbits/__pycache__/lnurlreq.cpython-37.pyc b/LNbits/__pycache__/lnurlreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..760e879b6f77560be66ec146151bb9772794bb60 GIT binary patch literal 371 zcmYjNJx{|h5IujivS=d~7B(2O5VkG|Ay`od5JHN?;KYWuI1Sj2TBKxSuFyRS*CG literal 0 HcmV?d00001 diff --git a/LNbits/database.sqlite3 b/LNbits/database.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..12bc1151b09e98fb2083b141e64d22a8ad68a128 GIT binary patch literal 81920 zcmeI*X^0zT9LMpQB$G)to85ZA3Z*t|Ewt7aZ&8GvtCrTH+f{l}r)_E%H`%qDVv8WQ zN(E6-JP^En(TXor@IX8(f~bg!;(=NzT0yI5MYMtkKJ(13yG!zH=ig4!+3h#OJexev zFV8&BCuw$*nNF5ozPP(mENtlARPri?v#bf0ZCi5+1MXmR%HKo?U zi#>S7{8RNY%U+RJ0VluHYQ4YZ)0SQNJ^7vamHCzCd(nab0tg_000IagfB*sr9FqdG z{aK&0I^DK#ifwh5*B7_+U)!VJvaRtpS9R8rwnyT-Bi$b;b7V z!X;fD7k6~}v#)IO%KhHDN_TI$e`q3QucTswLYw=Gn}%*xO|pHIIqLza32!*TZJRX7 z-ZnXSMCnPAbov)j`VB$adD0Yi?lZO2s&~q@ zYE5;{MaGshjV&h|Tm1b&H7}_@YF4Yt)HlYK_l+$tnOa2kDbe#Pb-Ac>Q#hsmq7Hva zejh$-S;^g^w7=Ib^d;FBI;w)nOGN2{B%SzEl>ShZenOPKQIuXLN}n!DXC!HRuPFVZ zD1E0Wy-}2&BTAnnNm~a(r}yjRK3#sT%g=TBkuKlUN$P=DP0E7vd8uH z2Xz^|#s_w{>YAH%d4n#u=yH=Tdvv)$msja>g)X~vxkQ(j=yIMeFVy9^x(uFEr|Rpc z=rVXM52TLQHO;zATh`$F|KyC(7oDd-0DAiLAyun?k{o^^gm;_S4n_8$31d<;&R3f>)p_>~g z8%xX@ClfJG!xnx1Ywjm(%U5B8QRI4~=p?qfeZkPL`;e(2*#A-8>RwY_r)%6!Q-kUFFSlU0N3H7g zZ?$SwUHS`CgJl1I`W{m+*P9yFni>|G8iM^l)vamM@h{H5)nQ%Zd}nA7RXdLe;!d#t zE8IOC$?-pqWKUu0$8aOisnlzd@LiIy`5C4#NNJ@@>OgUvQJrWbc<#fvaSrV4K{@JG2zgio#CCC5T z7u4#)P-pAC-iF4i>b+Gpqf|UQN?TRaj;fkbDn!SBo;FHHG$DWh0tg_000IagfB*sr zAb#31P0IlZyyY|#BBHs=hza+FCB~XZ8n|%DrS?(#pe9SIn(*SVkQ=1 zI8Bd+2*op!jpY1a5zH;SDuPZT=_2z{B;6c&CmGZE-;TWNM)%+b-+$ET%|^7n^zMi{ zifK2_-k1*T(8F@39y&8N5~-DAW1KZdnS8ir_0g+Liq8Lb^u~GUEhpw5Ix{vBw&;60 zV>YK(V>TY~aQuG|8MV4<_0JFNe@mdFR`m^mmj9hGC#bbWt*vU!snySmzDQf;xgdZ5 z0tg_000IagfB*srAb!f1oYQ{sy+VMzx^e%Z)kBQ z3|~_3N|!nfm~Ih30D)KwWc!kL#Cm{ZdT`mkgy}oZ1@m%uSQiQ6b&Y0@kIz`LeO3hj z$04`Ex~;Bc4ez{ZUKB2>mvQEz4itT@;SYvkgZTyaenV5ktJPReYWPMC8_X|=;#t?S zDn74LhKU}f>clHYzTxqw+d3 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/', 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') \ No newline at end of file diff --git a/LNbits/templates/deletewallet.html b/LNbits/templates/deletewallet.html new file mode 100644 index 000000000..058ef540d --- /dev/null +++ b/LNbits/templates/deletewallet.html @@ -0,0 +1,199 @@ + + + + + LNBits Wallet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+ +
+

+ Wallet + Control panel +

+ +
+ + +
+

Wallet Deleted! + + +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LNbits/templates/index.html b/LNbits/templates/index.html new file mode 100644 index 000000000..5867cbfed --- /dev/null +++ b/LNbits/templates/index.html @@ -0,0 +1,249 @@ + + + + + LNBits Wallet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+ +
+ + + +

+
+ +

Warning - Wallet is still in BETA and very, very #reckless, please be careful with your funds!

+ +
+
+ + +
+ +
+
+ +
+
+

+ + free and open-source lightning wallet +

+

+ LNbits is a simple, free and open-source lightning-network wallet for bits and bobs. You can run it on your own server, or use this one. +

+The wallet can be used in a variety of ways, an instant wallet for LN demonstrations, a fallback wallet for the LNURL scheme, an accounts system to mitigate the risk of exposing applications to your full balance. +

+The wallet can run on top of LND, lntxbot, paywall, opennode +

+Please note that although one of the aims of this wallet is to mitigate exposure of all your funds, it’s still very BETA and may in fact do the opposite! +
https://github.com/arcbtc/lnbits

+
+ +
+ +
+ + + +
+ +
+
+

+ + Make a wallet +

+
+ +
+ +
+ +
+ +
+ + + +
+ + + + + + +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LNbits/templates/lnurlwallet.html b/LNbits/templates/lnurlwallet.html new file mode 100644 index 000000000..194f69644 --- /dev/null +++ b/LNbits/templates/lnurlwallet.html @@ -0,0 +1,701 @@ + + + + + LNBits Wallet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+ +
+

+ Wallet + Control panel
+

+ +
+ + +
+ + + +
+
+
+
+ + + +
+
+ + + + +
+
+
+
+

Transactions

+ +
+
+ + + + + + + + + + + +
Memodateamount
+
+
+
+
+ +
+ + + +
+
+
+
+ +
+
+
+ +
+ + +
+ + +
+ + + +
+ +
+
+
+
+
+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LNbits/templates/wallet.html b/LNbits/templates/wallet.html new file mode 100644 index 000000000..bfb0b19af --- /dev/null +++ b/LNbits/templates/wallet.html @@ -0,0 +1,717 @@ + + + + + LNBits Wallet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+ +
+

+ Wallet + Control panel
+

+ + + + +
+ + +
+ + + +
+
+
+
+ + + +
+
+ + + + +
+
+
+
+

Transactions

+ +
+
+ + + + + + + + + + + +
Memodateamount
+
+
+
+
+ +
+ + + +
+
+
+
+ +
+
+
+ +
+ + +
+ + +
+ + + +
+ +
+
+
+
+
+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file