Exemple #1
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)
Exemple #2
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)
Exemple #3
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))
Exemple #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
Exemple #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)
Exemple #6
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")
    def resolve(self):
        self.is_alias, self.validated = False, False
        if self.hasFocus():
            return
        if self.is_multiline():  # only supports single line entries atm
            return
        if self.is_pr:
            return
        key = str(self.toPlainText())
        key = key.strip()  # strip whitespaces
        if key == self.previous_payto:
            return
        self.previous_payto = key
        if not (('.' in key) and (not '<' in key) and (not ' ' in key)):
            return
        parts = key.split(sep=',')  # assuming single line
        if parts and len(parts) > 0 and Address.is_valid(parts[0]):
            return
        try:
            data = self.win.contacts.resolve(key)
        except Exception as e:
            print_error(f'error resolving alias: {repr(e)}')
            return
        if not data:
            return

        address = data.get('address')
        name = data.get('name')
        _type = data.get('type')

        if _type != 'openalias':
            return

        address_str = None
        if isinstance(address, str):
            address_str = address
        elif isinstance(address, Address):
            address_str = address.to_ui_string()
        else:
            raise RuntimeError('unknown address type')

        self.is_alias = True

        new_url = key + ' <' + address_str + '>'
        self.setText(new_url)
        self.previous_payto = new_url

        self.win.contacts[key] = ('openalias', name)
        self.win.contact_list.update()

        self.setFrozen(True)

        self.validated = bool(data.get('validated'))
        if self.validated:
            self.setGreen()
        else:
            self.setExpired()
Exemple #8
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))
Exemple #9
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 resolve(self):
        self.is_alias = False
        if self.hasFocus():
            return
        if self.is_multiline():  # only supports single line entries atm
            return
        if self.is_pr:
            return
        key = str(self.toPlainText())
        if key == self.previous_payto:
            return
        self.previous_payto = key
        if not (('.' in key) and (not '<' in key) and (not ' ' in key)):
            return
        parts = key.split(sep=',')  # assuming single lie
        if parts and len(parts) > 0 and Address.is_valid(parts[0]):
            return
        try:
            data = self.win.contacts.resolve(key)
        except:
            return
        if not data:
            return
        self.is_alias = True

        address = data.get('address')
        name = data.get('name')
        new_url = key + ' <' + address + '>'
        self.setText(new_url)
        self.previous_payto = new_url

        if isinstance(self.win.contacts, dict):
            # old contacts API
            self.win.contacts[key] = ('openalias', name)
        else:
            try:
                from electroncash.contacts import Contact
                self.win.contacts.add(Contact(name=name,
                                              address=key,
                                              type='openalias'),
                                      unique=True)
            except Exception as e:
                print_error(
                    "[Custom PayToEdit] Could not determine contacts API, giving up:",
                    repr(e))
        self.win.contact_list.on_update()

        self.setFrozen(True)
        if data.get('type') == 'openalias':
            self.validated = data.get('validated')
            if self.validated:
                self.setGreen()
            else:
                self.setExpired()
        else:
            self.validated = None
Exemple #11
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)
Exemple #12
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)
Exemple #13
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)
Exemple #14
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
Exemple #15
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)
Exemple #16
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
Exemple #18
0
 def reader_didScanResult_(self, reader, result) -> None:
     utils.NSLog("Reader data = '%s'", str(result))
     result = cleanup_address_remove_colon(result)
     if not Address.is_valid(result):
         title = _("Invalid QR Code")
         message = _(
             "The QR code does not appear to be a valid BCH address.\nPlease try again."
         )
         reader.stopScanning()
         gui.ElectrumGui.gui.show_error(title=title,
                                        message=message,
                                        onOk=lambda: reader.startScanning(),
                                        vc=self.qrvc)
     else:
         self.address.text = result
         self.readerDidCancel_(reader)
Exemple #19
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
 def check_sufficient_ammount(self):
     coin_amount = self.coinshuffle_inputs_list.get_selected_amount()
     self.coinshuffle_inputs_total_output.setText(
         self.window.format_amount_and_units(coin_amount))
     shuffle_amount = self.coinshuffle_amount_radio.get_amount()
     fee = self.coinshuffle_fee_constant
     if shuffle_amount and fee:
         if coin_amount > (fee + shuffle_amount):
             self.coinshuffle_start_button.setEnabled(True)
             if self.coinshuffle_use_external_output.isChecked():
                 if not Address.is_valid(
                         self.coinshuffle_external_output.text()):
                     self.coinshuffle_start_button.setEnabled(False)
         else:
             self.coinshuffle_start_button.setEnabled(False)
     else:
         self.coinshuffle_start_button.setEnabled(False)
 def get_full_contacts(self, include_pseudo: bool = True) -> List[Contact]:
     ''' Returns all the contacts, with the "My CashAcct" pseudo-contacts
     clobbering dupes of the same type that were manually added.
     Client code should scan for type == 'cashacct' and type == 'cashacct_W' '''
     if include_pseudo:
         # filter out cachaccts that are "Wallet", as they will be added
         # at the end as pseudo contacts if they also appear in real contacts
         real_contacts = [contact for contact in
                          self.parent.contacts.get_all(nocopy=True)
                          if contact.type != 'cashacct'  # accept anything that's not cashacct
                             or not Address.is_valid(contact.address)  # or if it is, it can have invalid address as it's clearly 'not mine"
                             or not self.wallet.is_mine(  # or if it's not mine
                                 Address.from_string(contact.address))
                         ]
         return real_contacts + self._make_wallet_cashacct_pseudo_contacts()
     else:
         return self.parent.contacts.get_all(nocopy=True)
Exemple #22
0
    def do_send(self):
        if not Address.is_valid(self.str_recipient):
            print(_('Invalid Bitcoin address'))
            return
        try:
            amount = int(Decimal(self.str_amount) * COIN)
        except Exception:
            print(_('Invalid Amount'))
            return
        try:
            fee = int(Decimal(self.str_fee) * COIN)
        except Exception:
            print(_('Invalid Fee'))
            return

        if self.wallet.use_encryption:
            password = self.password_dialog()
            if not password:
                return
        else:
            password = None

        c = ""
        while c != "y":
            c = input("ok to send (y/n)?")
            if c == "n": return

        try:
            tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)],
                                  password, self.config, fee)
        except Exception as e:
            print(str(e))
            return

        if self.str_description:
            self.wallet.labels[tx.hash()] = self.str_description

        print(_("Please wait..."))
        status, msg = self.network.broadcast(tx)

        if status:
            print(_('Payment sent.'))
            #self.do_clear()
            #self.update_contacts_tab()
        else:
            print(_('Error'))
 def set_label(self, wallet, addr_or_txid, label):
     ''' Catch when they actually paid -- wallet.set_label is called once a payment is done, passing us txid and the unique description
         we generated in prompt_pay_overdue_payment_occurrences() below.
         We use that unique description key to catch the payment that was made and thus know the payments were made, so
         we mark them as such. '''
     self.print_error("set_label called", wallet, addr_or_txid, label)
     vals = self.will_possibly_pay.pop(label, None)
     if vals:
         wallet_name, payment_keys = vals
         if wallet.basename() == wallet_name and not Address.is_valid(addr_or_txid):
             # matches
             self.print_error("Payment occurrence matched, forgetting: ",addr_or_txid,label,wallet_name,payment_keys)
             self.forget_overdue_payment_occurrences(wallet_name, payment_keys, mark_paid = True)
         else:
             self.print_error("No match, putting it back in our dict")
             # doesn't match, remember this thing
             self.will_possibly_pay[label] = vals
 def get_full_contacts(self, include_pseudo_types: List[str] = ['cashacct', 'lns']) -> List[Contact]:
     ''' Returns all the contacts, with the "My CashAcct" and "My LNS names"
     pseudo-contacts clobbering dupes of the same type that were manually added.
     Client code should scan for type == 'cashacct' and type == 'cashacct_W'
     also for type == 'lns' and type == 'lns_W '''
     if not include_pseudo_types:
         return self.parent.contacts.get_all(nocopy=True)
     else:
         contacts = [contact for contact in self.parent.contacts.get_all(nocopy=True)
                     if contact.type not in ['cashacct', 'lns']
                         # or if it is, it can have invalid address as it's clearly 'not mine"
                         or not Address.is_valid(contact.address)
                         or not self.wallet.is_mine(Address.from_string(contact.address))]
         if 'cashacct' in include_pseudo_types:
             contacts = contacts + self._make_wallet_cashacct_pseudo_contacts()
         if self.have_lns and 'lns' in include_pseudo_types:
             contacts = contacts + self._make_wallet_lns_pseudo_contacts()
         return contacts
Exemple #25
0
    def do_send(self):
        if not Address.is_valid(self.str_recipient):
            print(_('Invalid DeVault address'))
            return
        try:
            amount = int(PyDecimal(self.str_amount) * COIN)
        except Exception:
            print(_('Invalid Amount'))
            return
        try:
            fee = int(PyDecimal(self.str_fee) * COIN)
        except Exception:
            print(_('Invalid Fee'))
            return

        if self.wallet.has_password():
            password = self.password_dialog()
            if not password:
                return
        else:
            password = None

        c = ""
        while c != "y":
            c = input("ok to send (y/n)?")
            if c == "n": return

        try:
            tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)],
                                  password, self.config, fee)
        except Exception as e:
            print(str(e))
            return

        if self.str_description:
            self.wallet.labels[tx.txid()] = self.str_description

        print(_("Please wait..."))
        status, msg = self.network.broadcast_transaction(tx)

        if status:
            print(_('Payment sent.'))
        else:
            print(_('Error'))
    def resolve(self):
        self.is_alias = False
        if self.hasFocus():
            return
        if self.is_multiline():  # only supports single line entries atm
            return
        if self.is_pr:
            return
        key = str(self.toPlainText())
        if key == self.previous_payto:
            return
        self.previous_payto = key
        if not (('.' in key) and (not '<' in key) and (not ' ' in key)):
            return
        parts = key.split(sep=',')  # assuming single lie
        if parts and len(parts) > 0 and Address.is_valid(parts[0]):
            return
        try:
            data = self.win.contacts.resolve(key)
        except:
            return
        if not data:
            return
        self.is_alias = True

        address = data.get('address')
        name = data.get('name')
        new_url = key + ' <' + address + '>'
        self.setText(new_url)
        self.previous_payto = new_url

        #if self.win.config.get('openalias_autoadd') == 'checked':
        self.win.contacts[key] = ('openalias', name)
        self.win.contact_list.on_update()

        self.setFrozen(True)
        if data.get('type') == 'openalias':
            self.validated = data.get('validated')
            if self.validated:
                self.setGreen()
            else:
                self.setExpired()
        else:
            self.validated = None
Exemple #27
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, web.ExplorerUrlParts.ADDR, addr)
             if addr_URL:
                 webopen(addr_URL)
         return
     if link.startswith('http'):
         webopen(link)
     elif len(link) == 64:  # 64 character txid
         tx = wallet.transactions.get(link)
         if tx:
             parent.show_transaction(tx, tx_desc=wallet.get_label(link))
         else:
             parent.do_process_from_txid(txid=link, tx_desc=wallet.get_label(link))
         return
Exemple #28
0
 def make_unsigned_transaction(self, amount, fee, all_inputs, outputs,
                               changes):
     "make unsigned transaction"
     dust = dust_threshold(self.network)
     coins = {}
     tx_inputs = []
     amounts = {}
     try:
         for player in all_inputs:
             inputs_coins = self.get_coins(all_inputs[player])
             # if there is no coins on input it terminates the process
             if inputs_coins:
                 coins[player] = inputs_coins
             else:
                 return None
     except:
         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)
     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
Exemple #29
0
    def do_send(self):
        if not Address.is_valid(self.str_recipient):
            self.show_message(_('Invalid Bitcoin address'))
            return
        try:
            amount = int(Decimal(self.str_amount) * COIN)
        except Exception:
            self.show_message(_('Invalid Amount'))
            return
        try:
            fee = int(Decimal(self.str_fee) * COIN)
        except Exception:
            self.show_message(_('Invalid Fee'))
            return

        if self.wallet.has_password():
            password = self.password_dialog()
            if not password:
                return
        else:
            password = None
        try:
            tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)],
                                  password, self.config, fee)
        except Exception as e:
            self.show_message(str(e))
            return

        if self.str_description:
            self.wallet.labels[tx.txid()] = self.str_description

        self.show_message(_("Please wait..."), getchar=False)
        status, msg = self.network.broadcast(tx)

        if status:
            self.show_message(_('Payment sent.'))
            self.do_clear()
            #self.update_contacts_tab()
        else:
            self.show_message(_('Error'))
Exemple #30
0
 def format_value(self, value, display_type=0):
     if display_type in (DISPLAY_AS_AMOUNT, DISPLAY_AS_AMOUNT_NO_UNITS):
         return self.window.format_amount(value, whitespaces=False) + (
             (' ' + self.window.base_unit())
             if display_type == DISPLAY_AS_AMOUNT else '')
     elif display_type == DISPLAY_AS_AMOUNT_FIAT:
         fx = self.window.fx
         units = fx.get_currency() if fx else '(FIAT)'
         return '%0.2f %s' % (float(value), units)
     elif display_type == DISPLAY_AS_ADDRESS:
         contact_name = self.format_contact(value)
         if contact_name is None:
             if Address.is_valid(value):
                 contact_name = Address.from_string(value).to_ui_string()
             else:
                 contact_name = value
         return contact_name
     elif display_type == DISPLAY_AS_DATETIME:
         if value is None:
             return "-"
         return datetime.datetime.fromtimestamp(value).strftime(
             "%Y-%m-%d %H:%M")
     return str(value)