From 37181cd3a85a2d511f2083760f285b166dce1725 Mon Sep 17 00:00:00 2001 From: f321x Date: Mon, 9 Jun 2025 16:56:11 +0200 Subject: [PATCH] disable qt swap fee slider on reverse swaps, change eta disables the fee slider in the swap dialog for reverse swaps as the tx fee for claiming is not configurable by the user. Also replaces calls to `sm.get_swap_tx_fee()` with `sm.get_fee_for_txbatcher()` as this is the correct fee estimate for claim transactions, instead of the config fee eta used by `get_swap_tx_fee()`. --- electrum/commands.py | 2 +- electrum/gui/qml/qeswaphelper.py | 4 ++-- electrum/gui/qt/swap_dialog.py | 36 ++++++++++++++++++++++++-------- electrum/submarine_swaps.py | 7 ++----- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/electrum/commands.py b/electrum/commands.py index 04e1bfc23..4594676d5 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -1943,7 +1943,7 @@ class Commands(Logger): funding_txid = None else: lightning_amount_sat = satoshis(lightning_amount) - claim_fee = sm.get_swap_tx_fee() + claim_fee = sm.get_fee_for_txbatcher() onchain_amount_sat = satoshis(onchain_amount) + claim_fee funding_txid = await wallet.lnworker.swap_manager.reverse_swap( transport, diff --git a/electrum/gui/qml/qeswaphelper.py b/electrum/gui/qml/qeswaphelper.py index d3a264885..de972853b 100644 --- a/electrum/gui/qml/qeswaphelper.py +++ b/electrum/gui/qml/qeswaphelper.py @@ -581,7 +581,7 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener): server_miningfee = swap_manager.mining_fee self.serverMiningfee = QEAmount(amount_sat=server_miningfee) if self.isReverse: - self.miningfee = QEAmount(amount_sat=swap_manager.get_swap_tx_fee()) + self.miningfee = QEAmount(amount_sat=swap_manager.get_fee_for_txbatcher()) self.check_valid(self._send_amount, self._receive_amount) else: # update tx only if slider isn't moved for a while @@ -703,7 +703,7 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener): txid = await swap_manager.reverse_swap( self.swap_transport, lightning_amount_sat=lightning_amount, - expected_onchain_amount_sat=onchain_amount + swap_manager.get_swap_tx_fee(), + expected_onchain_amount_sat=onchain_amount + swap_manager.get_fee_for_txbatcher(), ) try: # swaphelper might be destroyed at this point if txid: diff --git a/electrum/gui/qt/swap_dialog.py b/electrum/gui/qt/swap_dialog.py index 0992a13ab..72f16ab87 100644 --- a/electrum/gui/qt/swap_dialog.py +++ b/electrum/gui/qt/swap_dialog.py @@ -78,9 +78,13 @@ class SwapDialog(WindowModalDialog, QtEventListener): self.send_amount_e.setEnabled(recv_amount_sat is None) self.recv_amount_e.setEnabled(recv_amount_sat is None) self.max_button.setEnabled(recv_amount_sat is None) + self.fee_policy = FeePolicy(self.config.FEE_POLICY) - fee_slider = FeeSlider(parent=self, network=self.network, fee_policy=self.fee_policy, callback=self.fee_slider_callback) - fee_combo = FeeComboBox(fee_slider) + self.fee_slider = FeeSlider(parent=self, network=self.network, fee_policy=self.fee_policy, callback=self.fee_slider_callback) + self.fee_combo = FeeComboBox(self.fee_slider) + self.fee_target_label = QLabel() + self._set_fee_slider_visibility(is_visible=not self.is_reverse) + self.swap_limits_label = QLabel() self.fee_label = QLabel() self.server_fee_label = QLabel() @@ -100,8 +104,9 @@ class SwapDialog(WindowModalDialog, QtEventListener): h.addWidget(self.server_fee_label, 5, 1, 1, 2) h.addWidget(QLabel(_('Mining fee')+':'), 6, 0) h.addWidget(self.fee_label, 6, 1, 1, 2) - h.addWidget(fee_slider, 7, 1) - h.addWidget(fee_combo, 7, 2) + h.addWidget(self.fee_slider, 7, 1) + h.addWidget(self.fee_combo, 7, 2) + h.addWidget(self.fee_target_label, 7, 0) vbox.addLayout(h) vbox.addStretch(1) self.ok_button = OkButton(self) @@ -113,7 +118,7 @@ class SwapDialog(WindowModalDialog, QtEventListener): self.update() self.needs_tx_update = True self.window.gui_object.timer.timeout.connect(self.timer_actions) - fee_slider.update() + self.fee_slider.update() self.register_callbacks() def closeEvent(self, event): @@ -146,14 +151,28 @@ class SwapDialog(WindowModalDialog, QtEventListener): def fee_slider_callback(self, fee_rate): self.config.FEE_POLICY = self.fee_policy.get_descriptor() + if not self.is_reverse: + self.fee_target_label.setText(self.fee_policy.get_target_text()) if self.send_follows: self.on_recv_edited() else: self.on_send_edited() self.update() + def _set_fee_slider_visibility(self, *, is_visible: bool): + if is_visible: + self.fee_slider.setEnabled(True) + self.fee_combo.setEnabled(True) + self.fee_target_label.setText(self.fee_policy.get_target_text()) + else: + self.fee_slider.setEnabled(False) + self.fee_combo.setEnabled(False) + # show the eta of the swap claim + self.fee_target_label.setText(FeePolicy(self.config.FEE_POLICY_SWAPS).get_target_text()) + def toggle_direction(self): self.is_reverse = not self.is_reverse + self._set_fee_slider_visibility(is_visible=not self.is_reverse) self.send_amount_e.setAmount(None) self.recv_amount_e.setAmount(None) self.max_button.setChecked(False) @@ -222,7 +241,6 @@ class SwapDialog(WindowModalDialog, QtEventListener): self.needs_tx_update = True def update(self): - from .util import IconLabel sm = self.swap_manager w_base_unit = self.window.base_unit() send_icon = read_QIcon("lightning.png" if self.is_reverse else "bitcoin.png") @@ -266,10 +284,10 @@ class SwapDialog(WindowModalDialog, QtEventListener): """Updates self.fee_label. No other side-effects.""" if self.is_reverse: sm = self.swap_manager - fee = sm.get_swap_tx_fee() + fee = sm.get_fee_for_txbatcher() else: fee = tx.get_fee() if tx else None - fee_text = self.window.format_amount(fee) + ' ' + self.window.base_unit() if fee else '' + fee_text = self.window.format_amount(fee) + ' ' + self.window.base_unit() if fee else _("no input") self.fee_label.setText(fee_text) self.fee_label.repaint() # macOS hack for #6269 @@ -286,7 +304,7 @@ class SwapDialog(WindowModalDialog, QtEventListener): coro = sm.reverse_swap( transport, lightning_amount_sat=lightning_amount, - expected_onchain_amount_sat=onchain_amount + self.swap_manager.get_swap_tx_fee(), + expected_onchain_amount_sat=onchain_amount + self.swap_manager.get_fee_for_txbatcher(), ) try: # we must not leave the context, so we use run_couroutine_dialog diff --git a/electrum/submarine_swaps.py b/electrum/submarine_swaps.py index fa1904f6f..8770bd859 100644 --- a/electrum/submarine_swaps.py +++ b/electrum/submarine_swaps.py @@ -476,9 +476,6 @@ class SwapManager(Logger): self.logger.info('utxo value below dust threshold') return - def get_swap_tx_fee(self): - return self._get_tx_fee(self.config.FEE_POLICY) - def get_fee_for_txbatcher(self): return self._get_tx_fee(self.config.FEE_POLICY_SWAPS) @@ -1094,13 +1091,13 @@ class SwapManager(Logger): f"send_amount={send_amount} -> recv_amount={recv_amount} -> inverted_send_amount={inverted_send_amount}") # second, add on-chain claim tx fee if is_reverse and recv_amount is not None: - recv_amount -= self.get_swap_tx_fee() + recv_amount -= self.get_fee_for_txbatcher() return recv_amount def get_send_amount(self, recv_amount: Optional[int], *, is_reverse: bool) -> Optional[int]: # first, add on-chain claim tx fee if is_reverse and recv_amount is not None: - recv_amount += self.get_swap_tx_fee() + recv_amount += self.get_fee_for_txbatcher() # second, add percentage fee send_amount = self._get_send_amount(recv_amount, is_reverse=is_reverse) # sanity check calculation can be inverted