Exemplo n.º 1
0
 def create_menu(self, position):
     item = self.itemAt(position)
     if not item:
         return
     addr = str(item.text(1))
     req = self.wallet.receive_requests.get(addr)
     if req is None:
         self.update()
         return
     column = self.currentColumn()
     column_title = self.headerItem().text(column)
     column_data = item.text(column)
     menu = QMenu(self)
     menu.addAction(
         _("Copy {}").format(column_title),
         lambda: self.parent.app.clipboard().setText(column_data))
     menu.addAction(
         _("Copy URI"), lambda: self.parent.view_and_paste(
             'URI', '', self.parent.get_request_URI(addr)))
     menu.addAction(_("Save as BIP70 file"),
                    lambda: self.parent.export_payment_request(addr))
     menu.addAction(_("Delete"),
                    lambda: self.parent.delete_payment_request(addr))
     run_hook('receive_list_menu', menu, addr)
     menu.exec_(self.viewport().mapToGlobal(position))
Exemplo n.º 2
0
    def on_start(self):
        ''' This is the start point of the kivy ui
        '''
        import time
        Logger.info('Time to on_start: {} <<<<<<<<'.format(time.clock()))
        win = Window
        win.bind(size=self.on_size, on_keyboard=self.on_keyboard)
        win.bind(on_key_down=self.on_key_down)
        #win.softinput_mode = 'below_target'
        self.on_size(win, win.size)
        self.init_ui()
        self.load_wallet_by_name(self.electrum_config.get_wallet_path())
        # init plugins
        run_hook('init_kivy', self)

        # fiat currency
        self.fiat_unit = self.fx.ccy if self.fx.is_enabled() else ''
        self.network.register_callback(self.on_quotes, ['on_quotes'])
        self.network.register_callback(self.on_history, ['on_history'])

        # default tab
        self.switch_to('history')
        # bind intent for bitcoin: URI scheme
        if platform == 'android':
            from android import activity
            from jnius import autoclass
            PythonActivity = autoclass('org.kivy.android.PythonActivity')
            mactivity = PythonActivity.mActivity
            self.on_new_intent(mactivity.getIntent())
            activity.bind(on_new_intent=self.on_new_intent)

        # URI passed in config
        uri = self.electrum_config.get('url')
        if uri:
            self.set_URI(uri)
Exemplo n.º 3
0
 def close_window(self, window):
     self.windows.remove(window)
     self.build_tray_menu()
     # save wallet path of last open window
     if not self.windows:
         self.config.save_last_wallet(window.wallet)
     run_hook('on_close_window', window)
Exemplo n.º 4
0
 def create_window_for_wallet(self, wallet):
     w = ElectrumWindow(self, wallet)
     self.windows.append(w)
     self.build_tray_menu()
     # FIXME: Remove in favour of the load_wallet hook
     run_hook('on_new_window', w)
     return w
    def update(self):

        is_relevant, is_mine, v, fee = self.wallet.get_tx_value(self.tx)
        if self.wallet.can_sign(self.tx):
            self.sign_button.show()
        else:
            self.sign_button.hide()

        if self.tx.is_complete():
            status = _("Signed")
            tx_hash = self.tx.hash()

            if tx_hash in self.wallet.transactions.keys():
                conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash)
                if timestamp:
                    time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
                else:
                    time_str = 'pending'
                status = _("%d confirmations")%conf
                self.broadcast_button.hide()
            else:
                time_str = None
                conf = 0
                self.broadcast_button.show()
        else:
            s, r = self.tx.signature_count()
            status = _("Unsigned") if s == 0 else _('Partially signed (%d/%d)'%(s,r))
            time_str = None
            self.broadcast_button.hide()
            tx_hash = 'unknown'

        self.tx_hash_e.setText(tx_hash)
        self.status_label.setText(_('Status:') + ' ' + status)

        if time_str is not None:
            self.date_label.setText(_("Date: %s")%time_str)
            self.date_label.show()
        else:
            self.date_label.hide()

        # if we are not synchronized, we cannot tell
        if self.parent.network is None or not self.parent.network.is_running() or not self.parent.network.is_connected():
            return
        if not self.wallet.up_to_date:
            return

        if is_relevant:    
            if is_mine:
                if fee is not None: 
                    self.amount_label.setText(_("Amount sent:")+' %s'% self.parent.format_amount(v-fee) + ' ' + self.parent.base_unit())
                    self.fee_label.setText(_("Transaction fee")+': %s'% self.parent.format_amount(fee) + ' ' + self.parent.base_unit())
                else:
                    self.amount_label.setText(_("Amount sent:")+' %s'% self.parent.format_amount(v) + ' ' + self.parent.base_unit())
                    self.fee_label.setText(_("Transaction fee")+': '+ _("unknown"))
            else:
                self.amount_label.setText(_("Amount received:")+' %s'% self.parent.format_amount(v) + ' ' + self.parent.base_unit())
        else:
            self.amount_label.setText(_("Transaction unrelated to your wallet"))

        run_hook('transaction_dialog_update', self)
Exemplo n.º 6
0
 def __init__(self, config, daemon, plugins):
     set_language(config.get('language'))
     # Uncomment this call to verify objects are being properly
     # GC-ed when windows are closed
     #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
     #                            ElectrumWindow], interval=5)])
     QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
     if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"):
         QtCore.QCoreApplication.setAttribute(
             QtCore.Qt.AA_ShareOpenGLContexts)
     if hasattr(QGuiApplication, 'setDesktopFileName'):
         QGuiApplication.setDesktopFileName('vialectrum.desktop')
     self.config = config
     self.daemon = daemon
     self.plugins = plugins
     self.windows = []
     self.efilter = OpenFileEventFilter(self.windows)
     self.app = QElectrumApplication(sys.argv)
     self.app.installEventFilter(self.efilter)
     self.timer = Timer()
     self.nd = None
     self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
     # init tray
     self.dark_icon = self.config.get("dark_icon", False)
     self.tray = QSystemTrayIcon(self.tray_icon(), None)
     self.tray.setToolTip('Vialectrum')
     self.tray.activated.connect(self.tray_activated)
     self.build_tray_menu()
     self.tray.show()
     self.app.new_window_signal.connect(self.start_new_window)
     run_hook('init_qt', self)
     ColorScheme.update_from_widget(QWidget())
Exemplo n.º 7
0
 def create_quote_text(self, btc_balance):
     """Return a string copy of the amount fiat currency the 
     user has in bitcoins."""
     from vialectrum.plugins import run_hook
     r = {}
     run_hook('get_fiat_balance_text', btc_balance, r)
     return r.get(0,'')
Exemplo n.º 8
0
 def __init__(self, text="", allow_multi=False):
     ButtonsTextEdit.__init__(self, text)
     self.allow_multi = allow_multi
     self.setReadOnly(0)
     self.addButton(":icons/file.png", self.file_input, _("Read file"))
     icon = ":icons/qrcode_white.png" if ColorScheme.dark_scheme else ":icons/qrcode.png"
     self.addButton(icon, self.qr_input, _("Read QR code"))
     run_hook('scan_text_edit', self)
Exemplo n.º 9
0
 def load_wallet(self, wallet):
     self.wallet = wallet
     self.update_wallet()
     # Once GUI has been initialized check if we want to announce something
     # since the callback has been called before the GUI was initialized
     if self.receive_screen:
         self.receive_screen.clear()
     self.update_tabs()
     run_hook('load_wallet', wallet, self)
Exemplo n.º 10
0
 def on_update(self):
     item = self.currentItem()
     current_key = item.data(0, Qt.UserRole).toString() if item else None
     self.clear()
     for key in sorted(self.parent.contacts.keys()):
         _type, name = self.parent.contacts[key]
         item = QTreeWidgetItem([name, key])
         item.setData(0, Qt.UserRole, key)
         self.addTopLevelItem(item)
         if key == current_key:
             self.setCurrentItem(item)
     run_hook('update_contacts_tab', self)
Exemplo n.º 11
0
 def __init__(self, parent, seed, passphrase):
     WindowModalDialog.__init__(self, parent, ('Vialectrum - ' + _('Seed')))
     self.setMinimumWidth(400)
     vbox = QVBoxLayout(self)
     title = _("Your wallet generation seed is:")
     slayout = SeedLayout(title=title,
                          seed=seed,
                          msg=True,
                          passphrase=passphrase)
     vbox.addLayout(slayout)
     run_hook('set_seed', seed, slayout.seed_e)
     vbox.addLayout(Buttons(CloseButton(self)))
Exemplo n.º 12
0
    def update(self):
        desc = self.desc
        base_unit = self.main_window.base_unit()
        format_amount = self.main_window.format_amount
        tx_hash, status, label, can_broadcast, can_rbf, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info(
            self.tx)
        size = self.tx.estimated_size()
        self.broadcast_button.setEnabled(can_broadcast)
        can_sign = not self.tx.is_complete() and \
            (self.wallet.can_sign(self.tx) or bool(self.main_window.tx_external_keypairs))
        self.sign_button.setEnabled(can_sign)
        self.tx_hash_e.setText(tx_hash or _('Unknown'))
        if desc is None:
            self.tx_desc.hide()
        else:
            self.tx_desc.setText(_("Description") + ': ' + desc)
            self.tx_desc.show()
        self.status_label.setText(_('Status:') + ' ' + status)

        if timestamp:
            time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(
                ' ')[:-3]
            self.date_label.setText(_("Date: {}").format(time_str))
            self.date_label.show()
        elif exp_n:
            text = '%.2f MB' % (exp_n / 1000000)
            self.date_label.setText(
                _('Position in mempool') + ': ' + text + ' ' + _('from tip'))
            self.date_label.show()
        else:
            self.date_label.hide()
        if amount is None:
            amount_str = _("Transaction unrelated to your wallet")
        elif amount > 0:
            amount_str = _("Amount received:"
                           ) + ' %s' % format_amount(amount) + ' ' + base_unit
        else:
            amount_str = _("Amount sent:"
                           ) + ' %s' % format_amount(-amount) + ' ' + base_unit
        size_str = _("Size:") + ' %d bytes' % size
        fee_str = _("Fee") + ': %s' % (format_amount(fee) + ' ' + base_unit
                                       if fee is not None else _('unknown'))
        if fee is not None:
            fee_rate = fee / size * 1000
            fee_str += '  ( %s ) ' % self.main_window.format_fee_rate(fee_rate)
            confirm_rate = simple_config.FEERATE_WARNING_HIGH_FEE
            if fee_rate > confirm_rate:
                fee_str += ' - ' + _('Warning') + ': ' + _("high fee") + '!'
        self.amount_label.setText(amount_str)
        self.fee_label.setText(fee_str)
        self.size_label.setText(size_str)
        run_hook('transaction_dialog_update', self)
Exemplo n.º 13
0
    def create_menu(self, position):
        from vialectrum.wallet import Multisig_Wallet
        is_multisig = isinstance(self.wallet, Multisig_Wallet)
        can_delete = self.wallet.can_delete_address()
        selected = self.selectedItems()
        multi_select = len(selected) > 1
        addrs = [item.text(0) for item in selected]
        if not addrs:
            return
        if not multi_select:
            item = self.itemAt(position)
            col = self.currentColumn()
            if not item:
                return
            addr = addrs[0]
            if not is_address(addr):
                item.setExpanded(not item.isExpanded())
                return

        menu = QMenu()
        if not multi_select:
            column_title = self.headerItem().text(col)
            copy_text = item.text(col)
            menu.addAction(_("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(copy_text))
            menu.addAction(_('Details'), lambda: self.parent.show_address(addr))
            if col in self.editable_columns:
                menu.addAction(_("Edit {}").format(column_title), lambda: self.editItem(item, col))
            menu.addAction(_("Request payment"), lambda: self.parent.receive_at(addr))
            if self.wallet.can_export():
                menu.addAction(_("Private key"), lambda: self.parent.show_private_key(addr))
            if not is_multisig and not self.wallet.is_watching_only():
                menu.addAction(_("Sign/verify message"), lambda: self.parent.sign_verify_message(addr))
                menu.addAction(_("Encrypt/decrypt message"), lambda: self.parent.encrypt_message(addr))
            if can_delete:
                menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr))
            addr_URL = block_explorer_URL(self.config, 'addr', addr)
            if addr_URL:
                menu.addAction(_("View on block explorer"), lambda: webbrowser.open(addr_URL))

            if not self.wallet.is_frozen(addr):
                menu.addAction(_("Freeze"), lambda: self.parent.set_frozen_state([addr], True))
            else:
                menu.addAction(_("Unfreeze"), lambda: self.parent.set_frozen_state([addr], False))

        coins = self.wallet.get_utxos(addrs)
        if coins:
            menu.addAction(_("Spend from"), lambda: self.parent.spend_coins(coins))

        run_hook('receive_menu', menu, addrs, self.wallet)
        menu.exec_(self.viewport().mapToGlobal(position))
Exemplo n.º 14
0
 def __init__(self, parent=None, msg=None):
     msg = msg or _('Please enter your password')
     WindowModalDialog.__init__(self, parent, _("Enter Password"))
     self.pw = pw = QLineEdit()
     pw.setEchoMode(2)
     vbox = QVBoxLayout()
     vbox.addWidget(QLabel(msg))
     grid = QGridLayout()
     grid.setSpacing(8)
     grid.addWidget(QLabel(_('Password')), 1, 0)
     grid.addWidget(pw, 1, 1)
     vbox.addLayout(grid)
     vbox.addLayout(Buttons(CancelButton(self), OkButton(self)))
     self.setLayout(vbox)
     run_hook('password_dialog', pw, grid, 1)
Exemplo n.º 15
0
    def update(self):
        desc = self.desc
        base_unit = self.main_window.base_unit()
        format_amount = self.main_window.format_amount
        tx_hash, status, label, can_broadcast, can_rbf, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info(
            self.tx)
        size = self.tx.estimated_size()
        self.broadcast_button.setEnabled(can_broadcast)
        self.sign_button.setEnabled(self.wallet.can_sign(self.tx))
        self.tx_hash_e.setText(tx_hash or _('Unknown'))
        if desc is None:
            self.tx_desc.hide()
        else:
            self.tx_desc.setText(_("Description") + ': ' + desc)
            self.tx_desc.show()
        self.status_label.setText(_('Status:') + ' ' + status)

        if timestamp:
            time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(
                ' ')[:-3]
            self.date_label.setText(_("Date: %s") % time_str)
            self.date_label.show()
        elif exp_n:
            text = '%d blocks' % (exp_n) if exp_n > 0 else _(
                'unknown (low fee)')
            self.date_label.setText(
                _('Expected confirmation time') + ': ' + text)
            self.date_label.show()
        else:
            self.date_label.hide()
        if amount is None:
            amount_str = _("Transaction unrelated to your wallet")
        elif amount > 0:
            amount_str = _("Amount received:"
                           ) + ' %s' % format_amount(amount) + ' ' + base_unit
        else:
            amount_str = _("Amount sent:"
                           ) + ' %s' % format_amount(-amount) + ' ' + base_unit
        size_str = _("Size:") + ' %d bytes' % size
        fee_str = _("Fee") + ': %s' % (format_amount(fee) + ' ' + base_unit
                                       if fee is not None else _('unknown'))
        if fee is not None:
            fee_str += '  ( %s )' % (format_amount(fee * 1000 / size) + ' ' +
                                     base_unit + '/kB')
        self.amount_label.setText(amount_str)
        self.fee_label.setText(fee_str)
        self.size_label.setText(size_str)
        run_hook('transaction_dialog_update', self)
Exemplo n.º 16
0
    def qr_input(self):
        from vialectrum.plugins import run_hook

        data = run_hook("scan_qr_hook")
        if type(data) != str:
            return
        self.setText(data)
Exemplo n.º 17
0
 def __init__(self, config, daemon, plugins):
     set_language(config.get('language'))
     # Uncomment this call to verify objects are being properly
     # GC-ed when windows are closed
     #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
     #                            ElectrumWindow], interval=5)])
     self.config = config
     self.daemon = daemon
     self.plugins = plugins
     self.windows = []
     self.efilter = OpenFileEventFilter(self.windows)
     self.app = QApplication(sys.argv)
     self.app.installEventFilter(self.efilter)
     self.timer = Timer()
     # init tray
     self.dark_icon = self.config.get("dark_icon", False)
     self.tray = QSystemTrayIcon(self.tray_icon(), None)
     self.tray.setToolTip('Vialectrum')
     self.tray.activated.connect(self.tray_activated)
     self.build_tray_menu()
     self.tray.show()
     self.app.connect(self.app, QtCore.SIGNAL('new_window'),
                      self.start_new_window)
     run_hook('init_qt', self)
Exemplo n.º 18
0
    def create_menu(self, position):
        menu = QMenu()
        selected = self.selectedItems()
        if not selected:
            menu.addAction(_("New contact"),
                           lambda: self.parent.new_contact_dialog())
            menu.addAction(_("Import file"),
                           lambda: self.parent.import_contacts())
        else:
            names = [unicode(item.text(0)) for item in selected]
            keys = [unicode(item.text(1)) for item in selected]
            column = self.currentColumn()
            column_title = self.headerItem().text(column)
            column_data = '\n'.join(
                [unicode(item.text(column)) for item in selected])
            menu.addAction(
                _("Copy %s") % column_title,
                lambda: self.parent.app.clipboard().setText(column_data))
            if column in self.editable_columns:
                menu.addAction(
                    _("Edit %s") % column_title,
                    lambda: self.editItem(item, column))
            menu.addAction(_("Pay to"),
                           lambda: self.parent.payto_contacts(keys))
            menu.addAction(_("Delete"),
                           lambda: self.parent.delete_contacts(keys))
            URLs = [
                block_explorer_URL(self.config, 'addr', key)
                for key in filter(is_address, keys)
            ]
            if URLs:
                menu.addAction(_("View on block explorer"),
                               lambda: map(webbrowser.open, URLs))

        run_hook('create_contact_menu', menu, selected)
        menu.exec_(self.viewport().mapToGlobal(position))
Exemplo n.º 19
0
    def restore_or_create(self):

        vbox = QVBoxLayout()

        main_label = QLabel(_("Vialectrum could not find an existing wallet."))
        vbox.addWidget(main_label)

        grid = QGridLayout()
        grid.setSpacing(5)

        label = QLabel(_("What do you want to do?"))
        label.setWordWrap(True)
        grid.addWidget(label, 0, 0)

        gb1 = QGroupBox()
        grid.addWidget(gb1, 0, 0)

        group1 = QButtonGroup()

        b1 = QRadioButton(gb1)
        b1.setText(_("Create new wallet"))
        b1.setChecked(True)

        b2 = QRadioButton(gb1)
        b2.setText(_("Restore an existing wallet"))

        group1.addButton(b1)
        group1.addButton(b2)

        grid.addWidget(b1, 1, 0)
        grid.addWidget(b2, 2, 0)
        vbox.addLayout(grid)

        grid2 = QGridLayout()
        grid2.setSpacing(5)

        class ClickableLabel(QLabel):
            def mouseReleaseEvent(self, ev):
                self.emit(SIGNAL('clicked()'))

        label2 = ClickableLabel(_("Wallet type:") + " [+]")
        hbox = QHBoxLayout()
        hbox.addWidget(label2)
        grid2.addLayout(hbox, 0, 0)

        gb2 = QGroupBox()
        grid.addWidget(gb2, 3, 0)
        group2 = QButtonGroup()

        self.wallet_types = [
            ('standard', _("Standard wallet"), Wallet),
            ('2of2', _("Multisig wallet (2 of 2)"), Wallet_2of2),
            ('2of3', _("Multisig wallet (2 of 3)"), Wallet_2of3)
        ]
        run_hook('add_wallet_types', self.wallet_types)

        for i, (t, l, c) in enumerate(self.wallet_types):
            button = QRadioButton(gb2)
            button.setText(l)
            grid2.addWidget(button, i + 1, 0)
            group2.addButton(button)
            group2.setId(button, i)
            if i == 0:
                button.setChecked(True)
            #else:
            #    button.setHidden(True)

        def toggle():
            buttons = group2.buttons()
            x = buttons[1].isHidden()
            label2.setText(_("Wallet type:") + (' [+]' if x else ' [-]'))
            for b in buttons[1:]:
                b.setHidden(not x)

        self.connect(label2, SIGNAL('clicked()'), toggle)
        grid2.addWidget(label2)

        vbox.addLayout(grid2)
        vbox.addStretch(1)
        hbox, button = ok_cancel_buttons2(self, _('Next'))
        vbox.addLayout(hbox)
        self.set_layout(vbox)
        self.show()
        self.raise_()
        button.setDefault(True)

        if not self.exec_():
            return None, None

        action = 'create' if b1.isChecked() else 'restore'
        wallet_type = self.wallet_types[group2.checkedId()][0]
        return action, wallet_type
Exemplo n.º 20
0
    def restore(self, t):

            if t == 'standard':
                text = self.enter_seed_dialog(MSG_ENTER_ANYTHING, None)
                if not text:
                    return
                if Wallet.is_seed(text):
                    password = self.password_dialog()
                    wallet = Wallet.from_seed(text, self.storage)
                    wallet.add_seed(text, password)
                    wallet.create_accounts(password)
                elif Wallet.is_xprv(text):
                    password = self.password_dialog()
                    wallet = Wallet.from_xprv(text, password, self.storage)
                elif Wallet.is_old_mpk(text):
                    wallet = Wallet.from_old_mpk(text, self.storage)
                elif Wallet.is_xpub(text):
                    wallet = Wallet.from_xpub(text, self.storage)
                elif Wallet.is_address(text):
                    wallet = Wallet.from_address(text, self.storage)
                elif Wallet.is_private_key(text):
                    wallet = Wallet.from_private_key(text, self.storage)
                else:
                    raise

            elif t in ['2of2']:
                r = self.multi_seed_dialog(1)
                if not r: 
                    return
                text1, text2 = r
                wallet = Wallet_2of2(self.storage)
                if Wallet.is_seed(text1) or Wallet.is_seed(text2):
                    password = self.password_dialog()
                else:
                    password = None

                if Wallet.is_seed(text1):
                    wallet.add_seed(text1, password)
                    if Wallet.is_seed(text2):
                        wallet.add_cold_seed(text2, password)
                    else:
                        wallet.add_master_public_key("cold/", text2)
                else:
                    assert Wallet.is_xpub(text1)
                    if Wallet.is_seed(text2):
                        wallet.add_seed(text2, password)
                        wallet.add_master_public_key("cold/", text1)
                    else:
                        wallet.add_master_public_key("m/", text1)
                        wallet.add_master_public_key("cold/", text2)

                wallet.create_accounts(password)


            elif t in ['2of3']:
                r = self.multi_seed_dialog(2)
                if not r: 
                    return
                text1, text2, text3 = r
                wallet = Wallet_2of3(self.storage)
                if Wallet.is_seed(text1) or Wallet.is_seed(text2) or Wallet.is_seed(text3):
                    password = self.password_dialog()
                else:
                    password = None

                if Wallet.is_seed(text1):
                    wallet.add_seed(text1, password)
                    if Wallet.is_seed(text2):
                        wallet.add_cold_seed(text2, password)
                    else:
                        wallet.add_master_public_key("cold/", text2)

                elif Wallet.is_xpub(text1):
                    if Wallet.is_seed(text2):
                        wallet.add_seed(text2, password)
                        wallet.add_master_public_key("cold/", text1)
                    else:
                        wallet.add_master_public_key("m/", text1)
                        wallet.add_master_public_key("cold/", text2)

                wallet.create_accounts(password)

            else:
                wallet = run_hook('installwizard_restore', self, self.storage)
                if not wallet:
                    return

            # create first keys offline
            self.waiting_dialog(wallet.synchronize)
                
            return wallet
Exemplo n.º 21
0
    def __init__(self, tx, parent, desc, prompt_if_unsaved):
        '''Transactions in the wallet will show their description.
        Pass desc to give a description for txs not yet in the wallet.
        '''
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        # Take a copy; it might get updated in the main window by
        # e.g. the FX plugin.  If this happens during or after a long
        # sign operation the signatures are lost.
        self.tx = copy.deepcopy(tx)
        self.tx.deserialize()
        self.main_window = parent
        self.wallet = parent.wallet
        self.prompt_if_unsaved = prompt_if_unsaved
        self.saved = False
        self.desc = desc

        self.setMinimumWidth(660)
        self.setWindowTitle(_("Transaction"))

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        vbox.addWidget(QLabel(_("Transaction ID:")))
        self.tx_hash_e = ButtonsLineEdit()
        qr_show = lambda: parent.show_qrcode(
            str(self.tx_hash_e.text()), 'Transaction ID', parent=self)
        self.tx_hash_e.addButton(":icons/qrcode.png", qr_show,
                                 _("Show as QR code"))
        self.tx_hash_e.setReadOnly(True)
        vbox.addWidget(self.tx_hash_e)
        self.tx_desc = QLabel()
        vbox.addWidget(self.tx_desc)
        self.status_label = QLabel()
        vbox.addWidget(self.status_label)
        self.date_label = QLabel()
        vbox.addWidget(self.date_label)
        self.amount_label = QLabel()
        vbox.addWidget(self.amount_label)
        self.size_label = QLabel()
        vbox.addWidget(self.size_label)
        self.fee_label = QLabel()
        vbox.addWidget(self.fee_label)

        self.add_io(vbox)

        vbox.addStretch(1)

        self.sign_button = b = QPushButton(_("Sign"))
        b.clicked.connect(self.sign)

        self.broadcast_button = b = QPushButton(_("Broadcast"))
        b.clicked.connect(self.do_broadcast)

        self.save_button = b = QPushButton(_("Save"))
        b.clicked.connect(self.save)

        self.cancel_button = b = QPushButton(_("Close"))
        b.clicked.connect(self.close)
        b.setDefault(True)

        self.qr_button = b = QPushButton()
        b.setIcon(QIcon(":icons/qrcode.png"))
        b.clicked.connect(self.show_qr)

        self.copy_button = CopyButton(lambda: str(self.tx), parent.app)

        # Action buttons
        self.buttons = [
            self.sign_button, self.broadcast_button, self.cancel_button
        ]
        # Transaction sharing buttons
        self.sharing_buttons = [
            self.copy_button, self.qr_button, self.save_button
        ]

        run_hook('transaction_dialog', self)

        hbox = QHBoxLayout()
        hbox.addLayout(Buttons(*self.sharing_buttons))
        hbox.addStretch(1)
        hbox.addLayout(Buttons(*self.buttons))
        vbox.addLayout(hbox)
        self.update()
Exemplo n.º 22
0
    def restore_or_create(self):

        vbox = QVBoxLayout()

        main_label = QLabel(_("Vialectrum could not find an existing wallet."))
        vbox.addWidget(main_label)

        grid = QGridLayout()
        grid.setSpacing(5)

        label = QLabel(_("What do you want to do?"))
        label.setWordWrap(True)
        grid.addWidget(label, 0, 0)

        gb1 = QGroupBox()
        grid.addWidget(gb1, 0, 0)

        group1 = QButtonGroup()

        b1 = QRadioButton(gb1)
        b1.setText(_("Create new wallet"))
        b1.setChecked(True)

        b2 = QRadioButton(gb1)
        b2.setText(_("Restore an existing wallet"))

        group1.addButton(b1)
        group1.addButton(b2)

        grid.addWidget(b1, 1, 0)
        grid.addWidget(b2, 2, 0)
        vbox.addLayout(grid)

        grid2 = QGridLayout()
        grid2.setSpacing(5)

        class ClickableLabel(QLabel):
            def mouseReleaseEvent(self, ev):
                self.emit(SIGNAL('clicked()'))

        label2 = ClickableLabel(_("Wallet type:") + " [+]")
        hbox = QHBoxLayout()
        hbox.addWidget(label2)
        grid2.addLayout(hbox, 0, 0)
        
        gb2 = QGroupBox()
        grid.addWidget(gb2, 3, 0)
        group2 = QButtonGroup()

        self.wallet_types = [ 
            ('standard', _("Standard wallet"),          Wallet), 
            ('2of2',     _("Multisig wallet (2 of 2)"), Wallet_2of2),
            ('2of3',     _("Multisig wallet (2 of 3)"), Wallet_2of3)
        ]
        run_hook('add_wallet_types', self.wallet_types)

        for i, (t,l,c) in enumerate(self.wallet_types):
            button = QRadioButton(gb2)
            button.setText(l)
            grid2.addWidget(button, i+1, 0)
            group2.addButton(button)
            group2.setId(button, i)
            if i==0:
                button.setChecked(True)
            #else:
            #    button.setHidden(True)


        def toggle():
            buttons = group2.buttons()
            x = buttons[1].isHidden()
            label2.setText(_("Wallet type:") + (' [+]' if x else ' [-]'))
            for b in buttons[1:]:
                b.setHidden(not x)

        self.connect(label2, SIGNAL('clicked()'), toggle)
        grid2.addWidget(label2)
 
        vbox.addLayout(grid2)
        vbox.addStretch(1)
        hbox, button = ok_cancel_buttons2(self, _('Next'))
        vbox.addLayout(hbox)
        self.set_layout(vbox)
        self.show()
        self.raise_()
        button.setDefault(True)

        if not self.exec_():
            return None, None
        
        action = 'create' if b1.isChecked() else 'restore'
        wallet_type = self.wallet_types[group2.checkedId()][0]
        return action, wallet_type
    def __init__(self, tx, parent):
        self.tx = tx
        tx_dict = tx.as_dict()
        self.parent = parent
        self.wallet = parent.wallet
            
        QDialog.__init__(self)
        self.setMinimumWidth(600)
        self.setWindowTitle(_("Transaction"))
        self.setModal(1)

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        vbox.addWidget(QLabel(_("Transaction ID:")))
        self.tx_hash_e  = QLineEdit()
        self.tx_hash_e.setReadOnly(True)
        vbox.addWidget(self.tx_hash_e)
        self.status_label = QLabel()
        vbox.addWidget(self.status_label)

        self.date_label = QLabel()
        vbox.addWidget(self.date_label)
        self.amount_label = QLabel()
        vbox.addWidget(self.amount_label)
        self.fee_label = QLabel()
        vbox.addWidget(self.fee_label)

        self.add_io(vbox)

        vbox.addStretch(1)

        self.buttons = buttons = QHBoxLayout()
        vbox.addLayout( buttons )

        buttons.addStretch(1)

        self.sign_button = b = QPushButton(_("Sign"))
        b.clicked.connect(self.sign)
        buttons.addWidget(b)

        self.broadcast_button = b = QPushButton(_("Broadcast"))
        b.clicked.connect(lambda: self.parent.broadcast_transaction(self.tx))

        b.hide()
        buttons.addWidget(b)

        self.save_button = b = QPushButton(_("Save"))
        b.clicked.connect(self.save)
        buttons.addWidget(b)

        cancelButton = QPushButton(_("Close"))
        cancelButton.clicked.connect(lambda: self.done(0))
        buttons.addWidget(cancelButton)
        cancelButton.setDefault(True)

        b = QPushButton()
        b.setIcon(QIcon(":icons/qrcode.png"))
        b.clicked.connect(self.show_qr)
        buttons.insertWidget(1,b)

        run_hook('transaction_dialog', self)
        
        self.update()
Exemplo n.º 24
0
    def run(self, action):

        if action == 'new':
            action, wallet_type = self.restore_or_create()
            self.storage.put('wallet_type', wallet_type, False)

        if action is None:
            return

        if action == 'restore':
            wallet = self.restore(wallet_type)
            if not wallet:
                return
            action = None

        else:
            wallet = Wallet(self.storage)
            action = wallet.get_action()
            # fixme: password is only needed for multiple accounts
            password = None

        while action is not None:

            util.print_error("installwizard:", wallet, action)

            if action == 'create_seed':
                seed = wallet.make_seed()
                if not self.show_seed(seed, None):
                    return
                if not self.verify_seed(seed, None):
                    return
                password = self.password_dialog()
                wallet.add_seed(seed, password)

            elif action == 'add_cosigner':
                xpub_hot = wallet.master_public_keys.get("m/")
                r = self.multi_mpk_dialog(xpub_hot, 1)
                if not r:
                    return
                xpub_cold = r[0]
                wallet.add_master_public_key("cold/", xpub_cold)

            elif action == 'add_two_cosigners':
                xpub_hot = wallet.master_public_keys.get("m/")
                r = self.multi_mpk_dialog(xpub_hot, 2)
                if not r:
                    return
                xpub1, xpub2 = r
                wallet.add_master_public_key("cold/", xpub1)
                wallet.add_master_public_key("remote/", xpub2)

            elif action == 'create_accounts':
                wallet.create_accounts(password)
                self.waiting_dialog(wallet.synchronize)

            elif action == 'create_cold_seed':
                self.create_cold_seed(wallet)
                return

            else:
                 r = run_hook('install_wizard_action', self, wallet, action)
                 if not r: 
                     raise BaseException('unknown wizard action', action)

            # next action
            action = wallet.get_action()


        if self.network:
            if self.network.interfaces:
                self.network_dialog()
            else:
                QMessageBox.information(None, _('Warning'), _('You are offline'), _('OK'))
                self.network.stop()
                self.network = None

        # start wallet threads
        wallet.start_threads(self.network)

        if action == 'restore':
            self.waiting_dialog(lambda: wallet.restore(self.waiting_label.setText))
            if self.network:
                if wallet.is_found():
                    QMessageBox.information(None, _('Information'), _("Recovery successful"), _('OK'))
                else:
                    QMessageBox.information(None, _('Information'), _("No transactions found for this seed"), _('OK'))
            else:
                QMessageBox.information(None, _('Information'), _("This wallet was restored offline. It may contain more addresses than displayed."), _('OK'))

        return wallet
Exemplo n.º 25
0
 def __init__(self, text=""):
     ButtonsTextEdit.__init__(self, text)
     self.setReadOnly(0)
     self.addButton(":icons/file.png", self.file_input, _("Read file"))
     self.addButton(":icons/qrcode.png", self.qr_input, _("Read QR code"))
     run_hook('scan_text_edit', self)
Exemplo n.º 26
0
    def restore(self, t):

        if t == 'standard':
            text = self.enter_seed_dialog(MSG_ENTER_ANYTHING, None)
            if not text:
                return
            if Wallet.is_seed(text):
                password = self.password_dialog()
                wallet = Wallet.from_seed(text, self.storage)
                wallet.add_seed(text, password)
                wallet.create_accounts(password)
            elif Wallet.is_xprv(text):
                password = self.password_dialog()
                wallet = Wallet.from_xprv(text, password, self.storage)
            elif Wallet.is_old_mpk(text):
                wallet = Wallet.from_old_mpk(text, self.storage)
            elif Wallet.is_xpub(text):
                wallet = Wallet.from_xpub(text, self.storage)
            elif Wallet.is_address(text):
                wallet = Wallet.from_address(text, self.storage)
            elif Wallet.is_private_key(text):
                wallet = Wallet.from_private_key(text, self.storage)
            else:
                raise

        elif t in ['2of2']:
            r = self.multi_seed_dialog(1)
            if not r:
                return
            text1, text2 = r
            wallet = Wallet_2of2(self.storage)
            if Wallet.is_seed(text1) or Wallet.is_seed(text2):
                password = self.password_dialog()
            else:
                password = None

            if Wallet.is_seed(text1):
                wallet.add_seed(text1, password)
                if Wallet.is_seed(text2):
                    wallet.add_cold_seed(text2, password)
                else:
                    wallet.add_master_public_key("cold/", text2)
            else:
                assert Wallet.is_xpub(text1)
                if Wallet.is_seed(text2):
                    wallet.add_seed(text2, password)
                    wallet.add_master_public_key("cold/", text1)
                else:
                    wallet.add_master_public_key("m/", text1)
                    wallet.add_master_public_key("cold/", text2)

            wallet.create_accounts(password)

        elif t in ['2of3']:
            r = self.multi_seed_dialog(2)
            if not r:
                return
            text1, text2, text3 = r
            wallet = Wallet_2of3(self.storage)
            if Wallet.is_seed(text1) or Wallet.is_seed(
                    text2) or Wallet.is_seed(text3):
                password = self.password_dialog()
            else:
                password = None

            if Wallet.is_seed(text1):
                wallet.add_seed(text1, password)
                if Wallet.is_seed(text2):
                    wallet.add_cold_seed(text2, password)
                else:
                    wallet.add_master_public_key("cold/", text2)

            elif Wallet.is_xpub(text1):
                if Wallet.is_seed(text2):
                    wallet.add_seed(text2, password)
                    wallet.add_master_public_key("cold/", text1)
                else:
                    wallet.add_master_public_key("m/", text1)
                    wallet.add_master_public_key("cold/", text2)

            wallet.create_accounts(password)

        else:
            wallet = run_hook('installwizard_restore', self, self.storage)
            if not wallet:
                return

        # create first keys offline
        self.waiting_dialog(wallet.synchronize)

        return wallet
Exemplo n.º 27
0
    def run(self, action):

        if action == 'new':
            action, wallet_type = self.restore_or_create()
            self.storage.put('wallet_type', wallet_type, False)

        if action is None:
            return

        if action == 'restore':
            wallet = self.restore(wallet_type)
            if not wallet:
                return
            action = None

        else:
            wallet = Wallet(self.storage)
            action = wallet.get_action()
            # fixme: password is only needed for multiple accounts
            password = None

        while action is not None:

            util.print_error("installwizard:", wallet, action)

            if action == 'create_seed':
                seed = wallet.make_seed()
                if not self.show_seed(seed, None):
                    return
                if not self.verify_seed(seed, None):
                    return
                password = self.password_dialog()
                wallet.add_seed(seed, password)

            elif action == 'add_cosigner':
                xpub_hot = wallet.master_public_keys.get("m/")
                r = self.multi_mpk_dialog(xpub_hot, 1)
                if not r:
                    return
                xpub_cold = r[0]
                wallet.add_master_public_key("cold/", xpub_cold)

            elif action == 'add_two_cosigners':
                xpub_hot = wallet.master_public_keys.get("m/")
                r = self.multi_mpk_dialog(xpub_hot, 2)
                if not r:
                    return
                xpub1, xpub2 = r
                wallet.add_master_public_key("cold/", xpub1)
                wallet.add_master_public_key("remote/", xpub2)

            elif action == 'create_accounts':
                wallet.create_accounts(password)
                self.waiting_dialog(wallet.synchronize)

            elif action == 'create_cold_seed':
                self.create_cold_seed(wallet)
                return

            else:
                r = run_hook('install_wizard_action', self, wallet, action)
                if not r:
                    raise BaseException('unknown wizard action', action)

            # next action
            action = wallet.get_action()

        if self.network:
            if self.network.interfaces:
                self.network_dialog()
            else:
                QMessageBox.information(None, _('Warning'),
                                        _('You are offline'), _('OK'))
                self.network.stop()
                self.network = None

        # start wallet threads
        wallet.start_threads(self.network)

        if action == 'restore':
            self.waiting_dialog(
                lambda: wallet.restore(self.waiting_label.setText))
            if self.network:
                if wallet.is_found():
                    QMessageBox.information(None, _('Information'),
                                            _("Recovery successful"), _('OK'))
                else:
                    QMessageBox.information(
                        None, _('Information'),
                        _("No transactions found for this seed"), _('OK'))
            else:
                QMessageBox.information(
                    None, _('Information'),
                    _("This wallet was restored offline. It may contain more addresses than displayed."
                      ), _('OK'))

        return wallet
Exemplo n.º 28
0
    def main(self, url):

        storage = WalletStorage(self.config)
        if storage.file_exists:
            wallet = Wallet(storage)
            action = wallet.get_action()
        else:
            action = 'new'

        if action is not None:
            import installwizard
            wizard = installwizard.InstallWizard(self.config, self.network, storage)
            wallet = wizard.run(action)
            if not wallet: 
                exit()
        else:
            wallet.start_threads(self.network)

        # init tray
        self.dark_icon = self.config.get("dark_icon", False)
        icon = QIcon(":icons/electrum_dark_icon.png") if self.dark_icon else QIcon(':icons/electrum_light_icon.png')
        self.tray = QSystemTrayIcon(icon, None)
        self.tray.setToolTip('Vialectrum')
        self.tray.activated.connect(self.tray_activated)
        self.build_tray_menu()
        self.tray.show()

        # main window
        self.main_window = w = ElectrumWindow(self.config, self.network, self)
        self.current_window = self.main_window

        #lite window
        self.init_lite()

        # initial configuration
        if self.config.get('hide_gui') is True and self.tray.isVisible():
            self.main_window.hide()
            self.lite_window.hide()
        else:
            if self.config.get('lite_mode') is True:
                self.go_lite()
            else:
                self.go_full()

        # plugins that need to change the GUI do it here
        run_hook('init')

        w.load_wallet(wallet)

        s = Timer()
        s.start()

        self.windows.append(w)
        if url: 
            self.set_url(url)

        w.app = self.app
        w.connect_slots(s)
        w.update_wallet()

        self.app.exec_()

        # clipboard persistence
        # see http://www.mail-archive.com/[email protected]/msg17328.html
        event = QtCore.QEvent(QtCore.QEvent.Clipboard)
        self.app.sendEvent(self.app.clipboard(), event)

        wallet.stop_threads()
Exemplo n.º 29
0
    def main(self, url):

        storage = WalletStorage(self.config)
        if storage.file_exists:
            wallet = Wallet(storage)
            action = wallet.get_action()
        else:
            action = 'new'

        if action is not None:
            import installwizard
            wizard = installwizard.InstallWizard(self.config, self.network,
                                                 storage)
            wallet = wizard.run(action)
            if not wallet:
                exit()
        else:
            wallet.start_threads(self.network)

        # init tray
        self.dark_icon = self.config.get("dark_icon", False)
        icon = QIcon(
            ":icons/electrum_dark_icon.png") if self.dark_icon else QIcon(
                ':icons/electrum_light_icon.png')
        self.tray = QSystemTrayIcon(icon, None)
        self.tray.setToolTip('Vialectrum')
        self.tray.activated.connect(self.tray_activated)
        self.build_tray_menu()
        self.tray.show()

        # main window
        self.main_window = w = ElectrumWindow(self.config, self.network, self)
        self.current_window = self.main_window

        #lite window
        self.init_lite()

        # initial configuration
        if self.config.get('hide_gui') is True and self.tray.isVisible():
            self.main_window.hide()
            self.lite_window.hide()
        else:
            if self.config.get('lite_mode') is True:
                self.go_lite()
            else:
                self.go_full()

        # plugins that need to change the GUI do it here
        run_hook('init')

        w.load_wallet(wallet)

        s = Timer()
        s.start()

        self.windows.append(w)
        if url:
            self.set_url(url)

        w.app = self.app
        w.connect_slots(s)
        w.update_wallet()

        self.app.exec_()

        # clipboard persistence
        # see http://www.mail-archive.com/[email protected]/msg17328.html
        event = QtCore.QEvent(QtCore.QEvent.Clipboard)
        self.app.sendEvent(self.app.clipboard(), event)

        wallet.stop_threads()
Exemplo n.º 30
0
    def __init__(self, text=None):
        ButtonsTextEdit.__init__(self, text)
        self.setReadOnly(1)
        self.addButton(":icons/qrcode.png", self.qr_show, _("Show as QR code"))

        run_hook('show_text_edit', self)
Exemplo n.º 31
0
 def qr_input(self):
     from vialectrum.plugins import run_hook
     data = run_hook('scan_qr_hook')
     if type(data) != str:
         return
     self.setText(data)