def test_multisig(self): self.setup_mnemonic_allallall() xpubs = [] for n in range(1, 4): node = btc.get_public_node(self.client, parse_path("44'/0'/%d'" % n)) xpubs.append(node.xpub) for nr in range(1, 4): assert ( btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/0/0" % nr), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) == "3Pdz86KtfJBuHLcSv4DysJo4aQfanTqCzG" ) assert ( btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/1/0" % nr), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), ) == "36gP3KVx1ooStZ9quZDXbAF3GCr42b2zzd" )
def test_multisig_missing(self): self.setup_mnemonic_allallall() xpubs = [] for n in range(1, 4): # shift account numbers by 10 to create valid multisig, # but not containing the keys used below n = n + 10 node = btc.get_public_node(self.client, parse_path("44'/0'/%d'" % n)) xpubs.append(node.xpub) for nr in range(1, 4): with pytest.raises(CallException): btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/0/0" % nr), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) with pytest.raises(CallException): btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/1/0" % nr), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), )
def test_get_address(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses( [proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Address()] ) btc.get_address(self.client, "Bitcoin", [])
def test_bch_multisig(self): self.setup_mnemonic_allallall() xpubs = [] for n in range(1, 4): node = btc.get_public_node(self.client, parse_path("44'/145'/%d'" % n)) xpubs.append(node.xpub) for nr in range(1, 4): assert ( btc.get_address( self.client, "Bcash", parse_path("44'/145'/%d'/0/0" % nr), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) == "bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw" ) assert ( btc.get_address( self.client, "Bcash", parse_path("44'/145'/%d'/1/0" % nr), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), ) == "bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a" )
def test_show_segwit(self): self.setup_mnemonic_allallall() assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/0/0"), True, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s" ) assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/1/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDADDRESS, ) == "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q" ) assert ( btc.get_address( self.client, "Groestlcoin", parse_path("84'/17'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "grs1qw4teyraux2s77nhjdwh9ar8rl9dt7zww8r6lne" )
def test_show_segwit(self): self.setup_mnemonic_allallall() assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/1/0"), True, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX" ) assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDADDRESS, ) == "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q" ) assert ( btc.get_address( self.client, "Groestlcoin Testnet", parse_path("49'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e" )
def test_public_ckd(self): self.setup_mnemonic_nopin_nopassphrase() btc.get_address(self.client, "Bitcoin", []) # to compute root node via BIP39 for depth in range(8): start = time.time() btc.get_address(self.client, "Bitcoin", range(depth)) delay = time.time() - start expected = (depth + 1) * 0.26 print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay) assert delay <= expected
def test_grs(self): self.setup_mnemonic_allallall() assert ( btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/0/0")) == "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM" ) assert ( btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/1/0")) == "FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN" ) assert ( btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/1/1")) == "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di" )
def test_show(self): self.setup_mnemonic_nopin_nopassphrase() assert ( btc.get_address(self.client, "Bitcoin", [1], show_display=True) == "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb" ) assert ( btc.get_address(self.client, "Bitcoin", [2], show_display=True) == "15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG" ) assert ( btc.get_address(self.client, "Bitcoin", [3], show_display=True) == "1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5" )
def test_bch(self): self.setup_mnemonic_allallall() assert ( btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/0")) == "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv" ) assert ( btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/1")) == "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4" ) assert ( btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/1/0")) == "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw" )
def test_show_multisig_3(self): self.setup_mnemonic_allallall() nodes = map( lambda index: btc.get_public_node( self.client, parse_path("999'/1'/%d'" % index) ), range(1, 4), ) multisig1 = proto.MultisigRedeemScriptType( nodes=[bip32.deserialize(n.xpub) for n in nodes], address_n=[2, 0], signatures=[b"", b"", b""], m=2, ) # multisig2 = proto.MultisigRedeemScriptType( # pubkeys=map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes), # signatures=[b'', b'', b''], # m=2, # ) for i in [1, 2, 3]: assert ( btc.get_address( self.client, "Testnet", parse_path("999'/1'/%d'/2/0" % i), False, multisig1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y" )
def test_cache(self): self.setup_mnemonic_nopin_nopassphrase() start = time.time() for x in range(10): btc.get_address(self.client, "Bitcoin", [x, 2, 3, 4, 5, 6, 7, 8]) nocache_time = time.time() - start start = time.time() for x in range(10): btc.get_address(self.client, "Bitcoin", [1, 2, 3, 4, 5, 6, 7, x]) cache_time = time.time() - start print("NOCACHE TIME", nocache_time) print("CACHED TIME", cache_time) # Cached time expected to be at least 2x faster assert cache_time <= nocache_time / 2.0
def test_load_device_1(self): self.setup_mnemonic_nopin_nopassphrase(lock=False) state = self.client.debug.state() assert state.mnemonic_secret == self.mnemonic12.encode() assert state.pin is None assert state.passphrase_protection is False address = btc.get_address(self.client, "Bitcoin", []) assert address == "1EfKbQupktEMXf4gujJ9kCFo83k1iMqwqK"
def test_load_device_2(self): self.setup_mnemonic_pin_passphrase(lock=False) self.client.set_passphrase("passphrase") state = self.client.debug.state() assert state.mnemonic_secret == self.mnemonic12.encode() assert state.pin == self.pin4 assert state.passphrase_protection is True address = btc.get_address(self.client, "Bitcoin", []) assert address == "15fiTDFwZd2kauHYYseifGi9daH2wniDHH"
def test_show_multisig_3(self): self.setup_mnemonic_allallall() nodes = [ btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)) for index in range(1, 4) ] multisig1 = proto.MultisigRedeemScriptType( nodes=[bip32.deserialize(n.xpub) for n in nodes], address_n=[2, 0], signatures=[b"", b"", b""], m=2, ) multisig2 = proto.MultisigRedeemScriptType( nodes=[bip32.deserialize(n.xpub) for n in nodes], address_n=[2, 1], signatures=[b"", b"", b""], m=2, ) for i in [1, 2, 3]: assert ( btc.get_address( self.client, "Testnet", parse_path("999'/1'/%d'/2/1" % i), False, multisig2, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1qch62pf820spe9mlq49ns5uexfnl6jzcezp7d328fw58lj0rhlhasge9hzy" ) assert ( btc.get_address( self.client, "Testnet", parse_path("999'/1'/%d'/2/0" % i), False, multisig1, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1qr6xa5v60zyt3ry9nmfew2fk5g9y3gerkjeu6xxdz7qga5kknz2ssld9z2z" )
def main(): # Use first connected device client = get_default_client() # Print out TREZOR's features and settings print(client.features) # Get the first address of first BIP44 account # (should be the same address as shown in wallet.trezor.io) bip32_path = parse_path("44'/0'/0'/0/0") address = btc.get_address(client, "Bitcoin", bip32_path, True) print("Bitcoin address:", address)
def test_ltc(self): self.setup_mnemonic_nopin_nopassphrase() assert ( btc.get_address(self.client, "Litecoin", []) == "LYtGrdDeqYUQnTkr5sHT2DKZLG7Hqg7HTK" ) assert ( btc.get_address(self.client, "Litecoin", [1]) == "LKRGNecThFP3Q6c5fosLVA53Z2hUDb1qnE" ) assert ( btc.get_address(self.client, "Litecoin", [0, H_(1)]) == "LcinMK8pVrAtpz7Qpc8jfWzSFsDLgLYfG6" ) assert ( btc.get_address(self.client, "Litecoin", [H_(9), 0]) == "LZHVtcwAEDf1BR4d67551zUijyLUpDF9EX" ) assert ( btc.get_address(self.client, "Litecoin", [0, 9999999]) == "Laf5nGHSCT94C5dK6fw2RxuXPiw2ZuRR9S" )
def test_btc(self): self.setup_mnemonic_nopin_nopassphrase() assert ( btc.get_address(self.client, "Bitcoin", []) == "1EfKbQupktEMXf4gujJ9kCFo83k1iMqwqK" ) assert ( btc.get_address(self.client, "Bitcoin", [1]) == "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb" ) assert ( btc.get_address(self.client, "Bitcoin", [0, H_(1)]) == "1JVq66pzRBvqaBRFeU9SPVvg3er4ZDgoMs" ) assert ( btc.get_address(self.client, "Bitcoin", [H_(9), 0]) == "1F4YdQdL9ZQwvcNTuy5mjyQxXkyCfMcP2P" ) assert ( btc.get_address(self.client, "Bitcoin", [0, 9999999]) == "1GS8X3yc7ntzwGw9vXwj9wqmBWZkTFewBV" )
def test_load_device_xprv_1(self): debuglink.load_device_by_xprv( self.client, xprv="xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73", pin="", passphrase_protection=False, label="test", language="english", ) passphrase_protection = self.client.debug.read_passphrase_protection() assert passphrase_protection is False address = btc.get_address(self.client, "Bitcoin", []) assert address == "128RdrAkJDmqasgvfRf6MC5VcX4HKqH4mR"
def test_public_ckd(self): self.setup_mnemonic_nopin_nopassphrase() node = btc.get_public_node(self.client, []).node node_sub1 = btc.get_public_node(self.client, [1]).node node_sub2 = bip32.public_ckd(node, [1]) assert node_sub1.chain_code == node_sub2.chain_code assert node_sub1.public_key == node_sub2.public_key address1 = btc.get_address(self.client, "Bitcoin", [1]) address2 = bip32.get_address(node_sub2, 0) assert address2 == "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb" assert address1 == address2
def test_load_device_xprv_2(self): debuglink.load_device_by_xprv( self.client, xprv="xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73", pin="", passphrase_protection=True, label="test", language="english", ) self.client.set_passphrase("passphrase") passphrase_protection = self.client.debug.read_passphrase_protection() assert passphrase_protection is True address = btc.get_address(self.client, "Bitcoin", []) assert address == "1CHUbFa4wTTPYgkYaw2LHSd5D4qJjMU8ri"
def test_show_multisig_15(self): self.setup_mnemonic_nopin_nopassphrase() node = bip32.deserialize( "xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy" ) pubs = [] for x in range(15): pubs.append(proto.HDNodePathType(node=node, address_n=[x])) multisig = proto.MultisigRedeemScriptType( pubkeys=pubs, signatures=[b""] * 15, m=15 ) for i in range(15): assert ( btc.get_address( self.client, "Bitcoin", [i], show_display=True, multisig=multisig ) == "3QaKF8zobqcqY8aS6nxCD5ZYdiRfL3RCmU" )
def test_show_multisig_3(self): self.setup_mnemonic_nopin_nopassphrase() node = bip32.deserialize( "xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy" ) multisig = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=node, address_n=[1]), proto.HDNodePathType(node=node, address_n=[2]), proto.HDNodePathType(node=node, address_n=[3]), ], signatures=[b"", b"", b""], m=2, ) for i in [1, 2, 3]: assert ( btc.get_address( self.client, "Bitcoin", [i], show_display=True, multisig=multisig ) == "3E7GDtuHqnqPmDgwH59pVC7AvySiSkbibz" )
def test_load_device_utf(self): words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a" words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f" words_nfkc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f" words_nfd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a" passphrase_nfkd = ( u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko" ) passphrase_nfc = ( u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko" ) passphrase_nfkc = ( u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko" ) passphrase_nfd = ( u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko" ) device.wipe(self.client) debuglink.load_device_by_mnemonic( self.client, mnemonic=words_nfkd, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) self.client.set_passphrase(passphrase_nfkd) address_nfkd = btc.get_address(self.client, "Bitcoin", []) device.wipe(self.client) debuglink.load_device_by_mnemonic( self.client, mnemonic=words_nfc, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) self.client.set_passphrase(passphrase_nfc) address_nfc = btc.get_address(self.client, "Bitcoin", []) device.wipe(self.client) debuglink.load_device_by_mnemonic( self.client, mnemonic=words_nfkc, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) self.client.set_passphrase(passphrase_nfkc) address_nfkc = btc.get_address(self.client, "Bitcoin", []) device.wipe(self.client) debuglink.load_device_by_mnemonic( self.client, mnemonic=words_nfd, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) self.client.set_passphrase(passphrase_nfd) address_nfd = btc.get_address(self.client, "Bitcoin", []) assert address_nfkd == address_nfc assert address_nfkd == address_nfkc assert address_nfkd == address_nfd
def test_tbtc(self, client): assert (btc.get_address( client, "Testnet", [111, 42]) == "moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa")
def _ensure_unlocked(client, pin): with client: client.use_pin_sequence([pin]) btc.get_address(client, "Testnet", PASSPHRASE_TEST_PATH) client.init_device()
def test_crw(client: Client): assert (btc.get_address(client, "Crown", parse_path("m/44h/72h/0h/0/0")) == "CRWYdvZM1yXMKQxeN3hRsAbwa7drfvTwys48")
def test_tbtc(self): self.setup_mnemonic_nopin_nopassphrase() assert (btc.get_address( self.client, "Testnet", [111, 42]) == "moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa")
def asserts(client): assert not client.features.pin_protection assert not client.features.passphrase_protection assert client.features.initialized assert client.features.label == LABEL assert btc.get_address(client, "Bitcoin", PATH) == ADDRESS
def _get_address(ctrl, hw_session: HwSessionInfo, bip32_path: str, show_display: bool = False, message_to_display: str = None): if ctrl: ctrl.dlg_config_fun(dlg_title=DEFAULT_HW_BUSY_TITLE, show_progress_bar=False) if message_to_display: ctrl.display_msg_fun(message_to_display) else: ctrl.display_msg_fun( '<b>Click the confirmation button on your hardware wallet to exit...</b>' ) client = hw_session.hw_client if client: if isinstance(bip32_path, str): bip32_path.strip() if bip32_path.lower().find('m/') >= 0: # removing m/ prefix because of keepkey library bip32_path = bip32_path[2:] if hw_session.app_config.hw_type == HWType.trezor: from trezorlib import btc from trezorlib import exceptions try: if isinstance(bip32_path, str): bip32_path = stash_utils.bip32_path_string_to_n( bip32_path) ret = btc.get_address(client, hw_session.app_config.hw_coin_name, bip32_path, show_display) return ret except (CancelException, exceptions.Cancelled): raise CancelException() elif hw_session.app_config.hw_type == HWType.keepkey: from keepkeylib.client import CallException try: if isinstance(bip32_path, str): bip32_path = stash_utils.bip32_path_string_to_n( bip32_path) return client.get_address( hw_session.app_config.hw_coin_name, bip32_path, show_display) except CallException as e: if isinstance(e.args, tuple) and len(e.args) >= 2 and isinstance(e.args[1], str) and \ e.args[1].find('cancel') >= 0: raise CancelException('Cancelled') elif hw_session.app_config.hw_type == HWType.ledger_nano_s: import hw_intf_ledgernano as ledger if isinstance(bip32_path, list): # ledger requires bip32 path argument as a string bip32_path = bip32_path_n_to_string(bip32_path) adr_pubkey = ledger.get_address_and_pubkey( client, bip32_path, show_display) return adr_pubkey.get('address') else: raise Exception('Unknown hardware wallet type: ' + hw_session.app_config.hw_type) else: raise Exception('HW client not open.')
def test_show_multisig_xpubs(client): nodes = [ btc.get_public_node(client, tools.parse_path(f"48h/0h/{i}h"), coin_name="Bitcoin") for i in range(3) ] multisig = messages.MultisigRedeemScriptType( nodes=[n.node for n in nodes], signatures=[b"", b"", b""], address_n=[0, 0], m=2, ) xpubs = [[n.xpub[i * 16:(i + 1) * 16] for i in range(5)] for n in nodes] for i in range(3): def input_flow(): yield # show address assert client.debug.wait_layout().lines == [ "Multisig 2 of 3", "34yJV2b2GtbmxfZNw", "jPyuyUYkUbUnogqa8", ] client.debug.press_no() yield # show QR code assert client.debug.wait_layout().text.startswith("Qr") client.debug.press_no() yield # show XPUB#1 lines = client.debug.wait_layout().lines assert lines[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(others)") assert lines[1:] == xpubs[0] # just for UI test client.debug.swipe_up() client.debug.press_no() yield # show XPUB#2 lines = client.debug.wait_layout().lines assert lines[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(others)") assert lines[1:] == xpubs[1] # just for UI test client.debug.swipe_up() client.debug.press_no() yield # show XPUB#3 lines = client.debug.wait_layout().lines assert lines[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(others)") assert lines[1:] == xpubs[2] # just for UI test client.debug.swipe_up() client.debug.press_yes() with client: client.set_input_flow(input_flow) btc.get_address( client, "Bitcoin", tools.parse_path(f"48h/0h/{i}h/0/0"), show_display=True, multisig=multisig, script_type=messages.InputScriptType.SPENDMULTISIG, )
def get_bad_address(): btc.get_address(client, "Bitcoin", parse_path("m/0"))
def test_tbtc(self): self.setup_mnemonic_nopin_nopassphrase() assert ( btc.get_address(self.client, "Testnet", [111, 42]) == "moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa" )
def test_address(client): return btc.get_address(client, "Testnet", TEST_ADDRESS_N)
def test_invalid_path(client): with pytest.raises(TrezorFailure, match="Forbidden key path"): # slip44 id mismatch btc.get_address(client, "Bitcoin", parse_path("m/44'/111'/0'/0/0"))
def test_load_device_utf(self, client): words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a" words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f" words_nfkc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f" words_nfd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a" passphrase_nfkd = ( u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko" ) passphrase_nfc = ( u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko" ) passphrase_nfkc = ( u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko" ) passphrase_nfd = ( u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko" ) device.wipe(client) debuglink.load_device_by_mnemonic( client, mnemonic=words_nfkd, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) client.set_passphrase(passphrase_nfkd) address_nfkd = btc.get_address(client, "Bitcoin", []) device.wipe(client) debuglink.load_device_by_mnemonic( client, mnemonic=words_nfc, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) client.set_passphrase(passphrase_nfc) address_nfc = btc.get_address(client, "Bitcoin", []) device.wipe(client) debuglink.load_device_by_mnemonic( client, mnemonic=words_nfkc, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) client.set_passphrase(passphrase_nfkc) address_nfkc = btc.get_address(client, "Bitcoin", []) device.wipe(client) debuglink.load_device_by_mnemonic( client, mnemonic=words_nfd, pin="", passphrase_protection=True, label="test", language="english", skip_checksum=True, ) client.set_passphrase(passphrase_nfd) address_nfd = btc.get_address(client, "Bitcoin", []) assert address_nfkd == address_nfc assert address_nfkd == address_nfkc assert address_nfkd == address_nfd
def test_show_multisig_xpubs(client, script_type, purpose48_type, address, xpubs, ignore_xpub_magic): nodes = [ btc.get_public_node( client, tools.parse_path(f"48h/0h/{i}h/{purpose48_type}h"), coin_name="Bitcoin", ) for i in range(3) ] multisig = messages.MultisigRedeemScriptType( nodes=[n.node for n in nodes], signatures=[b"", b"", b""], address_n=[0, 0], m=2, ) for i in range(3): def input_flow(): yield # show address lines = client.debug.wait_layout().lines assert lines[0] == "Multisig 2 of 3" assert "".join(lines[1:]) == address client.debug.press_no() yield # show QR code assert client.debug.wait_layout().text.startswith("Qr") client.debug.press_no() yield # show XPUB#1 lines1 = client.debug.wait_layout().lines assert lines1[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)") client.debug.swipe_up() lines2 = client.debug.wait_layout().lines assert lines2[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(cosigner)") assert "".join(lines1[1:] + lines2[1:]) == xpubs[0] client.debug.press_no() yield # show XPUB#2 lines1 = client.debug.wait_layout().lines assert lines1[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)") client.debug.swipe_up() lines2 = client.debug.wait_layout().lines assert lines2[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(cosigner)") assert "".join(lines1[1:] + lines2[1:]) == xpubs[1] client.debug.press_no() yield # show XPUB#3 lines1 = client.debug.wait_layout().lines assert lines1[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)") client.debug.swipe_up() lines2 = client.debug.wait_layout().lines assert lines2[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(cosigner)") assert "".join(lines1[1:] + lines2[1:]) == xpubs[2] client.debug.press_yes() with client: client.watch_layout() client.set_input_flow(input_flow) btc.get_address( client, "Bitcoin", tools.parse_path(f"48h/0h/{i}h/{purpose48_type}h/0/0"), show_display=True, multisig=multisig, script_type=script_type, ignore_xpub_magic=ignore_xpub_magic, )
def test_3of6_nopin_nopassphrase(self): # 128 bits security, 3 of 6 mnemonics = [ "extra extend academic bishop cricket bundle tofu goat apart victim enlarge program behavior permit course armed jerky faint language modern", "extra extend academic acne away best indicate impact square oasis prospect painting voting guest either argue username racism enemy eclipse", "extra extend academic arcade born dive legal hush gross briefing talent drug much home firefly toxic analysis idea umbrella slice", ] word_count = len(mnemonics[0].split(" ")) ret = self.client.call_raw( proto.RecoveryDevice(passphrase_protection=False, pin_protection=False, label="label")) # Confirm Recovery assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Enter word count assert ret == proto.ButtonRequest( code=proto.ButtonRequestType.MnemonicWordCount) self.client.debug.input(str(word_count)) ret = self.client.call_raw(proto.ButtonAck()) # Enter shares for mnemonic in mnemonics: # Enter mnemonic words assert ret == proto.ButtonRequest( code=proto.ButtonRequestType.MnemonicInput) self.client.transport.write(proto.ButtonAck()) for word in mnemonic.split(" "): time.sleep(1) self.client.debug.input(word) ret = self.client.transport.read() if mnemonic != mnemonics[-1]: # Confirm status assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Confirm success assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Workflow succesfully ended assert ret == proto.Success(message="Device recovered") assert self.client.features.pin_protection is False assert self.client.features.passphrase_protection is False # Check mnemonic assert (self.client.debug.read_mnemonic_secret().hex() == "491b795b80fc21ccdf466c0fbc98c8fc") # BIP32 Root Key for empty passphrase # provided by Andrew, address calculated using T1 # xprv9s21ZrQH143K3reExTJbGTHPu6mGuUx6yN1H1KkqoiAcw6j1t6hBiwwnXYxNQXxU8T7pANSv1rJYQPXn1LMQk1gbWes5BjSz3rJ5ZfH1cc3 address = btc.get_address(self.client, "Bitcoin", []) assert address == "1G1MwH5sLVxKQ7yKYasfE5pxWaABLo7VK7"
def test_elements(client: Client): assert (btc.get_address( client, "Elements", parse_path("m/44h/1h/0h/0/0")) == "2dpWh6jbhAowNsQ5agtFzi7j6nKscj6UnEr" )
def test_2of5_pin_passphrase(self): # 256 bits security, 2 of 5 mnemonics = [ "hobo romp academic axis august founder knife legal recover alien expect emphasis loan kitchen involve teacher capture rebuild trial numb spider forward ladle lying voter typical security quantity hawk legs idle leaves gasoline", "hobo romp academic agency ancestor industry argue sister scene midst graduate profile numb paid headset airport daisy flame express scene usual welcome quick silent downtown oral critical step remove says rhythm venture aunt", ] word_count = len(mnemonics[0].split(" ")) ret = self.client.call_raw( proto.RecoveryDevice(passphrase_protection=True, pin_protection=True, label="label")) # Confirm Recovery assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Enter word count assert ret == proto.ButtonRequest( code=proto.ButtonRequestType.MnemonicWordCount) self.client.debug.input(str(word_count)) ret = self.client.call_raw(proto.ButtonAck()) # Enter shares for mnemonic in mnemonics: # Enter mnemonic words assert ret == proto.ButtonRequest( code=proto.ButtonRequestType.MnemonicInput) self.client.transport.write(proto.ButtonAck()) for word in mnemonic.split(" "): time.sleep(1) self.client.debug.input(word) ret = self.client.transport.read() if mnemonic != mnemonics[-1]: # Confirm status assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Enter PIN for first time assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other) self.client.debug.input("654") ret = self.client.call_raw(proto.ButtonAck()) # Enter PIN for second time assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other) self.client.debug.input("654") ret = self.client.call_raw(proto.ButtonAck()) # Confirm success assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Workflow succesfully ended assert ret == proto.Success(message="Device recovered") # Check mnemonic self.client.init_device() assert ( self.client.debug.read_mnemonic_secret().hex() == "b770e0da1363247652de97a39bdbf2463be087848d709ecbf28e84508e31202a") assert self.client.features.pin_protection is True assert self.client.features.passphrase_protection is True device.apply_settings(self.client, passphrase_source=PASSPHRASE_ON_HOST) # BIP32 Root Key for empty passphrase # provided by Andrew, address calculated using T1 # xprv9s21ZrQH143K2kP9RYJE5AFggTHLs8PbDaaTYtvh238THxDyXqyqQV6H1QpFr3aaQ7CFusFMYyGZ6VcK7aLADyCaCJrszovxtzVZmnRfca4 address = btc.get_address(self.client, "Bitcoin", []) assert address == "1BmqXKM8M1gWA4bgkbPeCtJruRnrY2qYKP" # hackish way to clear passphrase # TODO: move this to another test file and test using load_device on a new session self.client.state = None self.client.init_device() self.client.set_passphrase("TREZOR") # BIP32 Root Key for passphrase TREZOR # provided by Andrew, address calculated using T1 # xprv9s21ZrQH143K2o6EXEHpVy8TCYoMmkBnDCCESLdR2ieKwmcNG48ck2XJQY4waS7RUQcXqR9N7HnQbUVEDMWYyREdF1idQqxFHuCfK7fqFni address = btc.get_address(self.client, "Bitcoin", []) assert address == "19Fjs9AvT13Y2Nx8GtoVfADmFWnccsPinQ"
def get_test_address(client): """Fetch a testnet address on a fixed path. Useful to make a pin/passphrase protected call, or to identify the root secret (seed+passphrase)""" return btc.get_address(client, "Testnet", TEST_ADDRESS_N)