Decoding a malformed or wrong-network invoice (e.g. a regtest lnbcrt...
invoice on a mainnet node) made each backend fail with a cryptic,
leaked error: LND with the Go 'strconv.ParseUint: parsing "rt500":
invalid syntax' surfaced as a 500, and CLN with 'Invalid bolt11: ...'.
Add a shared helper raise_for_pay_req_decode_error() in lightning/utils
that recognizes the decode-failure signatures of both backends and
raises one clear 400 pointing at the likely cause (malformed or wrong
network). Wire LND (lnd_grpc), CLN gRPC and CLN JSON-RPC through it so
they behave identically; genuine backend errors still return 500.
Fixes#225
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
While LND is up but its RPC server is 'in the process of starting up, but
not yet ready to accept calls', every LND method returned a bare 500 -
the caller (e.g. the WebUI polling list-all-tx) got a generic server
error with no useful signal.
_check_if_locked only mapped the 'wallet locked' case; generalize it to
_check_transient_ln_error and also map the startup message to
425 TOO_EARLY (matching how bitcoind warmup is reported), with a clear
'try again shortly' detail. This covers all LND methods that share the
same error-handling path.
Fixes#247
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
get_event_loop() is deprecated on Python 3.11+ when there is no running
loop and is slated to change behaviour further.
- SSEManager.setup() ran at import time (app.api.utils) via
get_event_loop(); this only worked because uvicorn imports the app
inside its loop and would break when imported without a running loop
(e.g. a Celery worker). Start the broadcast consumer lazily from
within a running loop instead.
- everywhere else the pattern was get_event_loop().create_task(x)
inside a coroutine; replace with asyncio.create_task(x).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the deprecated Pydantic v1 @validator('amount', pre=True,
always=True) with a v2 @model_validator(mode='after'). The model
validator always runs and can see both amount and send_all, preserving
the cross-field rule (and the always=True semantics that reject the
empty/default case). Removes the last Pydantic v1 deprecation warning.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two bugs in the CLN JSON-RPC list_all_tx:
- 'if pay is not Payment' compared each item to the Payment class rather
than its type, so it was always true and every payment was skipped -
payments never showed up in the transaction list.
- the successful_only filter appended the item inside the match branch
and then again unconditionally, so it never filtered anything.
Use isinstance for the type check and skip non-matching items when
successful_only is set. Also guard the source lists against None so a
failed sub-query no longer crashes the loop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two authenticated code paths interpolated user-controlled input into a
shell command:
- decode_pay_request passed the bolt11 string into _make_local_call,
which ran it via create_subprocess_shell; a crafted /lightning/
decode-pay-req request could execute arbitrary commands. Switch
_make_local_call to create_subprocess_exec with a discrete argv list.
- blitz_cln_unlock interpolated the wallet password into a
cl.hsmtool.sh invocation run through a shell, and logged it in the
clear. shlex.quote the interpolated values and mark the call
sensitive=True.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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.
Implementations sometimes don't find aliases in the gossip, even if
they are openeing a channel to the pubkey. In this case an empty
string will be returned and the problem logged in debug mode.
refs #199
both:
feat: add send_all field to SendCoinsResponse
CLN_gRPC only:
feat: improve error handling
fix: return a status 412 when no funds are available to send
CLN_gRPC only:
fix: send-coins sending incorrect amount
- fix: Crash in send-coins incorrectly assigning a value to a variable
- improvement: Robustness of the init code. Better detect a invalid
RPC file path
- CLN-JRPC: short_channel_id is not available while a channel is
confirming => return an empty string
- CLN-GRPC: don't send all=False with the amount flag when opening a
channel as it'll lead to an erro
- CLN-GRPC: don't utf8-decode the open-channel result
CLN returns no error when a payment was already completed before.
This commit adds a check to the payment status before attempting to
complete the payment. If the payment was already completed, the API
returns an exception.