Commit Graph

424 Commits

Author SHA1 Message Date
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
ThomasV 253b0989b8 cli: rename clearconfig -> unsetconfig 2025-06-12 19:56:14 +02:00
SomberNight 47e76b25b1 swaps: add some type hints, and force kwargs 2025-06-10 16:20:43 +00:00
f321x 37181cd3a8 disable qt swap fee slider on reverse swaps, change eta
disables the fee slider in the swap dialog for reverse swaps as the tx
fee for claiming is not configurable by the user. Also replaces calls to
`sm.get_swap_tx_fee()` with `sm.get_fee_for_txbatcher()` as this is the
correct fee estimate for claim transactions, instead of the config fee
eta used by `get_swap_tx_fee()`.
2025-06-09 17:36:38 +02:00
ThomasV 85c3c77096 CLI: make 'wallet_path' relative to wallets dir
If the wallet_path passed to the RPC is a simple filename,
interpret it as relative to the user wallets directory,
rather than to the current working directory.

This is a breaking change, it might affect existing scripts
2025-06-05 09:06:29 +02:00
ThomasV 37914d5af0 cmdline: use 'wallet_path' argument to pass wallet_path 2025-06-05 09:06:29 +02:00
ThomasV 2024fa4507 Merge pull request #9902 from SomberNight/202506_base64_trailing_garbage
base64.b64decode: always set validate=True
2025-06-04 14:59:20 +02:00
ThomasV 69545f08ca list_wallets: fix wallet path (follow-up 902ec09791) 2025-06-04 10:46:45 +02:00
SomberNight 3e4601c61d base64.b64decode: always set validate=True
Notably verifymessage and decrypt(message) were silently ignoring trailing garbage
or inserted non-base64 characters present in signatures/ciphertext.
(both the CLI commands and in the GUI)
I think it is much cleaner and preferable to treat such signatures/ciphertext as invalid.

In fact I find it surprising that base64.b64decode(validate=False) is the default.
Perhaps we should create a helper function for it that set validate=True and use that.
2025-06-03 18:58:05 +00:00
Sander van Grieken 6f653af3ff whitespace, imports 2025-06-03 11:26:23 +02:00