def update(self): format_amount = self.app.format_amount_and_units tx_hash, self.status_str, self.description, self.can_broadcast, self.can_rbf, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info(self.tx) self.tx_hash = tx_hash or '' if timestamp: self.date_label = _('Date') self.date_str = datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] elif exp_n: self.date_label = _('Mempool depth') self.date_str = _('{} from tip').format('%.2f MB'%(exp_n/1000000)) else: self.date_label = '' self.date_str = '' if amount is None: self.amount_str = _("Transaction unrelated to your wallet") elif amount > 0: self.is_mine = False self.amount_str = format_amount(amount) else: self.is_mine = True self.amount_str = format_amount(-amount) self.fee_str = format_amount(fee) if fee is not None else _('unknown') self.can_sign = self.wallet.can_sign(self.tx) self.ids.output_list.update(self.tx.outputs())
def update(self): self.menu_actions = [(_('Use'), self.do_use), (_('Details'), self.do_view)] wallet = self.app.wallet if self.show_change == 0: _list = wallet.get_receiving_addresses() elif self.show_change == 1: _list = wallet.get_change_addresses() else: _list = wallet.get_addresses() search = self.message container = self.ids.search_container container.clear_widgets() n = 0 for address in _list: label = wallet.labels.get(address, '') balance = sum(wallet.get_addr_balance(address)) is_used = wallet.is_used(address) if self.show_used == 1 and (balance or is_used): continue if self.show_used == 2 and balance == 0: continue if self.show_used == 3 and not is_used: continue card = self.get_card(address, balance, is_used, label) if search and not self.ext_search(card, search): continue container.add_widget(card) n += 1 if not n: msg = _('No address matching your search') container.add_widget(EmptyLabel(text=msg))
def update_status(self, *dt): self.num_blocks = self.network.get_local_height() if not self.wallet: self.status = _("No Wallet") return if self.network is None or not self.network.is_running(): status = _("Offline") elif self.network.is_connected(): server_height = self.network.get_server_height() server_lag = self.network.get_local_height() - server_height if not self.wallet.up_to_date or server_height == 0: status = _("Synchronizing...") elif server_lag > 1: status = _("Server lagging") else: status = '' else: status = _("Disconnected") self.status = self.wallet.basename() + (' [size=15dp](%s)[/size]' % status if status else '') # balance c, u, x = self.wallet.get_balance() text = self.format_amount(c + x + u) self.balance = str( text.strip()) + ' [size=22dp]%s[/size]' % self.base_unit self.fiat_balance = self.fx.format_amount( c + u + x) + ' [size=22dp]%s[/size]' % self.fx.ccy
def update(self): self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.do_delete)] requests_list = self.ids.requests_container requests_list.clear_widgets() _list = self.app.wallet.get_sorted_requests(self.app.electrum_config) for pr in _list: ci = self.get_card(pr) requests_list.add_widget(ci)
def get_card(self, addr, balance, is_used, label): ci = self.cards.get(addr) if ci is None: ci = Factory.AddressItem() ci.screen = self ci.address = addr self.cards[addr] = ci 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') return ci
def _show_seed(self, label, password): if self.wallet.has_password() and password is None: return keystore = self.wallet.keystore try: seed = keystore.get_seed(password) passphrase = keystore.get_passphrase(password) except: self.show_error("Invalid PIN") return label.text = _('Seed') + ':\n' + seed if passphrase: label.text += '\n\n' + _('Passphrase') + ': ' + passphrase
def invoices_dialog(self, screen): from .uix.dialogs.invoices import InvoicesDialog if len(self.wallet.invoices.sorted_list()) == 0: self.show_info(' '.join([ _('No saved invoices.'), _('Signed invoices are saved automatically when you scan them.' ), _('You may also save unsigned requests or contact addresses using the save button.' ) ])) return popup = InvoicesDialog(self, screen, None) popup.update() popup.open()
def _sign_tx(self, tx, password, on_success, on_failure): try: self.wallet.sign_transaction(tx, password) except InvalidPassword: Clock.schedule_once(lambda dt: on_failure(_("Invalid PIN"))) return Clock.schedule_once(lambda dt: on_success(tx))
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 requests_dialog(self, screen): from .uix.dialogs.requests import RequestsDialog if len(self.wallet.get_sorted_requests(self.electrum_config)) == 0: self.show_info(_('No saved requests.')) return popup = RequestsDialog(self, screen, None) popup.update() popup.open()
def change_password(self, cb): from .uix.dialogs.password_dialog import PasswordDialog if self._password_dialog is None: self._password_dialog = PasswordDialog() message = _("Changing PIN code.") + '\n' + _("Enter your current PIN:") def on_success(old_password, new_password): self.wallet.update_password(old_password, new_password) self.show_info(_("Your PIN code was updated")) on_failure = lambda: self.show_error(_("PIN codes do not match")) self._password_dialog.init(self, self.wallet, message, on_success, on_failure, is_change=1) self._password_dialog.open()
def on_keyboard(self, instance, key, keycode, codepoint, modifiers): if key == 27 and self.is_exit is False: self.is_exit = True self.show_info(_('Press again to exit')) return True # override settings button if key in (319, 282): #f1/settings button on android #self.gui.main_gui.toggle_settings(self) return True
def label_dialog(self, obj): from .dialogs.label_dialog import LabelDialog key = obj.tx_hash text = self.app.wallet.get_label(key) def callback(text): self.app.wallet.set_label(key, text) self.update() d = LabelDialog(_('Enter Transaction Label'), text, callback) d.open()
def do_rbf(self): from .bump_fee_dialog import BumpFeeDialog is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx) if fee is None: self.app.show_error(_("Can't bump fee: unknown fee for original transaction.")) return size = self.tx.estimated_size() d = BumpFeeDialog(self.app, fee, size, self._do_rbf) d.open()
def description_dialog(self, screen): from .uix.dialogs.label_dialog import LabelDialog text = screen.message def callback(text): screen.message = text d = LabelDialog(_('Enter description'), text, callback) 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 on_address(self, addr): req = self.app.wallet.get_payment_request(addr, self.app.electrum_config) self.screen.status = '' if req: self.screen.message = req.get('memo', '') amount = req.get('amount') self.screen.amount = self.app.format_amount_and_units(amount) if amount else '' status = req.get('status', PR_UNKNOWN) self.screen.status = _('Payment received') if status == PR_PAID else '' Clock.schedule_once(lambda dt: self.update_qr())
def on_ref_label(self, label, touch): if label.touched: label.touched = False self.qr_dialog(label.name, label.data, True) else: label.touched = True self._clipboard.copy(label.data) Clock.schedule_once(lambda dt: self.show_info( _('Text copied to clipboard.\nTap again to display it as QR code.' )))
def show_info_bubble(self, text=_('Hello World'), pos=None, duration=0, arrow_pos='bottom_mid', width=None, icon='', modal=False, exit=False): '''Method to show an Information Bubble .. parameters:: text: Message to be displayed pos: position for the bubble duration: duration the bubble remains on screen. 0 = click to hide width: width of the Bubble arrow_pos: arrow position for the bubble ''' info_bubble = self.info_bubble if not info_bubble: info_bubble = self.info_bubble = Factory.InfoBubble() win = Window if info_bubble.parent: win.remove_widget(info_bubble if not info_bubble.modal else info_bubble._modal_view) if not arrow_pos: info_bubble.show_arrow = False else: info_bubble.show_arrow = True info_bubble.arrow_pos = arrow_pos img = info_bubble.ids.img if text == 'texture': # icon holds a texture not a source image # display the texture in full screen text = '' img.texture = icon info_bubble.fs = True info_bubble.show_arrow = False img.allow_stretch = True info_bubble.dim_background = True info_bubble.background_image = 'atlas://gui/kivy/theming/light/card' else: info_bubble.fs = False info_bubble.icon = icon #if img.texture and img._coreimage: # img.reload() img.allow_stretch = False info_bubble.dim_background = False info_bubble.background_image = 'atlas://data/images/defaulttheme/bubble' info_bubble.message = text if not pos: pos = (win.center[0], win.center[1] - (info_bubble.height / 2)) info_bubble.show(pos, duration, width, modal=modal, exit=exit)
def on_complete(ok, msg): if ok: self.show_info(_('Payment sent.')) if self.send_screen: self.send_screen.do_clear() if pr: self.wallet.invoices.set_paid(pr, tx.txid()) self.wallet.invoices.save() self.update_tab('invoices') else: self.show_error(msg)
def broadcast(self, tx, pr=None): def on_complete(ok, msg): if ok: self.show_info(_('Payment sent.')) if self.send_screen: self.send_screen.do_clear() if pr: self.wallet.invoices.set_paid(pr, tx.txid()) self.wallet.invoices.save() self.update_tab('invoices') else: self.show_error(msg) if self.network and self.network.is_connected(): self.show_info(_('Sending')) threading.Thread(target=self._broadcast_thread, args=(tx, on_complete)).start() else: self.show_info( _('Cannot broadcast transaction') + ':\n' + _('Not connected'))
def do_delete(self, obj): from .question import Question def cb(result): if result: self.app.wallet.invoices.remove(obj.key) self.hide_menu() self.update() d = Question(_('Delete invoice?'), cb) d.open()
def __init__(self, obj, action_list): Bubble.__init__(self) self.obj = obj for k, v in action_list: l = MenuItem() l.text = _(k) def func(f=v): Clock.schedule_once(lambda dt: f(obj), 0.15) l.on_release = func self.ids.buttons.add_widget(l)
def do_delete(self, req): from .question import Question def cb(result): if result: self.app.wallet.remove_payment_request( req.address, self.app.electrum_config) self.hide_menu() self.update() d = Question(_('Delete request'), cb) d.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 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 do_send(self): if self.screen.is_pr: if self.payment_request.has_expired(): self.app.show_error(_('Payment request has expired')) return outputs = self.payment_request.get_outputs() else: address = str(self.screen.address) if not address: self.app.show_error(_('Recipient not specified.') + ' ' + _('Please scan a Berycoin address or a payment request')) return if not bitcoin.is_address(address): self.app.show_error(_('Invalid Berycoin Address') + ':\n' + address) return try: amount = self.app.get_amount(self.screen.amount) except: self.app.show_error(_('Invalid amount') + ':\n' + self.screen.amount) return outputs = [(bitcoin.TYPE_ADDRESS, address, amount)] message = self.screen.message amount = sum(map(lambda x:x[2], outputs)) if self.app.electrum_config.get('use_rbf'): from .dialogs.question import Question d = Question(_('Should this transaction be replaceable?'), lambda b: self._do_send(amount, message, outputs, b)) d.open() else: self._do_send(amount, message, outputs, False)
def set_URI(self, text): import electrum_bery as electrum try: uri = electrum.util.parse_URI(text, self.app.on_pr) except: self.app.show_info(_("Not a Berycoin URI")) return amount = uri.get('amount') self.screen.address = uri.get('address', '') self.screen.message = uri.get('message', '') self.screen.amount = self.app.format_amount_and_units(amount) if amount else '' self.payment_request = None self.screen.is_pr = False
def choose_blockchain_dialog(self, dt): from .uix.dialogs.choice_dialog import ChoiceDialog chains = self.network.get_blockchains() def cb(name): for index, b in self.network.blockchains.items(): if name == self.network.get_blockchain_name(b): self.network.follow_chain(index) #self.block names = [self.network.blockchains[b].get_name() for b in chains] if len(names) > 1: ChoiceDialog(_('Choose your chain'), names, '', cb).open()
def export_private_keys(self, pk_label, addr): if self.wallet.is_watching_only(): self.show_info( _('This is a watching-only wallet. It does not contain private keys.' )) return def show_private_key(addr, pk_label, password): if self.wallet.has_password() and password is None: return if not self.wallet.can_export(): return try: key = str(self.wallet.export_private_key(addr, password)[0]) pk_label.data = key except InvalidPassword: self.show_error("Invalid PIN") return self.protected( _("Enter your PIN code in order to decrypt your private key"), show_private_key, (addr, pk_label))