Commit Graph

9264 Commits

Author SHA1 Message Date
SomberNight c2f3729424 plugins: timelock_recovery: move checksum func to base class
don't import qt from tests unless it is qt being tested
2026-03-16 00:41:33 +00:00
Oren 2f3f397a70 Fix checksum following BIP-128 standard
Non-Ascii characters should not be converted for
checksum calculation.
This will give consistent hash to BIP-128 and its
Javascript code example.

Timelock-Recovery Plans that contained only ascii
characters are not affected.

Also, 8 hex-chars is enough for a checksum.
2026-03-15 10:56:14 +02:00
ghost43 169227e148 Merge pull request #10509 from SomberNight/202603_lnpeer_send_commitment
lnpeer: simplify where maybe_send_commitment() is called
2026-03-11 22:20:02 +00:00
SomberNight 7e3af72ad6 lnpeer: maybe_send_commitment: impl batching updates 2026-03-11 17:07:23 +00:00
SomberNight 93f0452406 lnpeer: simplify where maybe_send_commitment() is called
The typical flow of an update is:
---UPDATE--->
--- SIG  --->
<--REVACK----
<-- SIG  ----
---REVACK--->

It makes sense to try to send a sig ("commitment_signed") right after we send an update.
It also makes sense right after we send revack.

Besides those times, we could call "maybe_send_commitment" at *any* time, that is safe, and depending on other call locations, it might be an optimisation, however it is not needed.

In particular it is unclear why we had those calls when we *receive* updates (and only for certain types of updates - not consistently).
2026-03-11 17:07:19 +00:00
Jochen Hoenicke e31ce7dce6 Update my Electrum server details in servers.json
I moved my node to standard port again because the non-standard one was apparently used by malware.  I also updated the domain name (both work at the moment, but I prefer the shorter one).
2026-03-10 17:58:43 +01:00
f321x d85985cdf2 qml: rbf/cancel: fix type error
self.oldfeeRate is initialized as int in `QETxRbfFeeBumper` and
`QETxCanceller`. However QML expects it to be a string. Initializing
it as string fixes the exception. Previously this didn't happen as
`Abstract_Wallet.add_info_from_wallet_and_network()` would never
return False, so the `get_tx()` method would immediately overwrite
the self.oldfeeRate variable with a string.

```
 20.95 | D | gui.qml.qetxfinalizer | TxMonMixin.__init__
 20.95 | E | gui.qml.qeapp.Exception_Hook | exception caught by crash reporter
TypeError: unable to convert a Python 'int' object to a C++ 'QString' instance
```
2026-03-09 14:39:40 +01:00
f321x 3d13d478c9 qml: rbf/cancel: abort update if adding tx info fails
Early return the update() methods of QETxRbfFeeBumper and QETxCanceller
if it fails to fetch missing tx information from the Network to prevent
an exception in `Abstract_Wallet.bump_fee()` and
`Abstract_Wallet.dscancel()`. See
https://github.com/spesmilo/electrum/issues/5502#issuecomment-40213084270
2026-03-09 14:19:36 +01:00
f321x e8eee065a5 transaction: re-raise NetworkException in add_info_from_network
`Transaction.add_info_from_network` would swallow a `NetworkException`
even when `ignore_network_issues=False` is passed.
This causes `Transaction.add_info_from_wallet_and_network` to
incorrectly return True even if the operation failed.
If `QETxRbfFeeBumper` then incorrectly proceeds assuming the call was
successful `Abstract_Wallet.bump_fee()` would raise an `Exception("tx
missing info from network")`.
Should fix the traceback in
https://github.com/spesmilo/electrum/issues/5502#issuecomment-4021308427.
2026-03-09 13:45:19 +01:00
f321x f64923b472 plugin: nwc: lookup_invoice: fix exc, include b11
Fixes exception in lookup_invoice:
```
 62.69 | E | plugins.nwc.nwcserver.NWCServer | Error handling nwc request
Traceback (most recent call last):
  File "/home/user/code/vibecoding_vm/electrum/electrum/plugins/nwc/nwcserver.py", line 381, in run_request_task
    await task
  File "/home/user/code/vibecoding_vm/electrum/electrum/util.py", line 1211, in wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/code/vibecoding_vm/electrum/electrum/plugins/nwc/nwcserver.py", line 526, in handle_lookup_invoice
    info = self.wallet.lnworker.get_payment_info(invoice.payment_hash, direction=RECEIVED)
                                                 ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Invoice' object has no attribute 'payment_hash'
```

Always includes bolt11 invoice in response, even if the client already
sent it to us in the request. It doesn't seem useful and is marked
optional in the spec but https://sandbox.albylabs.com considers the
response invalid if the invoice is not included.
2026-03-06 14:42:42 +01:00
f321x f53203d171 plugin: nwc: consider inflight htlcs in get_payment_info
Also consider htlcs that are still inflight when calculating
the amount/fee of a payment to prevent calculating an incorrect
payment value/fee when calling get_payment_info directly after
a payment succeeds (one htlc settled, but others could still be
inflight).
This assumes that once a payments htlc got settled all other inflight
htlcs will also get settled.
2026-03-06 12:09:07 +01:00
f321x 9b4d4d61bb plugin: nwc: add update timer to connection list 2026-03-06 12:09:05 +01:00
f321x 8ccdc3f7af plugin: nwc: consider routing fees for payment budget
Include the lightning routing fees into the payment budget accounting
to prevent untrusted nwc clients from exceeding the budget by crafting
a high fee route.
2026-03-06 12:09:03 +01:00
f321x 8dddb5d538 plugin: nwc: unify budget_allows_spend and add_to_budget
There is now only add_to_budget which will return None if the budget
doesn't allow for this spend. It will always add the spend to the
budget, even if the user has no budget so it can be used for display
purposes (and simpler code, only one path).
2026-03-06 12:08:58 +01:00
ghost43 fd52b97046 Merge pull request #10505 from f321x/nwc_improvement
plugins: nwc: sync with spec, fix some bugs
2026-03-03 17:56:14 +00:00
ghost43 cb696ed6f8 Merge pull request #10504 from accumulator/move_qt_event_listener
common_qt: move QtEventListener and qt_event_listener decorator to common_qt
2026-03-03 17:48:01 +00:00
ghost43 0cb4e89aee Merge pull request #10503 from accumulator/qt_coins_fully_spend_menu
qt: utxo_list: only enable 'fully spend...' menu if there are unfrozen coins in the selection.
2026-03-03 17:37:58 +00:00
SomberNight 4c27b8de8d qt: utxo_list: add asserts to helper methods that coins are selected
- otherwise they default to selecting all coins, which is unlikely to be what the user intends
- prev commit makes sure this should never happen
2026-03-03 17:29:22 +00:00
f321x 835ab39d77 plugin: nwc: bump version to 0.0.2
these changes deserve a new version
2026-03-03 18:04:54 +01:00
f321x ea1e2c8240 plugin: nwc: add 'state' field to responses
NIP-47 got extended to include an optional 'state' field in responses.
Implementing this acutally fixes an issue of Alby Go showing succeeded
payments as failed that appeared recently.
2026-03-03 18:04:52 +01:00
f321x 5222374046 plugin: nwc: improved budget accounting
Increase the payment budget before attempting the payment
and decrease again if the payment fails. This prevents a race
where multiple concurrent payments could pass the budget check
before the budget is incremented through any of the other payments.

A lock around the budget is not suitable either as then one long
stuck payment (hold invoice) would render the budget inaccessible for
all other payment attempts.
2026-03-03 18:04:51 +01:00
f321x 3956bff068 plugin: nwc: do budget accounting in msat
Keep track of the spent amount in msat instead of sat to prevent
issues due to rounding.
The budget is still specified in sat.
2026-03-03 18:04:47 +01:00
f321x 423cc678c8 qt: MyTreeView: close menu if its context changes
Stores the currently open (right-click) menu in MyTreeView
and adds a `close_menu()` method so inheritants can cleanly
close the menu again if the context it was opened upon has changed.

This is utilized by `AddressList` and `UTXOList` to close the menu
if a call to `update()` has chenged the address list in some way or
removed a utxo from the list to prevent the user from trying to use
a utxo that doesn't exist anymore.

Fixes #10464
2026-03-03 17:28:57 +01:00
Sander van Grieken 91efb3e1f4 common_qt: move QtEventListener and qt_event_listener decorator to common_qt 2026-03-03 13:03:46 +01:00
f321x 0dc08fdf24 plugin: nwc: handle encryption scheme signaling
NIP-47 now defines how client/server should communicate their supported
encryption schemes. For backwards compatibility its not strictly
neccessary to implement this but it seems cleaner to explicitly handle
it.
2026-03-03 11:27:09 +01:00
f321x 4c703ea278 plugin: nwc: remove multi_pay_invoice rpc
It got removed from the spec so we don't need to support it anymore.
https://github.com/nostr-protocol/nips/pull/2210
2026-03-03 11:22:07 +01:00
SomberNight fe5cb09e05 wallet_db: convert PaymentInfo amounts from 0 to None
When creating a "zero-amount" payment request, currently we save a PaymentInfo with a "None" amount.
I think there were a few releases in 2023 that saved PaymentInfos with a `0` amount instead. This was changed in #8659 [0], but as said there [1], a DB upgrade was not done.
Now an assert added in [2] is failing due to this inconsistency, for affected old wallets.
- I think to trigger that, one needs a wallet that has a payment request (with a `0` amount) created around that time, which is still unpaid.

This patch tries to restore consistency by enforcing None amounts.

fixes https://github.com/spesmilo/electrum/issues/10501

[0]: https://github.com/spesmilo/electrum/pull/8659
[1]: https://github.com/spesmilo/electrum/pull/8659#issuecomment-1777101285
[2]: https://github.com/spesmilo/electrum/commit/286fc4b86e4d23cb9af15b9061b3d709e7592bcb
2026-03-02 17:12:07 +00:00
Sander van Grieken f3ba25df7d qt: utxo_list: only enable 'fully spend...' menu if there are unfrozen coins in the selection.
otherwise, when selecting only frozen coins, the set of usable coins is empty, and the menu options
will instead fall back to using ALL coins without informing the user.
2026-03-02 18:04:08 +01:00
f321x c4dcd85afc txbatcher: don't spend anchors if ctx fee is sufficient
If the tx fee of the ctx is already higher than the required target it
is not useful to spend the anchor with a lower fee (the current target),
so instead it is skipped.
2026-02-27 17:17:53 +01:00
SomberNight d72b741173 update block header checkpoints 2026-02-26 17:49:31 +00:00
f321x eee2e85826 bump version to 4.7.1 2026-02-26 18:06:31 +01:00
SomberNight d733350ac5 lnwatcher: ~document behaviour re subbing to historical chans and swaps
not so intuitive

ref https://github.com/spesmilo/electrum/pull/7852 ("Persist lnwatcher")
2026-02-25 18:48:04 +00:00
ghost43 2c9f4fdbae Merge pull request #10433 from f321x/qt_changelog
qt: add Changelog to Help menu in toolbar
2026-02-25 17:26:06 +00:00
ghost43 9a41a5472a Merge pull request #10442 from SomberNight/202601_lnworker_is_preimage_public
lnsweep: simplify maybe_reveal_preimage_for_htlc
2026-02-25 15:35:20 +00:00
SomberNight 10274c1cd7 simplify prev 2026-02-24 17:57:58 +00:00
SomberNight 0b2c7a8a38 lnsweep: safer maybe_reveal_preimage_for_htlc, add "is_preimage_public"
"When should we reveal preimages onchain?"
This commit tries to simplify the thinking by making the observation:
- we can reveal preimages (actually in any context) if they are already public
- a preimage is public if any other lightning node knows it besides us
  - if we learn the preimage from another LN node, it is public
  - if we send update_fulfill_htlc, it becomes public
  - if we see a preimage onchain, it is public

- in lnsweep._maybe_reveal_preimage_for_htlc:
  - partial mpp check is not relevant if preimage is already public
  - let's just always do KeepWatchingTXO, for sanity/safety

Co-authored-by: ThomasV <thomasv@electrum.org>
2026-02-24 17:49:15 +00:00
ThomasV 6feb992712 Merge pull request #10453 from f321x/debug_rbf_fee_calculation
wallet: estimate base tx feerate based on original base tx size
2026-02-24 16:45:07 +01:00
f321x 3133148acd transaction: extend estimated_size() docstring
Extends the docstring of Transaction.estimated_size().

Co-Authored-By: SomberNight <somber.night@protonmail.com>
2026-02-24 14:37:06 +01:00
f321x e9ac3e93d7 transaction: use dummy DER ECDSA sig from descriptor.py
We have two different dummy der signatures of varying size,
this unifies them to use a single one from descriptor.py.
2026-02-24 14:37:04 +01:00
f321x a9f20e4d3d wallet: rbf: estimate base tx size before stripping
Estimate the size of a base tx before stripping its signatures
so the lower bound feerate used to calculate the fee for the rbf
transaction doesn't underestimate the feerate of the base tx.
2026-02-24 14:36:50 +01:00
ghost43 8427a11a5f Merge pull request #10493 from f321x/gossip_fix_save_remote_update
lnpeer: don't try saving our own channel update as remote update
2026-02-23 16:35:13 +00:00
f321x 2df68d9249 qt: console: allow changing font size
Allows changing the font size in the qt Console with
`Ctrl` + `+` and `Ctrl` + `-`.
2026-02-23 17:27:39 +01:00
f321x ddb01f5355 lnpeer: don't save our own channel update as remote upd
I noticed CLN is sending our own channel update to us on
reestablishment, we then assume it to be the remote nodes
update and try to verify the signature against their pubkey
which fails and throws `InvalidGossipMsg`.

This adds a check preventing us from trying to save our own
channel updates as remote update.
2026-02-23 17:12:15 +01:00
SomberNight 4d2ea4f22c update locale
This includes https://github.com/spesmilo/electrum-locale/pull/54,
which adds the new "X-Electrum-SourceStringCount" header into the .po/.mo files.
2026-02-21 03:51:52 +00:00
SomberNight 3afa2fcdf3 locale: gui: show translation completion percentage in language names
In the GUIs, on the language-select screen, show e.g.
  Czech (100%), Danish (13%), Dutch (54%)
instead of
  Czech, Danish, Dutch

- we count the source strings when creating the .pot PO-template file
  and add an "X-Electrum-SourceStringCount" header to it, in the push_locale.py script that uploads the .pot file to crowdin.
  - later, when we run electrum-locale/update.py to download the translations in .po files, these files will also contain the same header.
  - then when the build_locale.sh script compiles those .po files, we can read the header and use it to populate a new "stats.json" file
    that we place in electrum/locale/locale/ and bundle in the all release binaries/distributables.
    - stats.json also includes the number of translated strings for each lang
- at runtime we simply read stats.json and use the values to calculate the percentages
  - a prior implementation did not pre-calc stats.json but did all calculations at runtime (by opening all .mo translations)
    - however that was deemed to slow, hence the build-time pre-calc
      - runtime calc took 40 ms on my laptop, so I guess it could easily take 10x that on an old phone
- just as we have always been very tolerant of any locale files or even the whole locale/ dir missing, we also tolerate stats.json missing
2026-02-21 03:40:09 +00:00
f321x a1f1b39368 wallet_db: assert WalletDBUpgrader.storage is dict
Assert `WalletDBUpgrader.data` is a regular in-memory dict and not
some StoredDict, so if an exception would happen during a wallet
db upgrade the partial changes don't get commited to disk.
2026-02-20 16:06:42 +01:00
f321x 73a03249df wallet_db: handle non-existing parent_set_key in v65
Handles non-existing parent_set_key in _convert_version_65.

Fixes #10487
2026-02-20 13:58:51 +01:00
SomberNight cf25990973 locale: don't translate string "Electrum", "BIP39" 2026-02-19 16:13:44 +00:00
Sander van Grieken b10b14c2f8 qml: ReceiveDetailsDialog use proper ButtonContainer 2026-02-19 17:12:17 +01:00
ThomasV 0c32bde721 Merge pull request #10480 from f321x/fix_exc_offline_mode
qt: fix toolbar action exc in offline mode
2026-02-18 17:41:23 +01:00