diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 3051176ed..22f6d2268 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -5,6 +5,21 @@ nav_order: 2 --- # Basic installation +Install Postgres and setup a database for LNbits: +```sh +# on debian/ubuntu 'sudo apt-get -y install postgresql' +# or follow instructions at https://www.postgresql.org/download/linux/ + +# Postgres doesn't have a default password, so we'll create one. +sudo -i -u postgres +psql +# on psql +ALTER USER postgres PASSWORD 'myPassword'; # choose whatever password you want +\q +# on postgres user +createdb lnbits +exit +``` Download this repo and install the dependencies: @@ -16,7 +31,10 @@ cd lnbits/ python3 -m venv venv ./venv/bin/pip install -r requirements.txt cp .env.example .env -mkdir data +# add the database connection string to .env 'nano .env' LNBITS_DATABASE_URL= +# postgres://:@/ - alter line bellow with your user, password and db name +LNBITS_DATABASE_URL="postgres://postgres:postgres@localhost/lnbits" +# save and exit ./venv/bin/uvicorn lnbits.__main__:app --port 5000 ``` @@ -28,6 +46,10 @@ Then you can restart it and it will be using the new settings. You might also need to install additional packages or perform additional setup steps, depending on the chosen backend. See [the short guide](./wallets.md) on each different funding source. +## Important note +If you already have LNbits installed and running, we **HIGHLY** recommend you migrate to postgres! +You can use the script and instructions on [this guide](https://github.com/talvasconcelos/lnbits-sqlite-to-postgres) to migrate your SQLite database to Postgres. + # Additional guides ### LNbits running on Umbrel behind Tor diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 76f4854c3..ebecb5e30 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -64,7 +64,7 @@ async def m001_initial(db): await db.execute( """ - CREATE VIEW IF NOT EXISTS balances AS + CREATE VIEW balances AS SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM ( SELECT wallet, SUM(amount) AS s -- incoming FROM apipayments @@ -144,7 +144,7 @@ async def m004_ensure_fees_are_always_negative(db): await db.execute("DROP VIEW balances") await db.execute( """ - CREATE VIEW IF NOT EXISTS balances AS + CREATE VIEW balances AS SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM ( SELECT wallet, SUM(amount) AS s -- incoming FROM apipayments diff --git a/lnbits/db.py b/lnbits/db.py index 6142952dd..028509584 100644 --- a/lnbits/db.py +++ b/lnbits/db.py @@ -1,9 +1,10 @@ -import os import asyncio -import time import datetime -from typing import Optional +import os +import time from contextlib import asynccontextmanager +from typing import Optional + from sqlalchemy import create_engine from sqlalchemy_aio.base import AsyncConnection from sqlalchemy_aio.strategy import ASYNCIO_STRATEGY # type: ignore @@ -93,6 +94,12 @@ class Database(Compat): import psycopg2 # type: ignore + def _parse_timestamp(value, _): + f = "%Y-%m-%d %H:%M:%S.%f" + if not "." in value: + f = "%Y-%m-%d %H:%M:%S" + return time.mktime(datetime.datetime.strptime(value, f).timetuple()) + psycopg2.extensions.register_type( psycopg2.extensions.new_type( psycopg2.extensions.DECIMAL.values, @@ -114,11 +121,12 @@ class Database(Compat): psycopg2.extensions.new_type( (1184, 1114), "TIMESTAMP2INT", - lambda value, curs: time.mktime( - datetime.datetime.strptime( - value, "%Y-%m-%d %H:%M:%S.%f" - ).timetuple() - ), + _parse_timestamp + # lambda value, curs: time.mktime( + # datetime.datetime.strptime( + # value, "%Y-%m-%d %H:%M:%S.%f" + # ).timetuple() + # ), ) ) else: diff --git a/lnbits/wallets/lnbits.py b/lnbits/wallets/lnbits.py index 70d7b141d..e24531790 100644 --- a/lnbits/wallets/lnbits.py +++ b/lnbits/wallets/lnbits.py @@ -63,7 +63,7 @@ class LNbitsWallet(Wallet): async with httpx.AsyncClient() as client: r = await client.post( - url=f"{self.endpoint}/api/v1/payments", headers=self.key, json=data + url=f"{self.endpoint}/api/v1/payments", headers=self.key, json=data, ) ok, checking_id, payment_request, error_message = ( not r.is_error, @@ -85,7 +85,8 @@ class LNbitsWallet(Wallet): r = await client.post( url=f"{self.endpoint}/api/v1/payments", headers=self.key, - json={"out": True, "bolt11": bolt11}, + json={"out": True, "bolt11": bolt11}, + timeout=100, ) ok, checking_id, fee_msat, error_message = not r.is_error, None, 0, None diff --git a/lnbits/wallets/lntxbot.py b/lnbits/wallets/lntxbot.py index 190336a31..6d706959c 100644 --- a/lnbits/wallets/lntxbot.py +++ b/lnbits/wallets/lntxbot.py @@ -80,10 +80,10 @@ class LntxbotWallet(Wallet): f"{self.endpoint}/payinvoice", headers=self.auth, json={"invoice": bolt11}, - timeout=40, + timeout=100, ) - if r.is_error: + if "error" in r.json(): try: data = r.json() error_message = data["message"]