Example #1
0
 def create_status_bar(self, parent):
     b = StatusBarButton(read_QIcon('revealer.png'),
                         "Revealer " + _("secret backup utility"),
                         partial(self.setup_dialog, parent))
     parent.addPermanentWidget(b)
Example #2
0
 def show_critical(self, msg, parent=None, title=None):
     return self.msg_box(QMessageBox.Critical, parent,
                         title or _('Critical Error'), msg)
Example #3
0
 def addCopyButton(self, app):
     self.app = app
     self.addButton(":icons/copy.png", self.on_copy, _("Copy to clipboard"))
Example #4
0
 def __init__(self, dialog, label=None):
     QPushButton.__init__(self, label or _("OK"))
     self.clicked.connect(dialog.accept)
     self.setDefault(True)
Example #5
0
 def show_warning(self, msg, parent=None, title=None):
     return self.msg_box(QMessageBox.Warning, parent,
                         title or _('Warning'), msg)
Example #6
0
else:
    MONOSPACE_FONT = 'monospace'


dialogs = []

from electrum_xzc.paymentrequest import PR_UNPAID, PR_PAID, PR_EXPIRED

pr_icons = {
    PR_UNPAID:":icons/unpaid.png",
    PR_PAID:":icons/confirmed.png",
    PR_EXPIRED:":icons/expired.png"
}

pr_tooltips = {
    PR_UNPAID:_('Pending'),
    PR_PAID:_('Paid'),
    PR_EXPIRED:_('Expired')
}

expiration_values = [
    (_('1 hour'), 60*60),
    (_('1 day'), 24*60*60),
    (_('1 week'), 7*24*60*60),
    (_('Never'), None)
]


class Timer(QThread):
    stopped = False
    timer_signal = pyqtSignal()
Example #7
0
 def __init__(self, text_getter, app):
     QPushButton.__init__(self, _("Copy"))
     self.clicked.connect(lambda: app.clipboard().setText(text_getter()))
Example #8
0
 def decrypt_message(self, sequence, message, password):
     raise RuntimeError(
         _('Encryption and decryption are not implemented by %s') %
         self.device)
Example #9
0
from electrum_xzc.i18n import _

fullname = 'KeepKey'
description = _('Provides support for KeepKey hardware wallet')
requires = [('keepkeylib', 'github.com/keepkey/python-keepkey')]
registers_keystore = ('hardware', 'keepkey', _("KeepKey wallet"))
available_for = ['qt', 'cmdline']
Example #10
0
 def change_label(self, label):
     with self.run_flow(_("Confirm the new label on your {} device")):
         trezorlib.device.apply_settings(self.client, label=label)
Example #11
0
 def change_homescreen(self, homescreen):
     with self.run_flow(
             _("Confirm on your {} device to change your home screen")):
         trezorlib.device.apply_settings(self.client, homescreen=homescreen)
Example #12
0
from electrum_xzc.i18n import _
from electrum_xzc.util import UserCancelled, UserFacingException
from electrum_xzc.keystore import bip39_normalize_passphrase
from electrum_xzc.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 as parse_path
from electrum_xzc.logging import Logger
from electrum_xzc.plugins.hw_wallet.plugin import OutdatedHwFirmwareException

from trezorlib.client import TrezorClient
from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError
from trezorlib.messages import WordRequestType, FailureType, RecoveryDeviceType
import trezorlib.btc
import trezorlib.device

MESSAGES = {
    3:
    _("Confirm the transaction output on your {} device"),
    4:
    _("Confirm internal entropy on your {} device to begin"),
    5:
    _("Write down the seed word shown on your {}"),
    6:
    _("Confirm on your {} that you want to wipe it clean"),
    7:
    _("Confirm on your {} device the message to sign"),
    8:
    _("Confirm the total amount spent and the transaction fee on your {} device"
      ),
    10:
    _("Confirm wallet address on your {} device"),
    14:
    _("Choose on your {} device where to enter your passphrase"),
Example #13
0
    def setup_dialog(self, window):
        self.wallet = window.parent().wallet
        self.update_wallet_name(self.wallet)
        self.user_input = False

        self.d = WindowModalDialog(window, "Setup Dialog")
        self.d.setMinimumWidth(500)
        self.d.setMinimumHeight(210)
        self.d.setMaximumHeight(320)
        self.d.setContentsMargins(11, 11, 1, 1)

        self.hbox = QHBoxLayout(self.d)
        vbox = QVBoxLayout()
        logo = QLabel()
        self.hbox.addWidget(logo)
        logo.setPixmap(QPixmap(icon_path('revealer.png')))
        logo.setAlignment(Qt.AlignLeft)
        self.hbox.addSpacing(16)
        vbox.addWidget(
            WWLabel(
                "<b>" + _("Revealer Secret Backup Plugin") + "</b><br>" +
                _("To encrypt your backup, first we need to load some noise.")
                + "<br/>"))
        vbox.addSpacing(7)
        bcreate = QPushButton(_("Create a new Revealer"))
        bcreate.setMaximumWidth(181)
        bcreate.setDefault(True)
        vbox.addWidget(bcreate, Qt.AlignCenter)
        self.load_noise = ScanQRTextEdit()
        self.load_noise.setTabChangesFocus(True)
        self.load_noise.textChanged.connect(self.on_edit)
        self.load_noise.setMaximumHeight(33)
        self.hbox.addLayout(vbox)
        vbox.addWidget(
            WWLabel(
                _("or type an existing revealer code below and click 'next':"))
        )
        vbox.addWidget(self.load_noise)
        vbox.addSpacing(3)
        self.next_button = QPushButton(_("Next"), self.d)
        self.next_button.setEnabled(False)
        vbox.addLayout(Buttons(self.next_button))
        self.next_button.clicked.connect(self.d.close)
        self.next_button.clicked.connect(
            partial(self.cypherseed_dialog, window))
        vbox.addWidget(
            QLabel("<b>" + _("Warning") + "</b>: " + _(
                "Each revealer should be used only once."
            ) + "<br>" + _(
                "more information at <a href=\"https://revealer.cc/faq\">https://revealer.cc/faq</a>"
            )))

        def mk_digital():
            try:
                self.make_digital(self.d)
            except Exception:
                self.logger.exception('')
            else:
                self.cypherseed_dialog(window)

        bcreate.clicked.connect(mk_digital)
        return bool(self.d.exec_())
Example #14
0
 def settings_widget(self, window):
     return EnterButton(_('Printer Calibration'),
                        partial(self.calibration_dialog, window))
Example #15
0
    def sign_message(self, sequence, message, password):
        sig = None
        try:
            message = message.encode('utf8')
            inputPath = self.get_derivation() + "/%d/%d" % sequence
            msg_hash = Hash(msg_magic(message))
            inputHash = to_hexstr(msg_hash)
            hasharray = []
            hasharray.append({'hash': inputHash, 'keypath': inputPath})
            hasharray = json.dumps(hasharray)

            msg = b'{"sign":{"meta":"sign message", "data":%s}}' % hasharray.encode(
                'utf8')

            dbb_client = self.plugin.get_client(self)

            if not dbb_client.is_paired():
                raise Exception("Could not sign message.")

            reply = dbb_client.hid_send_encrypt(msg)
            self.handler.show_message(_("Signing message ...\r\n\r\n" \
                                        "To continue, touch the Digital Bitbox's blinking light for 3 seconds.\r\n\r\n" \
                                        "To cancel, briefly touch the blinking light or wait for the timeout."))
            reply = dbb_client.hid_send_encrypt(
                msg
            )  # Send twice, first returns an echo for smart verification (not implemented)
            self.handler.finished()

            if 'error' in reply:
                raise Exception(reply['error']['message'])

            if 'sign' not in reply:
                raise Exception("Could not sign message.")

            if 'recid' in reply['sign'][0]:
                # firmware > v2.1.1
                sig = bytes([27 + int(reply['sign'][0]['recid'], 16) + 4
                             ]) + binascii.unhexlify(reply['sign'][0]['sig'])
                pk, compressed = pubkey_from_signature(sig, msg_hash)
                pk = point_to_ser(pk.pubkey.point, compressed)
                addr = public_key_to_p2pkh(pk)
                if verify_message(addr, sig, message) is False:
                    raise Exception("Could not sign message")
            elif 'pubkey' in reply['sign'][0]:
                # firmware <= v2.1.1
                for i in range(4):
                    sig = bytes([27 + i + 4]) + binascii.unhexlify(
                        reply['sign'][0]['sig'])
                    try:
                        addr = public_key_to_p2pkh(
                            binascii.unhexlify(reply['sign'][0]['pubkey']))
                        if verify_message(addr, sig, message):
                            break
                    except Exception:
                        continue
                else:
                    raise Exception("Could not sign message")

        except BaseException as e:
            self.give_error(e)
        return sig
Example #16
0
class WalletMNsModel(QAbstractTableModel):
    '''Model for wallet DIP3 masternodes.'''
    ALIAS = 0
    STATE = 1
    KEYS = 2
    SERVICE = 3
    PROTX_HASH = 4

    TOTAL_FIELDS = 5
    filterColumns = [ALIAS, SERVICE, PROTX_HASH]

    STATE_LOADING = 'Loading'
    STATE_UNREGISTERED = 'Unregistered'
    STATE_VALID = 'Valid'
    STATE_BANNED = 'PoSe Banned'
    STATE_REMOVED = 'Removed'

    STATES_TXT = {
        STATE_LOADING: _('Loading'),
        STATE_UNREGISTERED: _('Unregistered'),
        STATE_VALID: _('Valid'),
        STATE_BANNED: _('PoSe Banned'),
        STATE_REMOVED: _('Removed'),
    }

    def __init__(self, manager, mn_list, gui, row_h):
        super(WalletMNsModel, self).__init__()
        self.gui = gui
        self.manager = manager
        self.mn_list = mn_list

        sz = row_h - 10
        mode = Qt.SmoothTransformation
        imgfile = icon_path('dip3_unregistered.png')
        self.icon_unregistered = QPixmap(imgfile).scaledToWidth(sz, mode=mode)
        imgfile = icon_path('dip3_valid.png')
        self.icon_valid = QPixmap(imgfile).scaledToWidth(sz, mode=mode)
        imgfile = icon_path('dip3_banned.png')
        self.icon_banned = QPixmap(imgfile).scaledToWidth(sz, mode=mode)
        imgfile = icon_path('dip3_removed.png')
        self.icon_removed = QPixmap(imgfile).scaledToWidth(sz, mode=mode)
        imgfile = icon_path('dip3_own_op.png')
        self.icon_own_op = QPixmap(imgfile).scaledToWidth(sz, mode=mode)
        imgfile = icon_path('dip3_own.png')
        self.icon_own = QPixmap(imgfile).scaledToWidth(sz, mode=mode)
        imgfile = icon_path('dip3_op.png')
        self.icon_op = QPixmap(imgfile).scaledToWidth(sz, mode=mode)

        headers = [
            {
                Qt.DisplayRole: _('Alias')
            },
            {
                Qt.DisplayRole: _('State')
            },
            {
                Qt.DisplayRole: _('Keys')
            },
            {
                Qt.DisplayRole: _('Service')
            },
            {
                Qt.DisplayRole: _('ProRegTx hash')
            },
        ]

        for d in headers:
            d[Qt.EditRole] = d[Qt.DisplayRole]
        self.headers = headers
        self.mns = []
        self.mns_states = {}
        self.row_count = 0

    def reload_data(self):
        self.beginResetModel()
        self.mns = sorted(self.manager.mns.values(), key=lambda x: x.alias)
        protx_mns = {
            h: mn.as_dict()
            for h, mn in self.mn_list.protx_mns.items()
        }
        for mn in self.mns:
            h = mn.protx_hash

            if not h:
                self.mns_states[mn.alias] = self.STATE_UNREGISTERED
                continue

            if not self.mn_list or self.mn_list.protx_loading:
                self.mns_states[mn.alias] = self.STATE_LOADING
                continue

            protx_mn = protx_mns.get(h)
            if protx_mn:
                if protx_mn['isValid']:
                    self.mns_states[mn.alias] = self.STATE_VALID
                else:
                    self.mns_states[mn.alias] = self.STATE_BANNED
            else:
                conf = self.manager.wallet.get_tx_height(h).conf
                if conf > 0:
                    self.mns_states[mn.alias] = self.STATE_REMOVED
                else:
                    self.mns_states[mn.alias] = self.STATE_UNREGISTERED

        self.row_count = len(self.mns)
        self.endResetModel()

    def columnCount(self, parent=QModelIndex()):
        return self.TOTAL_FIELDS

    def rowCount(self, parent=QModelIndex()):
        return self.row_count

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role not in [Qt.DisplayRole]:
            return None
        if orientation != Qt.Horizontal:
            return None
        dataItem = self.headers[section]
        data = dataItem.get(role) if dataItem else None
        return QVariant(data)

    def data(self, index, role=Qt.DisplayRole):
        data = None
        if not index.isValid():
            return None

        mn = self.mns[index.row()]
        i = index.column()

        if i == self.ALIAS and role in (Qt.DisplayRole, Qt.EditRole):
            data = mn.alias
        elif i == self.STATE:
            if role == Qt.DecorationRole:
                state = self.mns_states.get(mn.alias)
                if state in [self.STATE_UNREGISTERED, self.STATE_LOADING]:
                    data = self.icon_unregistered
                elif state == self.STATE_VALID:
                    data = self.icon_valid
                elif state == self.STATE_BANNED:
                    data = self.icon_banned
                elif state == self.STATE_REMOVED:
                    data = self.icon_removed
                else:
                    data = None
            elif role == Qt.ToolTipRole:
                data = self.STATES_TXT.get(self.mns_states.get(mn.alias),
                                           'Unknown')
        elif i == self.KEYS:
            if role == Qt.DecorationRole:
                if mn.is_owned and mn.is_operated:
                    data = self.icon_own_op
                elif mn.is_owned and not mn.is_operated:
                    data = self.icon_own
                elif not mn.is_owned and mn.is_operated:
                    data = self.icon_op
                else:
                    data = None
            elif role == Qt.ToolTipRole:
                if mn.is_owned and mn.is_operated:
                    data = _('Owner and Operator private keys')
                elif mn.is_owned and not mn.is_operated:
                    data = _('Owner key')
                elif not mn.is_owned and mn.is_operated:
                    data = _('Operator privete key')
                else:
                    data = None
        elif i == self.SERVICE and role == Qt.DisplayRole:
            data = str(mn.service)
        elif i == self.PROTX_HASH and role == Qt.DisplayRole:
            data = mn.protx_hash

        return QVariant(data)

    def reload_alias(self, alias):
        idx = self.match(self.index(0, 0), Qt.DisplayRole, alias, 1,
                         Qt.MatchExactly)
        if not idx:
            return
        idx = idx[0]
        last_col_idx = idx.sibling(idx.row(), self.TOTAL_FIELDS - 1)
        self.mns = sorted(self.manager.mns.values(), key=lambda x: x.alias)
        mn = self.manager.mns[alias]
        if mn and not mn.protx_hash:
            self.mns_states[alias] = self.STATE_UNREGISTERED
        self.dataChanged.emit(idx, last_col_idx)

    def setData(self, idx, value, role):
        if role != Qt.EditRole:
            return False

        new_alias = value.strip()
        alias = self.data(idx, Qt.DisplayRole).value()
        if new_alias == alias:
            return False

        try:
            self.manager.rename_mn(alias, new_alias)
            self.mns_states[new_alias] = self.mns_states[alias]
            del self.mns_states[alias]
            self.layoutAboutToBeChanged.emit()
            self.mns = sorted(self.manager.mns.values(), key=lambda x: x.alias)
            new_row = [
                e[0] for e in enumerate(self.mns) if e[1].alias == new_alias
            ][0]
            new_idx = idx.sibling(new_row, 0)
            self.layoutChanged.emit()
            self.dataChanged.emit(new_idx, new_idx)
        except ProTxManagerExc as e:
            self.gui.show_error(str(e))
            return False
        return True

    def flags(self, idx):
        col = idx.column()
        if col != WalletMNsModel.ALIAS:
            return super(WalletMNsModel, self).flags(idx)
        else:
            return super(WalletMNsModel, self).flags(idx) | Qt.ItemIsEditable
Example #17
0
    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return

        try:
            p2pkhTransaction = True
            derivations = self.get_tx_derivations(tx)
            inputhasharray = []
            hasharray = []
            pubkeyarray = []

            # Build hasharray from inputs
            for i, txin in enumerate(tx.inputs()):
                if txin['type'] == 'coinbase':
                    self.give_error(
                        "Coinbase not supported")  # should never happen

                if txin['type'] != 'p2pkh':
                    p2pkhTransaction = False

                for x_pubkey in txin['x_pubkeys']:
                    if x_pubkey in derivations:
                        index = derivations.get(x_pubkey)
                        inputPath = "%s/%d/%d" % (self.get_derivation(),
                                                  index[0], index[1])
                        inputHash = Hash(
                            binascii.unhexlify(tx.serialize_preimage(i)))
                        hasharray_i = {
                            'hash': to_hexstr(inputHash),
                            'keypath': inputPath
                        }
                        hasharray.append(hasharray_i)
                        inputhasharray.append(inputHash)
                        break
                else:
                    self.give_error("No matching x_key for sign_transaction"
                                    )  # should never happen

            # Build pubkeyarray from outputs
            for _type, address, amount in tx.outputs():
                assert _type == TYPE_ADDRESS
                info = tx.output_info.get(address)
                if info is not None:
                    index, xpubs, m = info
                    changePath = self.get_derivation() + "/%d/%d" % index
                    changePubkey = self.derive_pubkey(index[0], index[1])
                    pubkeyarray_i = {
                        'pubkey': changePubkey,
                        'keypath': changePath
                    }
                    pubkeyarray.append(pubkeyarray_i)

            # Special serialization of the unsigned transaction for
            # the mobile verification app.
            # At the moment, verification only works for p2pkh transactions.
            if p2pkhTransaction:

                class CustomTXSerialization(Transaction):
                    @classmethod
                    def input_script(self, txin, estimate_size=False):
                        if txin['type'] == 'p2pkh':
                            return Transaction.get_preimage_script(txin)
                        if txin['type'] == 'p2sh':
                            # Multisig verification has partial support, but is disabled. This is the
                            # expected serialization though, so we leave it here until we activate it.
                            return '00' + push_script(
                                Transaction.get_preimage_script(txin))
                        raise Exception("unsupported type %s" % txin['type'])

                tx_dbb_serialized = CustomTXSerialization(
                    tx.serialize()).serialize()
            else:
                # We only need this for the signing echo / verification.
                tx_dbb_serialized = None

            # Build sign command
            dbb_signatures = []
            steps = math.ceil(1.0 * len(hasharray) / self.maxInputs)
            for step in range(int(steps)):
                hashes = hasharray[step * self.maxInputs:(step + 1) *
                                   self.maxInputs]

                msg = {
                    "sign": {
                        "data": hashes,
                        "checkpub": pubkeyarray,
                    },
                }
                if tx_dbb_serialized is not None:
                    msg["sign"]["meta"] = to_hexstr(Hash(tx_dbb_serialized))
                msg = json.dumps(msg).encode('ascii')
                dbb_client = self.plugin.get_client(self)

                if not dbb_client.is_paired():
                    raise Exception("Could not sign transaction.")

                reply = dbb_client.hid_send_encrypt(msg)
                if 'error' in reply:
                    raise Exception(reply['error']['message'])

                if 'echo' not in reply:
                    raise Exception("Could not sign transaction.")

                if self.plugin.is_mobile_paired(
                ) and tx_dbb_serialized is not None:
                    reply['tx'] = tx_dbb_serialized
                    self.plugin.comserver_post_notification(reply)

                if steps > 1:
                    self.handler.show_message(_("Signing large transaction. Please be patient ...\r\n\r\n" \
                                                "To continue, touch the Digital Bitbox's blinking light for 3 seconds. " \
                                                "(Touch " + str(step + 1) + " of " + str(int(steps)) + ")\r\n\r\n" \
                                                "To cancel, briefly touch the blinking light or wait for the timeout.\r\n\r\n"))
                else:
                    self.handler.show_message(_("Signing transaction ...\r\n\r\n" \
                                                "To continue, touch the Digital Bitbox's blinking light for 3 seconds.\r\n\r\n" \
                                                "To cancel, briefly touch the blinking light or wait for the timeout."))

                # Send twice, first returns an echo for smart verification
                reply = dbb_client.hid_send_encrypt(msg)
                self.handler.finished()

                if 'error' in reply:
                    if reply["error"].get('code') in (600, 601):
                        # aborted via LED short touch or timeout
                        raise UserCancelled()
                    raise Exception(reply['error']['message'])

                if 'sign' not in reply:
                    raise Exception("Could not sign transaction.")

                dbb_signatures.extend(reply['sign'])

            # Fill signatures
            if len(dbb_signatures) != len(tx.inputs()):
                raise Exception("Incorrect number of transactions signed."
                                )  # Should never occur
            for i, txin in enumerate(tx.inputs()):
                num = txin['num_sig']
                for pubkey in txin['pubkeys']:
                    signatures = list(filter(None, txin['signatures']))
                    if len(signatures) == num:
                        break  # txin is complete
                    ii = txin['pubkeys'].index(pubkey)
                    signed = dbb_signatures[i]
                    if 'recid' in signed:
                        # firmware > v2.1.1
                        recid = int(signed['recid'], 16)
                        s = binascii.unhexlify(signed['sig'])
                        h = inputhasharray[i]
                        pk = MyVerifyingKey.from_signature(s,
                                                           recid,
                                                           h,
                                                           curve=SECP256k1)
                        pk = to_hexstr(point_to_ser(pk.pubkey.point, True))
                    elif 'pubkey' in signed:
                        # firmware <= v2.1.1
                        pk = signed['pubkey']
                    if pk != pubkey:
                        continue
                    sig_r = int(signed['sig'][:64], 16)
                    sig_s = int(signed['sig'][64:], 16)
                    sig = sigencode_der(sig_r, sig_s,
                                        generator_secp256k1.order())
                    txin['signatures'][ii] = to_hexstr(sig) + '01'
                    tx._inputs[i] = txin
        except UserCancelled:
            raise
        except BaseException as e:
            self.give_error(e, True)
        else:
            print_error("Transaction is_complete", tx.is_complete())
            tx.raw = tx.serialize()
Example #18
0
 def create_reg_menu(self, position):
     menu = QMenu()
     h = self.reg_cur_protx
     menu.addAction(_('Details'),
                    lambda: Dip3MNInfoDialog(self, protx_hash=h).show())
     menu.exec_(self.reg_view.viewport().mapToGlobal(position))
Example #19
0
 def __init__(self, dialog):
     QPushButton.__init__(self, _("Close"))
     self.clicked.connect(dialog.close)
     self.setDefault(True)
Example #20
0
    def create_wallet_mn_tab(self):
        w = QWidget()
        hw = QWidget()

        self.w_label = QLabel(self.wallet_label())
        self.w_add_btn = QPushButton(_('Add / Import'))
        self.w_file_btn = QPushButton(_('File'))
        self.w_del_btn = QPushButton(_('Remove'))
        self.w_up_params_btn = QPushButton(_('Update Params'))
        self.w_up_coll_btn = QPushButton(_('Change Collateral'))
        self.w_protx_btn = QPushButton(_('Register'))
        self.w_up_srv_btn = QPushButton(_('Update Service'))
        self.w_up_reg_btn = QPushButton(_('Update Registrar'))
        self.w_add_btn.clicked.connect(self.on_add_masternode)
        self.w_file_btn.clicked.connect(self.on_file)
        self.w_del_btn.clicked.connect(self.on_del_masternode)
        self.w_up_params_btn.clicked.connect(self.on_update_params)
        self.w_up_coll_btn.clicked.connect(self.on_update_collateral)
        self.w_protx_btn.clicked.connect(self.on_make_pro_reg_tx)
        self.w_up_srv_btn.clicked.connect(self.on_make_pro_up_srv_tx)
        self.w_up_reg_btn.clicked.connect(self.on_make_pro_up_reg_tx)

        self.w_view = QTableView()
        self.w_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.w_view.customContextMenuRequested.connect(self.create_wallet_menu)
        self.w_hheader = QHeaderView(Qt.Horizontal, self.w_view)
        self.w_hheader.setSectionResizeMode(QHeaderView.ResizeToContents)
        self.w_hheader.setStretchLastSection(True)

        self.w_view.setHorizontalHeader(self.w_hheader)
        self.w_view.verticalHeader().hide()
        self.w_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.w_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.w_view.doubleClicked.connect(self.w_mn_dbl_clicked)

        row_h = self.w_view.verticalHeader().defaultSectionSize()
        self.w_hheader.setMinimumSectionSize(row_h)
        src_model = WalletMNsModel(self.manager, self.mn_list, self.gui, row_h)
        src_model.dataChanged.connect(self.w_data_changed)
        self.w_model = Dip3FilterProxyModel()
        self.w_model.setSourceModel(src_model)
        self.w_view.setModel(self.w_model)

        sel_model = self.w_view.selectionModel()
        sel_model.selectionChanged.connect(self.on_wallet_selection_changed)
        self.w_model.modelReset.connect(self.on_wallet_model_reset)

        hbox = QHBoxLayout()
        vbox = QVBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.addWidget(self.w_label)
        hbox.addStretch(1)
        hbox.addWidget(self.w_del_btn)
        hbox.addWidget(self.w_up_params_btn)
        hbox.addWidget(self.w_up_coll_btn)
        hbox.addWidget(self.w_protx_btn)
        hbox.addWidget(self.w_up_reg_btn)
        hbox.addWidget(self.w_up_srv_btn)
        hbox.addWidget(self.w_file_btn)
        hbox.addWidget(self.w_add_btn)
        hw.setLayout(hbox)
        vbox.addWidget(hw)
        vbox.addWidget(self.w_view)
        w.setLayout(vbox)
        self.addTab(w, read_QIcon('tab_dip3.png'), _('Wallet MNs'))
        if not self.mn_list.protx_loading:
            self.w_model.reload_data()
        return w
Example #21
0
 def __init__(self, text_getter, app, dialog):
     QPushButton.__init__(self, _("Copy and Close"))
     self.clicked.connect(lambda: app.clipboard().setText(text_getter()))
     self.clicked.connect(dialog.close)
     self.setDefault(True)
Example #22
0
    def __init__(self, parent, protx_hash=None, alias=None):
        '''
        Show information about registred Masternodes with given prot_hash,
        or Masternodes in manager with given alias.
        '''
        super(Dip3MNInfoDialog, self).__init__(parent)
        self.setMinimumSize(950, 450)
        self.setWindowIcon(read_QIcon('electrum-dash.png'))

        self.parent = parent
        self.gui = parent.gui
        self.manager = parent.manager
        self.mn_list = parent.mn_list
        self.diff_updated.connect(self.on_diff_updated)
        self.info_updated.connect(self.on_info_updated)

        if alias:
            self.mn = self.manager.mns.get(alias)
        else:
            self.mn = None

        if self.mn:
            self.protx_hash = self.mn.protx_hash
            self.setWindowTitle(_('%s Dip3 Masternode Info') % alias)
        elif protx_hash:
            self.protx_hash = protx_hash
            self.setWindowTitle(
                _('%s... Dip3 Masternode Info') % protx_hash[:32])

        if self.mn_list and self.protx_hash:
            mn_list = self.mn_list
            sml_entry = mn_list.protx_mns.get(self.protx_hash, {})
            self.diff_info = sml_entry.as_dict() if sml_entry else {}
            self.mn_list.register_callback(self.on_mn_list_diff_updated,
                                           ['mn-list-diff-updated'])
            self.mn_list.register_callback(self.on_mn_list_info_updated,
                                           ['mn-list-info-updated'])
            self.info = mn_list.protx_info.get(self.protx_hash, {})
            if not self.info and self.gui.network.is_connected():
                self.gui.network.run_from_another_thread(
                    self.gui.network.request_protx_info(self.protx_hash))
        else:
            self.diff_info = {}
            self.info = {}

        layout = QGridLayout()
        self.setLayout(layout)
        self.tabs = QTabWidget(self)
        self.close_btn = b = QPushButton(_('Close'))
        b.setDefault(True)
        b.clicked.connect(self.close)
        layout.addWidget(self.tabs, 0, 0, 1, -1)
        layout.setColumnStretch(0, 1)
        layout.addWidget(b, 1, 1)

        if self.mn:
            self.mn_tab = QWidget()
            self.mn_label = QLabel(_('Wallet Masternode: %s') % self.mn.alias)
            self.mn_view = QTextEdit()
            self.mn_view.setReadOnly(True)
            self.mn_view.setText(pformat(self.mn.as_dict()))
            mn_vbox = QVBoxLayout()
            mn_vbox.addWidget(self.mn_label)
            mn_vbox.addWidget(self.mn_view)
            self.mn_tab.setLayout(mn_vbox)
            self.tabs.addTab(self.mn_tab, _('Wallet'))
        if self.protx_hash:
            self.diff_info_tab = QWidget()
            self.diff_info_view = QTextEdit()
            self.diff_info_view.setReadOnly(True)
            self.diff_info_view.setText(pformat(self.diff_info))
            diff_info_vbox = QVBoxLayout()
            diff_info_vbox.addWidget(self.diff_info_view)
            self.diff_info_tab.setLayout(diff_info_vbox)
            self.tabs.addTab(self.diff_info_tab,
                             _('protx.diff data (merkle '
                               'root verified)'))

            self.info_tab = QWidget()
            self.info_view = QTextEdit()
            self.info_view.setReadOnly(True)
            self.info_view.setText(pformat(self.info))
            info_vbox = QVBoxLayout()
            info_vbox.addWidget(self.info_view)
            self.info_tab.setLayout(info_vbox)
            self.tabs.addTab(self.info_tab, _('protx.info data (unverified)'))
Example #23
0
 def __init__(self, dialog, label=None):
     QPushButton.__init__(self, label or _("Cancel"))
     self.clicked.connect(dialog.reject)
Example #24
0
from electrum_xzc.i18n import _

fullname = 'Coldcard Wallet'
description = 'Provides support for the Coldcard hardware wallet from Coinkite'
requires = [('ckcc-protocol', 'github.com/Coldcard/ckcc-protocol')]
registers_keystore = ('hardware', 'coldcard', _("Coldcard Wallet"))
available_for = ['qt', 'cmdline']
Example #25
0
 def show_error(self, msg, parent=None):
     return self.msg_box(QMessageBox.Warning, parent,
                         _('Error'), msg)
Example #26
0
 def transaction_dialog(self, d):
     d.cosigner_send_button = b = QPushButton(_("Send to cosigner"))
     b.clicked.connect(lambda: self.do_send(d.tx))
     d.buttons.insert(0, b)
     self.transaction_dialog_update(d)
Example #27
0
 def show_message(self, msg, parent=None, title=None):
     return self.msg_box(QMessageBox.Information, parent,
                         title or _('Information'), msg)
Example #28
0
 def decrypt_message(self, pubkey, message, password):
     raise RuntimeError(
         _('Encryption and decryption are currently not supported for %s') %
         self.device)
Example #29
0
 def on_copy(self):
     self.app.clipboard().setText(self.text())
     QToolTip.showText(QCursor.pos(), _("Text copied to clipboard"), self)
Example #30
0
    def seed_img(self, is_seed=True):

        if is_seed:
            try:
                cseed = self.get_seed()
            except UserCancelled:
                return
            except InvalidPassword as e:
                self.d.show_error(str(e))
                return
            if not cseed:
                self.d.show_message(_("This wallet has no seed"))
                return
            txt = cseed.upper()
        else:
            txt = self.txt.upper()

        img = QImage(self.SIZE[0], self.SIZE[1], QImage.Format_Mono)
        bitmap = QBitmap.fromImage(img, Qt.MonoOnly)
        bitmap.fill(Qt.white)
        painter = QPainter()
        painter.begin(bitmap)
        QFontDatabase.addApplicationFont(
            os.path.join(os.path.dirname(__file__), 'SourceSansPro-Bold.otf'))
        if len(txt) < 102:
            fontsize = 15
            linespace = 15
            max_letters = 17
            max_lines = 6
            max_words = 3
        else:
            fontsize = 12
            linespace = 10
            max_letters = 21
            max_lines = 9
            max_words = int(max_letters / 4)

        font = QFont('Source Sans Pro', fontsize, QFont.Bold)
        font.setLetterSpacing(QFont.PercentageSpacing, 100)
        font.setPixelSize(fontsize)
        painter.setFont(font)
        seed_array = txt.split(' ')

        for n in range(max_lines):
            nwords = max_words
            temp_seed = seed_array[:nwords]
            while len(' '.join(map(str, temp_seed))) > max_letters:
                nwords = nwords - 1
                temp_seed = seed_array[:nwords]
            painter.drawText(
                QRect(0, linespace * n, self.SIZE[0], self.SIZE[1]),
                Qt.AlignHCenter, ' '.join(map(str, temp_seed)))
            del seed_array[:nwords]

        painter.end()
        img = bitmap.toImage()
        if (self.rawnoise == False):
            self.make_rawnoise()

        self.make_cypherseed(img, self.rawnoise, False, is_seed)
        return img