Commit Graph

20005 Commits

Author SHA1 Message Date
ghost43 cbaa3a8ba6 Merge pull request #10467 from f321x/fix_10464
qt: MyTreeView: close menu if its context changes
2026-03-03 16:53:45 +00: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
ThomasV 161142ddb0 Merge pull request #10502 from SomberNight/202603_lnworker_payment_infos_convert_amount
wallet_db: convert PaymentInfo amounts from 0 to None
2026-03-03 09:27:40 +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
SomberNight 31ed05c05c build: win: change from win-iconv to GNU libiconv
- (zbar requires [0] iconv)
- issues [1][3] compiling win-iconv:
    - pre-existing issue: lots of "-Wincompatible-pointer-types" warnings when compiling zbar with win-iconv
    - new debian means newer GCC
    - new GCC changed that [2] warning type to "error"
- GNU libiconv works as an alternative
    - drawback: win-iconv is more minimal, it uses the win32 API to do most of the work
    - still, is a 25+ year old GNU project with one release every ~2 years, so IMO fine

[0]: https://github.com/mchehab/zbar/blob/a549566ea11eb03622bd4458a1728ffe3f589163/README-windows.md
[1]: https://github.com/SomberNight/electrum/commit/cb00cb60cf9a0cb059dcac5e7acfe5186620cabe
[2]: https://gcc.gnu.org/pipermail/gcc-cvs/2023-December/394351.html

[3]: see snippet when compiling libzbar:
```
decoder.c: In function ‘zbar_decoder_reset’:
decoder.c:116:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  116 |     memset(dcode, 0, (long)&dcode->buf_alloc - (long)dcode);
      |                      ^
decoder.c:116:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  116 |     memset(dcode, 0, (long)&dcode->buf_alloc - (long)dcode);
      |                                                ^
  CC       processor/libzbar_la-win.lo
/bin/bash ../libtool --tag=RC   \
--mode=compile x86_64-w64-mingw32-windres -DHAVE_CONFIG_H -I. -I../include  \
-I../include  -o libzbar-rc.lo libzbar.rc
  CC       processor/libzbar_la-lock.lo
  CC       decoder/libzbar_la-qr_finder.lo
  CC       qrcode/libzbar_la-qrdec.lo
In file included from ./processor.h:26,
                 from processor/lock.c:25:
../include/config.h:423:9: warning: "_WIN32_WINNT" redefined
  423 | #define _WIN32_WINNT 0x0500
      |         ^~~~~~~~~~~~
In file included from /usr/share/mingw-w64/include/corecrt.h:10,
                 from /usr/share/mingw-w64/include/crtdefs.h:10,
                 from /usr/share/mingw-w64/include/assert.h:15,
                 from processor/lock.c:24:
/usr/share/mingw-w64/include/_mingw.h:232:9: note: this is the location of the previous definition
  232 | #define _WIN32_WINNT 0xa00
      |         ^~~~~~~~~~~~
libtool: compile:  x86_64-w64-mingw32-windres -DHAVE_CONFIG_H -I. -I../include -I../include libzbar.rc  -o .libs/libzbar-rc.o
  CC       qrcode/libzbar_la-qrdectxt.lo
  CC       qrcode/libzbar_la-rs.lo
  CC       qrcode/libzbar_la-isaac.lo
  CC       qrcode/libzbar_la-bch15_5.lo
  CC       qrcode/libzbar_la-binarize.lo
  CC       qrcode/libzbar_la-util.lo
In file included from ./image.h:26,
                 from qrcode/binarize.c:10:
../include/config.h:423:9: warning: "_WIN32_WINNT" redefined
  423 | #define _WIN32_WINNT 0x0500
      |         ^~~~~~~~~~~~
In file included from /usr/share/mingw-w64/include/corecrt.h:10,
                 from /usr/share/mingw-w64/include/crtdefs.h:10,
                 from /usr/share/mingw-w64/include/math.h:13,
                 from qrcode/binarize.c:7:
/usr/share/mingw-w64/include/_mingw.h:232:9: note: this is the location of the previous definition
  232 | #define _WIN32_WINNT 0xa00
      |         ^~~~~~~~~~~~
  CC       video/libzbar_la-dshow.lo
  CC       window/libzbar_la-win.lo
In file included from ./window.h:26,
                 from window/win.c:26:
../include/config.h:423:9: warning: "_WIN32_WINNT" redefined
  423 | #define _WIN32_WINNT 0x0500
      |         ^~~~~~~~~~~~
In file included from /usr/share/mingw-w64/include/corecrt.h:10,
                 from /usr/share/mingw-w64/include/crtdefs.h:10,
                 from /usr/share/mingw-w64/include/ctype.h:9,
                 from window/win.c:24:
/usr/share/mingw-w64/include/_mingw.h:232:9: note: this is the location of the previous definition
  232 | #define _WIN32_WINNT 0xa00
      |         ^~~~~~~~~~~~
In file included from ./processor.h:26,
                 from processor/win.c:29:
../include/config.h:423:9: warning: "_WIN32_WINNT" redefined
  423 | #define _WIN32_WINNT 0x0500
      |         ^~~~~~~~~~~~
In file included from /usr/share/mingw-w64/include/corecrt.h:10,
                 from /usr/share/mingw-w64/include/crtdefs.h:10,
                 from /usr/share/mingw-w64/include/assert.h:15,
                 from processor/win.c:24:
/usr/share/mingw-w64/include/_mingw.h:232:9: note: this is the location of the previous definition
  232 | #define _WIN32_WINNT 0xa00
      |         ^~~~~~~~~~~~
processor/win.c: In function ‘_zbar_processor_open’:
processor/win.c:282:47: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  282 |     proc->display = CreateWindowEx(EXT_STYLE, (LPCTSTR)(long)wca, "ZBar",
      |                                               ^
processor/win.c: In function ‘_zbar_processor_close’:
processor/win.c:297:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  297 |         UnregisterClass((LPCTSTR)(long)proc->state->registeredClass, 0);
      |                         ^
  CC       window/libzbar_la-dib.lo
qrcode/qrdectxt.c: In function ‘qr_code_data_list_extract_text’:
qrcode/qrdectxt.c:302:62: error: passing argument 2 of ‘iconv’ from incompatible pointer type [-Wincompatible-pointer-types]
  302 |                                               iconv(utf8_cd, &in, &inleft, &out,
      |                                                              ^~~
      |                                                              |
      |                                                              char **
In file included from qrcode/qrdectxt.c:12:
/usr/x86_64-w64-mingw32/include/iconv.h:43:56: note: expected ‘const char **’ but argument is of type ‘char **’
   43 |         size_t iconv(iconv_t cd, WINICONV_CONST char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
qrcode/qrdectxt.c:352:71: error: passing argument 2 of ‘iconv’ from incompatible pointer type [-Wincompatible-pointer-types]
  352 |                                             err = iconv(enc_list[ei], &in,
      |                                                                       ^~~
      |                                                                       |
      |                                                                       char **
/usr/x86_64-w64-mingw32/include/iconv.h:43:56: note: expected ‘const char **’ but argument is of type ‘char **’
   43 |         size_t iconv(iconv_t cd, WINICONV_CONST char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
qrcode/qrdectxt.c:374:53: error: passing argument 2 of ‘iconv’ from incompatible pointer type [-Wincompatible-pointer-types]
  374 |                                       iconv(eci_cd, &in, &inleft, &out,
      |                                                     ^~~
      |                                                     |
      |                                                     char **
/usr/x86_64-w64-mingw32/include/iconv.h:43:56: note: expected ‘const char **’ but argument is of type ‘char **’
   43 |         size_t iconv(iconv_t cd, WINICONV_CONST char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
make[2]: *** [Makefile:1089: qrcode/libzbar_la-qrdectxt.lo] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/opt/wine64/drive_c/electrum/contrib/zbar/zbar'
make[1]: *** [Makefile:1895: all-recursive] Error 1
make[1]: Leaving directory '/opt/wine64/drive_c/electrum/contrib/zbar'
make: *** [Makefile:989: all] Error 2
🗯 ERROR: Could not build zbar
🗯 ERROR: Could not build zbar

```
2026-02-28 07:41:45 +00:00
ghost43 ff44d4b4d1 Merge pull request #10093 from f321x/anchor_output_sweeping_lower_fee
txbatcher: don't spend anchors if ctx fee is already sufficient
2026-02-28 03:52:25 +00:00
SomberNight 3674232dd5 build: win: bump wine (10->11) 2026-02-27 16:35:05 +00:00
SomberNight b939e8779f build: win: update debian base (12->13) 2026-02-27 16:27:11 +00:00
f321x 04a034e6ba tests: add unittest for TxBatch._to_sweep_after()
Adds unittest for `TxBatch._to_sweep_after()` anchor claiming part.
2026-02-27 17:18:01 +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 a36c9a24db build: appimage: fix build missing a system-wide python
```
�� INFO:  preparing electrum-locale.
[...]
running stats.py
/usr/bin/env: �python3�: No such file or directory
```

regression from https://github.com/spesmilo/electrum/commit/3afa2fcdf3cce609d8813bbdd7b5962214de5ec0

This had shown up on the CI [0] but we did not notice - there is too many random failures, too much noise :(

[0]: https://github.com/spesmilo/electrum/runs/64623983097
2026-02-26 19:34:08 +00:00
SomberNight d72b741173 update block header checkpoints 2026-02-26 17:49:31 +00:00
SomberNight 57bf8c89ec follow-up RELEASE-NOTES 2026-02-26 17:38:12 +00:00
ghost43 67b4ebd82c Merge pull request #10497 from f321x/version_4_7_1
Version 4.7.1 preparation
2026-02-26 17:35:15 +00:00
f321x eee2e85826 bump version to 4.7.1 2026-02-26 18:06:31 +01:00
f321x 8d95135af6 add version 4.7.1 release notes
Co-authored-by: SomberNight <somber.night@protonmail.com>
2026-02-26 18:05:31 +01:00
ghost43 ff6f37389e Merge pull request #10495 from SomberNight/202602_bump_secp
deps: bump libsecp256k1 version (0.7.0->0.7.1) and electrum-ecc
2026-02-26 15:28:19 +00: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
SomberNight 9dc725fa56 deps: bump libsecp256k1 version (0.7.0->0.7.1) and electrum-ecc 2026-02-25 16:38:11 +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 f1e792cc7b test_wallet_vertical: test bump_fee raises for too low fee
Test that Abstract_Wallet.bump_fee() raises if the given feerate
of the replacement is equal to the feerate of the tx to bump as this
wouldn't be accepted to the mempool.
2026-02-24 14:37:02 +01:00
f321x 6c143fa946 test_wallet_vertical: add test for dscancel fee estimate
Check that dscancel properly raises CannotDoubleSpendTx if the
feerate of the new tx is lower than the tx to be cancelled.
2026-02-24 14:37:01 +01:00
f321x 6e1bf7c4fb test_wallet_vertical: add test for batch tx fee increase
Adds unittest to check the fee increase when adding outputs to a base
tx. Supposed to prevent creating transactions that don't get accepted
like in this traceback:
```
broadcast_transaction error [DO NOT TRUST THIS MESSAGE]: "RPCError(1, 'the transaction was rejected by network rules.\\n\\ninsufficient fee, rejecting replacement ceeaef5ac7f82286e42ebd530e965fa4c7a6c11933d6b89d6d6f0ee2c69db839; new feerate 0.00001109 BTC/kvB <= old feerate 0.00001110 BTC/kvB
```
2026-02-24 14:36:59 +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
ghost43 cb97200933 Merge pull request #10494 from f321x/console_font_size
qt: console: allow changing font size
2026-02-23 16:33:08 +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
ghost43 9a71382c5a Merge pull request #10479 from SomberNight/202602_locale_fancy_names
locale: gui: show translation completion percentage in language names
2026-02-21 04:07:54 +00: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
SomberNight 6de3fef717 (trivial) consistent whitespaces in .gitmodules 2026-02-20 16:30:48 +00:00
ghost43 49f1eff115 Merge pull request #10490 from f321x/locale_llm_proofreader_cleanup
locale: exclude llm proofreader directory from build
2026-02-20 16:20:38 +00:00
f321x 0e7f7b30fc locale: rm llm_proofreader directory during build
Deletes the llm_proofreader directory during the build so
these scripts aren't bundled into the binaries.
2026-02-20 16:39:18 +01:00
f321x 53166cc077 git: ignore changes to locale submodule
add ignore = dirty to electrum locale submodule so changes to the
locale submodule files don't show up in the main git status.
2026-02-20 16:39:11 +01: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
ghost43 71a1e96df6 Merge pull request #10489 from f321x/fix_10487
wallet_db: handle non-existing parent_set_key in v65
2026-02-20 14:54:38 +00: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 6c1e085937 contrib/locale/push_locale: do not sort source-strings
xgettext and related tools have a -s/--sort-output option, which results in the output being lexicographically sorted. The gettext maintainers recommend against using this option and even started deprecating it in some of their tools (xgettext included):
- with -s, source strings are lexicographically sorted in the .pot/.po files
- without -s, source string are output in the same order they are found in the code
  - this way, translators have to do much fewer context switches when contributing translations

note that the qml part we have already *not* been sorting
2026-02-19 16:25:22 +00:00
SomberNight cf25990973 locale: don't translate string "Electrum", "BIP39" 2026-02-19 16:13:44 +00:00