def update(self): self.menu_actions = [('Show', self.do_show), ('Details', self.do_view), ('Delete', self.do_delete)] requests_list = self.screen.ids.requests_container requests_list.clear_widgets() _list = self.app.wallet.get_sorted_requests( self.app.electrum_config) if self.app.wallet else [] for req in _list: address = req['address'] timestamp = req.get('time', 0) amount = req.get('amount') expiration = req.get('exp', None) status = req.get('status') signature = req.get('sig') ci = Factory.RequestItem() ci.address = address ci.memo = self.app.wallet.get_label(address) if amount: status = req.get('status') ci.status = request_text[status] else: received = self.app.wallet.get_addr_received(address) ci.status = self.app.format_amount_and_units(amount) ci.icon = pr_icon[status] ci.amount = self.app.format_amount_and_units( amount) if amount else _('No Amount') ci.date = format_time(timestamp) ci.screen = self requests_list.add_widget(ci) if not _list: msg = _('This screen shows the list of payment requests you made.') requests_list.add_widget(EmptyLabel(text=msg))
def do_new(self): addr = self.get_new_address() if not addr: self.app.show_info(_('Please use the existing requests first.')) else: self.save_request() self.app.show_info(_('New request added to your list.'))
def update(self): self.menu_actions = [('Pay', self.do_pay), ('Details', self.do_view), ('Delete', self.do_delete)] invoices_list = self.screen.ids.invoices_container invoices_list.clear_widgets() _list = self.app.invoices.sorted_list() for pr in _list: ci = Factory.InvoiceItem() ci.key = pr.get_id() ci.requestor = pr.get_requestor() ci.memo = pr.get_memo() amount = pr.get_amount() if amount: ci.amount = self.app.format_amount_and_units(amount) status = self.app.invoices.get_status(ci.key) ci.status = invoice_text[status] ci.icon = pr_icon[status] else: ci.amount = _('No Amount') ci.status = '' exp = pr.get_expiration_date() ci.date = format_time(exp) if exp else _('Never') ci.screen = self invoices_list.add_widget(ci) if not _list: msg = _( 'This screen shows the list of payment requests that have been sent to you. You may also use it to store contact addresses.' ) invoices_list.add_widget(EmptyLabel(text=msg))
def notify_transactions(self, *dt): if not self.network or not self.network.is_connected(): return # temporarily disabled for merge return iface = self.network ptfn = iface.pending_transactions_for_notifications if len(ptfn) > 0: # Combine the transactions if there are more then three tx_amount = len(ptfn) if(tx_amount >= 3): total_amount = 0 for tx in ptfn: is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx) if(v > 0): total_amount += v self.notify(_("{txs}s new transactions received. Total amount" "received in the new transactions {amount}s" "{unit}s").format(txs=tx_amount, amount=self.format_amount(total_amount), unit=self.base_unit())) iface.pending_transactions_for_notifications = [] else: for tx in iface.pending_transactions_for_notifications: if tx: iface.pending_transactions_for_notifications.remove(tx) is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx) if(v > 0): self.notify( _("{txs} new transaction received. {amount} {unit}"). format(txs=tx_amount, amount=self.format_amount(v), unit=self.base_unit))
def parse_history(self, items): for item in items: tx_hash, conf, value, timestamp, balance = item time_str = _("unknown") if conf > 0: try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except Exception: time_str = _("error") if conf == -1: time_str = _('Not Verified') icon = "atlas://gui/kivy/theming/light/close" elif conf == 0: time_str = _('Unconfirmed') icon = "atlas://gui/kivy/theming/light/unconfirmed" elif conf < 6: conf = max(1, conf) icon = "atlas://gui/kivy/theming/light/clock{}".format(conf) else: icon = "atlas://gui/kivy/theming/light/confirmed" label = self.app.wallet.get_label(tx_hash) if tx_hash else _( 'Pruned transaction outputs') date = timestamp_to_datetime(timestamp) quote_text = '' if self.app.fiat_unit and date: rate = run_hook('history_rate', date) if rate: s = run_hook('value_str', value, rate) quote_text = '' if s is None else s + ' ' + self.app.fiat_unit yield (conf, icon, time_str, label, value, tx_hash, quote_text)
def broadcast(self, tx, pr=None): def on_complete(ok, txid): self.show_info(txid) if ok and pr: pr.set_paid(tx.hash()) self.invoices.save() self.update_tab('invoices') 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 __init__(self, **kwargs): # initialize variables self._clipboard = Clipboard self.info_bubble = None self.nfcscanner = None self.tabs = None self.is_exit = False super(ElectrumWindow, self).__init__(**kwargs) title = _('Electrum App') self.electrum_config = config = kwargs.get('config', None) self.language = config.get('language', 'en') self.network = network = kwargs.get('network', None) self.plugins = kwargs.get('plugins', []) self.gui_object = kwargs.get('gui_object', None) #self.config = self.gui_object.config self.contacts = Contacts(self.electrum_config) self.invoices = InvoiceStore(self.electrum_config) # create triggers so as to minimize updation a max of 2 times a sec self._trigger_update_wallet =\ Clock.create_trigger(self.update_wallet, .5) self._trigger_update_status =\ Clock.create_trigger(self.update_status, .5) self._trigger_notify_transactions = \ Clock.create_trigger(self.notify_transactions, 5) # cached dialogs self._settings_dialog = None self._password_dialog = None
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 _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 update(self): if not self.screen.address: self.get_new_address() else: status = self.app.wallet.get_request_status(self.screen.address) self.screen.status = _( 'Payment received') if status == PR_PAID else ''
def update(self, see_all=False): if self.app.wallet is None: return history = self.parse_history( reversed(self.app.wallet.get_history(self.app.current_account))) # repopulate History Card history_card = self.screen.ids.history_container history_card.clear_widgets() count = 0 for item in history: count += 1 conf, icon, date_time, message, value, tx, quote_text = item ri = Factory.HistoryItem() ri.icon = icon ri.date = date_time ri.message = message ri.value = value or 0 ri.value_known = value is not None ri.quote_text = quote_text ri.confirmations = conf ri.tx_hash = tx ri.screen = self history_card.add_widget(ri) if count == 8 and not see_all: break if count == 0: msg = _( 'This screen shows your list of transactions. It is currently empty.' ) history_card.add_widget(EmptyLabel(text=msg))
def add_seed(self, text, password): def task(): self.wallet = Wallet.from_text(text, password, self.storage) self.wallet.create_main_account() self.wallet.synchronize() msg = _("Electrum is generating your addresses, please wait.") self.waiting_dialog(task, msg, self.terminate)
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 do_delete(self, obj): from dialogs.question import Question def cb(): self.app.invoices.remove(obj.key) self.app.update_tab('invoices') d = Question(_('Delete invoice?'), cb) d.open()
def _show_seed(self, label, password): if self.wallet.use_encryption and password is None: return try: seed = self.wallet.get_seed(password) except: self.show_error("Invalid PIN") return label.text = _('Seed') + ':\n' + seed
def new_wallet(self, app, dirname): def cb(text): if text: app.load_wallet_by_name(os.path.join(dirname, text)) if self.ids.wallet_selector.selection: app.load_wallet_by_name(self.ids.wallet_selector.selection[0]) else: d = LabelDialog(_('Enter wallet name'), '', cb) d.open()
def do_delete(self, obj): from dialogs.question import Question def cb(): self.app.wallet.remove_payment_request(obj.address, self.app.electrum_config) self.update() d = Question(_('Delete request?'), cb) d.open()
def _change_password(self, cb, old_password): if self.wallet.use_encryption: if old_password is None: return try: self.wallet.check_password(old_password) except InvalidPassword: self.show_error("Invalid PIN") return self.password_dialog(_('Enter new PIN'), self._change_password2, (cb, old_password,))
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 self.is_exit = False # override settings button if key in (319, 282): #f1/settings button on android #self.gui.main_gui.toggle_settings(self) return True
def update_status(self, *dt): if not self.wallet: self.status = _("No Wallet") return if self.network is None or not self.network.is_running(): self.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: self.status = _("Synchronizing...") elif server_lag > 1: self.status = _("Server lagging (%d blocks)"%server_lag) else: c, u, x = self.wallet.get_account_balance(self.current_account) text = self.format_amount(c+x+u) self.status = str(text.strip() + ' ' + self.base_unit) else: self.status = _("Not connected")
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.keys(), self.app.base_unit, cb) self._unit_dialog.open()
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 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 restore_seed(self): def on_seed(_dlg, btn): _dlg.close() if btn is _dlg.ids.back: self.run('new') return text = _dlg.get_text() self.run('enter_pin', (text, )) msg = _('Please type your seed phrase using the virtual keyboard.') RestoreSeedDialog(test=Wallet.is_seed, message=msg, on_release=on_seed).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: self.hide(), 0.1) Clock.schedule_once(lambda dt: f(obj), 0.15) l.on_release = func self.ids.buttons.add_widget(l)
def scan_qr(self, on_complete): if platform != 'android': return from jnius import autoclass from android import activity PythonActivity = autoclass('org.renpy.android.PythonActivity') Intent = autoclass('android.content.Intent') intent = Intent("com.google.zxing.client.android.SCAN") intent.putExtra("SCAN_MODE", "QR_CODE_MODE") def on_qr_result(requestCode, resultCode, intent): if requestCode == 0: if resultCode == -1: # RESULT_OK: contents = intent.getStringExtra("SCAN_RESULT") if intent.getStringExtra("SCAN_RESULT_FORMAT") == 'QR_CODE': on_complete(contents) else: self.show_error("wrong format " + intent.getStringExtra("SCAN_RESULT_FORMAT")) activity.bind(on_activity_result=on_qr_result) try: PythonActivity.mActivity.startActivityForResult(intent, 0) except: self.show_error(_('Could not start Barcode Scanner.') + ' ' + _('Please install the Barcode Scanner app from ZXing'))
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 = unicode(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 set_URI(self, text): import electrum_ion try: uri = electrum.util.parse_URI(text, self.app.on_pr) except: self.app.show_info(_("Not a Bitcoin 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 restore_xpub(self): def on_xpub(_dlg, btn): _dlg.close() if btn is _dlg.ids.back: self.run('new') return text = _dlg.get_text() self.run('add_seed', (text, None)) msg = _( 'To create a watching-only wallet, paste your master public key, or scan it using the camera button.' ) RestoreXpubDialog(test=Wallet.is_mpk, message=msg, on_release=on_xpub).open()