Logging with loguru (#708)
* logging * requirements * add loguru dependency * restore it * add loguru * set log level in .env file * remove service fee print * set log level * more logging * more logging * more logging * pyament.checking_id * fix
This commit is contained in:
parent
847fd18796
commit
089313f613
|
@ -1,10 +1,8 @@
|
|||
QUART_APP=lnbits.app:create_app()
|
||||
QUART_ENV=development
|
||||
QUART_DEBUG=true
|
||||
|
||||
HOST=127.0.0.1
|
||||
PORT=5000
|
||||
|
||||
DEBUG=true
|
||||
|
||||
LNBITS_ALLOWED_USERS=""
|
||||
LNBITS_ADMIN_USERS=""
|
||||
# Extensions only admin can access
|
||||
|
|
1
Pipfile
1
Pipfile
|
@ -12,6 +12,7 @@ cerberus = "*"
|
|||
ecdsa = "*"
|
||||
environs = "*"
|
||||
lnurl = "==0.3.6"
|
||||
loguru = "*"
|
||||
pyscss = "*"
|
||||
shortuuid = "*"
|
||||
typing-extensions = "*"
|
||||
|
|
|
@ -3,15 +3,19 @@ import asyncio
|
|||
import uvloop
|
||||
from starlette.requests import Request
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .commands import bundle_vendored, migrate_databases, transpile_scss
|
||||
from .settings import (
|
||||
DEBUG,
|
||||
LNBITS_COMMIT,
|
||||
LNBITS_DATA_FOLDER,
|
||||
LNBITS_SITE_TITLE,
|
||||
HOST,
|
||||
PORT,
|
||||
SERVICE_FEE,
|
||||
WALLET,
|
||||
LNBITS_DATABASE_URL,
|
||||
LNBITS_DATA_FOLDER,
|
||||
)
|
||||
|
||||
uvloop.install()
|
||||
|
@ -24,13 +28,15 @@ from .app import create_app
|
|||
|
||||
app = create_app()
|
||||
|
||||
print(
|
||||
f"""Starting LNbits with
|
||||
- git version: {LNBITS_COMMIT}
|
||||
- site title: {LNBITS_SITE_TITLE}
|
||||
- debug: {DEBUG}
|
||||
- data folder: {LNBITS_DATA_FOLDER}
|
||||
- funding source: {WALLET.__class__.__name__}
|
||||
- service fee: {SERVICE_FEE}
|
||||
"""
|
||||
logger.info("Starting LNbits")
|
||||
logger.info(f"Host: {HOST}")
|
||||
logger.info(f"Port: {PORT}")
|
||||
logger.info(f"Debug: {DEBUG}")
|
||||
logger.info(f"Site title: {LNBITS_SITE_TITLE}")
|
||||
logger.info(f"Funding source: {WALLET.__class__.__name__}")
|
||||
logger.info(
|
||||
f"Database: {'PostgreSQL' if LNBITS_DATABASE_URL.startswith('postgres://') else 'CockroachDB' if LNBITS_DATABASE_URL.startswith('cockroachdb://') else 'SQLite'}"
|
||||
)
|
||||
logger.info(f"Data folder: {LNBITS_DATA_FOLDER}")
|
||||
logger.info(f"Git version: {LNBITS_COMMIT}")
|
||||
# logger.info(f"Service fee: {SERVICE_FEE}")
|
||||
|
|
|
@ -3,6 +3,9 @@ import importlib
|
|||
import sys
|
||||
import traceback
|
||||
import warnings
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from http import HTTPStatus
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
|
@ -41,6 +44,8 @@ def create_app(config_object="lnbits.settings") -> FastAPI:
|
|||
"""Create application factory.
|
||||
:param config_object: The configuration object to use.
|
||||
"""
|
||||
set_logging_level()
|
||||
|
||||
app = FastAPI()
|
||||
app.mount("/static", StaticFiles(directory="lnbits/static"), name="static")
|
||||
app.mount(
|
||||
|
@ -94,14 +99,14 @@ def check_funding_source(app: FastAPI) -> None:
|
|||
error_message, balance = await WALLET.status()
|
||||
if not error_message:
|
||||
break
|
||||
warnings.warn(
|
||||
f" × The backend for {WALLET.__class__.__name__} isn't working properly: '{error_message}'",
|
||||
logger.error(
|
||||
f"The backend for {WALLET.__class__.__name__} isn't working properly: '{error_message}'",
|
||||
RuntimeWarning,
|
||||
)
|
||||
print("Retrying connection to backend in 5 seconds...")
|
||||
logger.info("Retrying connection to backend in 5 seconds...")
|
||||
await asyncio.sleep(5)
|
||||
print(
|
||||
f" ✔️ {WALLET.__class__.__name__} seems to be connected and with a balance of {balance} msat."
|
||||
logger.info(
|
||||
f"✔️ Backend {WALLET.__class__.__name__} connected and with a balance of {balance} msat."
|
||||
)
|
||||
|
||||
|
||||
|
@ -124,9 +129,10 @@ def register_routes(app: FastAPI) -> None:
|
|||
for s in ext_statics:
|
||||
app.mount(s["path"], s["app"], s["name"])
|
||||
|
||||
logger.trace(f"adding route for extension {ext_module}")
|
||||
app.include_router(ext_route)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
logger.error(str(e))
|
||||
raise ImportError(
|
||||
f"Please make sure that the extension `{ext.code}` follows conventions."
|
||||
)
|
||||
|
@ -173,8 +179,8 @@ def register_async_tasks(app):
|
|||
def register_exception_handlers(app: FastAPI):
|
||||
@app.exception_handler(Exception)
|
||||
async def basic_error(request: Request, err):
|
||||
print("handled error", traceback.format_exc())
|
||||
print("ERROR:", err)
|
||||
logger.error("handled error", traceback.format_exc())
|
||||
logger.error("ERROR:", err)
|
||||
etype, _, tb = sys.exc_info()
|
||||
traceback.print_exception(etype, err, tb)
|
||||
exc = traceback.format_exc()
|
||||
|
@ -188,3 +194,10 @@ def register_exception_handlers(app: FastAPI):
|
|||
status_code=HTTPStatus.NO_CONTENT,
|
||||
content={"detail": err},
|
||||
)
|
||||
|
||||
|
||||
def set_logging_level() -> None:
|
||||
"""Set the logging level for the application."""
|
||||
logger.remove()
|
||||
log_level: str = "DEBUG" if lnbits.settings.DEBUG else "INFO"
|
||||
logger.add(sys.stderr, level=log_level)
|
||||
|
|
|
@ -5,6 +5,8 @@ import importlib
|
|||
import re
|
||||
import os
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .db import SQLITE, POSTGRES, COCKROACH
|
||||
from .core import db as core_db, migrations as core_migrations
|
||||
from .helpers import (
|
||||
|
@ -69,7 +71,7 @@ async def migrate_databases():
|
|||
if match:
|
||||
version = int(match.group(1))
|
||||
if version > current_versions.get(db_name, 0):
|
||||
print(f"running migration {db_name}.{version}")
|
||||
logger.debug(f"running migration {db_name}.{version}")
|
||||
await migrate(db)
|
||||
|
||||
if db.schema == None:
|
||||
|
@ -110,4 +112,4 @@ async def migrate_databases():
|
|||
async with ext_db.connect() as ext_conn:
|
||||
await run_migration(ext_conn, ext_migrations)
|
||||
|
||||
print(" ✔️ All migrations done.")
|
||||
logger.info("✔️ All migrations done.")
|
||||
|
|
|
@ -7,6 +7,9 @@ from lnurl import encode as lnurl_encode # type: ignore
|
|||
from typing import List, NamedTuple, Optional, Dict
|
||||
from sqlite3 import Row
|
||||
from pydantic import BaseModel
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.settings import WALLET
|
||||
|
||||
|
||||
|
@ -142,10 +145,12 @@ class Payment(BaseModel):
|
|||
status = await WALLET.get_invoice_status(self.checking_id)
|
||||
|
||||
if self.is_out and status.failed:
|
||||
print(f" - deleting outgoing failed payment {self.checking_id}: {status}")
|
||||
logger.info(
|
||||
f" - deleting outgoing failed payment {self.checking_id}: {status}"
|
||||
)
|
||||
await self.delete()
|
||||
elif not status.pending:
|
||||
print(
|
||||
logger.info(
|
||||
f" - marking '{'in' if self.is_in else 'out'}' {self.checking_id} as not pending anymore: {status}"
|
||||
)
|
||||
await self.set_pending(status.pending)
|
||||
|
|
|
@ -3,6 +3,9 @@ import json
|
|||
from binascii import unhexlify
|
||||
from io import BytesIO
|
||||
from typing import Dict, Optional, Tuple
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
import httpx
|
||||
|
@ -120,6 +123,7 @@ async def pay_invoice(
|
|||
# check_internal() returns the checking_id of the invoice we're waiting for
|
||||
internal_checking_id = await check_internal(invoice.payment_hash, conn=conn)
|
||||
if internal_checking_id:
|
||||
logger.debug(f"creating temporary internal payment with id {internal_id}")
|
||||
# create a new payment from this wallet
|
||||
await create_payment(
|
||||
checking_id=internal_id,
|
||||
|
@ -129,6 +133,7 @@ async def pay_invoice(
|
|||
**payment_kwargs,
|
||||
)
|
||||
else:
|
||||
logger.debug(f"creating temporary payment with id {temp_id}")
|
||||
# create a temporary payment here so we can check if
|
||||
# the balance is enough in the next step
|
||||
await create_payment(
|
||||
|
@ -142,6 +147,7 @@ async def pay_invoice(
|
|||
wallet = await get_wallet(wallet_id, conn=conn)
|
||||
assert wallet
|
||||
if wallet.balance_msat < 0:
|
||||
logger.debug("balance is too low, deleting temporary payment")
|
||||
if not internal_checking_id and wallet.balance_msat > -fee_reserve_msat:
|
||||
raise PaymentFailure(
|
||||
f"You must reserve at least 1% ({round(fee_reserve_msat/1000)} sat) to cover potential routing fees."
|
||||
|
@ -149,6 +155,7 @@ async def pay_invoice(
|
|||
raise PermissionError("Insufficient balance.")
|
||||
|
||||
if internal_checking_id:
|
||||
logger.debug(f"marking temporary payment as not pending {internal_checking_id}")
|
||||
# mark the invoice from the other side as not pending anymore
|
||||
# so the other side only has access to his new money when we are sure
|
||||
# the payer has enough to deduct from
|
||||
|
@ -163,11 +170,14 @@ async def pay_invoice(
|
|||
|
||||
await internal_invoice_queue.put(internal_checking_id)
|
||||
else:
|
||||
logger.debug(f"backend: sending payment {temp_id}")
|
||||
# actually pay the external invoice
|
||||
payment: PaymentResponse = await WALLET.pay_invoice(
|
||||
payment_request, fee_reserve_msat
|
||||
)
|
||||
logger.debug(f"backend: pay_invoice finished {temp_id}")
|
||||
if payment.checking_id:
|
||||
logger.debug(f"creating final payment {payment.checking_id}")
|
||||
async with db.connect() as conn:
|
||||
await create_payment(
|
||||
checking_id=payment.checking_id,
|
||||
|
@ -177,15 +187,18 @@ async def pay_invoice(
|
|||
conn=conn,
|
||||
**payment_kwargs,
|
||||
)
|
||||
logger.debug(f"deleting temporary payment {temp_id}")
|
||||
await delete_payment(temp_id, conn=conn)
|
||||
else:
|
||||
logger.debug(f"backend payment failed, no checking_id {temp_id}")
|
||||
async with db.connect() as conn:
|
||||
logger.debug(f"deleting temporary payment {temp_id}")
|
||||
await delete_payment(temp_id, conn=conn)
|
||||
raise PaymentFailure(
|
||||
payment.error_message
|
||||
or "Payment failed, but backend didn't give us an error message."
|
||||
)
|
||||
|
||||
logger.debug(f"payment successful {payment.checking_id}")
|
||||
return invoice.payment_hash
|
||||
|
||||
|
||||
|
@ -216,7 +229,7 @@ async def redeem_lnurl_withdraw(
|
|||
conn=conn,
|
||||
)
|
||||
except:
|
||||
print(
|
||||
logger.warn(
|
||||
f"failed to create invoice on redeem_lnurl_withdraw from {lnurl}. params: {res}"
|
||||
)
|
||||
return None
|
||||
|
@ -325,11 +338,11 @@ async def check_invoice_status(
|
|||
if not payment.pending:
|
||||
return status
|
||||
if payment.is_out and status.failed:
|
||||
print(f" - deleting outgoing failed payment {payment.checking_id}: {status}")
|
||||
logger.info(f"deleting outgoing failed payment {payment.checking_id}: {status}")
|
||||
await payment.delete()
|
||||
elif not status.pending:
|
||||
print(
|
||||
f" - marking '{'in' if payment.is_in else 'out'}' {payment.checking_id} as not pending anymore: {status}"
|
||||
logger.info(
|
||||
f"marking '{'in' if payment.is_in else 'out'}' {payment.checking_id} as not pending anymore: {status}"
|
||||
)
|
||||
await payment.set_pending(status.pending)
|
||||
return status
|
||||
|
|
|
@ -2,6 +2,8 @@ import asyncio
|
|||
import httpx
|
||||
from typing import List
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.tasks import register_invoice_listener
|
||||
|
||||
from . import db
|
||||
|
@ -20,7 +22,7 @@ async def register_task_listeners():
|
|||
async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue):
|
||||
while True:
|
||||
payment = await invoice_paid_queue.get()
|
||||
|
||||
logger.debug("received invoice paid event")
|
||||
# send information to sse channel
|
||||
await dispatch_invoice_listener(payment)
|
||||
|
||||
|
@ -44,7 +46,7 @@ async def dispatch_invoice_listener(payment: Payment):
|
|||
try:
|
||||
send_channel.put_nowait(payment)
|
||||
except asyncio.QueueFull:
|
||||
print("removing sse listener", send_channel)
|
||||
logger.debug("removing sse listener", send_channel)
|
||||
api_invoice_listeners.remove(send_channel)
|
||||
|
||||
|
||||
|
@ -52,6 +54,7 @@ async def dispatch_webhook(payment: Payment):
|
|||
async with httpx.AsyncClient() as client:
|
||||
data = payment.dict()
|
||||
try:
|
||||
logger.debug("sending webhook", payment.webhook)
|
||||
r = await client.post(payment.webhook, json=data, timeout=40)
|
||||
await mark_webhook_sent(payment, r.status_code)
|
||||
except (httpx.ConnectError, httpx.RequestError):
|
||||
|
|
|
@ -7,6 +7,9 @@ from typing import Dict, List, Optional, Union
|
|||
from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse
|
||||
|
||||
import httpx
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from fastapi import Header, Query, Request
|
||||
from fastapi.exceptions import HTTPException
|
||||
from fastapi.param_functions import Depends
|
||||
|
@ -347,7 +350,7 @@ async def subscribe(request: Request, wallet: Wallet):
|
|||
|
||||
payment_queue: asyncio.Queue[Payment] = asyncio.Queue(0)
|
||||
|
||||
print("adding sse listener", payment_queue)
|
||||
logger.debug("adding sse listener", payment_queue)
|
||||
api_invoice_listeners.append(payment_queue)
|
||||
|
||||
send_queue: asyncio.Queue[tuple[str, Payment]] = asyncio.Queue(0)
|
||||
|
@ -356,6 +359,7 @@ async def subscribe(request: Request, wallet: Wallet):
|
|||
while True:
|
||||
payment: Payment = await payment_queue.get()
|
||||
if payment.wallet_id == this_wallet_id:
|
||||
logger.debug("payment receieved", payment)
|
||||
await send_queue.put(("payment-received", payment))
|
||||
|
||||
asyncio.create_task(payment_received())
|
||||
|
@ -391,7 +395,7 @@ async def api_payment(payment_hash, X_Api_Key: Optional[str] = Header(None)):
|
|||
wallet = None
|
||||
try:
|
||||
if X_Api_Key.extra:
|
||||
print("No key")
|
||||
logger.warn("No key")
|
||||
except:
|
||||
wallet = await get_wallet_for_key(X_Api_Key)
|
||||
payment = await get_standalone_payment(payment_hash)
|
||||
|
|
|
@ -10,6 +10,8 @@ from fastapi.routing import APIRouter
|
|||
from pydantic.types import UUID4
|
||||
from starlette.responses import HTMLResponse, JSONResponse
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core import db
|
||||
from lnbits.core.models import User
|
||||
from lnbits.decorators import check_user_exists
|
||||
|
@ -66,10 +68,12 @@ async def extensions(
|
|||
)
|
||||
|
||||
if extension_to_enable:
|
||||
logger.info(f"Enabling extension: {extension_to_enable} for user {user.id}")
|
||||
await update_user_extension(
|
||||
user_id=user.id, extension=extension_to_enable, active=True
|
||||
)
|
||||
elif extension_to_disable:
|
||||
logger.info(f"Disabling extension: {extension_to_disable} for user {user.id}")
|
||||
await update_user_extension(
|
||||
user_id=user.id, extension=extension_to_disable, active=False
|
||||
)
|
||||
|
@ -109,6 +113,7 @@ async def wallet(
|
|||
|
||||
if not user_id:
|
||||
user = await get_user((await create_account()).id)
|
||||
logger.info(f"Created new account for user {user.id}")
|
||||
else:
|
||||
user = await get_user(user_id)
|
||||
if not user:
|
||||
|
@ -126,12 +131,16 @@ async def wallet(
|
|||
wallet = user.wallets[0]
|
||||
else:
|
||||
wallet = await create_wallet(user_id=user.id, wallet_name=wallet_name)
|
||||
logger.info(
|
||||
f"Created new wallet {wallet_name if wallet_name else '(no name)'} for user {user.id}"
|
||||
)
|
||||
|
||||
return RedirectResponse(
|
||||
f"/wallet?usr={user.id}&wal={wallet.id}",
|
||||
status_code=status.HTTP_307_TEMPORARY_REDIRECT,
|
||||
)
|
||||
|
||||
logger.info(f"Access wallet {wallet_name} of user {user.id}")
|
||||
wallet = user.get_wallet(wallet_id)
|
||||
if not wallet:
|
||||
return template_renderer().TemplateResponse(
|
||||
|
@ -202,13 +211,13 @@ async def lnurl_full_withdraw_callback(request: Request):
|
|||
async def deletewallet(request: Request, wal: str = Query(...), usr: str = Query(...)):
|
||||
user = await get_user(usr)
|
||||
user_wallet_ids = [u.id for u in user.wallets]
|
||||
print("USR", user_wallet_ids)
|
||||
|
||||
if wal not in user_wallet_ids:
|
||||
raise HTTPException(HTTPStatus.FORBIDDEN, "Not your wallet.")
|
||||
else:
|
||||
await delete_wallet(user_id=user.id, wallet_id=wal)
|
||||
user_wallet_ids.remove(wal)
|
||||
logger.debug("Deleted wallet {wal} of user {user.id}")
|
||||
|
||||
if user_wallet_ids:
|
||||
return RedirectResponse(
|
||||
|
|
|
@ -7,6 +7,8 @@ from fastapi import HTTPException
|
|||
from starlette.requests import Request
|
||||
from starlette.responses import HTMLResponse
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits import bolt11
|
||||
|
||||
from .. import core_app
|
||||
|
@ -45,7 +47,7 @@ async def api_public_payment_longpolling(payment_hash):
|
|||
|
||||
payment_queue = asyncio.Queue(0)
|
||||
|
||||
print("adding standalone invoice listener", payment_hash, payment_queue)
|
||||
logger.debug("adding standalone invoice listener", payment_hash, payment_queue)
|
||||
api_invoice_listeners.append(payment_queue)
|
||||
|
||||
response = None
|
||||
|
|
|
@ -5,6 +5,8 @@ import time
|
|||
from contextlib import asynccontextmanager
|
||||
from typing import Optional
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy_aio.base import AsyncConnection
|
||||
from sqlalchemy_aio.strategy import ASYNCIO_STRATEGY # type: ignore
|
||||
|
@ -139,7 +141,7 @@ class Database(Compat):
|
|||
f"LNBITS_DATA_FOLDER named {LNBITS_DATA_FOLDER} was not created"
|
||||
f" - please 'mkdir {LNBITS_DATA_FOLDER}' and try again"
|
||||
)
|
||||
|
||||
logger.trace(f"database {self.type} added for {self.name}")
|
||||
self.schema = self.name
|
||||
if self.name.startswith("ext_"):
|
||||
self.schema = self.name[4:]
|
||||
|
|
|
@ -5,6 +5,8 @@ from http import HTTPStatus
|
|||
|
||||
from starlette.requests import Request
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from . import bleskomat_ext
|
||||
from .crud import (
|
||||
create_bleskomat_lnurl,
|
||||
|
@ -122,7 +124,7 @@ async def api_bleskomat_lnurl(req: Request):
|
|||
except LnurlHttpError as e:
|
||||
return {"status": "ERROR", "reason": str(e)}
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
logger.error(str(e))
|
||||
return {"status": "ERROR", "reason": "Unexpected error"}
|
||||
|
||||
return {"status": "OK"}
|
||||
|
|
|
@ -6,6 +6,8 @@ from fastapi.params import Query
|
|||
from pydantic import BaseModel, validator
|
||||
from starlette.requests import Request
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits import bolt11
|
||||
from lnbits.core.services import pay_invoice, PaymentFailure
|
||||
|
||||
|
@ -125,7 +127,7 @@ class BleskomatLnurl(BaseModel):
|
|||
except (ValueError, PermissionError, PaymentFailure) as e:
|
||||
raise LnurlValidationError("Failed to pay invoice: " + str(e))
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
logger.error(str(e))
|
||||
raise LnurlValidationError("Unexpected error")
|
||||
|
||||
async def use(self, conn) -> bool:
|
||||
|
|
|
@ -3,6 +3,8 @@ from http import HTTPStatus
|
|||
from fastapi import Depends, Query
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core.crud import get_user
|
||||
from lnbits.decorators import WalletTypeInfo, require_admin_key
|
||||
from lnbits.extensions.bleskomat.models import CreateBleskomat
|
||||
|
@ -60,7 +62,7 @@ async def api_bleskomat_create_or_update(
|
|||
currency=fiat_currency, provider=exchange_rate_provider
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
logger.error(e)
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=f'Failed to fetch BTC/{fiat_currency} currency pair from "{exchange_rate_provider}"',
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import asyncio
|
||||
import json
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core import db as core_db
|
||||
from lnbits.core.crud import create_payment
|
||||
from lnbits.core.models import Payment
|
||||
|
@ -26,11 +28,11 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
|
||||
track = await get_track(payment.extra.get("track", -1))
|
||||
if not track:
|
||||
print("this should never happen", payment)
|
||||
logger.error("this should never happen", payment)
|
||||
return
|
||||
|
||||
if payment.extra.get("shared_with"):
|
||||
print("payment was shared already", payment)
|
||||
logger.error("payment was shared already", payment)
|
||||
return
|
||||
|
||||
producer = await get_producer(track.producer)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from datetime import datetime, timedelta
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.helpers import urlsafe_short_hash
|
||||
|
||||
from . import db
|
||||
|
@ -186,9 +188,9 @@ async def purge_addresses(domain_id: str):
|
|||
) # give user 1 day to topup is address
|
||||
|
||||
if not paid and pay_expire:
|
||||
print("DELETE UNP_PAY_EXP", r["username"])
|
||||
logger.debug("DELETE UNP_PAY_EXP", r["username"])
|
||||
await delete_address(r["id"])
|
||||
|
||||
if paid and expired:
|
||||
print("DELETE PAID_EXP", r["username"])
|
||||
logger.debug("DELETE PAID_EXP", r["username"])
|
||||
await delete_address(r["id"])
|
||||
|
|
|
@ -3,6 +3,9 @@ import json
|
|||
from datetime import datetime, timedelta
|
||||
|
||||
import httpx
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from fastapi.params import Query
|
||||
from lnurl import ( # type: ignore
|
||||
LnurlErrorResponse,
|
||||
|
@ -38,13 +41,12 @@ async def lnurl_response(username: str, domain: str, request: Request):
|
|||
"maxSendable": 1000000000,
|
||||
}
|
||||
|
||||
print("RESP", resp)
|
||||
logger.debug("RESP", resp)
|
||||
return resp
|
||||
|
||||
|
||||
@lnaddress_ext.get("/lnurl/cb/{address_id}", name="lnaddress.lnurl_callback")
|
||||
async def lnurl_callback(address_id, amount: int = Query(...)):
|
||||
print("PING")
|
||||
address = await get_address(address_id)
|
||||
if not address:
|
||||
return LnurlErrorResponse(reason=f"Address not found").dict()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import asyncio
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core.models import Payment
|
||||
from lnbits.tasks import register_invoice_listener
|
||||
|
||||
|
@ -22,7 +24,7 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
|
||||
ticket = await get_ticket(payment.checking_id)
|
||||
if not ticket:
|
||||
print("this should never happen", payment)
|
||||
logger.error("this should never happen", payment)
|
||||
return
|
||||
|
||||
await payment.set_pending(False)
|
||||
|
|
|
@ -150,7 +150,7 @@ async def lnurl_v1_params(
|
|||
"defaultDescription": device.title,
|
||||
}
|
||||
price_msat = int(price_msat * ((device.profit / 100) + 1) / 1000)
|
||||
print(price_msat)
|
||||
|
||||
lnurldevicepayment = await create_lnurldevicepayment(
|
||||
deviceid=device.id,
|
||||
payload=p,
|
||||
|
@ -204,7 +204,7 @@ async def lnurl_callback(
|
|||
extra={"tag": "withdraw"},
|
||||
)
|
||||
return {"status": "OK"}
|
||||
print(lnurldevicepayment.sats)
|
||||
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=device.wallet,
|
||||
amount=lnurldevicepayment.sats / 1000,
|
||||
|
|
|
@ -2,6 +2,9 @@ import asyncio
|
|||
from http import HTTPStatus
|
||||
|
||||
import httpx
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from lnbits.core import db as core_db
|
||||
|
@ -27,7 +30,7 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
try:
|
||||
# Check its got a payout associated with it
|
||||
lnurlpayout_link = await get_lnurlpayout_from_wallet(payment.wallet_id)
|
||||
print("LNURLpayout", lnurlpayout_link)
|
||||
logger.debug("LNURLpayout", lnurlpayout_link)
|
||||
if lnurlpayout_link:
|
||||
|
||||
# Check the wallet balance is more than the threshold
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import asyncio
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core.models import Payment
|
||||
from lnbits.extensions.satspay.crud import check_address_balance, get_charge
|
||||
from lnbits.tasks import register_invoice_listener
|
||||
|
@ -23,7 +25,7 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
|
||||
charge = await get_charge(payment.memo)
|
||||
if not charge:
|
||||
print("this should never happen", payment)
|
||||
logger.error("this should never happen", payment)
|
||||
return
|
||||
|
||||
await payment.set_pending(False)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import asyncio
|
||||
import json
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core import db as core_db
|
||||
from lnbits.core.crud import create_payment
|
||||
from lnbits.core.models import Payment
|
||||
|
@ -34,7 +36,9 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
amount_left = payment.amount - sum([amount for _, amount in transfers])
|
||||
|
||||
if amount_left < 0:
|
||||
print("splitpayments failure: amount_left is negative.", payment.payment_hash)
|
||||
logger.error(
|
||||
"splitpayments failure: amount_left is negative.", payment.payment_hash
|
||||
)
|
||||
return
|
||||
|
||||
if not targets:
|
||||
|
|
|
@ -4,6 +4,8 @@ from fastapi import Query
|
|||
from fastapi.params import Depends
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core.crud import get_user
|
||||
from lnbits.core.services import create_invoice
|
||||
from lnbits.core.views.api import api_payment
|
||||
|
@ -88,6 +90,6 @@ async def api_tpos_check_invoice(tpos_id: str, payment_hash: str):
|
|||
status = await api_payment(payment_hash)
|
||||
|
||||
except Exception as exc:
|
||||
print(exc)
|
||||
logger.error(exc)
|
||||
return {"paid": False}
|
||||
return status
|
||||
|
|
|
@ -5,6 +5,8 @@ import httpx
|
|||
from datetime import datetime
|
||||
from http import HTTPStatus
|
||||
|
||||
from loguru import logger
|
||||
|
||||
import shortuuid # type: ignore
|
||||
from fastapi import HTTPException
|
||||
from fastapi.param_functions import Query
|
||||
|
@ -136,13 +138,13 @@ async def api_lnurl_callback(
|
|||
)
|
||||
except Exception as exc:
|
||||
# webhook fails shouldn't cause the lnurlw to fail since invoice is already paid
|
||||
print("Caught exception when dispatching webhook url:", exc)
|
||||
logger.error("Caught exception when dispatching webhook url:", exc)
|
||||
|
||||
return {"status": "OK"}
|
||||
|
||||
except Exception as e:
|
||||
await update_withdraw_link(link.id, **changesback)
|
||||
print(traceback.format_exc())
|
||||
logger.error(traceback.format_exc())
|
||||
return {"status": "ERROR", "reason": "Link not working"}
|
||||
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ wallet_class = getattr(
|
|||
wallets_module, env.str("LNBITS_BACKEND_WALLET_CLASS", default="VoidWallet")
|
||||
)
|
||||
|
||||
ENV = env.str("QUART_ENV", default="production")
|
||||
DEBUG = env.bool("QUART_DEBUG", default=False) or ENV == "development"
|
||||
DEBUG = env.bool("DEBUG", default=False)
|
||||
|
||||
HOST = env.str("HOST", default="127.0.0.1")
|
||||
PORT = env.int("PORT", default=5000)
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import traceback
|
|||
from http import HTTPStatus
|
||||
from typing import List, Callable
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from fastapi.exceptions import HTTPException
|
||||
|
||||
from lnbits.settings import WALLET
|
||||
|
@ -37,9 +39,9 @@ async def catch_everything_and_restart(func):
|
|||
except asyncio.CancelledError:
|
||||
raise # because we must pass this up
|
||||
except Exception as exc:
|
||||
print("caught exception in background task:", exc)
|
||||
print(traceback.format_exc())
|
||||
print("will restart the task in 5 seconds.")
|
||||
logger.error("caught exception in background task:", exc)
|
||||
logger.error(traceback.format_exc())
|
||||
logger.error("will restart the task in 5 seconds.")
|
||||
await asyncio.sleep(5)
|
||||
await catch_everything_and_restart(func)
|
||||
|
||||
|
@ -77,7 +79,7 @@ async def internal_invoice_listener():
|
|||
|
||||
async def invoice_listener():
|
||||
async for checking_id in WALLET.paid_invoices_stream():
|
||||
print("> got a payment notification", checking_id)
|
||||
logger.info("> got a payment notification", checking_id)
|
||||
asyncio.create_task(invoice_callback_dispatcher(checking_id))
|
||||
|
||||
|
||||
|
@ -117,6 +119,7 @@ async def perform_balance_checks():
|
|||
async def invoice_callback_dispatcher(checking_id: str):
|
||||
payment = await get_standalone_payment(checking_id, incoming=True)
|
||||
if payment and payment.is_in:
|
||||
logger.trace("sending invoice callback for payment", checking_id)
|
||||
await payment.set_pending(False)
|
||||
for send_chan in invoice_listeners:
|
||||
await send_chan.put(payment)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import asyncio
|
||||
from typing import Callable, NamedTuple
|
||||
|
||||
from loguru import logger
|
||||
|
||||
import httpx
|
||||
|
||||
currencies = {
|
||||
|
@ -280,7 +282,7 @@ async def btc_price(currency: str) -> float:
|
|||
if not rates:
|
||||
return 9999999999
|
||||
elif len(rates) == 1:
|
||||
print("Warning could only fetch one Bitcoin price.")
|
||||
logger.warn("Could only fetch one Bitcoin price.")
|
||||
|
||||
return sum([rate for rate in rates]) / len(rates)
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import urllib.parse
|
|||
from os import getenv
|
||||
from typing import AsyncGenerator, Dict, Optional
|
||||
|
||||
from loguru import logger
|
||||
|
||||
import httpx
|
||||
from websockets import connect
|
||||
from websockets.exceptions import (
|
||||
|
@ -193,8 +195,8 @@ class EclairWallet(Wallet):
|
|||
ConnectionClosedError,
|
||||
ConnectionClosed,
|
||||
) as ose:
|
||||
print("OSE", ose)
|
||||
logger.error("OSE", ose)
|
||||
pass
|
||||
|
||||
print("lost connection to eclair's websocket, retrying in 5 seconds")
|
||||
logger.error("lost connection to eclair's websocket, retrying in 5 seconds")
|
||||
await asyncio.sleep(5)
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import asyncio
|
||||
import json
|
||||
import httpx
|
||||
|
||||
from os import getenv
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
import random
|
||||
import string
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.helpers import urlsafe_short_hash
|
||||
import hashlib
|
||||
from ..bolt11 import encode, decode
|
||||
|
@ -20,7 +21,7 @@ from .base import (
|
|||
|
||||
class FakeWallet(Wallet):
|
||||
async def status(self) -> StatusResponse:
|
||||
print(
|
||||
logger.info(
|
||||
"FakeWallet funding source is for using LNbits as a centralised, stand-alone payment system with brrrrrr."
|
||||
)
|
||||
return StatusResponse(None, float("inf"))
|
||||
|
|
|
@ -4,6 +4,8 @@ import httpx
|
|||
from os import getenv
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .base import (
|
||||
StatusResponse,
|
||||
InvoiceResponse,
|
||||
|
@ -144,5 +146,7 @@ class LNbitsWallet(Wallet):
|
|||
except (OSError, httpx.ReadError, httpx.ConnectError, httpx.ReadTimeout):
|
||||
pass
|
||||
|
||||
print("lost connection to lnbits /payments/sse, retrying in 5 seconds")
|
||||
logger.error(
|
||||
"lost connection to lnbits /payments/sse, retrying in 5 seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
|
|
|
@ -11,6 +11,9 @@ import base64
|
|||
import hashlib
|
||||
from os import environ, error, getenv
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .macaroon import load_macaroon, AESCipher
|
||||
|
||||
if imports_ok:
|
||||
|
@ -187,6 +190,8 @@ class LndWallet(Wallet):
|
|||
checking_id = stringify_checking_id(i.r_hash)
|
||||
yield checking_id
|
||||
except error:
|
||||
print(error)
|
||||
logger.error(error)
|
||||
|
||||
print("lost connection to lnd InvoiceSubscription, please restart lnbits.")
|
||||
logger.error(
|
||||
"lost connection to lnd InvoiceSubscription, please restart lnbits."
|
||||
)
|
||||
|
|
|
@ -6,6 +6,8 @@ import base64
|
|||
from os import getenv
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits import bolt11 as lnbits_bolt11
|
||||
from .macaroon import load_macaroon, AESCipher
|
||||
|
||||
|
@ -191,5 +193,7 @@ class LndRestWallet(Wallet):
|
|||
except (OSError, httpx.ConnectError, httpx.ReadError):
|
||||
pass
|
||||
|
||||
print("lost connection to lnd invoices stream, retrying in 5 seconds")
|
||||
logger.error(
|
||||
"lost connection to lnd invoices stream, retrying in 5 seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
|
|
|
@ -6,6 +6,8 @@ from os import getenv
|
|||
from http import HTTPStatus
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .base import (
|
||||
StatusResponse,
|
||||
InvoiceResponse,
|
||||
|
@ -127,7 +129,7 @@ class LNPayWallet(Wallet):
|
|||
try:
|
||||
data = json.loads(text)
|
||||
except json.decoder.JSONDecodeError:
|
||||
print(f"got something wrong on lnpay webhook endpoint: {text[:200]}")
|
||||
logger.error(f"got something wrong on lnpay webhook endpoint: {text[:200]}")
|
||||
data = None
|
||||
if (
|
||||
type(data) is not dict
|
||||
|
|
|
@ -4,6 +4,8 @@ import httpx
|
|||
from os import getenv
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .base import (
|
||||
StatusResponse,
|
||||
InvoiceResponse,
|
||||
|
@ -143,5 +145,7 @@ class LntxbotWallet(Wallet):
|
|||
except (OSError, httpx.ReadError, httpx.ReadTimeout, httpx.ConnectError):
|
||||
pass
|
||||
|
||||
print("lost connection to lntxbot /payments/stream, retrying in 5 seconds")
|
||||
logger.error(
|
||||
"lost connection to lntxbot /payments/stream, retrying in 5 seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
|
|
|
@ -4,6 +4,8 @@ import base64
|
|||
from hashlib import md5
|
||||
import getpass
|
||||
|
||||
from loguru import logger
|
||||
|
||||
BLOCK_SIZE = 16
|
||||
import getpass
|
||||
|
||||
|
@ -103,5 +105,5 @@ if __name__ == "__main__":
|
|||
macaroon = input("Enter macaroon: ")
|
||||
macaroon = load_macaroon(macaroon)
|
||||
macaroon = AESCipher(description="encryption").encrypt(macaroon.encode())
|
||||
print("Encrypted macaroon:")
|
||||
print(macaroon)
|
||||
logger.info("Encrypted macaroon:")
|
||||
logger.info(macaroon)
|
||||
|
|
|
@ -8,6 +8,8 @@ from http import HTTPStatus
|
|||
from os import getenv
|
||||
from typing import Optional, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .base import (
|
||||
StatusResponse,
|
||||
InvoiceResponse,
|
||||
|
@ -139,7 +141,7 @@ class OpenNodeWallet(Wallet):
|
|||
x = hmac.new(self.auth["Authorization"].encode("ascii"), digestmod="sha256")
|
||||
x.update(charge_id.encode("ascii"))
|
||||
if x.hexdigest() != data["hashed_order"]:
|
||||
print("invalid webhook, not from opennode")
|
||||
logger.error("invalid webhook, not from opennode")
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
||||
await self.queue.put(charge_id)
|
||||
|
|
|
@ -5,6 +5,8 @@ import random
|
|||
from os import getenv
|
||||
from typing import Optional, AsyncGenerator
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .base import (
|
||||
StatusResponse,
|
||||
InvoiceResponse,
|
||||
|
@ -204,5 +206,5 @@ class SparkWallet(Wallet):
|
|||
except (OSError, httpx.ReadError, httpx.ConnectError, httpx.ReadTimeout):
|
||||
pass
|
||||
|
||||
print("lost connection to spark /stream, retrying in 5 seconds")
|
||||
logger.error("lost connection to spark /stream, retrying in 5 seconds")
|
||||
await asyncio.sleep(5)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from typing import AsyncGenerator, Optional
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .base import (
|
||||
InvoiceResponse,
|
||||
PaymentResponse,
|
||||
|
@ -20,7 +22,7 @@ class VoidWallet(Wallet):
|
|||
raise Unsupported("")
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
print(
|
||||
logger.info(
|
||||
"This backend does nothing, it is here just as a placeholder, you must configure an actual backend before being able to do anything useful with LNbits."
|
||||
)
|
||||
return StatusResponse(None, 0)
|
||||
|
|
|
@ -21,6 +21,7 @@ idna==3.2
|
|||
importlib-metadata==4.8.1
|
||||
jinja2==3.0.1
|
||||
lnurl==0.3.6
|
||||
loguru==0.6.0
|
||||
markupsafe==2.0.1
|
||||
marshmallow==3.13.0
|
||||
outcome==1.1.0
|
||||
|
|
Loading…
Reference in New Issue
Block a user