Browse Source

balances view and other minor edits.

fee_issues
fiatjaf 5 years ago
parent
commit
23ffa40f30
  1. 1
      .gitignore
  2. 141
      LNbits/__init__.py
  3. 14
      LNbits/data/schema.sql

1
.gitignore

@ -22,3 +22,4 @@ Pipfile.lock
venv venv
database.sqlite3 database.sqlite3
database.sqlite3*

141
LNbits/__init__.py

@ -38,14 +38,16 @@ def deletewallet():
thewal = request.args.get("wal") thewal = request.args.get("wal")
with Database() as db: with Database() as db:
wallets = db.fetchall("SELECT * FROM wallets WHERE hash = ?", (thewal,)) wallet_row = db.fetchone("SELECT * FROM wallets WHERE hash = ?", (thewal,))
if wallets: if not wallet_row:
db.execute("UPDATE wallets SET user = ? WHERE hash = ?", (f"del{wallets[0][4]}", wallets[0][0])) return render_template("index.html")
db.execute("UPDATE wallets SET adminkey = ? WHERE hash = ?", (f"del{wallets[0][5]}", wallets[0][0]))
db.execute("UPDATE wallets SET inkey = ? WHERE hash = ?", (f"del{wallets[0][6]}", wallets[0][0]))
user_wallets = db.fetchall("SELECT * FROM wallets WHERE user = ?", (wallets[0][4],))
db.execute("UPDATE wallets SET user = ? WHERE hash = ?", (f"del{wallet_row[4]}", wallet_row[0]))
db.execute("UPDATE wallets SET adminkey = ? WHERE hash = ?", (f"del{wallet_row[5]}", wallet_row[0]))
db.execute("UPDATE wallets SET inkey = ? WHERE hash = ?", (f"del{wallet_row[6]}", wallet_row[0]))
user_wallets = db.fetchall("SELECT * FROM wallets WHERE user = ?", (wallet_row[4],))
if user_wallets: if user_wallets:
return render_template("deletewallet.html", theid=user_wallets[0][4], thewal=user_wallets[0][0]) return render_template("deletewallet.html", theid=user_wallets[0][4], thewal=user_wallets[0][0])
@ -163,55 +165,51 @@ def wallet():
return render_template("index.html") return render_template("index.html")
with Database() as db: with Database() as db:
user_exists = len(db.fetchall("SELECT * FROM accounts WHERE userhash = ?", (theid,))) > 0 user_exists = db.fetchone("SELECT * FROM accounts WHERE userhash = ?", (theid,))
if not user_exists:
# user does not exist: create an account
# --------------------------------------
db.execute("INSERT INTO accounts (userhash) VALUES (?)", (theid,))
# user exists # user exists
# ----------- # -----------
if user_exists:
user_wallets = db.fetchall("SELECT * FROM wallets WHERE user = ?", (theid,)) user_wallets = db.fetchall("SELECT * FROM wallets WHERE user = ?", (theid,))
if user_wallets:
# user has wallets # user has wallets
# ---------------- # ----------------
if user_wallets: wallet_row = db.fetchone(
wallet = db.fetchall("SELECT * FROM wallets WHERE hash = ?", (thewal,)) """
SELECT
(SELECT balance/1000 FROM balances WHERE wallet = wallets.hash),
name,
adminkey,
inkey
FROM wallets
WHERE user = ? AND hash = ?
""",
(theid, thewal,),
)
transactions = []
if wallet:
walb = str(wallet[0][1]).split(",")[-1]
return render_template( return render_template(
"wallet.html", "wallet.html",
thearr=user_wallets, thearr=user_wallets,
len=len(user_wallets), len=len(user_wallets),
walnme=wallet[0][3], walnme=wallet_row[1],
user=theid, user=theid,
walbal=walb, walbal=wallet_row[0],
theid=theid, theid=theid,
thewal=thewal, thewal=thewal,
transactions=wallet[0][2], transactions=transactions,
adminkey=wallet[0][5], adminkey=wallet_row[2],
inkey=wallet[0][6], inkey=wallet_row[3],
)
adminkey = encrypt(thewal)
inkey = encrypt(adminkey)
db.execute(
"INSERT INTO wallets (hash, name, user, adminkey, inkey) VALUES (?, ?, ?, ?, ?)",
(thewal, thenme, theid, adminkey, inkey),
)
rows = db.fetchall("SELECT * FROM wallets WHERE user = ?", (theid,))
return render_template(
"wallet.html",
thearr=rows,
len=len(rows),
walnme=thenme,
walbal="0",
theid=theid,
thewal=thewal,
adminkey=adminkey,
inkey=inkey,
) )
# user has no wallets # user has no wallets
@ -221,61 +219,41 @@ def wallet():
inkey = encrypt(adminkey) inkey = encrypt(adminkey)
db.execute( db.execute(
"INSERT INTO wallets (hash, name, user, adminkey, inkey) " "VALUES (?, ?, ?, ?, ?)", "INSERT INTO wallets (hash, name, user, adminkey, inkey) VALUES (?, ?, ?, ?, ?)",
(thewal, thenme, theid, adminkey, inkey),
)
return render_template(
"wallet.html",
len=len("1"),
walnme=thenme,
walbal="0",
theid=theid,
thewal=thewal,
adminkey=adminkey,
inkey=inkey,
)
# user does not exist: create an account
# --------------------------------------
db.execute("INSERT INTO accounts (userhash) VALUES (?)", (theid,))
adminkey = encrypt(theid)
inkey = encrypt(adminkey)
db.execute(
"INSERT INTO wallets (hash, name, user, adminkey, inkey) " "VALUES (?, ?, ?, ?, ?)",
(thewal, thenme, theid, adminkey, inkey), (thewal, thenme, theid, adminkey, inkey),
) )
return render_template( return render_template(
"wallet.html", "wallet.html",
len=len("1"), len=1,
walnme=thenme, walnme=thenme,
walbal="0", walbal=0,
theid=theid, theid=theid,
thewal=thewal, thewal=thewal,
adminkey=adminkey, adminkey=adminkey,
inkey=inkey, inkey=inkey,
transactions=[],
) )
@app.route("/v1/invoices", methods=["GET", "POST"]) @app.route("/v1/invoices", methods=["GET", "POST"])
def api_invoices(): def api_invoices():
if request.headers["Content-Type"] != "application/json": if request.headers["Content-Type"] != "application/json":
return jsonify({"ERROR": "MUST BE JSON"}), 200 return jsonify({"ERROR": "MUST BE JSON"}), 400
postedjson = request.json postedjson = request.json
if "value" not in postedjson: if "value" not in postedjson:
return jsonify({"ERROR": "NO VALUE"}), 200 return jsonify({"ERROR": "NO VALUE"}), 400
if not postedjson["value"].isdigit(): if not postedjson["value"].isdigit():
return jsonify({"ERROR": "VALUE MUST BE A NUMMBER"}), 200 return jsonify({"ERROR": "VALUE MUST BE A NUMBER"}), 400
if postedjson["value"] < 0:
return jsonify({"ERROR": "AMOUNTLESS INVOICES NOT SUPPORTED"}), 400
if "memo" not in postedjson: if "memo" not in postedjson:
return jsonify({"ERROR": "NO MEMO"}), 200 return jsonify({"ERROR": "NO MEMO"}), 400
with Database() as db: with Database() as db:
wallet_row = db.fetchone( wallet_row = db.fetchone(
@ -350,6 +328,8 @@ def api_transactions():
# decode the invoice # decode the invoice
invoice = bolt11.decode(data["payment_request"]) invoice = bolt11.decode(data["payment_request"])
if invoice.amount == 0:
return jsonify({"ERROR": "AMOUNTLESS INVOICES NOT SUPPORTED"}), 400
# insert the payment # insert the payment
db.execute( db.execute(
@ -364,26 +344,7 @@ def api_transactions():
) )
# check balance # check balance
balance = db.fetchone( balance = db.fetchone("SELECT balance/1000 FROM balances WHERE wallet = ?", (wallet_row[0]))[0]
"""
WITH wallettransactions AS (
SELECT *
FROM apipayments
WHERE wallet = ?
)
SELECT sum(s) FROM (
SELECT sum(amount) AS s -- incoming
FROM wallettransactions
WHERE amount > 0 AND pending = false -- don't sum pending
UNION ALL
SELECT sum(amount + fee) AS s -- outgoing, sum fees
FROM wallettransactions
WHERE amount < 0 -- do sum pending
)
""",
(wallet_row[0],),
)
if balance < 0: if balance < 0:
return jsonify({"ERROR": "INSUFFICIENT BALANCE"}), 403 return jsonify({"ERROR": "INSUFFICIENT BALANCE"}), 403
@ -423,7 +384,7 @@ def api_checkinvoice(payhash):
SELECT pending FROM apipayments SELECT pending FROM apipayments
INNER JOIN wallets AS w ON apipayments.wallet = w.hash INNER JOIN wallets AS w ON apipayments.wallet = w.hash
WHERE payhash = ? WHERE payhash = ?
AND (w.adminkey = ? OR w.invkey = ?) AND (w.adminkey = ? OR w.inkey = ?)
""", """,
(payhash, request.headers["Grpc-Metadata-macaroon"], request.headers["Grpc-Metadata-macaroon"]), (payhash, request.headers["Grpc-Metadata-macaroon"], request.headers["Grpc-Metadata-macaroon"]),
) )

14
LNbits/data/schema.sql

@ -15,8 +15,20 @@ CREATE TABLE IF NOT EXISTS wallets (
CREATE TABLE IF NOT EXISTS apipayments ( CREATE TABLE IF NOT EXISTS apipayments (
payhash text PRIMARY KEY, payhash text PRIMARY KEY,
amount integer NOT NULL, amount integer NOT NULL,
fee integer NOT NULL, fee integer NOT NULL DEFAULT 0,
wallet text NOT NULL, wallet text NOT NULL,
pending boolean NOT NULL, pending boolean NOT NULL,
memo text memo text
); );
CREATE VIEW IF NOT EXISTS balances AS
SELECT wallet, coalesce(sum(s), 0) AS balance FROM (
SELECT wallet, sum(amount) AS s -- incoming
FROM apipayments
WHERE amount > 0 AND pending = false -- don't sum pending
UNION ALL
SELECT wallet, sum(amount + fee) AS s -- outgoing, sum fees
FROM apipayments
WHERE amount < 0 -- do sum pending
)
GROUP BY wallet;

Loading…
Cancel
Save