URI: 
       tcoldcard: avoid creating keystore with testnet/mainnet mixed up - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit f3c1313a4fb7b2a058b0b3cfcfbdbb5551514a78
   DIR parent fa8c751abfbb83f16b4ef69d77b8ac05b424b2fb
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Wed, 18 Nov 2020 00:47:20 +0100
       
       coldcard: avoid creating keystore with testnet/mainnet mixed up
       
       fixes #6722
       
       Diffstat:
         M electrum/base_wizard.py             |       6 ++++++
         M electrum/plugins/coldcard/coldcard… |      29 ++++++++++++++---------------
         M electrum/plugins/hw_wallet/plugin.… |       7 +++++++
       
       3 files changed, 27 insertions(+), 15 deletions(-)
       ---
   DIR diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py
       t@@ -480,6 +480,12 @@ class BaseWizard(Logger):
                    'label': label,
                    'soft_device_id': soft_device_id,
                }
       +        try:
       +            client.manipulate_keystore_dict_during_wizard_setup(d)
       +        except Exception as e:
       +            self.logger.exception('')
       +            self.show_error(e)
       +            raise ChooseHwDeviceAgain()
                k = hardware_keystore(d)
                self.on_keystore(k)
        
   DIR diff --git a/electrum/plugins/coldcard/coldcard.py b/electrum/plugins/coldcard/coldcard.py
       t@@ -142,19 +142,19 @@ class CKCCClient(HardwareClientBase):
                else:
                    lab = 'Coldcard ' + xfp2str(self.dev.master_fingerprint)
        
       -        # Hack zone: during initial setup I need the xfp and master xpub but 
       -        # very few objects are passed between the various steps of base_wizard.
       -        # Solution: return a string with some hidden metadata
       -        # - see <https://stackoverflow.com/questions/7172772/abc-for-string>
       -        # - needs to work w/ deepcopy
       -        class LabelStr(str):
       -            def __new__(cls, s, xfp=None, xpub=None):
       -                self = super().__new__(cls, str(s))
       -                self.xfp = getattr(s, 'xfp', xfp)
       -                self.xpub = getattr(s, 'xpub', xpub)
       -                return self
       -
       -        return LabelStr(lab, self.dev.master_fingerprint, self.dev.master_xpub)
       +        return lab
       +
       +    def manipulate_keystore_dict_during_wizard_setup(self, d: dict):
       +        master_xpub = self.dev.master_xpub
       +        if master_xpub is not None:
       +            try:
       +                node = BIP32Node.from_xkey(master_xpub)
       +            except InvalidMasterKeyVersionBytes:
       +                raise UserFacingException(
       +                    _('Invalid xpub magic. Make sure your {} device is set to the correct chain.').format(self.device) + ' ' +
       +                    _('You might have to unplug and plug it in again.')
       +                ) from None
       +            d['ckcc_xpub'] = master_xpub
        
            @runs_in_hwd_thread
            def has_usable_connection_with_device(self):
       t@@ -262,8 +262,7 @@ class Coldcard_KeyStore(Hardware_KeyStore):
                # we need to know at least the fingerprint of the master xpub to verify against MiTM
                # - device reports these value during encryption setup process
                # - full xpub value now optional
       -        lab = d['label']
       -        self.ckcc_xpub = getattr(lab, 'xpub', None) or d.get('ckcc_xpub', None)
       +        self.ckcc_xpub = d.get('ckcc_xpub', None)
        
            def dump(self):
                # our additions to the stored data about keystore -- only during creation?
   DIR diff --git a/electrum/plugins/hw_wallet/plugin.py b/electrum/plugins/hw_wallet/plugin.py
       t@@ -266,6 +266,13 @@ class HardwareClientBase:
                """
                return None
        
       +    def manipulate_keystore_dict_during_wizard_setup(self, d: dict) -> None:
       +        """Called during wallet creation in the wizard, before the keystore
       +        is constructed for the first time. 'd' is the dict that will be
       +        passed to the keystore constructor.
       +        """
       +        pass
       +
        
        class HardwareHandlerBase:
            """An interface between the GUI and the device handling logic for handling I/O."""