@@ -218,7 +222,7 @@
@@ -303,7 +311,8 @@
data() {
return {
charge: JSON.parse('{{charge_data | tojson}}'),
- mempool_endpoint: '{{mempool_endpoint}}',
+ mempoolEndpoint: '{{mempool_endpoint}}',
+ network: '{{network}}',
pendingFunds: 0,
ws: null,
newProgress: 0.4,
@@ -316,19 +325,19 @@
cancelListener: () => {}
}
},
+ computed: {
+ mempoolHostname: function () {
+ let hostname = new URL(this.mempoolEndpoint).hostname
+ if (this.network === 'Testnet') {
+ hostname += '/testnet'
+ }
+ return hostname
+ }
+ },
methods: {
- startPaymentNotifier() {
- this.cancelListener()
- if (!this.lnbitswallet) return
- this.cancelListener = LNbits.events.onInvoicePaid(
- this.wallet,
- payment => {
- this.checkInvoiceBalance()
- }
- )
- },
checkBalances: async function () {
- if (this.charge.hasStaleBalance) return
+ if (!this.charge.payment_request && this.charge.hasOnchainStaleBalance)
+ return
try {
const {data} = await LNbits.api.request(
'GET',
@@ -345,7 +354,7 @@
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS({
- hostname: new URL(this.mempool_endpoint).hostname
+ hostname: new URL(this.mempoolEndpoint).hostname
})
try {
@@ -353,7 +362,8 @@
address: this.charge.onchainaddress
})
const newBalance = utxos.reduce((t, u) => t + u.value, 0)
- this.charge.hasStaleBalance = this.charge.balance === newBalance
+ this.charge.hasOnchainStaleBalance =
+ this.charge.balance === newBalance
this.pendingFunds = utxos
.filter(u => !u.status.confirmed)
@@ -388,10 +398,10 @@
const {
bitcoin: {websocket}
} = mempoolJS({
- hostname: new URL(this.mempool_endpoint).hostname
+ hostname: new URL(this.mempoolEndpoint).hostname
})
- this.ws = new WebSocket('wss://mempool.space/api/v1/ws')
+ this.ws = new WebSocket(`wss://${this.mempoolHostname}/api/v1/ws`)
this.ws.addEventListener('open', x => {
if (this.charge.onchainaddress) {
this.trackAddress(this.charge.onchainaddress)
@@ -428,13 +438,10 @@
}
},
created: async function () {
- if (this.charge.lnbitswallet) this.payInvoice()
+ if (this.charge.payment_request) this.payInvoice()
else this.payOnchain()
- await this.checkBalances()
- // empty for onchain
- this.wallet.inkey = '{{ wallet_inkey }}'
- this.startPaymentNotifier()
+ await this.checkBalances()
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 396200cf1..60c4d5199 100644
--- a/lnbits/extensions/satspay/templates/satspay/index.html
+++ b/lnbits/extensions/satspay/templates/satspay/index.html
@@ -203,9 +203,14 @@
:href="props.row.webhook"
target="_blank"
style="color: unset; text-decoration: none"
- >{{props.row.webhook || props.row.webhook}}{{props.row.webhook}}
+
+
+ {{props.row.webhook_message }}
+
+
ID:
@@ -409,10 +414,11 @@
balance: null,
walletLinks: [],
chargeLinks: [],
- onchainwallet: '',
+ onchainwallet: null,
rescanning: false,
mempool: {
- endpoint: ''
+ endpoint: '',
+ network: 'Mainnet'
},
chargesTable: {
@@ -505,6 +511,7 @@
methods: {
cancelCharge: function (data) {
this.formDialogCharge.data.description = ''
+ this.formDialogCharge.data.onchain = false
this.formDialogCharge.data.onchainwallet = ''
this.formDialogCharge.data.lnbitswallet = ''
this.formDialogCharge.data.time = null
@@ -518,7 +525,7 @@
try {
const {data} = await LNbits.api.request(
'GET',
- '/watchonly/api/v1/wallet',
+ `/watchonly/api/v1/wallet?network=${this.mempool.network}`,
this.g.user.wallets[0].inkey
)
this.walletLinks = data.map(w => ({
@@ -538,6 +545,7 @@
this.g.user.wallets[0].inkey
)
this.mempool.endpoint = data.mempool_endpoint
+ this.mempool.network = data.network || 'Mainnet'
const url = new URL(this.mempool.endpoint)
this.mempool.hostname = url.hostname
} catch (error) {
@@ -577,7 +585,8 @@
const data = this.formDialogCharge.data
data.amount = parseInt(data.amount)
data.time = parseInt(data.time)
- data.onchainwallet = this.onchainwallet?.id
+ data.lnbitswallet = data.lnbits ? data.lnbitswallet : null
+ data.onchainwallet = data.onchain ? this.onchainwallet?.id : null
this.createCharge(wallet, data)
},
refreshActiveChargesBalance: async function () {
@@ -695,8 +704,8 @@
},
created: async function () {
await this.getCharges()
- await this.getWalletLinks()
await this.getWalletConfig()
+ await this.getWalletLinks()
setInterval(() => this.refreshActiveChargesBalance(), 10 * 2000)
await this.rescanOnchainAddresses()
setInterval(() => this.rescanOnchainAddresses(), 10 * 1000)
diff --git a/lnbits/extensions/satspay/views.py b/lnbits/extensions/satspay/views.py
index b789bf8fe..7b769a20e 100644
--- a/lnbits/extensions/satspay/views.py
+++ b/lnbits/extensions/satspay/views.py
@@ -6,12 +6,12 @@ from starlette.exceptions import HTTPException
from starlette.requests import Request
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.satspay.helpers import public_charge
from . import satspay_ext, satspay_renderer
-from .crud import get_charge, get_charge_config
+from .crud import get_charge
templates = Jinja2Templates(directory="templates")
@@ -30,18 +30,13 @@ async def display(request: Request, charge_id: str):
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Charge link does not exist."
)
- wallet = await get_wallet(charge.lnbitswallet)
- onchainwallet_config = await get_charge_config(charge_id)
- inkey = wallet.inkey if wallet else None
- mempool_endpoint = (
- onchainwallet_config.mempool_endpoint if onchainwallet_config else None
- )
+
return satspay_renderer().TemplateResponse(
"satspay/display.html",
{
"request": request,
- "charge_data": charge.dict(),
- "wallet_inkey": inkey,
- "mempool_endpoint": mempool_endpoint,
+ "charge_data": public_charge(charge),
+ "mempool_endpoint": charge.config.mempool_endpoint,
+ "network": charge.config.network,
},
)
diff --git a/lnbits/extensions/satspay/views_api.py b/lnbits/extensions/satspay/views_api.py
index e1b87c41f..bfff55a21 100644
--- a/lnbits/extensions/satspay/views_api.py
+++ b/lnbits/extensions/satspay/views_api.py
@@ -1,6 +1,6 @@
+import json
from http import HTTPStatus
-import httpx
from fastapi.params import Depends
from starlette.exceptions import HTTPException
@@ -20,7 +20,7 @@ from .crud import (
get_charges,
update_charge,
)
-from .helpers import compact_charge
+from .helpers import call_webhook, public_charge
from .models import CreateCharge
#############################CHARGES##########################
@@ -58,6 +58,7 @@ async def api_charges_retrieve(wallet: WalletTypeInfo = Depends(get_key_type)):
**{"time_elapsed": charge.time_elapsed},
**{"time_left": charge.time_left},
**{"paid": charge.paid},
+ **{"webhook_message": charge.config.webhook_message},
}
for charge in await get_charges(wallet.wallet.user)
]
@@ -119,19 +120,9 @@ async def api_charge_balance(charge_id):
status_code=HTTPStatus.NOT_FOUND, detail="Charge does not exist."
)
- if charge.paid and charge.webhook:
- async with httpx.AsyncClient() as client:
- try:
- r = await client.post(
- charge.webhook,
- json=compact_charge(charge),
- timeout=40,
- )
- except AssertionError:
- charge.webhook = None
- return {
- **compact_charge(charge),
- **{"time_elapsed": charge.time_elapsed},
- **{"time_left": charge.time_left},
- **{"paid": charge.paid},
- }
+ if charge.must_call_webhook():
+ resp = await call_webhook(charge)
+ extra = {**charge.config.dict(), **resp}
+ await update_charge(charge_id=charge.id, extra=json.dumps(extra))
+
+ return {**public_charge(charge)}
diff --git a/lnbits/tasks.py b/lnbits/tasks.py
index 94e43dcfd..de3c69aa7 100644
--- a/lnbits/tasks.py
+++ b/lnbits/tasks.py
@@ -124,7 +124,7 @@ async def check_pending_payments():
while True:
async with db.connect() as conn:
- logger.debug(
+ logger.info(
f"Task: checking all pending payments (incoming={incoming}, outgoing={outgoing}) of last 15 days"
)
start_time: float = time.time()
@@ -140,15 +140,15 @@ async def check_pending_payments():
for payment in pending_payments:
await payment.check_status(conn=conn)
- logger.debug(
+ logger.info(
f"Task: pending check finished for {len(pending_payments)} payments (took {time.time() - start_time:0.3f} s)"
)
# we delete expired invoices once upon the first pending check
if incoming:
- logger.debug("Task: deleting all expired invoices")
+ logger.info("Task: deleting all expired invoices")
start_time: float = time.time()
await delete_expired_invoices(conn=conn)
- logger.debug(
+ logger.info(
f"Task: expired invoice deletion finished (took {time.time() - start_time:0.3f} s)"
)