From 144ff52b7a7003b094d884f3a62f2d4c9d056e53 Mon Sep 17 00:00:00 2001 From: grdddj Date: Fri, 22 Sep 2023 11:49:40 +0200 Subject: [PATCH] feat(core): show account number in receive/public key details for altcoins [no changelog] --- core/src/apps/binance/get_address.py | 7 ++- core/src/apps/binance/get_public_key.py | 8 ++- core/src/apps/common/paths.py | 43 +++++++++++++ core/src/apps/eos/get_public_key.py | 5 +- core/src/apps/eos/layout.py | 6 +- core/src/apps/ethereum/get_address.py | 8 ++- core/src/apps/monero/get_address.py | 10 ++- core/src/apps/nem/get_address.py | 9 ++- core/src/apps/ripple/get_address.py | 11 +++- core/src/apps/stellar/get_address.py | 15 +++-- core/src/apps/tezos/get_address.py | 11 +++- core/src/apps/tezos/get_public_key.py | 6 +- .../device_tests/binance/test_get_address.py | 41 ++++++++---- .../device_tests/ethereum/test_getaddress.py | 20 ++++-- tests/device_tests/monero/test_getaddress.py | 62 ++++++++++++------- tests/device_tests/ripple/__init__.py | 0 tests/device_tests/ripple/test_get_address.py | 34 +++++++--- tests/device_tests/stellar/test_stellar.py | 32 ++++++---- tests/device_tests/tezos/test_getaddress.py | 40 ++++++++---- tests/input_flows.py | 12 +++- 20 files changed, 286 insertions(+), 94 deletions(-) create mode 100644 tests/device_tests/ripple/__init__.py diff --git a/core/src/apps/binance/get_address.py b/core/src/apps/binance/get_address.py index 2cbe0dca94..3e017a7d3d 100644 --- a/core/src/apps/binance/get_address.py +++ b/core/src/apps/binance/get_address.py @@ -26,8 +26,13 @@ async def get_address(msg: BinanceGetAddress, keychain: Keychain) -> BinanceAddr pubkey = node.public_key() address = address_from_public_key(pubkey, HRP) if msg.show_display: + from . import PATTERN, SLIP44_ID + await show_address( - address, path=paths.address_n_to_str(address_n), chunkify=bool(msg.chunkify) + address, + path=paths.address_n_to_str(address_n), + account=paths.get_account_name("BNB", address_n, PATTERN, SLIP44_ID), + chunkify=bool(msg.chunkify), ) return BinanceAddress(address=address) diff --git a/core/src/apps/binance/get_public_key.py b/core/src/apps/binance/get_public_key.py index fba66761ad..89f3b13dfc 100644 --- a/core/src/apps/binance/get_public_key.py +++ b/core/src/apps/binance/get_public_key.py @@ -24,7 +24,13 @@ async def get_public_key( pubkey = node.public_key() if msg.show_display: + from . import PATTERN, SLIP44_ID + path = paths.address_n_to_str(msg.address_n) - await show_pubkey(hexlify(pubkey).decode(), path=path) + await show_pubkey( + hexlify(pubkey).decode(), + account=paths.get_account_name("BNB", msg.address_n, PATTERN, SLIP44_ID), + path=path, + ) return BinancePublicKey(public_key=pubkey) diff --git a/core/src/apps/common/paths.py b/core/src/apps/common/paths.py index afc7a979c1..976a5cb9e0 100644 --- a/core/src/apps/common/paths.py +++ b/core/src/apps/common/paths.py @@ -372,3 +372,46 @@ def address_n_to_str(address_n: Iterable[int]) -> str: def unharden(item: int) -> int: return item ^ (item & HARDENED) + + +def get_account_name( + coin: str, address_n: Bip32Path, pattern: str | Sequence[str], slip44_id: int +) -> str | None: + account_num = _get_account_num(address_n, pattern, slip44_id) + if account_num is None: + return None + return f"{coin} #{account_num}" + + +def _get_account_num( + address_n: Bip32Path, pattern: str | Sequence[str], slip44_id: int +) -> int | None: + if isinstance(pattern, str): + pattern = [pattern] + + # Trying all possible patterns - at least one should match + for patt in pattern: + try: + return _get_account_num_single(address_n, patt, slip44_id) + except ValueError: + pass + + # This function should not raise + return None + + +def _get_account_num_single(address_n: Bip32Path, pattern: str, slip44_id: int) -> int: + # Validating address_n is compatible with pattern + if not PathSchema.parse(pattern, slip44_id).match(address_n): + raise ValueError + + account_pos = pattern.find("/account") + if account_pos >= 0: + i = pattern.count("/", 0, account_pos) + num = address_n[i] + if is_hardened(num): + return unharden(num) + 1 + else: + return num + 1 + else: + raise ValueError diff --git a/core/src/apps/eos/get_public_key.py b/core/src/apps/eos/get_public_key.py index 55a9bbbd4b..19678f0551 100644 --- a/core/src/apps/eos/get_public_key.py +++ b/core/src/apps/eos/get_public_key.py @@ -26,6 +26,9 @@ async def get_public_key(msg: EosGetPublicKey, keychain: Keychain) -> EosPublicK wif = public_key_to_wif(public_key) if msg.show_display: + from . import PATTERN, SLIP44_ID + path = paths.address_n_to_str(msg.address_n) - await require_get_public_key(wif, path) + account = paths.get_account_name("EOS", msg.address_n, PATTERN, SLIP44_ID) + await require_get_public_key(wif, path, account) return EosPublicKey(wif_public_key=wif, raw_public_key=public_key) diff --git a/core/src/apps/eos/layout.py b/core/src/apps/eos/layout.py index 5c99f5e054..5ea24236f2 100644 --- a/core/src/apps/eos/layout.py +++ b/core/src/apps/eos/layout.py @@ -1,7 +1,9 @@ -async def require_get_public_key(public_key: str, path: str) -> None: +async def require_get_public_key( + public_key: str, path: str, account: str | None +) -> None: from trezor.ui.layouts import show_pubkey - await show_pubkey(public_key, path=path) + await show_pubkey(public_key, path=path, account=account) async def require_sign_tx(num_actions: int) -> None: diff --git a/core/src/apps/ethereum/get_address.py b/core/src/apps/ethereum/get_address.py index 33de65fa39..92ab88bd08 100644 --- a/core/src/apps/ethereum/get_address.py +++ b/core/src/apps/ethereum/get_address.py @@ -32,8 +32,14 @@ async def get_address( address = address_from_bytes(node.ethereum_pubkeyhash(), defs.network) if msg.show_display: + slip44_id = address_n[1] # it depends on the network (ETH vs ETC...) await show_address( - address, path=paths.address_n_to_str(address_n), chunkify=bool(msg.chunkify) + address, + path=paths.address_n_to_str(address_n), + account=paths.get_account_name( + "ETH", address_n, PATTERNS_ADDRESS, slip44_id + ), + chunkify=bool(msg.chunkify), ) return EthereumAddress(address=address) diff --git a/core/src/apps/monero/get_address.py b/core/src/apps/monero/get_address.py index 49ab3f28d7..3653f0af11 100644 --- a/core/src/apps/monero/get_address.py +++ b/core/src/apps/monero/get_address.py @@ -22,10 +22,11 @@ async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddres account = msg.account # local_cache_attribute minor = msg.minor # local_cache_attribute payment_id = msg.payment_id # local_cache_attribute + address_n = msg.address_n # local_cache_attribute - await paths.validate_path(keychain, msg.address_n) + await paths.validate_path(keychain, address_n) - creds = misc.get_creds(keychain, msg.address_n, msg.network_type) + creds = misc.get_creds(keychain, address_n, msg.network_type) addr = creds.address have_subaddress = ( @@ -65,10 +66,13 @@ async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddres ) if msg.show_display: + from . import PATTERN, SLIP44_ID + await show_address( addr, address_qr="monero:" + addr, - path=paths.address_n_to_str(msg.address_n), + path=paths.address_n_to_str(address_n), + account=paths.get_account_name("XMR", msg.address_n, PATTERN, SLIP44_ID), chunkify=bool(msg.chunkify), ) diff --git a/core/src/apps/nem/get_address.py b/core/src/apps/nem/get_address.py index d0c9061ffe..c09299ae73 100644 --- a/core/src/apps/nem/get_address.py +++ b/core/src/apps/nem/get_address.py @@ -15,7 +15,7 @@ async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress: from trezor.messages import NEMAddress from trezor.ui.layouts import show_address - from apps.common.paths import address_n_to_str, validate_path + from apps.common import paths from .helpers import check_path, get_network_str from .validators import validate_network @@ -24,16 +24,19 @@ async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress: network = msg.network # local_cache_attribute validate_network(network) - await validate_path(keychain, address_n, check_path(address_n, network)) + await paths.validate_path(keychain, address_n, check_path(address_n, network)) node = keychain.derive(address_n) address = node.nem_address(network) if msg.show_display: + from . import PATTERNS, SLIP44_ID + await show_address( address, case_sensitive=False, - path=address_n_to_str(address_n), + path=paths.address_n_to_str(address_n), + account=paths.get_account_name("NEM", msg.address_n, PATTERNS, SLIP44_ID), network=get_network_str(network), chunkify=bool(msg.chunkify), ) diff --git a/core/src/apps/ripple/get_address.py b/core/src/apps/ripple/get_address.py index b21d9659f2..1450669817 100644 --- a/core/src/apps/ripple/get_address.py +++ b/core/src/apps/ripple/get_address.py @@ -18,16 +18,21 @@ async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddres from .helpers import address_from_public_key - await paths.validate_path(keychain, msg.address_n) + address_n = msg.address_n # local_cache_attribute - node = keychain.derive(msg.address_n) + await paths.validate_path(keychain, address_n) + + node = keychain.derive(address_n) pubkey = node.public_key() address = address_from_public_key(pubkey) if msg.show_display: + from . import PATTERN, SLIP44_ID + await show_address( address, - path=paths.address_n_to_str(msg.address_n), + path=paths.address_n_to_str(address_n), + account=paths.get_account_name("XRP", msg.address_n, PATTERN, SLIP44_ID), chunkify=bool(msg.chunkify), ) diff --git a/core/src/apps/stellar/get_address.py b/core/src/apps/stellar/get_address.py index 6d48b23108..65b323bbf8 100644 --- a/core/src/apps/stellar/get_address.py +++ b/core/src/apps/stellar/get_address.py @@ -17,16 +17,23 @@ async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddr from . import helpers - await paths.validate_path(keychain, msg.address_n) + address_n = msg.address_n # local_cache_attribute - node = keychain.derive(msg.address_n) + await paths.validate_path(keychain, address_n) + + node = keychain.derive(address_n) pubkey = seed.remove_ed25519_prefix(node.public_key()) address = helpers.address_from_public_key(pubkey) if msg.show_display: - path = paths.address_n_to_str(msg.address_n) + from . import PATTERN, SLIP44_ID + await show_address( - address, case_sensitive=False, path=path, chunkify=bool(msg.chunkify) + address, + case_sensitive=False, + path=paths.address_n_to_str(address_n), + account=paths.get_account_name("XLM", msg.address_n, PATTERN, SLIP44_ID), + chunkify=bool(msg.chunkify), ) return StellarAddress(address=address) diff --git a/core/src/apps/tezos/get_address.py b/core/src/apps/tezos/get_address.py index d7fd52d277..8269fce154 100644 --- a/core/src/apps/tezos/get_address.py +++ b/core/src/apps/tezos/get_address.py @@ -20,18 +20,23 @@ async def get_address(msg: TezosGetAddress, keychain: Keychain) -> TezosAddress: from . import helpers - await paths.validate_path(keychain, msg.address_n) + address_n = msg.address_n # local_cache_attribute - node = keychain.derive(msg.address_n) + await paths.validate_path(keychain, address_n) + + node = keychain.derive(address_n) pk = seed.remove_ed25519_prefix(node.public_key()) pkh = hashlib.blake2b(pk, outlen=helpers.PUBLIC_KEY_HASH_SIZE).digest() address = helpers.base58_encode_check(pkh, helpers.TEZOS_ED25519_ADDRESS_PREFIX) if msg.show_display: + from . import PATTERNS, SLIP44_ID + await show_address( address, - path=paths.address_n_to_str(msg.address_n), + path=paths.address_n_to_str(address_n), + account=paths.get_account_name("XTZ", address_n, PATTERNS, SLIP44_ID), chunkify=bool(msg.chunkify), ) diff --git a/core/src/apps/tezos/get_public_key.py b/core/src/apps/tezos/get_public_key.py index f70a8e5d19..aab680d71e 100644 --- a/core/src/apps/tezos/get_public_key.py +++ b/core/src/apps/tezos/get_public_key.py @@ -26,6 +26,10 @@ async def get_public_key(msg: TezosGetPublicKey, keychain: Keychain) -> TezosPub pk_prefixed = helpers.base58_encode_check(pk, helpers.TEZOS_PUBLICKEY_PREFIX) if msg.show_display: - await show_pubkey(pk_prefixed) + from . import PATTERNS, SLIP44_ID + + account = paths.get_account_name("XTZ", msg.address_n, PATTERNS, SLIP44_ID) + path = paths.address_n_to_str(msg.address_n) + await show_pubkey(pk_prefixed, account=account, path=path) return TezosPublicKey(public_key=pk_prefixed) diff --git a/tests/device_tests/binance/test_get_address.py b/tests/device_tests/binance/test_get_address.py index 612e50c538..f58336aca6 100644 --- a/tests/device_tests/binance/test_get_address.py +++ b/tests/device_tests/binance/test_get_address.py @@ -20,26 +20,41 @@ from trezorlib.binance import get_address from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.tools import parse_path +from ...input_flows import InputFlowShowAddressQRCode + +pytestmark = [ + pytest.mark.altcoin, + pytest.mark.binance, + pytest.mark.skip_t1, # T1 support is not planned + pytest.mark.setup_client( + mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin" + ), +] + BINANCE_ADDRESS_TEST_VECTORS = [ ("m/44h/714h/0h/0/0", "bnb1hgm0p7khfk85zpz5v0j8wnej3a90w709vhkdfu"), ("m/44h/714h/0h/0/1", "bnb1egswqkszzfc2uq78zjslc6u2uky4pw46x4rstd"), ] -@pytest.mark.altcoin -@pytest.mark.binance -@pytest.mark.skip_t1 # T1 support is not planned -@pytest.mark.setup_client( - mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin" -) -@pytest.mark.parametrize("chunkify", (True, False)) @pytest.mark.parametrize("path, expected_address", BINANCE_ADDRESS_TEST_VECTORS) -def test_binance_get_address( - client: Client, chunkify: bool, path: str, expected_address: str +def test_binance_get_address(client: Client, path: str, expected_address: str): + # data from https://github.com/binance-chain/javascript-sdk/blob/master/__tests__/crypto.test.js#L50 + + address = get_address(client, parse_path(path), show_display=True) + assert address == expected_address + + +@pytest.mark.parametrize("path, expected_address", BINANCE_ADDRESS_TEST_VECTORS) +def test_binance_get_address_chunkify_details( + client: Client, path: str, expected_address: str ): # data from https://github.com/binance-chain/javascript-sdk/blob/master/__tests__/crypto.test.js#L50 - address = get_address( - client, parse_path(path), show_display=True, chunkify=chunkify - ) - assert address == expected_address + with client: + IF = InputFlowShowAddressQRCode(client) + client.set_input_flow(IF.get()) + address = get_address( + client, parse_path(path), show_display=True, chunkify=True + ) + assert address == expected_address diff --git a/tests/device_tests/ethereum/test_getaddress.py b/tests/device_tests/ethereum/test_getaddress.py index 0720197b08..3d0b678378 100644 --- a/tests/device_tests/ethereum/test_getaddress.py +++ b/tests/device_tests/ethereum/test_getaddress.py @@ -21,15 +21,27 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.tools import parse_path from ...common import parametrize_using_common_fixtures +from ...input_flows import InputFlowShowAddressQRCode pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum] @parametrize_using_common_fixtures("ethereum/getaddress.json") -@pytest.mark.parametrize("chunkify", (True, False)) -def test_getaddress(client: Client, chunkify: bool, parameters, result): +def test_getaddress(client: Client, parameters, result): address_n = parse_path(parameters["path"]) assert ( - ethereum.get_address(client, address_n, show_display=True, chunkify=chunkify) - == result["address"] + ethereum.get_address(client, address_n, show_display=True) == result["address"] ) + + +@pytest.mark.skip_t1("No input flow for T1") +@parametrize_using_common_fixtures("ethereum/getaddress.json") +def test_getaddress_chunkify_details(client: Client, parameters, result): + with client: + IF = InputFlowShowAddressQRCode(client) + client.set_input_flow(IF.get()) + address_n = parse_path(parameters["path"]) + assert ( + ethereum.get_address(client, address_n, show_display=True, chunkify=True) + == result["address"] + ) diff --git a/tests/device_tests/monero/test_getaddress.py b/tests/device_tests/monero/test_getaddress.py index 1e056b5852..4c0808fc33 100644 --- a/tests/device_tests/monero/test_getaddress.py +++ b/tests/device_tests/monero/test_getaddress.py @@ -21,29 +21,45 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.tools import parse_path from ...common import MNEMONIC12 +from ...input_flows import InputFlowShowAddressQRCode + +TEST_VECTORS = [ + ( + "m/44h/128h/0h", + b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM", + ), + ( + "m/44h/128h/1h", + b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie", + ), + ( + "m/44h/128h/2h", + b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH", + ), +] + +pytestmark = [ + pytest.mark.altcoin, + pytest.mark.monero, + pytest.mark.skip_t1, + pytest.mark.setup_client(mnemonic=MNEMONIC12), +] -@pytest.mark.altcoin -@pytest.mark.monero -@pytest.mark.skip_t1 -@pytest.mark.setup_client(mnemonic=MNEMONIC12) -@pytest.mark.parametrize("chunkify", (True, False)) -def test_monero_getaddress(client: Client, chunkify: bool): - assert ( - monero.get_address( - client, parse_path("m/44h/128h/0h"), show_display=True, chunkify=chunkify +@pytest.mark.parametrize("path, expected_address", TEST_VECTORS) +def test_monero_getaddress(client: Client, path: str, expected_address: bytes): + address = monero.get_address(client, parse_path(path), show_display=True) + assert address == expected_address + + +@pytest.mark.parametrize("path, expected_address", TEST_VECTORS) +def test_monero_getaddress_chunkify_details( + client: Client, path: str, expected_address: bytes +): + with client: + IF = InputFlowShowAddressQRCode(client) + client.set_input_flow(IF.get()) + address = monero.get_address( + client, parse_path(path), show_display=True, chunkify=True ) - == b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM" - ) - assert ( - monero.get_address( - client, parse_path("m/44h/128h/1h"), show_display=True, chunkify=chunkify - ) - == b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie" - ) - assert ( - monero.get_address( - client, parse_path("m/44h/128h/2h"), show_display=True, chunkify=chunkify - ) - == b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH" - ) + assert address == expected_address diff --git a/tests/device_tests/ripple/__init__.py b/tests/device_tests/ripple/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/device_tests/ripple/test_get_address.py b/tests/device_tests/ripple/test_get_address.py index 147c984bbb..027b8b7e42 100644 --- a/tests/device_tests/ripple/test_get_address.py +++ b/tests/device_tests/ripple/test_get_address.py @@ -20,6 +20,8 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.ripple import get_address from trezorlib.tools import parse_path +from ...input_flows import InputFlowShowAddressQRCode + CUSTOM_MNEMONIC = ( "armed bundle pudding lazy strategy impulse where identify " "submit weekend physical antenna flight social acoustic absurd " @@ -32,15 +34,31 @@ pytestmark = [ pytest.mark.skip_t1, # T1 support is not planned ] +# data from https://iancoleman.io/bip39/ +TEST_VECTORS = [ + ("m/44h/144h/0h/0/0", "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H"), + ("m/44h/144h/0h/0/1", "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws"), + ("m/44h/144h/1h/0/0", "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX"), +] -def test_ripple_get_address(client: Client): - # data from https://iancoleman.io/bip39/ - address = get_address(client, parse_path("m/44h/144h/0h/0/0")) - assert address == "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H" - address = get_address(client, parse_path("m/44h/144h/0h/0/1")) - assert address == "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws" - address = get_address(client, parse_path("m/44h/144h/1h/0/0")) - assert address == "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX" + +@pytest.mark.parametrize("path, expected_address", TEST_VECTORS) +def test_ripple_get_address(client: Client, path: str, expected_address: str): + address = get_address(client, parse_path(path), show_display=True) + assert address == expected_address + + +@pytest.mark.parametrize("path, expected_address", TEST_VECTORS) +def test_ripple_get_address_chunkify_details( + client: Client, path: str, expected_address: str +): + with client: + IF = InputFlowShowAddressQRCode(client) + client.set_input_flow(IF.get()) + address = get_address( + client, parse_path(path), show_display=True, chunkify=True + ) + assert address == expected_address @pytest.mark.setup_client(mnemonic=CUSTOM_MNEMONIC) diff --git a/tests/device_tests/stellar/test_stellar.py b/tests/device_tests/stellar/test_stellar.py index 4916123e81..12c356a6d9 100644 --- a/tests/device_tests/stellar/test_stellar.py +++ b/tests/device_tests/stellar/test_stellar.py @@ -59,6 +59,12 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.tools import parse_path from ...common import parametrize_using_common_fixtures +from ...input_flows import InputFlowShowAddressQRCode + +pytestmark = [ + pytest.mark.altcoin, + pytest.mark.stellar, +] def parameters_to_proto(parameters): @@ -80,8 +86,6 @@ def parameters_to_proto(parameters): return tx, operations -@pytest.mark.altcoin -@pytest.mark.stellar @parametrize_using_common_fixtures("stellar/sign_tx.json") def test_sign_tx(client: Client, parameters, result): tx, operations = parameters_to_proto(parameters) @@ -92,8 +96,6 @@ def test_sign_tx(client: Client, parameters, result): assert b64encode(response.signature).decode() == result["signature"] -@pytest.mark.altcoin -@pytest.mark.stellar @parametrize_using_common_fixtures("stellar/sign_tx.json") @pytest.mark.skipif(not stellar.HAVE_STELLAR_SDK, reason="requires Stellar SDK") def test_xdr(parameters, result): @@ -110,13 +112,21 @@ def test_xdr(parameters, result): assert expected == actual -@pytest.mark.altcoin -@pytest.mark.stellar -@pytest.mark.parametrize("chunkify", (True, False)) @parametrize_using_common_fixtures("stellar/get_address.json") -def test_get_address(client: Client, chunkify: bool, parameters, result): +def test_get_address(client: Client, parameters, result): address_n = parse_path(parameters["path"]) - address = stellar.get_address( - client, address_n, show_display=True, chunkify=chunkify - ) + address = stellar.get_address(client, address_n, show_display=True) assert address == result["address"] + + +@pytest.mark.skip_t1("No input flow for T1") +@parametrize_using_common_fixtures("stellar/get_address.json") +def test_get_address_chunkify_details(client: Client, parameters, result): + with client: + IF = InputFlowShowAddressQRCode(client) + client.set_input_flow(IF.get()) + address_n = parse_path(parameters["path"]) + address = stellar.get_address( + client, address_n, show_display=True, chunkify=True + ) + assert address == result["address"] diff --git a/tests/device_tests/tezos/test_getaddress.py b/tests/device_tests/tezos/test_getaddress.py index 5330d132c0..b6683b2f03 100644 --- a/tests/device_tests/tezos/test_getaddress.py +++ b/tests/device_tests/tezos/test_getaddress.py @@ -20,16 +20,34 @@ from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.tezos import get_address from trezorlib.tools import parse_path +from ...input_flows import InputFlowShowAddressQRCode -@pytest.mark.altcoin -@pytest.mark.tezos -@pytest.mark.skip_t1 -@pytest.mark.parametrize("chunkify", (True, False)) -def test_tezos_get_address(client: Client, chunkify: bool): - path = parse_path("m/44h/1729h/0h") - address = get_address(client, path, show_display=True, chunkify=chunkify) - assert address == "tz1Kef7BSg6fo75jk37WkKRYSnJDs69KVqt9" +pytestmark = [ + pytest.mark.altcoin, + pytest.mark.tezos, + pytest.mark.skip_t1, +] - path = parse_path("m/44h/1729h/1h") - address = get_address(client, path, show_display=True, chunkify=chunkify) - assert address == "tz1ekQapZCX4AXxTJhJZhroDKDYLHDHegvm1" +TEST_VECTORS = [ + ("m/44h/1729h/0h", "tz1Kef7BSg6fo75jk37WkKRYSnJDs69KVqt9"), + ("m/44h/1729h/1h", "tz1ekQapZCX4AXxTJhJZhroDKDYLHDHegvm1"), +] + + +@pytest.mark.parametrize("path, expected_address", TEST_VECTORS) +def test_tezos_get_address(client: Client, path: str, expected_address: str): + address = get_address(client, parse_path(path), show_display=True) + assert address == expected_address + + +@pytest.mark.parametrize("path, expected_address", TEST_VECTORS) +def test_tezos_get_address_chunkify_details( + client: Client, path: str, expected_address: str +): + with client: + IF = InputFlowShowAddressQRCode(client) + client.set_input_flow(IF.get()) + address = get_address( + client, parse_path(path), show_display=True, chunkify=True + ) + assert address == expected_address diff --git a/tests/input_flows.py b/tests/input_flows.py index ae90db4bab..90e1f7a780 100644 --- a/tests/input_flows.py +++ b/tests/input_flows.py @@ -273,7 +273,15 @@ class InputFlowShowAddressQRCode(InputFlowBase): self.debug.press_yes() def input_flow_tr(self) -> BRGeneratorType: - yield + # Find out the page-length of the address + br = yield + if br.pages is not None: + address_swipes = br.pages - 1 + else: + address_swipes = 0 + for _ in range(address_swipes): + self.debug.press_right() + # Go into details self.debug.press_right() # Go through details and back @@ -281,6 +289,8 @@ class InputFlowShowAddressQRCode(InputFlowBase): self.debug.press_left() self.debug.press_left() # Confirm + for _ in range(address_swipes): + self.debug.press_right() self.debug.press_middle()