From d89dcdeaf8a487632a87f4b681e1686b9613e3e5 Mon Sep 17 00:00:00 2001 From: Kristaps Kaupe Date: Thu, 1 Feb 2024 21:23:26 +0200 Subject: [PATCH] Remove convert_old_wallet.py script Old wallet format isn't used for years and script is broken since removal of pyaes dependency. If somebody still needs it, he can use older JoinMarket version to do conversion. --- scripts/convert_old_wallet.py | 168 ---------------------------------- src/jmclient/wallet_utils.py | 4 +- 2 files changed, 1 insertion(+), 171 deletions(-) delete mode 100755 scripts/convert_old_wallet.py diff --git a/scripts/convert_old_wallet.py b/scripts/convert_old_wallet.py deleted file mode 100755 index b9f663d8f..000000000 --- a/scripts/convert_old_wallet.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import json -import os.path -from hashlib import sha256 -from binascii import hexlify, unhexlify -from collections import defaultdict -from pyaes import AESModeOfOperationCBC, Decrypter -from jmbase import JM_APP_NAME -from jmclient import Storage, load_program_config, BTCEngine, BaseWallet -from jmclient.wallet_utils import get_password, get_wallet_cls,\ - cli_get_wallet_passphrase_check, get_wallet_path, \ - get_configured_wallet_type - - -class ConvertException(Exception): - pass - - -def get_max_mixdepth(data): - return max(1, len(data.get('index_cache', [1])) - 1, - *data.get('imported', {}).keys()) - - -def is_encrypted(wallet_data): - return 'encrypted_seed' in wallet_data or 'encrypted_entropy' in wallet_data - - -def double_sha256(plaintext): - return sha256(sha256(plaintext).digest()).digest() - - -def decrypt_data(key, data): - decrypter = Decrypter(AESModeOfOperationCBC(key, iv=data[:16])) - plain = decrypter.feed(data[16:]) - plain += decrypter.feed() - return plain - - -def decrypt_entropy_extension(enc_data, key): - data = decrypt_data(key, unhexlify(enc_data)) - if data[-9] != b'\xff': - raise ConvertException("Wrong password.") - chunks = data.split(b'\xff') - if len(chunks) < 3 or data[-8:] != hexlify(double_sha256(chunks[1]).decode('ascii')[:4]): - raise ConvertException("Wrong password.") - return chunks[1] - - -def decrypt_wallet_data(data, password): - key = double_sha256(password) - - enc_entropy = data.get('encrypted_seed') or data.get('encrypted_entropy') - enc_entropy_ext = data.get('encrypted_mnemonic_extension') - enc_imported = data.get('imported_keys') - - entropy = decrypt_data(key, unhexlify(enc_entropy)) - data['entropy'] = entropy - if enc_entropy_ext: - data['entropy_ext'] = decrypt_entropy_extension(enc_entropy_ext, key) - - if enc_imported: - imported_keys = defaultdict(list) - for e in enc_imported: - md = int(e['mixdepth']) - imported_enc_key = unhexlify(e['encrypted_privkey']) - imported_key = decrypt_data(key, imported_enc_key) - imported_keys[md].append(imported_key) - data['imported'] = imported_keys - - -def new_wallet_from_data(data, file_name): - print("Creating new wallet file.") - new_pw = cli_get_wallet_passphrase_check() - if new_pw is False: - return False - - storage = Storage(file_name, create=True, password=new_pw) - wallet_cls = get_wallet_cls(wtype=get_configured_wallet_type(False)) - - kwdata = { - 'entropy': data['entropy'], - 'timestamp': data.get('creation_time'), - 'max_mixdepth': get_max_mixdepth(data) - } - - if 'entropy_ext' in data: - kwdata['entropy_extension'] = data['entropy_ext'] - - wallet_cls.initialize(storage, data['network'], **kwdata) - wallet = wallet_cls(storage) - - if 'index_cache' in data: - for md, indices in enumerate(data['index_cache']): - wallet.set_next_index(md, BaseWallet.ADDRESS_TYPE_EXTERNAL, - indices[0], force=True) - wallet.set_next_index(md, BaseWallet.ADDRESS_TYPE_INTERNAL, - indices[1], force=True) - - if 'imported' in data: - for md in data['imported']: - for privkey in data['imported'][md]: - privkey += b'\x01' - wif = BTCEngine.privkey_to_wif(privkey) - wallet.import_private_key(md, wif) - - wallet.save() - wallet.close() - return True - - -def parse_old_wallet(fh): - file_data = json.load(fh) - - if is_encrypted(file_data): - pw = get_password("Enter password for old wallet file: ") - try: - decrypt_wallet_data(file_data, pw) - except ValueError: - print("Failed to open wallet: bad password") - return - except Exception as e: - print("Error: {}".format(e)) - print("Failed to open wallet. Wrong password?") - return - - return file_data - - -def main(): - parser = argparse.ArgumentParser( - description="Convert old joinmarket json wallet format to new jmdat " - "format") - parser.add_argument('old_wallet_file', type=open) - parser.add_argument('--name', '-n', required=False, dest='name', - help="Name of the new wallet file. Default: [old wallet name].jmdat") - # hack; not using jmclient.add_base_options because ArgumentParser not OptionParser: - parser.add_argument( - '--datadir', - dest='datadir', - default="", - help='Specify the path to a directory you want to use to store your user' - 'data - wallets, logs and commitment files - and your joinmarket.cfg. ' - 'By default, the directory .' + JM_APP_NAME + ' is used.' - ) - - try: - args = parser.parse_args() - except Exception as e: - print("Error: {}".format(e)) - return - load_program_config(config_path=args.datadir) - data = parse_old_wallet(args.old_wallet_file) - - if not data: - return - - file_name = args.name or\ - os.path.split(args.old_wallet_file.name)[-1].rsplit('.', 1)[0] + '.jmdat' - wallet_path = get_wallet_path(file_name, None) - if new_wallet_from_data(data, wallet_path): - print("New wallet file created at {}".format(wallet_path)) - else: - print("Failed to convert wallet.") - - -if __name__ == '__main__': - main() diff --git a/src/jmclient/wallet_utils.py b/src/jmclient/wallet_utils.py index 28fe4d323..8956e7331 100644 --- a/src/jmclient/wallet_utils.py +++ b/src/jmclient/wallet_utils.py @@ -1518,9 +1518,7 @@ def open_wallet(path, ask_for_password=True, password=None, read_only=False, if not Storage.is_storage_file(path): raise Exception("Failed to open wallet at '{}': not a valid joinmarket" - " wallet.\n\nIf this wallet is in the old json format " - "you need to convert it using the conversion script " - "at `scripts/convert_old_wallet.py`".format(path)) + " wallet.".format(path)) if ask_for_password and Storage.is_encrypted_storage_file(path): while True: