From 0d380218a65bb2e977d9def8c0b0f2ffc34668da Mon Sep 17 00:00:00 2001 From: f321x Date: Mon, 5 Jan 2026 16:02:14 +0100 Subject: [PATCH 1/3] bug: psbt_nostr: set CosignerWallet.pending on aio loop Fixes: ``` Traceback (most recent call last): File "/home/user/code/electrum-fork/electrum/plugins/psbt_nostr/qt.py", line 149, in on_receive self.mark_pending_event_rcvd(event_id) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^ File "/home/user/code/electrum-fork/electrum/plugins/psbt_nostr/psbt_nostr.py", line 254, in mark_pending_event_rcvd self.pending.set() ~~~~~~~~~~~~~~~~^^ File "/usr/lib64/python3.14/asyncio/locks.py", line 192, in set fut.set_result(True) ~~~~~~~~~~~~~~^^^^^^ File "/usr/lib64/python3.14/asyncio/base_events.py", line 829, in call_soon self._check_thread() ~~~~~~~~~~~~~~~~~~^^ File "/usr/lib64/python3.14/asyncio/base_events.py", line 866, in _check_thread raise RuntimeError( "Non-thread-safe operation invoked on an event loop other " "than the current one") RuntimeError: Non-thread-safe operation invoked on an event loop other than the current one ``` --- electrum/plugins/psbt_nostr/psbt_nostr.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/electrum/plugins/psbt_nostr/psbt_nostr.py b/electrum/plugins/psbt_nostr/psbt_nostr.py index fed2a8a01..6d45349bf 100644 --- a/electrum/plugins/psbt_nostr/psbt_nostr.py +++ b/electrum/plugins/psbt_nostr/psbt_nostr.py @@ -40,7 +40,8 @@ from electrum.logging import Logger from electrum.plugin import BasePlugin from electrum.transaction import PartialTransaction, tx_from_any from electrum.util import ( - log_exceptions, OldTaskGroup, ca_path, trigger_callback, event_listener, json_decode, make_aiohttp_proxy_connector + log_exceptions, OldTaskGroup, ca_path, trigger_callback, event_listener, json_decode, + make_aiohttp_proxy_connector, run_sync_function_on_asyncio_thread, ) from electrum.wallet import Multisig_Wallet @@ -250,7 +251,7 @@ class CosignerWallet(Logger): def mark_pending_event_rcvd(self, event_id): self.logger.debug('marking event rcvd') self.known_events[event_id] = now() - self.pending.set() + run_sync_function_on_asyncio_thread(self.pending.set, block=False) def prepare_messages(self, tx: Union[Transaction, PartialTransaction], label: str = None) -> List[Tuple[str, dict]]: messages = [] From e033a5e67bcc3c440e12cf7188b05ef8f7994c8a Mon Sep 17 00:00:00 2001 From: f321x Date: Mon, 5 Jan 2026 16:25:24 +0100 Subject: [PATCH 2/3] psbt_nostr: add EventListener comment to CosignerWallet I got confused how on_event_proxy_set can even work if CosignerWallet doesn't inherit from EventListener until i figured out its children use the EventListener too. To avoid this confusion i added two comments. --- electrum/plugins/psbt_nostr/psbt_nostr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/electrum/plugins/psbt_nostr/psbt_nostr.py b/electrum/plugins/psbt_nostr/psbt_nostr.py index 6d45349bf..929984457 100644 --- a/electrum/plugins/psbt_nostr/psbt_nostr.py +++ b/electrum/plugins/psbt_nostr/psbt_nostr.py @@ -74,7 +74,7 @@ class PsbtNostrPlugin(BasePlugin): self.cosigner_wallets.pop(wallet) -class CosignerWallet(Logger): +class CosignerWallet(Logger): # children have to inherit EventListener and register callbacks # one for each open window (Qt) / open wallet (QML) # if user signs a tx, we have the password # if user receives a dm? needs to enter password first @@ -124,6 +124,7 @@ class CosignerWallet(Logger): @event_listener async def on_event_proxy_set(self, *args): + # note: the callbacks get registered in the child classes of CosignerWallet if not (self.network and self.nostr_pubkey): return await self.stop() From 31ac44dddd05206659cef0f9a931631379694de5 Mon Sep 17 00:00:00 2001 From: f321x Date: Mon, 5 Jan 2026 16:32:22 +0100 Subject: [PATCH 3/3] TxEditor: register correct callback on_event_channels_updated doesn't get fired if channels change their state to OPEN. TxEditor needs to use on_event_channel to notice channels coming online. --- electrum/gui/qt/confirm_tx_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electrum/gui/qt/confirm_tx_dialog.py b/electrum/gui/qt/confirm_tx_dialog.py index 9bfcc17fd..3e7fc482e 100644 --- a/electrum/gui/qt/confirm_tx_dialog.py +++ b/electrum/gui/qt/confirm_tx_dialog.py @@ -874,7 +874,7 @@ class TxEditor(WindowModalDialog, QtEventListener, Logger): self.update_submarine_tab() @qt_event_listener - def on_event_channels_updated(self, wallet): + def on_event_channel(self, wallet, _channel): # useful e.g. if the user quickly opens the tab after startup before the channels are initialized if wallet == self.wallet and self.swap_manager and self.swap_manager.is_initialized.is_set(): self.update_submarine_tab()