URI: 
       tMerge branch 'master' of https://github.com/spesmilo/electrum - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 6b914232e499c96204de3e003b6c63f0df8aae45
   DIR parent a7cd8b5e9f95940922496d372be415efe4e7528a
  HTML Author: Eagle[TM] <eagletm@mpex.net>
       Date:   Tue, 19 Aug 2014 14:42:17 +0200
       
       Merge branch 'master' of https://github.com/spesmilo/electrum
       
       Diffstat:
         M lib/wallet.py                       |     162 ++++++++++++++++---------------
       
       1 file changed, 85 insertions(+), 77 deletions(-)
       ---
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -961,6 +961,10 @@ class Abstract_Wallet(object):
            def get_accounts(self):
                return self.accounts
        
       +    def add_account(self, account_id, account):
       +        self.accounts[account_id] = account
       +        self.save_accounts()
       +
            def save_accounts(self):
                d = {}
                for k, v in self.accounts.items():
       t@@ -1136,13 +1140,7 @@ class Deterministic_Wallet(Abstract_Wallet):
                        self.create_new_address(account, for_change)
        
            def check_pending_accounts(self):
       -        for account_id, addr in self.next_addresses.items():
       -            if self.address_is_old(addr):
       -                print_error( "creating account", account_id )
       -                xpub = self.master_public_keys[account_id]
       -                account = BIP32_Account({'xpub':xpub})
       -                self.add_account(account_id, account)
       -                self.next_addresses.pop(account_id)
       +        pass
        
            def synchronize_account(self, account):
                self.synchronize_sequence(account, 0)
       t@@ -1184,35 +1182,6 @@ class Deterministic_Wallet(Abstract_Wallet):
                    self.synchronize()
                self.fill_addressbook()
        
       -    def create_account(self, name, password):
       -        i = self.num_accounts()
       -        account_id = self.account_id(i)
       -        account = self.make_account(account_id, password)
       -        self.add_account(account_id, account)
       -        if name:
       -            self.set_label(account_id, name)
       -
       -        # add address of the next account
       -        _, _ = self.next_account_address(password)
       -
       -
       -    def add_account(self, account_id, account):
       -        self.accounts[account_id] = account
       -        self.save_accounts()
       -
       -    def account_is_pending(self, k):
       -        return type(self.accounts.get(k)) == PendingAccount
       -
       -    def delete_pending_account(self, k):
       -        assert self.account_is_pending(k)
       -        self.accounts.pop(k)
       -        self.save_accounts()
       -
       -    def create_pending_account(self, name, password):
       -        account_id, addr = self.next_account_address(password)
       -        self.set_label(account_id, name)
       -        self.accounts[account_id] = PendingAccount({'pending':addr})
       -        self.save_accounts()
        
            def is_beyond_limit(self, address, account, is_change):
                if type(account) == ImportedAccount:
       t@@ -1236,7 +1205,9 @@ class Deterministic_Wallet(Abstract_Wallet):
                    return 'create_accounts'
        
        
       -class NewWallet(Deterministic_Wallet):
       +
       +class BIP32_Wallet(Deterministic_Wallet):
       +    # bip32 derivation
        
            def __init__(self, storage):
                Deterministic_Wallet.__init__(self, storage)
       t@@ -1283,7 +1254,7 @@ class NewWallet(Deterministic_Wallet):
                self.add_master_public_key(account_id, xpub)
                self.add_account(account_id, account)
        
       -    def create_watching_only_wallet(self, xpub):
       +    def create_xpub_wallet(self, xpub):
                account = BIP32_Account({'xpub':xpub})
                account_id = 'm/' + bitcoin.get_xkey_name(xpub)
                self.storage.put('seed_version', self.seed_version, True)
       t@@ -1304,25 +1275,6 @@ class NewWallet(Deterministic_Wallet):
                self.master_private_keys[name] = pw_encode(xpriv, password)
                self.storage.put('master_private_keys', self.master_private_keys, True)
        
       -    def add_master_keys(self, root, account_id, password):
       -        x = self.master_private_keys.get(root)
       -        if x:
       -            master_xpriv = pw_decode(x, password )
       -            xpriv, xpub = bip32_private_derivation(master_xpriv, root, account_id)
       -            self.add_master_public_key(account_id, xpub)
       -            self.add_master_private_key(account_id, xpriv, password)
       -        else:
       -            master_xpub = self.master_public_keys[root]
       -            xpub = bip32_public_derivation(master_xpub, root, account_id)
       -            self.add_master_public_key(account_id, xpub)
       -        return xpub
       -
       -    def create_master_keys(self, password):
       -        seed = self.get_seed(password)
       -        xpriv, xpub = bip32_root(seed)
       -        self.add_master_public_key("m/", xpub)
       -        self.add_master_private_key("m/", xpriv, password)
       -
            def can_sign(self, tx):
                if self.is_watching_only():
                    return False
       t@@ -1338,31 +1290,52 @@ class NewWallet(Deterministic_Wallet):
                        return True
                return False
        
       -    def num_accounts(self):
       -        keys = []
       -        for k, v in self.accounts.items():
       -            if type(v) != BIP32_Account:
       -                continue
       -            keys.append(k)
        
       -        i = 0
       -        while True:
       -            account_id = self.account_id(i)
       -            if account_id not in keys: break
       -            i += 1
       -        return i
       +class BIP32_HD_Wallet(BIP32_Wallet):
       +    # sequence of accounts
        
       -    def next_account_address(self, password):
       +    def create_account(self, name, password):
                i = self.num_accounts()
                account_id = self.account_id(i)
       +        account = self.make_account(account_id, password)
       +        self.add_account(account_id, account)
       +        if name:
       +            self.set_label(account_id, name)
       +        # add address of the next account
       +        _, _ = self.next_account_address(password)
       +
       +    def account_is_pending(self, k):
       +        return type(self.accounts.get(k)) == PendingAccount
        
       +    def delete_pending_account(self, k):
       +        assert self.account_is_pending(k)
       +        self.accounts.pop(k)
       +        self.save_accounts()
       +
       +    def create_pending_account(self, name, password):
       +        account_id, addr = self.next_account_address(password)
       +        self.set_label(account_id, name)
       +        self.accounts[account_id] = PendingAccount({'pending':addr})
       +        self.save_accounts()
       +
       +    def check_pending_accounts(self):
       +        for account_id, addr in self.next_addresses.items():
       +            if self.address_is_old(addr):
       +                print_error( "creating account", account_id )
       +                xpub = self.master_public_keys[account_id]
       +                account = BIP32_Account({'xpub':xpub})
       +                self.add_account(account_id, account)
       +                self.next_addresses.pop(account_id)
       +
       +    def next_account_address(self, password):
       +        i = self.num_accounts()
       +        account_id = self.account_id(i)
                addr = self.next_addresses.get(account_id)
                if not addr:
                    account = self.make_account(account_id, password)
                    addr = account.first_address()
                    self.next_addresses[account_id] = addr
                    self.storage.put('next_addresses', self.next_addresses)
       -
                return account_id, addr
        
            def account_id(self, i):
       t@@ -1374,6 +1347,36 @@ class NewWallet(Deterministic_Wallet):
                account = BIP32_Account({'xpub':xpub})
                return account
        
       +    def num_accounts(self):
       +        keys = []
       +        for k, v in self.accounts.items():
       +            if type(v) != BIP32_Account:
       +                continue
       +            keys.append(k)
       +        i = 0
       +        while True:
       +            account_id = self.account_id(i)
       +            if account_id not in keys: break
       +            i += 1
       +        return i
       +
       +    def add_master_keys(self, root, account_id, password):
       +        x = self.master_private_keys.get(root)
       +        if x:
       +            master_xpriv = pw_decode(x, password )
       +            xpriv, xpub = bip32_private_derivation(master_xpriv, root, account_id)
       +            self.add_master_public_key(account_id, xpub)
       +            self.add_master_private_key(account_id, xpriv, password)
       +        else:
       +            master_xpub = self.master_public_keys[root]
       +            xpub = bip32_public_derivation(master_xpub, root, account_id)
       +            self.add_master_public_key(account_id, xpub)
       +        return xpub
       +
       +
       +
       +class NewWallet(BIP32_HD_Wallet):
       +    # BIP39 seed generation
        
            @classmethod
            def make_seed(self, custom_entropy=1):
       t@@ -1402,6 +1405,14 @@ class NewWallet(Deterministic_Wallet):
                import unicodedata
                return NEW_SEED_VERSION, unicodedata.normalize('NFC', unicode(seed.strip()))
        
       +    def create_master_keys(self, password):
       +        seed = self.get_seed(password)
       +        xpriv, xpub = bip32_root(seed)
       +        self.add_master_public_key("m/", xpub)
       +        self.add_master_private_key("m/", xpriv, password)
       +
       +
       +
        
        class Wallet_2of2(NewWallet):
            """ This class is used for multisignature addresses"""
       t@@ -1539,9 +1550,6 @@ class OldWallet(Deterministic_Wallet):
                s = self.get_seed(password)
                return ' '.join(mnemonic.mn_encode(s))
        
       -    def check_pending_accounts(self):
       -        pass
       -
            def can_sign(self, tx):
                if self.is_watching_only():
                    return False
       t@@ -1684,12 +1692,12 @@ class Wallet(object):
        
            @classmethod
            def from_xpub(self, xpub, storage):
       -        w = NewWallet(storage)
       -        w.create_watching_only_wallet(xpub)
       +        w = BIP32_Wallet(storage)
       +        w.create_xpub_wallet(xpub)
                return w
        
            @classmethod
            def from_xprv(self, xprv, password, storage):
       -        w = NewWallet(storage)
       +        w = BIP32_Wallet(storage)
                w.create_xprv_wallet(xprv, password)
                return w