diff --git a/lnbits/extensions/satspay/crud.py b/lnbits/extensions/satspay/crud.py index bd156ae4..b31ac255 100644 --- a/lnbits/extensions/satspay/crud.py +++ b/lnbits/extensions/satspay/crud.py @@ -11,7 +11,6 @@ import httpx from lnbits.core.services import create_invoice, check_invoice_status from ..watchonly.crud import get_watch_wallet, get_derive_address, get_mempool -import time ###############CHARGES########################## @@ -45,13 +44,12 @@ async def create_charge(user: str, description: Optional[str] = None, onchainwal webhook, time, amount, - balance, - paid + balance ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, (charge_id, user, description, onchainwallet, onchainaddress, lnbitswallet, - payment_request, payment_hash, webhook, time, amount, 0, False), + payment_request, payment_hash, webhook, time, amount, 0), ) return await get_charge(charge_id) @@ -79,21 +77,24 @@ async def delete_charge(charge_id: str) -> None: async def check_address_balance(charge_id: str) -> List[Charges]: charge = await get_charge(charge_id) - if charge.onchainaddress: - mempool = await get_mempool(charge.user) - try: - async with httpx.AsyncClient() as client: - r = await client.get(mempool.endpoint + "/api/address/" + charge.onchainaddress) - respAmount = r.json()['chain_stats']['funded_txo_sum'] - if (charge.balance + respAmount) >= charge.balance: - return await update_charge(charge_id=charge_id, balance=(charge.balance + respAmount), paid=True) - else: - return await update_charge(charge_id=charge_id, balance=(charge.balance + respAmount), paid=False) - except Exception: - pass - if charge.lnbitswallet: - invoice_status = await check_invoice_status(charge.lnbitswallet, charge.payment_hash) - if invoice_status.paid: - return await update_charge(charge_id=charge_id, balance=charge.balance, paid=True) + print(charge.balance) + if not charge.paid: + if charge.onchainaddress: + mempool = await get_mempool(charge.user) + try: + async with httpx.AsyncClient() as client: + r = await client.get(mempool.endpoint + "/api/address/" + charge.onchainaddress) + respAmount = r.json()['chain_stats']['funded_txo_sum'] + print(respAmount) + if respAmount >= charge.balance: + await update_charge(charge_id=charge_id, balance=respAmount) + except Exception: + pass + if charge.lnbitswallet: + invoice_status = await check_invoice_status(charge.lnbitswallet, charge.payment_hash) + print(invoice_status) + if invoice_status.paid: + print("paid") + return await update_charge(charge_id=charge_id, balance=charge.amount) row = await db.fetchone("SELECT * FROM charges WHERE id = ?", (charge_id,)) return Charges.from_row(row) if row else None diff --git a/lnbits/extensions/satspay/migrations.py b/lnbits/extensions/satspay/migrations.py index 044eed13..6fdb29c3 100644 --- a/lnbits/extensions/satspay/migrations.py +++ b/lnbits/extensions/satspay/migrations.py @@ -3,7 +3,6 @@ async def m001_initial(db): Initial wallet table. """ - await db.execute( """ CREATE TABLE IF NOT EXISTS charges ( @@ -19,8 +18,7 @@ async def m001_initial(db): time INTEGER, amount INTEGER, balance INTEGER DEFAULT 0, - paid BOOLEAN, timestamp TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) ); """ - ) \ No newline at end of file + ) diff --git a/lnbits/extensions/satspay/models.py b/lnbits/extensions/satspay/models.py index 5eee1061..145164c4 100644 --- a/lnbits/extensions/satspay/models.py +++ b/lnbits/extensions/satspay/models.py @@ -1,5 +1,6 @@ from sqlite3 import Row from typing import NamedTuple +import time class Charges(NamedTuple): @@ -12,12 +13,25 @@ class Charges(NamedTuple): payment_request: str payment_hash: str webhook: str - time: str + time: int amount: int balance: int - paid: bool timestamp: int @classmethod def from_row(cls, row: Row) -> "Charges": return cls(**dict(row)) + + @property + def time_elapsed(self): + if (self.timestamp + (self.time * 60)) >= time.time(): + return False + else: + return True + + @property + def paid(self): + if self.balance >= self.amount: + return True + else: + return False diff --git a/lnbits/extensions/satspay/templates/satspay/_api_docs.html b/lnbits/extensions/satspay/templates/satspay/_api_docs.html index 3c0bc720..d8df4d5b 100644 --- a/lnbits/extensions/satspay/templates/satspay/_api_docs.html +++ b/lnbits/extensions/satspay/templates/satspay/_api_docs.html @@ -117,80 +117,6 @@ - - - - POST /pay/api/v1/links -
Headers
- {"X-Api-Key": <invoice_key>}
-
- Body (application/json) -
- {"description": <string> "amount": <integer>} -
- Returns 201 CREATED (application/json) -
- - { "deliveryId": <string>, "description": <string>, - "webhookId": <string>, "originalDeliveryId": <string>, - "isRedelivery": <boolean>, "type": <string>, - "timestamp": <int>, "paytime": <int>, "storeId": - <string>, "invoiceId": <string>, "manuallyMarked": - <boolean>, "overPaid": <boolean>, "afterExpiration": - <boolean>, "partiallyPaid": <boolean> }
"type" can be InvoiceReceivedPayment, InvoicePaidInFull, - InvoiceExpired, InvoiceConfirmed, and InvoiceInvalid -
-
Curl example
- curl -X POST {{ request.url_root }}pay/api/v1/links -d - '{"description": <string>, "amount": <integer>}' -H - "Content-type: application/json" -H "X-Api-Key: {{ - g.user.wallets[0].adminkey }}" - -
-
-
- - - - PUT - /pay/api/v1/links/<pay_id> -
Headers
- {"X-Api-Key": <admin_key>}
-
- Body (application/json) -
- {"description": <string>, "amount": <integer>} -
- Returns 200 OK (application/json) -
- {"lnurl": <string>} -
Curl example
- curl -X PUT {{ request.url_root }}pay/api/v1/links/<pay_id> - -d '{"description": <string>, "amount": <integer>}' -H - "Content-type: application/json" -H "X-Api-Key: {{ - g.user.wallets[0].adminkey }}" - -
-
-
DELETE - /pay/api/v1/links/<pay_id>
Headers
{"X-Api-Key": <admin_key>}
@@ -211,11 +137,36 @@
Curl example
curl -X DELETE {{ request.url_root - }}pay/api/v1/links/<pay_id> -H "X-Api-Key: {{ + }}api/v1/charge/<charge_id> -H "X-Api-Key: {{ g.user.wallets[0].adminkey }}"
+ + + + GET + /satspay/api/v1/charges/balance/<charge_id> +
Headers
+ {"X-Api-Key": <admin_key>}
+
+ Body (application/json) +
+
+ Returns 200 OK (application/json) +
+ [<charge_object>, ...] +
Curl example
+ curl -X GET {{ request.url_root + }}api/v1/charges/balance/<charge_id> -H "X-Api-Key: {{ + g.user.wallets[0].inkey }}" + +
+
+
diff --git a/lnbits/extensions/satspay/templates/satspay/display.html b/lnbits/extensions/satspay/templates/satspay/display.html index c0773e33..7f5d5efc 100644 --- a/lnbits/extensions/satspay/templates/satspay/display.html +++ b/lnbits/extensions/satspay/templates/satspay/display.html @@ -1,74 +1,241 @@ {% extends "public.html" %} {% block page %} - -
+
- -
Our Changing Planet
-
by John Doe
-
+ + +
- - + +
- - - - - {% endblock %} {% block scripts %} + {% endblock %} diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 4259ab41..0a7f49b7 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -64,33 +64,53 @@ type="a" :href="props.row.displayUrl" target="_blank" - > + > + + Payment link + + - + > + + Time elapsed + + - + > + + PAID! + + - + > + + Check balance + + { + obj._data = _.clone(obj) + obj.theTime = (obj.time * 60) - (Date.now()/1000 - obj.timestamp) + console.log(obj.theTime) + obj.time = obj.time + "mins" + + if(obj.time_elapsed){ obj.date = "Time elapsed" } else{ obj.date = Quasar.utils.date.formatDate( - - new Date(obj.theDate * 1000), + new Date((obj.theTime - 3600)*1000), 'HH:mm:ss' - ) - } - + )} obj.displayUrl = ['/satspay/', obj.id].join('') - + console.log(obj.date) return obj } + new Vue({ el: '#vue', mixins: [windowMixin], @@ -326,8 +348,8 @@ ChargesTable: { columns: [ - { - name: 'id', + { + name: 'theId', align: 'left', label: 'ID', field: 'id' @@ -344,6 +366,12 @@ label: 'Time left', field: 'date' }, + { + name: 'time to pay', + align: 'left', + label: 'Time to Pay', + field: 'time' + }, { name: 'amount', align: 'left', @@ -356,12 +384,6 @@ label: 'Balance', field: 'balance' }, - { - name: 'time to pay', - align: 'left', - label: 'Time to Pay', - field: 'time' - }, { name: 'onchain address', align: 'left', @@ -394,11 +416,6 @@ } }, methods: { - updateCountdowns: function () { - setInterval(function(){ - - }, 1000) - }, getWalletLinks: function () { var self = this @@ -410,13 +427,9 @@ this.g.user.wallets[0].inkey ) .then(function (response) { - console.log(response.data) for (i = 0; i < response.data.length; i++) { self.walletLinks.push(response.data[i].id) } - console.log(self.walletLinks) - - return }) .catch(function (error) { @@ -463,25 +476,8 @@ this.g.user.wallets[0].inkey ) .then(function (response) { - console.log(response.data) - var i - var now = parseInt(new Date() / 1000) - for (i = 0; i < response.data.length; i++) { - timeleft = response.data[i].time_to_pay - (now - response.data[i].time) - if (timeleft < 1) { - response.data[i].timeleft = 0 - } - else{ - response.data[i].timeleft = timeleft - } - - } - - self.ChargeLinks = response.data.map(function (obj) { - - - return mapCharge(obj) - }) + console.log(response.data[0].time_elapsed) + self.ChargeLinks = response.data.map(mapCharge) }) .catch(function (error) { LNbits.utils.notifyApiError(error) @@ -491,7 +487,6 @@ var self = this var wallet = self.g.user.wallets[0].adminkey var data = self.formDialogCharge.data - console.log(data) data.amount = parseInt(data.amount) data.time = parseInt(data.time) if (data.id) { @@ -509,7 +504,7 @@ LNbits.api .request( 'PUT', - '/satspay/api/v1/Charge/' + data.id, + '/satspay/api/v1/charge/' + data.id, wallet.adminkey, data) .then(function (response) { self.Charge = _.reject(self.Charge, function (obj) { @@ -531,7 +526,7 @@ this.g.user.wallets[0].inkey ) .then(function (response) { - console.log(response.data) + this.ChargeLinks = response.data.map(mapCharge) }) .catch(function (error) { LNbits.utils.notifyApiError(error) @@ -556,14 +551,13 @@ deleteCharge: function (linkId) { var self = this var link = _.findWhere(this.Charge, {id: linkId}) - console.log(self.g.user.wallets[0].adminkey) LNbits.utils .confirmDialog('Are you sure you want to delete this pay link?') .onOk(function () { LNbits.api .request( 'DELETE', - '/satspay/api/v1/Charge/' + linkId, + '/satspay/api/v1/charge/' + linkId, self.g.user.wallets[0].inkey ) .then(function (response) { @@ -603,7 +597,6 @@ .then(function (response) { self.walletLinks.push(mapWalletLink(response.data)) self.formDialog.show = false - console.log(response.data[1][1]) }) .catch(function (error) { LNbits.utils.notifyApiError(error) @@ -612,7 +605,6 @@ deleteWalletLink: function (linkId) { var self = this var link = _.findWhere(this.walletLinks, {id: linkId}) - console.log(self.g.user.wallets[0].adminkey) LNbits.utils .confirmDialog('Are you sure you want to delete this pay link?') .onOk(function () { @@ -642,15 +634,6 @@ getCharges() var getWalletLinks = this.getWalletLinks getWalletLinks() - var getBalance = this.getBalance - setTimeout(function(){ - for (i = 0; i < self.ChargeLinks.length; i++) { - getBalance(self.ChargeLinks[i].id) - } - }, 5000); - getCharges() - var updateCountdowns = this.updateCountdowns - updateCountdowns() } }) diff --git a/lnbits/extensions/satspay/views.py b/lnbits/extensions/satspay/views.py index 1be0d266..e02e10af 100644 --- a/lnbits/extensions/satspay/views.py +++ b/lnbits/extensions/satspay/views.py @@ -1,4 +1,4 @@ -from quart import g, abort, render_template +from quart import g, abort, render_template, jsonify from http import HTTPStatus from lnbits.decorators import check_user_exists, validate_uuids @@ -16,6 +16,6 @@ async def index(): @satspay_ext.route("/") async def display(charge_id): - charge = get_charge(charge_id) or abort(HTTPStatus.NOT_FOUND, "Charge link does not exist.") - - return await render_template("satspay/display.html", charge=charge) \ No newline at end of file + charge = await get_charge(charge_id) or abort( + HTTPStatus.NOT_FOUND, "Charge link does not exist.") + return await render_template("satspay/display.html", charge=charge) diff --git a/lnbits/extensions/satspay/views_api.py b/lnbits/extensions/satspay/views_api.py index 790dc4b9..70ba78e4 100644 --- a/lnbits/extensions/satspay/views_api.py +++ b/lnbits/extensions/satspay/views_api.py @@ -46,38 +46,32 @@ async def api_charge_create_or_update(charge_id=None): @satspay_ext.route("/api/v1/charges", methods=["GET"]) @api_check_wallet_key("invoice") async def api_charges_retrieve(): - - charges = await get_charges(g.wallet.user) - if not charges: - return ( - jsonify(""), - HTTPStatus.OK - ) - else: - return jsonify([charge._asdict() for charge in charges]), HTTPStatus.OK + try: + return jsonify([{**charge._asdict(), **{"time_elapsed": charge.time_elapsed}, **{"paid": charge.paid}}for charge in await get_charges(g.wallet.user)]), HTTPStatus.OK + except: + return "" @satspay_ext.route("/api/v1/charge/", methods=["GET"]) @api_check_wallet_key("invoice") async def api_charge_retrieve(charge_id): charge = await get_charge(charge_id) - print(charge) if not charge: return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND - return jsonify(charge._asdict()), HTTPStatus.OK + return jsonify({**charge._asdict(), **{"time_elapsed": charge.time_elapsed}, **{"paid": charge.paid}}), HTTPStatus.OK @satspay_ext.route("/api/v1/charge/", methods=["DELETE"]) @api_check_wallet_key("invoice") async def api_charge_delete(charge_id): - charge = await get_watch_wallet(charge_id) + charge = await get_charge(charge_id) if not charge: return jsonify({"message": "Wallet link does not exist."}), HTTPStatus.NOT_FOUND - await delete_watch_wallet(charge_id) + await delete_charge(charge_id) return "", HTTPStatus.NO_CONTENT @@ -85,15 +79,12 @@ async def api_charge_delete(charge_id): #############################BALANCE########################## @satspay_ext.route("/api/v1/charges/balance/", methods=["GET"]) -@api_check_wallet_key("invoice") async def api_charges_balance(charge_id): charge = await check_address_balance(charge_id) + if not charge: - return ( - jsonify(""), - HTTPStatus.OK - ) + return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND else: return jsonify(charge._asdict()), HTTPStatus.OK