tqt: separate module for swap_dialog - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 10fa11267d9e317431ea7cb1226776580b3230a8 DIR parent 1b1c7d1f9e836acef8b8ee3db53cde12deacc756 HTML Author: ThomasV <thomasv@electrum.org> Date: Fri, 22 May 2020 12:49:41 +0200 qt: separate module for swap_dialog Diffstat: M electrum/gui/qt/channels_list.py | 21 +++------------------ A electrum/gui/qt/swap_dialog.py | 131 +++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 18 deletions(-) --- DIR diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py t@@ -369,21 +369,6 @@ class ChannelsList(MyTreeView): self.parent.open_channel(connect_str, funding_sat, 0) def swap_dialog(self): - lnworker = self.parent.wallet.lnworker - d = WindowModalDialog(self.parent, _('Reverse Submarine Swap')) - vbox = QVBoxLayout(d) - amount_e = BTCAmountEdit(self.parent.get_decimal_point) - h = QGridLayout() - h.addWidget(QLabel('Amount'), 3, 0) - h.addWidget(amount_e, 3, 1) - vbox.addLayout(h) - ok_button = OkButton(d) - ok_button.setDefault(True) - vbox.addLayout(Buttons(CancelButton(d), ok_button)) - if not d.exec_(): - return - from electrum.submarine_swaps import reverse_swap - import asyncio - amount_sat = amount_e.get_amount() - coro = reverse_swap(amount_sat, self.parent.wallet, self.parent.network) - fut = asyncio.run_coroutine_threadsafe(coro, self.parent.network.asyncio_loop) + from .swap_dialog import SwapDialog + d = SwapDialog(self.parent) + d.run() DIR diff --git a/electrum/gui/qt/swap_dialog.py b/electrum/gui/qt/swap_dialog.py t@@ -0,0 +1,131 @@ +from PyQt5 import QtCore, QtGui +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import (QMenu, QHBoxLayout, QLabel, QVBoxLayout, QGridLayout, QLineEdit, + QPushButton, QAbstractItemView, QComboBox) +from PyQt5.QtGui import QFont, QStandardItem, QBrush + +from electrum.util import bh2u, NotEnoughFunds, NoDynamicFeeEstimates +from electrum.i18n import _ +from electrum.lnchannel import AbstractChannel, PeerState +from electrum.wallet import Abstract_Wallet +from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id, LN_MAX_FUNDING_SAT +from electrum.lnworker import LNWallet + +from .util import (MyTreeView, WindowModalDialog, Buttons, OkButton, CancelButton, + EnterButton, WaitingDialog, MONOSPACE_FONT, ColorScheme) +from .amountedit import BTCAmountEdit, FreezableLineEdit + + +from electrum import submarine_swaps as ss +import asyncio +from .util import read_QIcon + + +class SwapDialog(WindowModalDialog): + + def __init__(self, window): + WindowModalDialog.__init__(self, window, _('Submarine Swap')) + self.window = window + self.network = window.network + self.normal_fee = 0 + self.lockup_fee = 0 + self.claim_fee = 0 + self.percentage = 0 + vbox = QVBoxLayout(self) + self.send_amount_e = BTCAmountEdit(self.window.get_decimal_point) + self.recv_amount_e = BTCAmountEdit(self.window.get_decimal_point) + self.send_button = QPushButton('') + self.recv_button = QPushButton('') + self.is_reverse = False + self.toggle_direction() + self.send_amount_e.follows = False + self.recv_amount_e.follows = False + self.send_button.clicked.connect(self.toggle_direction) + self.recv_button.clicked.connect(self.toggle_direction) + self.send_amount_e.textChanged.connect(self.on_send_edited) + self.recv_amount_e.textChanged.connect(self.on_recv_edited) + h = QGridLayout() + h.addWidget(QLabel(_('You send')+':'), 2, 0) + h.addWidget(self.send_amount_e, 2, 1) + h.addWidget(self.send_button, 2, 2) + h.addWidget(QLabel(_('You receive')+':'), 3, 0) + h.addWidget(self.recv_amount_e, 3, 1) + h.addWidget(self.recv_button, 3, 2) + self.normal_fee_label = QLabel() + self.lockup_fee_label = QLabel() + self.claim_fee_label = QLabel() + h.addWidget(self.normal_fee_label, 4, 0, 1, 2) + h.addWidget(self.lockup_fee_label, 5, 0, 1, 2) + h.addWidget(self.claim_fee_label, 6, 0, 1, 2) + vbox.addLayout(h) + ok_button = OkButton(self) + ok_button.setDefault(True) + vbox.addLayout(Buttons(CancelButton(self), ok_button)) + # todo: add a fee slider for the claim tx + + def toggle_direction(self): + self.is_reverse = not self.is_reverse + self.send_button.setIcon(read_QIcon("lightning.png" if self.is_reverse else "bitcoin.png")) + self.recv_button.setIcon(read_QIcon("lightning.png" if not self.is_reverse else "bitcoin.png")) + + def on_send_edited(self): + if self.send_amount_e.follows: + return + amount = self.send_amount_e.get_amount() + self.recv_amount_e.follows = True + self.recv_amount_e.setAmount(self.get_recv_amount(amount)) + self.recv_amount_e.follows = False + + def on_recv_edited(self): + if self.recv_amount_e.follows: + return + amount = self.recv_amount_e.get_amount() + self.send_amount_e.follows = True + self.send_amount_e.setAmount(self.get_send_amount(amount)) + self.send_amount_e.follows = False + + def get_pairs(self): + fut = asyncio.run_coroutine_threadsafe(ss.get_pairs(self.network), self.network.asyncio_loop) + pairs = fut.result() + print(pairs) + fees = pairs['pairs']['BTC/BTC']['fees'] + self.percentage = fees['percentage'] + self.normal_fee = fees['minerFees']['baseAsset']['normal'] + self.lockup_fee = fees['minerFees']['baseAsset']['reverse']['lockup'] + self.claim_fee = fees['minerFees']['baseAsset']['reverse']['claim'] + self.normal_fee_label.setText(f'normal fee: {self.normal_fee}') + self.lockup_fee_label.setText(f'lockup fee: {self.lockup_fee}') + self.claim_fee_label.setText(f'claim fee: {self.claim_fee}') + + def get_recv_amount(self, send_amount): + if send_amount is None: + return + x = send_amount * (100 - self.percentage) / 100 + if self.is_reverse: + x -= self.lockup_fee + x -= self.claim_fee + else: + x -= self.normal_fee + return x + + def get_send_amount(self, recv_amount): + if not recv_amount: + return + x = recv_amount * (100 + self.percentage) / 100 + if self.is_reverse: + x += self.lockup_fee + x += self.claim_fee + else: + x += self.normal_fee + return x + + def run(self): + self.get_pairs() + if not self.exec_(): + return + amount_sat = self.send_amount_e.get_amount() + if self.is_reverse: + coro = ss.reverse_swap(amount_sat, self.window.wallet, self.network) + asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop) + else: + pass