qt, qml: for new transaction notifications, instead of using sign, explicitly say sent/received. For multiple transactions, split summary in total sent/received and a balance change.
What changed, and why it matters
This commit is a user-interface cleanup, not a security fix. It changes how Electrum's desktop and mobile-style GUIs describe new transactions in pop-up notifications: instead of showing a positive or negative number with a plus/minus sign, the notification now explicitly says 'sent' or 'received'. It also moves duplicated notification-building code from the two GUI layers into a shared wallet method. There is no evidence this change addresses a vulnerability.
No security action needed. Treat as a normal UI/UX refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors transaction notification text generation. Previously, both Qt and QML GUI code computed wallet deltas and emitted strings like ‘New transaction: +0.001 BTC’ or ‘New transaction: -0.001 BTC’. The new shared Abstract_Wallet.get_user_notifications_for_new_txns() method produces ‘New transaction: received 0.001 BTC’ / ‘sent 0.001 BTC’, and for batches of three or more transactions splits the summary into total sent, total received, and net balance change. The change is purely presentational and consolidates duplicated logic.
Changed components
electrum/gui/qt/main_window.pyelectrum/gui/qml/qewallet.pyelectrum/wallet.pyInspect captured patch +45 / −36
diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py
index 314368a..443fca4 100644
--- a/electrum/gui/qml/qewallet.py
+++ b/electrum/gui/qml/qewallet.py
@@ -198,7 +198,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
self.invoiceStatusChanged.emit(key, status)
@qt_event_listener
- def on_event_new_transaction(self, wallet, tx):
+ def on_event_new_transaction(self, wallet: Abstract_Wallet, tx: Transaction):
if wallet == self.wallet:
self._logger.info(f'new transaction {tx.txid()}')
self.add_tx_notification(tx)
@@ -258,7 +258,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
def on_destroy(self):
self.unregister_callbacks()
- def add_tx_notification(self, tx):
+ def add_tx_notification(self, tx: Transaction):
self._logger.debug('new transaction event')
self.tx_notification_queue.put(tx)
if not self.notification_timer.isActive():
@@ -285,23 +285,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
except queue.Empty:
break
- config = self.wallet.config
- # Combine the transactions if there are at least three
- if len(txns) >= 3:
- total_amount = 0
- for tx in txns:
- tx_wallet_delta = self.wallet.get_wallet_delta(tx)
- if not tx_wallet_delta.is_relevant:
- continue
- total_amount += tx_wallet_delta.delta
- self.userNotify.emit(self.wallet, _("{} new transactions: Total amount received in the new transactions {}").format(len(txns), config.format_amount_and_units(total_amount)))
- else:
- for tx in txns:
- tx_wallet_delta = self.wallet.get_wallet_delta(tx)
- if not tx_wallet_delta.is_relevant:
- continue
- self.userNotify.emit(self.wallet,
- _("New transaction: {}").format(config.format_amount_and_units(tx_wallet_delta.delta)))
+ for notification in self.wallet.get_user_notifications_for_new_txns(txns):
+ self.userNotify.emit(self.wallet, notification)
def update_sync_progress(self):
if self.wallet.network and self.wallet.network.is_connected():
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
index 6b85422..993a216 100644
--- a/electrum/gui/qt/main_window.py
+++ b/electrum/gui/qt/main_window.py
@@ -474,7 +474,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
self.need_update.set()
@event_listener
- def on_event_new_transaction(self, wallet, tx):
+ def on_event_new_transaction(self, wallet: Abstract_Wallet, tx: Transaction):
if wallet == self.wallet:
self.tx_notification_queue.put(tx)
self.need_update.set()
@@ -930,22 +930,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
txns.append(self.tx_notification_queue.get_nowait())
except queue.Empty:
break
- # Combine the transactions if there are at least three
- if len(txns) >= 3:
- total_amount = 0
- for tx in txns:
- tx_wallet_delta = self.wallet.get_wallet_delta(tx)
- if not tx_wallet_delta.is_relevant:
- continue
- total_amount += tx_wallet_delta.delta
- self.notify(_("{} new transactions: Total amount received in the new transactions {}")
- .format(len(txns), self.format_amount_and_units(total_amount)))
- else:
- for tx in txns:
- tx_wallet_delta = self.wallet.get_wallet_delta(tx)
- if not tx_wallet_delta.is_relevant:
- continue
- self.notify(_("New transaction: {}").format(self.format_amount_and_units(tx_wallet_delta.delta)))
+
+ for notification in self.wallet.get_user_notifications_for_new_txns(txns):
+ self.notify(notification)
def notify(self, message):
if self.tray:
diff --git a/electrum/wallet.py b/electrum/wallet.py
index ae116e9..de34105 100644
--- a/electrum/wallet.py
+++ b/electrum/wallet.py
@@ -3691,6 +3691,43 @@ class Abstract_Wallet(ABC, Logger, EventListener):
else:
f.write(util.json_encode(txns))
+ def get_user_notifications_for_new_txns(self, txns: Sequence[Transaction]) -> Sequence[str]:
+ notifications = []
+ # Combine the transactions if there are at least three
+ if len(txns) >= 3:
+ total_amount = 0
+ total_debit = 0
+ total_credit = 0
+ for tx in txns:
+ tx_wallet_delta = self.get_wallet_delta(tx)
+ if not tx_wallet_delta.is_relevant:
+ continue
+ if tx_wallet_delta.delta < 0:
+ total_debit += -tx_wallet_delta.delta
+ else:
+ total_credit += tx_wallet_delta.delta
+ total_amount += tx_wallet_delta.delta
+ message = _('{} new transactions:').format(len(txns))
+ if total_debit:
+ message += '\n' + _('Total amount sent {}').format(self.config.format_amount_and_units(total_debit))
+ if total_credit:
+ message += '\n' + _('Total amount received {}').format(self.config.format_amount_and_units(total_credit))
+ if total_debit and total_credit:
+ message += '\n' + _('Total balance change: {}').format(self.config.format_amount_and_units(total_amount))
+ notifications.append(message)
+ else:
+ for tx in txns:
+ tx_wallet_delta = self.get_wallet_delta(tx)
+ if not tx_wallet_delta.is_relevant:
+ continue
+ if tx_wallet_delta.delta < 0:
+ message = _('sent {}').format(self.config.format_amount_and_units(-tx_wallet_delta.delta))
+ else:
+ message = _('received {}').format(self.config.format_amount_and_units(tx_wallet_delta.delta))
+ message = _("New transaction: {}").format(message)
+ notifications.append(message)
+ return notifications
+
class Simple_Wallet(Abstract_Wallet):
# wallet with a single keystore
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.