1
0
Commit Graph

18982 Commits

Author SHA1 Message Date
Marko Bencun
6567e01f61 bitbox02: update to 7.0.0
This adds support for BitBox02 Nova devices.
2025-07-17 12:07:24 +02:00
ThomasV
244a4c5053 update date for 4.6.0 4.6.0 2025-07-16 14:50:11 +02:00
ghost43
c3b9ef0c89 Merge pull request #10034 from f321x/fix_confirm_tx_dialog_timer_exc
fix: qt: handle main_window.gui_object.timer being None
2025-07-16 12:17:24 +00:00
Sander van Grieken
0e055f8127 qt: don't share ElectrumGui.QTimer, use self-contained QTimer so its lifecycle is synced in
`ElectrumWindow`, `TxEditor`, `SwapDialog`

Also use `QTimer` classmethod for `.singleShot()` occurrences.
2025-07-16 13:13:26 +02:00
accumulator
371c1bd1e3 Merge pull request #10036 from accumulator/fix_10035
qml: fix passphrase/seed extension wordwrap
2025-07-16 13:06:44 +02:00
Sander van Grieken
b9ea17674d qml: fix passphrase/seed extension wordwrap 2025-07-16 13:05:44 +02:00
ghost43
b259aab727 Merge pull request #10032 from SomberNight/202507_qt_confirm_txdialog_fee
qt ConfirmTxDialog: also save custom fixed feerate fee_policies
2025-07-16 10:47:28 +00:00
f321x
121b7b767e fix: qt: handle main_window.gui_object.timer being None
When closing Electrum with open `ConfirmTxDialog` the following
exception is raised:

```
1319.20 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/user/code/electrum-fork/electrum/gui/qt/send_tab.py", line 575, in do_pay_or_get_invoice
    self.do_pay_invoice(self.pending_invoice)
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/gui/qt/send_tab.py", line 602, in do_pay_invoice
    self.pay_onchain_dialog(invoice.outputs, invoice=invoice)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/gui/qt/send_tab.py", line 328, in pay_onchain_dialog
    tx, is_preview = self.window.confirm_tx_dialog(make_tx, output_value, batching_candidates=candidates)
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/gui/qt/main_window.py", line 1502, in confirm_tx_dialog
    return d.run(), d.is_preview
           ~~~~~^^
  File "/home/user/code/electrum-fork/electrum/gui/qt/confirm_tx_dialog.py", line 477, in run
    self.stop_editor_updates()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/user/code/electrum-fork/electrum/gui/qt/confirm_tx_dialog.py", line 133, in stop_editor_updates
    self.main_window.gui_object.timer.timeout.disconnect(self.timer_actions)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'timeout'
```

This can be prevented by checking if `main_window.gui_object.timer` is
None before trying to disconnect it.
2025-07-16 09:47:32 +02:00
SomberNight
5fad4bff8f verifier: fix off-by-one for max_checkpoint
if a wallet had a tx mined in the max_checkpoint block, in certain cases
we would leave it forever in the "unverified" state and remain stuck in "synchronizing..."
2025-07-15 22:35:21 +00:00
SomberNight
76005372a6 qt ConfirmTxDialog: only show fee_target text if slider is active 2025-07-15 16:52:11 +00:00
SomberNight
02b0073ca5 qt ConfirmTxDialog: also save custom fixed feerate fee_policies
- save custom fixed feerate fee_policies, not just slider-restricted ones
- dynamically update fee_target text, to follow feerate_e
  - otherwise when the slider is set to "feerate", users would be shown two conflicting values
2025-07-15 16:45:29 +00:00
SomberNight
68a203336e qt ConfirmTxDialog: fix feerate_e 2025-07-15 16:43:53 +00:00
SomberNight
dd2fa90838 prepare release 4.6.0 2025-07-15 14:46:41 +00:00
ThomasV
bfba6873f8 Merge pull request #10031 from SomberNight/202507_walletdb_add_configvar_partial_writes_4
wallet_db: add configvar for partial_writes, disable by default
2025-07-15 16:28:33 +02:00
SomberNight
85fc95c71b wallet_db: add configvar for partial_writes, disable by default
Adds a new configvar `WALLET_PARTIAL_WRITES` to enable/disable partial writes for the walletDB.
This is a further restriction on top of the existing restrictions,
e.g. wallet files still need to have file encryption disabled for partial writes.
It defaults to off, so even for unencrypted wallets we disable partial writes for now.

This is used as a stopgap measure until we fix the issues found with the partial writes impl
(see https://github.com/spesmilo/electrum/issues/10000).
2025-07-15 14:03:48 +00:00
ThomasV
6d22c24deb Merge pull request #10028 from SomberNight/202507_issue10021
qt: only allow wallet unlock if wallet has ks-enc
2025-07-15 15:30:33 +02:00
SomberNight
482d573f55 stdio gui: use daemon.load_wallet(), similar to text gui 2025-07-15 13:23:50 +00:00
SomberNight
3c82b00c5e WalletDB() usage: trivial refactors and fixes
split off from https://github.com/spesmilo/electrum/pull/10027
2025-07-15 12:30:06 +00:00
SomberNight
7611d4c3b3 scripts: fix "cannot schedule new futures after interpreter shutdown"
- looks like around python3.9, they changed it so that
  if we don't block on the main thread, it starts to shut things down
- polling thread.join() makes Ctrl+C work. kind of.

```
$ ./electrum/scripts/txradar.py 6bde84a981e72573666fcc51c81ec3f8f4a813709bf16451dce3f106a114d392
Exception in run: RuntimeError('cannot schedule new futures after interpreter shutdown')
Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/util.py", line 1218, in wrapper
    return await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/interface.py", line 649, in wrapper_func
    return await func(self, *args, **kwargs)
  File "/home/user/wspace/electrum/electrum/interface.py", line 675, in run
    await self.open_session(ssl_context=ssl_context)
  File "/home/user/wspace/electrum/electrum/interface.py", line 872, in open_session
    async with _RSClient(
  File "/home/user/.local/lib/python3.10/site-packages/aiorpcx/rawsocket.py", line 167, in __aenter__
    _transport, protocol = await self.create_connection()
  File "/home/user/wspace/electrum/electrum/interface.py", line 285, in create_connection
    return await super().create_connection()
  File "/home/user/.local/lib/python3.10/site-packages/aiorpcx/rawsocket.py", line 163, in create_connection
    return await connector.create_connection(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 1036, in create_connection
    infos = await self._ensure_resolved(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 1418, in _ensure_resolved
    return await loop.getaddrinfo(host, port, family=family, type=type,
  File "/usr/lib/python3.10/asyncio/base_events.py", line 863, in getaddrinfo
    return await self.run_in_executor(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 821, in run_in_executor
    executor.submit(func, *args), loop=self)
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 169, in submit
    raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown
```
2025-07-15 12:00:31 +00:00
ThomasV
e442f38d08 Merge pull request #10026 from SomberNight/202507_jsonpatch_monkeypatch_exc
JsonDB: monkeypatch jsonpatch exceptions to avoid leaking secrets
2025-07-15 12:06:39 +02:00
SomberNight
9e752d2c67 update locale 2025-07-14 21:46:08 +00:00
SomberNight
426e99f5ad update RELEASE-NOTES 2025-07-14 21:40:36 +00:00
SomberNight
f2f1dddcc8 swaps: factor out pubkey_to_rgb_color into core lib 2025-07-14 21:09:18 +00:00
SomberNight
9b5b2bad4a qt: only allow wallet unlock if wallet has ks-enc
fixes https://github.com/spesmilo/electrum/issues/10021
2025-07-14 14:26:14 +00:00
SomberNight
b16760b861 jsonpatch exception-mangling: more robust against secrets in dict keys 2025-07-14 12:53:56 +00:00
SomberNight
195d89a509 JsonDB: monkeypatch jsonpatch exceptions to avoid leaking secrets
closes https://github.com/spesmilo/electrum/issues/10001
2025-07-14 12:16:09 +00:00
Sander van Grieken
78a7c85f49 qml: swap: like on desktop, use pkh of nostr pubkey as color 2025-07-11 16:33:40 +02:00
accumulator
62a30c5688 Merge pull request #10017 from f321x/fix_qml_wizard_exception
fix: qml: wizard: delete seed_type from wizard_data if not set explicitly
2025-07-11 11:52:05 +02:00
accumulator
f87243dd5c Merge pull request #10014 from f321x/fix_qml_label_setting
fix: qml: update tx label on detailsChanged signal
2025-07-11 10:50:27 +02:00
SomberNight
0f4d8d6d57 follow-up prev: fix weird pyqt bug re QPushButton.clicked
When clicking the "close_button" button (labelled "Not Now"), the whole app state got bugged:
none of the existing windows (e.g. ElectrumWindow) could get focus anymore.

The signature of PushButton.clicked is:
`void QAbstractButton::clicked(bool checked = false)`
https://doc.qt.io/qt-6/qabstractbutton.html#clicked

and pyqt is probably doing some polymorphism, dynamically deciding if the qt slot wants the "checked" arg or not.

The extremely weird part is that the bug is triggered on clicking "close_button" (probably pyqt is passing "checked" to self.close)
but instead of the current commit, the following diff, touching a completely different button, would also "fix" the issue:

```
diff --git a/electrum/gui/qt/exception_window.py b/electrum/gui/qt/exception_window.py
index eceab89de6..e0162e5827 100644
--- a/electrum/gui/qt/exception_window.py
+++ b/electrum/gui/qt/exception_window.py
@@ -67,7 +67,7 @@ class Exception_Window(BaseCrashReporter, QWidget, MessageBoxMixin, Logger):

         self._report_contents_dlg = None  # type: Optional[ReportContentsDialog]
         collapse_info = QPushButton(_("Show report contents"))
-        collapse_info.clicked.connect(self.show_report_contents_dlg)
+        collapse_info.clicked.connect(lambda: self.show_report_contents_dlg())

         main_box.addWidget(collapse_info)
 ```

No idea why.
2025-07-09 15:32:07 +00:00
f321x
aefb180007 fix: qml: wizard: delete seed_type if not set
deletes the `seed_type` key from `wizard_data` in `WCWalletType` if it
is not explicitly set to prevent a stale value from a previous wizard
flow if the user goes back in the wizard and selects a different wallet
type instead of completing the wizard with the previously selected
wallet type.
This happens as the `apply()` function gets called with the
previously set radio button (e.g. 2fa) if the user goes back, if he then
selects multisig the `2fa_segwit` `seed_type` won't get cleared and
cause the exception later.
Example exception when first selecting 2fa, then going back and creating
a multisig wallet:
```
32.77 | E | gui.qml.qeapp.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/vagrant/electrum/electrum/gui/qml/qewizard.py", line 40, in submit
    view = self.resolve_next(self._current.view, wdata)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vagrant/electrum/electrum/wizard.py", line 78, in resolve_next
    view_accept(wizard_data)
  File "/home/vagrant/electrum/electrum/wizard.py", line 501, in maybe_master_pubkey
    wizard_data['multisig_master_pubkey'] = self.keystore_from_data(wizard_data['wallet_type'], wizard_data).get_master_public_key()
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vagrant/electrum/electrum/wizard.py", line 339, in keystore_from_data
    return keystore.from_seed(data['seed'], passphrase=seed_extension, for_multisig=for_multisig)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vagrant/electrum/electrum/keystore.py", line 1197, in from_seed
    raise BitcoinException('Unexpected seed type {}'.format(repr(t)))
electrum.util.BitcoinException: Unexpected seed type '2fa_segwit'
```

Triggered by the following wizard stack:
```
 30.94 | D | wizard | view=create_seed
 30.94 | D | wizard | resolve_next view is confirm_seed
 30.94 | D | wizard | wizard stack:
0: 0x7fdc6804ae80 - {}

1: 0x7fdc6ac61400 - {'wallet_name': 'wallet_1'}

2: 0x7fdc680d8a80 - {'seed_type': '2fa_segwit', 'wallet_name': 'wallet_1', 'wallet_type': 'multisig'}

3: 0x7fdc6804ab00 - {'multisig_cosigner_data': {}, 'multisig_participants': 2, 'multisig_signatures': 2, 'seed_type': '2fa_segwit', 'wallet_name': 'wallet_1', 'wallet_type': 'multisig'}

4: 0x7fdc6807f0c0 - {'keystore_type': 'createseed', 'multisig_cosigner_data': {}, 'multisig_participants': 2, 'multisig_signatures': 2, 'seed_type': '2fa_segwit', 'wallet_name': 'wallet_1', 'wallet_type': 'multisig'}

c: 0x7fdc6807c380 - {'keystore_type': 'createseed', 'multisig_cosigner_data': {}, 'multisig_participants': 2, 'multisig_signatures': 2, 'seed': '<redacted>', 'seed_extend': False, 'seed_extra_words': '<redacted>', 'seed_type': '2fa_segwit', 'seed_variant': 'electrum', 'wallet_name': 'wallet_1', 'wallet_type': 'multisig'}
 30.94 | W | gui.qml.qeapp | next view: confirm_seed
```
2025-07-09 16:29:20 +02:00
SomberNight
a1ee18f975 qt: crash reporter: replace msg_box with dedi ReportContentsDialog
- the msg_box did not allow neither vertical nor horizontal scrolling
  - long lines were not word-wrapped, but were effectively truncated
  - long reports could only be inspected if the user somehow selected
    the full text and pasted it into a text editor
- new dialog allows vertical and horizontal scrolling
  - we could maybe word-wrap instead of horizontal scrolling,
    but this is already a strict improvement for long reports
2025-07-09 14:24:15 +00:00
ThomasV
487053a8a4 Merge pull request #9996 from spesmilo/lnwatcher_fix_9987
lnwatcher: add 'subscribe' parameter to add_callback
2025-07-09 11:02:26 +02:00
ThomasV
102132fa43 lnwatcher: add 'subscribe' parameter to add_callback
when a channel is redeemed, we still need to call the callback
in order to set labels, accounting_addresses.

Fixes #9987
2025-07-09 10:32:05 +02:00
ghost43
f5773fdf1f Merge pull request #9994 from SomberNight/202506_lnwatcher_to_wait_until_fees_go_down
lnwatcher: keep_watching until fees go down
2025-07-08 14:28:45 +00:00
SomberNight
f337b4782d lnwatcher: keep watching sweep TXOs that are dust due to high fees
- if fee estimates are high atm, some outputs are not worth to sweep
- however, fee estimates might be only-temporarily very high
  - previously in such a case lnwatcher would just discard outputs as dust,
    and mark the channel REDEEMED (and hence never watch it or try again)
  - now, instead, if the outputs would not be dust if fee estimates were lower,
    lnwatcher will keep watching the channel
    - and if estimates go down, lnwatcher will sweep them then
- relatedly, previously txbatcher.is_dust() used allow_fallback_to_static_rates=True,
    and it erroneously almost always fell back to the static rates (150 s/b) during
	startup (race: lnwatcher was faster than the network managed to get estimates)
	- now, instead, txbatcher.is_dust() does not fallback to static rates,
	  and the callers are supposed to handle NoDynamicFeeEstimates.
	  - I think this makes much more sense. The previous meaning of "is_dust"
	    with the fallback was weird. Now it means: "is dust at current feerates".

fixes https://github.com/spesmilo/electrum/issues/9980
2025-07-08 14:02:52 +00:00
SomberNight
a1a55db39c lnwatcher: keep_watching should wait at least until closing_tx is deep
Even if it decides there is nothing to sweep from the ctx/etc, it still needs to
keep watching until a reorg-safe depth.
2025-07-08 13:36:04 +00:00
SomberNight
6ce8eb12f7 regtests: add test "lnwatcher_waits_until_fees_go_down"
reproduces https://github.com/spesmilo/electrum/issues/9980
2025-07-08 13:36:01 +00: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
SomberNight
93738e7159 lnwatcher: maybe_add_pending_forceclose: also check SRK channels
ref https://github.com/spesmilo/electrum/pull/9798#discussion_r2172090792

and clarify "was_added" parameter
2025-07-08 13:31:15 +00:00
SomberNight
aade542e1d json_db: add a few type hints 2025-07-08 13:20:47 +00:00
SomberNight
770341a253 interface: increase default config.NETWORK_MAX_INCOMING_MSG_SIZE
ref 2969ab1104
ref a704a68f7f
2025-07-07 15:47:12 +00:00
ghost43
250fdaefce Merge pull request #10013 from f321x/fix_command_gettransaction
commands: fix: only try to get wallet if wallet_path
2025-07-07 14:42:36 +00:00
ghost43
d8014ac068 Merge pull request #10011 from SomberNight/202507_syntax_check_i18n_format_strings
i18n: syntax-check translations at runtime
2025-07-07 14:24:33 +00:00
f321x
86dd267d15 fix: qml: update tx label on detailsChanged signal
when setting a transaction label in the qml
`LightningPaymentDetails` or `TxDetails` dialogs which get opened
directly by the `ReceiveDialog` (`onRequestPaid`) the label is not applied on the main
transaction list as no callback for `detailsChanged` is registered which
gets called when the label changes. As a result the label is only
visible after the main list gets reloaded (e.g. restart).
This commit adds callbacks for `detailsChanged` to fix this.
2025-07-07 15:55:14 +02:00
SomberNight
d16c625019 i18n: syntax-check translations at runtime
We often call str.format() on translated strings.
E.g. `_("time left: {} seconds").format(t1)`
If the translated string has a different format syntax, this can raise at runtime.

This PR adds some runtime checks that try to ensure the source string and the translated string
have a similar format syntax. If the checks fail, `_()` will "reject" the translation by
returning the source string.

fixes https://github.com/spesmilo/electrum/issues/10010
ref https://github.com/spesmilo/electrum/issues/10007#issue-3203378250
2025-07-07 13:54:11 +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
SomberNight
bbac398d1b i18n: add comment about positional substitution in str.format() 2025-07-06 00:20:11 +00:00
ghost43
08965d93c4 Merge pull request #10006 from shangchenglumetro/master
chore: fix some minor issues in the comments
2025-07-05 23:54:43 +00:00
ghost43
fecd161c24 Merge pull request #10009 from f321x/fix_revealer_backup
plugin: revealer: stop catching exceptions on noise file creation
2025-07-05 22:12:31 +00:00