feat: erc20information simple test and refacto plugin class

This commit is contained in:
Coline
2022-07-04 10:38:32 +02:00
parent 9b4d6504f1
commit 87eaaeeb5b
6 changed files with 100 additions and 14 deletions

View File

@@ -8,7 +8,7 @@ from speculos.client import SpeculosClient, ApduException
from ethereum_client.ethereum_cmd_builder import EthereumCommandBuilder, InsType
from ethereum_client.exception import DeviceException
from ethereum_client.transaction import PersonalTransaction, Transaction
from ethereum_client.plugin import Plugin
from ethereum_client.plugin import ERC20_Information, Plugin
from ethereum_client.utils import parse_sign_response
@@ -42,20 +42,30 @@ class EthereumCommand:
def set_plugin(self, plugin: Plugin):
try:
response = self.client._apdu_exchange(
self.client._apdu_exchange(
self.builder.set_plugin(plugin=plugin)
)
except ApduException as error:
raise DeviceException(error_code=error.sw, ins=InsType.INS_SET_PLUGIN)
def provide_nft_information(self, plugin: Plugin):
try:
response = self.client._apdu_exchange(
self.client._apdu_exchange(
self.builder.provide_nft_information(plugin=plugin)
)
except ApduException as error:
raise DeviceException(error_code=error.sw, ins=InsType.INS_SET_PLUGIN)
raise DeviceException(error_code=error.sw, ins=InsType.INS_PROVIDE_NFT_INFORMATION)
def provide_erc20_token_information(self, info: ERC20_Information):
try:
self.client._apdu_exchange(
self.builder.provide_erc20_token_information(info=info)
)
except ApduException as error:
raise DeviceException(error_code=error.sw, ins=InsType.INS_PROVIDE_ERC20)
@contextmanager

View File

@@ -4,7 +4,7 @@ import struct
from typing import List, Tuple, Union, Iterator, cast
from ethereum_client.transaction import PersonalTransaction, Transaction
from ethereum_client.plugin import Plugin
from ethereum_client.plugin import ERC20_Information, Plugin
from ethereum_client.utils import bip32_path_from_string
MAX_APDU_LEN: int = 255
@@ -164,6 +164,27 @@ class EthereumCommandBuilder:
p2=0x00,
cdata=cdata)
def provide_erc20_token_information(self, info: ERC20_Information):
"""Command builder for PROVIDE_ERC20_INFORMATION.
Parameters
----------
-> Check documentation of APDU
Returns
-------
bytes
APDU command for PROVIDE_ERC20_INFORMATION.
"""
cdata: bytes = info.serialize()
return self.serialize(cla=self.CLA,
ins=InsType.INS_PROVIDE_ERC20,
p1=0x00,
p2=0x00,
cdata=cdata)
def get_public_key(self, bip32_path: str, display: bool = False) -> bytes:
"""Command builder for GET_PUBLIC_KEY.

View File

@@ -1,6 +1,29 @@
import string
from typing import Union
from ethereum_client.utils import write_varint
from ethereum_client.utils import apdu_as_string, write_varint
class ERC20_Information:
def __init__(self, erc20_ticker: string , addr: Union[str, bytes], nb_decimals: int, chainID: int, sign: str) -> None:
self.erc20_ticker: bytes = apdu_as_string(erc20_ticker)
self.addr: bytes = bytes.fromhex(addr[2:]) if isinstance(addr, str) else addr
self.nb_decimals: int = nb_decimals
self.chainID: int = chainID
self.sign: bytes = apdu_as_string(sign)
def serialize(self) -> bytes:
return b"".join([
write_varint(len(self.erc20_ticker)),
self.erc20_ticker,
self.addr,
self.nb_decimals.to_bytes(4, byteorder="big"),
self.chainID.to_bytes(4, byteorder="big"),
self.sign,
])
class Plugin:
"""Plugin class
@@ -11,7 +34,7 @@ class Plugin:
do not define a selector
"""
def __init__(self, type: int, version: int, name: str, addr: Union[str, bytes], selector: int = -1, chainID: int = 1, keyID: int = 0, algorithm: int = 1, sign: bytes = b'') -> None:
def __init__(self, type: int, version: int, name: str, addr: Union[str, bytes], selector: int = -1, chainID: int = 1, keyID: int = 0, algorithm: int = 1, sign: str = "") -> None:
self.type: int = type
self.version: int = version
self.name: bytes = bytes(name, 'UTF-8')
@@ -20,7 +43,7 @@ class Plugin:
self.chainID: int = chainID
self.keyID: int = keyID
self.algorithm: int = algorithm
self.sign: bytes = sign
self.sign: bytes = apdu_as_string(sign)
def serialize(self) -> bytes:
return b"".join([

View File

@@ -16,7 +16,7 @@ PLUGIN = Plugin(
chainID=1,
keyID=0,
algorithm=1,
sign=b"\x30\x45\x02\x21\x00\xec\x43\x77\xd1\x7e\x8d\x98\xd4\x24\xbf\x16\xb2\x9c\x69\x1b\xc1\xa0\x10\x82\x5f\xb5\xb8\xa3\x5d\xe0\x26\x8a\x9d\xc2\x2e\xab\x24\x02\x20\x67\x01\xb0\x16\xfe\x67\x18\xbf\x51\x9d\x18\xcc\x12\xe9\x83\x8e\x9e\xf8\x98\xcc\x4c\x14\x30\x17\x83\x90\x23\xc3\x26\x0b\x2d\x74",
sign="3045022100ec4377d17e8d98d424bf16b29c691bc1a010825fb5b8a35de0268a9dc22eab2402206701b016fe6718bf519d18cc12e9838e9ef898cc4c143017839023c3260b2d74",
)
PROVIDE_NFT_INFORMATION = Plugin(
@@ -27,7 +27,7 @@ PROVIDE_NFT_INFORMATION = Plugin(
chainID=1,
keyID=0,
algorithm=1,
sign=b"\x30\x45\x02\x21\x00\x83\xe3\x57\xa8\x28\xf1\x3d\x57\x4b\x12\x96\x21\x4a\x37\x49\xc1\x94\xab\x1d\xf1\xf8\xa2\x43\x65\x5c\x05\x3b\x1c\x72\xf9\x1e\x0c\x02\x20\x1e\xd9\x3c\xfa\xc7\xe8\x77\x59\x44\x5c\x4d\xa2\xe4\xbf\xd6\xe1\xcf\x04\x05\xea\x37\xc7\x29\x3b\xc9\x65\x94\x8f\x51\xbe\xf5\xcc",
sign="304502210083e357a828f13d574b1296214a3749c194ab1df1f8a243655c053b1c72f91e0c02201ed93cfac7e87759445c4da2e4bfd6e1cf0405ea37c7293bc965948f51bef5cc",
)
def test_transfer_erc1155(cmd):
@@ -139,7 +139,7 @@ PLUGIN_BATCH = Plugin(
chainID=1,
keyID=0,
algorithm=1,
sign=b"\x30\x45\x02\x21\x00\x87\xb3\x5c\xef\xc5\x3f\xd9\x4e\x25\x40\x49\x33\xeb\x0d\x5f\xf0\x8f\x20\xba\x65\x5d\x18\x1d\xe3\xb2\x4f\xf0\x09\x9d\xc3\x31\x7f\x02\x20\x4a\x21\x6a\xa9\xe0\xb8\x4b\xef\x6e\x20\xfc\xb0\x36\xbd\x49\x64\x7b\xf0\xca\xb6\x67\x32\xb9\x9b\x49\xec\x27\x7f\xfb\x68\x2a\xa1",
sign="304502210087b35cefc53fd94e25404933eb0d5ff08f20ba655d181de3b24ff0099dc3317f02204a216aa9e0b84bef6e20fcb036bd49647bf0cab66732b99b49ec277ffb682aa1",
)
PROVIDE_NFT_INFORMATION_BATCH = Plugin(
@@ -150,7 +150,7 @@ PROVIDE_NFT_INFORMATION_BATCH = Plugin(
chainID=1,
keyID=0,
algorithm=1,
sign=b"\x30\x45\x02\x21\x00\xc7\x4c\xd6\x13\xa2\x7a\x9f\x48\x87\x21\x0f\x5a\x3a\x0e\x12\x74\x5e\x1b\xa0\xab\x3a\x0d\x28\x4c\xb6\x48\x5d\x89\xc3\xcc\xe4\xe6\x02\x20\x5a\x13\xe6\x2a\x91\x16\x49\x85\xcf\x58\xa8\x38\xf8\xf5\x31\xc0\xb9\x1b\x98\x0d\x20\x6a\x5b\xa8\xdf\x28\x27\x00\x23\xef\x93\xa3",
sign="3045022100c74cd613a27a9f4887210f5a3a0e12745e1ba0ab3a0d284cb6485d89c3cce4e602205a13e62a91164985cf58a838f8f531c0b91b980d206a5ba8df28270023ef93a3",
)
def test_transfer_batch_erc1155(cmd):

View File

@@ -0,0 +1,32 @@
from ethereum_client.plugin import ERC20_Information
import ethereum_client
def test_provide_erc20_token(cmd):
erc20_info = ERC20_Information(
erc20_ticker="5a5258",
addr="0xe41d2489571d322189246dafa5ebde1f4699f498",
nb_decimals=18,
chainID=1,
sign="304402200ae8634c22762a8ba41d2acb1e068dcce947337c6dd984f13b820d396176952302203306a49d8a6c35b11a61088e1570b3928ca3a0db6bd36f577b5ef87628561ff7"
)
# Test if return 9000
try:
cmd.provide_erc20_token_information(info=erc20_info)
except:
raise
def test_provide_erc20_token_error(cmd):
erc20_info = ERC20_Information(
erc20_ticker="5a5258",
addr="0xe41d2489571d322189246dafa5ebde1f4699f498",
nb_decimals=18,
chainID=1,
sign="deadbeef"
)
# Test if return 9000
try:
cmd.provide_erc20_token_information(info=erc20_info)
except ethereum_client.exception.errors.UnknownDeviceError as error:
assert error.args[0] == '0x6a80'

View File

@@ -16,7 +16,7 @@ PLUGIN = Plugin(
chainID=1,
keyID=0,
algorithm=1,
sign=b"\x30\x45\x02\x20\x2e\x22\x82\xd7\xd3\xea\x71\x4d\xa2\x83\x01\x0f\x51\x7a\xf4\x69\xe1\xd5\x96\x54\xaa\xee\x0f\xc4\x38\xf0\x17\xaa\x55\x7e\xae\xa5\x02\x21\x00\x8b\x36\x96\x79\x38\x10\x65\xbb\xe0\x11\x35\x72\x3a\x4f\x9a\xdb\x22\x92\x95\x01\x7d\x37\xc4\xd3\x01\x38\xb9\x0a\x51\xcf\x6a\xb6",
sign="304502202e2282d7d3ea714da283010f517af469e1d59654aaee0fc438f017aa557eaea50221008b369679381065bbe01135723a4f9adb229295017d37c4d30138b90a51cf6ab6",
)
PROVIDE_NFT_INFORMATION = Plugin(
@@ -27,7 +27,7 @@ PROVIDE_NFT_INFORMATION = Plugin(
chainID=1,
keyID=0,
algorithm=1,
sign=b"\x30\x45\x02\x20\x25\x69\x69\x86\xef\x5f\x0e\xe2\xf7\x2d\x9c\x6e\x41\xd7\xe2\xbf\x2e\x4f\x06\x37\x3a\xb2\x6d\x73\xeb\xe3\x26\xc7\xfd\x4c\x7a\x66\x02\x21\x00\x84\xf6\xb0\x64\xd8\x75\x0a\xe6\x8e\xd5\xdd\x01\x22\x96\xf3\x70\x30\x39\x0e\xc0\x6f\xf5\x34\xc5\xda\x6f\x0f\x4a\x44\x60\xaf\x33",
sign="3045022025696986ef5f0ee2f72d9c6e41d7e2bf2e4f06373ab26d73ebe326c7fd4c7a6602210084f6b064d8750ae68ed5dd012296f37030390ec06ff534c5da6f0f4a4460af33",
)
def test_transfer_erc721(cmd):