URI: 
       tdetect if wallet can sign tx before showing sign button - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 2c7bf3ca1aff2326f3cc788f57c9c4289d0366f5
   DIR parent b32d0c77a3afcfbfa3b551610cab3cba4ddd84c9
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Tue, 24 Jun 2014 13:22:10 +0200
       
       detect if wallet can sign tx before showing sign button
       
       Diffstat:
         M gui/qt/transaction_dialog.py        |       9 ++++-----
         M lib/account.py                      |       2 ++
         M lib/transaction.py                  |      30 ++++++++++++++++++++++++++++++
         M lib/wallet.py                       |      65 +++++++++++++++++--------------
       
       4 files changed, 72 insertions(+), 34 deletions(-)
       ---
   DIR diff --git a/gui/qt/transaction_dialog.py b/gui/qt/transaction_dialog.py
       t@@ -131,10 +131,13 @@ class TxDialog(QDialog):
            def update(self):
        
                is_relevant, is_mine, v, fee = self.wallet.get_tx_value(self.tx)
       +        if self.wallet.can_sign(self.tx):
       +            self.sign_button.show()
       +        else:
       +            self.sign_button.hide()
        
                if self.tx.is_complete():
                    status = _("Signed")
       -            self.sign_button.hide()
                    tx_hash = self.tx.hash()
        
                    if tx_hash in self.wallet.transactions.keys():
       t@@ -153,10 +156,6 @@ class TxDialog(QDialog):
                    s, r = self.tx.signature_count()
                    status = _("Unsigned") if s == 0 else _('Partially signed (%d/%d)'%(s,r))
                    time_str = None
       -            if not self.wallet.is_watching_only():
       -                self.sign_button.show()
       -            else:
       -                self.sign_button.hide()
                    self.broadcast_button.hide()
                    tx_hash = 'unknown'
        
   DIR diff --git a/lib/account.py b/lib/account.py
       t@@ -75,6 +75,8 @@ class PendingAccount(Account):
            def get_name(self, k):
                return _('Pending account')
        
       +    def get_master_pubkeys(self):
       +        return []
        
        class ImportedAccount(Account):
            def __init__(self, d):
   DIR diff --git a/lib/transaction.py b/lib/transaction.py
       t@@ -618,6 +618,36 @@ class Transaction:
                return r == s
        
        
       +    def inputs_to_sign(self):
       +        from account import BIP32_Account, OldAccount
       +        xpub_list = []
       +        addr_list = set()
       +        for txin in self.inputs:
       +            x_signatures = txin['signatures']
       +            signatures = filter(lambda x: x is not None, x_signatures)
       +
       +            if len(signatures) == txin['num_sig']:
       +                # input is complete
       +                continue
       +
       +            for k, x_pubkey in enumerate(txin['x_pubkeys']):
       +
       +                if x_signatures[k] is not None:
       +                    # this pubkey already signed
       +                    continue
       +
       +                if x_pubkey[0:2] == 'ff':
       +                    xpub, sequence = BIP32_Account.parse_xpubkey(x_pubkey)
       +                    xpub_list.append((xpub,sequence))
       +                elif x_pubkey[0:2] == 'fe':
       +                    xpub, sequence = OldAccount.parse_xpubkey(x_pubkey)
       +                    xpub_list.add((xpub,sequence))
       +                else:
       +                    addr_list.add(txin['address'])
       +
       +        return addr_list, xpub_list
       +
       +
            def sign(self, keypairs):
                print_error("tx.sign(), keypairs:", keypairs)
        
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -392,47 +392,54 @@ class Abstract_Wallet:
                return self.accounts[account_id].get_pubkeys(sequence)
        
        
       +    def can_sign(self, tx):
       +
       +        if self.is_watching_only():
       +            return False
       +
       +        if tx.is_complete():
       +            return False
       +
       +        addr_list, xpub_list = tx.inputs_to_sign()
       +        for addr in addr_list:
       +            if self.is_mine(addr):
       +                return True
       +
       +        mpk = [ self.master_public_keys[k] for k in self.master_private_keys.keys() ]
       +        for xpub, sequence in xpub_list:
       +            if xpub in mpk:
       +                return True
       +
       +        return False
       +            
       +
       +
            def add_keypairs(self, tx, keypairs, password):
                # first check the provided password
                seed = self.get_seed(password)
        
       -        for txin in tx.inputs:
       -            x_pubkeys = txin['x_pubkeys']
       -            address = txin['address']
       -
       -            if self.is_mine(address):
       +        addr_list, xpub_list = tx.inputs_to_sign()
        
       +        for addr in addr_list:
       +            if self.is_mine(addr):
                        private_keys = self.get_private_key(address, password)
                        for sec in private_keys:
                            pubkey = public_key_from_private_key(sec)
                            keypairs[ pubkey ] = sec
        
       +        for xpub, sequence in xpub_list:
       +            # look for account that can sign
       +            for k, account in self.accounts.items():
       +                if xpub in account.get_master_pubkeys():
       +                    break
                    else:
       +                continue
        
       -                from account import BIP32_Account, OldAccount
       -                for x_pubkey in x_pubkeys:
       -                    if not is_extended_pubkey(x_pubkey):
       -                        continue
       -
       -                    if x_pubkey[0:2] == 'ff':
       -                        xpub, sequence = BIP32_Account.parse_xpubkey(x_pubkey)
       -                    elif x_pubkey[0:2] == 'fe':
       -                        xpub, sequence = OldAccount.parse_xpubkey(x_pubkey)
       -
       -                    # look for account that can sign
       -                    for k, account in self.accounts.items():
       -                        if xpub in account.get_master_pubkeys():
       -                            break
       -                    else:
       -                        continue
       -
       -                    addr = account.get_address(*sequence)
       -                    assert txin['address'] == addr
       -                    pk = self.get_private_key(addr, password)
       -                    for sec in pk:
       -                        pubkey = public_key_from_private_key(sec)
       -                        keypairs[pubkey] = sec
       -
       +            addr = account.get_address(*sequence)
       +            pk = self.get_private_key(addr, password)
       +            for sec in pk:
       +                pubkey = public_key_from_private_key(sec)
       +                keypairs[pubkey] = sec