Merge branch 'lnbits:master' into TwitchAlerts
This commit is contained in:
commit
989f4eef8e
30 changed files with 115 additions and 42 deletions
|
|
@ -17,6 +17,7 @@ LNBITS_DEFAULT_WALLET_NAME="LNbits wallet"
|
|||
LNBITS_DATA_FOLDER="./data"
|
||||
# LNBITS_DATABASE_URL="postgres://user:password@host:port/databasename"
|
||||
|
||||
# disable selected extensions, or use "all" to disable all extensions
|
||||
LNBITS_DISABLED_EXTENSIONS="amilk,ngrok"
|
||||
LNBITS_FORCE_HTTPS=true
|
||||
LNBITS_SERVICE_FEE="0.0"
|
||||
|
|
@ -50,12 +51,12 @@ LNBITS_KEY=LNBITS_ADMIN_KEY
|
|||
LND_GRPC_ENDPOINT=127.0.0.1
|
||||
LND_GRPC_PORT=11009
|
||||
LND_GRPC_CERT="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/tls.cert"
|
||||
LND_GRPC_MACAROON="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/admin.macaroon"
|
||||
LND_GRPC_MACAROON="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/admin.macaroon or HEXSTRING"
|
||||
|
||||
# LndRestWallet
|
||||
LND_REST_ENDPOINT=https://127.0.0.1:8080/
|
||||
LND_REST_CERT="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/tls.cert"
|
||||
LND_REST_MACAROON="HEXSTRING"
|
||||
LND_REST_MACAROON="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/admin.macaroon or HEXSTRING"
|
||||
|
||||
# LNPayWallet
|
||||
LNPAY_API_ENDPOINT=https://api.lnpay.co/v1/
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ LNbits
|
|||
|
||||
# LNbits v0.3 BETA, free and open-source lightning-network wallet/accounts system
|
||||
|
||||
(Join us on [https://t.me/lnbits](https://t.me/lnbits))
|
||||
|
||||
Use [lnbits.com](https://lnbits.com), or run your own LNbits server!
|
||||
|
||||
LNbits is a very simple Python server that sits on top of any funding source, and can be used as:
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@ title: Basic installation
|
|||
nav_order: 2
|
||||
---
|
||||
|
||||
|
||||
Basic installation
|
||||
==================
|
||||
# Basic installation
|
||||
|
||||
Download this repo and install the dependencies:
|
||||
|
||||
|
|
@ -31,10 +29,16 @@ 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.
|
||||
|
||||
Docker installation
|
||||
===================
|
||||
# Additional guides
|
||||
|
||||
### LNbits running on Umbrel behind Tor
|
||||
|
||||
If you want to run LNbits on your Umbrel but want it to be reached through clearnet, _Uxellodunum_ made an extensive [guide](https://community.getumbrel.com/t/guide-lnbits-without-tor/604) on how to do it.
|
||||
|
||||
### Docker installation
|
||||
|
||||
To install using docker you first need to build the docker image as:
|
||||
|
||||
```
|
||||
git clone https://github.com/lnbits/lnbits.git
|
||||
cd lnbits/ # ${PWD} referred as <lnbits_repo>
|
||||
|
|
@ -42,19 +46,30 @@ docker build -t lnbits .
|
|||
```
|
||||
|
||||
You can launch the docker in a different directory, but make sure to copy `.env.example` from lnbits there
|
||||
|
||||
```
|
||||
cp <lnbits_repo>/.env.example .env
|
||||
```
|
||||
|
||||
and change the configuration in `.env` as required.
|
||||
|
||||
Then create the data directory for the user ID 1000, which is the user that runs the lnbits within the docker container.
|
||||
|
||||
```
|
||||
mkdir data
|
||||
sudo chown 1000:1000 ./data/
|
||||
```
|
||||
|
||||
Then the image can be run as:
|
||||
|
||||
```
|
||||
docker run --detach --publish 5000:5000 --name lnbits --volume ${PWD}/.env:/app/.env --volume ${PWD}/data/:/app/data lnbits
|
||||
```
|
||||
|
||||
Finally you can access your lnbits on your machine at port 5000.
|
||||
|
||||
# Additional guides
|
||||
|
||||
## LNbits running on Umbrel behind Tor
|
||||
|
||||
If you want to run LNbits on your Umbrel but want it to be reached through clearnet, _Uxellodunum_ made an extensive [guide](https://community.getumbrel.com/t/guide-lnbits-without-tor/604) on how to do it.
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@ from .helpers import (
|
|||
)
|
||||
from .proxy_fix import ASGIProxyFix
|
||||
from .tasks import (
|
||||
webhook_handler,
|
||||
invoice_listener,
|
||||
run_deferred_async,
|
||||
check_pending_payments,
|
||||
invoice_listener,
|
||||
internal_invoice_listener,
|
||||
webhook_handler,
|
||||
catch_everything_and_restart,
|
||||
)
|
||||
from .settings import WALLET
|
||||
|
||||
|
|
@ -118,10 +119,10 @@ def register_async_tasks(app):
|
|||
|
||||
@app.before_serving
|
||||
async def listeners():
|
||||
run_deferred_async(app.nursery)
|
||||
app.nursery.start_soon(check_pending_payments)
|
||||
app.nursery.start_soon(invoice_listener, app.nursery)
|
||||
app.nursery.start_soon(internal_invoice_listener, app.nursery)
|
||||
run_deferred_async()
|
||||
app.nursery.start_soon(catch_everything_and_restart, check_pending_payments)
|
||||
app.nursery.start_soon(catch_everything_and_restart, invoice_listener)
|
||||
app.nursery.start_soon(catch_everything_and_restart, internal_invoice_listener)
|
||||
|
||||
@app.after_serving
|
||||
async def stop_listeners():
|
||||
|
|
@ -131,6 +132,7 @@ def register_async_tasks(app):
|
|||
def register_exception_handlers(app):
|
||||
@app.errorhandler(Exception)
|
||||
async def basic_error(err):
|
||||
print("handled error", traceback.format_exc())
|
||||
etype, value, tb = sys.exc_info()
|
||||
traceback.print_exception(etype, err, tb)
|
||||
exc = traceback.format_exc()
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
filled
|
||||
dense
|
||||
v-model="walletName"
|
||||
label="Name your LNbits wallet *"
|
||||
label="Name your {{SITE_TITLE}} wallet *"
|
||||
></q-input>
|
||||
<q-btn
|
||||
unelevated
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@
|
|||
:columns="paymentsTable.columns"
|
||||
:pagination.sync="paymentsTable.pagination"
|
||||
no-data-label="No transactions made yet"
|
||||
:filter="paymentsTable.filter"
|
||||
>
|
||||
{% raw %}
|
||||
<template v-slot:header="props">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<q-expansion-item
|
||||
group="extras"
|
||||
icon="swap_vertical_circle"
|
||||
label="Bleskomat Extension for lnbits"
|
||||
label="Setup guide"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-card>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits Bleskomat extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} Bleskomat extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -85,7 +85,9 @@
|
|||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits captcha extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} captcha extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -133,7 +133,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits StreamCopilot Extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} StreamCopilot Extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -164,7 +164,9 @@
|
|||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits Events extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} Events extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
%} {% block page %}
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-subtitle1 q-mt-none q-mb-md">Frameworks used by LNbits</h5>
|
||||
<h5 class="text-subtitle1 q-mt-none q-mb-md">
|
||||
Frameworks used by {{SITE_TITLE}}
|
||||
</h5>
|
||||
<q-list>
|
||||
<q-item
|
||||
v-for="tool in tools"
|
||||
|
|
|
|||
|
|
@ -95,7 +95,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits jukebox extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} jukebox extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -215,7 +215,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits Livestream extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} Livestream extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@
|
|||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits LndHub extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} LndHub extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@
|
|||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
LNbits Support Tickets extension
|
||||
{{SITE_TITLE}} Support Tickets extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
|
|
|
|||
|
|
@ -120,7 +120,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits LNURL-pay extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} LNURL-pay extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -213,7 +213,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits OfflineShop extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} OfflineShop extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,9 @@
|
|||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits paywall extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} paywall extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -145,7 +145,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits satspay Extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} satspay Extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -84,7 +84,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits SplitPayments extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} SplitPayments extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -153,7 +153,9 @@
|
|||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits Subdomain extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} Subdomain extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits TPoS extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} TPoS extension</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -133,7 +133,9 @@
|
|||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits User Manager Extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} User Manager Extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -111,7 +111,9 @@
|
|||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits Watch Only Extension</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
{{SITE_TITLE}} Watch Only Extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
|
|
|
|||
|
|
@ -97,6 +97,9 @@ async def get_withdraw_links(wallet_ids: Union[str, List[str]]) -> List[Withdraw
|
|||
|
||||
|
||||
async def update_withdraw_link(link_id: str, **kwargs) -> Optional[WithdrawLink]:
|
||||
if "is_unique" in kwargs:
|
||||
kwargs["is_unique"] = int(kwargs["is_unique"])
|
||||
|
||||
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
|
||||
await db.execute(
|
||||
f"UPDATE withdraw.withdraw_link SET {q} WHERE id = ?",
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@
|
|||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
LNbits LNURL-withdraw extension
|
||||
{{SITE_TITLE}} LNURL-withdraw extension
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ class ExtensionManager:
|
|||
def extensions(self) -> List[Extension]:
|
||||
output = []
|
||||
|
||||
if "all" in self._disabled:
|
||||
return output
|
||||
|
||||
for extension in [
|
||||
ext for ext in self._extension_folders if ext not in self._disabled
|
||||
]:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import time
|
||||
import trio
|
||||
import traceback
|
||||
from http import HTTPStatus
|
||||
from typing import Optional, List, Callable
|
||||
from quart_trio import QuartTrio
|
||||
from quart import current_app
|
||||
from typing import List, Callable
|
||||
|
||||
from lnbits.settings import WALLET
|
||||
from lnbits.core.crud import (
|
||||
|
|
@ -24,9 +25,22 @@ def record_async(func: Callable) -> Callable:
|
|||
return recorder
|
||||
|
||||
|
||||
def run_deferred_async(nursery):
|
||||
def run_deferred_async():
|
||||
for func in deferred_async:
|
||||
nursery.start_soon(func)
|
||||
current_app.nursery.start_soon(catch_everything_and_restart, func)
|
||||
|
||||
|
||||
async def catch_everything_and_restart(func):
|
||||
try:
|
||||
await func()
|
||||
except trio.Cancelled:
|
||||
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.")
|
||||
await trio.sleep(5)
|
||||
await catch_everything_and_restart(func)
|
||||
|
||||
|
||||
async def send_push_promise(a, b) -> None:
|
||||
|
|
@ -54,14 +68,14 @@ async def webhook_handler():
|
|||
internal_invoice_paid, internal_invoice_received = trio.open_memory_channel(0)
|
||||
|
||||
|
||||
async def internal_invoice_listener(nursery):
|
||||
async def internal_invoice_listener():
|
||||
async for checking_id in internal_invoice_received:
|
||||
nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
||||
current_app.nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
||||
|
||||
|
||||
async def invoice_listener(nursery):
|
||||
async def invoice_listener():
|
||||
async for checking_id in WALLET.paid_invoices_stream():
|
||||
nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
||||
current_app.nursery.start_soon(invoice_callback_dispatcher, checking_id)
|
||||
|
||||
|
||||
async def check_pending_payments():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue