Commit Graph

8561 Commits

Author SHA1 Message Date
SomberNight
b590c864ee config: fix setting CLI_TIMEOUT configvar, and add "convert_setter"s
"type_=float" behaves a bit weirdly. Was kinda broken before, still not fully "fixed" here.
With this commit, if used together with convert_setter, it at least behaves in a sane way.

```
$ ./run_electrum -o setconfig timeout 10
  1.16 | E | __main__ | error running command (without daemon)
Traceback (most recent call last):
  File "/home/user/wspace/electrum/./run_electrum", line 593, in handle_cmd
    result = fut.result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 458, in result
    return self.__get_result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/home/user/wspace/electrum/./run_electrum", line 268, in run_offline_command
    result = await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/commands.py", line 194, in func_wrapper
    return await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/commands.py", line 408, in setconfig
    self._setconfig(key, value)
  File "/home/user/wspace/electrum/electrum/commands.py", line 398, in _setconfig
    cv.set(value)
  File "/home/user/wspace/electrum/electrum/simple_config.py", line 126, in set
    self._config_var._set_config_value(self._config, value, save=save)
  File "/home/user/wspace/electrum/electrum/simple_config.py", line 89, in _set_config_value
    raise ValueError(
ValueError: ConfigVar.set type-check failed. key='timeout'. type=<class 'float'>. value=10
```
2025-06-25 17:15:52 +00:00
SomberNight
aeba531aa8 logging: keep more log files by default
To reduce chance an important log file gets lost due to the user restarting the app a couple times.
Perhaps we should make this smarter and cap based on bytes size of folder, instead of number of files.
2025-06-25 16:46:16 +00:00
accumulator
26e6c0900b Merge pull request #9975 from SomberNight/202506_qml_lnurl_btn_disabled
qml: set BtcField.textAsSats initial value to match its text
2025-06-24 12:54:19 +02:00
f321x
f1837ef58d fix: sort qml swap provider list by PoW
This change orders the list of swapproviders in the qml gui by the
`pow_bits` value in the announcement by inserting the orders at the
correct index in the list instead of just appending new incoming offers.
2025-06-24 11:45:34 +02:00
SomberNight
71627b91c4 qml: set BtcField.textAsSats initial value to match its text
textAsSats was being set to 0 initially, regardless of actual text, only healing after onTextChanged.

fixes https://github.com/spesmilo/electrum/issues/9974
2025-06-24 09:19:13 +00:00
SomberNight
6f5041443f qt: SwapServerDialog: explicit columns 2025-06-23 14:49:36 +00:00
ghost43
0c0a8b7c82 Merge pull request #9955 from SomberNight/202506_qt_mac_camera_permission
qt gui: qrreader: macos: add runtime requesting of camera permission
2025-06-23 14:21:52 +00:00
SomberNight
c1d21aab1d qml: QENetwork: reduce log spam a bit in ln-gossip mode 2025-06-23 13:10:44 +00:00
ThomasV
b79a73b483 qt swaps dialog: replace config menu with a direct button 2025-06-21 10:46:33 +02:00
ThomasV
2607a0d9f6 Plugins dialog: remove direct download option.
Since users have to trust plugin publishers, we should expect
the plugin to be signed by its author, and the user to verify
the signature before installing.
2025-06-21 10:10:31 +02:00
ThomasV
d7f6820fd6 hardware_wallets: register keystore if if external plugin was authorized
Also remove 'gui_good' from hw_wallets dict (was always True)
2025-06-19 11:23:57 +02:00
ThomasV
f6075a5825 follow-up ba3783f998 2025-06-19 09:44:56 +02:00
ThomasV
4714fdfba2 plugins: add icons to manifest.json 2025-06-17 10:45:03 +02:00
accumulator
96ea80a8a1 Merge pull request #9959 from accumulator/nostr_swap_server_wait_unlock
submarine_swaps: wait for unlock if wallet is password protected before starting nostr swap service
2025-06-16 16:14:36 +02:00
f321x
c58ff7caec qt: wrap show_bitcoin_paper() in WaitingDialog
i noticed that the `show_bitcoin_paper()` call can be a bit slow on some
machines blocking the gui for multiple seconds without giving feedback.
Wrapping it in a waiting dialog gives the user some feedback that
something is happening.
2025-06-16 10:08:11 +02:00
Sander van Grieken
1687b17e00 submarine_swaps: wait for unlock if wallet is password protected before starting nostr swap service 2025-06-16 09:39:50 +02:00
наб
e28836eb1d address_synchronizer: add a cache in front of get_utxos()
get_utxos() is called pretty often, both spuriously,
and on focus change, on tab switch, &c.

It blocks as it iterates, functionally, /every/ address the wallet knows of.

On large wallets (like testnet
  vpub5VfkVzoT7qgd5gUKjxgGE2oMJU4zKSktusfLx2NaQCTfSeeSY3S723qXKUZZaJzaF6YaF8nwQgbMTWx54Ugkf4NZvSxdzicENHoLJh96EKg
from #6625 with 11k TXes and 10.5k addresses),
this takes 1.3s of 100%ed CPU usage,
basically in a loop from the UI thread.

get_utxos() is 50-70% of the flame-graph when sampling
a synced wallet process.

This data is a function of the block-chain state,
and we have hooks that notify us of when the block-chain state changes:
we can just cache the result and only re-compute it then.

For example, here's a trace log where get_utxos() has
  print(end - start, len(domain), block_height)
and a transaction is clearing:
  1.3775344607420266 10540 4507192
  0.0010390589013695717 10540 4507192 cached!
  0.001393263228237629 10540 4507192 cached!
  0.0009001069702208042 10540 4507192 cached!
  0.0010241391137242317 10540 4507192 cached!
  ...
  0.00207632128149271 10540 4507192 cached!
  0.001397700048983097 10540 4507192 cached!
  invalidate_cache
  1.4686454269103706 10540 4507192
  0.0012429207563400269 10540 4507192 cached!
  0.0015075239352881908 10540 4507192 cached!
  0.0010459059849381447 10540 4507192 cached!
  0.0009669591672718525 10540 4507192 cached!
  ...
  on_event_blockchain_updated
  invalidate_cache
  1.3897203942760825 10540 4507193
  0.0010689008049666882 10540 4507193 cached!
  0.0010420521721243858 10540 4507193 cached!
  ...
  invalidate_cache
  1.408584670163691 10540 4507193
  0.001336586195975542 10540 4507193 cached!
  0.0009196233004331589 10540 4507193 cached!
  0.0009176661260426044 10540 4507193 cached!
  ...
about 30s of low activity.

Without this patch, the UI is prone to freezing,
running behind, and I wouldn't be surprised if UI thread blocking
on Windows ends up crashing to some extent as the issue notes.
In the log, this manifests as a much slower but consistent
stream of full 1.3-1.4s updates during use,
and every time the window is focused.
2025-06-15 22:08:30 +02:00
наб
fdaafd5abf address_synchronizer: apply @with_lock where applicable 2025-06-15 21:22:27 +02:00
SomberNight
4887fb3e7f util.with_lock: add support for chaining with @event_listener
Consider e.g.:
```
class AddressSynchronizer(Logger, EventListener):
[... snip ...]
    @event_listener
    @with_lock
    def on_event_blockchain_updated(self, *args):
        self._get_balance_cache = {}  # invalidate cache
        self.db.put('stored_height', self.get_local_height())
```

was raising:
```
func.__qualname__='with_lock.<locals>.func_wrapper'
Traceback (most recent call last):
  File "...\electrum\run_electrum", line 105, in <module>
    from electrum.logging import get_logger, configure_logging  # import logging submodule first
  File "...\electrum\electrum\__init__.py", line 19, in <module>
    from .wallet import Wallet
  File "...\electrum\electrum\wallet.py", line 70, in <module>
    from .address_synchronizer import (
  File "...\electrum\electrum\address_synchronizer.py", line 75, in <module>
    class AddressSynchronizer(Logger, EventListener):
  File "...\electrum\electrum\address_synchronizer.py", line 205, in AddressSynchronizer
    def on_event_blockchain_updated(self, *args):
  File "...\electrum\electrum\util.py", line 2005, in event_listener
    classname, method_name = func.__qualname__.split('.')
ValueError: too many values to unpack (expected 2)
```
2025-06-15 19:06:10 +00:00
SomberNight
051b7eb56c Merge branch 'pr/9957': run_electrum: improve check_imports()
merges https://github.com/spesmilo/electrum/pull/9957
2025-06-15 18:28:49 +00:00
SomberNight
8a99219456 follow-up prev: electrum-ecc should search for libsecp dll in electrum/
The hack needs to be applied before we try importing electrum_ecc, i.e. it needs to be in the main script.
However, it should also be applied if the main script is not invoked directly, but e.g. the user imports electrum directly.
Hence the duplication.
2025-06-15 18:25:42 +00:00
SomberNight
4c9ab617e3 dpcs: rm some instances of "sudo pip" recommendations
we should not recommend users to invoke pip with sudo
2025-06-15 17:57:22 +00:00
SomberNight
612d82e8d4 qt gui: qrreader: macos: add runtime requesting of camera permission
- we were already
  - statically declaring "NSCameraUsageDescription" in the Info.plist
    - this used to be enough in the past
  - codesigning with an entitlements.plist that declares "com.apple.security.device.camera"
    - I believe this is required for notarization to pass for an app that declares "NSCameraUsageDescription".
- previously this was enough to access the camera IIRC
  - in any case, if the user goes into "System Preferences">"Security & Privacy", they can manually modify permissions there
- now with this commit, we on-demand trigger at runtime the OS permission prompt
  - making it much easier for users to actually use the camera
  - note: if you run via the Terminal, e.g. `$ $HOME/Desktop/Electrum.app/Contents/MacOS/run_electrum`,
    then it will be the Terminal app that requires the camera permission. If you run by double-clicking Electrum.app,
    then Electrum.app will be the "app" that requires the camera permission.
  - `$ tccutil reset Camera` can be used to clear permissions for all apps (back to the Qt::PermissionStatus::Undetermined state)

ref https://doc.qt.io/qt-6.5/qcoreapplication.html#requestPermission-1
2025-06-14 17:06:15 +00:00
SomberNight
f8cfedb27b prepare release 4.6.0b1 2025-06-13 16:50:58 +00:00
SomberNight
f366f3e7fb qt gui: be more resilient against import issues of QtMultimedia
The user should still be able to open the Preferences dialog, despite the camera functionality being broken.

see https://github.com/spesmilo/electrum/issues/9949

```
  6.36 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "electrum\gui\qt\main_window.py", line 2672, in settings_dialog
  File "electrum\gui\qt\settings_dialog.py", line 229, in __init__
  File "electrum\gui\qt\qrreader\__init__.py", line 96, in find_system_cameras
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 450, in exec_module
  File "electrum\gui\qt\qrreader\qtmultimedia\__init__.py", line 28, in <module>
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 450, in exec_module
  File "electrum\gui\qt\qrreader\qtmultimedia\camera_dialog.py", line 32, in <module>
RuntimeError: PyQt6.QtMultimedia cannot import type '���d�⌂' from PyQt6.QtCore

```
2025-06-13 14:22:31 +00:00
ThomasV
40e244dfe9 Merge pull request #9948 from f321x/disable_disabling_i_agree_ToU
qt: fix: ToU 'I Accept' button not getting enabled
2025-06-13 15:06:06 +02:00
f321x
52e2ced62e qt: fix: ToU 'I Accept' button not getting enabled
The 'I Accept' button might not get enabled for some users where startup
is very slow.
The first check if the 'I Agree' button should be enabled gets fired
100ms after constructing the Dialog, which might not be enough.
So we can either remove the logic completely (done here) to prevent these
issues, or alternatively increase the initial timer to some large timout
after which the window should be assembled fully (e.g. 2 seconds). As
the user is not able to read the whole terms in few seconds this would
be a viable option too.
2025-06-13 14:45:27 +02:00
f321x
cc848be61c qt: fix: set ApplicationAttribute.AA_DontShowIconsInMenus False
Explicitly sets the AA_DontShowIconsInMenus attribute to false as it
defaults to true on some Qt versions / environments which causes icons
to not show up in the menus (e.g. MacOS).
see https://forum.qt.io/post/813228
The attribute has to be set on self.app after the QApplication has been
instanciated (https://doc.qt.io/qt-6/qt.html#ApplicationAttribute-enum)
2025-06-13 12:21:57 +02:00
ThomasV
4305845643 update locale 2025-06-12 21:02:58 +02:00
SomberNight
d4a57dcd9e prepare release 4.6.0b0 2025-06-12 18:47:39 +00:00
ThomasV
253b0989b8 cli: rename clearconfig -> unsetconfig 2025-06-12 19:56:14 +02:00
Sander van Grieken
3c9c6a286c imports, whitespace, type hints, copyright headers 2025-06-12 14:32:00 +02:00
Sander van Grieken
2c7afacbe1 timelock_recovery: remove redundant pi.parse_output() call and use pi fields directly 2025-06-12 10:07:28 +02:00
f321x
97f9521cb1 fix: handle ! amount for payment identifiers
fixes exceptions ocurring when entering a '!' amount with a payment
identifier that is not allowed to send max (e.g. bolt11).
fixes exception when "Max" is still set from previous PI and the PI gets
replaced by one that doesn't allow max sending.
2025-06-11 19:26:26 +02:00
ghost43
39371fb0e6 Merge pull request #9939 from f321x/allow_more_genesis_in_crash_reporter
allow testnet4 and signet in crash reporter
2025-06-11 12:34:01 +00:00
f321x
6a8478695d allow testnet4 and signet in crash reporter
allows to submit crash reports from testnet 4 and signet too in addition
to testnet3 and mainnet.
2025-06-11 14:14:49 +02:00
ThomasV
3f24cea5bb Merge pull request #9938 from f321x/fix_history_export
fix: update do_export_history to use wallet.get_full_history
2025-06-11 13:12:18 +02:00
ThomasV
213d182f30 Merge pull request #9933 from f321x/prevent_fail_swap_exception
fix: prevent KeyError if _fail_swap gets called multiple times
2025-06-11 13:09:52 +02:00
f321x
8b15d64dc9 fix: prevent KeyError if _fail_swap gets called multiple times
If `_fail_swap()` gets called multiple times (e.g. from callbacks) this
would race a `KeyError` as the swap got already popped from
`self._swaps`.
In theory `_fail_swap` unregisters itself from the lnwatcher callback
but the callback may is scheduled multiple times before it has the
chance to unregister itself.
2025-06-11 11:37:24 +02:00
f321x
86183797db fix: update do_export_history to use wallet.get_full_history
`do_export_history()` which is used by the qt history export function was
broken as it used a method that did not exist anymore.
this updates `do_export_history()` to use `get_full_history()` and also
adds support for payment grouping and lightning transactions to the
generated CSV file.
2025-06-11 11:03:57 +02:00
ghost43
e30392cd16 Merge pull request #9934 from f321x/matplotlib_warning
qt: provide more detailed warning for plot feature, change matplotlib backend
2025-06-10 18:41:42 +00:00
ThomasV
b8761ca006 payserver plugin: fix config var names 2025-06-10 20:39:14 +02:00
ghost43
448cbc7869 Merge pull request #9936 from f321x/nwc_incoming_event_filtering
plugin: nwc: improve filtering of expired requests
2025-06-10 18:32:13 +00:00
f321x
0f442f4c85 plugin: nwc: improve filtering of expired requests
improve the filtering of incoming requests by checking if they have
explicitly set an expiration tag. If so, they will only be ignored if
this timestamp is exceeded. Otherwise requests older than 30 secons will
get ignored and an error will get sent to the client so the client is
aware it's request arrived too late.
This is done to prevent handling requests the user may already expects
to have failed.
2025-06-10 19:29:19 +02:00
SomberNight
47e76b25b1 swaps: add some type hints, and force kwargs 2025-06-10 16:20:43 +00:00
SomberNight
2fb4debc7c commands: fix normal_swap cmd 2025-06-10 16:20:39 +00:00
SomberNight
527d9e8215 plugins: nwc: clean-up imports
Try to follow PEP-8 import grouping, to make things readable.
I want to be able to quickly spot 3rd-party library imports! :P
2025-06-10 15:22:13 +00:00
SomberNight
dd7a284fd9 plugins: nwc: fix constants.net import
"# don't import net directly, import the module instead (so that net is singleton)"

set_as_network does not work if net is not a singleton, it results in a split worldview.
2025-06-10 15:22:10 +00:00
SomberNight
65bc28056c plugins: psbt_nostr: trivial rename
pycharm static analyser was getting confused and thinking this line was rebinding "_" from i18n._
(but AFAICT that's a bug in the static analyser)
2025-06-10 15:01:27 +00:00
SomberNight
f846a16f07 plugins: psbt_nostr: add comment about testnet/mainnet separation 2025-06-10 15:01:24 +00:00