mirror of
https://github.com/lnbits/lnbits.git
synced 2025-09-28 21:02:31 +02:00
balances view and other minor edits.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@ Pipfile.lock
|
|||||||
venv
|
venv
|
||||||
|
|
||||||
database.sqlite3
|
database.sqlite3
|
||||||
|
database.sqlite3*
|
||||||
|
@@ -38,16 +38,18 @@ 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],))
|
|
||||||
|
|
||||||
if user_wallets:
|
db.execute("UPDATE wallets SET user = ? WHERE hash = ?", (f"del{wallet_row[4]}", wallet_row[0]))
|
||||||
return render_template("deletewallet.html", theid=user_wallets[0][4], thewal=user_wallets[0][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:
|
||||||
|
return render_template("deletewallet.html", theid=user_wallets[0][4], thewal=user_wallets[0][0])
|
||||||
|
|
||||||
return render_template("index.html")
|
return render_template("index.html")
|
||||||
|
|
||||||
@@ -163,119 +165,95 @@ 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
|
||||||
if wallet:
|
(SELECT balance/1000 FROM balances WHERE wallet = wallets.hash),
|
||||||
walb = str(wallet[0][1]).split(",")[-1]
|
name,
|
||||||
return render_template(
|
adminkey,
|
||||||
"wallet.html",
|
inkey
|
||||||
thearr=user_wallets,
|
FROM wallets
|
||||||
len=len(user_wallets),
|
WHERE user = ? AND hash = ?
|
||||||
walnme=wallet[0][3],
|
""",
|
||||||
user=theid,
|
(theid, thewal,),
|
||||||
walbal=walb,
|
|
||||||
theid=theid,
|
|
||||||
thewal=thewal,
|
|
||||||
transactions=wallet[0][2],
|
|
||||||
adminkey=wallet[0][5],
|
|
||||||
inkey=wallet[0][6],
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
# -------------------
|
|
||||||
|
|
||||||
adminkey = encrypt(theid)
|
|
||||||
inkey = encrypt(adminkey)
|
|
||||||
|
|
||||||
db.execute(
|
|
||||||
"INSERT INTO wallets (hash, name, user, adminkey, inkey) " "VALUES (?, ?, ?, ?, ?)",
|
|
||||||
(thewal, thenme, theid, adminkey, inkey),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
transactions = []
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"wallet.html",
|
"wallet.html",
|
||||||
len=len("1"),
|
thearr=user_wallets,
|
||||||
walnme=thenme,
|
len=len(user_wallets),
|
||||||
walbal="0",
|
walnme=wallet_row[1],
|
||||||
|
user=theid,
|
||||||
|
walbal=wallet_row[0],
|
||||||
theid=theid,
|
theid=theid,
|
||||||
thewal=thewal,
|
thewal=thewal,
|
||||||
adminkey=adminkey,
|
transactions=transactions,
|
||||||
inkey=inkey,
|
adminkey=wallet_row[2],
|
||||||
|
inkey=wallet_row[3],
|
||||||
)
|
)
|
||||||
|
|
||||||
# user does not exist: create an account
|
# user has no wallets
|
||||||
# --------------------------------------
|
# -------------------
|
||||||
|
|
||||||
db.execute("INSERT INTO accounts (userhash) VALUES (?)", (theid,))
|
|
||||||
|
|
||||||
adminkey = encrypt(theid)
|
adminkey = encrypt(theid)
|
||||||
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),
|
(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"]),
|
||||||
)
|
)
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user