tkivy: add bump fee dialog - electrum - Electrum Bitcoin wallet (HTM) git clone https://git.parazyd.org/electrum (DIR) Log (DIR) Files (DIR) Refs (DIR) Submodules --- (DIR) commit 536a9aecde241493e92a66be939faccda00a5ab7 (DIR) parent 9896718f098174d6fcc9f81198511e7a77c61529 (HTM) Author: ThomasV <thomasv@electrum.org> Date: Thu, 9 Jun 2016 19:48:06 +0200 kivy: add bump fee dialog Diffstat: A gui/kivy/uix/dialogs/bump_fee_dial… | 108 +++++++++++++++++++++++++++++++ M gui/kivy/uix/dialogs/fee_dialog.py | 2 +- M gui/kivy/uix/dialogs/tx_dialog.py | 25 ++++++++++++++++++++++--- 3 files changed, 131 insertions(+), 4 deletions(-) --- (DIR) diff --git a/gui/kivy/uix/dialogs/bump_fee_dialog.py b/gui/kivy/uix/dialogs/bump_fee_dialog.py t@@ -0,0 +1,108 @@ +from kivy.app import App +from kivy.factory import Factory +from kivy.properties import ObjectProperty +from kivy.lang import Builder + +from electrum.bitcoin import FEE_STEP, RECOMMENDED_FEE +from electrum.util import fee_levels +from electrum_gui.kivy.i18n import _ + +Builder.load_string(''' +<BumpFeeDialog@Popup> + title: _('Bump fee') + size_hint: 0.8, 0.8 + pos_hint: {'top':0.9} + BoxLayout: + orientation: 'vertical' + + GridLayout: + height: self.minimum_height + size_hint_y: None + cols: 1 + spacing: '10dp' + BoxLabel: + id: old_fee + text: _('Fee') + value: '' + BoxLabel: + id: new_fee + text: _('New Fee') + value: '' + Label: + id: tooltip + text: '' + Slider: + id: slider + range: 0, 4 + step: 1 + on_value: root.on_slider(self.value) + Widget: + size_hint: 1, 1 + BoxLayout: + orientation: 'horizontal' + size_hint: 1, 0.5 + Button: + text: 'Cancel' + size_hint: 0.5, None + height: '48dp' + on_release: root.dismiss() + Button: + text: 'OK' + size_hint: 0.5, None + height: '48dp' + on_release: + root.dismiss() + root.on_ok() +''') + +class BumpFeeDialog(Factory.Popup): + + def __init__(self, app, fee, size, callback): + Factory.Popup.__init__(self) + self.app = app + self.init_fee = fee + self.tx_size = size + self.callback = callback + self.config = app.electrum_config + self.dynfees = self.config.get('dynamic_fees', True) and self.app.network + self.ids.old_fee.value = self.app.format_amount_and_units(self.init_fee) + self.update_slider() + self.update_text() + + def update_text(self): + value = int(self.ids.slider.value) + self.ids.new_fee.value = self.app.format_amount_and_units(self.get_fee()) + if self.dynfees: + value = int(self.ids.slider.value) + self.ids.tooltip.text = fee_levels[value] + + def update_slider(self): + slider = self.ids.slider + if self.dynfees: + slider.range = (0, 4) + slider.step = 1 + slider.value = 0 + else: + slider.range = (FEE_STEP, 2*RECOMMENDED_FEE) + slider.step = FEE_STEP + slider.value = self.init_fee*1.5 + + def get_fee(self): + value = int(self.ids.slider.value) + if self.dynfees: + dynfee = self.app.network.dynfee(value) + if dynfee: + return dynfee*self.tx_size/1000 + else: + return value*self.tx_size/1000 + + def on_ok(self): + new_fee = self.get_fee() + self.callback(self.init_fee, new_fee) + + def on_slider(self, value): + self.update_text() + + def on_checkbox(self, b): + self.dynfees = b + self.update_text() (DIR) diff --git a/gui/kivy/uix/dialogs/fee_dialog.py b/gui/kivy/uix/dialogs/fee_dialog.py t@@ -60,7 +60,7 @@ class FeeDialog(Factory.Popup): self.app = app self.config = config self.callback = callback - self.dynfees = self.config.get('dynamic_fees', False) + self.dynfees = self.config.get('dynamic_fees', True) self.ids.dynfees.active = self.dynfees self.update_slider() self.update_text() (DIR) diff --git a/gui/kivy/uix/dialogs/tx_dialog.py b/gui/kivy/uix/dialogs/tx_dialog.py t@@ -90,7 +90,7 @@ Builder.load_string(''' size_hint: 0.5, None height: '48dp' text: _('Close') - on_release: popup.dismiss() + on_release: root.dismiss() ''') t@@ -129,8 +129,27 @@ class TxDialog(Factory.Popup): self.ids.output_list.update(self.tx.outputs()) def do_rbf(self): - # not implemented - pass + from bump_fee_dialog import BumpFeeDialog + is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx) + size = self.tx.estimated_size() + d = BumpFeeDialog(self.app, fee, size, self._do_rbf) + d.open() + + def _do_rbf(self, old_fee, new_fee): + if new_fee is None: + return + delta = new_fee - old_fee + if delta < 0: + self.app.show_error("fee too low") + return + try: + new_tx = self.wallet.bump_fee(self.tx, delta) + except BaseException as e: + self.app.show_error(e) + return + self.tx = new_tx + self.update() + self.do_sign() def do_sign(self): self.app.protected(_("Enter your PIN code in order to sign this transaction"), self._do_sign, ())