fee_dialog.py (4865B)
1 from kivy.app import App 2 from kivy.factory import Factory 3 from kivy.properties import ObjectProperty 4 from kivy.lang import Builder 5 6 from electrum.gui.kivy.i18n import _ 7 8 Builder.load_string(''' 9 <FeeDialog@Popup> 10 id: popup 11 title: _('Transaction Fees') 12 size_hint: 0.8, 0.8 13 pos_hint: {'top':0.9} 14 method: 0 15 BoxLayout: 16 orientation: 'vertical' 17 BoxLayout: 18 orientation: 'horizontal' 19 size_hint: 1, 0.5 20 Label: 21 text: _('Method') + ':' 22 Button: 23 text: _('Mempool') if root.method == 2 else _('ETA') if root.method == 1 else _('Static') 24 background_color: (0,0,0,0) 25 bold: True 26 on_release: 27 root.method = (root.method + 1) % 3 28 root.update_slider() 29 root.update_text() 30 BoxLayout: 31 orientation: 'horizontal' 32 size_hint: 1, 0.5 33 Label: 34 text: (_('Target') if root.method > 0 else _('Fee')) + ':' 35 Label: 36 id: fee_target 37 text: '' 38 Slider: 39 id: slider 40 range: 0, 4 41 step: 1 42 on_value: root.on_slider(self.value) 43 Widget: 44 size_hint: 1, 0.5 45 BoxLayout: 46 orientation: 'horizontal' 47 size_hint: 1, 0.5 48 TopLabel: 49 id: fee_estimate 50 text: '' 51 font_size: '14dp' 52 Widget: 53 size_hint: 1, 0.5 54 BoxLayout: 55 orientation: 'horizontal' 56 size_hint: 1, 0.5 57 Button: 58 text: 'Cancel' 59 size_hint: 0.5, None 60 height: '48dp' 61 on_release: popup.dismiss() 62 Button: 63 text: 'OK' 64 size_hint: 0.5, None 65 height: '48dp' 66 on_release: 67 root.on_ok() 68 root.dismiss() 69 ''') 70 71 72 73 74 class FeeSliderDialog: 75 76 def __init__(self, config, slider): 77 self.config = config 78 self.slider = slider 79 self.read_config() 80 self.update_slider() 81 82 def get_method(self): 83 dynfees = self.method > 0 84 mempool = self.method == 2 85 return dynfees, mempool 86 87 def update_slider(self): 88 dynfees, mempool = self.get_method() 89 maxp, pos, fee_rate = self.config.get_fee_slider(dynfees, mempool) 90 self.slider.range = (0, maxp) 91 self.slider.step = 1 92 self.slider.value = pos 93 94 def read_config(self): 95 mempool = self.config.use_mempool_fees() 96 dynfees = self.config.is_dynfee() 97 self.method = (2 if mempool else 1) if dynfees else 0 98 99 def save_config(self): 100 value = int(self.slider.value) 101 dynfees, mempool = self.get_method() 102 self.config.set_key('dynamic_fees', dynfees, False) 103 self.config.set_key('mempool_fees', mempool, False) 104 if dynfees: 105 if mempool: 106 self.config.set_key('depth_level', value, True) 107 else: 108 self.config.set_key('fee_level', value, True) 109 else: 110 self.config.set_key('fee_per_kb', self.config.static_fee(value), True) 111 112 def update_text(self): 113 pass 114 115 116 class FeeDialog(FeeSliderDialog, Factory.Popup): 117 118 def __init__(self, app, config, callback): 119 Factory.Popup.__init__(self) 120 FeeSliderDialog.__init__(self, config, self.ids.slider) 121 self.app = app 122 self.config = config 123 self.callback = callback 124 self.update_text() 125 126 def on_ok(self): 127 self.save_config() 128 self.callback() 129 130 def on_slider(self, value): 131 self.update_text() 132 133 def update_text(self): 134 pos = int(self.ids.slider.value) 135 dynfees, mempool = self.get_method() 136 if self.method == 2: 137 fee_rate = self.config.depth_to_fee(pos) 138 target, estimate = self.config.get_fee_text(pos, dynfees, mempool, fee_rate) 139 msg = 'In the current network conditions, in order to be positioned %s, a transaction will require a fee of %s.' % (target, estimate) 140 elif self.method == 1: 141 fee_rate = self.config.eta_to_fee(pos) 142 target, estimate = self.config.get_fee_text(pos, dynfees, mempool, fee_rate) 143 msg = 'In the last few days, transactions that confirmed %s usually paid a fee of at least %s.' % (target.lower(), estimate) 144 else: 145 fee_rate = self.config.static_fee(pos) 146 target, estimate = self.config.get_fee_text(pos, dynfees, True, fee_rate) 147 msg = 'In the current network conditions, a transaction paying %s would be positioned %s.' % (target, estimate) 148 self.ids.fee_target.text = target 149 self.ids.fee_estimate.text = msg