def scan_qr(self, on_complete): flag = True try: if platform != 'android': return from jnius import autoclass from android import activity flag = False except Exception as e: pass finally: if flag: self.show_info(_('Please install the Barcode Scanner app')) PythonActivity = autoclass('org.kivy.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'))
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 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 CommerciumElectro address or a payment request' )) return if not bitcoin.is_address(address): self.app.show_error( _('Invalid CommerciumElectro 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)) self._do_send(amount, message, outputs)
def update(self): format_amount = self.app.format_amount_and_units tx_hash, self.status_str, self.description, self.can_broadcast, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info( self.tx) self.tx_hash = tx_hash or '' if timestamp: self.date_str = datetime.fromtimestamp(timestamp).isoformat( ' ')[:-3] elif exp_n: self.date_str = _('Within %d blocks') % exp_n if exp_n > 0 else _( 'unknown (low fee)') else: 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 derivation_dialog_other(self, f, default_derivation): message = '\n'.join([ _('Enter your wallet derivation here.'), _('If you are not sure what this is, leave this field unchanged.') ]) self.line_dialog(run_next=f, title=_('Derivation'), message=message, default=default_derivation, test=bitcoin.is_bip32_derivation)
def derivation_dialog(self, f): default = bip44_derivation(0) message = '\n'.join([ _('Enter your wallet derivation here.'), _('If you are not sure what this is, leave this field unchanged.'), _("If you want the wallet to use legacy CommerciumElectro addresses use m/44'/0'/0'"), _("If you want the wallet to use Bitcoin Cash addresses use m/44'/145'/0'") ]) self.line_dialog(run_next=f, title=_('Derivation'), message=message, default=default, test=bitcoin.is_bip32_derivation)
def _change_password(self, cb, old_password): if self.wallet.has_password(): 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 confirm_passphrase(self, seed, passphrase): f = lambda x: self.run('create_keystore', seed, x) if passphrase: title = _('Confirm Seed Extension') message = '\n'.join([ _('Your seed extension must be saved together with your seed.'), _('Please type it here.'), ]) self.line_dialog(run_next=f, title=title, message=message, default='', test=lambda x: x == passphrase) else: f('')
def restore_from_key(self): if self.wallet_type == 'standard': v = keystore.is_master_key title = _("Create keystore from a master key") message = ' '.join([ _("To create a watching-only wallet, please enter your master public key (xpub/ypub/zpub)."), _("To create a spending wallet, please enter a master private key (xprv/yprv/zprv).") ]) self.add_xpub_dialog(title=title, message=message, run_next=self.on_restore_from_key, is_valid=v) else: i = len(self.keystores) + 1 self.add_cosigner_dialog(index=i, run_next=self.on_restore_from_key, is_valid=keystore.is_bip32_key)
def passphrase_dialog(self, run_next): title = _('Seed extension') message = '\n'.join([ _('You may extend your seed with custom words.'), _('Your seed extension must be saved together with your seed.'), ]) warning = '\n'.join([ _('Note that this is NOT your encryption password.'), _('If you do not know what this is, leave this field empty.'), ]) self.line_dialog(title=title, message=message, warning=warning, default='', test=lambda x: True, run_next=run_next)
def new(self): name = os.path.basename(self.storage.path) title = _("Create") + ' ' + name message = '\n'.join([ _("What kind of wallet do you want to create ?") ]) wallet_kinds = [ ('standard', _("Standard wallet")), # ('multisig', _("Multi-signature wallet")), ('imported', _("Import CommerciumElectro addresses or private keys")), ] choices = [pair for pair in wallet_kinds if pair[0] in wallet_types] self.choice_dialog(title=title, message=message, choices=choices, run_next=self.on_wallet_type)
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 get_card(self, tx_hash, height, conf, timestamp, value, balance): status, status_str = self.app.wallet.get_tx_status( tx_hash, height, conf, timestamp) icon = "atlas://gui/kivy/theming/light/" + TX_ICONS[status] label = self.app.wallet.get_label(tx_hash) if tx_hash else _( 'Pruned transaction outputs') date = timestamp_to_datetime(timestamp) ri = self.cards.get(tx_hash) if ri is None: ri = Factory.HistoryItem() ri.screen = self ri.tx_hash = tx_hash self.cards[tx_hash] = ri ri.icon = icon ri.date = status_str ri.message = label ri.value = value or 0 amount = self.app.format_amount(value, True) if value is not None else '--' ri.amount = amount[:-1] if amount.endswith(".") else amount ri.confirmations = conf if self.app.fiat_unit and date: rate = self.app.fx.history_rate(date) if rate: s = self.app.fx.value_str(value, rate) ri.quote_text = '' if s is None else s + ' ' + self.app.fiat_unit return ri
def update(self): self.menu_actions = [('Receive', self.do_show), ('Details', self.do_view)] wallet = self.app.wallet if not hasattr(wallet, 'change_addresses'): wallet.change_addresses = [] if not hasattr(wallet, 'receiving_addresses'): wallet.receiving_addresses = [] _list = wallet.change_addresses if self.screen.show_change else wallet.receiving_addresses search = self.screen.message container = self.screen.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.screen.show_used == 1 and (balance or is_used): continue if self.screen.show_used == 2 and balance == 0: continue if self.screen.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(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 on_qr(self, data): from commerciumelectro.bitcoin import base_decode, is_address data = data.strip() if is_address(data): self.set_URI(data) return if data.startswith('cmm:'): self.set_URI(data) return # try to decode transaction from commerciumelectro.transaction import Transaction from commerciumelectro.util import bh2u try: text = bh2u(base_decode(data, None, base=43)) tx = Transaction(text) tx.deserialize() if self.wallet: my_coins = self.wallet.get_spendable_coins(None, self.electrum_config) my_outpoints = [vin['prevout_hash'] + ':' + str(vin['prevout_n']) for vin in my_coins] for i, txin in enumerate(tx.inputs()): outpoint = txin['prevout_hash'] + ':' + str(txin['prevout_n']) if outpoint in my_outpoints: my_index = my_outpoints.index(outpoint) tx._inputs[i]['value'] = my_coins[my_index]['value'] except: tx = None if tx: self.tx_dialog(tx) return # show error self.show_error(_("Unable to decode QR data"))
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 __init__(self, wizard, **kwargs): super(RestoreSeedDialog, self).__init__(wizard, **kwargs) self._test = kwargs['test'] from commerciumelectro.mnemonic import Mnemonic from commerciumelectro.old_mnemonic import words as old_wordlist self.words = set(Mnemonic('en').wordlist).union(set(old_wordlist)) self.ids.text_input_seed.text = test_seed if is_test else '' self.message = _('Please type your seed phrase using the virtual keyboard.') self.title = _('Enter Seed') self.ext = False # Modifying the style of the input method for line in [self.ids.line1, self.ids.line2, self.ids.line3]: for c in line.children: if isinstance(c, Button): c.font_size = '20sp' c.font_name = 'gui/kivy/data/fonts/SourceHanSansK-Bold.ttf'
def create_addresses(self): def task(): self.wallet.synchronize() self.wallet.storage.write() self.terminate() msg = _("CommerciumElectro wallet is generating your addresses, please wait.") self.waiting_dialog(task, msg)
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"))
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 Clock.schedule_once(lambda dt: self.add_exchanges())
def request_password(self, run_next): def callback(pin): if pin: self.run('confirm_password', pin, run_next) else: run_next(None, None) self.password_dialog(_('Choose a PIN code'), callback)
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 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 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 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 export_private_keys(self, pk_label, addr): def show_private_key(addr, pk_label, password): if self.wallet.has_password() and password is None: return key = str(self.wallet.export_private_key(addr, password)[0]) pk_label.data = key self.protected(_("Enter your PIN code in order to decrypt your private key"), show_private_key, (addr, pk_label))
def confirm_password(self, pin, run_next): def callback(conf): if conf == pin: run_next(pin, False) else: self.show_error(_('PIN mismatch')) self.run('request_password', run_next) self.password_dialog(_('Confirm your PIN code'), callback)
def do_delete(self, obj): from .dialogs.question import Question def cb(result): if result: self.app.wallet.invoices.remove(obj.key) self.app.update_tab('invoices') d = Question(_('Delete invoice?'), cb) d.open()
def description_dialog(self, screen, title="Enter description"): if title == "Enter description": title = _("Enter description") from .uix.dialogs.label_dialog import LabelDialog text = screen.message def callback(text): screen.message = text d = LabelDialog(title, text, callback) d.open()