mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-03-03 17:37:06 +01:00
stop doing the check_invoices thing on each call. do it once on lnbits starup and then rely on the invoices listener.
This commit is contained in:
parent
f27c2ebc21
commit
7e4a42e7ff
8 changed files with 61 additions and 70 deletions
|
@ -11,10 +11,17 @@ from .commands import db_migrate, handle_assets
|
||||||
from .core import core_app
|
from .core import core_app
|
||||||
from .helpers import get_valid_extensions, get_js_vendored, get_css_vendored, url_for_vendored
|
from .helpers import get_valid_extensions, get_js_vendored, get_css_vendored, url_for_vendored
|
||||||
from .proxy_fix import ASGIProxyFix
|
from .proxy_fix import ASGIProxyFix
|
||||||
from .tasks import run_deferred_async, invoice_listener, internal_invoice_listener, webhook_handler, grab_app_for_later
|
from .tasks import (
|
||||||
|
run_deferred_async,
|
||||||
|
check_pending_payments,
|
||||||
|
invoice_listener,
|
||||||
|
internal_invoice_listener,
|
||||||
|
webhook_handler,
|
||||||
|
grab_app_for_later,
|
||||||
|
)
|
||||||
from .settings import WALLET
|
from .settings import WALLET
|
||||||
|
|
||||||
secure_headers = SecureHeaders(hsts=False,xfo=False)
|
secure_headers = SecureHeaders(hsts=False, xfo=False)
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_object="lnbits.settings") -> QuartTrio:
|
def create_app(config_object="lnbits.settings") -> QuartTrio:
|
||||||
|
@ -123,8 +130,9 @@ def register_async_tasks(app):
|
||||||
@app.before_serving
|
@app.before_serving
|
||||||
async def listeners():
|
async def listeners():
|
||||||
run_deferred_async(app.nursery)
|
run_deferred_async(app.nursery)
|
||||||
app.nursery.start_soon(invoice_listener)
|
app.nursery.start_soon(check_pending_payments)
|
||||||
app.nursery.start_soon(internal_invoice_listener)
|
app.nursery.start_soon(invoice_listener, app.nursery)
|
||||||
|
app.nursery.start_soon(internal_invoice_listener, app.nursery)
|
||||||
|
|
||||||
@app.after_serving
|
@app.after_serving
|
||||||
async def stop_listeners():
|
async def stop_listeners():
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from typing import List, Optional, Dict
|
from typing import List, Optional, Dict, Any
|
||||||
|
|
||||||
from lnbits import bolt11
|
from lnbits import bolt11
|
||||||
from lnbits.settings import DEFAULT_WALLET_NAME
|
from lnbits.settings import DEFAULT_WALLET_NAME
|
||||||
|
@ -158,9 +158,9 @@ async def get_wallet_payment(wallet_id: str, payment_hash: str) -> Optional[Paym
|
||||||
return Payment.from_row(row) if row else None
|
return Payment.from_row(row) if row else None
|
||||||
|
|
||||||
|
|
||||||
async def get_wallet_payments(
|
async def get_payments(
|
||||||
wallet_id: str,
|
|
||||||
*,
|
*,
|
||||||
|
wallet_id: Optional[str] = None,
|
||||||
complete: bool = False,
|
complete: bool = False,
|
||||||
pending: bool = False,
|
pending: bool = False,
|
||||||
outgoing: bool = False,
|
outgoing: bool = False,
|
||||||
|
@ -171,41 +171,48 @@ async def get_wallet_payments(
|
||||||
Filters payments to be returned by complete | pending | outgoing | incoming.
|
Filters payments to be returned by complete | pending | outgoing | incoming.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
clause = ""
|
args: Any = ()
|
||||||
if complete and pending:
|
|
||||||
clause += ""
|
|
||||||
elif complete:
|
|
||||||
clause += "AND ((amount > 0 AND pending = 0) OR amount < 0)"
|
|
||||||
elif pending:
|
|
||||||
clause += "AND pending = 1"
|
|
||||||
else:
|
|
||||||
raise TypeError("at least one of [complete, pending] must be True.")
|
|
||||||
|
|
||||||
clause += " "
|
clause = []
|
||||||
|
|
||||||
|
if wallet_id:
|
||||||
|
clause.append("wallet = ?")
|
||||||
|
args = (wallet_id,)
|
||||||
|
|
||||||
|
if complete and pending:
|
||||||
|
pass
|
||||||
|
elif complete:
|
||||||
|
clause.append("((amount > 0 AND pending = 0) OR amount < 0)")
|
||||||
|
elif pending:
|
||||||
|
clause.append("pending = 1")
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
if outgoing and incoming:
|
if outgoing and incoming:
|
||||||
clause += ""
|
pass
|
||||||
elif outgoing:
|
elif outgoing:
|
||||||
clause += "AND amount < 0"
|
clause.append("amount < 0")
|
||||||
elif incoming:
|
elif incoming:
|
||||||
clause += "AND amount > 0"
|
clause.append("amount > 0")
|
||||||
else:
|
else:
|
||||||
raise TypeError("at least one of [outgoing, incoming] must be True.")
|
pass
|
||||||
|
|
||||||
clause += " "
|
|
||||||
|
|
||||||
if exclude_uncheckable: # checkable means it has a checking_id that isn't internal
|
if exclude_uncheckable: # checkable means it has a checking_id that isn't internal
|
||||||
clause += "AND checking_id NOT LIKE 'temp_%' "
|
clause.append("checking_id NOT LIKE 'temp_%'")
|
||||||
clause += "AND checking_id NOT LIKE 'internal_%' "
|
clause.append("checking_id NOT LIKE 'internal_%'")
|
||||||
|
|
||||||
|
where = ""
|
||||||
|
if clause:
|
||||||
|
where = f"WHERE {' AND '.join(clause)}"
|
||||||
|
|
||||||
rows = await db.fetchall(
|
rows = await db.fetchall(
|
||||||
f"""
|
f"""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM apipayments
|
FROM apipayments
|
||||||
WHERE wallet = ? {clause}
|
{where}
|
||||||
ORDER BY time DESC
|
ORDER BY time DESC
|
||||||
""",
|
""",
|
||||||
(wallet_id,),
|
args,
|
||||||
)
|
)
|
||||||
|
|
||||||
return [Payment.from_row(row) for row in rows]
|
return [Payment.from_row(row) for row in rows]
|
||||||
|
|
|
@ -60,10 +60,10 @@ class Wallet(NamedTuple):
|
||||||
incoming: bool = True,
|
incoming: bool = True,
|
||||||
exclude_uncheckable: bool = False
|
exclude_uncheckable: bool = False
|
||||||
) -> List["Payment"]:
|
) -> List["Payment"]:
|
||||||
from .crud import get_wallet_payments
|
from .crud import get_payments
|
||||||
|
|
||||||
return await get_wallet_payments(
|
return await get_payments(
|
||||||
self.id,
|
wallet_id=self.id,
|
||||||
complete=complete,
|
complete=complete,
|
||||||
pending=pending,
|
pending=pending,
|
||||||
outgoing=outgoing,
|
outgoing=outgoing,
|
||||||
|
|
|
@ -604,19 +604,6 @@ new Vue({
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
checkPendingPayments: function () {
|
|
||||||
var dismissMsg = this.$q.notify({
|
|
||||||
timeout: 0,
|
|
||||||
message: 'Checking pending transactions...'
|
|
||||||
})
|
|
||||||
|
|
||||||
LNbits.api
|
|
||||||
.checkPending(this.g.wallet)
|
|
||||||
.then(() => LNbits.api.fetchPayments)
|
|
||||||
.then(() => {
|
|
||||||
dismissMsg()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
exportCSV: function () {
|
exportCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.paymentsTable.columns, this.payments)
|
LNbits.utils.exportCSV(this.paymentsTable.columns, this.payments)
|
||||||
}
|
}
|
||||||
|
@ -629,7 +616,6 @@ new Vue({
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchBalance()
|
this.fetchBalance()
|
||||||
this.fetchPayments()
|
this.fetchPayments()
|
||||||
this.checkPendingPayments()
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
// show disclaimer
|
// show disclaimer
|
||||||
|
|
|
@ -13,7 +13,6 @@ from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
||||||
|
|
||||||
from .. import core_app, db
|
from .. import core_app, db
|
||||||
from ..services import create_invoice, pay_invoice, perform_lnurlauth
|
from ..services import create_invoice, pay_invoice, perform_lnurlauth
|
||||||
from ..crud import delete_expired_invoices
|
|
||||||
from ..tasks import sse_listeners
|
from ..tasks import sse_listeners
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,17 +31,6 @@ async def api_wallet():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@core_app.route("/api/v1/checkpending", methods=["POST"])
|
|
||||||
@api_check_wallet_key("invoice")
|
|
||||||
async def api_checkpending():
|
|
||||||
g.nursery.start_soon(delete_expired_invoices)
|
|
||||||
|
|
||||||
for payment in await g.wallet.get_payments(complete=False, pending=True, exclude_uncheckable=True):
|
|
||||||
await payment.check_pending()
|
|
||||||
|
|
||||||
return "", HTTPStatus.NO_CONTENT
|
|
||||||
|
|
||||||
|
|
||||||
@core_app.route("/api/v1/payments", methods=["GET"])
|
@core_app.route("/api/v1/payments", methods=["GET"])
|
||||||
@api_check_wallet_key("invoice")
|
@api_check_wallet_key("invoice")
|
||||||
async def api_payments():
|
async def api_payments():
|
||||||
|
|
|
@ -4,7 +4,7 @@ from lnbits.core.models import Payment
|
||||||
from lnbits.core.crud import (
|
from lnbits.core.crud import (
|
||||||
create_account,
|
create_account,
|
||||||
get_user,
|
get_user,
|
||||||
get_wallet_payments,
|
get_payments,
|
||||||
create_wallet,
|
create_wallet,
|
||||||
delete_wallet,
|
delete_wallet,
|
||||||
)
|
)
|
||||||
|
@ -91,7 +91,7 @@ async def get_usermanager_wallets(user_id: str) -> List[Wallets]:
|
||||||
|
|
||||||
|
|
||||||
async def get_usermanager_wallet_transactions(wallet_id: str) -> List[Payment]:
|
async def get_usermanager_wallet_transactions(wallet_id: str) -> List[Payment]:
|
||||||
return await get_wallet_payments(wallet_id=wallet_id, complete=True, pending=False, outgoing=True, incoming=True)
|
return await get_payments(wallet_id=wallet_id, complete=True, pending=False, outgoing=True, incoming=True)
|
||||||
|
|
||||||
|
|
||||||
async def delete_usermanager_wallet(wallet_id: str, user_id: str) -> None:
|
async def delete_usermanager_wallet(wallet_id: str, user_id: str) -> None:
|
||||||
|
|
|
@ -52,9 +52,6 @@ window.LNbits = {
|
||||||
getWallet: function (wallet) {
|
getWallet: function (wallet) {
|
||||||
return this.request('get', '/api/v1/wallet', wallet.inkey)
|
return this.request('get', '/api/v1/wallet', wallet.inkey)
|
||||||
},
|
},
|
||||||
checkPending: function (wallet) {
|
|
||||||
return this.request('post', '/api/v1/checkpending', wallet.inkey)
|
|
||||||
},
|
|
||||||
getPayments: function (wallet) {
|
getPayments: function (wallet) {
|
||||||
return this.request('get', '/api/v1/payments', wallet.inkey)
|
return this.request('get', '/api/v1/payments', wallet.inkey)
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Optional, List, Callable
|
||||||
from quart_trio import QuartTrio
|
from quart_trio import QuartTrio
|
||||||
|
|
||||||
from lnbits.settings import WALLET
|
from lnbits.settings import WALLET
|
||||||
from lnbits.core.crud import get_standalone_payment
|
from lnbits.core.crud import get_payments, get_standalone_payment, delete_expired_invoices
|
||||||
|
|
||||||
main_app: Optional[QuartTrio] = None
|
main_app: Optional[QuartTrio] = None
|
||||||
|
|
||||||
|
@ -54,16 +54,21 @@ async def webhook_handler():
|
||||||
internal_invoice_paid, internal_invoice_received = trio.open_memory_channel(0)
|
internal_invoice_paid, internal_invoice_received = trio.open_memory_channel(0)
|
||||||
|
|
||||||
|
|
||||||
async def internal_invoice_listener():
|
async def internal_invoice_listener(nursery):
|
||||||
async with trio.open_nursery() as nursery:
|
async for checking_id in internal_invoice_received:
|
||||||
async for checking_id in internal_invoice_received:
|
nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
||||||
nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
|
||||||
|
|
||||||
|
|
||||||
async def invoice_listener():
|
async def invoice_listener(nursery):
|
||||||
async with trio.open_nursery() as nursery:
|
async for checking_id in WALLET.paid_invoices_stream():
|
||||||
async for checking_id in WALLET.paid_invoices_stream():
|
nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
||||||
nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
|
||||||
|
|
||||||
|
async def check_pending_payments():
|
||||||
|
await delete_expired_invoices()
|
||||||
|
for payment in await get_payments(complete=False, pending=True, exclude_uncheckable=True):
|
||||||
|
print(" - checking pending", payment.checking_id)
|
||||||
|
await payment.check_pending()
|
||||||
|
|
||||||
|
|
||||||
async def invoice_callback_dispatcher(checking_id: str):
|
async def invoice_callback_dispatcher(checking_id: str):
|
||||||
|
|
Loading…
Add table
Reference in a new issue