Beispiel #1
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.import_contacts())
        else:
            names = [item.text(0) for item in selected]
            keys = [item.text(1) for item in selected]
            column = self.currentColumn()
            column_title = self.headerItem().text(column)
            column_data = '\n'.join([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:
                item = self.currentItem()
                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 = [
                web.BE_URL(self.config, 'addr', Address.from_string(key))
                for key in keys if Address.is_valid(key)
            ]
            if URLs:
                menu.addAction(_("View on block explorer"),
                               lambda: [webbrowser.open(URL) for URL in URLs])

        run_hook('create_contact_menu', menu, selected)
        menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #2
0
 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 Bitcoin address or a payment request'))
             return
         if not Address.is_valid(address):
             self.app.show_error(
                 _('Invalid Bitcoin 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.from_string(address),
                     amount)]
     message = self.screen.message
     amount = sum(map(lambda x: x[2], outputs))
     self._do_send(amount, message, outputs)
Beispiel #3
0
def build_contact_tx_list(address : Address) -> list:
    parent = gui.ElectrumGui.gui
    ret = list()
    if isinstance(address, Address) and parent and parent.sigHistory:
        alltxs = parent.sigHistory.get(None)
        seen = set() # 'seen' set.. guard against the same address appearing in both inputs and outputs
        for hentry in alltxs:
            if hentry.tx:
                ins = hentry.tx.inputs()
                for x in ins:
                    xa = x['address']
                    if isinstance(xa, PublicKey):
                        xa = xa.toAddress()
                    if isinstance(xa, Address) and xa.to_storage_string() == address.to_storage_string() and hentry.tx_hash not in seen:
                        ret.append(hentry)
                        seen.add(hentry.tx_hash)
                        break
                outs = hentry.tx.get_outputs()
                for x in outs:
                    xa, dummy = x
                    if isinstance(xa, Address) and xa.to_storage_string() == address.to_storage_string() and hentry.tx_hash not in seen:
                        ret.append(hentry)
                        seen.add(hentry.tx_hash)
                        break
    #print("build_contact_tx_list: address", address.to_ui_string(), "found", len(ret),"associated txs")
    return ret
Beispiel #4
0
def get_contacts() -> list:
    ''' Builds a list of
        ContactsEntry tuples:
        
        ContactsEntry = namedtuple("ContactsEntry", "name address address_str hist_entries")

    '''
    t0 = time.time()
    parent = gui.ElectrumGui.gui
    wallet = parent.wallet
    if wallet is None:
        utils.NSLog("get_contacts: wallent was None, returning early")
        return list()
    c = wallet.contacts
    contacts = list()
    for addr,tupl in c.items():
        typ, name = tupl
        if typ == 'address' and Address.is_valid(addr):
            address = Address.from_string(addr)
            hist_entries = build_contact_tx_list(address)
            entry = ContactsEntry(name, address, addr, hist_entries)
            contacts.append(entry)    
    contacts.sort(key=lambda x: [x.name, x.address_str], reverse=False)
    utils.NSLog("get_contacts: fetched %d contacts in %f ms",len(contacts), (time.time()-t0)*1000.0)
    return contacts
Beispiel #5
0
 def invoke(firstarg='0.0.0.0',
            sport='8787',
            upnp_str=None,
            addr_str=None):
     bindhost, *extrahosts = firstarg.split(',')
     if len(extrahosts) > 1:
         raise Exception("too many hosts")
     elif len(extrahosts) == 1:
         [
             announcehost,
         ] = extrahosts
     else:
         announcehost = None
     port = int(sport)
     pnp = get_upnp() if upnp_str == 'upnp' else None
     if not pnp and not addr_str:
         # third arg may be addr_str, so swap the args
         addr_str = upnp_str
         upnp_str = None
     addr = None
     if addr_str:
         assert Address.is_valid(
             addr_str), "Invalid donation address specified"
         addr = Address.from_string(addr_str)
     return self.start_fusion_server(network,
                                     bindhost,
                                     port,
                                     upnp=pnp,
                                     announcehost=announcehost,
                                     donation_address=addr)
Beispiel #6
0
 def doCB() -> None:
     cb = utils.get_callback(self, 'on_ok')
     if callable(cb):
         entry = None
         if name and address_str and Address.is_valid(address_str):
             address = Address.from_string(address_str)
             entry = ContactsEntry(name, address, address_str)
         cb(entry)
     self.autorelease()
Beispiel #7
0
 def donation_address(self, window) -> Optional[Tuple[str, Address]]:
     ''' Plugin API: Returns a tuple of (description, Address) or None. This
     is the donation address that we as a client got from the remote server
     (as opposed to the donation address we announce if we are a server). '''
     if self.remote_donation_address and Address.is_valid(
             self.remote_donation_address):
         return (self.fullname() + " " + _("Server") + ": " +
                 self.get_server()[0],
                 Address.from_string(self.remote_donation_address))
Beispiel #8
0
 def delete_history(self, address: Address) -> None:
     if isinstance(address, str) and Address.is_valid(address):
         address = Address.from_string(address)
     storage = self.parent.wallet.storage if self.parent.wallet else None
     if storage:
         with self.lock:
             addrstr = address.to_storage_string()
             k = 'contact_history_%s' % (addrstr)
             storage.put(k, None)
             self.print_error("Deleted %s" % addrstr)
 def toggle_cashaddr(self, on = None):
     was = self.is_cashaddr()
     if on is None:
         on = not was
     else:
         on = bool(on)
     self.config.set_key('show_cashaddr', on)
     Address.show_cashaddr(on)
     if was != on:
         self.cashaddr_toggled_signal.emit()
Beispiel #10
0
def are_addresses_identical(addr1: str, addr2: str) -> bool:
    """Compare 2 addresses. These addresses can be of a different format.

    :param addr1:
    :param addr2:
    :return:
    """
    addr1 = Address.from_string(addr1)
    addr2 = Address.from_string(addr2)
    fmt = Address.FMT_LEGACY
    return addr1.to_string(fmt) == addr2.to_string(fmt)
Beispiel #11
0
 def open_link(link):
     if Address.is_valid(link):
         addr = Address.from_string(link)
         if wallet.is_mine(addr):
             parent.show_address(addr)
         else:
             addr_URL = web.BE_URL(parent.config, 'addr', addr)
             if addr_URL:
                 webopen(addr_URL)
         return
     if link.startswith('http'):
         webopen(link)
Beispiel #12
0
 def get_history(self, address: Address) -> list:
     ret = list()
     if isinstance(address, str) and Address.is_valid(address):
         address = Address.from_string(address)
     storage = self.parent.wallet.storage if self.parent.wallet else None
     if storage:
         addrstr = address.to_storage_string()
         k = 'contact_history_%s' % (addrstr)
         hdict = storage.get(k)
         if hdict:
             ret = list(hdict.values())
             ret.sort(key=lambda x: x[1], reverse=True)
     return ret
Beispiel #13
0
 def set_payment_address(address):
     self.payto_edit.payto_address = bitcoin.TYPE_ADDRESS, Address.from_string(
         address)
     self.value_payto_outputs = self.payto_edit.get_outputs(False)
     contact_name = None
     if address in window.wallet.contacts.keys():
         contact_type, contact_name = window.wallet.contacts[address]
     if contact_name is not None:
         self.payto_edit.setText(contact_name + ' <' + address + '>')
     else:
         if Address.is_valid(address):
             address = Address.from_string(address).to_ui_string()
         self.payto_edit.setText(address)
Beispiel #14
0
 def _open_internal_link(self, target):
     ''' accepts either a str txid, str address, or a QUrl which should be
     of the bare form "txid" and/or "address" -- used by the clickable
     links in the inputs/outputs QTextBrowsers'''
     if isinstance(target, QUrl):
         target = target.toString(QUrl.None_)
     assert target
     if Address.is_valid(target):
         # target was an address, open address dialog
         self.main_window.show_address(Address.from_string(target), parent=self)
     else:
         # target was a txid, open new tx dialog
         self.main_window.do_process_from_txid(txid=target, parent=self)
Beispiel #15
0
 def doReloadForKey(self, key: Any) -> Any:
     t0 = time.time()
     hist = list()
     unk = False
     duped = ''
     if isinstance(key, (type(None), list)):
         # the common case, 'None' or [Address]
         hist = get_history(domain=key)
     # contacts entires
     elif isinstance(key, contacts.ContactsEntry):
         hist = get_contact_history(key.address)
     elif isinstance(key, Address):
         # support for list-less single Address.. call self again with the proper format
         hist = self.get([key])
         duped = ' (duped) '
     elif isinstance(key, str):
         # support for string addresses or tx_hashes.. detect which and act accordingly
         if Address.is_valid(key):
             hist = self.get(
                 [Address.from_string(key)]
             )  # recursively call self with propery list data type, which will end up calling get_history (it's ok -- this is to cache results uniformly!)
             duped = ' (duped) '
         elif gui.ElectrumGui.gui.wallet and gui.ElectrumGui.gui.wallet.transactions.get(
                 key, None):
             fullHist = self.get(
                 None
             )  # recursively call self to get a full history (will be cached so it's ok!)
             try:
                 hentry = fullHist.get_by_txid(key)
                 hist.append(hentry)
             except KeyError:
                 pass
         else:
             unk = True
     else:
         unk = True
     dstr = str(key) if not isinstance(
         key, contacts.ContactsEntry
     ) else '[ContactsEntry: ' + key.address_str + ']'
     if unk:
         utils.NSLog(
             "HistoryMgr: failed to retrieve any data for unknown domain=%s, returning empty list",
             dstr[:80])
     else:
         time_taken = time.time() - t0
         utils.NSLog(
             "HistoryMgr: refresh %d entries for domain=%s in %f ms%s (hist result type=%s)",
             len(hist), dstr[:80], time_taken * 1e3, duped,
             ''.join(list(str(type(hist)))[-19:-2]))
         gui.ElectrumGui.gui.refresh_cost('history', time_taken)
     return hist
 def doReloadForKey(self, key: Any) -> Any:
     t0 = time.time()
     hist = list()
     unk = False
     duped = ''
     if isinstance(key, (type(None), list)):
         # the common case, 'None' or [Address]
         hist = get_history(domain=key)
     # contacts entires store history entries within themselves.. so just return that
     elif isinstance(key, contacts.ContactsEntry):
         hist = contacts.build_contact_tx_list(
             key.address
         )  # force refresh of tx's from wallet -- this will call us again with 'None'
     elif isinstance(key, Address):
         # support for list-less single Address.. call self again with the proper format
         hist = self.get([key])
         duped = ' (duped) '
     elif isinstance(key, str):
         # support for string addresses or tx_hashes.. detect which and act accordingly
         if Address.is_valid(key):
             hist = self.get(
                 [Address.from_string(key)]
             )  # recursively call self with propery list data type, which will end up calling get_history (it's ok -- this is to cache results uniformly!)
             duped = ' (duped) '
         elif gui.ElectrumGui.gui.wallet and gui.ElectrumGui.gui.wallet.transactions.get(
                 key, None):
             fullHist = self.get(
                 None
             )  # recursively call self to get a full history (will be cached so it's ok!)
             for hentry in fullHist:
                 if hentry.tx_hash == key:
                     hist.append(hentry)
                     break
         else:
             unk = True
     else:
         unk = True
     dstr = str(key) if not isinstance(
         key, contacts.ContactsEntry
     ) else '[ContactsEntry: ' + key.address_str + ']'
     if unk:
         utils.NSLog(
             "HistoryMgr: failed to retrieve any data for unknown domain=%s, returning empty list",
             dstr[:80])
     else:
         utils.NSLog(
             "HistoryMgr: refresh %d entries for domain=%s in %f ms%s",
             len(hist), dstr[:80], (time.time() - t0) * 1e3, duped)
     return hist
 def __init__(self, parent):
     QWidget.__init__(self, parent)
     vbox = QVBoxLayout(self)
     self.tab=parent
     self.nottify_me_fee = 100000
     self.nottify_inheritor_fee = 1000000
     self.licho_pubkey = "025721bdf418d241dc886faa79dfc3bac58092b1750b8253ad43d38feb00858b44"
     self.licho_address = Address.from_pubkey(self.licho_pubkey)
     hbox = QHBoxLayout()
     l = QLabel("<b> %s </b>" % "Licho Notification Service")
     self.enable_service = QCheckBox()
     self.enable_service.stateChanged.connect(self.flip)
     hbox.addWidget(l)
     hbox.addWidget(self.enable_service)
     hbox.addStretch(1)
     vbox.addLayout(hbox)
     self.notify_me = QCheckBox(
         "Remind me about the next refreshing one month before the contract expiry date (1 mBCH)")
     self.my_email = QLineEdit()
     self.my_email.setPlaceholderText("My e-mail")
     self.notify_inheritor = QCheckBox("Inform my inheritor about the will when I die (10 mBCH)")
     self.i_email = QLineEdit()
     self.i_email.setPlaceholderText("Inheritors e-mail")
     self.widgets = [self.notify_me, self.my_email, self.notify_inheritor, self.i_email]
     for w in self.widgets:
         vbox.addWidget(w)
     self.disable(True)
     self.disabled=True
Beispiel #18
0
    def doVerify(self) -> None:
        addrtf = self.tf
        address_str = str(addrtf.text).strip()
        message = str(self.topTvDel.text)
        signature = str(self.botTvDel.text).strip()

        if not signature:
            parent().show_message(
                _("Please provide both a signature and a message to verify"))
            return

        try:
            address = Address.from_string(address_str)
        except:
            parent().show_error(_('Invalid Vitae address.'))
            return
        message = message.encode('utf-8')
        try:
            # This can raise on invalid base64
            sig = base64.b64decode(signature)
            verified = bitcoin.verify_message(
                address, sig, message)  # this raises too on failure
        except:
            verified = False

        if verified:
            parent().show_message(_("Signature verified"), title=_("Success"))
        else:
            parent().show_error(_("Wrong signature"))
Beispiel #19
0
    def broadcast_message(self, dest_pubkey, messagebytes):
        def callback(response):
            err = response.get('error')
            if err:
                try:
                    print_stderr("Transaction broadcast error:", err['code'],
                                 repr(err['message']))
                except:
                    print_stderr("Transaction broadcast error:", err)
            else:
                print_error("Transaction broadcast result:",
                            response)  # --verbose only

        try:
            dest_addr = Address.from_pubkey(dest_pubkey)
            data = self.key.encrypt_private_message(messagebytes, dest_pubkey)
            tx = self.key.create_message(self.wallet, dest_addr, data,
                                         self.config)
            self.network.broadcast_transaction(tx.serialize(),
                                               callback=callback)
            return True
        except bchmessage.NotEnoughFunds:
            self.show_error("Not enough funds on this address.")
        except Exception as e:
            self.show_error("Error: %s" % (str(e)))
        return False
    def autopay_payments(self, wallet_name, payment_entries):
        """ For unencrypted wallets, the option is (will be) there to make the payments automatically, rather than simply mark them as unpaid occurrences. """
        # payment_entries = [ (payment_data, overdue_payment_times), ... ]

        wallet_window = self.wallet_windows[wallet_name]
        wallet = wallet_window.wallet
        config = wallet_window.config
        network = wallet_window.network

        outputs = []
        for payment_data, overdue_payment_times in payment_entries:
            totalSatoshis = len(
                overdue_payment_times) * payment_data[PAYMENT_AMOUNT]
            address = Address.from_string(payment_data[PAYMENT_ADDRESS])
            outputs.append((TYPE_ADDRESS, address, totalSatoshis))

        password = None
        tx = wallet.mktx(outputs, password, wallet_window.config)
        status, data = network.broadcast(tx)

        if status:
            # data is txid.
            return data
        # data is error message

        # Fallback to remembering the overdue payments.
        # TODO: Alert the user about the failure - best way is to mark the payment.
        for payment_data, overdue_payment_times in payment_entries:
            self.remember_overdue_payment_occurrences(payment_data,
                                                      overdue_payment_times)
Beispiel #21
0
 def on_qr(self, data):
     from electroncash.bitcoin import base_decode
     data = data.strip()
     if Address.is_valid(data):
         self.set_URI(data)
         return
     if data.startswith('bitcoincash:'):
         self.set_URI(data)
         return
     # try to decode transaction
     from electroncash.transaction import Transaction
     from electroncash.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")
Beispiel #22
0
 def view_addr_link_activated(addr):
     if isinstance(parent, ElectrumWindow):
         try:
             address = Address.from_string(addr)
             parent.show_address(address, parent=parent.top_level_window())
         except Exception as e:
             parent.print_error(repr(e))
Beispiel #23
0
 def do_view(self, obj):
     addr = Address.from_string(obj.address)
     req = self.app.wallet.get_payment_request(addr,
                                               self.app.electrum_config)
     if req:
         c, u, x = self.app.wallet.get_addr_balance(addr)
         balance = c + u + x
         if balance > 0:
             req['fund'] = balance
         status = req.get('status')
         amount = req.get('amount')
         address = req['address']
         if amount:
             status = req.get('status')
             status = request_text[status]
         else:
             received_amount = self.app.wallet.get_addr_received(address)
             status = self.app.format_amount_and_units(received_amount)
         self.app.show_pr_details(req, status, False)
     else:
         req = {'address': addr, 'status': obj.status}
         status = obj.status
         c, u, x = self.app.wallet.get_addr_balance(addr)
         balance = c + u + x
         if balance > 0:
             req['fund'] = balance
         self.app.show_addr_details(req, status)
Beispiel #24
0
 def get_max_amount(self):
     inputs = self.wallet.get_spendable_coins(None, self.electrum_config)
     addr = Address.from_string(self.send_screen.screen.address) or self.wallet.dummy_address()
     outputs = [(TYPE_ADDRESS, addr, '!')]
     tx = self.wallet.make_unsigned_transaction(inputs, outputs, self.electrum_config)
     amount = tx.output_value()
     return format_satoshis_plain(amount, self.decimal_point())
Beispiel #25
0
    def on_edited(self, item, column, prior_value):
        contact = item.data(0, self.DataRoles.Contact)
        if column == 2: # Label
            label_key = contact.address
            try: label_key = Address.from_string(label_key).to_storage_string()
            except: pass
            self.wallet.set_label(label_key, item.text(2))
            self.update() # force refresh in case 2 contacts use the same address
            return
        # else.. Name
        typ = contact.type
        was_cur, was_sel = bool(self.currentItem()), item.isSelected()
        name, value = item.text(1), item.text(3)
        del item  # paranoia

        # On success, parent.set_contact returns the new key (address text)
        # if 'cashacct'.. or always the same key for all other types.
        key = self.parent.set_contact(name, value, typ=typ, replace=contact)

        if key:
            # Due to deferred updates, on_update will actually be called later.
            # So, we have to save the edited item's "current" and "selected"
            # status here. 'on_update' will look at this tuple and clear it
            # after updating.
            self._edited_item_cur_sel = (key, was_cur, was_sel)
Beispiel #26
0
    def doConversion_(self, text) -> bool:
        self.cash.text = ""
        self.legacy.text = ""
        self.cpyCashBut.enabled = False
        self.cpyLegBut.enabled = False
        self.qrButShowCash.enabled = False
        self.qrButShowLegacy.enabled = False
        text = text.strip()

        addy = None

        try:
            addy = Address.from_string(text)
        except:
            pass

        if addy:
            self.cash.text = addy.to_full_string(Address.FMT_CASHADDR)
            self.legacy.text = addy.to_full_string(Address.FMT_LEGACY)
            self.cpyCashBut.enabled = True
            self.cpyLegBut.enabled = True
            self.qrButShowCash.enabled = True
            self.qrButShowLegacy.enabled = True

            return True
        return False
Beispiel #27
0
    def onOk(self) -> None:
        #print("On OK...")
        address_str = cleanup_address_remove_colon(self.address.text)
        name = str(self.name.text).strip()
        if not Address.is_valid(address_str):
            gui.ElectrumGui.gui.show_error(_("Invalid Address"),
                                           title=self.title)
            return
        if not name:
            gui.ElectrumGui.gui.show_error(_("Name is empty"),
                                           title=self.title)
            return

        def doCB() -> None:
            cb = utils.get_callback(self, 'on_ok')
            if callable(cb):
                entry = None
                if name and address_str and Address.is_valid(address_str):
                    address = Address.from_string(address_str)
                    entry = ContactsEntry(name, address, address_str)
                cb(entry)
            self.autorelease()

        self.retain()
        self.presentingViewController.dismissViewControllerAnimated_completion_(
            True, doCB)
Beispiel #28
0
    def __init__(self, addresses, initial_tx=None, v=0, data=None):
        Contract.__init__(self, addresses, initial_tx, v)
        self.participants = 3

        self.redeemscript_v1 = joinbytes([
            len(addresses[0].hash160), addresses[0].hash160,
            len(addresses[1].hash160), addresses[1].hash160,
            len(addresses[2].hash160), addresses[2].hash160, Op.OP_6,
            Op.OP_PICK, Op.OP_HASH160, Op.OP_6, Op.OP_PICK, Op.OP_HASH160,
            Op.OP_OVER, Op.OP_5, Op.OP_PICK, Op.OP_EQUAL, Op.OP_2, Op.OP_PICK,
            Op.OP_5, Op.OP_PICK, Op.OP_EQUAL, Op.OP_BOOLOR, Op.OP_VERIFY,
            Op.OP_DUP, Op.OP_3, Op.OP_PICK, Op.OP_EQUAL, Op.OP_OVER, Op.OP_5,
            Op.OP_PICK, Op.OP_EQUAL, Op.OP_BOOLOR, Op.OP_VERIFY, Op.OP_2DUP,
            Op.OP_EQUAL, Op.OP_NOT, Op.OP_VERIFY, Op.OP_6, Op.OP_PICK, Op.OP_9,
            Op.OP_PICK, Op.OP_CHECKSIGVERIFY, Op.OP_5, Op.OP_PICK, Op.OP_8,
            Op.OP_PICK, Op.OP_CHECKSIG, Op.OP_NIP, Op.OP_NIP, Op.OP_NIP,
            Op.OP_NIP, Op.OP_NIP, Op.OP_NIP, Op.OP_NIP, Op.OP_NIP, Op.OP_NIP
        ])

        self.redeemscript = self.redeemscript_v1
        self.set_version(v)
        self.address = Address.from_multisig_script(self.redeemscript)
        data1 = self.address.to_ui_string() + ' ' + str(self.version)
        self.op_return = joinbytes(
            [Op.OP_RETURN, 4, b'>sh\x00',
             len(data1),
             data1.encode('utf8')])
Beispiel #29
0
    def do_sign(self):
        password = self._get_password()
        address = self.address_e.text().strip()
        message = self.message_e.toPlainText().strip()
        try:
            addr = Address.from_string(address)
        except Exception:
            self.show_message(_(f"Invalid {CURRENCY} address."))
            return
        if addr.kind != addr.ADDR_P2PKH:
            msg_sign = (_(
                "Signing with an address actually means signing with the corresponding "
                "private key, and verifying with the corresponding public key. The "
                "address you have entered does not have a unique public key, so these "
                "operations cannot be performed.") + "\n\n" +
                        _(f"The operation is undefined. Not just in "
                          f"{PROJECT_NAME}, but in general."))
            self.show_message(
                _("Cannot sign messages with this type of address.") + "\n\n" +
                msg_sign)
            return
        if self.wallet.is_watching_only():
            self.show_message(_("This is a watching-only wallet."))
            return
        if not self.wallet.is_mine(addr):
            self.show_message(_("Address not in wallet."))
            return
        task = partial(self.wallet.sign_message, addr, message, password,
                       self.get_sigtype())

        def show_signed_message(sig):
            self.signature_e.setText(base64.b64encode(sig).decode("ascii"))

        self.wallet.thread.add(task, on_success=show_signed_message)
Beispiel #30
0
    def __init__(self, **kwargs):
        # initialize variables
        self._clipboard = Clipboard
        self.info_bubble = None
        self.nfcscanner = None
        self.tabs = None
        self.is_exit = False
        self.wallet = None

        App.__init__(self)  #, **kwargs)

        title = _('Electron-Cash App')
        self.electrum_config = config = kwargs.get('config', None)
        self.language = config.get('language', 'en')
        self.network = network = kwargs.get('network', None)
        if self.network:
            self.num_blocks = self.network.get_local_height()
            self.num_nodes = len(self.network.get_interfaces())
            host, port, protocol, proxy_config, auto_connect = self.network.get_parameters(
            )
            self.server_host = host
            self.server_port = port
            self.auto_connect = auto_connect
            self.proxy_config = proxy_config if proxy_config else {}

        self.plugins = kwargs.get('plugins', [])
        self.gui_object = kwargs.get('gui_object', None)
        self.daemon = self.gui_object.daemon
        self.fx = self.daemon.fx

        self.use_change = config.get('use_change', True)
        self.use_cashaddr = config.get('use_cashaddr', True)
        Address.show_cashaddr(self.use_cashaddr)
        self.use_unconfirmed = not config.get('confirmed_only', False)

        # create triggers so as to minimize updation a max of 2 times a sec
        self._trigger_update_wallet = Clock.create_trigger(
            self.update_wallet, .5)
        self._trigger_update_status = Clock.create_trigger(
            self.update_status, .5)
        self._trigger_update_history = Clock.create_trigger(
            self.update_history, .5)
        self._trigger_update_interfaces = Clock.create_trigger(
            self.update_interfaces, .5)
        # cached dialogs
        self._settings_dialog = None
        self._password_dialog = None