diff --git a/tests/conftest.py b/tests/conftest.py index 4bdf8db3..8aac9622 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,8 @@ +import pytest + from ragger.conftest import configuration +from .utils import WalletAddr + ########################### ### CONFIGURATION START ### @@ -20,3 +24,7 @@ # Pull all features from the base ragger conftest using the overridden configuration pytest_plugins = ("ragger.conftest.base_conftest", ) + +@pytest.fixture +def wallet_addr(backend): + return WalletAddr(backend) diff --git a/tests/test_swap.py b/tests/test_swap.py index 059d2e89..d777ce42 100644 --- a/tests/test_swap.py +++ b/tests/test_swap.py @@ -1,17 +1,17 @@ from pathlib import Path import json import os - import datetime from web3 import Web3 from eth_typing import ChainId -from ledger_app_clients.ethereum.client import EthAppClient, StatusWord -from ledger_app_clients.ethereum.utils import get_selector_from_data +from ledger_app_clients.ethereum.client import EthAppClient +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ledger_app_clients.ethereum.utils import get_selector_from_data, recover_transaction from ragger.navigator import NavInsID -from .utils import get_appname_from_makefile +from .utils import get_appname_from_makefile, DERIVATION_PATH ROOT_SCREENSHOT_PATH = Path(__file__).parent @@ -19,6 +19,7 @@ PLUGIN_NAME = get_appname_from_makefile() + with open("%s/0x000102030405060708090a0b0c0d0e0f10111213.abi.json" % (ABIS_FOLDER)) as file: contract = Web3().eth.contract( abi=json.load(file), @@ -28,7 +29,7 @@ # EDIT THIS: build your own test -def test_swap_exact_eth_for_token(backend, firmware, navigator, test_name): +def test_swap_exact_eth_for_token(backend, firmware, navigator, test_name, wallet_addr): client = EthAppClient(backend) data = contract.encodeABI("swapExactETHForTokens", [ @@ -48,17 +49,18 @@ def test_swap_exact_eth_for_token(backend, firmware, navigator, test_name): get_selector_from_data(data)): pass + tx_params = { + "nonce": 20, + "maxFeePerGas": Web3.to_wei(145, "gwei"), + "maxPriorityFeePerGas": Web3.to_wei(1.5, "gwei"), + "gas": 173290, + "to": contract.address, + "value": Web3.to_wei(0.1, "ether"), + "chainId": ChainId.ETH, + "data": data + } # send the transaction - with client.sign("m/44'/60'/1'/0/0", { - "nonce": 20, - "maxFeePerGas": Web3.to_wei(145, "gwei"), - "maxPriorityFeePerGas": Web3.to_wei(1.5, "gwei"), - "gas": 173290, - "to": contract.address, - "value": Web3.to_wei(0.1, "ether"), - "chainId": ChainId.ETH, - "data": data - }): + with client.sign(DERIVATION_PATH, tx_params): # Validate the on-screen request by performing the navigation appropriate for this device if firmware.device.startswith("nano"): navigator.navigate_until_text_and_compare(NavInsID.RIGHT_CLICK, @@ -73,3 +75,7 @@ def test_swap_exact_eth_for_token(backend, firmware, navigator, test_name): "Hold to sign", ROOT_SCREENSHOT_PATH, test_name) + # verify signature + vrs = ResponseParser.signature(client.response().data) + addr = recover_transaction(tx_params, vrs) + assert addr == wallet_addr.get() diff --git a/tests/utils.py b/tests/utils.py index de202329..221ca848 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,9 +1,12 @@ import os import re - from pathlib import Path from typing import Optional +from ledger_app_clients.ethereum.client import EthAppClient +import ledger_app_clients.ethereum.response_parser as ResponseParser + +DERIVATION_PATH = "m/44'/60'/0'/0/0" makefile_relative_path = "../Makefile" makefile_path = (Path(os.path.dirname(os.path.realpath(__file__))) / Path(makefile_relative_path)).resolve() @@ -12,6 +15,7 @@ default_strip_parameter = " \t\n\r\x0b\x0c" + def get_appname_from_makefile() -> str: ''' Parse the app Makefile to automatically get the APPNAME value @@ -27,3 +31,15 @@ def get_appname_from_makefile() -> str: raise AssertionError("Unable to find APPNAME in the Makefile") return APPNAME + + +class WalletAddr: + client: EthAppClient + + def __init__(self, backend): + self.client = EthAppClient(backend) + + def get(self, path=DERIVATION_PATH) -> bytes: + with self.client.get_public_addr(display=False, bip32_path=path): + pass + return ResponseParser.pk_addr(self.client.response().data)[1]