From d93b1997357ae3da602a281e43e570fa2bdd2996 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 6 Jul 2022 11:35:11 +0300 Subject: [PATCH 001/106] fix: pass `charge` param as JSON --- .../satspay/templates/satspay/display.html | 16 +++++++++------- lnbits/extensions/satspay/views.py | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/display.html b/lnbits/extensions/satspay/templates/satspay/display.html index 8c577fbed..680e5fbe1 100644 --- a/lnbits/extensions/satspay/templates/satspay/display.html +++ b/lnbits/extensions/satspay/templates/satspay/display.html @@ -226,6 +226,7 @@ mixins: [windowMixin], data() { return { + charge: JSON.parse('{{charge | tojson}}'), newProgress: 0.4, counter: 1, newTimeLeft: '', @@ -246,7 +247,7 @@ startPaymentNotifier() { this.cancelListener() - this.cancelListener = LNbits.event.onInvoicePaid( + this.cancelListener = LNbits.events.onInvoicePaid( this.wallet, payment => { this.checkBalance() @@ -258,7 +259,7 @@ LNbits.api .request( 'GET', - '/satspay/api/v1/charges/balance/{{ charge.id }}', + `/satspay/api/v1/charges/balance/${this.charge.id}`, 'filla' ) .then(function (response) { @@ -316,12 +317,13 @@ } }, created: function () { - console.log('{{ charge.onchainaddress }}' == 'None') - if ('{{ charge.lnbitswallet }}' == 'None') { - this.lnbtc = false - this.onbtc = true - } + console.log('### charge ', this.charge) + this.lnbtc = !!this.charge.lnbitswallet + this.onbtc = !!this.charge.onchainwallet + + // empty for onchain this.wallet.inkey = '{{ wallet_inkey }}' + this.getTheTime() this.getThePercentage() var timerCount = this.timerCount diff --git a/lnbits/extensions/satspay/views.py b/lnbits/extensions/satspay/views.py index d33d5c17e..67dfe1a09 100644 --- a/lnbits/extensions/satspay/views.py +++ b/lnbits/extensions/satspay/views.py @@ -24,14 +24,15 @@ async def index(request: Request, user: User = Depends(check_user_exists)): @satspay_ext.get("/{charge_id}", response_class=HTMLResponse) -async def display(request: Request, charge_id): +async def display(request: Request, charge_id: str): charge = await get_charge(charge_id) if not charge: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Charge link does not exist." ) wallet = await get_wallet(charge.lnbitswallet) + inkey = wallet.inkey if wallet else None return satspay_renderer().TemplateResponse( "satspay/display.html", - {"request": request, "charge": charge, "wallet_key": wallet.inkey}, + {"request": request, "charge": charge.dict(), "wallet_inkey": inkey}, ) From 5a005e830cfe21b09a24363b8bcb05a909f9d03f Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 6 Jul 2022 12:55:34 +0300 Subject: [PATCH 002/106] chore: add a todo --- lnbits/extensions/satspay/models.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lnbits/extensions/satspay/models.py b/lnbits/extensions/satspay/models.py index 7e8080dc9..b0a3a064b 100644 --- a/lnbits/extensions/satspay/models.py +++ b/lnbits/extensions/satspay/models.py @@ -40,6 +40,10 @@ class Charges(BaseModel): @property def time_elapsed(self): + # todo: + # now = datetime.utcnow().timestamp() + # start = datetime.utcfromtimestamp(self.timestamp) + # expiration = (start + timedelta(minutes=self.time)).timestamp() if (self.timestamp + (self.time * 60)) >= time.time(): return False else: From 6cfa8e30bc7c4cb722a03423490945aaa7b1fdc7 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 6 Jul 2022 16:16:29 +0300 Subject: [PATCH 003/106] refactor: replace promises with async/await --- .../satspay/templates/satspay/index.html | 124 ++++++++---------- 1 file changed, 58 insertions(+), 66 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 551b81b8e..7b1ce4927 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -246,7 +246,7 @@ filled dense emit-value - v-model="formDialogCharge.data.onchainwallet" + v-model="onchainwallet" :options="walletLinks" label="Onchain Wallet" /> @@ -401,6 +401,7 @@ show: false, data: { onchain: false, + onchainwallet: '', lnbits: false, description: '', time: null, @@ -426,24 +427,21 @@ self.formDialogCharge.show = false }, - getWalletLinks: function () { - var self = this - - LNbits.api - .request( + getWalletLinks: async function () { + try { + const {data} = await LNbits.api.request( 'GET', '/watchonly/api/v1/wallet', this.g.user.wallets[0].inkey ) - .then(function (response) { - for (i = 0; i < response.data.length; i++) { - self.walletLinks.push(response.data[i].id) - } - return - }) - .catch(function (error) { - LNbits.utils.notifyApiError(error) - }) + this.walletLinks = data.map(w => ({ + id: w.id, + label: w.title + })) + + } catch (error) { + LNbits.utils.notifyApiError(error) + } }, closeFormDialog: function () { this.formDialog.data = { @@ -457,22 +455,17 @@ self.current = linkId self.Addresses.show = true }, - getCharges: function () { - var self = this - var getAddressBalance = this.getAddressBalance - - LNbits.api - .request( + getCharges: async function () { + try { + const {data} = await LNbits.api.request( 'GET', '/satspay/api/v1/charges', this.g.user.wallets[0].inkey ) - .then(function (response) { - self.ChargeLinks = response.data.map(mapCharge) - }) - .catch(function (error) { - LNbits.utils.notifyApiError(error) - }) + this.ChargeLinks = data.map(mapCharge) + } catch (error) { + LNbits.utils.notifyApiError(error) + } }, sendFormDataCharge: function () { var self = this @@ -480,6 +473,7 @@ var data = this.formDialogCharge.data data.amount = parseInt(data.amount) data.time = parseInt(data.time) + data.onchainwallet = this.onchainwallet?.id this.createCharge(wallet, data) }, timerCount: function () { @@ -487,40 +481,40 @@ var refreshIntervalId = setInterval(function () { for (i = 0; i < self.ChargeLinks.length - 1; i++) { if (self.ChargeLinks[i]['paid'] == 'True') { - setTimeout(function () { - LNbits.api - .request( - 'GET', - '/satspay/api/v1/charges/balance/' + - self.ChargeLinks[i]['id'], - 'filla' - ) - .then(function (response) {}) + setTimeout(async function () { + await LNbits.api.request( + 'GET', + '/satspay/api/v1/charges/balance/' + + self.ChargeLinks[i]['id'], + 'filla' + ) }, 2000) } } self.getCharges() }, 20000) }, - createCharge: function (wallet, data) { - var self = this + createCharge: async function (wallet, data) { + try { + const resp = await LNbits.api.request( + 'POST', + '/satspay/api/v1/charge', + wallet, + data + ) - LNbits.api - .request('POST', '/satspay/api/v1/charge', wallet, data) - .then(function (response) { - self.ChargeLinks.push(mapCharge(response.data)) - self.formDialogCharge.show = false - self.formDialogCharge.data = { - onchain: false, - lnbits: false, - description: '', - time: null, - amount: null - } - }) - .catch(function (error) { - LNbits.utils.notifyApiError(error) - }) + this.ChargeLinks.push(mapCharge(resp.data)) + this.formDialogCharge.show = false + this.formDialogCharge.data = { + onchain: false, + lnbits: false, + description: '', + time: null, + amount: null + } + } catch (error) { + LNbits.utils.notifyApiError(error) + } }, deleteChargeLink: function (chargeId) { @@ -528,26 +522,24 @@ var link = _.findWhere(this.ChargeLinks, {id: chargeId}) LNbits.utils .confirmDialog('Are you sure you want to delete this pay link?') - .onOk(function () { - LNbits.api - .request( + .onOk(async function () { + try { + const response = await LNbits.api.request( 'DELETE', '/satspay/api/v1/charge/' + chargeId, self.g.user.wallets[0].adminkey ) - .then(function (response) { - self.ChargeLinks = _.reject(self.ChargeLinks, function (obj) { - return obj.id === chargeId - }) - }) - .catch(function (error) { - LNbits.utils.notifyApiError(error) + + self.ChargeLinks = _.reject(self.ChargeLinks, function (obj) { + return obj.id === chargeId }) + } catch (error) { + LNbits.utils.notifyApiError(error) + } }) }, exportchargeCSV: function () { - var self = this - LNbits.utils.exportCSV(self.ChargesTable.columns, this.ChargeLinks) + LNbits.utils.exportCSV(this.ChargesTable.columns, this.ChargeLinks) } }, created: function () { From 50b2dcfcaac793a370d52883286c6fe276747578 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 6 Jul 2022 16:19:33 +0300 Subject: [PATCH 004/106] refactor: clean-up unnecessary `self` --- .../satspay/templates/satspay/index.html | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 7b1ce4927..b050b95e1 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -416,15 +416,14 @@ }, methods: { cancelCharge: function (data) { - var self = this - self.formDialogCharge.data.description = '' - self.formDialogCharge.data.onchainwallet = '' - self.formDialogCharge.data.lnbitswallet = '' - self.formDialogCharge.data.time = null - self.formDialogCharge.data.amount = null - self.formDialogCharge.data.webhook = '' - self.formDialogCharge.data.completelink = '' - self.formDialogCharge.show = false + this.formDialogCharge.data.description = '' + this.formDialogCharge.data.onchainwallet = '' + this.formDialogCharge.data.lnbitswallet = '' + this.formDialogCharge.data.time = null + this.formDialogCharge.data.amount = null + this.formDialogCharge.data.webhook = '' + this.formDialogCharge.data.completelink = '' + this.formDialogCharge.show = false }, getWalletLinks: async function () { @@ -449,11 +448,10 @@ } }, openQrCodeDialog: function (linkId) { - var self = this var getAddresses = this.getAddresses getAddresses(linkId) - self.current = linkId - self.Addresses.show = true + this.current = linkId + this.Addresses.show = true }, getCharges: async function () { try { @@ -468,30 +466,28 @@ } }, sendFormDataCharge: function () { - var self = this - var wallet = this.g.user.wallets[0].inkey - var data = this.formDialogCharge.data + const wallet = this.g.user.wallets[0].inkey + const data = this.formDialogCharge.data data.amount = parseInt(data.amount) data.time = parseInt(data.time) data.onchainwallet = this.onchainwallet?.id this.createCharge(wallet, data) }, timerCount: function () { - self = this - var refreshIntervalId = setInterval(function () { - for (i = 0; i < self.ChargeLinks.length - 1; i++) { - if (self.ChargeLinks[i]['paid'] == 'True') { + var refreshIntervalId = setInterval( () => { + for (i = 0; i < this.ChargeLinks.length - 1; i++) { + if (this.ChargeLinks[i]['paid'] == 'True') { setTimeout(async function () { await LNbits.api.request( 'GET', '/satspay/api/v1/charges/balance/' + - self.ChargeLinks[i]['id'], + this.ChargeLinks[i]['id'], 'filla' ) }, 2000) } } - self.getCharges() + this.getCharges() }, 20000) }, createCharge: async function (wallet, data) { @@ -518,19 +514,18 @@ }, deleteChargeLink: function (chargeId) { - var self = this var link = _.findWhere(this.ChargeLinks, {id: chargeId}) LNbits.utils .confirmDialog('Are you sure you want to delete this pay link?') - .onOk(async function () { + .onOk(async () => { try { const response = await LNbits.api.request( 'DELETE', '/satspay/api/v1/charge/' + chargeId, - self.g.user.wallets[0].adminkey + this.g.user.wallets[0].adminkey ) - self.ChargeLinks = _.reject(self.ChargeLinks, function (obj) { + this.ChargeLinks = _.reject(this.ChargeLinks, function (obj) { return obj.id === chargeId }) } catch (error) { @@ -544,7 +539,6 @@ }, created: function () { console.log(this.g.user) - var self = this var getCharges = this.getCharges getCharges() var getWalletLinks = this.getWalletLinks From 8e05a11978a3e9883a98b33c17f9758a44c1bdc6 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 6 Jul 2022 16:39:23 +0300 Subject: [PATCH 005/106] refactor: replace `var` with `const` --- .../satspay/templates/satspay/index.html | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index b050b95e1..343a163a4 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -287,7 +287,7 @@ From b5e97f08a6e79c9ac65f08e544e9e14b32ec51ce Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 6 Jul 2022 16:45:03 +0300 Subject: [PATCH 006/106] chore: code clean-up --- .../satspay/templates/satspay/index.html | 49 ++++++------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 343a163a4..0d212109b 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -38,10 +38,10 @@ @@ -330,6 +436,12 @@ label: 'Balance', field: 'balance' }, + { + name: 'pendingBalance', + align: 'left', + label: 'Pending Balance', + field: 'pendingBalance' + }, { name: 'onchain address', align: 'left', @@ -394,7 +506,7 @@ ) this.walletLinks = data.map(w => ({ id: w.id, - label: w.title + label: w.title + ' - ' + w.id })) } catch (error) { LNbits.utils.notifyApiError(error) @@ -413,6 +525,16 @@ LNbits.utils.notifyApiError(error) } }, + getOnchainWalletName: function (walletId) { + const wallet = this.walletLinks.find(w => w.id === walletId) + if (!wallet) return 'unknown' + return wallet.label + }, + getLNbitsWalletName: function (walletId) { + const wallet = this.g.user.walletOptions.find(w => w.value === walletId) + if (!wallet) return 'unknown' + return wallet.label + }, getCharges: async function () { try { @@ -421,7 +543,13 @@ '/satspay/api/v1/charges', this.g.user.wallets[0].inkey ) - this.chargeLinks = data.map(mapCharge) + this.chargeLinks = data.map(c => + mapCharge( + c, + this.chargeLinks.find(old => old.id === c.id) + ) + ) + console.log('### this.chargeLinks', this.chargeLinks) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -466,7 +594,7 @@ }) const utxos = await retryWithDelay(fn) - charge.balance = utxos.reduce((t, u) => t + u.value, 0) + charge.pendingBalance = utxos.reduce((t, u) => t + u.value, 0) } } catch (error) { console.error(error) From 4cb54ce549a2811f541be3769013cd73122afa50 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 8 Jul 2022 15:58:43 +0300 Subject: [PATCH 031/106] feat: allow refresh balance for individual charge - expired or paid charges are not auto-refreshed --- .../satspay/templates/satspay/index.html | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 7c0f36ce4..3c4418be3 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -208,16 +208,27 @@
- Details
+ Details + Refresh Balance +
Date: Fri, 8 Jul 2022 16:37:35 +0300 Subject: [PATCH 032/106] feat: use custom mempool_endpoint for the charge details --- lnbits/extensions/satspay/crud.py | 2 +- .../satspay/templates/satspay/display.html | 18 ++++++++++++++---- .../satspay/templates/satspay/index.html | 12 ++++++------ lnbits/extensions/satspay/views.py | 9 ++++++++- lnbits/extensions/satspay/views_api.py | 1 - 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lnbits/extensions/satspay/crud.py b/lnbits/extensions/satspay/crud.py index 65f9e2281..be681dc21 100644 --- a/lnbits/extensions/satspay/crud.py +++ b/lnbits/extensions/satspay/crud.py @@ -6,7 +6,7 @@ from lnbits.core.services import create_invoice from lnbits.core.views.api import api_payment from lnbits.helpers import urlsafe_short_hash -from ..watchonly.crud import get_fresh_address, get_config, get_watch_wallet +from ..watchonly.crud import get_fresh_address, get_config # from lnbits.db import open_ext_db from . import db diff --git a/lnbits/extensions/satspay/templates/satspay/display.html b/lnbits/extensions/satspay/templates/satspay/display.html index b6d2019d9..94ff5e002 100644 --- a/lnbits/extensions/satspay/templates/satspay/display.html +++ b/lnbits/extensions/satspay/templates/satspay/display.html @@ -215,7 +215,15 @@ class="row items-center" >
- + +
@@ -294,6 +302,7 @@ data() { return { charge: JSON.parse('{{charge_data | tojson}}'), + mempool_endpoint: '{{mempool_endpoint}}', pendingFunds: 0, ws: null, newProgress: 0.4, @@ -339,7 +348,9 @@ checkPendingOnchain: async function () { const { bitcoin: {addresses: addressesAPI} - } = mempoolJS() + } = mempoolJS({ + hostname: new URL(this.mempool_endpoint).hostname + }) try { const utxos = await addressesAPI.getAddressTxsUtxo({ @@ -394,7 +405,7 @@ const { bitcoin: {websocket} } = mempoolJS({ - hostname: 'mempool.space' + hostname: new URL(this.mempool_endpoint).hostname }) this.ws = new WebSocket('wss://mempool.space/api/v1/ws') @@ -434,7 +445,6 @@ } }, created: async function () { - console.log('### charge', this.charge) if (this.charge.lnbitswallet) this.payInvoice() else this.payOnchain() await this.checkBalances() diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 3c4418be3..0e02285db 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -532,6 +532,8 @@ this.g.user.wallets[0].inkey ) this.mempool.endpoint = data.mempool_endpoint + const url = new URL(this.mempool.endpoint) + this.mempool.hostname = url.hostname } catch (error) { LNbits.utils.notifyApiError(error) } @@ -560,7 +562,6 @@ this.chargeLinks.find(old => old.id === c.id) ) ) - console.log('### this.chargeLinks', this.chargeLinks) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -587,7 +588,7 @@ await this.getCharges() }, 20000) }, - refreshBalance: async function(charge) { + refreshBalance: async function (charge) { try { const {data} = await LNbits.api.request( 'GET', @@ -595,16 +596,15 @@ 'filla' ) charge.balance = data.balance - } catch (error) { - - } + } catch (error) {} }, rescanOnchainAddresses: async function () { if (this.rescanning) return this.rescanning = true + const { bitcoin: {addresses: addressesAPI} - } = mempoolJS() + } = mempoolJS({hostname: this.mempool.hostname}) try { const onchainActiveCharges = this.chargeLinks.filter( diff --git a/lnbits/extensions/satspay/views.py b/lnbits/extensions/satspay/views.py index d4fc457df..5b641510a 100644 --- a/lnbits/extensions/satspay/views.py +++ b/lnbits/extensions/satspay/views.py @@ -9,6 +9,7 @@ from starlette.responses import HTMLResponse from lnbits.core.crud import get_wallet from lnbits.core.models import User from lnbits.decorators import check_user_exists +from lnbits.extensions.watchonly.crud import get_config from . import satspay_ext, satspay_renderer from .crud import get_charge @@ -31,8 +32,14 @@ async def display(request: Request, charge_id: str): status_code=HTTPStatus.NOT_FOUND, detail="Charge link does not exist." ) wallet = await get_wallet(charge.lnbitswallet) + onchainwallet_config = await get_config(charge.user) inkey = wallet.inkey if wallet else None return satspay_renderer().TemplateResponse( "satspay/display.html", - {"request": request, "charge_data": charge.dict(), "wallet_inkey": inkey}, + { + "request": request, + "charge_data": charge.dict(), + "wallet_inkey": inkey, + "mempool_endpoint": onchainwallet_config.mempool_endpoint, + }, ) diff --git a/lnbits/extensions/satspay/views_api.py b/lnbits/extensions/satspay/views_api.py index 5aaf04f13..43593cb39 100644 --- a/lnbits/extensions/satspay/views_api.py +++ b/lnbits/extensions/satspay/views_api.py @@ -1,7 +1,6 @@ from http import HTTPStatus import httpx -from fastapi import Query from fastapi.params import Depends from starlette.exceptions import HTTPException From 86f7ea64c4dd5e801b82fda9a966a552fb6de473 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 10:22:12 +0300 Subject: [PATCH 033/106] fix: use the config mempool.space endpoint --- lnbits/extensions/watchonly/static/js/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lnbits/extensions/watchonly/static/js/index.js b/lnbits/extensions/watchonly/static/js/index.js index 5eee21761..31644f185 100644 --- a/lnbits/extensions/watchonly/static/js/index.js +++ b/lnbits/extensions/watchonly/static/js/index.js @@ -647,7 +647,7 @@ new Vue({ getAddressTxsDelayed: async function (addrData) { const { bitcoin: {addresses: addressesAPI} - } = mempoolJS() + } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) const fn = async () => addressesAPI.getAddressTxs({ @@ -660,7 +660,7 @@ new Vue({ refreshRecommendedFees: async function () { const { bitcoin: {fees: feesAPI} - } = mempoolJS() + } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) const fn = async () => feesAPI.getFeesRecommended() this.payment.recommededFees = await retryWithDelay(fn) @@ -668,7 +668,7 @@ new Vue({ getAddressTxsUtxoDelayed: async function (address) { const { bitcoin: {addresses: addressesAPI} - } = mempoolJS() + } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) const fn = async () => addressesAPI.getAddressTxsUtxo({ @@ -679,7 +679,7 @@ new Vue({ fetchTxHex: async function (txId) { const { bitcoin: {transactions: transactionsAPI} - } = mempoolJS() + } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) try { const response = await transactionsAPI.getTxHex({txid: txId}) From e960285c8f694f9191183acbfb4007f659259af4 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 10:35:27 +0300 Subject: [PATCH 034/106] chore: code format --- lnbits/extensions/watchonly/static/js/index.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lnbits/extensions/watchonly/static/js/index.js b/lnbits/extensions/watchonly/static/js/index.js index 31644f185..f44d30cd1 100644 --- a/lnbits/extensions/watchonly/static/js/index.js +++ b/lnbits/extensions/watchonly/static/js/index.js @@ -647,7 +647,9 @@ new Vue({ getAddressTxsDelayed: async function (addrData) { const { bitcoin: {addresses: addressesAPI} - } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) + } = mempoolJS({ + hostname: new URL(this.config.data.mempool_endpoint).hostname + }) const fn = async () => addressesAPI.getAddressTxs({ @@ -660,7 +662,9 @@ new Vue({ refreshRecommendedFees: async function () { const { bitcoin: {fees: feesAPI} - } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) + } = mempoolJS({ + hostname: new URL(this.config.data.mempool_endpoint).hostname + }) const fn = async () => feesAPI.getFeesRecommended() this.payment.recommededFees = await retryWithDelay(fn) @@ -668,7 +672,9 @@ new Vue({ getAddressTxsUtxoDelayed: async function (address) { const { bitcoin: {addresses: addressesAPI} - } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) + } = mempoolJS({ + hostname: new URL(this.config.data.mempool_endpoint).hostname + }) const fn = async () => addressesAPI.getAddressTxsUtxo({ @@ -679,7 +685,9 @@ new Vue({ fetchTxHex: async function (txId) { const { bitcoin: {transactions: transactionsAPI} - } = mempoolJS({hostname: new URL(this.config.data.mempool_endpoint).hostname}) + } = mempoolJS({ + hostname: new URL(this.config.data.mempool_endpoint).hostname + }) try { const response = await transactionsAPI.getTxHex({txid: txId}) From 31b6a9410c3ed078373abae349897b11929dc2cb Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 10:36:03 +0300 Subject: [PATCH 035/106] refactor: move setInterval outside method logic --- .../satspay/templates/satspay/index.html | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 0e02285db..1879925fd 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -574,19 +574,17 @@ data.onchainwallet = this.onchainwallet?.id this.createCharge(wallet, data) }, - timerCount: function () { - setInterval(async () => { - const activeLinkIds = this.chargeLinks - .filter(c => !c.paid && !c.time_elapsed) - .map(c => c.id) - .join(',') - await LNbits.api.request( - 'GET', - '/satspay/api/v1/charges/balance/' + activeLinkIds, - 'filla' - ) - await this.getCharges() - }, 20000) + refreshActiveChargesBalance: async function () { + const activeLinkIds = this.chargeLinks + .filter(c => !c.paid && !c.time_elapsed) + .map(c => c.id) + .join(',') + await LNbits.api.request( + 'GET', + '/satspay/api/v1/charges/balance/' + activeLinkIds, + 'filla' + ) + await this.getCharges() }, refreshBalance: async function (charge) { try { @@ -617,7 +615,9 @@ }) const utxos = await retryWithDelay(fn) - charge.pendingBalance = utxos.reduce((t, u) => t + u.value, 0) + charge.pendingBalance = utxos + .filter(u => !u.status.confirmed) + .reduce((t, u) => t + u.value, 0) } } catch (error) { console.error(error) @@ -669,14 +669,18 @@ }) }, exportchargeCSV: function () { - LNbits.utils.exportCSV(this.chargesTable.columns, this.chargeLinks) + LNbits.utils.exportCSV( + this.chargesTable.columns, + this.chargeLinks, + 'charges' + ) } }, created: async function () { await this.getCharges() await this.getWalletLinks() await this.getWalletConfig() - this.timerCount() + setInterval(() => this.refreshActiveChargesBalance(), 10 * 2000) await this.rescanOnchainAddresses() setInterval(() => this.rescanOnchainAddresses(), 10 * 1000) } From 057de41678af1c35869ac6521f9816d2e4d34ab8 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 11:13:26 +0300 Subject: [PATCH 036/106] feat: only refresh balance on the back-end if new funds are detected by the front-end refresh --- .../satspay/templates/satspay/display.html | 11 +++++++++++ .../extensions/satspay/templates/satspay/index.html | 12 +++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lnbits/extensions/satspay/templates/satspay/display.html b/lnbits/extensions/satspay/templates/satspay/display.html index 94ff5e002..a60bce17d 100644 --- a/lnbits/extensions/satspay/templates/satspay/display.html +++ b/lnbits/extensions/satspay/templates/satspay/display.html @@ -329,6 +329,9 @@ ) }, checkBalances: async function () { + console.log('### checkBalances 1', this.charge.hasStaleBalance) + if (!this.charge.hasStaleBalance) return + console.log('### checkBalances 2') try { const {data} = await LNbits.api.request( 'GET', @@ -356,10 +359,18 @@ const utxos = await addressesAPI.getAddressTxsUtxo({ address: this.charge.onchainaddress }) + const newBalance = utxos.reduce((t, u) => t + u.value, 0) + this.charge.hasStaleBalance = this.charge.balance === newBalance this.pendingFunds = utxos .filter(u => !u.status.confirmed) .reduce((t, u) => t + u.value, 0) + + console.log( + '### charge new funds', + this.charge.balance === newBalance, + this.charge + ) } catch (error) { console.error('cannot check pending funds') } diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 1879925fd..c007b44ac 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -576,9 +576,10 @@ }, refreshActiveChargesBalance: async function () { const activeLinkIds = this.chargeLinks - .filter(c => !c.paid && !c.time_elapsed) + .filter(c => !c.paid && !c.time_elapsed && !c.hasStaleBalance) .map(c => c.id) .join(',') + console.log('### activeLinkIds', activeLinkIds) await LNbits.api.request( 'GET', '/satspay/api/v1/charges/balance/' + activeLinkIds, @@ -615,9 +616,18 @@ }) const utxos = await retryWithDelay(fn) + const newBalance = utxos.reduce((t, u) => t + u.value, 0) + charge.pendingBalance = utxos .filter(u => !u.status.confirmed) .reduce((t, u) => t + u.value, 0) + + charge.hasStaleBalance = charge.balance === newBalance + console.log( + '### charge new funds', + charge.balance === newBalance, + charge + ) } } catch (error) { console.error(error) From 25f37b0e4fc4181b654cf863fba7a809bf17f69d Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 11:26:43 +0300 Subject: [PATCH 037/106] chore: code clean-up --- lnbits/extensions/satspay/templates/satspay/display.html | 8 -------- lnbits/extensions/satspay/templates/satspay/index.html | 6 ------ 2 files changed, 14 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/display.html b/lnbits/extensions/satspay/templates/satspay/display.html index a60bce17d..58f6b51c4 100644 --- a/lnbits/extensions/satspay/templates/satspay/display.html +++ b/lnbits/extensions/satspay/templates/satspay/display.html @@ -329,9 +329,7 @@ ) }, checkBalances: async function () { - console.log('### checkBalances 1', this.charge.hasStaleBalance) if (!this.charge.hasStaleBalance) return - console.log('### checkBalances 2') try { const {data} = await LNbits.api.request( 'GET', @@ -365,12 +363,6 @@ this.pendingFunds = utxos .filter(u => !u.status.confirmed) .reduce((t, u) => t + u.value, 0) - - console.log( - '### charge new funds', - this.charge.balance === newBalance, - this.charge - ) } catch (error) { console.error('cannot check pending funds') } diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index c007b44ac..abef0291b 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -579,7 +579,6 @@ .filter(c => !c.paid && !c.time_elapsed && !c.hasStaleBalance) .map(c => c.id) .join(',') - console.log('### activeLinkIds', activeLinkIds) await LNbits.api.request( 'GET', '/satspay/api/v1/charges/balance/' + activeLinkIds, @@ -623,11 +622,6 @@ .reduce((t, u) => t + u.value, 0) charge.hasStaleBalance = charge.balance === newBalance - console.log( - '### charge new funds', - charge.balance === newBalance, - charge - ) } } catch (error) { console.error(error) From e4078504bac93f8e1e88eb7fb1f38ef1a03f2640 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:03:19 +0300 Subject: [PATCH 038/106] fix: do not update charge if balance has not changed --- lnbits/extensions/satspay/crud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnbits/extensions/satspay/crud.py b/lnbits/extensions/satspay/crud.py index be681dc21..dfc5c47af 100644 --- a/lnbits/extensions/satspay/crud.py +++ b/lnbits/extensions/satspay/crud.py @@ -111,7 +111,7 @@ async def check_address_balance(charge_id: str) -> List[Charges]: + charge.onchainaddress ) respAmount = r.json()["chain_stats"]["funded_txo_sum"] - if respAmount >= charge.balance: + if respAmount > charge.balance: await update_charge(charge_id=charge_id, balance=respAmount) except Exception: pass From d79d4e371e78a3bba372326b744ef7fe91c9cd6c Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:03:48 +0300 Subject: [PATCH 039/106] feat: use `datetime` to compute `time_left` and `time_elapsed` --- lnbits/extensions/satspay/models.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lnbits/extensions/satspay/models.py b/lnbits/extensions/satspay/models.py index b0a3a064b..325ce817e 100644 --- a/lnbits/extensions/satspay/models.py +++ b/lnbits/extensions/satspay/models.py @@ -1,4 +1,4 @@ -import time +from datetime import datetime, timedelta from sqlite3 import Row from typing import Optional @@ -38,16 +38,17 @@ class Charges(BaseModel): def from_row(cls, row: Row) -> "Charges": return cls(**dict(row)) + @property + def time_left(self): + now = datetime.utcnow().timestamp() + start = datetime.fromtimestamp(self.timestamp) + expiration = (start + timedelta(minutes=self.time)).timestamp() + return (expiration - now) / 60 + @property def time_elapsed(self): - # todo: - # now = datetime.utcnow().timestamp() - # start = datetime.utcfromtimestamp(self.timestamp) - # expiration = (start + timedelta(minutes=self.time)).timestamp() - if (self.timestamp + (self.time * 60)) >= time.time(): - return False - else: - return True + return self.time_left < 0 + @property def paid(self): From 8c6b31ec123c247abacd6d4b0fa96f7631b7489c Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:05:12 +0300 Subject: [PATCH 040/106] feat: `mapCharge` now computes fields `progress`, `timeLeft` and fixes `time` --- lnbits/extensions/satspay/static/js/utils.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lnbits/extensions/satspay/static/js/utils.js b/lnbits/extensions/satspay/static/js/utils.js index 535615af5..5f686755f 100644 --- a/lnbits/extensions/satspay/static/js/utils.js +++ b/lnbits/extensions/satspay/static/js/utils.js @@ -15,20 +15,20 @@ const retryWithDelay = async function (fn, retryCount = 0) { const mapCharge = (obj, oldObj = {}) => { obj._data = _.clone(obj) - obj.theTime = obj.time * 60 - (Date.now() / 1000 - obj.timestamp) - obj.time = obj.time + ' min' - if (obj.time_elapsed) { - obj.date = '' - } else { - obj.date = Quasar.utils.date.formatDate( - new Date((obj.theTime - 3600) * 1000), - 'HH:mm:ss' - ) - } + obj.progress = obj.time_left < 0 ? 1 : 1 - obj.time_left / obj.time + obj.time = minutesToShortTime(obj.time) + obj.timeLeft = minutesToTime(obj.time_left) + obj.expanded = false obj.displayUrl = ['/satspay/', obj.id].join('') obj.expanded = oldObj.expanded obj.pendingBalance = oldObj.pendingBalance || 0 return obj } + +const minutesToTime = min => + min > 0 ? new Date(min * 1000).toISOString().substring(11, 19) : '' + +const minutesToShortTime = min => + min > 0 ? new Date(min * 1000).toISOString().substring(14, 22) : '' From 0f204485c37115534539a73e193916ac39382af1 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:05:45 +0300 Subject: [PATCH 041/106] feat: return `time_elapsed`, `time_left` and `paid` fields --- lnbits/extensions/satspay/views_api.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lnbits/extensions/satspay/views_api.py b/lnbits/extensions/satspay/views_api.py index 43593cb39..f94b970af 100644 --- a/lnbits/extensions/satspay/views_api.py +++ b/lnbits/extensions/satspay/views_api.py @@ -30,7 +30,12 @@ async def api_charge_create( data: CreateCharge, wallet: WalletTypeInfo = Depends(require_invoice_key) ): charge = await create_charge(user=wallet.wallet.user, data=data) - return charge.dict() + return { + **charge.dict(), + **{"time_elapsed": charge.time_elapsed}, + **{"time_left": charge.time_left}, + **{"paid": charge.paid}, + } @satspay_ext.put("/api/v1/charge/{charge_id}") @@ -50,6 +55,7 @@ async def api_charges_retrieve(wallet: WalletTypeInfo = Depends(get_key_type)): { **charge.dict(), **{"time_elapsed": charge.time_elapsed}, + **{"time_left": charge.time_left}, **{"paid": charge.paid}, } for charge in await get_charges(wallet.wallet.user) @@ -72,6 +78,7 @@ async def api_charge_retrieve( return { **charge.dict(), **{"time_elapsed": charge.time_elapsed}, + **{"time_left": charge.time_left}, **{"paid": charge.paid}, } @@ -133,4 +140,9 @@ async def api_charge_balance(charge_id): ) except AssertionError: charge.webhook = None - return charge.dict() + return { + **charge.dict(), + **{"time_elapsed": charge.time_elapsed}, + **{"time_left": charge.time_left}, + **{"paid": charge.paid}, + } From 46a7b54a00a40c878383c36e6611f8577e23008e Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:06:33 +0300 Subject: [PATCH 042/106] fix: fix progress for charges --- .../satspay/templates/satspay/display.html | 63 ++++++++----------- .../satspay/templates/satspay/index.html | 15 +++-- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/display.html b/lnbits/extensions/satspay/templates/satspay/display.html index 58f6b51c4..02bec9303 100644 --- a/lnbits/extensions/satspay/templates/satspay/display.html +++ b/lnbits/extensions/satspay/templates/satspay/display.html @@ -13,7 +13,7 @@
Time elapsed
@@ -25,14 +25,18 @@ Charge paid
- + Awaiting payment... - {% raw %} {{ newTimeLeft }} {% endraw %} @@ -155,7 +159,7 @@
-
+
-
+
-
+
= this.charge.amount) { - this.charge.paid = true - } + this.charge = mapCharge(data, this.charge) + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }, + refreshCharge: async function () { + try { + const {data} = await LNbits.api.request( + 'GET', + `/satspay/api/v1/charge/${this.charge.id}` + ) + this.charge = mapCharge(data, this.charge) + console.log('### ', this.charge) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -375,28 +380,13 @@ this.lnbtc = false this.onbtc = true }, - refreshExpirationTime: function () { - this.timetoComplete = - parseInt(this.charge.time) * 60 - - (Date.now() / 1000 - parseInt(this.charge.timestamp)) - this.newTimeLeft = Quasar.utils.date.formatDate( - new Date((this.timeToComplete - 3600) * 1000), - 'HH:mm:ss' - ) - }, - refreshProgres: function () { - this.refreshExpirationTime() - this.newProgress = - 1 - this.timeToComplete / (parseInt(this.charge.time) * 60) - }, loopRefresh: function () { // invoice only const refreshIntervalId = setInterval(async () => { - if (this.charge.paid || this.timetoComplete < 1) { + if (this.charge.paid || !this.charge.timeLeft) { clearInterval(refreshIntervalId) } - this.refreshProgres() if (this.counter % 10 === 0) { await this.checkBalances() await this.checkPendingOnchain() @@ -456,7 +446,6 @@ this.wallet.inkey = '{{ wallet_inkey }}' this.startPaymentNotifier() - this.refreshProgres() if (!this.charge.paid) { this.loopRefresh() } diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index abef0291b..7158453ff 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -125,8 +125,13 @@ >{{props.row.description}} - -
{{props.row.date}}
+ +
{{props.row.timeLeft}}
+ +
{{props.row.time}}
@@ -424,10 +429,10 @@ field: 'description' }, { - name: 'timeleft', + name: 'timeLeft', align: 'left', label: 'Time left', - field: 'date' + field: 'timeLeft' }, { name: 'time to pay', @@ -638,7 +643,7 @@ data ) - this.chargeLinks.push(mapCharge(resp.data)) + this.chargeLinks.unshift(mapCharge(resp.data)) this.formDialogCharge.show = false this.formDialogCharge.data = { onchain: false, From c419afc1b12b7a9658913bfcb1f5ca4450e24e26 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:14:51 +0300 Subject: [PATCH 043/106] refactor: code clean-up --- lnbits/extensions/satspay/static/js/utils.js | 24 +++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lnbits/extensions/satspay/static/js/utils.js b/lnbits/extensions/satspay/static/js/utils.js index 5f686755f..9015803df 100644 --- a/lnbits/extensions/satspay/static/js/utils.js +++ b/lnbits/extensions/satspay/static/js/utils.js @@ -14,21 +14,19 @@ const retryWithDelay = async function (fn, retryCount = 0) { } const mapCharge = (obj, oldObj = {}) => { - obj._data = _.clone(obj) + const charge = _.clone(obj) - obj.progress = obj.time_left < 0 ? 1 : 1 - obj.time_left / obj.time - obj.time = minutesToShortTime(obj.time) - obj.timeLeft = minutesToTime(obj.time_left) + charge.progress = obj.time_left < 0 ? 1 : 1 - obj.time_left / obj.time + charge.time = minutesToTime(obj.time) + charge.timeLeft = minutesToTime(obj.time_left) - obj.expanded = false - obj.displayUrl = ['/satspay/', obj.id].join('') - obj.expanded = oldObj.expanded - obj.pendingBalance = oldObj.pendingBalance || 0 - return obj + charge.expanded = false + charge.displayUrl = ['/satspay/', obj.id].join('') + charge.expanded = oldObj.expanded + charge.pendingBalance = oldObj.pendingBalance || 0 + console.log('### charge', charge) + return charge } const minutesToTime = min => - min > 0 ? new Date(min * 1000).toISOString().substring(11, 19) : '' - -const minutesToShortTime = min => - min > 0 ? new Date(min * 1000).toISOString().substring(14, 22) : '' + min > 0 ? new Date(min * 1000).toISOString().substring(14, 19) : '' From 739c108bdf5b36821e42070bf004c84f5418c20b Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Mon, 11 Jul 2022 15:15:12 +0300 Subject: [PATCH 044/106] feat: add `(hh:mm)` to time columns --- lnbits/extensions/satspay/templates/satspay/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lnbits/extensions/satspay/templates/satspay/index.html b/lnbits/extensions/satspay/templates/satspay/index.html index 7158453ff..3108324e7 100644 --- a/lnbits/extensions/satspay/templates/satspay/index.html +++ b/lnbits/extensions/satspay/templates/satspay/index.html @@ -58,10 +58,10 @@