# (c) Copyright 2020 by Coinkite Inc. This file is covered by license found in COPYING-CC. # # test "show address" feature # # - these only work well on the simulator # - must put real device into testnet mode first # import pytest, time from ckcc_protocol.protocol import CCProtocolPacker from ckcc_protocol.constants import * from charcodes import KEY_QR from constants import msg_sign_unmap_addr_fmt from helpers import addr_from_display_format @pytest.mark.parametrize('path', [ 'm', "m/1/2", "m/1'/100'"]) @pytest.mark.parametrize('addr_fmt', [ AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH ]) def test_show_addr_usb(dev, press_select, addr_vs_path, path, addr_fmt, is_simulator): addr = dev.send_recv(CCProtocolPacker.show_address(path, addr_fmt), timeout=None) press_select() if "'" in path and not is_simulator(): raise pytest.skip('we cant confirm hardened-derived keypaths') # check expected addr was used addr_vs_path(addr, path, addr_fmt) @pytest.mark.qrcode @pytest.mark.parametrize('path', [ 'm', "m/1/2", "m/1'/100'", "m/0h/500h"]) @pytest.mark.parametrize('addr_fmt', [ AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH ]) def test_show_addr_displayed(dev, need_keypress, addr_vs_path, path, addr_fmt, cap_story, verify_qr_address, qr_quality_check, press_cancel, is_q1): time.sleep(0.1) addr = dev.send_recv(CCProtocolPacker.show_address(path, addr_fmt), timeout=None) time.sleep(0.1) title, story = cap_story() assert title == 'Address:' if "'" in path: assert path not in story # we normalize to h assert path.replace("'", "h") in story else: assert path in story assert addr in addr_from_display_format(story.split("\n\n")[0]) # check expected addr was used addr_vs_path(addr, path, addr_fmt) print('addr_fmt = 0x%x' % addr_fmt) need_keypress(KEY_QR if is_q1 else '4') time.sleep(0.1) verify_qr_address(addr_fmt, addr) @pytest.mark.bitcoind def test_addr_vs_bitcoind(use_regtest, press_select, dev, bitcoind_d_sim_sign): # check our p2wpkh wrapped in p2sh is right use_regtest() for i in range(5): core_addr = bitcoind_d_sim_sign.getnewaddress(f"{i}-addr", "p2sh-segwit") assert core_addr[0] == '2' resp = bitcoind_d_sim_sign.getaddressinfo(core_addr) assert resp['embedded']['iswitness'] == True assert resp['isscript'] == True path = resp['hdkeypath'] addr = dev.send_recv(CCProtocolPacker.show_address(path, AF_P2WPKH_P2SH), timeout=None) press_select() assert addr == core_addr @pytest.mark.parametrize("body_err", [ ("m\np2wsh", "Invalid address format: 'p2wsh'"), ("m\np2sh-p2wsh", "Invalid address format: 'p2sh-p2wsh'"), ("m\np2tr", "Invalid address format: 'p2tr'"), ("m/0/0/0/0/0/0/0/0/0/0/0/0/0\np2pkh", "too deep"), ("m/0/0/0/0/0/q/0/0/0\np2pkh", "invalid characters"), ]) def test_show_addr_nfc_invalid(body_err, goto_home, pick_menu_item, nfc_write_text, cap_story, skip_if_useless_way): skip_if_useless_way("nfc") body, err = body_err goto_home() pick_menu_item('Advanced/Tools') pick_menu_item('NFC Tools') pick_menu_item('Show Address') nfc_write_text(body) time.sleep(0.5) _, story = cap_story() assert err in story @pytest.mark.parametrize("path", ["m/84'/0'/0'/300/0", "m/800h/0h", "m/0/0/0/0/1/1/1"]) @pytest.mark.parametrize("str_addr_fmt", ["p2pkh", "", "p2wpkh", "p2wpkh-p2sh", "p2sh-p2wpkh"]) def test_show_addr_nfc(path, str_addr_fmt, nfc_write_text, nfc_read_text, pick_menu_item, goto_home, cap_story, press_nfc, addr_vs_path, press_select, is_q1, cap_screen, skip_if_useless_way): skip_if_useless_way("nfc") # import pdb;pdb.set_trace() for _ in range(5): # need to wait for ApproveMessageSign to be popped from ux stack try: goto_home() break except: time.sleep(0.5) pick_menu_item('Advanced/Tools') pick_menu_item('NFC Tools') pick_menu_item('Show Address') if str_addr_fmt != "": addr_fmt = msg_sign_unmap_addr_fmt[str_addr_fmt] body = "\n".join([path, str_addr_fmt]) else: addr_fmt = AF_CLASSIC body = path nfc_write_text(body) time.sleep(0.5) _, story = cap_story() split_story = story.split("\n\n") story_addr = addr_from_display_format(split_story[0]) story_path = split_story[1][2:] # remove "= " if not is_q1: assert "Press (3) to share via NFC" in story if "'" in path: assert path != story_path # normalized to h assert path.replace("'", "h") == story_path else: assert story_path == path press_nfc() # share over NFC addr = nfc_read_text() if addr == body: # missed it - again addr = nfc_read_text() press_select() # exit NFC animation assert story_addr == addr addr_vs_path(addr, path, addr_fmt) # EOF