diff --git a/tests/speculos/conftest.py b/tests/speculos/conftest.py index f370ec7..514e7d3 100644 --- a/tests/speculos/conftest.py +++ b/tests/speculos/conftest.py @@ -1,12 +1,10 @@ -from collections import namedtuple from pathlib import Path -from pyexpat import model import pytest from speculos.client import SpeculosClient -from boilerplate_client.boilerplate_cmd import BoilerplateCommand +from ethereum_client.ethereum_cmd import EthereumCommand SCRIPT_DIR = Path(__file__).absolute().parent @@ -28,14 +26,14 @@ def client(pytestconfig): if model == "nanox": version = '2.0.2' # latest version of nanox_sdk - args = ['--model', model, '--display', pytestconfig.getoption("display"), '--sdk', version] + args = ['--log-level', 'speculos:DEBUG','--model', model, '--display', pytestconfig.getoption("display"), '--sdk', version] with SpeculosClient(app=str(file_path), args=args) as client: yield client @pytest.fixture() def cmd(client, pytestconfig): - yield BoilerplateCommand( + yield EthereumCommand( client=client, debug=True, model=pytestconfig.getoption("model"), diff --git a/tests/speculos/boilerplate_client/__init__.py b/tests/speculos/ethereum_client/__init__.py similarity index 100% rename from tests/speculos/boilerplate_client/__init__.py rename to tests/speculos/ethereum_client/__init__.py diff --git a/tests/speculos/boilerplate_client/boilerplate_cmd.py b/tests/speculos/ethereum_client/ethereum_cmd.py similarity index 79% rename from tests/speculos/boilerplate_client/boilerplate_cmd.py rename to tests/speculos/ethereum_client/ethereum_cmd.py index 0f86c96..bac567d 100644 --- a/tests/speculos/boilerplate_client/boilerplate_cmd.py +++ b/tests/speculos/ethereum_client/ethereum_cmd.py @@ -7,18 +7,18 @@ from typing import Tuple from speculos.client import SpeculosClient, ApduException -from boilerplate_client.boilerplate_cmd_builder import BoilerplateCommandBuilder, InsType -from boilerplate_client.exception import DeviceException -from boilerplate_client.transaction import Transaction +from ethereum_client.ethereum_cmd_builder import EthereumCommandBuilder, InsType +from ethereum_client.exception import DeviceException +from ethereum_client.transaction import Transaction -class BoilerplateCommand: +class EthereumCommand: def __init__(self, client: SpeculosClient, debug: bool = False, model: str = "nanos") -> None: self.client = client - self.builder = BoilerplateCommandBuilder(debug=debug) + self.builder = EthereumCommandBuilder(debug=debug) self.debug = debug self.model = model @@ -80,41 +80,42 @@ class BoilerplateCommand: result.append(eth_addr) result.append(chain_code) + @contextmanager def test_zemu_hard_apdu_sign(self, transaction: Transaction) -> Tuple[int, int, int]: sign: bytes = b'\xe0\x04\x00\x00\x80\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x69\x46\x85\x06\xa8\xb1\x5e\x00\x82\xeb\xeb\x94\x6b\x17\x54\x74\xe8\x90\x94\xc4\x4d\xa9\x8b\x95\x4e\xed\xea\xc4\x95\x27\x1d\x0f\x80\xb8\x44\x09\x5e\xa7\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7d\x27\x68\xde\x32\xb0\xb8\x0b\x7a\x34\x54\xc0\x6b\xda\xc9\x4a\x69\xdd\xc7\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\x80' simple_eth: bytes = b'\xe0\x04\x00\x00\x41\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xeb\x44\x85\x03\x06\xdc\x42\x00\x82\x52\x08\x94\x5a\x32\x17\x44\x66\x70\x52\xaf\xfa\x83\x86\xed\x49\xe0\x0e\xf2\x23\xcb\xff\xc3\x87\x6f\x9c\x9e\x7b\xf6\x18\x18\x80\x01\x80\x80' provide_erc20: bytes = b'\xe0\x0a\x00\x00\x67\x03\x44\x41\x49\x6b\x17\x54\x74\xe8\x90\x94\xc4\x4d\xa9\x8b\x95\x4e\xed\xea\xc4\x95\x27\x1d\x0f\x00\x00\x00\x12\x00\x00\x00\x01\x30\x45\x02\x21\x00\xb3\xaa\x97\x96\x33\x28\x4e\xb0\xf5\x54\x59\x09\x93\x33\xab\x92\xcf\x06\xfd\xd5\x8d\xc9\x0e\x9c\x07\x00\x00\xc8\xe9\x68\x86\x4c\x02\x20\x7b\x10\xec\x7d\x66\x09\xf5\x1d\xda\x53\xd0\x83\xa6\xe1\x65\xa0\xab\xf3\xa7\x7e\x13\x25\x0e\x6f\x26\x07\x72\x80\x9b\x49\xaf\xf5' b: bytes = b'\xe0\x04\x00\x00\x56\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x3f\x26\x8e\x02\xcc\x9b\xe5\xc5\x3e\xa4\x4b\xd4\x3c\x28\x9d\xcd\xdc\x82\x52\x08\x94\xda\xc1\x7f\x95\x8d\x2e\xe5\x23\xa2\x20\x62\x06\x99\x45\x97\xc1\x3d\x83\x1e\xc7\x92\x8d\xb8\xb0\x86\x1b\x8f\x7f\xe5\xdf\x83\xcd\x55\x3a\x82\x98\x78\x00\x00\x80\x01\x80\x80' + test: bytes = b"".join([b'\xe0\x04\x00\x00\x89\x05\x80\x00\x00\x2c\x80\x00\x00\x3c\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02', + b'\xf8\x70\x02', + b'\x02', #nonce + b'\x85', + b'\x02\x54\x0b\xe4\x00', # max priority fee per gas + b'\x85', + b'\x02\x54\x0b\xe4\x00', # max fee per gas + b'\x86', + b'\x24\x61\x39\xca\x80\x80', # gas limit + b'\x94', + b'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc', # destination + b'\x81'+ + b'\xFF' + # Amount + b'\x00' + # Payload + b'\xc0\x01\xa0\xe0\x7f\xb8\xa6\x4e\xa3\x78\x6c\x9a\x66\x49\xe5\x44\x29\xe2\x78\x6a\xf3\xea\x31\xc6\xd0\x61\x65\x34\x66\x78\xcf\x8c\xe4\x4f\x9b\xa0\x0e\x4a\x05\x26\xdb\x1e\x90\x5b\x71\x64\xa8\x58\xfd\x5e\xbd\x2f\x17\x59\xe2\x2e\x69\x55\x49\x94\x48\xbd\x27\x6a\x6a\xa6\x28\x30']) a = self.builder.simple_sign_tx(bip32_path="44'/60'/1'/0/0", transaction=transaction) try: - response = self.client._apdu_exchange( - a - ) # type: int, bytes + with self.client._apdu_exchange_nowait(test) as ex: + yield ex #response = self.client._apdu_exchange( # sign #) except ApduException as error: raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - # response = V (1) || R (32) || S (32) - assert len(response) == 65 - - offset: int = 0 - - v: bytes = response[offset] - offset += 1 - - r: bytes = response[offset:offset + 32] - offset += 32 - - s: bytes = response[offset:] - - return v, r, s @contextmanager diff --git a/tests/speculos/boilerplate_client/boilerplate_cmd_builder.py b/tests/speculos/ethereum_client/ethereum_cmd_builder.py similarity index 97% rename from tests/speculos/boilerplate_client/boilerplate_cmd_builder.py rename to tests/speculos/ethereum_client/ethereum_cmd_builder.py index 4508cdb..1dc0e67 100644 --- a/tests/speculos/boilerplate_client/boilerplate_cmd_builder.py +++ b/tests/speculos/ethereum_client/ethereum_cmd_builder.py @@ -1,13 +1,11 @@ import enum import logging -import string import struct from typing import List, Tuple, Union, Iterator, cast -import rlp -from boilerplate_client.transaction import Transaction -from boilerplate_client.utils import bip32_path_from_string +from ethereum_client.transaction import Transaction +from ethereum_client.utils import bip32_path_from_string MAX_APDU_LEN: int = 255 @@ -45,7 +43,7 @@ class InsType(enum.IntEnum): INS_SET_PLUGIN = 0x16 -class BoilerplateCommandBuilder: +class EthereumCommandBuilder: """APDU command builder for the Boilerplate application. Parameters diff --git a/tests/speculos/boilerplate_client/exception/__init__.py b/tests/speculos/ethereum_client/exception/__init__.py similarity index 100% rename from tests/speculos/boilerplate_client/exception/__init__.py rename to tests/speculos/ethereum_client/exception/__init__.py diff --git a/tests/speculos/boilerplate_client/exception/device_exception.py b/tests/speculos/ethereum_client/exception/device_exception.py similarity index 100% rename from tests/speculos/boilerplate_client/exception/device_exception.py rename to tests/speculos/ethereum_client/exception/device_exception.py diff --git a/tests/speculos/boilerplate_client/exception/errors.py b/tests/speculos/ethereum_client/exception/errors.py similarity index 100% rename from tests/speculos/boilerplate_client/exception/errors.py rename to tests/speculos/ethereum_client/exception/errors.py diff --git a/tests/speculos/boilerplate_client/transaction.py b/tests/speculos/ethereum_client/transaction.py similarity index 96% rename from tests/speculos/boilerplate_client/transaction.py rename to tests/speculos/ethereum_client/transaction.py index 8660c2a..f7aec02 100644 --- a/tests/speculos/boilerplate_client/transaction.py +++ b/tests/speculos/ethereum_client/transaction.py @@ -1,13 +1,16 @@ from io import BytesIO from typing import Union -from boilerplate_client.utils import (read, read_uint, read_varint, +from ethereum_client.utils import (read, read_uint, read_varint, write_varint, UINT64_MAX) class TransactionError(Exception): pass +EIP2930 = 1 +EIP1559 = 2 + class Transaction: def __init__(self, txType: int, nonce: int, gasPrice: int, gasLimit: int, to: Union[str, bytes], value: int, data: Union[str, bytes] = "", chainID: int = -1) -> None: diff --git a/tests/speculos/boilerplate_client/utils.py b/tests/speculos/ethereum_client/utils.py similarity index 100% rename from tests/speculos/boilerplate_client/utils.py rename to tests/speculos/ethereum_client/utils.py diff --git a/tests/speculos/test_pubkey_cmd.py b/tests/speculos/test_pubkey_cmd.py index 7d3d90e..4f940f7 100644 --- a/tests/speculos/test_pubkey_cmd.py +++ b/tests/speculos/test_pubkey_cmd.py @@ -5,8 +5,8 @@ from typing import Tuple from time import sleep -import boilerplate_client -from boilerplate_client.utils import UINT64_MAX, compare_screenshot, save_screenshot +import ethereum_client +from ethereum_client.utils import UINT64_MAX, compare_screenshot, save_screenshot def test_get_public_key(cmd): @@ -115,5 +115,5 @@ def test_reject_get_public_key(cmd): compare_screenshot(cmd, f"screenshots/pubkey/{cmd.model}/reject_get_public_key/00003.png") cmd.client.press_and_release('both') - except boilerplate_client.exception.errors.DenyError as error: + except ethereum_client.exception.errors.DenyError as error: assert error.args[0] == '0x6985' diff --git a/tests/speculos/test_sign_cmd.py b/tests/speculos/test_sign_cmd.py index a2f286c..6c44f5d 100644 --- a/tests/speculos/test_sign_cmd.py +++ b/tests/speculos/test_sign_cmd.py @@ -1,9 +1,9 @@ from time import sleep -import boilerplate_client +import ethereum_client -from boilerplate_client.utils import UINT64_MAX, compare_screenshot, compare_screenshot, save_screenshot -from boilerplate_client.transaction import Transaction +from ethereum_client.utils import UINT64_MAX, compare_screenshot, compare_screenshot, save_screenshot +from ethereum_client.transaction import Transaction # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md @@ -246,7 +246,7 @@ def test_sign_reject(cmd): compare_screenshot(cmd, f"screenshots/sign/{cmd.model}/reject/00005.png") cmd.client.press_and_release('both') - except boilerplate_client.exception.errors.DenyError as error: + except ethereum_client.exception.errors.DenyError as error: assert error.args[0] == '0x6985' @@ -347,7 +347,7 @@ def test_sign_error_transaction_type(cmd): try: with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: pass - except boilerplate_client.exception.errors.UnknownDeviceError as error: + except ethereum_client.exception.errors.UnknownDeviceError as error: # Throw error of transaction type not supported assert error.args[0] == '0x6501' @@ -355,7 +355,7 @@ def test_sign_error_transaction_type(cmd): try: with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: pass - except boilerplate_client.exception.errors.UnknownDeviceError as error: + except ethereum_client.exception.errors.UnknownDeviceError as error: # Throw error of transaction type not supported assert error.args[0] == '0x6501' @@ -588,7 +588,7 @@ def test_sign_blind_error_disabled(cmd): pass if cmd.model == "nanox": pass - except boilerplate_client.exception.errors.UnknownDeviceError as error: + except ethereum_client.exception.errors.UnknownDeviceError as error: assert error.args[0] == '0x6a80'