<gh_stars>1-10
import os
import csv
import json
import unittest
from btc_hd_wallet.paper_wallet import PaperWallet


class TestColdWallet(unittest.TestCase):
    mnemonic = (
        "vast tell razor drip stick one engine action "
        "width sport else try scare phone blouse view "
        "program ketchup pole rapid use length student raven"
    )
    wallet = PaperWallet.from_mnemonic(mnemonic=mnemonic)
    wallet_testnet = PaperWallet.from_mnemonic(mnemonic=mnemonic, testnet=True)

    @staticmethod
    def load_csv_file(_file):
        with open(_file, "r") as f:
            csv_f = list(csv.reader(f, delimiter=','))
        return csv_f

    def test_bip44(self):
        m44h0h0h0 = "<KEY>"
        M44h0h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet.bip44()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip44_vast_tell_razor_drip_stick_one_engine"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m44h0h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip44_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M44h0h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip44_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            # paths differ -> as imported key is treated as root
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            # private key - last element in the list - is None --> watch only
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip49(self):
        m49h0h0h0 = "<KEY>"
        M49h0h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet.bip49()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip49_vast_tell_razor_drip_stick_one_engine"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m49h0h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip49_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M49h0h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip49_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip84(self):
        m84h0h0h0 = "<KEY>"
        M84h0h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet.bip84()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip84_vast_tell_razor_drip_stick_one_engine"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m84h0h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip84_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M84h0h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip84_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip44_testnet(self):
        m44h1h0h0 = "<KEY>"
        M44h1h0h0 = "<KEY>"
        node_m44h1h0h0 = self.wallet_testnet.by_path(path="m/44'/1'/0'/0")
        self.assertEqual(node_m44h1h0h0.extended_private_key(), m44h1h0h0)
        self.assertEqual(node_m44h1h0h0.extended_public_key(), M44h1h0h0)
        acct_ext_keys, wallet = self.wallet_testnet.bip44()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip44_vast_tell_razor_drip_stick_one_engine-testnet"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m44h1h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip44_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M44h1h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip44_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            # paths differ -> as imported key is treated as root
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            # private key - last element in the list - is None --> watch only
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip49_testnet(self):
        m49h1h0h0 = "<KEY>"
        M49h1h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet_testnet.bip49()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip49_vast_tell_razor_drip_stick_one_engine-testnet"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m49h1h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip49_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M49h1h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip49_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip84_testnet(self):
        m84h1h0h0 = "<KEY>"
        M84h1h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet_testnet.bip84()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip84_vast_tell_razor_drip_stick_one_engine-testnet"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m84h1h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip84_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M84h1h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip84_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_generate_mainnet(self):
        pw = self.wallet.generate(account=100)

        xpub = "<KEY>"
        xprv = "<KEY>"
        ypub = "<KEY>"
        yprv = "<KEY>"
        zpub = "<KEY>"
        zprv = "<KEY>"

        self.assertEqual(pw["BIP44"]["account_extended_keys"]["pub"], xpub)
        self.assertEqual(pw["BIP44"]["account_extended_keys"]["prv"], xprv)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["pub"], ypub)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["prv"], yprv)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["pub"], zpub)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["prv"], zprv)

        address = "13UkPjRAmH1sDWuoX1zeL8yCFWXdwPvGAE"
        pubkey = "03597d9a56c46c0e6e1827525bb517c5a8dfe21ace626f31a2e11c4e4e23cd353e"
        wif = "<KEY>"
        self.assertEqual(pw["BIP44"]["groups"][19][1], address)
        self.assertEqual(pw["BIP44"]["groups"][19][2], pubkey)
        self.assertEqual(pw["BIP44"]["groups"][19][3], wif)

        address = "3EGt757gbPFn1z5uvrUMhTcwKmxK78jsvC"
        pubkey = "020a0aff849f9addb615ef67ada2dfddbc59c377ab5668f2713bb379cc9d0f287b"
        wif = "L2PRabCy4qhKJTYkbcA6MEm2hC6DyPqSFj7jsCvNpHkU8DpmDWJR"
        self.assertEqual(pw["BIP49"]["groups"][19][1], address)
        self.assertEqual(pw["BIP49"]["groups"][19][2], pubkey)
        self.assertEqual(pw["BIP49"]["groups"][19][3], wif)

        address = "bc1q9gxcsd5wmdrg5909628kx96384h0w5dyyj82gz"
        pubkey = "03c66906128c24b82babeaea82205c10b0eeb09413da198ed8aa1337b82ac0d028"
        wif = "KzyLyHiys138p2EY4fPCV9JZfz6wVE4x6DeMg9HGM9eaXQkRENtF"
        self.assertEqual(pw["BIP84"]["groups"][19][1], address)
        self.assertEqual(pw["BIP84"]["groups"][19][2], pubkey)
        self.assertEqual(pw["BIP84"]["groups"][19][3], wif)

    def test_generate_testnet(self):
        pw = self.wallet_testnet.generate(account=66, interval=(0, 50))

        tpub = "<KEY>"
        tprv = "<KEY>"
        upub = "<KEY>"
        uprv = "<KEY>"
        vpub = "<KEY>"
        vprv = "<KEY>"

        self.assertEqual(pw["BIP44"]["account_extended_keys"]["pub"], tpub)
        self.assertEqual(pw["BIP44"]["account_extended_keys"]["prv"], tprv)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["pub"], upub)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["prv"], uprv)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["pub"], vpub)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["prv"], vprv)

        address = "mjXHL5oujxymKFdRUpLbAxFGU9ZaGvhPQ4"
        pubkey = "<KEY>"
        wif = "cUbsTivUmb1dcpGwbRMsCznmwLZMuT85akmScPtwEhco4EQ9xDtD"
        self.assertEqual(pw["BIP44"]["groups"][49][1], address)
        self.assertEqual(pw["BIP44"]["groups"][49][2], pubkey)
        self.assertEqual(pw["BIP44"]["groups"][49][3], wif)

        address = "2N6yVCdJu6Z3o3mUQfQizeVi1yNYEXwYEVe"
        pubkey = "02e10c0eddc2456720e337359948204f5cdc0ca05da6a3b5ac48580316e7fc9278"
        wif = "cSDgEWgZxSHJq36H6ou4jwnEG14Qdx7QwdMvvgLREdE932DFbwT2"
        self.assertEqual(pw["BIP49"]["groups"][49][1], address)
        self.assertEqual(pw["BIP49"]["groups"][49][2], pubkey)
        self.assertEqual(pw["BIP49"]["groups"][49][3], wif)

        address = "tb1q8fa5tlqsvs38knnn79y8lzduy7lznvhv74mvfs"
        pubkey = "<KEY>"
        wif = "cUpJB4hmzFgQL4oo33td3FYmGy3CatxWyPkSGtdrS4kfRRgPsqK9"
        self.assertEqual(pw["BIP84"]["groups"][49][1], address)
        self.assertEqual(pw["BIP84"]["groups"][49][2], pubkey)
        self.assertEqual(pw["BIP84"]["groups"][49][3], wif)

    def test_watch_only_generate_failure(self):
        # cannot do hardened ckd
        xpub = "<KEY>"
        w = PaperWallet.from_extended_key(extended_key=xpub)
        self.assertTrue(w.watch_only)
        with self.assertRaises(RuntimeError):
            w.generate()

    def test_master_data(self):
        md = self.wallet.master_data()
        self.assertEqual(md["mnemonic"], self.wallet.mnemonic)
        self.assertEqual(md["password"], self.wallet.password)

        md = self.wallet_testnet.master_data()
        self.assertEqual(md["mnemonic"], self.wallet_testnet.mnemonic)
        self.assertEqual(md["password"], self.wallet_testnet.password)

    def test_json(self):
        json_ = self.wallet.json()
        self.assertIsInstance(json_, str)
        self.assertEqual(self.wallet.generate(), json.loads(json_))

        json_ = self.wallet_testnet.json()
        self.assertIsInstance(json_, str)
        self.assertEqual(self.wallet_testnet.generate(), json.loads(json_))

    def test_wasabi_json(self):
        expect = '{"ExtPubKey": "<KEY>", "MasterFingerprint": "2D36E0EB", "ColdCardFirmwareVersion": "3.1.3"}'
        json_ = self.wallet.wasabi_json()
        self.assertEqual(json_, expect)

        expect = '{"ExtPubKey": "<KEY>", "MasterFingerprint": "2D36E0EB", "ColdCardFirmwareVersion": "3.1.3"}'
        json_ = self.wallet_testnet.wasabi_json()
        self.assertEqual(json_, expect)

    def load_file_data(self, file_path):
        self.assertTrue(os.path.isfile(file_path))
        with open(file_path, "r") as f:
            data = json.loads(f.read())
        os.remove(file_path)
        self.assertFalse(os.path.isfile(file_path))
        return data

    def test_export_wallet(self):
        expected_mainnet = self.wallet.generate()
        filename_mainnet = "wallet.json"
        self.wallet.export_wallet(file_path=filename_mainnet)
        data_mainnet = self.load_file_data(file_path=filename_mainnet)
        self.assertEqual(expected_mainnet, data_mainnet)

        expected_testnet = self.wallet_testnet.generate()
        filename_testnet = "wallet_testnet.json"
        self.wallet_testnet.export_wallet(file_path=filename_testnet)
        data_testnet = self.load_file_data(file_path=filename_testnet)
        self.assertEqual(expected_testnet, data_testnet)

    def test_export_wasabi(self):
        expect = {
            "ExtPubKey": "<KEY>",
            "MasterFingerprint": "2D36E0EB",
            "ColdCardFirmwareVersion": "3.1.3"
        }
        filename = "wasabi.json"
        self.wallet.export_wasabi(file_path=filename)
        data = self.load_file_data(file_path=filename)
        self.assertEqual(expect, data)

import os
import csv
import json
import unittest
from btc_hd_wallet.paper_wallet import PaperWallet


class TestColdWallet(unittest.TestCase):
    mnemonic = (
        "vast tell razor drip stick one engine action "
        "width sport else try scare phone blouse view "
        "program ketchup pole rapid use length student raven"
    )
    wallet = PaperWallet.from_mnemonic(mnemonic=mnemonic)
    wallet_testnet = PaperWallet.from_mnemonic(mnemonic=mnemonic, testnet=True)

    @staticmethod
    def load_csv_file(_file):
        with open(_file, "r") as f:
            csv_f = list(csv.reader(f, delimiter=','))
        return csv_f

    def test_bip44(self):
        m44h0h0h0 = "<KEY>"
        M44h0h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet.bip44()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip44_vast_tell_razor_drip_stick_one_engine"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m44h0h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip44_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M44h0h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip44_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            # paths differ -> as imported key is treated as root
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            # private key - last element in the list - is None --> watch only
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip49(self):
        m49h0h0h0 = "<KEY>"
        M49h0h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet.bip49()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip49_vast_tell_razor_drip_stick_one_engine"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m49h0h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip49_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M49h0h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip49_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip84(self):
        m84h0h0h0 = "<KEY>"
        M84h0h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet.bip84()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip84_vast_tell_razor_drip_stick_one_engine"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m84h0h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip84_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M84h0h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip84_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip44_testnet(self):
        m44h1h0h0 = "<KEY>"
        M44h1h0h0 = "<KEY>"
        node_m44h1h0h0 = self.wallet_testnet.by_path(path="m/44'/1'/0'/0")
        self.assertEqual(node_m44h1h0h0.extended_private_key(), m44h1h0h0)
        self.assertEqual(node_m44h1h0h0.extended_public_key(), M44h1h0h0)
        acct_ext_keys, wallet = self.wallet_testnet.bip44()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip44_vast_tell_razor_drip_stick_one_engine-testnet"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m44h1h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip44_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M44h1h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip44_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            # paths differ -> as imported key is treated as root
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            # private key - last element in the list - is None --> watch only
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip49_testnet(self):
        m49h1h0h0 = "<KEY>"
        M49h1h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet_testnet.bip49()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip49_vast_tell_razor_drip_stick_one_engine-testnet"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m49h1h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip49_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M49h1h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip49_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_bip84_testnet(self):
        m84h1h0h0 = "<KEY>"
        M84h1h0h0 = "<KEY>"
        acct_ext_keys, wallet = self.wallet_testnet.bip84()
        acct_ext_prv = "<KEY>"
        acct_ext_pub = "<KEY>"
        self.assertEqual(acct_ext_prv, acct_ext_keys["prv"])
        self.assertEqual(acct_ext_pub, acct_ext_keys["pub"])
        csv_f = self.load_csv_file(
            _file="tests/data/bip84_vast_tell_razor_drip_stick_one_engine-testnet"
        )
        wallet0 = PaperWallet.from_extended_key(extended_key=m84h1h0h0)
        self.assertFalse(wallet0.watch_only)
        wallet0 = wallet0.bip84_group(nodes=wallet0.master.generate_children())

        wallet1 = PaperWallet.from_extended_key(extended_key=M84h1h0h0)
        self.assertTrue(wallet1.watch_only)
        wallet1 = wallet1.bip84_group(nodes=wallet1.master.generate_children())

        self.assertEqual(len(wallet), len(csv_f))
        self.assertEqual(len(wallet0), len(csv_f))
        self.assertEqual(len(wallet1), len(csv_f))
        for i in range(len(wallet)):
            self.assertEqual(wallet[i], csv_f[i])
            self.assertEqual(wallet0[i][1:], csv_f[i][1:])
            self.assertEqual(wallet1[i][1:-1], csv_f[i][1:-1])

    def test_generate_mainnet(self):
        pw = self.wallet.generate(account=100)

        xpub = "<KEY>"
        xprv = "<KEY>"
        ypub = "<KEY>"
        yprv = "<KEY>"
        zpub = "<KEY>"
        zprv = "<KEY>"

        self.assertEqual(pw["BIP44"]["account_extended_keys"]["pub"], xpub)
        self.assertEqual(pw["BIP44"]["account_extended_keys"]["prv"], xprv)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["pub"], ypub)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["prv"], yprv)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["pub"], zpub)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["prv"], zprv)

        address = "13UkPjRAmH1sDWuoX1zeL8yCFWXdwPvGAE"
        pubkey = "03597d9a56c46c0e6e1827525bb517c5a8dfe21ace626f31a2e11c4e4e23cd353e"
        wif = "<KEY>"
        self.assertEqual(pw["BIP44"]["groups"][19][1], address)
        self.assertEqual(pw["BIP44"]["groups"][19][2], pubkey)
        self.assertEqual(pw["BIP44"]["groups"][19][3], wif)

        address = "3EGt757gbPFn1z5uvrUMhTcwKmxK78jsvC"
        pubkey = "020a0aff849f9addb615ef67ada2dfddbc59c377ab5668f2713bb379cc9d0f287b"
        wif = "L2PRabCy4qhKJTYkbcA6MEm2hC6DyPqSFj7jsCvNpHkU8DpmDWJR"
        self.assertEqual(pw["BIP49"]["groups"][19][1], address)
        self.assertEqual(pw["BIP49"]["groups"][19][2], pubkey)
        self.assertEqual(pw["BIP49"]["groups"][19][3], wif)

        address = "bc1q9gxcsd5wmdrg5909628kx96384h0w5dyyj82gz"
        pubkey = "03c66906128c24b82babeaea82205c10b0eeb09413da198ed8aa1337b82ac0d028"
        wif = "KzyLyHiys138p2EY4fPCV9JZfz6wVE4x6DeMg9HGM9eaXQkRENtF"
        self.assertEqual(pw["BIP84"]["groups"][19][1], address)
        self.assertEqual(pw["BIP84"]["groups"][19][2], pubkey)
        self.assertEqual(pw["BIP84"]["groups"][19][3], wif)

    def test_generate_testnet(self):
        pw = self.wallet_testnet.generate(account=66, interval=(0, 50))

        tpub = "<KEY>"
        tprv = "<KEY>"
        upub = "<KEY>"
        uprv = "<KEY>"
        vpub = "<KEY>"
        vprv = "<KEY>"

        self.assertEqual(pw["BIP44"]["account_extended_keys"]["pub"], tpub)
        self.assertEqual(pw["BIP44"]["account_extended_keys"]["prv"], tprv)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["pub"], upub)
        self.assertEqual(pw["BIP49"]["account_extended_keys"]["prv"], uprv)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["pub"], vpub)
        self.assertEqual(pw["BIP84"]["account_extended_keys"]["prv"], vprv)

        address = "mjXHL5oujxymKFdRUpLbAxFGU9ZaGvhPQ4"
        pubkey = "<KEY>"
        wif = "cUbsTivUmb1dcpGwbRMsCznmwLZMuT85akmScPtwEhco4EQ9xDtD"
        self.assertEqual(pw["BIP44"]["groups"][49][1], address)
        self.assertEqual(pw["BIP44"]["groups"][49][2], pubkey)
        self.assertEqual(pw["BIP44"]["groups"][49][3], wif)

        address = "2N6yVCdJu6Z3o3mUQfQizeVi1yNYEXwYEVe"
        pubkey = "02e10c0eddc2456720e337359948204f5cdc0ca05da6a3b5ac48580316e7fc9278"
        wif = "cSDgEWgZxSHJq36H6ou4jwnEG14Qdx7QwdMvvgLREdE932DFbwT2"
        self.assertEqual(pw["BIP49"]["groups"][49][1], address)
        self.assertEqual(pw["BIP49"]["groups"][49][2], pubkey)
        self.assertEqual(pw["BIP49"]["groups"][49][3], wif)

        address = "tb1q8fa5tlqsvs38knnn79y8lzduy7lznvhv74mvfs"
        pubkey = "<KEY>"
        wif = "cUpJB4hmzFgQL4oo33td3FYmGy3CatxWyPkSGtdrS4kfRRgPsqK9"
        self.assertEqual(pw["BIP84"]["groups"][49][1], address)
        self.assertEqual(pw["BIP84"]["groups"][49][2], pubkey)
        self.assertEqual(pw["BIP84"]["groups"][49][3], wif)

    def test_watch_only_generate_failure(self):
        # cannot do hardened ckd
        xpub = "<KEY>"
        w = PaperWallet.from_extended_key(extended_key=xpub)
        self.assertTrue(w.watch_only)
        with self.assertRaises(RuntimeError):
            w.generate()

    def test_master_data(self):
        md = self.wallet.master_data()
        self.assertEqual(md["mnemonic"], self.wallet.mnemonic)
        self.assertEqual(md["password"], self.wallet.password)

        md = self.wallet_testnet.master_data()
        self.assertEqual(md["mnemonic"], self.wallet_testnet.mnemonic)
        self.assertEqual(md["password"], self.wallet_testnet.password)

    def test_json(self):
        json_ = self.wallet.json()
        self.assertIsInstance(json_, str)
        self.assertEqual(self.wallet.generate(), json.loads(json_))

        json_ = self.wallet_testnet.json()
        self.assertIsInstance(json_, str)
        self.assertEqual(self.wallet_testnet.generate(), json.loads(json_))

    def test_wasabi_json(self):
        expect = '{"ExtPubKey": "<KEY>", "MasterFingerprint": "2D36E0EB", "ColdCardFirmwareVersion": "3.1.3"}'
        json_ = self.wallet.wasabi_json()
        self.assertEqual(json_, expect)

        expect = '{"ExtPubKey": "<KEY>", "MasterFingerprint": "2D36E0EB", "ColdCardFirmwareVersion": "3.1.3"}'
        json_ = self.wallet_testnet.wasabi_json()
        self.assertEqual(json_, expect)

    def load_file_data(self, file_path):
        self.assertTrue(os.path.isfile(file_path))
        with open(file_path, "r") as f:
            data = json.loads(f.read())
        os.remove(file_path)
        self.assertFalse(os.path.isfile(file_path))
        return data

    def test_export_wallet(self):
        expected_mainnet = self.wallet.generate()
        filename_mainnet = "wallet.json"
        self.wallet.export_wallet(file_path=filename_mainnet)
        data_mainnet = self.load_file_data(file_path=filename_mainnet)
        self.assertEqual(expected_mainnet, data_mainnet)

        expected_testnet = self.wallet_testnet.generate()
        filename_testnet = "wallet_testnet.json"
        self.wallet_testnet.export_wallet(file_path=filename_testnet)
        data_testnet = self.load_file_data(file_path=filename_testnet)
        self.assertEqual(expected_testnet, data_testnet)

    def test_export_wasabi(self):
        expect = {
            "ExtPubKey": "<KEY>",
            "MasterFingerprint": "2D36E0EB",
            "ColdCardFirmwareVersion": "3.1.3"
        }
        filename = "wasabi.json"
        self.wallet.export_wasabi(file_path=filename)
        data = self.load_file_data(file_path=filename)
        self.assertEqual(expect, data)
# paths differ -> as imported key is treated as root # private key - last element in the list - is None --> watch only # paths differ -> as imported key is treated as root # private key - last element in the list - is None --> watch only # cannot do hardened ckd