Esempio n. 1
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)
Esempio n. 2
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)
    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)
Esempio n. 4
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)
Esempio n. 5
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
Esempio n. 6
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))
Esempio n. 7
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"))
Esempio n. 8
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)
Esempio n. 9
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)
Esempio n. 10
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))
Esempio n. 11
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)
Esempio n. 12
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
Esempio n. 13
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)
Esempio n. 14
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())
Esempio n. 15
0
 def make_unsigned_transaction(self, amount, fee, all_inputs, outputs,
                               changes):
     ''' make unsigned transaction '''
     dust = self.dust_threshold(
     )  # always 546 for now, but this call is here in case something more sophisticated happens in the future
     coins = {}
     tx_inputs = []
     amounts = {}
     try:
         for player in all_inputs:
             inputs_coins = self.get_coins(all_inputs[player])
             # if there are no coins on input it terminates the process
             if inputs_coins:
                 coins[player] = inputs_coins
             else:
                 return None
     except BaseException as e:
         self.print_error('make_unsigned_transaction:', repr(e))
         return None
     for player, pubkey_utxos in coins.items():
         amounts[player] = 0
         for pubkey, utxos in pubkey_utxos.items():
             for utxo in utxos:
                 utxo['type'] = 'p2pkh'
                 utxo['address'] = Address.from_pubkey(pubkey)
                 utxo['pubkeys'] = [pubkey]
                 utxo['x_pubkeys'] = [pubkey]
                 utxo['prevout_hash'] = utxo['tx_hash']
                 utxo['prevout_n'] = utxo['tx_pos']
                 utxo['signatures'] = [None]
                 utxo['num_sig'] = 1
                 tx_inputs.append(utxo)
                 amounts[player] += utxo['value']
     tx_inputs.sort(key=lambda x: x['prevout_hash'] + str(x["tx_pos"]))
     tx_outputs = [(TYPE_ADDRESS, Address.from_string(output), int(amount))
                   for output in outputs]
     transaction = Transaction.from_io(tx_inputs,
                                       tx_outputs,
                                       sign_schnorr=False)
     tx_changes = [
         (TYPE_ADDRESS, Address.from_string(changes[player]),
          int(amounts[player] - amount - fee)) for player in sorted(changes)
         if Address.is_valid(changes[player]) and int(amounts[player] -
                                                      amount - fee) >= dust
     ]
     transaction.add_outputs(tx_changes)
     return transaction
Esempio n. 16
0
    def mecenate_info_changed(self, ):
        # if any of the txid/out#/value changes
        try:
            self.protege_address = Address.from_string(
                self.protege_address_wid.text())
            self.reps = int(self.repetitions.text())
            self.rpayment_time = int(
                self.rpayment_time_wid.text()) * 3600 * 24 // 512
            self.rpayment_value = self.rpayment_value_wid.get_amount()
            total_time = int(self.rpayment_time_wid.text()) * self.reps
            self.total_time_label.setText("<b>%s</b>" %
                                          (str(total_time) + " days"))

            if self.advanced_wid.option == 2:
                self.version = 2
                self.addresses = [self.protege_address, self.mecenas_address]
            elif self.advanced_wid.option == 3:
                self.version = 3
                self.escrow_address = Address.from_string(
                    self.advanced_wid.escrow_address.text())
                self.addresses = [
                    self.protege_address, self.mecenas_address,
                    self.escrow_address
                ]
            elif self.advanced_wid.option == 1:
                self.version = 1.1
                self.addresses = [self.protege_address, self.mecenas_address]
            elif self.advanced_wid.option == 4:
                self.version = 1
                self.addresses = [self.protege_address, self.mecenas_address]
            self.total_value = self.reps * (self.rpayment_value +
                                            MecenasContract.fee(self.version))
            self.total_label.setText(
                "<b>%s</b>" %
                (self.main_window.format_amount(self.total_value) + " " +
                 self.main_window.base_unit()))

        except Exception as e:
            self.create_button.setDisabled(True)
            print(e)
        else:
            self.create_button.setDisabled(False)
            # PROTEGE is 0, MECENAS is 1
            self.contract = MecenasContract(
                self.addresses,
                v=self.version,
                data=[self.rpayment_time, self.rpayment_value])
Esempio n. 17
0
 def checkAddress(self):
     xpub = self.textBox.document().toPlainText()
     if xpub[:2] != "ff" or len(xpub) < 100:
         self.textBox.setPlainText(
             "Please enter your partner's x_pubkey into this textbox before clicking CheckAddress."
         )
         return
     addrOrig = self.addressBox.text()
     try:
         addr = Address.from_string(addrOrig)
     except:
         self.addressBox.setText(
             "Please enter multisig address here before clicking CheckAddress."
         )
         return
     if addr.kind != Address.ADDR_P2SH:
         self.addressBox.setText(
             "The address you entered was not a multisig address.")
         return
     currentContract = self.getCurrentContract()
     if currentContract != None:
         if "address" in cashrip.contracts[currentContract]:
             self.textBox.setPlainText(
                 "This contract already has an address. Maybe you selected the wrong contract?"
             )
             return
         if cashrip.contracts[currentContract]["my_x_pubkey"] == xpub:
             self.textBox.setPlainText(
                 "You entered your own x_pubkey, not your partner's.")
             return
         try:
             self.textBox.setPlainText("Please wait . . .")
             self.textBox.repaint()
             contract = cashrip.create_multisig_addr(
                 currentContract, xpub, False)
         except:
             self.textBox.setPlainText(
                 "Something was wrong with the x_pubkey you pasted.")
             return
         if contract["address"] == addr:
             self.textBox.setPlainText(
                 "Success. You and your partner generated the same address. You can now send funds to {}"
                 .format(addrOrig))
             cashrip.startSyncMultiWallet(currentContract, self.network)
         else:
             self.textBox.setPlainText(
                 "Something went wrong. You and your partner generated different addresses. Please double-check the x_pubkeys that you have sent to each other."
             )
             os.remove(contract['addrWalletFile'])
             del contract["addrWalletFile"]
             del contract["address"]
             del contract["partner_addr"]
             del contract["partner_x_pubkey"]
             del contract["partner_pubkey"]
             del contract["gen_by_me"]
             del contract["redeemScript"]
             cashrip.updateContracts()
             cashrip.multiWallets[currentContract] = None
         self.parent.update()
Esempio n. 18
0
 def save_request(self):
     addr = Address.from_string(self.screen.address)
     amount = self.screen.amount
     message = self.screen.message
     amount = self.app.get_amount(amount) if amount else 0
     req = self.app.wallet.make_payment_request(addr, amount, message, None)
     self.app.wallet.add_payment_request(req, self.app.electrum_config)
     self.app.update_tab('requests')
Esempio n. 19
0
 def get_URI(self):
     amount = self.screen.amount
     if amount:
         a, u = self.screen.amount.split()
         assert u == self.app.base_unit
         amount = Decimal(a) * pow(10, self.app.decimal_point())
     addr = Address.from_string(self.screen.address)
     return create_URI(addr, amount, self.screen.message)
Esempio n. 20
0
 def update(self):
     if not self.screen.address:
         self.get_new_address()
     else:
         addr = Address.from_string(self.screen.address)
         status = self.app.wallet.get_request_status(addr)
         self.screen.status = _(
             'Payment received') if status == PR_PAID else ''
Esempio n. 21
0
 def onBlkXplo() -> None:
     print("onBlkXplo")
     if isInput:
         data = getData(x, False, True)
     else:
         data = getData(x, True, False)
         data = Address.from_string(data)
     parent.view_on_block_explorer(data, "tx" if isInput else "addr")
Esempio n. 22
0
 def show_private_key(addr, pk_label, password):
     if self.wallet.has_password() and password is None:
         return
     if not self.wallet.can_export():
         return
     addr = Address.from_string(addr)
     key = self.wallet.export_private_key(addr, password)
     pk_label.data = key
Esempio n. 23
0
 def validate_address(self, address_text: str):
     previous_address = self.output_address
     try:
         self.output_address = Address.from_string(address_text)
     except AddressError:
         self.output_address = None
     if self.output_address != previous_address:
         self.completeChanged.emit()
Esempio n. 24
0
 def make_unsigned_transaction(self, amount, fee, inputs, outputs, changes):
     coins = {vk : self.get_first_sufficient_utxo(inputs[vk], amount) for vk in inputs}
     for vk in coins:
         coins[vk]['type'] = 'p2pkh'
         coins[vk]['address'] = Address.from_string(self.address(vk))
         coins[vk]['pubkeys'] = [vk]
         coins[vk]['x_pubkeys'] = [vk]
         coins[vk]['prevout_hash'] = coins[vk]['tx_hash']
         coins[vk]['prevout_n'] = coins[vk]['tx_pos']
         coins[vk]['signatures'] = [None]
         coins[vk]['num_sig'] = 1
     tx_inputs = [coins[vk] for vk in sorted(coins)]
     tx_outputs = [(TYPE_ADDRESS, Address.from_string(output), int(amount)) for output in outputs ]
     tx = Transaction.from_io(tx_inputs, tx_outputs)
     tx_changes = [(TYPE_ADDRESS, Address.from_string(changes[vk]), int(coins[vk]['value'] - amount - fee))  for vk in changes if Address.is_valid(changes[vk])]
     tx.add_outputs(tx_changes)
     return tx
Esempio n. 25
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))
Esempio n. 26
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()
 def parse_address(self, line):
     slp_token_type_index = self.parent.token_type_combo.currentIndex()
     r = line.strip()
     m = re.match(RE_ALIAS, r)
     address = m.group(2) if m else r
     if slp_token_type_index > 0:
         if "simpleledger" not in address:
             address = "simpleledger:" + address
     return Address.from_string(address)
Esempio n. 28
0
def decodeAddress(addr: str) -> Address:
    ret = None
    if addr:
        try:
            # re-encode addr in case they went to/from cashaddr
            ret = Address.from_string(addr)
        except BaseException as e:
            utils.NSLog("Caught exception decoding address %s: %s", addr,
                        str(e))
    return ret
Esempio n. 29
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)
Esempio n. 30
0
 def new_contract_info_changed(self, ):
     # if any of the txid/out#/value changes
     try:
         self.total_value = self.value_wid.get_amount()
         self.receiver_address = Address.from_string(
             self.receiver_address_wid.text())
         self.arbiter_address = Address.from_string(
             self.arbiter_address_wid.text())
         addresses = [
             self.receiver_address, self.sender_address,
             self.arbiter_address
         ]
     except:
         self.create_button.setDisabled(True)
     else:
         self.create_button.setDisabled(False)
         self.contract = MultisigContract(addresses,
                                          v=self.version,
                                          data=None)