def get_xpub(self, bip32_path, xtype): self.checkDevice() # bip32_path is of the form 44'/0'/1' # S-L-O-W - we don't handle the fingerprint directly, so compute # it manually from the previous node # This only happens once so it's bearable #self.get_client() # prompt for the PIN before displaying the dialog if necessary #self.handler.show_message("Computing master public key") if xtype in ['p2wpkh', 'p2wsh'] and not self.supports_native_segwit(): raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT) if xtype in ['p2wpkh-p2sh', 'p2wsh-p2sh'] and not self.supports_segwit(): raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT) bip32_path = bip32.normalize_bip32_derivation(bip32_path) bip32_intpath = bip32.convert_bip32_path_to_list_of_uint32(bip32_path) bip32_path = bip32_path[2:] # cut off "m/" if len(bip32_intpath) >= 1: prevPath = bip32.convert_bip32_intpath_to_strpath(bip32_intpath[:-1])[2:] nodeData = self.dongleObject.getWalletPublicKey(prevPath) publicKey = compress_public_key(nodeData['publicKey']) fingerprint_bytes = hash_160(publicKey)[0:4] childnum_bytes = bip32_intpath[-1].to_bytes(length=4, byteorder="big") else: fingerprint_bytes = bytes(4) childnum_bytes = bytes(4) nodeData = self.dongleObject.getWalletPublicKey(bip32_path) publicKey = compress_public_key(nodeData['publicKey']) depth = len(bip32_intpath) return BIP32Node(xtype=xtype, eckey=ecc.ECPubkey(bytes(publicKey)), chaincode=nodeData['chainCode'], depth=depth, fingerprint=fingerprint_bytes, child_number=childnum_bytes).to_xpub()
def test_normalize_bip32_derivation(self): self.assertEqual("m/0/1'/1'", normalize_bip32_derivation("m/0/1h/1'")) self.assertEqual("m", normalize_bip32_derivation("m////")) self.assertEqual("m/0/2/1'", normalize_bip32_derivation("m/0/2/-1/")) self.assertEqual("m/0/1'/1'/5'", normalize_bip32_derivation("m/0//-1/1'///5h"))
def create_storage(self, js_data, single_password_enabled, single_password): self._logger.info('Creating wallet from wizard data') data = js_data.toVariant() self._logger.debug(str(data)) if single_password_enabled and single_password: data['encrypt'] = True data['password'] = single_password try: path = os.path.join( os.path.dirname(self.daemon.config.get_wallet_path()), data['wallet_name']) if os.path.exists(path): raise Exception('file already exists at path') storage = WalletStorage(path) if data['seed_type'] in ['old', 'standard', 'segwit']: #2fa, 2fa-segwit self._logger.debug('creating keystore from electrum seed') k = keystore.from_seed(data['seed'], data['seed_extra_words'], data['wallet_type'] == 'multisig') elif data['seed_type'] == 'bip39': self._logger.debug('creating keystore from bip39 seed') root_seed = keystore.bip39_to_seed(data['seed'], data['seed_extra_words']) derivation = normalize_bip32_derivation( data['derivation_path']) script = data['script_type'] if data[ 'script_type'] != 'p2pkh' else 'standard' k = keystore.from_bip43_rootseed(root_seed, derivation, xtype=script) else: raise Exception('unsupported/unknown seed_type %s' % data['seed_type']) if data['encrypt']: if k.may_have_password(): k.update_password(None, data['password']) storage.set_password( data['password'], enc_version=StorageEncryptionVersion.USER_PASSWORD) db = WalletDB('', manual_upgrades=False) db.set_keystore_encryption( bool(data['password']) and data['encrypt']) db.put('wallet_type', data['wallet_type']) db.put('seed_type', data['seed_type']) db.put('keystore', k.dump()) if k.can_have_deterministic_lightning_xprv(): db.put( 'lightning_xprv', k.get_lightning_xprv( data['password'] if data['encrypt'] else None)) db.load_plugins() db.write(storage) # minimally populate self after create self._password = data['password'] self.path = path self.createSuccess.emit() except Exception as e: self._logger.error(str(e)) self.createError.emit(str(e))
def test_normalize_bip32_derivation(self): self.assertEqual("m/0/1'/1'", normalize_bip32_derivation("m/0/1h/1'")) self.assertEqual("m", normalize_bip32_derivation("m////")) self.assertEqual("m/0/2/1'", normalize_bip32_derivation("m/0/2/-1/")) self.assertEqual("m/0/1'/1'/5'", normalize_bip32_derivation("m/0//-1/1'///5h"))