Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a360a47be9 | ||
|
|
552f253b5d | ||
|
|
5021d86488 | ||
|
|
c257e42222 | ||
|
|
17cdf57b8f | ||
|
|
375b575eed | ||
|
|
f860c170fc | ||
|
|
095206e2ed | ||
|
|
4f3159339a | ||
|
|
9ba2983572 | ||
|
|
acaf4849d2 | ||
|
|
3fa4135a12 | ||
|
|
a8f534cd2e | ||
|
|
c58fac39cd | ||
|
|
161cb9cfbc | ||
|
|
892d8ffa62 | ||
|
|
f2849a6e68 | ||
|
|
3d55d98d33 | ||
|
|
dc2a7898f7 | ||
|
|
2787d5c6b6 | ||
|
|
39c1dcb942 | ||
|
|
be078a8c52 | ||
|
|
934fc0abbb | ||
|
|
81986c9b4d | ||
|
|
00b3ab94ba | ||
|
|
194b063311 | ||
|
|
235513f2ef | ||
|
|
0ca4b8dea1 | ||
|
|
83f04534e7 | ||
|
|
6cf1d97d5a | ||
|
|
8410776ffb | ||
|
|
e93fbd24be | ||
|
|
1e39e7dd63 | ||
|
|
aac392a053 | ||
|
|
c81d3e06c8 | ||
|
|
a2ce8fc955 | ||
|
|
a5edcc94ff | ||
|
|
061121d635 | ||
|
|
61d809ebdb | ||
|
|
4df74c6896 | ||
|
|
de445aa593 | ||
|
|
cbde5744aa |
+1
-7
@@ -30,8 +30,6 @@ LNBITS_DEFAULT_WALLET_NAME="LNbits wallet"
|
||||
# Hides wallet api, extensions can choose to honor
|
||||
LNBITS_HIDE_API=false
|
||||
|
||||
# Disable extensions for all users, use "all" to disable all extensions
|
||||
LNBITS_DISABLED_EXTENSIONS="amilk"
|
||||
# LNBITS_EXTENSIONS_MANIFESTS="https://raw.githubusercontent.com/lnbits/lnbits-extensions/main/extensions.json,https://raw.githubusercontent.com/lnbits/lnbits-extensions/main/extensions-trial.json"
|
||||
# GitHub has rate-limits for its APIs. The limit can be increased specifying a GITHUB_TOKEN
|
||||
# LNBITS_EXT_GITHUB_TOKEN=github_pat_xxxxxxxxxxxxxxxxxx
|
||||
@@ -62,7 +60,7 @@ LNBITS_SITE_DESCRIPTION="Some description about your service, will display if ti
|
||||
LNBITS_THEME_OPTIONS="classic, bitcoin, flamingo, freedom, mint, autumn, monochrome, salvador, cyber"
|
||||
# LNBITS_CUSTOM_LOGO="https://lnbits.com/assets/images/logo/logo.svg"
|
||||
|
||||
# Choose from LNPayWallet, OpenNodeWallet, LntxbotWallet, ClicheWallet,
|
||||
# Choose from LNPayWallet, OpenNodeWallet, ClicheWallet,
|
||||
# LndWallet, LndRestWallet, CoreLightningWallet, EclairWallet,
|
||||
# LnTipsWallet, LNbitsWallet, SparkWallet, FakeWallet,
|
||||
LNBITS_BACKEND_WALLET_CLASS=VoidWallet
|
||||
@@ -110,10 +108,6 @@ LNPAY_API_KEY=LNPAY_API_KEY
|
||||
# Wallet Admin in Wallet Access Keys
|
||||
LNPAY_WALLET_KEY=LNPAY_ADMIN_KEY
|
||||
|
||||
# LntxbotWallet
|
||||
LNTXBOT_API_ENDPOINT=https://lntxbot.com/
|
||||
LNTXBOT_KEY=LNTXBOT_ADMIN_KEY
|
||||
|
||||
# OpenNodeWallet
|
||||
OPENNODE_API_ENDPOINT=https://api.opennode.com/
|
||||
OPENNODE_KEY=OPENNODE_ADMIN_KEY
|
||||
|
||||
@@ -43,6 +43,8 @@ docker
|
||||
# fly.io
|
||||
fly.toml
|
||||
|
||||
lnbits-backup.zip
|
||||
|
||||
# Ignore extensions (post installable extension PR)
|
||||
extensions/
|
||||
upgrades/
|
||||
|
||||
+10
-3
@@ -3,18 +3,25 @@ FROM python:3.10-slim
|
||||
RUN apt-get clean
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y curl pkg-config build-essential
|
||||
RUN curl -sSL https://install.python-poetry.org | python3 -
|
||||
|
||||
RUN curl -sSL https://install.python-poetry.org | python3 -
|
||||
ENV PATH="/root/.local/bin:$PATH"
|
||||
|
||||
# needed for backups postgresql-client version 14 (pg_dump)
|
||||
RUN apt-get install -y wget
|
||||
RUN echo "deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
||||
RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y postgresql-client-14
|
||||
|
||||
WORKDIR /app
|
||||
RUN mkdir -p lnbits/data
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN mkdir data
|
||||
|
||||
RUN poetry config virtualenvs.create false
|
||||
RUN poetry install --only main
|
||||
RUN poetry run python tools/build.py
|
||||
|
||||
ENV LNBITS_PORT="5000"
|
||||
ENV LNBITS_HOST="0.0.0.0"
|
||||
|
||||
@@ -7,7 +7,7 @@ LNbits
|
||||
|
||||

|
||||
|
||||
# LNbits v0.9 BETA, free and open-source Lightning wallet accounts system
|
||||
# LNbits v0.10 BETA, free and open-source Lightning wallet accounts system
|
||||
|
||||
(Join us on [https://t.me/lnbits](https://t.me/lnbits))
|
||||
|
||||
@@ -23,9 +23,9 @@ LNbits is a Python server that sits on top of any funding source. It can be used
|
||||
* Fallback wallet for the LNURL scheme
|
||||
* Instant wallet for LN demonstrations
|
||||
|
||||
LNbits can run on top of any Lightning funding source. It supports LND, CLN, Eclair, Spark, LNpay, OpenNode, lntxbot, LightningTipBot, and with more being added regularly.
|
||||
LNbits can run on top of any Lightning funding source. It supports LND, CLN, Eclair, Spark, LNpay, OpenNode, LightningTipBot, and with more being added regularly.
|
||||
|
||||
See [docs.lnbits.org](https://docs.lnbits.org) for more detailed documentation.
|
||||
See [LNbits Wiki](https://github.com/lnbits/lnbits/wiki/) for more detailed documentation.
|
||||
|
||||
Checkout the LNbits [YouTube](https://www.youtube.com/playlist?list=PLPj3KCksGbSYG0ciIQUWJru1dWstPHshe) video series.
|
||||
|
||||
@@ -33,7 +33,7 @@ LNbits is inspired by all the great work of [opennode.com](https://www.opennode.
|
||||
|
||||
## Running LNbits
|
||||
|
||||
See the [install guide](docs/guide/installation.md) for details on installation and setup.
|
||||
See the [install guide](https://github.com/lnbits/lnbits/wiki/) for details on installation and setup.
|
||||
|
||||
## LNbits as an account system
|
||||
|
||||
@@ -69,7 +69,7 @@ Wallets can be easily generated and given out to people at events. "Go to this
|
||||
If you like this project [send some tip love](https://legend.lnbits.com/paywall/GAqKguK5S8f6w5VNjS9DfK)!
|
||||
|
||||
|
||||
[docs]: https://docs.lnbits.org/
|
||||
[docs]: https://github.com/lnbits/lnbits/wiki
|
||||
[docs-badge]: https://img.shields.io/badge/docs-lnbits.org-673ab7.svg
|
||||
[github-mypy]: https://github.com/lnbits/lnbits/actions?query=workflow%3Amypy
|
||||
[github-mypy-badge]: https://github.com/lnbits/lnbits/workflows/mypy/badge.svg
|
||||
|
||||
@@ -9,11 +9,14 @@ nav_order: 2
|
||||
Making extensions
|
||||
=================
|
||||
|
||||
Start off by copying the example extension in `lnbits/extensions/example` into your own:
|
||||
Start off by cloning the [example extension](https://github.com/lnbits/example) into your `lnbits/extensions` folder and renaming it to `mysuperplugin`:
|
||||
```sh
|
||||
cp lnbits/extensions/example lnbits/extensions/mysuperplugin -r # Let's not use dashes or anything; it doesn't like those.
|
||||
cd lnbits/extensions/mysuperplugin
|
||||
cd lnbits/extensions
|
||||
git clone https://github.com/lnbits/example.git --depth=1 mysuperplugin # Let's not use dashes or anything; it doesn't like those.
|
||||
cd mysuperplugin
|
||||
rm -rf .git/
|
||||
find . -type f -print0 | xargs -0 sed -i 's/example/mysuperplugin/g' # Change all occurrences of 'example' to your plugin name 'mysuperplugin'.
|
||||
mv templates/example templates/mysuperplugin # Rename templates folder.
|
||||
```
|
||||
- if you are on macOS and having difficulty with 'sed', consider `brew install gnu-sed` and use 'gsed', without -0 option after xargs.
|
||||
|
||||
@@ -28,9 +31,9 @@ Going over the example extension's structure:
|
||||
Adding new dependencies
|
||||
-----------------------
|
||||
|
||||
DO NOT ADD NEW DEPENDENCIES. Try to use the dependencies that are availabe in `pyproject.toml`. Getting the LNbits project to accept a new dependency is time consuming and uncertain, and may result in your extension NOT being made available to others.
|
||||
DO NOT ADD NEW DEPENDENCIES. Try to use the dependencies that are available in `pyproject.toml`. Getting the LNbits project to accept a new dependency is time consuming and uncertain, and may result in your extension NOT being made available to others.
|
||||
|
||||
If for some reason your extensions must have a new python package to work, and its nees are not met in `pyproject.toml`, you can add a new package using `venv`, or `poerty`:
|
||||
If for some reason your extensions must have a new python package to work, and its needs are not met in `pyproject.toml`, you can add a new package using `venv`, or `poerty`:
|
||||
|
||||
```sh
|
||||
$ poetry add <package>
|
||||
@@ -39,7 +42,7 @@ $ ./venv/bin/pip install <package>
|
||||
```
|
||||
|
||||
**But we need an extra step to make sure LNbits doesn't break in production.**
|
||||
Dependencies need to be added to `pyproject.toml` and `requirements.txt`, then tested by running on `venv` and `poetry` compatability can be tested with `nix build .#checks.x86_64-linux.vmTest`.
|
||||
Dependencies need to be added to `pyproject.toml` and `requirements.txt`, then tested by running on `venv` and `poetry` compatibility can be tested with `nix build .#checks.x86_64-linux.vmTest`.
|
||||
|
||||
|
||||
SQLite to PostgreSQL migration
|
||||
|
||||
@@ -8,7 +8,7 @@ nav_order: 4
|
||||
Admin UI
|
||||
========
|
||||
The LNbits Admin UI lets you change LNbits settings via the LNbits frontend.
|
||||
It is disabled by default and the first time you set the enviroment variable LNBITS_ADMIN_UI=true
|
||||
It is disabled by default and the first time you set the environment variable LNBITS_ADMIN_UI=true
|
||||
the settings are initialized and saved to the database and will be used from there as long the UI is enabled.
|
||||
From there on the settings from the database are used.
|
||||
|
||||
@@ -32,14 +32,14 @@ There is also the possibility of posting the super user via webhook to another s
|
||||
|
||||
Admin Users
|
||||
===========
|
||||
enviroment variable: LNBITS_ADMIN_USERS, comma-seperated list of user ids
|
||||
Admin Users can change settings in the admin ui aswell, with the exception of funding source settings, because they require e server restart and could potentially make the server inaccessable. Also they have access to all the extension defined in LNBITS_ADMIN_EXTENSIONS.
|
||||
environment variable: LNBITS_ADMIN_USERS, comma-separated list of user ids
|
||||
Admin Users can change settings in the admin ui as well, with the exception of funding source settings, because they require e server restart and could potentially make the server inaccessable. Also they have access to all the extension defined in LNBITS_ADMIN_EXTENSIONS.
|
||||
|
||||
|
||||
Allowed Users
|
||||
=============
|
||||
enviroment variable: LNBITS_ALLOWED_USERS, comma-seperated list of user ids
|
||||
By defining this users, LNbits will no longer be useable by the public, only defined users and admins can then access the LNbits frontend.
|
||||
environment variable: LNBITS_ALLOWED_USERS, comma-separated list of user ids
|
||||
By defining this users, LNbits will no longer be usable by the public, only defined users and admins can then access the LNbits frontend.
|
||||
|
||||
|
||||
How to activate
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Extension Install
|
||||
|
||||
Anyone can create an extension by following the [example extension](https://github.com/lnbits/lnbits/tree/extension_install_02/lnbits/extensions/example).
|
||||
Anyone can create an extension by following the [example extension](https://github.com/lnbits/example) and [making extensions](https://github.com/lnbits/lnbits/blob/main/docs/devs/extensions.md) dev guide.
|
||||
|
||||
Extensions can be installed by an admin user after the **LNbits** instance has been started.
|
||||
|
||||
@@ -12,7 +12,7 @@ Go to `Manage Server` > `Server` > `Extensions Manifests`
|
||||
|
||||
|
||||
An `Extension Manifest` is a link to a `JSON` file which contains information about various extensions that can be installed (repository of extensions).
|
||||
Multiple repositories can be configured. For more information check the [Manifest File](https://github.com/lnbits/lnbits/blob/extension_install_02/docs/guide/extension-install.md#manifest-file) section.
|
||||
Multiple repositories can be configured. For more information check the [Manifest File](https://github.com/lnbits/lnbits/blob/main/docs/guide/extension-install.md#manifest-file) section.
|
||||
|
||||
|
||||
**LNbits** administrators should configure their instances to use repositories that they trust (like the [lnbits-extensions](https://github.com/lnbits/lnbits-extensions/) one).
|
||||
@@ -100,7 +100,7 @@ It goes under the `extensions` object and it is of the form:
|
||||
|----------------------|---------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| id | string | mandatory | The ID of the extension. Must be unique for each extension. It is also used as the path in the URL. |
|
||||
| name | string | mandatory | User friendly name for the extension. It will be displayed on the installation page. |
|
||||
| version | string | mandatory | Version of this release. [Semantic versoning](https://semver.org/) is recommended. |
|
||||
| version | string | mandatory | Version of this release. [Semantic versioning](https://semver.org/) is recommended. |
|
||||
| shortDescription | string | optional | A few words about the extension. It will be displayed on the installation page. |
|
||||
| icon | string | optional | quasar valid icon name |
|
||||
| details | string (html) | optional | Details about this particular release |
|
||||
|
||||
+11
-11
@@ -33,7 +33,7 @@ allow-self-payment=1
|
||||
</details>
|
||||
|
||||
<details><summary>Which funding sources can I use for LNbits?</summary>
|
||||
<p>There are several ways to run a LNbits instance funded from different sources. It is importan to choose a source that has a good liquidity and good peers connected. If you use LNbits for public services your users´ payments can then flow happily in both directions. If you would like to fund your LNbits wallet via btc please see section Troubleshooting.</p>
|
||||
<p>There are several ways to run a LNbits instance funded from different sources. It is important to choose a source that has a good liquidity and good peers connected. If you use LNbits for public services your users´ payments can then flow happily in both directions. If you would like to fund your LNbits wallet via btc please see section Troubleshooting.</p>
|
||||
<p>The <a href="http://docs.lnbits.org/guide/wallets.html">LNbits manual</a> shows you which sources can be used and how to configure each: CLN, LND, LNPay, Cliche, OpenNode as well as bots.</p>
|
||||
</details>
|
||||
|
||||
@@ -47,7 +47,7 @@ allow-self-payment=1
|
||||
<p>When you run your LNbits in clearnet basically everyone can generate a wallet on it. Since the funds of your node are bound to these wallets you might want to prevent that. There are two ways to do so:</p>
|
||||
<ul>
|
||||
<li>Configure allowed users & extensions <a href="https://github.com/lnbits/lnbits/blob/main/.env.example">in the .env file</a></li>
|
||||
<li>Configure allowed users & extensions <a href="https://github.com/lnbits/lnbits/tree/main/lnbits/extensions/usermanager">via the Usermanager-Extension</a>. You can find <a href="http://docs.lnbits.org/guide/admin_ui.html">more info about the superuser and the admin extension here</a></li>
|
||||
<li>Configure allowed users & extensions <a href="https://github.com/lnbits/usermanager">via the Usermanager-Extension</a>. You can find <a href="http://docs.lnbits.org/guide/admin_ui.html">more info about the superuser and the admin extension here</a></li>
|
||||
</ul>
|
||||
<p>Please note that all entries in the .env file will not be the taken into account once you activated the admin extension.</p>
|
||||
</details>
|
||||
@@ -112,7 +112,7 @@ allow-self-payment=1
|
||||
<ul>
|
||||
<li>
|
||||
<details><summary>A - Via an external swap service</summary>
|
||||
<p>If the user do not have full acceess of your LNbits, is just an external user, can use swap services like <a href="https://boltz.exchange/">Boltz</a>, <a href="https://fixedfloat.com/">FixedFloat</a>, <a href="https://swap.diamondhands.technology/">DiamondHands</a> or <a href="https://zigzag.io/">ZigZag</a>.</p>
|
||||
<p>If the user do not have full access of your LNbits, is just an external user, can use swap services like <a href="https://boltz.exchange/">Boltz</a>, <a href="https://fixedfloat.com/">FixedFloat</a>, <a href="https://swap.diamondhands.technology/">DiamondHands</a> or <a href="https://zigzag.io/">ZigZag</a>.</p>
|
||||
<p>This is useful if you provide only LNURL/LN invoices from your LNbits instance, but a payer only has onchain sats so
|
||||
they will have to the swap those sats first on their side.</p>
|
||||
<p>The procedure is simple: user sends onchain btc to the swap service and provides the LNURL / LN invoice from LNbits as destination of the swap.</p>
|
||||
@@ -122,7 +122,7 @@ allow-self-payment=1
|
||||
<details><summary>B - Using the Onchain LNbits extension</summary>
|
||||
<p>Keep in mind that this is a separate wallet, not the LN btc one that is represented by LNbits as "your wallet" upon your LN funding source.
|
||||
This onchain wallet can be used also to swap LN btc to (e.g. your hardwarewallet) by using the LNbits Boltz or Deezy extension.
|
||||
If you run a webshop that is linked to your LNbits for LN payments, it is very handy to regularily drain all the sats from LN into onchain.
|
||||
If you run a webshop that is linked to your LNbits for LN payments, it is very handy to regularly drain all the sats from LN into onchain.
|
||||
This leads to more space in your LN channels to be able to receive new fresh sats.</p>
|
||||
<p>Procedure:</p>
|
||||
<ul>
|
||||
@@ -157,10 +157,10 @@ allow-self-payment=1
|
||||
|
||||
|
||||
<details><summary>How can I use a LNbits lndhub account in other wallet apps?</summary>
|
||||
<p>Open your LNbits with the account / wallet you want to use, go to "manage extensions" and activate the LNDHUB extension.</p>
|
||||
<p>Open your LNbits with the account / wallet you want to use, go to "manage extensions" and activate the <a href="https://github.com/lnbits/lndhub">LNDHUB extension</a>.</p>
|
||||
<p>Then open the LNDHUB extension, choose the wallet you want to use and scan the QR code you want to use: "admin" or "invoice only", depending on the security level you want for that wallet.</p>
|
||||
<p>You can use <a href="https://zeusln.app">Zeus</a> or <a href="https://bluewallet.io">Bluewallet</a> as wallet apps for a lndhub account.</p>
|
||||
<p>Keep in mind: if your LNbits instance is Tor only, you must use also theose apps behind Tor and open the LNbits page through your Tor .onion address.</p>
|
||||
<p>Keep in mind: if your LNbits instance is Tor only, you must use also those apps behind Tor and open the LNbits page through your Tor .onion address.</p>
|
||||
</details>
|
||||
</ul>
|
||||
</ul>
|
||||
@@ -169,11 +169,11 @@ allow-self-payment=1
|
||||
<ul> <p>LNbits has all sorts of open APIs and tools to program and connect to a lot of different devices for a gazillion of use-cases. Let us know what you did with it ! Come to the <a href="https://t.me/makerbits">Makerbits Telegram Group</a> if you are interested in building or if you need help with a project - we got you!</p>
|
||||
|
||||
<details><summary>ATM - deposit and withdraw in your shop or at your meetup</summary>
|
||||
<p>This is a do-it-yourself project consisting of a mini-computer (Raspberry Pi Zero), a coin acceptor, a display, a 3D printed case, and a Bitcoin Lightning wallet as a funding source. It exchanges fiat coins for valuable Bitcoin Lightning ⚡ Satoshis. The user can pick up the Satoshis via QR code (LNURL-withdraw) on a mobile phone wallet. It works based on BTCPayer server, LNTXBOT is not longer an option. You can get the components as individual parts and build the case yourself e.g. from <a href="https://www.Fulmo.org">Fulmo</a> who also made a <a href="https://blog.fulmo.org/the-lightningatm-pocket-edition/">guide</a> on it. The shop offers payments in Bitcoin and Lightning ⚡. The code can be found on <a href="https://github.com/21isenough/LightningATM">the ATM github project page></a>.</p>
|
||||
<p>This is a do-it-yourself project consisting of a mini-computer (Raspberry Pi Zero), a coin acceptor, a display, a 3D printed case, and a Bitcoin Lightning wallet as a funding source. It exchanges fiat coins for valuable Bitcoin Lightning ⚡ Satoshis. The user can pick up the Satoshis via QR code (LNURL-withdraw) on a mobile phone wallet. You can get the components as individual parts and build the case yourself e.g. from <a href="https://www.Fulmo.org">Fulmo</a> who also made a <a href="https://blog.fulmo.org/the-lightningatm-pocket-edition/">guide</a> on it. The shop offers payments in Bitcoin and Lightning ⚡. The code can be found on <a href="https://github.com/21isenough/LightningATM">the ATM github project page></a>.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>POS Terminal - an offline terminal for merchants</summary>
|
||||
<p>The LNpos is a self-sufficient point of sale terminal which allows offline onchain payments and an offline Lightning ATM for withdrawals. Free and open source software, free from intermediaries, with integrated battery, WLAN, DIY. You can get the 3D print as well as the whole kit from the LNbits shop from 👇 Ressources. It allows
|
||||
<p>The LNpos is a self-sufficient point of sale terminal which allows offline onchain payments and an offline Lightning ATM for withdrawals. Free and open source software, free from intermediaries, with integrated battery, WLAN, DIY. You can get the 3D print as well as the whole kit from the LNbits shop from 👇 Resources. It allows
|
||||
<li>LNPoS Online interactive Lightning payments</li>
|
||||
<li>LNURLPoS Offline Lightning Payments. Passive interaction, sharing a secret as evidence</li>
|
||||
<li>OnChain For onchain payments. Generates an address and displays a link for verification</li>
|
||||
@@ -192,7 +192,7 @@ allow-self-payment=1
|
||||
</details>
|
||||
|
||||
<details><summary>Bitcoin Switch - turn things on with bitcoin</summary>
|
||||
<p>Candy dispenser, vending machines (online), grabbing machines, jukeboxes, bandits and <a href="https://github.com/cryptoteun/awesome-lnbits">all sorts of other things have already been build with LNbits´ tools</a>. Further info see 👇 Ressources.</p>
|
||||
<p>Candy dispenser, vending machines (online), grabbing machines, jukeboxes, bandits and <a href="https://github.com/cryptoteun/awesome-lnbits">all sorts of other things have already been build with LNbits´ tools</a>. Further info see 👇 Resources.</p>
|
||||
<p>
|
||||
<img width="549" alt="Bildschirmfoto 2023-01-20 um 18 11 55" src="https://user-images.githubusercontent.com/63317640/213761646-d25d4745-e50d-4389-98e5-f83237a8cf6b.png">
|
||||
</p>
|
||||
@@ -209,7 +209,7 @@ allow-self-payment=1
|
||||
<ul>
|
||||
<li><a href="https://t.me/makerbits'">MakerBits</a> - Telegram support group</li>
|
||||
<li><a href="https://ereignishorizont.xyz/">Instructions for LNpos, Switch, ATM, BTCticker</a> - guides in DE & EN</li>
|
||||
<li><a href="https://shop.lnbits.com/">LNbits shop</a> - eadymade hardware gimmicks from the community</li>
|
||||
<li><a href="https://shop.lnbits.com/">LNbits shop</a> - readymade hardware gimmicks from the community</li>
|
||||
<li><a href="https://github.com/cryptoteun/awesome-lnbits#hardware-projects-utilizing-lnbits">Collection of hardware projects using LNbits</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -222,7 +222,7 @@ allow-self-payment=1
|
||||
</details>
|
||||
|
||||
<details><summary>Swapping ⚡️LN BTC to a BTC address</summary>
|
||||
<p>LNbits has two swap extensions integrated: <a href="https://github.com/lnbits/lnbits/tree/main/lnbits/extensions/boltz">Boltz</a> and <a href="https://github.com/lnbits/lnbits/tree/main/lnbits/extensions/deezy">Deezy</a>.</p>
|
||||
<p>LNbits has two swap extensions integrated: <a href="https://github.com/lnbits/boltz-extension/">Boltz</a> and <a href="hhttps://github.com/lnbits/deezy">Deezy</a>.</p>
|
||||
<p>For a merchant that uses LNbits to receive BTC payments through LN, this is very handy to move the received sats from LN channels into onchain wallets. It not only helps you HODLing but is also freeing up "space in your channels" so you are ready to receive more sats.</p>
|
||||
<p>Boltz has an option to setup an automated swap triggered by a certain amount received.</p>
|
||||
</details>
|
||||
|
||||
@@ -303,7 +303,7 @@ Description=LNbits
|
||||
|
||||
[Service]
|
||||
# replace with the absolute path of your lnbits installation
|
||||
WorkingDirectory=/home/lnbits/lnbits-legend
|
||||
WorkingDirectory=/home/lnbits/lnbits
|
||||
# same here. run `which poetry` if you can't find the poetry binary
|
||||
ExecStart=/home/lnbits/.local/bin/poetry run lnbits
|
||||
# replace with the user that you're running lnbits on
|
||||
@@ -405,7 +405,7 @@ service restart apache2
|
||||
## Using https without reverse proxy
|
||||
The most common way of using LNbits via https is to use a reverse proxy such as Caddy, nginx, or ngriok. However, you can also run LNbits via https without additional software. This is useful for development purposes or if you want to use LNbits in your local network.
|
||||
|
||||
We have to create a self-signed certificate using `mkcert`. Note that this certiciate is not "trusted" by most browsers but that's fine (since you know that you have created it) and encryption is always better than clear text.
|
||||
We have to create a self-signed certificate using `mkcert`. Note that this certificate is not "trusted" by most browsers but that's fine (since you know that you have created it) and encryption is always better than clear text.
|
||||
|
||||
#### Install mkcert
|
||||
You can find the install instructions for `mkcert` [here](https://github.com/FiloSottile/mkcert).
|
||||
|
||||
@@ -8,7 +8,7 @@ nav_order: 3
|
||||
Backend wallets
|
||||
===============
|
||||
|
||||
LNbits can run on top of many lightning-network funding sources. Currently there is support for CoreLightning, LND, LNbits, LNPay, lntxbot and OpenNode, with more being added regularly.
|
||||
LNbits can run on top of many lightning-network funding sources. Currently there is support for CoreLightning, LND, LNbits, LNPay and OpenNode, with more being added regularly.
|
||||
|
||||
A backend wallet can be configured using the following LNbits environment variables:
|
||||
|
||||
@@ -65,13 +65,6 @@ For the invoice listener to work you have a publicly accessible URL in your LNbi
|
||||
- `LNPAY_WALLET_KEY`: waka_apiKey
|
||||
|
||||
|
||||
### lntxbot
|
||||
|
||||
- `LNBITS_BACKEND_WALLET_CLASS`: **LntxbotWallet**
|
||||
- `LNTXBOT_API_ENDPOINT`: https://lntxbot.com/
|
||||
- `LNTXBOT_KEY`: lntxbotAdminApiKey
|
||||
|
||||
|
||||
### OpenNode
|
||||
|
||||
For the invoice to work you must have a publicly accessible URL in your LNbits. No manual webhook setting is necessary.
|
||||
|
||||
+24
-2
@@ -105,20 +105,42 @@ async def check_funding_source() -> None:
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
WALLET = get_wallet_class()
|
||||
|
||||
# fallback to void after 30 seconds of failures
|
||||
sleep_time = 5
|
||||
timeout = int(30 / sleep_time)
|
||||
|
||||
balance = 0
|
||||
retry_counter = 0
|
||||
|
||||
while True:
|
||||
try:
|
||||
error_message, balance = await WALLET.status()
|
||||
if not error_message:
|
||||
retry_counter = 0
|
||||
break
|
||||
|
||||
logger.error(
|
||||
f"The backend for {WALLET.__class__.__name__} isn't working properly: '{error_message}'",
|
||||
RuntimeWarning,
|
||||
)
|
||||
except:
|
||||
pass
|
||||
logger.info("Retrying connection to backend in 5 seconds...")
|
||||
await asyncio.sleep(5)
|
||||
|
||||
if settings.lnbits_admin_ui and retry_counter == timeout:
|
||||
logger.warning(
|
||||
f"Fallback to VoidWallet, because the backend for {WALLET.__class__.__name__} isn't working properly"
|
||||
)
|
||||
set_wallet_class("VoidWallet")
|
||||
WALLET = get_wallet_class()
|
||||
break
|
||||
else:
|
||||
logger.warning(f"Retrying connection to backend in {sleep_time} seconds...")
|
||||
retry_counter += 1
|
||||
await asyncio.sleep(sleep_time)
|
||||
|
||||
signal.signal(signal.SIGINT, original_sigint_handler)
|
||||
|
||||
logger.info(
|
||||
f"✔️ Backend {WALLET.__class__.__name__} connected and with a balance of {balance} msat."
|
||||
)
|
||||
|
||||
@@ -67,18 +67,6 @@
|
||||
></q-select>
|
||||
<br />
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<p>Disabled Extensions</p>
|
||||
<q-select
|
||||
filled
|
||||
v-model="formData.lnbits_disabled_extensions"
|
||||
:options="g.extensions.map(e => e.name)"
|
||||
multiple
|
||||
hint="Disable extensions *amilk disabled by default as resource heavy"
|
||||
label="Disable extensions"
|
||||
></q-select>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
<q-tooltip> Add funds to a wallet. </q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<!-- <q-btn
|
||||
<q-btn
|
||||
label="Download Database Backup"
|
||||
flat
|
||||
@click="downloadBackup"
|
||||
></q-btn> -->
|
||||
></q-btn>
|
||||
|
||||
<q-btn
|
||||
flat
|
||||
@@ -535,19 +535,7 @@
|
||||
})
|
||||
},
|
||||
downloadBackup() {
|
||||
LNbits.api
|
||||
.request('GET', '/admin/api/v1/backup/?usr=' + this.g.user.id)
|
||||
.then(response => {
|
||||
this.$q.notify({
|
||||
type: 'positive',
|
||||
message:
|
||||
'Success! Database backup request, download starts soon!',
|
||||
icon: null
|
||||
})
|
||||
})
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
window.open('/admin/api/v1/backup/?usr=' + this.g.user.id, '_blank')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<p>
|
||||
Easy to set up and lightweight, LNbits can run on any
|
||||
lightning-network funding source, currently supporting LND,
|
||||
c-lightning, OpenNode, lntxbot, LNPay and even LNbits itself!
|
||||
c-lightning, OpenNode, LNPay and even LNbits itself!
|
||||
</p>
|
||||
<p>
|
||||
You can run LNbits for yourself, or easily offer a custodian
|
||||
@@ -135,24 +135,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a href="https://github.com/shesek/spark-wallet">
|
||||
<q-img
|
||||
contain
|
||||
:src="($q.dark.isActive) ? '/static/images/spark.png' : '/static/images/sparkl.png'"
|
||||
></q-img>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col q-pl-md">
|
||||
<a href="https://t.me/lntxbot">
|
||||
<q-img
|
||||
contain
|
||||
:src="($q.dark.isActive) ? '/static/images/lntxbot.png' : '/static/images/lntxbotl.png'"
|
||||
></q-img>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a href="https://github.com/rootzoll/raspiblitz">
|
||||
@@ -182,6 +164,14 @@
|
||||
</div>
|
||||
<div class="col q-pl-md"> </div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a href="https://github.com/shesek/spark-wallet">
|
||||
<q-img
|
||||
contain
|
||||
:src="($q.dark.isActive) ? '/static/images/spark.png' : '/static/images/sparkl.png'"
|
||||
></q-img>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if AD_SPACE %} {% for ADS in AD_SPACE %} {% set AD = ADS.split(';') %}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import os
|
||||
import time
|
||||
from http import HTTPStatus
|
||||
from shutil import make_archive
|
||||
from subprocess import Popen
|
||||
from typing import Optional
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from fastapi import Body, Depends
|
||||
from fastapi.responses import FileResponse
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from lnbits.core.crud import get_wallet
|
||||
@@ -9,7 +15,7 @@ from lnbits.core.models import User
|
||||
from lnbits.core.services import update_cached_settings, update_wallet_balance
|
||||
from lnbits.decorators import check_admin, check_super_user
|
||||
from lnbits.server import server_restart
|
||||
from lnbits.settings import AdminSettings, EditableSettings
|
||||
from lnbits.settings import AdminSettings, EditableSettings, settings
|
||||
|
||||
from .. import core_app
|
||||
from ..crud import delete_admin_settings, get_admin_settings, update_admin_settings
|
||||
@@ -72,3 +78,43 @@ async def api_topup_balance(
|
||||
await update_wallet_balance(wallet_id=id, amount=int(amount))
|
||||
|
||||
return {"status": "Success"}
|
||||
|
||||
|
||||
@core_app.get(
|
||||
"/admin/api/v1/backup/",
|
||||
status_code=HTTPStatus.OK,
|
||||
dependencies=[Depends(check_super_user)],
|
||||
response_class=FileResponse,
|
||||
)
|
||||
async def api_download_backup() -> FileResponse:
|
||||
last_filename = "lnbits-backup"
|
||||
filename = f"lnbits-backup-{int(time.time())}.zip"
|
||||
db_url = settings.lnbits_database_url
|
||||
pg_backup_filename = f"{settings.lnbits_data_folder}/lnbits-database.dmp"
|
||||
is_pg = db_url and db_url.startswith("postgres://")
|
||||
|
||||
if is_pg:
|
||||
p = urlparse(db_url)
|
||||
command = (
|
||||
f"pg_dump --host={p.hostname} "
|
||||
f'--dbname={p.path.replace("/", "")} '
|
||||
f"--username={p.username} "
|
||||
f"--no-password "
|
||||
f"--format=c "
|
||||
f"--file={pg_backup_filename}"
|
||||
)
|
||||
proc = Popen(
|
||||
command, shell=True, env={**os.environ, "PGPASSWORD": p.password or ""}
|
||||
)
|
||||
proc.wait()
|
||||
|
||||
make_archive(last_filename, "zip", settings.lnbits_data_folder)
|
||||
|
||||
# cleanup pg_dump file
|
||||
if is_pg:
|
||||
proc = Popen(f"rm {pg_backup_filename}", shell=True)
|
||||
proc.wait()
|
||||
|
||||
return FileResponse(
|
||||
path=f"{last_filename}.zip", filename=filename, media_type="application/zip"
|
||||
)
|
||||
|
||||
@@ -54,8 +54,6 @@ class Extension(NamedTuple):
|
||||
|
||||
class ExtensionManager:
|
||||
def __init__(self):
|
||||
self._disabled: List[str] = settings.lnbits_disabled_extensions
|
||||
self._admin_only: List[str] = settings.lnbits_admin_extensions
|
||||
p = Path(settings.lnbits_path, "extensions")
|
||||
os.makedirs(p, exist_ok=True)
|
||||
self._extension_folders: List[Path] = [f for f in p.iterdir() if f.is_dir()]
|
||||
@@ -64,23 +62,18 @@ class ExtensionManager:
|
||||
def extensions(self) -> List[Extension]:
|
||||
output: List[Extension] = []
|
||||
|
||||
if "all" in self._disabled:
|
||||
return output
|
||||
|
||||
for extension in [
|
||||
ext for ext in self._extension_folders if ext not in self._disabled
|
||||
]:
|
||||
for extension_folder in self._extension_folders:
|
||||
extension_code = extension_folder.parts[-1]
|
||||
try:
|
||||
with open(extension / "config.json") as json_file:
|
||||
with open(extension_folder / "config.json") as json_file:
|
||||
config = json.load(json_file)
|
||||
is_valid = True
|
||||
is_admin_only = True if extension in self._admin_only else False
|
||||
is_admin_only = extension_code in settings.lnbits_admin_extensions
|
||||
except Exception:
|
||||
config = {}
|
||||
is_valid = False
|
||||
is_admin_only = False
|
||||
|
||||
*_, extension_code = extension.parts
|
||||
output.append(
|
||||
Extension(
|
||||
extension_code,
|
||||
|
||||
@@ -100,6 +100,7 @@ def template_renderer(additional_folders: List = None) -> Jinja2Templates:
|
||||
t.env.globals["AD_SPACE"] = settings.lnbits_ad_space.split(",")
|
||||
t.env.globals["AD_SPACE_TITLE"] = settings.lnbits_ad_space_title
|
||||
|
||||
t.env.globals["VOIDWALLET"] = settings.lnbits_backend_wallet_class == "VoidWallet"
|
||||
t.env.globals["HIDE_API"] = settings.lnbits_hide_api
|
||||
t.env.globals["SITE_TITLE"] = settings.lnbits_site_title
|
||||
t.env.globals["LNBITS_DENOMINATION"] = settings.lnbits_denomination
|
||||
|
||||
+6
-13
@@ -43,7 +43,6 @@ class UsersSettings(LNbitsSettings):
|
||||
|
||||
class ExtensionsSettings(LNbitsSettings):
|
||||
lnbits_admin_extensions: List[str] = Field(default=[])
|
||||
lnbits_disabled_extensions: List[str] = Field(default=[])
|
||||
lnbits_extensions_manifests: List[str] = Field(
|
||||
default=[
|
||||
"https://raw.githubusercontent.com/lnbits/lnbits-extensions/main/extensions.json"
|
||||
@@ -88,7 +87,7 @@ class ThemesSettings(LNbitsSettings):
|
||||
|
||||
|
||||
class OpsSettings(LNbitsSettings):
|
||||
lnbits_baseurl: str = Field(default="http://127.0.0.1/")
|
||||
lnbits_baseurl: str = Field(default="http://127.0.0.1:5000/")
|
||||
lnbits_reserve_fee_min: int = Field(default=2000)
|
||||
lnbits_reserve_fee_percent: float = Field(default=1.0)
|
||||
lnbits_service_fee: float = Field(default=0)
|
||||
@@ -147,11 +146,6 @@ class LnPayFundingSource(LNbitsSettings):
|
||||
lnpay_wallet_key: Optional[str] = Field(default=None)
|
||||
|
||||
|
||||
class LnTxtBotFundingSource(LNbitsSettings):
|
||||
lntxbot_api_endpoint: Optional[str] = Field(default=None)
|
||||
lntxbot_key: Optional[str] = Field(default=None)
|
||||
|
||||
|
||||
class OpenNodeFundingSource(LNbitsSettings):
|
||||
opennode_api_endpoint: Optional[str] = Field(default=None)
|
||||
opennode_key: Optional[str] = Field(default=None)
|
||||
@@ -190,7 +184,6 @@ class FundingSourcesSettings(
|
||||
LndRestFundingSource,
|
||||
LndGrpcFundingSource,
|
||||
LnPayFundingSource,
|
||||
LnTxtBotFundingSource,
|
||||
OpenNodeFundingSource,
|
||||
SparkFundingSource,
|
||||
LnTipsFundingSource,
|
||||
@@ -212,7 +205,6 @@ class EditableSettings(
|
||||
"lnbits_allowed_users",
|
||||
"lnbits_theme_options",
|
||||
"lnbits_admin_extensions",
|
||||
"lnbits_disabled_extensions",
|
||||
pre=True,
|
||||
)
|
||||
def validate_editable_settings(cls, val):
|
||||
@@ -317,8 +309,9 @@ def set_cli_settings(**kwargs):
|
||||
|
||||
|
||||
# set wallet class after settings are loaded
|
||||
def set_wallet_class():
|
||||
wallet_class = getattr(wallets_module, settings.lnbits_backend_wallet_class)
|
||||
def set_wallet_class(class_name: Optional[str] = None):
|
||||
backend_wallet_class = class_name or settings.lnbits_backend_wallet_class
|
||||
wallet_class = getattr(wallets_module, backend_wallet_class)
|
||||
global WALLET
|
||||
WALLET = wallet_class()
|
||||
|
||||
@@ -374,9 +367,9 @@ except:
|
||||
settings.lnbits_commit = "docker"
|
||||
|
||||
|
||||
# printing enviroment variable for debugging
|
||||
# printing environment variable for debugging
|
||||
if not settings.lnbits_admin_ui:
|
||||
logger.debug("Enviroment Settings:")
|
||||
logger.debug("Environment Settings:")
|
||||
for key, value in settings.dict(exclude_none=True).items():
|
||||
logger.debug(f"{key}: {value}")
|
||||
|
||||
|
||||
@@ -44,7 +44,11 @@
|
||||
endblock %}
|
||||
</q-btn>
|
||||
</q-toolbar-title>
|
||||
{% block beta %}
|
||||
{% block beta %} {% if VOIDWALLET %}
|
||||
<q-badge color="red" text-color="black" class="q-mr-md">
|
||||
<span>VoidWallet is active! Payments disabled</span>
|
||||
</q-badge>
|
||||
{%endif%}
|
||||
<q-badge color="yellow" text-color="black" class="q-mr-md">
|
||||
<span
|
||||
><span v-show="$q.screen.gt.sm"
|
||||
|
||||
@@ -11,7 +11,6 @@ from .lndgrpc import LndWallet
|
||||
from .lndrest import LndRestWallet
|
||||
from .lnpay import LNPayWallet
|
||||
from .lntips import LnTipsWallet
|
||||
from .lntxbot import LntxbotWallet
|
||||
from .opennode import OpenNodeWallet
|
||||
from .spark import SparkWallet
|
||||
from .void import VoidWallet
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
from typing import AsyncGenerator, Dict, Optional
|
||||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
from .base import (
|
||||
InvoiceResponse,
|
||||
PaymentResponse,
|
||||
PaymentStatus,
|
||||
StatusResponse,
|
||||
Wallet,
|
||||
)
|
||||
|
||||
|
||||
class LntxbotWallet(Wallet):
|
||||
"""https://github.com/fiatjaf/lntxbot/blob/master/api.go"""
|
||||
|
||||
def __init__(self):
|
||||
endpoint = settings.lntxbot_api_endpoint
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
|
||||
key = (
|
||||
settings.lntxbot_key
|
||||
or settings.lntxbot_admin_key
|
||||
or settings.lntxbot_invoice_key
|
||||
)
|
||||
self.auth = {"Authorization": f"Basic {key}"}
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.get(
|
||||
f"{self.endpoint}/balance", headers=self.auth, timeout=40
|
||||
)
|
||||
try:
|
||||
data = r.json()
|
||||
except:
|
||||
return StatusResponse(
|
||||
f"Failed to connect to {self.endpoint}, got: '{r.text[:200]}...'", 0
|
||||
)
|
||||
|
||||
if data.get("error"):
|
||||
return StatusResponse(data["message"], 0)
|
||||
|
||||
return StatusResponse(None, data["BTC"]["AvailableBalance"] * 1000)
|
||||
|
||||
async def create_invoice(
|
||||
self,
|
||||
amount: int,
|
||||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
data: Dict = {"amt": str(amount)}
|
||||
if description_hash:
|
||||
data["description_hash"] = description_hash.hex()
|
||||
elif unhashed_description:
|
||||
data["description_hash"] = hashlib.sha256(unhashed_description).hexdigest()
|
||||
else:
|
||||
data["memo"] = memo or ""
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
f"{self.endpoint}/addinvoice", headers=self.auth, json=data, timeout=40
|
||||
)
|
||||
|
||||
if r.is_error:
|
||||
try:
|
||||
data = r.json()
|
||||
error_message = data["message"]
|
||||
except:
|
||||
error_message = r.text
|
||||
|
||||
return InvoiceResponse(False, None, None, error_message)
|
||||
|
||||
data = r.json()
|
||||
return InvoiceResponse(True, data["payment_hash"], data["pay_req"], None)
|
||||
|
||||
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
f"{self.endpoint}/payinvoice",
|
||||
headers=self.auth,
|
||||
json={"invoice": bolt11},
|
||||
timeout=None,
|
||||
)
|
||||
|
||||
if "error" in r.json():
|
||||
try:
|
||||
data = r.json()
|
||||
error_message = data["message"]
|
||||
except:
|
||||
error_message = r.text
|
||||
return PaymentResponse(False, None, None, None, error_message)
|
||||
|
||||
data = r.json()
|
||||
if data.get("type") != "paid_invoice":
|
||||
return PaymentResponse(None)
|
||||
checking_id = data["payment_hash"]
|
||||
fee_msat = -data["fee_msat"]
|
||||
preimage = data["payment_preimage"]
|
||||
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
|
||||
|
||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
f"{self.endpoint}/invoicestatus/{checking_id}?wait=false",
|
||||
headers=self.auth,
|
||||
)
|
||||
|
||||
data = r.json()
|
||||
if r.is_error or "error" in data:
|
||||
return PaymentStatus(None)
|
||||
|
||||
if "preimage" not in data:
|
||||
return PaymentStatus(False)
|
||||
|
||||
return PaymentStatus(True)
|
||||
|
||||
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.post(
|
||||
url=f"{self.endpoint}/paymentstatus/{checking_id}", headers=self.auth
|
||||
)
|
||||
|
||||
data = r.json()
|
||||
if r.is_error or "error" in data:
|
||||
return PaymentStatus(None)
|
||||
|
||||
statuses = {"complete": True, "failed": False, "pending": None, "unknown": None}
|
||||
return PaymentStatus(statuses[data.get("status", "unknown")])
|
||||
|
||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||
url = f"{self.endpoint}/payments/stream"
|
||||
|
||||
while True:
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=None, headers=self.auth) as client:
|
||||
async with client.stream("GET", url) as r:
|
||||
async for line in r.aiter_lines():
|
||||
if line.startswith("data:"):
|
||||
data = json.loads(line[5:])
|
||||
if "payment_hash" in data and data.get("msatoshi") > 0:
|
||||
yield data["payment_hash"]
|
||||
except (OSError, httpx.ReadError, httpx.ReadTimeout, httpx.ConnectError):
|
||||
pass
|
||||
|
||||
logger.error(
|
||||
"lost connection to lntxbot /payments/stream, retrying in 5 seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
Generated
+7
-7
@@ -541,10 +541,10 @@ files = [
|
||||
cffi = ">=1.12"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx_rtd_theme"]
|
||||
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
|
||||
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
|
||||
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
||||
sdist = ["setuptools_rust (>=0.11.4)"]
|
||||
sdist = ["setuptools-rust (>=0.11.4)"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"]
|
||||
|
||||
@@ -1738,14 +1738,14 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (
|
||||
|
||||
[[package]]
|
||||
name = "shortuuid"
|
||||
version = "1.0.1"
|
||||
version = "1.0.11"
|
||||
description = "A generator library for concise, unambiguous and URL-safe UUIDs."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "shortuuid-1.0.1-py3-none-any.whl", hash = "sha256:492c7402ff91beb1342a5898bd61ea953985bf24a41cd9f247409aa2e03c8f77"},
|
||||
{file = "shortuuid-1.0.1.tar.gz", hash = "sha256:3c11d2007b915c43bee3e10625f068d8a349e04f0d81f08f5fa08507427ebf1f"},
|
||||
{file = "shortuuid-1.0.11-py3-none-any.whl", hash = "sha256:27ea8f28b1bd0bf8f15057a3ece57275d2059d2b0bb02854f02189962c13b6aa"},
|
||||
{file = "shortuuid-1.0.11.tar.gz", hash = "sha256:fc75f2615914815a8e4cb1501b3a513745cb66ef0fd5fc6fb9f8c3fa3481f789"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1821,7 +1821,7 @@ mssql = ["pyodbc"]
|
||||
mssql-pymssql = ["pymssql"]
|
||||
mssql-pyodbc = ["pyodbc"]
|
||||
mysql = ["mysqlclient"]
|
||||
oracle = ["cx_oracle"]
|
||||
oracle = ["cx-oracle"]
|
||||
postgresql = ["psycopg2"]
|
||||
postgresql-pg8000 = ["pg8000 (<1.16.6)"]
|
||||
postgresql-psycopg2binary = ["psycopg2-binary"]
|
||||
@@ -2205,4 +2205,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10 | ^3.9 | ^3.8 | ^3.7"
|
||||
content-hash = "9ade42d23e7541626f1d1be38c9af2313769c372bca8bb306a4e653812aea33c"
|
||||
content-hash = "3ede9f1c735533b865009b69fefba2faefc3e4a836b4453af34c81dec29e0682"
|
||||
|
||||
+5
-4
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "lnbits"
|
||||
version = "0.9.7"
|
||||
version = "0.10.3"
|
||||
description = "LNbits, free and open-source Lightning wallet and accounts system."
|
||||
authors = ["Alan Bits <alan@lnbits.com>"]
|
||||
|
||||
@@ -23,7 +23,7 @@ psycopg2-binary = "2.9.1"
|
||||
pydantic = "1.10.4"
|
||||
pyqrcode = "1.2.1"
|
||||
pyScss = "1.4.0"
|
||||
shortuuid = "1.0.1"
|
||||
shortuuid = "1.0.11"
|
||||
sqlalchemy = "1.3.24"
|
||||
sqlalchemy-aio = "0.17.0"
|
||||
sse-starlette = "0.6.2"
|
||||
@@ -54,7 +54,7 @@ flake8 = { version = "^6.0.0", python = ">=3.8.1" }
|
||||
pylint = { version = "^2.15.10", python = ">=3.7.2" }
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0", "pyScss"]
|
||||
requires = ["poetry-core>=1.0.0", "pyscss"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
@@ -72,12 +72,14 @@ exclude = [
|
||||
"lnbits/wallets",
|
||||
"lnbits/core",
|
||||
"lnbits/*.py",
|
||||
"lnbits/extensions",
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
files = "lnbits"
|
||||
exclude = """(?x)(
|
||||
^lnbits/wallets/lnd_grpc_files.
|
||||
| ^lnbits/extensions.
|
||||
)"""
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
@@ -90,7 +92,6 @@ module = [
|
||||
"websocket.*",
|
||||
"websockets.*",
|
||||
"pyqrcode.*",
|
||||
"cashu.*",
|
||||
"shortuuid.*",
|
||||
"grpc.*",
|
||||
"lnurl.*",
|
||||
|
||||
Reference in New Issue
Block a user