Commit Graph

433 Commits

Author SHA1 Message Date
SomberNight 3399c20ad6 commands: export_lightning_preimage: add comment about wallet password 2026-04-28 15:16:42 +00:00
ThomasV 06e9f2b5e3 Merge pull request #10534 from SomberNight/202603_rpc_password_not_empty
daemon: forbid "setconfig" command to change rpcserver settings in-flight
2026-03-25 08:35:52 +01:00
SomberNight 0dcef9780b daemon: forbid "setconfig" command to change rpcserver settings in-flight
It is much easier to reason about the rpcserver if we don't allow changing its basic settings while it is already running. What does it mean to change the TCP port it is listening on ("rpcport") if it's already running? It is even problematic to change the rpcpassword: care needs to be taken to already update it for the current server.
(ref https://github.com/spesmilo/electrum/issues/6762)

This commit disallows changing all of the "rpc*" config variables if the daemon is already running.

---

Simultaneously, it also ensures rpc_password is always set and auth cannot be disabled.

Previously if there was a daemon running, and the user ran
`$ electrum setconfig rpcpassword ""` that would leave the RPC unauthenticated
for the current session. However next time the daemon restarted, get_rpc_credentials would see
the unset password and generate one.

I think this was the worst of both worlds:
- we did not really allow removing the rpc password, except for the current session, and
- perhaps unexpectedly, we would generate a new password on daemon restart

Instead now we explicitly make sure the RPC server can never get into a state where it does not have a password set.

Based on a report by `Zuzana Kotásková <36777@mail.vsfs.cz>`
2026-03-24 17:07:26 +00:00
SomberNight 42ad18b216 rm bip70 support
- could not find a single project that still actually cares about bip70 [0]
    - well except maybe BitPay.
        - but I cannot test with BitPay:
            - they have a testnet3 staging environment on test.bitpay.com
                - but the SSL cert they use for bip70 has expired in 2021
                - the webUI probably also has not been updated since then...
                    - they claim to have added LN support in 2022 in a blog post,
                        but it's not there on test.bitpay.com
            - on mainnet, they require KYC before payment
                - < ... angry noises >
            - their loss then, I don't care.
- this is code that no one wants to maintain

- this does not yet delete the signed bip70 payment data for historical txs
    - but it is no longer possible to export it from the GUI

[0]: https://bitcoinops.org/en/topics/bip70-payment-protocol/
2026-03-20 18:12:55 +00:00
ThomasV 4680369599 add more options to list_channels 2026-03-19 11:29:43 +01:00
f321x f56e6318e3 swaps: make SwapManager.percentage Decimal
If SwapManager.percentage was a 0.2 float, rounding differences would
cause an exception in the fee calculation inverse sanity check when entering 20
000 sats into the SwapDialog. By making self.percentage a decimal we can
prevent this kind of issue.

```
File "/home/user/code/vibecoding_vm/electrum/electrum/gui/qt/swap_dialog.py", line 294, in on_send_edited
    recv_amount = self.swap_manager.get_recv_amount(send_amount, is_reverse=self.is_reverse)
  File "/home/user/code/vibecoding_vm/electrum/electrum/submarine_swaps.py", line 1320, in get_recv_amount
    if abs(send_amount - inverted_send_amount) > 1:
           ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
```
2026-03-19 09:17:34 +01:00
ThomasV 7e73aa7b7a CLI: separate list_channels and list_channel_backups
Add '--public' option flag to list public channels
2026-02-09 11:39:54 +01:00
SomberNight 21248817c9 config: allow setting "forgetconfig" option in file, not just on CLI
- by specifying "default=<VALUE>" in commands.py, <VALUE> would always overwrite what is in the config file
- note `$ ./run_electrum -o setconfig forget_config true` still does not work,
  as that first sets forget_config in memory, and then - by virtue of the setting -
  it refuses to write changes to the config file
  - hence this option would have to be set manually by editing the json
    (or as a CLI flag, as before)

ref https://github.com/spesmilo/electrum/pull/10421#issuecomment-3765862081
2026-01-19 11:30:53 +00:00
SomberNight 1006e8092f lnworker: split LNWallet and LNWorker: LNWallet "has an" LNWorker
- LNWallet no longer "is-an" LNWorker, instead LNWallet "has-an" LNWorker
- the motivation is to make the unit tests nicer, and allow writing unit tests for more things
  - I hope this makes it possible to e.g. test lnsweep in the unit tests
  - some stuff we would previously have to write a regtest for, maybe we can write a unit test for, now
- in unit tests, MockLNWallet now
  - inherits LNWallet
  - the Wallet is no longer being mocked
2026-01-05 15:55:31 +00:00
ghost43 f8fc2b63e3 Merge pull request #10271 from f321x/fix_save_payment_info
lightning: fix self payments (e.g. rebalance)
2025-12-05 17:19:39 +00:00
SomberNight cdcac8cb09 openalias: always enforce DNSSEC validation succeeds 2025-12-05 17:06:41 +00:00
f321x 923d48f9db lnworker: differentiate PaymentInfo by direction
Allows storing two different payment info of the same payment hash by
including the direction into the db key.
We create and store PaymentInfo for sending attempts and for requests (receiving),
if we try to pay ourself (e.g. through a channel rebalance) the checks
in `save_payment_info` would prevent this and throw an exception.
By storing the PaymentInfos of outgoing and incoming payments separately in
the db this collision is avoided and it makes it easier to reason about
which PaymentInfo belongs where.
2025-12-01 18:39:56 +01:00
SomberNight 828fc569c9 commands: version_info: include openssl version 2025-11-30 06:03:08 +00:00
f321x abc469c846 lnworker: split dont_settle_htlcs
Splits `LNWallet.dont_settle_htlcs` into `LNWallet.dont_settle_htlcs`
and `LNWallet.dont_expire_htlcs`.

Registering a payment hash in dont_settle_htlcs will prevent it from
getting fulfilled if we have the preimage stored. The preimage will not
be released before the the payment hash gets removed from
dont_settle_htlcs. Htlcs can still get expired as usual or failed if no
preimage is known.
This is only used by Just-in-time channel openings.

Registering a payment hash in dont_expire_htlcs allows to overwrite the
minimum final cltv delta value after which htlcs would usually get
expired. This allows to delay expiry of htlcs or, if the value in the
dont_settle_htlcs dict is None, completely prevent expiry and let the
htlc get expired onchain.

Splitting this up in two different dicts makes it more explicit and
easier to reason about what they are actually doing.

 Please enter the commit message for your changes. Lines starting
2025-11-27 17:58:44 +01:00
f321x 0f314d1dd9 lnpeer/lnworker: refactor htlc_switch
refactor `htlc_switch` to new architecture to make it more robust
against partial settlement of htlc sets and increase maintainability.
Htlcs are now processed in two steps, first the htlcs are collected into
sets from the channels, and potentially failed on their own already.
Then a second loop iterates over the htlc sets and finalizes only on
whole sets.

# Conflicts:
#	electrum/lnpeer.py
2025-11-27 17:57:14 +01:00
f321x 114c48e452 cli: payto: fix feerate parsing
Feerate is passed to `Commands._get_fee_policy()` as str which then
tried to multiply the string by 1000. Now it first casts the string to
`Decimal` and multiplies the decimal.

Fixes https://github.com/spesmilo/electrum/issues/10315
2025-11-19 17:38:58 +01:00
Sander van Grieken 7bfe2dd5f6 commands: print warnings to stderr so output is still valid json 2025-11-05 14:37:34 +01:00
f321x 76f69676d3 config/regtest: add config to disable automatic fee updates
Some regtest tests depend on manual fee injection to simulate certain
mempool conditions (e.g. lnwatcher_waits_until_fees_go_down). This is
done by manually injecting fee estimates into the `Network` object using
the `test_inject_fee_etas` cli command. However it can still happen that
the Network automatically updates its fee estimates from the connected
electrum server in the time between injecting the fee and the actual
tested logic making decisions based on the fee. This causes the test to
fail sometimes.
By setting the `test_disable_automatic_fee_eta_update` true the Network
will stop automatically updating the fee estimates and the test will
behave as expected.
2025-10-31 14:50:26 +01:00
f321x 95ba7e7547 cli: add_peer: make add_peer wait for connection
peer initialization was never awaited in the `add_peer` method.
This awaits the initialization of the peer so that the caller
actually knows if connection succeeded or timed out.
2025-10-28 17:07:57 +01:00
ghost43 89734b3bd4 Merge pull request #10242 from f321x/return_preimage_cli
cli: add command to export preimage, return preimage from check_hold_invoice
2025-10-09 15:31:04 +00:00
f321x b57f867c2f cli: add command to export preimage
..also export preimage in check_hold_invoice return value if available.

I intentionally did not return the preimage in the returned dict of
wallet.export_requests as this seems risky to do considering some users
of the cli might forward the response to a payer and the payserver
exposes it too.

Closes https://github.com/spesmilo/electrum/issues/10176
2025-09-30 10:37:20 +02:00
f321x 286fc4b86e lnworker: enforce creation of PaymentInfo for b11
Enforce that the information used to create a bolt11 invoice using
`get_bolt11_invoice()` is similar to the related instance of PaymentInfo
by requiring a PaymentInfo as argument for `get_bolt11_invoice()`.
This way the invoice cannot differ from the created PaymentInfo.
This allows to use the information in PaymentInfo for validation of
incoming htlcs more reliably.

To cover all required information for the creation of a b11 invoice the
PaymentInfo class has to be extended with a expiry and
min_final_cltv_expiry. This requires a db upgrade.
2025-09-30 09:54:35 +02:00
f321x 32aa6ab20c lnutil: rename RecvMPPResolution.ACCEPTED
Renames RecvMPPResolution.ACCEPTED to .COMPLETE as .ACCEPTED is somewhat
misleading. Accepted could imply that the preimage for this set has been
revealed or that the set has been settled, however it only means that we
have received the full set (it is complete), but the set still can be
failed (e.g. through cltv timeout) and has not been claimed yet.
2025-09-29 16:11:26 +00:00
SomberNight b944371ffd adb: change API of util.TxMinedInfo: height() is now always SPV-ed 2025-09-24 13:46:24 +00:00
SomberNight 7455cf9dec commands: add clear error that plugin commands cannot be run with -o
note that atm none of the plugin commands are explicitly marked with 'n' but all require it.
Also note that 'w' for plugin commands kind of implies 'n' anyway, as the 'load_wallet' hook relies on having a daemon.

```
$ ./run_electrum -o --testnet labels_pull
Password:
  1.96 | E | __main__ | error running command (without daemon)
Traceback (most recent call last):
  File "/home/user/wspace/electrum/./run_electrum", line 587, in handle_cmd
    result = fut.result()
  File "/usr/lib/python3.13/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/usr/lib/python3.13/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/home/user/wspace/electrum/./run_electrum", line 267, in run_offline_command
    result = await func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/commands.py", line 202, in func_wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/commands.py", line 2214, in func_wrapper
    kwargs['plugin'] = daemon._plugins.get_plugin(plugin_name)
                       ^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_plugins'
```
2025-09-05 18:26:24 +00:00
f321x e7bb75bc3e chore: replace calls to asyncio.iscoroutinefunction
Replace calls to deprecated asyncio.iscoroutinefunction with calls to
inspect.iscoroutinefunction to prevent the following deprecation
warnings from showing up if running with Python 3.14:
```
/home/user/code/electrum-fork/electrum/util.py:1225: DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16; use inspect.iscoroutinefunction() instead
  assert asyncio.iscoroutinefunction(func), 'func needs to be a coroutine'
/home/user/code/electrum-fork/electrum/util.py:507: DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16; use inspect.iscoroutinefunction() instead
  if asyncio.iscoroutinefunction(func):
/home/user/code/electrum-fork/electrum/util.py:1246: DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16; use inspect.iscoroutinefunction() instead
  assert asyncio.iscoroutinefunction(func), 'func needs to be a coroutine'
/home/user/code/electrum-fork/electrum/lnpeer.py:272: DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16; use inspect.iscoroutinefunction() instead
  assert asyncio.iscoroutinefunction(func), 'func needs to be a coroutine'
/home/user/code/electrum-fork/electrum/util.py:1225: DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16; use inspect.iscoroutinefunction() instead
  assert asyncio.iscoroutinefunction(func), 'func needs to be a coroutine'
/home/user/code/electrum-fork/electrum/util.py:507: DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16; use inspect.iscoroutinefunction() instead
  if asyncio.iscoroutinefunction(func):
```
2025-09-05 10:29:34 +02:00
SomberNight 8d8d1dba0f util.format_satoshis: floating-point paranoia 2025-08-22 13:30:26 +00:00
ThomasV 0949d9755c Merge pull request #10165 from spesmilo/swaps_prepayment
reverse swaps: in the CLI, replace 'server_mining_fee' with
2025-08-22 10:37:53 +02:00
ThomasV 864932c79a reverse swaps: in the CLI, replace 'server_mining_fee' with
'prepayment', which corresponds to the trusted part of the
lightning payment.

We use 2*sm.mining_fee, where 'mining_fee' is the flat part of
the server fee. However, future protocol should probably allow
to set a value that does not depend on 'mining_fee'.
(note that LND uses a hardcoded amount).
2025-08-21 19:47:00 +02:00
SomberNight 74cd2b4ac3 commands: use format_satoshis consistently. don't use sci-notation
old behaviour:
```
>>> from electrum.commands import format_satoshis
>>> format_satoshis(1)
'1E-8'
```
2025-08-21 17:38:27 +00:00
f321x 5bb9b71bae commands: add command to fetch nostr swap providers 2025-08-21 14:23:20 +02:00
SomberNight 2f1e373077 commands: reverse_swap: don't require provider_mining_fee in dryrun 2025-08-20 16:20:52 +00:00
f321x 71c71a96f3 swaps: add sanity check to reverse swap mining fee 2025-08-20 17:57:36 +02:00
SomberNight d7c76b991b commands: add back from_height/to_height params to onchain_history
closes https://github.com/spesmilo/electrum/issues/10119

also:
- wallet.get_onchain_history was broken with from_height/to_height args
- "show_fees" param is and was non-existent. fees are always added to output
- MyEncoder(json.JSONEncoder) changed a bit:
  - I am pretty sure cutting the last 3 chars was intended to cut off the seconds
  - however that was making incorrect assumptions about what datetime.isoformat() returns
    - which depends on whether microsecond precision is available or whether an explicit timezone is set
  - this now makes it clear that we want minutes-resolution, but still leaves the timezone-ambiguity
2025-08-13 15:09:04 +00:00
ghost43 4684cdbd17 Merge pull request #10067 from f321x/max_cltv_lnpay
cli: add max_cltv, max_fee_msat parameters to lnpay
2025-08-01 15:14:44 +00:00
SomberNight 6ddc975a94 follow-up prev: clean-up PaymentFeeBudget API 2025-08-01 15:06:33 +00:00
ghost43 c23cc29caa Merge pull request #10082 from f321x/check_hold_invoice_show_htlc_cltv
cli: return closest htlc expiry from check_hold_invoice
2025-08-01 14:29:24 +00:00
f321x 23fa50df88 cli: add max_cltv and max_fee_msat parameter to lnpay
Adds `max_cltv` and `max_fee_msat` parameters to the `lnpay` cli command which allow to
specify the maximum total locktime of the payment and the maximum
absolute fee budget. This is enabled by
constructing a custom `PaymentFeeBudget` object in the lnpay command and
passing it as argument to `LNWallet.pay_invoice()`.
Allowing to specify a `max_cltv` value can be useful for certain
usecases, e.g. see https://github.com/spesmilo/electrum/issues/10056.

Closes #10056
2025-08-01 16:22:51 +02:00
f321x 3afca6fdfc cli: fix typos
* remove unnecessary ':' from serialize desc
* fix typo in command subparser epilog
2025-07-25 12:53:23 +02:00
f321x 9f470d1d16 cli: set formatter_class for command descriptions
Sets the [`RawDescriptionHelpFormatter`](https://docs.python.org/3/library/argparse.html#argparse.RawDescriptionHelpFormatter)
as `formatter_class` for the command parser. This makes argparse respect
the newlines in the command descriptions and showing them in the cli
with `-h` looks better by representing the same formatting as in source.

E.g. `serialize -h` before:
```
usage: run_electrum serialize [-h] jsontx

Create a signed raw transaction from a json tx template. Example value for "jsontx" arg: { "inputs": [ {"prevout_hash":
"9d221a69ca3997cbeaf5624d723e7dc5f829b1023078c177d37bdae95f37c539", "prevout_n": 1, "value_sats": 1000000, "privkey":
"p2wpkh:cVDXzzQg6RoCTfiKpe8MBvmm5d5cJc6JLuFApsFDKwWa6F5TVHpD"} ], "outputs": [ {"address": "tb1q4s8z6g5jqzllkgt8a4har94wl8tg0k9m8kv5zd", "value_sats":
990000} ] } :

positional arguments:
  jsontx      Transaction in json

options:
  -h, --help  show this help message and exit

Run 'electrum -h to see the list of global options
```

after this patch:
```
usage: run_electrum serialize [-h] jsontx

Create a signed raw transaction from a json tx template.

Example value for "jsontx" arg: {
    "inputs": [
        {"prevout_hash": "9d221a69ca3997cbeaf5624d723e7dc5f829b1023078c177d37bdae95f37c539", "prevout_n": 1,
         "value_sats": 1000000, "privkey": "p2wpkh:cVDXzzQg6RoCTfiKpe8MBvmm5d5cJc6JLuFApsFDKwWa6F5TVHpD"}
    ],
    "outputs": [
        {"address": "tb1q4s8z6g5jqzllkgt8a4har94wl8tg0k9m8kv5zd", "value_sats": 990000}
    ]
}
:

positional arguments:
  jsontx      Transaction in json

options:
  -h, --help  show this help message and exit

Run 'electrum -h to see the list of global options
```
2025-07-25 12:42:50 +02:00
f321x 6425f9bf75 cli: return closest htlc expiry from check_hold_invoice
Adds a `closest_htlc_expiry_height` value to the `check_hold_invoice` cli command response.
This allows to see the next absolute expiry height of the pending htlcs
of a payment. Note, htlcs will get failed before the actual expiry
height (if block_height + 144 > htlc.cltv_abs).
2025-07-25 11:44:26 +02:00
Felix b4de29e692 Add invoice_amount_sat to check_hold_invoice response
Adds an additional value to the `check_hold_invoice` cli command: `invoice_amount_sat` which returns the requested amount value of the hold invoice.

Co-authored-by: ghost43 <somber.night@protonmail.com>
2025-07-20 18:14:59 +02:00
f321x 8f9951ebed fix: cli: check_hold_invoice showing settled invoice as unpaid
the cli command `check_hold_invoice` incorrectly assumes that
`lnworker.is_accepted_mpp(payment_hash)` is true for settled invoices,
however it is not as the received mpp entries will be removed from
the `lnworker.received_mpp_htlcs` shortly after adding the preimage to
lnworker (after the htlcs got removed from the channel).

Also renames `amount_sat` in the `check_hold_invoice` response to
`amount_sat_received` to make it more obvious that this is the currently
received amount instead of the amount the invoice of `payment_hash` has
been created with.
2025-07-20 13:23:06 +02:00
SomberNight 75be9c6d7b commands: add test_inject_fee_etas
- the fabled return of the "inject_fees" command :D
- also make fee_estimates.has_data() smarter, to ignore extraneous targets
2025-07-08 13:35:57 +00:00
f321x 9d0a40deb9 commands: fix: only try to get wallet if wallet_path
Only try to get wallet from daemon in the `command` decorator if the
wallet_path is available to prevent raising `TypeError` when
`daemon.get_wallet(path=None)` gets called.
Fixes https://github.com/spesmilo/electrum/issues/10012
2025-07-07 11:18:07 +02:00
ghost43 96a636d578 Merge pull request #9998 from f321x/hold_invoice_cli_hash
cli: use payment hash for hold invoice creation
2025-06-30 13:42:15 +00:00
f321x 389a0a6e91 cli: use payment hash for add_hold_invoice
Allowing to create hold invoices just by providing a payment hash
instead of the preimage right from the beginning allows for additional
use cases where the recipient doesn't have access to the preimage when
creating the invoice.
2025-06-30 09:34:05 +02:00
SomberNight 0e4b3a3d58 commands: add comment about "timeout" args
really is black magic
2025-06-28 10:02:40 +00:00
SomberNight 588363749c commands: fix convert_currency cmd 2025-06-27 15:15:12 +00:00
SomberNight 84cdbc930b commands: list_channels: include "closing_txid"
want to use this in regtests
2025-06-25 17:15:55 +00:00