class PasswordDialog(AbstractPasswordDialog): enter_pw_message = _('Enter your password') enter_new_pw_message = _('Enter new password') confirm_new_pw_message = _('Confirm new password') wrong_password_message = _('Wrong password') allow_disable = False def __init__(self, app, **kwargs): AbstractPasswordDialog.__init__(self, app, **kwargs) self.hide_wallet_label = app._use_single_password def clear_password(self): self.ids.textinput_generic_password.text = '' def on_password(self, pw: str): # if not self.require_password: self.success = True self.message = _('Please wait...') self.dismiss() return # if setting new generic password, enforce min length if self.level > 0: if len(pw) < 6: self.app.show_error( _('Password is too short (min {} characters)').format(6)) return # don't enforce minimum length on existing self.do_check(pw)
def selection_changed(self, nodes): w = self.app.wallet psman = w.psman self.hide_menu() self.coins_selected = [self.utxos[i] for i in nodes] if not self.coins_selected: self.selected_str = '' self.ids.clear_btn.disabled = True return else: self.selected_str = f' ({len(self.coins_selected)})' self.ids.clear_btn.disabled = False coins = self.coins_selected if len(coins) != 1: return r = coins[0].ps_rounds if r is None: return if r == PSCoinRounds.OTHER or r >= 0: coin_value = coins[0].value_sats() if coin_value >= psman.min_new_denoms_from_coins_val: cmenu = [(_('Create New Denoms'), self.create_new_denoms)] elif coin_value >= psman.min_new_collateral_from_coins_val: cmenu = [(_('Create New Collateral'), self.create_new_collateral)] self.context_menu = ContextMenu(None, cmenu) self.cmbox.add_widget(self.context_menu)
def privatesend_txt(self, is_ps=None): if is_ps is None: is_ps = self.is_ps if is_ps: return _('PrivateSend') else: return _('Regular Transaction')
def read_invoice(self): address = str(self.address) if not address: self.app.show_error(_('Recipient not specified.') + ' ' + _('Please scan a Dash address or a payment request')) return if not self.amount: self.app.show_error(_('Please enter an amount')) return if self.is_max: amount = '!' else: try: amount = self.app.get_amount(self.amount) except: self.app.show_error(_('Invalid amount') + ':\n' + self.amount) return message = self.message if self.payment_request: outputs = self.payment_request.get_outputs() else: if not bitcoin.is_address(address): self.app.show_error(_('Invalid Dash Address') + ':\n' + address) return outputs = [PartialTxOutput.from_address_and_value(address, amount)] return self.app.wallet.create_invoice( outputs=outputs, message=message, pr=self.payment_request, URI=self.parsed_URI)
def new_request(self): amount = self.amount amount = self.app.get_amount(amount) if amount else 0 message = self.message try: addr = self.address or self.app.wallet.get_unused_address() if not addr: if not self.app.wallet.is_deterministic(): addr = self.app.wallet.get_receiving_address() else: self.app.show_info( _('No address available. Please remove some of your pending requests.' )) return self.address = addr req = self.app.wallet.make_payment_request(addr, amount, message, self.expiry()) self.app.wallet.add_payment_request(req) key = addr except InvoiceError as e: self.app.show_error( _('Error creating payment request') + ':\n' + str(e)) return self.clear() self.update() self.app.show_request(key)
def __init__(self, msg, callback, *, yes_str: str = None, no_str: str = None, title: str = None): Factory.Popup.__init__(self) self.yes_str = yes_str or _('Yes') self.no_str = no_str or _('No') self.title = title or _('Question') self.message = msg self.callback = callback
def show_keep_amount_popup(self, *args): psman = self.psman if psman.calc_denoms_method == psman.CalcDenomsMethod.ABS: self.app.show_info(_('Value is calculated from denoms count')) return if psman.state in psman.mixing_running_states: self.app.show_info(_('To change value stop mixing process')) return KeepAmountPopup(self).open()
def update_status(self): req = self.app.wallet.get_request(self.key) self.status = self.app.wallet.get_request_status(self.key) self.status_str = req.get_status_str(self.status) self.status_color = pr_color[self.status] if self.status == PR_UNPAID: address = req.get_address() if self.app.wallet.is_used(address): self.warning = _('Warning') + ': ' + _( 'This address is being reused')
def get_card(self, addr, balance, is_used, label): ci = {} ci['screen'] = self ci['address'] = addr ci['memo'] = label ci['amount'] = self.app.format_amount_and_units(balance) ci['status'] = _('Used') if is_used else _( 'Funded') if balance > 0 else _('Unused') ci['is_frozen'] = self.app.wallet.is_frozen_address(addr) return ci
def on_password(self, pw: str): # if not self.require_password: self.success = True self.message = _('Please wait...') self.dismiss() return # if setting new generic password, enforce min length if self.level > 0: if len(pw) < 6: self.app.show_error(_('Password is too short (min {} characters)').format(6)) return # don't enforce minimum length on existing self.do_check(pw)
def on_text(self, new_val): if not new_val: self.err.text = _('Missing value') self.err.subs_val = self.min_val return new_val = int(new_val) if new_val < self.min_val: self.err.text = _('Value too small') self.err.subs_val = self.min_val elif new_val > self.max_val: self.err.text = _('Value too large') self.err.subs_val = self.max_val else: self.err.text = '' self.value = new_val
def update_action_dropdown(self): action_dropdown = self.ids.action_dropdown # type: ActionDropdown # note: button texts need to be short; there is only horizontal space for ~13 chars options = ( ActionButtonOption(text=_('Sign'), func=lambda btn: self.do_sign(), enabled=self.can_sign), ActionButtonOption(text=_('Broadcast'), func=lambda btn: self.do_broadcast(), enabled=self.can_broadcast), ActionButtonOption(text=_('Remove'), func=lambda btn: self.remove_local_tx(), enabled=self.can_remove_tx), ) action_dropdown.update(options=options)
def __init__(self, app): super(PluginsDialog, self).__init__() self.app = app self.config = app.electrum_config self.network = app.network plugins = app.plugins grid = self.ids.grid for i, plugin_dict in enumerate(plugins.descriptions.values()): if plugin_dict.get('registers_keystore'): continue try: module_name = plugin_dict['__name__'] prefix, _separator, name = module_name.rpartition('.') settings_box = SettingsBox() plugin_widget = PluginWidget(app=app, name=name, fullname=plugin_dict['fullname'], settings_box=settings_box) grid.add_widget(plugin_widget) grid.add_widget(settings_box) help_text = plugin_dict['description'] requires = plugin_dict.get('requires') if requires: help_text += '\n\n' + _('Requires') + ':\n' help_text += '\n'.join(map(lambda x: x[1], requires)) plugin_help = PluginHelp(app=app, help_text=help_text) grid.add_widget(plugin_help) except Exception as e: self.logger.exception(f'cannot display plugin {name}')
def update_tx(self): try: # make unsigned transaction tx = self.make_tx() except NotEnoughFunds: self.warning = _("Not enough funds") self.ids.ok_button.disabled = True return except Exception as e: self.ids.ok_button.disabled = True self.app.logger.exception('') self.app.show_error(repr(e)) return self.ids.ok_button.disabled = False amount = self.amount if self.amount != '!' else tx.output_value() tx_size = tx.estimated_size() fee = tx.get_fee() self.ids.fee_label.text = self.app.format_amount_and_units(fee) feerate = Decimal(fee) / Decimal(tx_size) * 1000 # duffs/kB self.ids.feerate_label.text = f'{feerate:.1f} duffs/kB' self.ids.amount_label.text = self.app.format_amount_and_units(amount) x_fee = run_hook('get_tx_extra_fee', self.app.wallet, tx) if x_fee: x_fee_address, x_fee_amount = x_fee self.extra_fee = self.app.format_amount_and_units(x_fee_amount) else: self.extra_fee = '' fee_warning_tuple = self.app.wallet.get_tx_fee_warning( invoice_amt=amount, tx_size=tx_size, fee=fee) if fee_warning_tuple: allow_send, long_warning, short_warning = fee_warning_tuple self.warning = long_warning else: self.warning = '' self.tx = tx
class PincodeDialog(AbstractPasswordDialog): enter_pw_message = _('Enter your PIN') enter_new_pw_message = _('Enter new PIN') confirm_new_pw_message = _('Confirm new PIN') wrong_password_message = _('Wrong PIN') allow_disable = True def __init__(self, app, **kwargs): AbstractPasswordDialog.__init__(self, app, **kwargs) def clear_password(self): self.ids.kb.password = '' def on_password(self, pw: str): # PIN codes are exactly 6 chars if len(pw) >= 6: self.do_check(pw)
def show_log(self): if self.log: log_str = _('Payment log:') + '\n\n' for payment_attempt_log in self.log: route_str, chan_str, message = payment_attempt_log.formatted_tuple( ) log_str += chan_str + ' --- ' + message + '\n' self.app.show_info(log_str)
def start_mixing(self, prev_kp_state): def on_success(password): self.psman.start_mixing(password) def on_failure(): self.psman.keypairs_state = prev_kp_state self.app.protected(_('Start mixing'), on_success, (), on_failure)
def toggle_gather_mix_stat(self, *args): psman = self.psman if psman.state in psman.mixing_running_states: self.app.show_info(_('To change value stop mixing process')) return psman.gather_mix_stat = not psman.gather_mix_stat self.gather_mix_stat = psman.gather_mix_stat self.psdlg.info_tab.update()
def fx_status(self): fx = self.app.fx if fx.is_enabled(): source = fx.exchange.name() ccy = fx.get_currency() return '%s [%s]' %(ccy, source) else: return _('None')
def unit_dialog(self, item, dt): if self._unit_dialog is None: def cb(text): self.app._set_bu(text) item.bu = self.app.base_unit self._unit_dialog = ChoiceDialog(_('Denomination'), base_units_list, self.app.base_unit, cb, keep_choice_order=True) self._unit_dialog.open()
def expiration_dialog(self, obj): from .dialogs.choice_dialog import ChoiceDialog def callback(c): self.app.electrum_config.set_key('request_expiry', c) d = ChoiceDialog(_('Expiration date'), pr_expiration_values, self.expiry(), callback) d.open()
def coinselect_dialog(self, item, dt): if self._coinselect_dialog is None: choosers = sorted(coinchooser.COIN_CHOOSERS.keys()) chooser_name = coinchooser.get_name(self.config) def cb(text): self.config.set_key('coin_chooser', text) item.status = text self._coinselect_dialog = ChoiceDialog(_('Coin selection'), choosers, chooser_name, cb) self._coinselect_dialog.open()
def language_dialog(self, item, dt): if self._language_dialog is None: l = self.config.get('language', 'en_UK') def cb(key): self.config.set_key("language", key, True) item.lang = self.get_language_name() self.app.language = key self._language_dialog = ChoiceDialog(_('Language'), languages, l, cb) self._language_dialog.open()
def on_address(self, addr): req = self.app.wallet.get_request(addr) self.status = '' if req: self.message = req.get('memo', '') amount = req.get('amount') self.amount = self.app.format_amount_and_units(amount) if amount else '' status = req.get('status', PR_UNKNOWN) self.status = _('Payment received') if status == PR_PAID else ''
def remove_local_tx(self): txid = self.tx.txid() num_child_txs = len(self.wallet.get_depending_transactions(txid)) question = _("Are you sure you want to remove this transaction?") if num_child_txs > 0: question = (_( "Are you sure you want to remove this transaction and {} child transactions?" ).format(num_child_txs)) def on_prompt(b): if b: self.wallet.remove_transaction(txid) self.wallet.save_db() self.app._trigger_update_wallet() # FIXME private... self.dismiss() d = Question(question, on_prompt) d.open()
def __init__(self, **kwargs): Button.__init__( self, text='', disabled=True, opacity=0, **kwargs, ) self.dropdown_text = _('Options') self._on_release = None
def start_mixing(self, prev_kp_state): def on_success_pwd(password): self.psman.start_mixing(password) def on_fail_pwd(): self.psman.keypairs_state = prev_kp_state w = self.app.wallet self.app.password_dialog(w, _('Enter your PIN code to start mixing'), on_success_pwd, on_fail_pwd)
def ps_dialog(self): from .dialogs.checkbox_dialog import CheckBoxDialog def ps_dialog_cb(key): self.is_ps = key if self.is_ps: w = self.app.wallet psman = w.psman denoms_by_vals = psman.calc_denoms_by_values() if denoms_by_vals: if not psman.check_enough_sm_denoms(denoms_by_vals): psman.postpone_notification('ps-not-enough-sm-denoms', w, denoms_by_vals) self.ps_txt = self.privatesend_txt() d = CheckBoxDialog(_('PrivateSend'), _('Send coins as a PrivateSend transaction'), self.is_ps, ps_dialog_cb) d.open()
def on_currency(self, ccy): b = (ccy != _('None')) self.fx.set_enabled(b) if b: if ccy != self.fx.get_currency(): self.fx.set_currency(ccy) self.app.fiat_unit = ccy else: self.app.is_fiat = False Clock.schedule_once(lambda dt: self.add_exchanges())
def delete_dialog(self): from .question import Question def cb(result): if result: self.dismiss() self.app.wallet.delete_invoice(self.key) self.app.send_screen.update() d = Question(_('Delete invoice?'), cb) d.open()