Commit graph

464 commits

Author SHA1 Message Date
Justin Sharp
d415fb30fd fix: handle missing bolt11 in CLN list_payments for keysend/BOLT12
Follow-up to #290 — same class of bug, different code path.

list_payments() in cln_jrpc.py unconditionally indexed p["bolt11"] for any
incomplete payment, causing a KeyError -> the function returned None and
then list_all_tx() crashed with `TypeError: 'NoneType' object is not
iterable`, returning HTTP 500 to the Transactions view.

CLN's `listpays` does not include `bolt11` for keysend payments or for
BOLT12 offer payments, so any node that has ever made one of those will
hit this on every Transactions load.

Fix: guard the bolt11 decode the same way #290 guards invoice fields —
only decode when bolt11 is present, and fall back to amount_sent_msat
when neither bolt11 nor amount_msat are available, so the payment still
shows up in the list.

Reproduced on RaspiBlitz v1.12.1 with Core Lightning v25.12.1 and a
keysend payment in history.
2026-05-12 19:01:33 +02:00
dependabot[bot]
e33c11cb8a chore(deps): bump python-multipart from 0.0.22 to 0.0.27
Bumps [python-multipart](https://github.com/Kludex/python-multipart) from 0.0.22 to 0.0.27.
- [Release notes](https://github.com/Kludex/python-multipart/releases)
- [Changelog](https://github.com/Kludex/python-multipart/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Kludex/python-multipart/compare/0.0.22...0.0.27)

---
updated-dependencies:
- dependency-name: python-multipart
  dependency-version: 0.0.27
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:59:46 +02:00
dependabot[bot]
4c2645e7d8 chore(deps): bump python-dotenv from 1.1.0 to 1.2.2
Bumps [python-dotenv](https://github.com/theskumar/python-dotenv) from 1.1.0 to 1.2.2.
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v1.1.0...v1.2.2)

---
updated-dependencies:
- dependency-name: python-dotenv
  dependency-version: 1.2.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:59:01 +02:00
dependabot[bot]
c1e510d8a5 chore(deps-dev): bump pytest from 9.0.2 to 9.0.3
Bumps [pytest](https://github.com/pytest-dev/pytest) from 9.0.2 to 9.0.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/9.0.2...9.0.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:58:34 +02:00
dependabot[bot]
7a269712cc chore(deps): bump aiohttp from 3.13.3 to 3.13.4
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:58:13 +02:00
dependabot[bot]
8b20bfcb98 chore(deps): bump pygments from 2.19.1 to 2.20.0
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.1 to 2.20.0.
- [Release notes](https://github.com/pygments/pygments/releases)
- [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES)
- [Commits](https://github.com/pygments/pygments/compare/2.19.1...2.20.0)

---
updated-dependencies:
- dependency-name: pygments
  dependency-version: 2.20.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:57:58 +02:00
dependabot[bot]
2e687b644b chore(deps): bump requests from 2.32.5 to 2.33.0
Bumps [requests](https://github.com/psf/requests) from 2.32.5 to 2.33.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.5...v2.33.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.33.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:57:40 +02:00
dependabot[bot]
7c1b6aebb9 chore(deps): bump deepdiff from 8.6.1 to 8.6.2
Bumps [deepdiff](https://github.com/seperman/deepdiff) from 8.6.1 to 8.6.2.
- [Release notes](https://github.com/seperman/deepdiff/releases)
- [Changelog](https://github.com/qlustered/deepdiff/blob/master/docs/changelog.rst)
- [Commits](https://github.com/seperman/deepdiff/commits)

---
updated-dependencies:
- dependency-name: deepdiff
  dependency-version: 8.6.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:57:22 +02:00
dependabot[bot]
88b7059ffa chore(deps): bump pyjwt from 2.10.1 to 2.12.0
Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.10.1 to 2.12.0.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.10.1...2.12.0)

---
updated-dependencies:
- dependency-name: pyjwt
  dependency-version: 2.12.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 18:56:59 +02:00
fusion44
3e34201f6a
refactor(flake): expose lib.mkBlitzApi for consumer-pkgs builds
Extract the Python virtualenv build into `mkBlitzApi { pkgs, python ?
null }` and expose it as `lib.mkBlitzApi`. Rewrite `overlays.default`
to call the builder against the consumer's `prev` instead of pulling
from `self.packages.${system}` (which captured this flake's pinned
nixpkgs at flake-eval time and shut consumer overlays out of the
build hook).

Motivation: NixBlitz pulls blitz-api's flake via `builtins.getFlake`
to keep the plugin self-contained. Without a pkgs-agnostic builder,
the operator's nixpkgs overlays (Pi 5 jemalloc page-size patch and
similar platform fixes) couldn't reach blitz-api's build, so the
package would either fail to compile on Pi 5 or silently link
against this flake's pinned nixpkgs and pull a second snapshot of
glibc / openssl / etc. into the operator's closure.

The `packages.${system}.${name}` attribute is preserved as a
convenience pre-built using this flake's pinned nixpkgs; consumers
that want consumer-pkgs builds should use `overlays.default` or
`lib.mkBlitzApi` directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:44:11 +02:00
fusion44
1081b7161a
fix(lightning): get_ln_info returns stub in bitcoin-only mode
`ln` is only bound to LnNode() when `BAPI_LN_NODE != "none"`. Every
`await ln.X()` call in this file therefore NameErrors when the
operator runs in bitcoin-only mode.

The most-hit caller is NativePythonSystem.get_system_info() at
app/system/impl/native_python.py:32, which always reads
`lninfo.alias` and `lninfo.color` to populate SystemInfo. The
NameError there breaks the SSE warmup pipeline
(get_full_client_warmup_data_bitcoinonly in app/api/warmup.py:116):

  warmup_new_connections() — calls get_full_client_warmup_data_bitcoinonly()
  → get_system_info() (via NativePythonSystem)
  → get_ln_info()
  → NameError: name 'ln' is not defined

The exception bubbles into the asyncio.gather(), which means new
SSE subscribers in bitcoin-only mode never receive `btc_info` /
`system_info` / `installed_app_status`. Their dashboards stay empty
forever (only periodic `hardware_info` and `ping` events flow,
because those run on separate gather loops).

Two fixes in this commit:

1. Return a stub LnInfo from get_ln_info() when ln_node == "none".
   All required fields filled with empty strings / zeros; the stub
   round-trips through any caller that reads alias/color/num_*
   without error. Other ln-method callers (get_wallet_balance,
   list_invoices, ...) keep their original behavior — they'll only
   ever fire from LN-aware code paths anyway.

2. Drop the duplicate `if ln_node != "none": ln = LnNode()` block
   at lines 69-70 (clearly a merge artifact).

Operator workaround used until this lands: enable lnd. After this
fix, bitcoin-only mode works end-to-end against the nixblitz
plugin streamer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 19:18:39 +02:00
fusion44
e691a956ae
feat: add celery services, persist auto-generated secrets 2026-04-23 13:37:31 +02:00
fusion44
5fc0d04c2e
feat: implement CLN LN backend in Nix module. 2026-04-23 11:20:14 +02:00
fusion44
c43183978a
feat: Swap out poerty2nix for uv2nix; remove devshell from flake 2026-04-23 10:56:16 +02:00
fusion44
e0f4d7e2fc
fix(deps): ensure async-timeout is included for older Python 3.11
- Add async-timeout as a direct dependency in pyproject.toml to fix
  ModuleNotFoundError on systems with Python < 3.11.3 (e.g. Raspberry Pi).
- Switch to universal requirements generation in Makefile and
  requirements.txt to include platform-specific markers and conditional
  dependencies.
- Update uv.lock to reflect dependency changes.

This resolves a crash where redis-py attempted to import async_timeout,
which was missing because it was pruned during requirements generation
on a newer Python version.
2026-02-21 08:04:34 +01:00
dependabot[bot]
5c1669aed5 chore(deps): bump urllib3 from 2.5.0 to 2.6.3
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.5.0 to 2.6.3.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.3)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-05 15:02:39 +01:00
dependabot[bot]
ae7f8f54fe chore(deps): bump python-multipart from 0.0.20 to 0.0.22
Bumps [python-multipart](https://github.com/Kludex/python-multipart) from 0.0.20 to 0.0.22.
- [Release notes](https://github.com/Kludex/python-multipart/releases)
- [Changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Kludex/python-multipart/compare/0.0.20...0.0.22)

---
updated-dependencies:
- dependency-name: python-multipart
  dependency-version: 0.0.22
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-05 15:02:21 +01:00
fusion44
74059b9256
tests: add better integration tests 2026-02-03 11:06:06 +01:00
fusion44
e564d18d2b
chore: clean up imports; add better LND error logging 2026-02-03 11:05:19 +01:00
fusion44
07d2bfbc76
feat: update Python and Devenv deps
- Updated all dependencies to their latest versions
- Vendored fastapi-plugins[redis] as it looks unmaintained
2026-02-03 11:04:41 +01:00
fusion44
44385ca40c
chore: deprecate poetry for uv; update dependencies 2025-11-10 12:30:03 +01:00
Justin Sharp
6b3acf0239 fix: handle missing fields in CLN invoice data gracefully
Fixes #129, #128, and addresses part of raspiblitz/raspiblitz#3182

BOLT12 offers, keysend payments, and certain CLN invoice types don't
always include all fields that the API expects, causing KeyError
exceptions that crash the web interface.

Changes:
- Modified Invoice.from_cln_json() to use .get() with safe defaults
  for all potentially missing fields (bolt11, amount_msat, payment_hash,
  description, label, status, etc.)
- Added fallback logic for amount_msat to use amount_received_msat
  when the primary field is missing
- Enhanced InvoiceState.from_cln_json() to handle unknown/missing
  statuses gracefully with logging instead of raising exceptions

This allows the web interface to display all CLN invoices including
BOLT12 payments from services like OCEAN mining pool, while preserving
all existing payment data for standard BOLT11 invoices.

Tested on RaspiBlitz v1.12.0 with Core Lightning and OCEAN mining
pool BOLT12 payouts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 10:00:05 +01:00
dependabot[bot]
acad234651 chore(deps): bump urllib3 from 2.4.0 to 2.5.0
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.4.0...2.5.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.5.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 18:38:14 +02:00
fusion44
b555466053
fix: increase timeout for fetching app statuses 2025-08-08 18:27:48 +02:00
fusion44
b5786399bf
fix: target python 3.11 2025-08-08 09:10:41 +02:00
fusion44
d63e63f4e6
chore: remove deprecated async-timeout dep use 2025-05-13 19:22:47 +02:00
fusion44
6d1aca7854
chore: pin dependencies to an exact version 2025-05-09 12:45:31 +02:00
fusion44
382f8303f3 chore: update deps and fake blitz scripts 2025-05-06 09:16:46 +02:00
fusion44
bda5d565ee fix: don't stop app status listener 2025-05-06 09:16:46 +02:00
fusion44
f1aa2107fd refactor: code cleanup
- rename various keys
- update app status updater code to work like the app management code
- remove some unused code

refs #123
2025-05-06 09:16:46 +02:00
fusion44
1f491ed0a0 feat: implement (un)install celery task
refs #123
2025-05-06 09:16:46 +02:00
fusion44
de1594f7e4 refactor: nicer layout for app status cache code 2025-05-06 09:16:46 +02:00
fusion44
6bd875f16b refactor: move app update code into its own file 2025-05-06 09:16:46 +02:00
fusion44
824fa62c4d chore: small fixes and updates
- formatting
- small fix in a bitcoind model
- update the fake blitz scripts
- remove some dead code (app status sub)
2025-05-06 09:16:46 +02:00
fusion44
4e038e8fc7 feat: fetch app status via a celery task
This is a feature that allows to fetch the app status via a celery
task which stores the result in the Redis database and notifies the API
of the change. The API sends a notification to connected clients via the
SSE mechanism.

Using a background task allows to avoid crashing the whole API if the
script call fails.

The by default the cache is refreshed every 30 minutes. This can be
changed by setting the `BAPI_APP_STATUS_UPDATE_INTERVAL_MIN` environment
variable.

refs #123
2025-05-06 09:16:46 +02:00
fusion44
4a70d2ca36 feat: add error handling to get_redis helper func
refs #123
2025-05-06 09:16:46 +02:00
fusion44
2b98912796 feat: replace call_script func with better func
use exec_bash_command instead

refs #123
2025-05-06 09:16:46 +02:00
fusion44
e1f87a3e8b feat: update fake blitz environment 2025-05-06 09:16:46 +02:00
fusion44
751687e60b chore: run ruff format and isort 2025-05-06 09:16:46 +02:00
fusion44
e5ba965818 feat: update test script to include fake_blitz env 2025-05-06 09:16:46 +02:00
fusion44
8ee5a49892 feat: update get app status error handling code
refs #123
2025-05-06 09:16:46 +02:00
fusion44
691d5da6b9 feat: update formatting of errors sent to clients
refs #123
2025-05-06 09:16:46 +02:00
fusion44
ef9bfbefe4 feat: add supporting types for error handling
- add a result type similar to the Rust Result type from
https://github.com/rustedpy/result
- add a Report class to propagate error information back on the stack
with return types instead of exceptions

refs #123
2025-05-06 09:16:46 +02:00
fusion44
8b372ecb47 feat: make typos available to the devenv 2025-05-06 09:16:46 +02:00
dependabot[bot]
b4e9112b1f chore(deps): bump h11 from 0.14.0 to 0.16.0
Bumps [h11](https://github.com/python-hyper/h11) from 0.14.0 to 0.16.0.
- [Commits](https://github.com/python-hyper/h11/compare/v0.14.0...v0.16.0)

---
updated-dependencies:
- dependency-name: h11
  dependency-version: 0.16.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-25 20:22:28 +02:00
fusion44
a341b69373
feat: add fake local raspiblitz dev environment 2025-03-23 20:36:51 +01:00
dependabot[bot]
b10ef720eb chore(deps): bump jinja2 from 3.1.4 to 3.1.6
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.6.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.6)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-23 17:47:13 +01:00
fusion44
25e4be8441 feat: make config loading more flexible
If the environment variable BAPI_ENV_PATH is set, the config system will
try to read configs from the given path instead of .env in pwd

If no file is found .env in pwd will be used as a fallback

Env variables will always override settings in .env files.
2025-03-23 17:43:39 +01:00
fusion44
76b3e5019b feat: improve devenv config 2025-03-23 17:43:39 +01:00
fusion44
b52732ead9 chore: update dependencies 2025-03-23 17:43:39 +01:00