Compare commits

..
12 changed files with 1754 additions and 38 deletions
+2
View File
@@ -42,6 +42,8 @@ lnbits/static/bundle.min.css.old
lnbits/static/bundle-components.min.js.old lnbits/static/bundle-components.min.js.old
lnbits/upgrades lnbits/upgrades
docker docker
generated
openapi.json*
# Nix # Nix
*result* *result*
+7 -3
View File
@@ -99,9 +99,13 @@ openapi:
curl -s http://0.0.0.0:5003/openapi.json | poetry run openapi-spec-validator --errors=all - curl -s http://0.0.0.0:5003/openapi.json | poetry run openapi-spec-validator --errors=all -
# kill -9 %1 # kill -9 %1
bak: generate:
# LNBITS_DATABASE_URL=postgres://postgres:postgres@0.0.0.0:5432/postgres rm -rf generated
# mkdir generated
rm -f openapi.json
wget localhost:5000/openapi.json
npm run generate
rm openapi.json
sass: sass:
npm run sass npm run sass
+18 -4
View File
@@ -29,11 +29,13 @@ It is recommended to use the latest version of Poetry. Make sure you have Python
### Install Python 3.12 ### Install Python 3.12
## Option 2 (recommended): Poetry
It is recommended to use the latest version of Poetry. Make sure you have Python version 3.9 or higher installed.
### Verify Python version
```sh ```sh
sudo add-apt-repository -y ppa:deadsnakes/ppa
sudo apt update -y
sudo apt install -y python3.12 python3.12-dev # ensure correct headers needed for secp256k1
sudo apt install -y pkg-config python3-dev build-essential # ensure correct headers
python3 --version python3 --version
``` ```
@@ -83,6 +85,18 @@ poetry install --only main
# Start LNbits with `poetry run lnbits` # Start LNbits with `poetry run lnbits`
``` ```
## Option 2: Install script (on Debian/Ubuntu)
```sh
wget https://raw.githubusercontent.com/lnbits/lnbits/main/lnbits.sh &&
chmod +x lnbits.sh &&
./lnbits.sh
```
Now visit `0.0.0.0:5000` to make a super-user account.
`./lnbits.sh` can be used to run, but for more control `cd lnbits` and use `poetry run lnbits` (see previous option).
## Option 3: Nix ## Option 3: Nix
```sh ```sh
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
# Check install has not already run
if [ ! -d lnbits/data ]; then
# Update package list and install prerequisites non-interactively
sudo apt update -y
sudo apt install -y software-properties-common
# Add the deadsnakes PPA repository non-interactively
sudo add-apt-repository -y ppa:deadsnakes/ppa
# Install Python 3.9 and distutils non-interactively
sudo apt install -y python3.9 python3.9-distutils
# Install Poetry
curl -sSL https://install.python-poetry.org | python3.9 -
# Add Poetry to PATH for the current session
export PATH="/home/$USER/.local/bin:$PATH"
if [ ! -d lnbits/wallets ]; then
# Clone the LNbits repository
git clone https://github.com/lnbits/lnbits.git
if [ $? -ne 0 ]; then
echo "Failed to clone the repository ... FAIL"
exit 1
fi
# Ensure we are in the lnbits directory
cd lnbits || { echo "Failed to cd into lnbits ... FAIL"; exit 1; }
fi
git checkout main
# Make data folder
mkdir data
# Copy the .env.example to .env
cp .env.example .env
elif [ ! -d lnbits/wallets ]; then
# cd into lnbits
cd lnbits || { echo "Failed to cd into lnbits ... FAIL"; exit 1; }
fi
# Install the dependencies using Poetry
poetry env use python3.9
poetry install --only main
# Set environment variables for LNbits
export LNBITS_ADMIN_UI=true
export HOST=0.0.0.0
# Run LNbits
poetry run lnbits
+37 -14
View File
@@ -5,6 +5,7 @@ import time
from functools import wraps from functools import wraps
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from uuid import uuid4
import click import click
import httpx import httpx
@@ -27,13 +28,13 @@ from lnbits.core.crud import (
update_payment, update_payment,
) )
from lnbits.core.helpers import is_valid_url, migrate_databases from lnbits.core.helpers import is_valid_url, migrate_databases
from lnbits.core.models import Payment, PaymentState from lnbits.core.models import Account, Payment, PaymentState
from lnbits.core.models.extensions import ( from lnbits.core.models.extensions import (
CreateExtension, CreateExtension,
ExtensionRelease, ExtensionRelease,
InstallableExtension, InstallableExtension,
) )
from lnbits.core.services import check_admin_settings from lnbits.core.services import check_admin_settings, create_user_account_no_ckeck
from lnbits.core.views.extension_api import ( from lnbits.core.views.extension_api import (
api_install_extension, api_install_extension,
api_uninstall_extension, api_uninstall_extension,
@@ -64,6 +65,13 @@ def db():
""" """
@lnbits_cli.group()
def users():
"""
Users related commands
"""
@lnbits_cli.group() @lnbits_cli.group()
def extensions(): def extensions():
""" """
@@ -109,7 +117,7 @@ async def delete_settings():
"""Deletes the settings""" """Deletes the settings"""
async with core_db.connect() as conn: async with core_db.connect() as conn:
await conn.execute("DELETE from settings") await conn.execute("DELETE from system_settings")
@db.command("migrate") @db.command("migrate")
@@ -180,17 +188,6 @@ async def database_revert_payment(checking_id: str):
click.echo(f"Payment '{checking_id}' marked as pending.") click.echo(f"Payment '{checking_id}' marked as pending.")
@db.command("cleanup-accounts")
@click.argument("days", type=int, required=False)
@coro
async def database_cleanup_accounts(days: Optional[int] = None):
"""Delete all accounts that have no wallets"""
async with core_db.connect() as conn:
delta = days or settings.cleanup_wallets_days
delta = delta * 24 * 60 * 60
await delete_accounts_no_wallets(delta, conn)
@db.command("check-payments") @db.command("check-payments")
@click.option("-d", "--days", help="Maximum age of payments in days.") @click.option("-d", "--days", help="Maximum age of payments in days.")
@click.option("-l", "--limit", help="Maximum number of payments to be checked.") @click.option("-l", "--limit", help="Maximum number of payments to be checked.")
@@ -271,6 +268,32 @@ async def check_invalid_payments(
click.echo(" ".join([w, str(data[0]), str(data[1] / 1000).ljust(10)])) click.echo(" ".join([w, str(data[0]), str(data[1] / 1000).ljust(10)]))
@users.command("new")
@click.option("-u", "--username", required=True, help="Username.")
@click.option("-p", "--password", required=True, help="Password.")
@coro
async def create_user(username: str, password: str):
"""Create a new user bypassing the system 'new_accounts_allowed' rules"""
account = Account(
id=uuid4().hex,
username=username,
)
account.hash_password(password)
user = await create_user_account_no_ckeck(account)
click.echo(f"User '{user.username}' created. Id: '{user.id}'")
@users.command("cleanup-accounts")
@click.argument("days", type=int, required=False)
@coro
async def database_cleanup_accounts(days: Optional[int] = None):
"""Delete all accounts that have no wallets"""
async with core_db.connect() as conn:
delta = days or settings.cleanup_wallets_days
delta = delta * 24 * 60 * 60
await delete_accounts_no_wallets(delta, conn)
@extensions.command("list") @extensions.command("list")
@coro @coro
async def extensions_list(): async def extensions_list():
+1 -1
View File
File diff suppressed because one or more lines are too long
+4 -3
View File
@@ -581,9 +581,10 @@ window.windowMixin = {
query: {wal: this.g.wallet.id} query: {wal: this.g.wallet.id}
}) })
} else { } else {
const url = new URL(window.location.href) this.$router.replace({
url.searchParams.set('wal', this.g.wallet.id) path: '/wallet',
window.history.replaceState({}, '', url.toString()) query: {wal: this.g.wallet.id}
})
} }
}, },
formatBalance(amount) { formatBalance(amount) {
+6 -3
View File
@@ -1120,7 +1120,6 @@ window.WalletPageLogic = {
} }
}, },
'g.updatePayments'(newVal, oldVal) { 'g.updatePayments'(newVal, oldVal) {
console.log('updatePayments changed:', {newVal, oldVal})
this.parse.show = false this.parse.show = false
if (this.receive.paymentHash === this.g.updatePaymentsHash) { if (this.receive.paymentHash === this.g.updatePaymentsHash) {
this.receive.show = false this.receive.show = false
@@ -1146,8 +1145,12 @@ window.WalletPageLogic = {
} }
}, },
'g.wallet': { 'g.wallet': {
handler(newWallet) { handler() {
this.createdTasks() try {
this.createdTasks()
} catch (error) {
console.warn(`Chart creation failed: ${error}`)
}
}, },
deep: true deep: true
} }
+7
View File
@@ -0,0 +1,7 @@
{
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "7.12.0"
}
}
+1613 -7
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -10,9 +10,11 @@
"vendor_minify_css": "./node_modules/.bin/minify ./lnbits/static/bundle.css > ./lnbits/static/bundle.min.css", "vendor_minify_css": "./node_modules/.bin/minify ./lnbits/static/bundle.css > ./lnbits/static/bundle.min.css",
"vendor_minify_js": "./node_modules/.bin/minify ./lnbits/static/bundle.js > ./lnbits/static/bundle.min.js", "vendor_minify_js": "./node_modules/.bin/minify ./lnbits/static/bundle.js > ./lnbits/static/bundle.min.js",
"vendor_minify_components": "./node_modules/.bin/minify ./lnbits/static/bundle-components.js > ./lnbits/static/bundle-components.min.js", "vendor_minify_components": "./node_modules/.bin/minify ./lnbits/static/bundle-components.js > ./lnbits/static/bundle-components.min.js",
"bundle": "npm run sass && npm run vendor_copy && npm run vendor_json && npm run vendor_bundle_css && npm run vendor_bundle_js && npm run vendor_bundle_components && npm run vendor_minify_css && npm run vendor_minify_js && npm run vendor_minify_components" "bundle": "npm run sass && npm run vendor_copy && npm run vendor_json && npm run vendor_bundle_css && npm run vendor_bundle_js && npm run vendor_bundle_components && npm run vendor_minify_css && npm run vendor_minify_js && npm run vendor_minify_components",
"generate": "openapi-generator-cli generate -i openapi.json -g typescript-fetch -o ./generated"
}, },
"devDependencies": { "devDependencies": {
"@openapitools/openapi-generator-cli": "^2.18.4",
"concat": "^1.0.3", "concat": "^1.0.3",
"minify": "^9.2.0", "minify": "^9.2.0",
"prettier": "^3.3.3", "prettier": "^3.3.3",
@@ -23,10 +25,10 @@
"axios": "^1.8.2", "axios": "^1.8.2",
"chart.js": "^4.4.4", "chart.js": "^4.4.4",
"moment": "^2.30.1", "moment": "^2.30.1",
"nostr-tools": "^2.7.2",
"qrcode.vue": "^3.4.1", "qrcode.vue": "^3.4.1",
"quasar": "2.17.0", "quasar": "2.17.0",
"showdown": "^2.1.0", "showdown": "^2.1.0",
"nostr-tools": "^2.7.2",
"underscore": "^1.13.7", "underscore": "^1.13.7",
"vue": "3.5.8", "vue": "3.5.8",
"vue-i18n": "^10.0.6", "vue-i18n": "^10.0.6",
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "lnbits" name = "lnbits"
version = "1.0.0-rc10" version = "1.0.0"
description = "LNbits, free and open-source Lightning wallet and accounts system." description = "LNbits, free and open-source Lightning wallet and accounts system."
authors = ["Alan Bits <alan@lnbits.com>"] authors = ["Alan Bits <alan@lnbits.com>"]
readme = "README.md" readme = "README.md"