from typing import Iterator from trezor.utils import ensure from ubinascii import hexlify, unhexlify # noqa: F401 from trezor import messages from apps.ethereum import networks, tokens EXPECTED_FORMAT_VERSION = 1 EXPECTED_DATA_VERSION = 1663054984 # unix epoch time class InfoWithDefinition(): def __init__(self, definition, info): self.definition = definition self.info = info # definitions created by `common/tools/ethereum_definitions.py` and copied here NETWORKS = { # chain_id: network info with encoded definition # Ethereum 1: InfoWithDefinition( definition=None, # built-in definitions are not encoded info=networks.NetworkInfo( chain_id=1, slip44=60, shortcut="ETH", name="Ethereum", rskip60=False, ), ), # Rinkeby 4: InfoWithDefinition( definition=unhexlify("74727a643100000000632034880015080410011a047452494e220752696e6b65627928000e8cc47ed4e657d9a9b98e1dd02164320c54a9724e17f91d1d79f6760169582c98ec70ca6f4e94d27e574175c59d2ae04e0cd30b65fb19acd8d2c5fb90bcb7db96f6102e4182c0cef5f412ac3c5fa94f9505b4df2633a0f7bdffa309588d722415624adeb8f329b1572ff9dfc81fbc86e61f1fcb2369f51ba85ea765c908ac254ba996f842a6277583f8d02f149c78bc0eeb8f3d41240403f85785dc3a3925ea768d76aae12342c8a24de223c1ea75e5f07f6b94b8f22189413631eed3c9a362b4501f68b645aa487b9d159a8161404a218507641453ebf045cec56710bb7d873e102777695b56903766e1af16f95576ec4f41874bdaf80cec02ee067d30e721515564d4f30fa74a6c61eb784ea65cc881ead7af2ffac02d5bf1fe1a756918fe37b74828a24b640025cd79443ada60063e3034444fc49ed6055dbba6a09fa4484c42cb85abb49103dc8c781c8f190c4632e2dec30081770448021313955dbb49e8a02fd49b34d030280452fe0a5c3bcba4958bc287c67e12519be4f4aec7ab0c8e574e53a663f635f75508f23d92c77b2147f29feb79c38d0f793fba295aae605c7e8226523edefc6ad1eefe088e5b8376028bf90116ece4fb876510b4ae1c89686dbcaacbbac8225baba429ca376fafac50f4bd1ff4ce1c61dd53318d0718bf513ea6f770cce81e07a653622e4dbd03bdaa570bfe43219eb0d4fab725c9a8da04"), info=networks.NetworkInfo( chain_id=4, slip44=1, shortcut="tRIN", name="Rinkeby", rskip60=False, ), ), # Ubiq 8: InfoWithDefinition( definition=unhexlify("74727a6431000000006320348800110808106c1a0355425122045562697128000e5641d82e3622b4e6addd4354efd933cf15947d1d608a60d324d1156b5a4999f70c41beb85bd866aa3059123447dfeef2e1b6c009b66ac8d04ebbca854ad30049edbbb2fbfda3bfedc6fdb4a76f1db8a4f210bd89d3c3ec1761157b0ec2b13e2f624adeb8f329b1572ff9dfc81fbc86e61f1fcb2369f51ba85ea765c908ac254ba996f842a6277583f8d02f149c78bc0eeb8f3d41240403f85785dc3a3925ea768d76aae12342c8a24de223c1ea75e5f07f6b94b8f22189413631eed3c9a362b4501f68b645aa487b9d159a8161404a218507641453ebf045cec56710bb7d873e102777695b56903766e1af16f95576ec4f41874bdaf80cec02ee067d30e721515564d4f30fa74a6c61eb784ea65cc881ead7af2ffac02d5bf1fe1a756918fe37b74828a24b640025cd79443ada60063e3034444fc49ed6055dbba6a09fa4484c42cb85abb49103dc8c781c8f190c4632e2dec30081770448021313955dbb49e8a02fd49b34d030280452fe0a5c3bcba4958bc287c67e12519be4f4aec7ab0c8e574e53a663f635f75508f23d92c77b2147f29feb79c38d0f793fba295aae605c7e8226523edefc6ad1eefe088e5b8376028bf90116ece4fb876510b4ae1c89686dbcaacbbac8225baba429ca376fafac50f4bd1ff4ce1c61dd53318d0718bf513ea6f770cce81e07a653622e4dbd03bdaa570bfe43219eb0d4fab725c9a8da04"), info=networks.NetworkInfo( chain_id=8, slip44=108, shortcut="UBQ", name="Ubiq", rskip60=False, ), ), # Ethereum Classic 61: InfoWithDefinition( definition=unhexlify("74727a64310000000063203488001d083d103d1a034554432210457468657265756d20436c617373696328000e6b891a57fe4c38c54b475f22f0d9242dd8ddab0b4f360bd86e37e2e8b79de5ef29237436351f7bc924cd110716b5adde7c28c03d76ac83b091dbce1b5d7d0edbddb221bd894806f7ea1b195443176e06830a83c0204e33f19c51d2fccc3a9f80ac2cca38822db998ddf76778dada240d39b3c6193c6335d7c693dea90d19a41f86855375c2f48c18cdc012ccac771aa316d776c8721c2b1f6d5980808337dfdae13b5be07e3cbc3526119b88c5eb44be0b1dab1094a5ec5215b47daf91736d16501f68b645aa487b9d159a8161404a218507641453ebf045cec56710bb7d873e102777695b56903766e1af16f95576ec4f41874bdaf80cec02ee067d30e721515564d4f30fa74a6c61eb784ea65cc881ead7af2ffac02d5bf1fe1a756918fe37b74828a24b640025cd79443ada60063e3034444fc49ed6055dbba6a09fa4484c42cb85abb49103dc8c781c8f190c4632e2dec30081770448021313955dbb49e8a02fd49b34d030280452fe0a5c3bcba4958bc287c67e12519be4f4aec7ab0c8e574e53a663f635f75508f23d92c77b2147f29feb79c38d0f793fba295aae605c7e8226523edefc6ad1eefe088e5b8376028bf90116ece4fb876510b4ae1c89686dbcaacbbac8225baba429ca376fafac50f4bd1ff4ce1c61dd53318d0718bf513ea6f770cce81e07a653622e4dbd03bdaa570bfe43219eb0d4fab725c9a8da04"), info=networks.NetworkInfo( chain_id=61, slip44=61, shortcut="ETC", name="Ethereum Classic", rskip60=False, ), ), } SLIP44_TO_CHAIN_ID_MAP = { 1: [4], 60: [1], 61: [61], 108: [8], } # definitions created by `common/tools/ethereum_definitions.py` and copied here TOKENS = { # chain_id: { address: token info with encoded definition, address: token info with encoded definition,... } 1: { # AAVE "7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9": InfoWithDefinition( definition=None, # built-in definitions are not encoded info=tokens.TokenInfo( symbol="AAVE", decimals=18, address=unhexlify("7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9"), chain_id=1, ), ), # TrueAUD "00006100f7090010005f1bd7ae6122c3c2cf0090": InfoWithDefinition( definition=unhexlify("74727a6431000000016320348800290a045441554410121a1400006100f7090010005f1bd7ae6122c3c2cf009020012a07547275654155440e310dad13f7d3012903a9a457134c9f38c62c04370cb92c7a528838e30a032dffbceeaa2aa849e590c4e6dbc69b0ea5359f3527b95b56ab59a33dc584105b35ea7c06afc296cc1c1e58cc3d6b461631c4c770b9409837ab3d29bc1b666fb9cf5245c4c218b0e9521c185d102f596905ba860e6f56a0a8b394f943855c74eea6fcac87210a9988ac02803f4cc61cf78e7e2409175a75f4f3a82eb84b1f2d1ea8177d5dccd62949d80d7942105e22a452be01859fe816736e803b120fb9bcc0c1117180dbda19e1ad1aafb9b9f1555c75275820bf7c1e568bcb265bdc4dfdae0511782026e11a151f6894d11128327c8c42958c9ae900af970fec13a11ffdeba6ac10733ca55a906142e0b9130312e8e85606108612581aca9087c452f38f14185db74828a24b640025cd79443ada60063e3034444fc49ed6055dbba6a09fa4484c42cb85abb49103dc8c781c8f190c4632e2dec30081770448021313955dbb49e8a02fd49b34d030280452fe0a5c3bcba4958bc287c67e12519be4f4aec7ab0c8e574e53a663f635f75508f23d92c77b2147f29feb79c38d0f793fba295aae605c7e8226523edefc6ad1eefe088e5b8376028bf90116ece4fb876510b4ae1c89686dbcaacbbac8225baba429ca376fafac50f4bd1ff4ce1c61dd53318d0718bf513ea6f770cce81e07a653622e4dbd03bdaa570bfe43219eb0d4fab725c9a8da04"), info=tokens.TokenInfo( symbol="TAUD", decimals=18, address=unhexlify("00006100f7090010005f1bd7ae6122c3c2cf0090"), chain_id=1, ), ), }, 4: { # Karma Token "275a5b346599b56917e7b1c9de019dcf9ead861a": InfoWithDefinition( definition=unhexlify("74727a64310000000163203488002b0a024b4310121a14275a5b346599b56917e7b1c9de019dcf9ead861a20042a0b4b61726d6120546f6b656e0e2b3cb176ff5a2cf431620c1a7eee9aa297f5de36d29ae6d423166cf7391e41c5826c57f30b11421a4bf10f336f12050f6d959e02bfb17a8ce7ae15087d4f083124c0cebed2ce45b15b2608b1a8f0ee443e8c4f33111d880a6a3c09a77c627f82d68b62a1bd39975b2a2c86f196b9a3dcb62bdc3554fbf85b75331bc0d39f23a46f5ed91f208757d1136bb20b3618294fbfb0a826e9c09e392fe8109181bc6c28cad78db1987947f461bfc1042b88a91d6d61297d0cf194dfeea981b4515c2ed09dc2966671f5c715c64ceb25e53e1df3c7234e3e0ddf0dcd54d40fde0c51903685f9dc7fa69c71184f17af852e74490ea7286e89a0aa4770629664f7dd8eab8c4e009ff4c24682f85f7e01d4e10ae5c06212d5a4f43bac2b4f0e79383666ef12054ddbf757809aa6b446d65f7fd1bdd76fb1d7770398bd17af50635027e680801d244bd7b4f14c57edc3cd961722315e076120bf1d35db8520edb812bfbb5bab8ff57cc2dc1b3d1f9d95b33dba5d759aef1123f2ef346b6328973fba204fd745e644c8e492f9a76c0019b2cf21715fba682b46b9c58013e0b0927e5272c808a67e8226523edefc6ad1eefe088e5b8376028bf90116ece4fb876510b4ae1c89686dbcaacbbac8225baba429ca376fafac50f4bd1ff4ce1c61dd53318d0718bf513ea6f770cce81e07a653622e4dbd03bdaa570bfe43219eb0d4fab725c9a8da04"), info=tokens.TokenInfo( symbol="KC", decimals=18, address=unhexlify("275a5b346599b56917e7b1c9de019dcf9ead861a"), chain_id=4, ), ), }, } def equalNetworkInfo(n1: networks.NetworkInfo, n2: networks.NetworkInfo, msg: str = '') -> bool: ensure( cond=( n1.chain_id == n2.chain_id and n1.slip44 == n2.slip44 and n1.shortcut == n2.shortcut and n1.name == n2.name and n1.rskip60 == n2.rskip60 ), msg=msg, ) def equalTokenInfo(t1: tokens.TokenInfo, t2: tokens.TokenInfo, msg: str = '') -> bool: ensure( cond=( t1.symbol == t2.symbol and t1.decimals == t2.decimals and t1.address == t2.address and t1.chain_id == t2.chain_id ), msg=msg, ) def construct_network_info(chain_id: int = 0, slip44: int = 0, shortcut: str = "", name: str = "", rskip60: bool = False) -> networks.NetworkInfo: return networks.NetworkInfo( chain_id=chain_id, slip44=slip44, shortcut=shortcut, name=name, rskip60=rskip60, ) def construct_token_info( symbol: str = "", decimals: int = 0, address: bytes = b'', chain_id: int = 0, name: str = "", ) -> tokens.TokenInfo: return tokens.TokenInfo( symbol=symbol, decimals=decimals, address=address, chain_id=chain_id, name=name, ) def get_ethereum_network_info_with_definition(chain_id: int | None = None, slip44: int | None = None) -> InfoWithDefinition | None: def slip44_to_chain_ids() -> list: return SLIP44_TO_CHAIN_ID_MAP.get(slip44, []) # resolve network if chain_id is not None: if slip44 is not None and chain_id not in slip44_to_chain_ids(): raise ValueError("Chain ID and slip44 are incompatible") return NETWORKS.get(chain_id) elif slip44 is not None: cid = slip44_to_chain_ids() if cid is not None: return NETWORKS.get(cid[0]) def get_ethereum_token_info_with_definition(chain_id: int, token_address: str = None) -> InfoWithDefinition | None: if chain_id is None: return None if token_address is None: # if we do not have address, get any of the tokens token_address = list(TOKENS[chain_id].keys())[0] return TOKENS[chain_id][token_address] def get_ethereum_encoded_network_definition(chain_id: int | None = None, slip44: int | None = None) -> bytes | None: network_info = get_ethereum_network_info_with_definition(chain_id, slip44) return network_info.definition if network_info is not None else None def get_ethereum_encoded_definition(chain_id: int | None = None, slip44: int | None = None, token_address: str | None = None) -> messages.EthereumEncodedDefinitions: return messages.EthereumEncodedDefinitions( encoded_network=get_ethereum_encoded_network_definition(chain_id, slip44), encoded_token=None, # TODO ) def builtin_networks_iterator() -> Iterator[networks.NetworkInfo]: """Mockup function replaces original function from core/src/apps/ethereum/networks.py used to get built-in network definitions.""" for _, network in NETWORKS.items(): if network.definition is None: yield network.info def builtin_token_by_chain_address(chain_id: int, address: bytes) -> tokens.TokenInfo: """Mockup function replaces original function from core/src/apps/ethereum/tokens.py used to get built-in token definitions.""" address_str = hexlify(address).decode('hex') try: if TOKENS[chain_id][address_str].definition is None: return TOKENS[chain_id][address_str].info except KeyError: pass return tokens.UNKNOWN_TOKEN