Skip to content

Commit

Permalink
test: fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Aug 2, 2023
1 parent 1179886 commit 5172f54
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 129 deletions.
12 changes: 8 additions & 4 deletions ape_ledger/_cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import List, Tuple, Union

import click
from ape import accounts
Expand All @@ -15,7 +15,12 @@
from ape_ledger.accounts import LedgerAccount
from ape_ledger.choices import AddressPromptChoice
from ape_ledger.exceptions import LedgerSigningError
from ape_ledger.hdpath import HDBasePath
from ape_ledger.hdpath import HDAccountPath, HDBasePath


def _select_account(hd_path: Union[HDBasePath, str]) -> Tuple[str, HDAccountPath]:
choices = AddressPromptChoice(hd_path)
return choices.get_user_selected_account()


@click.group(short_help="Manage Ledger accounts")
Expand Down Expand Up @@ -66,8 +71,7 @@ def _get_ledger_accounts() -> List[LedgerAccount]:
def add(cli_ctx, alias, hd_path):
"""Add an account from your Ledger hardware wallet"""

choices = AddressPromptChoice(hd_path)
address, account_hd_path = choices.get_user_selected_account()
address, account_hd_path = _select_account(hd_path)
container = accounts.containers.get("ledger")
container.save_account(alias, address, str(account_hd_path))
cli_ctx.logger.success(f"Account '{address}' successfully added with alias '{alias}'.")
Expand Down
1 change: 1 addition & 0 deletions ape_ledger/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def sign_transaction(self, txn: TransactionAPI, **kwargs) -> Optional[Transactio
else:
raise TypeError(type(txn))

_echo_object_to_sign(txn)
v, r, s = self._client.sign_transaction(txn_dict)
txn.signature = TransactionSignature(
v=v,
Expand Down
9 changes: 6 additions & 3 deletions ape_ledger/choices.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Optional, Tuple
from typing import Any, Optional, Tuple, Union

import click
from ape.cli import PromptChoice
Expand All @@ -17,10 +17,13 @@ class AddressPromptChoice(PromptChoice):

def __init__(
self,
hd_path: HDBasePath,
hd_path: Union[HDBasePath, str],
index_offset: int = 0,
page_size: int = DEFAULT_PAGE_SIZE,
):
if isinstance(hd_path, str):
hd_path = HDBasePath(base_path=hd_path)

self._hd_root_path = hd_path
self._index_offset = index_offset
self._page_size = page_size
Expand Down Expand Up @@ -99,4 +102,4 @@ def _get_address(self, account_id: int) -> str:
return device.get_address()


__all__ = ["AddressPromptChoice", "PromptChoice"]
__all__ = ["AddressPromptChoice"]
10 changes: 8 additions & 2 deletions ape_ledger/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from ape.logging import LogLevel, logger
from ledgerblue.comm import HIDDongleHIDAPI, getDongle # type: ignore
from ledgereth.accounts import get_account_by_path
from ledgereth.messages import sign_message
from ledgereth.messages import sign_message, sign_typed_data_draft
from ledgereth.transactions import SignedType2Transaction, create_transaction

from ape_ledger.hdpath import HDAccountPath
Expand Down Expand Up @@ -57,7 +57,13 @@ def get_address(self) -> str:
return get_account_by_path(self._account, dongle=self.dongle).address

def sign_message(self, text: bytes) -> Tuple[int, int, int]:
signed_msg = sign_message(text, sender_path=self._account)
signed_msg = sign_message(text, sender_path=self._account, dongle=self.dongle)
return signed_msg.v, signed_msg.r, signed_msg.s

def sign_typed_data(self, domain_hash: bytes, message_hash: bytes) -> Tuple[int, int, int]:
signed_msg = sign_typed_data_draft(
domain_hash, message_hash, sender_path=self._account, dongle=self.dongle
)
return signed_msg.v, signed_msg.r, signed_msg.s

def sign_transaction(self, txn: Dict) -> Tuple[int, int, int]:
Expand Down
28 changes: 20 additions & 8 deletions ape_ledger/hdpath.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import struct
from typing import Optional, Union


class HDPath:
Expand All @@ -8,12 +9,18 @@ class HDPath:
as well as the derivation HD path class :class:`~ape_ledger.hdpath.HDBasePath`.
"""

def __init__(self, path: str):
path = path.rstrip("/")
if not path.startswith("m/"):
def __init__(self, path: Union[str, "HDBasePath"]):
if not isinstance(path, str) and hasattr(path, "path"):
# NOTE: Using getattr for mypy
path_str = getattr(path, "path")
else:
path_str = path

path_str = path_str.rstrip("/")
if not path_str.startswith("m/"):
raise ValueError("HD path must begin with m/")

self.path = path
self.path = path_str

def __str__(self):
return self.path
Expand Down Expand Up @@ -64,11 +71,16 @@ class HDBasePath(HDPath):
:class:`~ape_ledger.hdpath.HDAccountPath`.
"""

def __init__(self, base_path=None):
def __init__(self, base_path: Optional[Union[str, "HDBasePath"]] = None):
base_path = base_path or "m/44'/60'/{x}'/0/0"
base_path = base_path.rstrip("/")
base_path = base_path if "{x}" in base_path else f"{base_path}/{{x}}"
super().__init__(base_path)
if not isinstance(base_path, str) and hasattr(base_path, "path"):
base_path_str = base_path.path
else:
base_path_str = base_path

base_path_str = base_path_str.rstrip("/")
base_path_str = base_path_str if "{x}" in base_path_str else f"{base_path_str}/{{x}}"
super().__init__(base_path_str)

def get_account_path(self, account_id) -> HDAccountPath:
return HDAccountPath(self.path.format(x=str(account_id)))
Expand Down
31 changes: 22 additions & 9 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ape_ledger.client import LedgerDeviceClient

TEST_ALIAS = "TestAlias"
TEST_HD_PATH = "m/44'/60'/0'/0/0"
TEST_HD_PATH = "m/44'/60'/{x}'/0/0"


@pytest.fixture
Expand Down Expand Up @@ -66,22 +66,26 @@ def msg_signature(account_0):


@pytest.fixture
def tx_signature(account_0, account_1):
txn = account_0.transfer(account_1, "1 gwei")
def receipt(account_0, account_1):
return account_0.transfer(account_1, "1 gwei")


@pytest.fixture
def tx_signature(receipt):
return (
txn.signature.v,
int(HexBytes(txn.signature.r).hex(), 16),
int(HexBytes(txn.signature.s).hex(), 16),
receipt.signature.v,
int(HexBytes(receipt.signature.r).hex(), 16),
int(HexBytes(receipt.signature.s).hex(), 16),
)


@pytest.fixture(autouse=True)
def mock_device(mocker, hd_path, account_addresses, msg_signature, tx_signature):
device = mocker.MagicMock(spec=LedgerDeviceClient)
patch = mocker.patch("ape_ledger.client.get_device")
patch.return_value = device
device._account = hd_path
device.get_address.side_effect = lambda a: account_addresses[a]
device.get_address.side_effect = (
lambda *args, **kwargs: account_addresses[args[0]] if args else account_addresses[0]
)
device.sign_message.side_effect = lambda *args, **kwargs: msg_signature
device.sign_transaction.side_effect = lambda *args, **kwargs: tx_signature
return device
Expand All @@ -107,3 +111,12 @@ def fn(account_path, expected_address=None, expected_hdpath="m/44'/60'/0'/0/0"):
assert account_data["hdpath"] == expected_hdpath

return fn


@pytest.fixture
def device_factory(mocker, mock_device):
def fn(module):
patch = mocker.patch(f"ape_ledger.{module}.get_device")
patch.return_value = mock_device

return fn
Loading

0 comments on commit 5172f54

Please sign in to comment.