URI: 
       tmv "electrum seed" stuff from bitcoin.py to mnemonic.py - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit b39c51adf7ef9d56bd45b1c30a86d4d415ef7940
   DIR parent e7f38467d7a592ab5288e29200cbace65e87834e
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri, 22 Feb 2019 18:01:54 +0100
       
       mv "electrum seed" stuff from bitcoin.py to mnemonic.py
       
       Diffstat:
         M electrum/base_wizard.py             |       9 +++++----
         M electrum/bitcoin.py                 |      50 -------------------------------
         M electrum/gui/qt/seed_dialog.py      |       3 +--
         M electrum/keystore.py                |       4 ++--
         M electrum/mnemonic.py                |      50 +++++++++++++++++++++++++++++--
         M electrum/old_mnemonic.py            |       6 +++---
         M electrum/plugins/trustedcoin/trust… |       4 ++--
         M electrum/tests/test_bitcoin.py      |      50 ++-----------------------------
         M electrum/tests/test_mnemonic.py     |      49 ++++++++++++++++++++++++++++++-
         M electrum/tests/test_wallet_vertica… |      17 +++++++++--------
       
       10 files changed, 120 insertions(+), 122 deletions(-)
       ---
   DIR diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py
       t@@ -31,6 +31,7 @@ from typing import List, TYPE_CHECKING, Tuple, NamedTuple, Any
        
        from . import bitcoin
        from . import keystore
       +from . import mnemonic
        from .bip32 import is_bip32_derivation, xpub_type
        from .keystore import bip44_derivation, purpose48_derivation
        from .wallet import (Imported_Wallet, Standard_Wallet, Multisig_Wallet,
       t@@ -429,12 +430,12 @@ class BaseWizard(object):
            def restore_from_seed(self):
                self.opt_bip39 = True
                self.opt_ext = True
       -        is_cosigning_seed = lambda x: bitcoin.seed_type(x) in ['standard', 'segwit']
       -        test = bitcoin.is_seed if self.wallet_type == 'standard' else is_cosigning_seed
       +        is_cosigning_seed = lambda x: mnemonic.seed_type(x) in ['standard', 'segwit']
       +        test = mnemonic.is_seed if self.wallet_type == 'standard' else is_cosigning_seed
                self.restore_seed_dialog(run_next=self.on_restore_seed, test=test)
        
            def on_restore_seed(self, seed, is_bip39, is_ext):
       -        self.seed_type = 'bip39' if is_bip39 else bitcoin.seed_type(seed)
       +        self.seed_type = 'bip39' if is_bip39 else mnemonic.seed_type(seed)
                if self.seed_type == 'bip39':
                    f = lambda passphrase: self.on_restore_bip39(seed, passphrase)
                    self.passphrase_dialog(run_next=f, is_restoring=True) if is_ext else f('')
       t@@ -443,7 +444,7 @@ class BaseWizard(object):
                    self.passphrase_dialog(run_next=f, is_restoring=True) if is_ext else f('')
                elif self.seed_type == 'old':
                    self.run('create_keystore', seed, '')
       -        elif bitcoin.is_any_2fa_seed_type(self.seed_type):
       +        elif mnemonic.is_any_2fa_seed_type(self.seed_type):
                    self.load_2fa()
                    self.run('on_restore_seed', seed, is_ext)
                else:
   DIR diff --git a/electrum/bitcoin.py b/electrum/bitcoin.py
       t@@ -310,56 +310,6 @@ def hash_decode(x: str) -> bytes:
            return bfh(x)[::-1]
        
        
       -################################## electrum seeds
       -
       -
       -def is_new_seed(x: str, prefix=version.SEED_PREFIX) -> bool:
       -    from . import mnemonic
       -    x = mnemonic.normalize_text(x)
       -    s = bh2u(hmac_oneshot(b"Seed version", x.encode('utf8'), hashlib.sha512))
       -    return s.startswith(prefix)
       -
       -
       -def is_old_seed(seed: str) -> bool:
       -    from . import old_mnemonic, mnemonic
       -    seed = mnemonic.normalize_text(seed)
       -    words = seed.split()
       -    try:
       -        # checks here are deliberately left weak for legacy reasons, see #3149
       -        old_mnemonic.mn_decode(words)
       -        uses_electrum_words = True
       -    except Exception:
       -        uses_electrum_words = False
       -    try:
       -        seed = bfh(seed)
       -        is_hex = (len(seed) == 16 or len(seed) == 32)
       -    except Exception:
       -        is_hex = False
       -    return is_hex or (uses_electrum_words and (len(words) == 12 or len(words) == 24))
       -
       -
       -def seed_type(x: str) -> str:
       -    if is_old_seed(x):
       -        return 'old'
       -    elif is_new_seed(x):
       -        return 'standard'
       -    elif is_new_seed(x, version.SEED_PREFIX_SW):
       -        return 'segwit'
       -    elif is_new_seed(x, version.SEED_PREFIX_2FA):
       -        return '2fa'
       -    elif is_new_seed(x, version.SEED_PREFIX_2FA_SW):
       -        return '2fa_segwit'
       -    return ''
       -
       -
       -def is_seed(x: str) -> bool:
       -    return bool(seed_type(x))
       -
       -
       -def is_any_2fa_seed_type(seed_type):
       -    return seed_type in ['2fa', '2fa_segwit']
       -
       -
        ############ functions from pywallet #####################
        
        def hash160_to_b58_address(h160: bytes, addrtype: int) -> str:
   DIR diff --git a/electrum/gui/qt/seed_dialog.py b/electrum/gui/qt/seed_dialog.py
       t@@ -29,7 +29,7 @@ from PyQt5.QtWidgets import (QVBoxLayout, QCheckBox, QHBoxLayout, QLineEdit,
                                     QLabel, QCompleter, QDialog)
        
        from electrum.i18n import _
       -from electrum.mnemonic import Mnemonic
       +from electrum.mnemonic import Mnemonic, seed_type
        import electrum.old_mnemonic
        
        from .util import (Buttons, OkButton, WWLabel, ButtonsTextEdit, icon_path,
       t@@ -161,7 +161,6 @@ class SeedLayout(QVBoxLayout):
                return ' '.join(text.split())
        
            def on_edit(self):
       -        from electrum.bitcoin import seed_type
                s = self.get_seed()
                b = self.is_seed(s)
                if not self.is_bip39:
   DIR diff --git a/electrum/keystore.py b/electrum/keystore.py
       t@@ -30,7 +30,7 @@ from typing import Tuple
        
        from . import bitcoin, ecc, constants, bip32
        from .bitcoin import (deserialize_privkey, serialize_privkey,
       -                      public_key_to_p2pkh, seed_type, is_seed)
       +                      public_key_to_p2pkh)
        from .bip32 import (bip32_public_derivation, deserialize_xpub, CKD_pub,
                            bip32_root, deserialize_xprv, bip32_private_derivation,
                            bip32_private_key, bip32_derivation, BIP32_PRIME,
       t@@ -40,7 +40,7 @@ from .crypto import (pw_decode, pw_encode, sha256, sha256d, PW_HASH_VERSION_LATE
                             SUPPORTED_PW_HASH_VERSIONS, UnsupportedPasswordHashVersion)
        from .util import (PrintError, InvalidPassword, WalletFileException,
                           BitcoinException, bh2u, bfh, print_error, inv_dict)
       -from .mnemonic import Mnemonic, load_wordlist
       +from .mnemonic import Mnemonic, load_wordlist, seed_type, is_seed
        from .plugin import run_hook
        
        
   DIR diff --git a/electrum/mnemonic.py b/electrum/mnemonic.py
       t@@ -30,8 +30,8 @@ import string
        
        import ecdsa
        
       -from .util import print_error, resource_path
       -from .bitcoin import is_old_seed, is_new_seed
       +from .util import print_error, resource_path, bfh, bh2u
       +from .crypto import hmac_oneshot
        from . import version
        
        # http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/e_asia.html
       t@@ -181,3 +181,49 @@ class Mnemonic(object):
                        break
                print_error('%d words'%len(seed.split()))
                return seed
       +
       +
       +def is_new_seed(x: str, prefix=version.SEED_PREFIX) -> bool:
       +    x = normalize_text(x)
       +    s = bh2u(hmac_oneshot(b"Seed version", x.encode('utf8'), hashlib.sha512))
       +    return s.startswith(prefix)
       +
       +
       +def is_old_seed(seed: str) -> bool:
       +    from . import old_mnemonic
       +    seed = normalize_text(seed)
       +    words = seed.split()
       +    try:
       +        # checks here are deliberately left weak for legacy reasons, see #3149
       +        old_mnemonic.mn_decode(words)
       +        uses_electrum_words = True
       +    except Exception:
       +        uses_electrum_words = False
       +    try:
       +        seed = bfh(seed)
       +        is_hex = (len(seed) == 16 or len(seed) == 32)
       +    except Exception:
       +        is_hex = False
       +    return is_hex or (uses_electrum_words and (len(words) == 12 or len(words) == 24))
       +
       +
       +def seed_type(x: str) -> str:
       +    if is_old_seed(x):
       +        return 'old'
       +    elif is_new_seed(x):
       +        return 'standard'
       +    elif is_new_seed(x, version.SEED_PREFIX_SW):
       +        return 'segwit'
       +    elif is_new_seed(x, version.SEED_PREFIX_2FA):
       +        return '2fa'
       +    elif is_new_seed(x, version.SEED_PREFIX_2FA_SW):
       +        return '2fa_segwit'
       +    return ''
       +
       +
       +def is_seed(x: str) -> bool:
       +    return bool(seed_type(x))
       +
       +
       +def is_any_2fa_seed_type(seed_type: str) -> bool:
       +    return seed_type in ['2fa', '2fa_segwit']
   DIR diff --git a/electrum/old_mnemonic.py b/electrum/old_mnemonic.py
       t@@ -1652,13 +1652,13 @@ words = [
        "total",
        "unseen",
        "weapon",
       -"weary"
       +"weary",
        ]
        
       +n = len(words)
       +assert n == 1626
        
        
       -n = 1626
       -
        # Note about US patent no 5892470: Here each word does not represent a given digit.
        # Instead, the digit represented by a word is variable, it depends on the previous word.
        
   DIR diff --git a/electrum/plugins/trustedcoin/trustedcoin.py b/electrum/plugins/trustedcoin/trustedcoin.py
       t@@ -36,12 +36,12 @@ from urllib.parse import quote
        from aiohttp import ClientResponse
        
        from electrum import ecc, constants, keystore, version, bip32, bitcoin
       -from electrum.bitcoin import TYPE_ADDRESS, is_new_seed, seed_type, is_any_2fa_seed_type
       +from electrum.bitcoin import TYPE_ADDRESS
        from electrum.bip32 import (deserialize_xpub, deserialize_xprv, bip32_private_key, CKD_pub,
                                    serialize_xpub, bip32_root, bip32_private_derivation, xpub_type)
        from electrum.crypto import sha256
        from electrum.transaction import TxOutput
       -from electrum.mnemonic import Mnemonic
       +from electrum.mnemonic import Mnemonic, seed_type, is_any_2fa_seed_type
        from electrum.wallet import Multisig_Wallet, Deterministic_Wallet
        from electrum.i18n import _
        from electrum.plugin import BasePlugin, hook
   DIR diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py
       t@@ -2,11 +2,11 @@ import base64
        import sys
        
        from electrum.bitcoin import (public_key_to_p2pkh, address_from_private_key,
       -                              is_address, is_private_key, is_new_seed, is_old_seed,
       +                              is_address, is_private_key,
                                      var_int, _op_push, address_to_script,
                                      deserialize_privkey, serialize_privkey, is_segwit_address,
                                      is_b58_address, address_to_scripthash, is_minikey,
       -                              is_compressed_privkey, seed_type, EncodeBase58Check,
       +                              is_compressed_privkey, EncodeBase58Check,
                                      script_num_to_hex, push_script, add_number_to_script, int_to_hex,
                                      opcodes)
        from electrum.bip32 import (bip32_root, bip32_public_derivation, bip32_private_derivation,
       t@@ -719,49 +719,3 @@ class Test_keyImport(SequentialTestCase):
                for priv_details in self.priv_pub_addr:
                    self.assertEqual(priv_details['compressed'],
                                     is_compressed_privkey(priv_details['priv']))
       -
       -
       -class Test_seeds(SequentialTestCase):
       -    """ Test old and new seeds. """
       -
       -    mnemonics = {
       -        ('cell dumb heartbeat north boom tease ship baby bright kingdom rare squeeze', 'old'),
       -        ('cell dumb heartbeat north boom tease ' * 4, 'old'),
       -        ('cell dumb heartbeat north boom tease ship baby bright kingdom rare badword', ''),
       -        ('cElL DuMb hEaRtBeAt nOrTh bOoM TeAsE ShIp bAbY BrIgHt kInGdOm rArE SqUeEzE', 'old'),
       -        ('   cElL  DuMb hEaRtBeAt nOrTh bOoM  TeAsE ShIp    bAbY BrIgHt kInGdOm rArE SqUeEzE   ', 'old'),
       -        # below seed is actually 'invalid old' as it maps to 33 hex chars
       -        ('hurry idiot prefer sunset mention mist jaw inhale impossible kingdom rare squeeze', 'old'),
       -        ('cram swing cover prefer miss modify ritual silly deliver chunk behind inform able', 'standard'),
       -        ('cram swing cover prefer miss modify ritual silly deliver chunk behind inform', ''),
       -        ('ostrich security deer aunt climb inner alpha arm mutual marble solid task', 'standard'),
       -        ('OSTRICH SECURITY DEER AUNT CLIMB INNER ALPHA ARM MUTUAL MARBLE SOLID TASK', 'standard'),
       -        ('   oStRiCh sEcUrItY DeEr aUnT ClImB       InNeR AlPhA ArM MuTuAl mArBlE   SoLiD TaSk  ', 'standard'),
       -        ('x8', 'standard'),
       -        ('science dawn member doll dutch real can brick knife deny drive list', '2fa'),
       -        ('science dawn member doll dutch real ca brick knife deny drive list', ''),
       -        (' sCience dawn   member doll Dutch rEAl can brick knife deny drive  lisT', '2fa'),
       -        ('frost pig brisk excite novel report camera enlist axis nation novel desert', 'segwit'),
       -        ('  fRoSt pig brisk excIte novel rePort CamEra enlist axis nation nOVeL dEsert ', 'segwit'),
       -        ('9dk', 'segwit'),
       -    }
       -
       -    def test_new_seed(self):
       -        seed = "cram swing cover prefer miss modify ritual silly deliver chunk behind inform able"
       -        self.assertTrue(is_new_seed(seed))
       -
       -        seed = "cram swing cover prefer miss modify ritual silly deliver chunk behind inform"
       -        self.assertFalse(is_new_seed(seed))
       -
       -    def test_old_seed(self):
       -        self.assertTrue(is_old_seed(" ".join(["like"] * 12)))
       -        self.assertFalse(is_old_seed(" ".join(["like"] * 18)))
       -        self.assertTrue(is_old_seed(" ".join(["like"] * 24)))
       -        self.assertFalse(is_old_seed("not a seed"))
       -
       -        self.assertTrue(is_old_seed("0123456789ABCDEF" * 2))
       -        self.assertTrue(is_old_seed("0123456789ABCDEF" * 4))
       -
       -    def test_seed_type(self):
       -        for seed_words, _type in self.mnemonics:
       -            self.assertEqual(_type, seed_type(seed_words), msg=seed_words)
   DIR diff --git a/electrum/tests/test_mnemonic.py b/electrum/tests/test_mnemonic.py
       t@@ -4,7 +4,7 @@ from electrum import keystore
        from electrum import mnemonic
        from electrum import old_mnemonic
        from electrum.util import bh2u, bfh
       -from electrum.bitcoin import is_new_seed
       +from electrum.mnemonic import is_new_seed, is_old_seed, seed_type
        from electrum.version import SEED_PREFIX_SW, SEED_PREFIX
        
        from . import SequentialTestCase
       t@@ -134,6 +134,7 @@ class Test_OldMnemonic(SequentialTestCase):
                self.assertEqual(result, words.split())
                self.assertEqual(old_mnemonic.mn_decode(result), seed)
        
       +
        class Test_BIP39Checksum(SequentialTestCase):
        
            def test(self):
       t@@ -141,3 +142,49 @@ class Test_BIP39Checksum(SequentialTestCase):
                is_checksum_valid, is_wordlist_valid = keystore.bip39_is_checksum_valid(mnemonic)
                self.assertTrue(is_wordlist_valid)
                self.assertTrue(is_checksum_valid)
       +
       +
       +class Test_seeds(SequentialTestCase):
       +    """ Test old and new seeds. """
       +
       +    mnemonics = {
       +        ('cell dumb heartbeat north boom tease ship baby bright kingdom rare squeeze', 'old'),
       +        ('cell dumb heartbeat north boom tease ' * 4, 'old'),
       +        ('cell dumb heartbeat north boom tease ship baby bright kingdom rare badword', ''),
       +        ('cElL DuMb hEaRtBeAt nOrTh bOoM TeAsE ShIp bAbY BrIgHt kInGdOm rArE SqUeEzE', 'old'),
       +        ('   cElL  DuMb hEaRtBeAt nOrTh bOoM  TeAsE ShIp    bAbY BrIgHt kInGdOm rArE SqUeEzE   ', 'old'),
       +        # below seed is actually 'invalid old' as it maps to 33 hex chars
       +        ('hurry idiot prefer sunset mention mist jaw inhale impossible kingdom rare squeeze', 'old'),
       +        ('cram swing cover prefer miss modify ritual silly deliver chunk behind inform able', 'standard'),
       +        ('cram swing cover prefer miss modify ritual silly deliver chunk behind inform', ''),
       +        ('ostrich security deer aunt climb inner alpha arm mutual marble solid task', 'standard'),
       +        ('OSTRICH SECURITY DEER AUNT CLIMB INNER ALPHA ARM MUTUAL MARBLE SOLID TASK', 'standard'),
       +        ('   oStRiCh sEcUrItY DeEr aUnT ClImB       InNeR AlPhA ArM MuTuAl mArBlE   SoLiD TaSk  ', 'standard'),
       +        ('x8', 'standard'),
       +        ('science dawn member doll dutch real can brick knife deny drive list', '2fa'),
       +        ('science dawn member doll dutch real ca brick knife deny drive list', ''),
       +        (' sCience dawn   member doll Dutch rEAl can brick knife deny drive  lisT', '2fa'),
       +        ('frost pig brisk excite novel report camera enlist axis nation novel desert', 'segwit'),
       +        ('  fRoSt pig brisk excIte novel rePort CamEra enlist axis nation nOVeL dEsert ', 'segwit'),
       +        ('9dk', 'segwit'),
       +    }
       +
       +    def test_new_seed(self):
       +        seed = "cram swing cover prefer miss modify ritual silly deliver chunk behind inform able"
       +        self.assertTrue(is_new_seed(seed))
       +
       +        seed = "cram swing cover prefer miss modify ritual silly deliver chunk behind inform"
       +        self.assertFalse(is_new_seed(seed))
       +
       +    def test_old_seed(self):
       +        self.assertTrue(is_old_seed(" ".join(["like"] * 12)))
       +        self.assertFalse(is_old_seed(" ".join(["like"] * 18)))
       +        self.assertTrue(is_old_seed(" ".join(["like"] * 24)))
       +        self.assertFalse(is_old_seed("not a seed"))
       +
       +        self.assertTrue(is_old_seed("0123456789ABCDEF" * 2))
       +        self.assertTrue(is_old_seed("0123456789ABCDEF" * 4))
       +
       +    def test_seed_type(self):
       +        for seed_words, _type in self.mnemonics:
       +            self.assertEqual(_type, seed_type(seed_words), msg=seed_words)
   DIR diff --git a/electrum/tests/test_wallet_vertical.py b/electrum/tests/test_wallet_vertical.py
       t@@ -11,6 +11,7 @@ from electrum.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCON
        from electrum.wallet import sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet
        from electrum.util import bfh, bh2u
        from electrum.transaction import TxOutput
       +from electrum.mnemonic import seed_type
        
        from electrum.plugins.trustedcoin import trustedcoin
        
       t@@ -80,7 +81,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_seed_standard(self, mock_write):
                seed_words = 'cycle rocket west magnet parrot shuffle foot correct salt library feed song'
       -        self.assertEqual(bitcoin.seed_type(seed_words), 'standard')
       +        self.assertEqual(seed_type(seed_words), 'standard')
        
                ks = keystore.from_seed(seed_words, '', False)
        
       t@@ -100,7 +101,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_seed_segwit(self, mock_write):
                seed_words = 'bitter grass shiver impose acquire brush forget axis eager alone wine silver'
       -        self.assertEqual(bitcoin.seed_type(seed_words), 'segwit')
       +        self.assertEqual(seed_type(seed_words), 'segwit')
        
                ks = keystore.from_seed(seed_words, '', False)
        
       t@@ -120,7 +121,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_seed_segwit_passphrase(self, mock_write):
                seed_words = 'bitter grass shiver impose acquire brush forget axis eager alone wine silver'
       -        self.assertEqual(bitcoin.seed_type(seed_words), 'segwit')
       +        self.assertEqual(seed_type(seed_words), 'segwit')
        
                ks = keystore.from_seed(seed_words, UNICODE_HORROR, False)
        
       t@@ -140,7 +141,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_seed_old(self, mock_write):
                seed_words = 'powerful random nobody notice nothing important anyway look away hidden message over'
       -        self.assertEqual(bitcoin.seed_type(seed_words), 'old')
       +        self.assertEqual(seed_type(seed_words), 'old')
        
                ks = keystore.from_seed(seed_words, '', False)
        
       t@@ -159,7 +160,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_seed_2fa_legacy(self, mock_write):
                seed_words = 'kiss live scene rude gate step hip quarter bunker oxygen motor glove'
       -        self.assertEqual(bitcoin.seed_type(seed_words), '2fa')
       +        self.assertEqual(seed_type(seed_words), '2fa')
        
                xprv1, xpub1, xprv2, xpub2 = trustedcoin.TrustedCoinPlugin.xkeys_from_seed(seed_words, '')
        
       t@@ -194,7 +195,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_seed_2fa_segwit(self, mock_write):
                seed_words = 'universe topic remind silver february ranch shine worth innocent cattle enhance wise'
       -        self.assertEqual(bitcoin.seed_type(seed_words), '2fa_segwit')
       +        self.assertEqual(seed_type(seed_words), '2fa_segwit')
        
                xprv1, xpub1, xprv2, xpub2 = trustedcoin.TrustedCoinPlugin.xkeys_from_seed(seed_words, '')
        
       t@@ -306,7 +307,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_multisig_seed_standard(self, mock_write):
                seed_words = 'blast uniform dragon fiscal ensure vast young utility dinosaur abandon rookie sure'
       -        self.assertEqual(bitcoin.seed_type(seed_words), 'standard')
       +        self.assertEqual(seed_type(seed_words), 'standard')
        
                ks1 = keystore.from_seed(seed_words, '', True)
                WalletIntegrityHelper.check_seeded_keystore_sanity(self, ks1)
       t@@ -329,7 +330,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_electrum_multisig_seed_segwit(self, mock_write):
                seed_words = 'snow nest raise royal more walk demise rotate smooth spirit canyon gun'
       -        self.assertEqual(bitcoin.seed_type(seed_words), 'segwit')
       +        self.assertEqual(seed_type(seed_words), 'segwit')
        
                ks1 = keystore.from_seed(seed_words, '', True)
                WalletIntegrityHelper.check_seeded_keystore_sanity(self, ks1)