From 5c37e8dae272b191eeb9e3c20da56ebf8b980f4f Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Thu, 7 Mar 2019 14:49:23 +0100 Subject: [PATCH 1/2] common: introduce mnemonic module To provide another layer between seed and mnemonic. First step to introduce SLIP-39 --- src/apps/cardano/seed.py | 4 +-- src/apps/common/mnemonic.py | 46 ++++++++++++++++++++++++++ src/apps/common/seed.py | 23 +++---------- src/apps/common/storage.py | 31 +++++++++++++---- src/apps/debug/__init__.py | 4 +-- src/apps/management/backup_device.py | 8 ++--- src/apps/management/load_device.py | 10 ++++-- src/apps/management/recovery_device.py | 20 +++++++---- src/apps/management/reset_device.py | 19 ++++++----- 9 files changed, 116 insertions(+), 49 deletions(-) create mode 100644 src/apps/common/mnemonic.py diff --git a/src/apps/cardano/seed.py b/src/apps/cardano/seed.py index 102c19b69..26b32ada7 100644 --- a/src/apps/cardano/seed.py +++ b/src/apps/cardano/seed.py @@ -2,7 +2,7 @@ from trezor import wire from trezor.crypto import bip32 from apps.cardano import SEED_NAMESPACE -from apps.common import cache, storage +from apps.common import cache, mnemonic, storage from apps.common.request_passphrase import protect_by_passphrase @@ -33,7 +33,7 @@ async def get_keychain(ctx: wire.Context) -> Keychain: if passphrase is None: passphrase = await protect_by_passphrase(ctx) cache.set_passphrase(passphrase) - root = bip32.from_mnemonic_cardano(storage.get_mnemonic(), passphrase) + root = bip32.from_mnemonic_cardano(mnemonic.restore(), passphrase) # derive the namespaced root node for i in SEED_NAMESPACE[0]: diff --git a/src/apps/common/mnemonic.py b/src/apps/common/mnemonic.py new file mode 100644 index 000000000..301fa23a8 --- /dev/null +++ b/src/apps/common/mnemonic.py @@ -0,0 +1,46 @@ +from trezor import ui +from trezor.crypto import bip39 + +from apps.common import storage + +TYPE_BIP39 = 0 + + +def get() -> (bytes, int): + mnemonic_secret = storage.get_mnemonic_secret() + mnemonic_type = storage.get_mnemonic_type() + return mnemonic_secret, mnemonic_type + + +def get_seed(passphrase: str = ""): + secret, mnemonic_type = get() + _start_progress() + if mnemonic_type == TYPE_BIP39: + return bip39.seed(secret.decode(), passphrase, _render_progress) + + +def process(mnemonics: list, mnemonic_type: int): + if mnemonic_type == TYPE_BIP39: + return mnemonics[0].encode() + else: + raise RuntimeError("Unknown mnemonic type") + + +def restore() -> str: + secret, mnemonic_type = get() + if mnemonic_type == TYPE_BIP39: + return secret.decode() + + +def _start_progress(): + ui.backlight_slide_sync(ui.BACKLIGHT_DIM) + ui.display.clear() + ui.header("Please wait") + ui.display.refresh() + ui.backlight_slide_sync(ui.BACKLIGHT_NORMAL) + + +def _render_progress(progress: int, total: int): + p = int(1000 * progress / total) + ui.display.loader(p, 18, ui.WHITE, ui.BG) + ui.display.refresh() diff --git a/src/apps/common/seed.py b/src/apps/common/seed.py index 54e0c6b76..4898c89f6 100644 --- a/src/apps/common/seed.py +++ b/src/apps/common/seed.py @@ -1,7 +1,7 @@ from trezor import ui, wire -from trezor.crypto import bip32, bip39 +from trezor.crypto import bip32 -from apps.common import cache, storage +from apps.common import cache, mnemonic, storage from apps.common.request_passphrase import protect_by_passphrase allow = list @@ -66,32 +66,17 @@ async def _compute_seed(ctx: wire.Context) -> bytes: if passphrase is None: passphrase = await protect_by_passphrase(ctx) cache.set_passphrase(passphrase) - _start_bip39_progress() - seed = bip39.seed(storage.get_mnemonic(), passphrase, _render_bip39_progress) + seed = mnemonic.get_seed(passphrase) cache.set_seed(seed) return seed -def _start_bip39_progress(): - ui.backlight_slide_sync(ui.BACKLIGHT_DIM) - ui.display.clear() - ui.header("Please wait") - ui.display.refresh() - ui.backlight_slide_sync(ui.BACKLIGHT_NORMAL) - - -def _render_bip39_progress(progress: int, total: int): - p = int(1000 * progress / total) - ui.display.loader(p, 18, ui.WHITE, ui.BG) - ui.display.refresh() - - def derive_node_without_passphrase( path: list, curve_name: str = "secp256k1" ) -> bip32.HDNode: if not storage.is_initialized(): raise Exception("Device is not initialized") - seed = bip39.seed(storage.get_mnemonic(), "") + seed = mnemonic.get_seed() node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node diff --git a/src/apps/common/storage.py b/src/apps/common/storage.py index e30f263dc..f477439f8 100644 --- a/src/apps/common/storage.py +++ b/src/apps/common/storage.py @@ -18,7 +18,7 @@ _COUNTER_TAIL_LEN = 8 _APP = const(0x01) # app namespace _DEVICE_ID = const(0x00) # bytes _VERSION = const(0x01) # int -_MNEMONIC = const(0x02) # str +_MNEMONIC_SECRET = const(0x02) # bytes _LANGUAGE = const(0x03) # str _LABEL = const(0x04) # str _USE_PASSPHRASE = const(0x05) # bool (0x01 or empty) @@ -30,6 +30,7 @@ _PASSPHRASE_SOURCE = const(0x0A) # int _UNFINISHED_BACKUP = const(0x0B) # bool (0x01 or empty) _AUTOLOCK_DELAY_MS = const(0x0C) # int _NO_BACKUP = const(0x0D) # bool (0x01 or empty) +_MNEMONIC_TYPE = const(0x0E) # int # fmt: on @@ -44,6 +45,17 @@ def _get_bool(app: int, key: int, public: bool = False) -> bool: return config.get(app, key, public) == _TRUE_BYTE +def _set_uint8(app: int, key: int, val: int): + config.set(app, key, val.to_bytes(1, "big")) + + +def _get_uint8(app: int, key: int) -> int: + val = config.get(app, key) + if not val: + return None + return int.from_bytes(val, "big") + + def _new_device_id() -> str: return hexlify(random.bytes(12)).decode().upper() @@ -67,11 +79,15 @@ def get_label() -> str: return label.decode() -def get_mnemonic() -> str: - mnemonic = config.get(_APP, _MNEMONIC) +def get_mnemonic_secret() -> bytes: + mnemonic = config.get(_APP, _MNEMONIC_SECRET) if mnemonic is None: return None - return mnemonic.decode() + return mnemonic + + +def get_mnemonic_type() -> int: + return _get_uint8(_APP, _MNEMONIC_TYPE) def has_passphrase() -> bool: @@ -82,8 +98,11 @@ def get_homescreen() -> bytes: return config.get(_APP, _HOMESCREEN, True) # public -def load_mnemonic(mnemonic: str, needs_backup: bool, no_backup: bool) -> None: - config.set(_APP, _MNEMONIC, mnemonic.encode()) +def store_mnemonic( + secret: bytes, mnemonic_type: int, needs_backup: bool, no_backup: bool +) -> None: + config.set(_APP, _MNEMONIC_SECRET, secret) + _set_uint8(_APP, _MNEMONIC_TYPE, mnemonic_type) config.set(_APP, _VERSION, _STORAGE_VERSION) _set_bool(_APP, _NO_BACKUP, no_backup) if not no_backup: diff --git a/src/apps/debug/__init__.py b/src/apps/debug/__init__.py index ea47f5367..58c031bef 100644 --- a/src/apps/debug/__init__.py +++ b/src/apps/debug/__init__.py @@ -9,7 +9,7 @@ if __debug__: from trezor.messages.DebugLinkState import DebugLinkState from trezor.ui import confirm, swipe from trezor.wire import register, protobuf_workflow - from apps.common import storage + from apps.common import storage, mnemonic reset_internal_entropy = None reset_current_words = None @@ -29,7 +29,7 @@ if __debug__: async def dispatch_DebugLinkGetState(ctx, msg): m = DebugLinkState() - m.mnemonic = storage.get_mnemonic() + m.mnemonic_secret, m.mnemonic_type = mnemonic.get() m.passphrase_protection = storage.has_passphrase() m.reset_word_pos = reset_word_index m.reset_entropy = reset_internal_entropy diff --git a/src/apps/management/backup_device.py b/src/apps/management/backup_device.py index 4acd929c6..d8c3b7344 100644 --- a/src/apps/management/backup_device.py +++ b/src/apps/management/backup_device.py @@ -1,7 +1,7 @@ from trezor import wire from trezor.messages.Success import Success -from apps.common import storage +from apps.common import mnemonic, storage from apps.management.reset_device import ( check_mnemonic, show_mnemonic, @@ -16,7 +16,7 @@ async def backup_device(ctx, msg): if not storage.needs_backup(): raise wire.ProcessError("Seed already backed up") - mnemonic = storage.get_mnemonic() + words = mnemonic.restore() # warn user about mnemonic safety await show_warning(ctx) @@ -26,8 +26,8 @@ async def backup_device(ctx, msg): while True: # show mnemonic and require confirmation of a random word - await show_mnemonic(ctx, mnemonic) - if await check_mnemonic(ctx, mnemonic): + await show_mnemonic(ctx, words) + if await check_mnemonic(ctx, words): break await show_wrong_entry(ctx) diff --git a/src/apps/management/load_device.py b/src/apps/management/load_device.py index 377a69843..a0b1b971a 100644 --- a/src/apps/management/load_device.py +++ b/src/apps/management/load_device.py @@ -4,7 +4,7 @@ from trezor.messages.Success import Success from trezor.pin import pin_to_int from trezor.ui.text import Text -from apps.common import storage +from apps.common import mnemonic, storage from apps.common.confirm import require_confirm @@ -24,7 +24,13 @@ async def load_device(ctx, msg): text.normal("Continue only if you", "know what you are doing!") await require_confirm(ctx, text) - storage.load_mnemonic(mnemonic=msg.mnemonic, needs_backup=True, no_backup=False) + secret = mnemonic.process([msg.mnemonic], mnemonic.TYPE_BIP39) + storage.store_mnemonic( + secret=secret, + mnemonic_type=mnemonic.TYPE_BIP39, + needs_backup=True, + no_backup=False, + ) storage.load_settings(use_passphrase=msg.passphrase_protection, label=msg.label) if msg.pin: config.change_pin(pin_to_int(""), pin_to_int(msg.pin)) diff --git a/src/apps/management/recovery_device.py b/src/apps/management/recovery_device.py index 271fc8de3..c62dd2301 100644 --- a/src/apps/management/recovery_device.py +++ b/src/apps/management/recovery_device.py @@ -15,7 +15,7 @@ from trezor.ui.text import Text from trezor.ui.word_select import WordSelector from trezor.utils import consteq, format_ordinal -from apps.common import storage +from apps.common import mnemonic, storage from apps.common.confirm import require_confirm from apps.management.change_pin import request_pin_ack, request_pin_confirm @@ -47,11 +47,11 @@ async def recovery_device(ctx, msg): wordcount = await request_wordcount(ctx) # ask for mnemonic words one by one - mnemonic = await request_mnemonic(ctx, wordcount) + words = await request_mnemonic(ctx, wordcount) # check mnemonic validity if msg.enforce_wordlist or msg.dry_run: - if not bip39.check(mnemonic): + if not bip39.check(words): raise wire.ProcessError("Mnemonic is not valid") # ask for pin repeatedly @@ -60,10 +60,13 @@ async def recovery_device(ctx, msg): else: newpin = "" + secret = mnemonic.process([words], mnemonic.TYPE_BIP39) + # dry run if msg.dry_run: - digest_input = sha256(mnemonic).digest() - digest_stored = sha256(storage.get_mnemonic()).digest() + digest_input = sha256(secret).digest() + stored, _ = mnemonic.get() + digest_stored = sha256(stored).digest() if consteq(digest_stored, digest_input): return Success( message="The seed is valid and matches the one in the device" @@ -78,7 +81,12 @@ async def recovery_device(ctx, msg): config.change_pin(pin_to_int(""), pin_to_int(newpin)) storage.set_u2f_counter(msg.u2f_counter) storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) - storage.load_mnemonic(mnemonic=mnemonic, needs_backup=False, no_backup=False) + storage.store_mnemonic( + secret=secret, + mnemonic_type=mnemonic.TYPE_BIP39, + needs_backup=False, + no_backup=False, + ) return Success(message="Device recovered") diff --git a/src/apps/management/reset_device.py b/src/apps/management/reset_device.py index becc2c27f..6d4862f3a 100644 --- a/src/apps/management/reset_device.py +++ b/src/apps/management/reset_device.py @@ -14,7 +14,7 @@ from trezor.ui.scroll import Scrollpage, animate_swipe, paginate from trezor.ui.text import Text from trezor.utils import chunks, format_ordinal -from apps.common import storage +from apps.common import mnemonic, storage from apps.common.confirm import require_confirm from apps.management.change_pin import request_pin_confirm @@ -59,7 +59,7 @@ async def reset_device(ctx, msg): # request external entropy and compute mnemonic ent_ack = await ctx.call(EntropyRequest(), MessageType.EntropyAck) - mnemonic = generate_mnemonic(msg.strength, internal_ent, ent_ack.entropy) + words = generate_mnemonic(msg.strength, internal_ent, ent_ack.entropy) if not msg.skip_backup and not msg.no_backup: # require confirmation of the mnemonic safety @@ -67,8 +67,8 @@ async def reset_device(ctx, msg): # show mnemonic and require confirmation of a random word while True: - await show_mnemonic(ctx, mnemonic) - if await check_mnemonic(ctx, mnemonic): + await show_mnemonic(ctx, words) + if await check_mnemonic(ctx, words): break await show_wrong_entry(ctx) @@ -77,10 +77,14 @@ async def reset_device(ctx, msg): if not config.change_pin(pin_to_int(""), pin_to_int(newpin)): raise wire.ProcessError("Could not change PIN") + secret = mnemonic.process([words], mnemonic.TYPE_BIP39) # write settings and mnemonic into storage storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) - storage.load_mnemonic( - mnemonic=mnemonic, needs_backup=msg.skip_backup, no_backup=msg.no_backup + storage.store_mnemonic( + secret=secret, + mnemonic_type=mnemonic.TYPE_BIP39, + needs_backup=msg.skip_backup, + no_backup=msg.no_backup, ) # show success message. if we skipped backup, it's possible that homescreen @@ -98,8 +102,7 @@ def generate_mnemonic(strength: int, int_entropy: bytes, ext_entropy: bytes) -> ehash.update(int_entropy) ehash.update(ext_entropy) entropy = ehash.digest() - mnemonic = bip39.from_data(entropy[: strength // 8]) - return mnemonic + return bip39.from_data(entropy[: strength // 8]) async def show_warning(ctx): From d02d173e69f11d2fd869805e32645828bc5a2a13 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Thu, 7 Mar 2019 16:07:10 +0100 Subject: [PATCH 2/2] vendor: update trezor-common --- src/apps/common/coininfo.py | 40 ++++++++++++++++++++ src/apps/ethereum/networks.py | 7 ++++ src/trezor/messages/BinanceAddress.py | 19 ++++++++++ src/trezor/messages/BinanceCancelMsg.py | 25 +++++++++++++ src/trezor/messages/BinanceGetAddress.py | 28 ++++++++++++++ src/trezor/messages/BinanceGetPublicKey.py | 28 ++++++++++++++ src/trezor/messages/BinanceOrderMsg.py | 40 ++++++++++++++++++++ src/trezor/messages/BinancePublicKey.py | 19 ++++++++++ src/trezor/messages/BinanceSignTx.py | 43 ++++++++++++++++++++++ src/trezor/messages/BinanceSignedTx.py | 25 +++++++++++++ src/trezor/messages/BinanceTransferMsg.py | 30 +++++++++++++++ src/trezor/messages/BinanceTxRequest.py | 7 ++++ src/trezor/messages/Coin.py | 21 +++++++++++ src/trezor/messages/DebugLinkState.py | 9 +++-- src/trezor/messages/InputOutput.py | 29 +++++++++++++++ src/trezor/messages/MessageType.py | 10 +++++ src/trezor/messages/OrderSide.py | 5 +++ src/trezor/messages/OrderType.py | 6 +++ src/trezor/messages/PublicKey.py | 2 +- src/trezor/messages/TimeInForce.py | 6 +++ vendor/trezor-common | 2 +- 21 files changed, 396 insertions(+), 5 deletions(-) create mode 100644 src/trezor/messages/BinanceAddress.py create mode 100644 src/trezor/messages/BinanceCancelMsg.py create mode 100644 src/trezor/messages/BinanceGetAddress.py create mode 100644 src/trezor/messages/BinanceGetPublicKey.py create mode 100644 src/trezor/messages/BinanceOrderMsg.py create mode 100644 src/trezor/messages/BinancePublicKey.py create mode 100644 src/trezor/messages/BinanceSignTx.py create mode 100644 src/trezor/messages/BinanceSignedTx.py create mode 100644 src/trezor/messages/BinanceTransferMsg.py create mode 100644 src/trezor/messages/BinanceTxRequest.py create mode 100644 src/trezor/messages/Coin.py create mode 100644 src/trezor/messages/InputOutput.py create mode 100644 src/trezor/messages/OrderSide.py create mode 100644 src/trezor/messages/OrderType.py create mode 100644 src/trezor/messages/TimeInForce.py diff --git a/src/apps/common/coininfo.py b/src/apps/common/coininfo.py index 875c68c34..fdfa8577f 100644 --- a/src/apps/common/coininfo.py +++ b/src/apps/common/coininfo.py @@ -924,6 +924,46 @@ COINS = [ decred=False, curve_name='secp256k1', ), + CoinInfo( + coin_name="Qtum", + coin_shortcut="QTUM", + address_type=58, + address_type_p2sh=50, + maxfee_kb=40000000, + signed_message_header="Qtum Signed Message:\n", + xpub_magic=0x0488b21e, + xpub_magic_segwit_p2sh=0x049d7cb2, + xpub_magic_segwit_native=0x04b24746, + bech32_prefix="qc", + cashaddr_prefix=None, + slip44=2301, + segwit=True, + fork_id=None, + force_bip143=False, + bip115=False, + decred=False, + curve_name='secp256k1', + ), + CoinInfo( + coin_name="Qtum Testnet", + coin_shortcut="tQTUM", + address_type=120, + address_type_p2sh=110, + maxfee_kb=40000000, + signed_message_header="Qtum Signed Message:\n", + xpub_magic=0x043587cf, + xpub_magic_segwit_p2sh=0x044a5262, + xpub_magic_segwit_native=0x045f1cf6, + bech32_prefix="tq", + cashaddr_prefix=None, + slip44=1, + segwit=True, + fork_id=None, + force_bip143=False, + bip115=False, + decred=False, + curve_name='secp256k1', + ), CoinInfo( coin_name="Ravencoin", coin_shortcut="RVN", diff --git a/src/apps/ethereum/networks.py b/src/apps/ethereum/networks.py index 039863643..9f9692b83 100644 --- a/src/apps/ethereum/networks.py +++ b/src/apps/ethereum/networks.py @@ -142,6 +142,13 @@ NETWORKS = [ name="Mix", rskip60=False, ), + NetworkInfo( + chain_id=237, + slip44=237, + shortcut="DXN", + name="DEXON", + rskip60=False, + ), NetworkInfo( chain_id=820, slip44=820, diff --git a/src/trezor/messages/BinanceAddress.py b/src/trezor/messages/BinanceAddress.py new file mode 100644 index 000000000..8f0ed5bec --- /dev/null +++ b/src/trezor/messages/BinanceAddress.py @@ -0,0 +1,19 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class BinanceAddress(p.MessageType): + MESSAGE_WIRE_TYPE = 701 + + def __init__( + self, + address: str = None, + ) -> None: + self.address = address + + @classmethod + def get_fields(cls): + return { + 1: ('address', p.UnicodeType, 0), + } diff --git a/src/trezor/messages/BinanceCancelMsg.py b/src/trezor/messages/BinanceCancelMsg.py new file mode 100644 index 000000000..a78252c7f --- /dev/null +++ b/src/trezor/messages/BinanceCancelMsg.py @@ -0,0 +1,25 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class BinanceCancelMsg(p.MessageType): + MESSAGE_WIRE_TYPE = 708 + + def __init__( + self, + refid: str = None, + sender: str = None, + symbol: str = None, + ) -> None: + self.refid = refid + self.sender = sender + self.symbol = symbol + + @classmethod + def get_fields(cls): + return { + 1: ('refid', p.UnicodeType, 0), + 2: ('sender', p.UnicodeType, 0), + 3: ('symbol', p.UnicodeType, 0), + } diff --git a/src/trezor/messages/BinanceGetAddress.py b/src/trezor/messages/BinanceGetAddress.py new file mode 100644 index 000000000..c5e82c576 --- /dev/null +++ b/src/trezor/messages/BinanceGetAddress.py @@ -0,0 +1,28 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + +if __debug__: + try: + from typing import List + except ImportError: + List = None # type: ignore + + +class BinanceGetAddress(p.MessageType): + MESSAGE_WIRE_TYPE = 700 + + def __init__( + self, + address_n: List[int] = None, + show_display: bool = None, + ) -> None: + self.address_n = address_n if address_n is not None else [] + self.show_display = show_display + + @classmethod + def get_fields(cls): + return { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('show_display', p.BoolType, 0), + } diff --git a/src/trezor/messages/BinanceGetPublicKey.py b/src/trezor/messages/BinanceGetPublicKey.py new file mode 100644 index 000000000..15acdee8c --- /dev/null +++ b/src/trezor/messages/BinanceGetPublicKey.py @@ -0,0 +1,28 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + +if __debug__: + try: + from typing import List + except ImportError: + List = None # type: ignore + + +class BinanceGetPublicKey(p.MessageType): + MESSAGE_WIRE_TYPE = 702 + + def __init__( + self, + address_n: List[int] = None, + show_display: bool = None, + ) -> None: + self.address_n = address_n if address_n is not None else [] + self.show_display = show_display + + @classmethod + def get_fields(cls): + return { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('show_display', p.BoolType, 0), + } diff --git a/src/trezor/messages/BinanceOrderMsg.py b/src/trezor/messages/BinanceOrderMsg.py new file mode 100644 index 000000000..b2382b1ef --- /dev/null +++ b/src/trezor/messages/BinanceOrderMsg.py @@ -0,0 +1,40 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class BinanceOrderMsg(p.MessageType): + MESSAGE_WIRE_TYPE = 707 + + def __init__( + self, + id: str = None, + ordertype: int = None, + price: int = None, + quantity: int = None, + sender: str = None, + side: int = None, + symbol: str = None, + timeinforce: int = None, + ) -> None: + self.id = id + self.ordertype = ordertype + self.price = price + self.quantity = quantity + self.sender = sender + self.side = side + self.symbol = symbol + self.timeinforce = timeinforce + + @classmethod + def get_fields(cls): + return { + 1: ('id', p.UnicodeType, 0), + 2: ('ordertype', p.UVarintType, 0), + 3: ('price', p.SVarintType, 0), + 4: ('quantity', p.SVarintType, 0), + 5: ('sender', p.UnicodeType, 0), + 6: ('side', p.UVarintType, 0), + 7: ('symbol', p.UnicodeType, 0), + 8: ('timeinforce', p.UVarintType, 0), + } diff --git a/src/trezor/messages/BinancePublicKey.py b/src/trezor/messages/BinancePublicKey.py new file mode 100644 index 000000000..fff036305 --- /dev/null +++ b/src/trezor/messages/BinancePublicKey.py @@ -0,0 +1,19 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class BinancePublicKey(p.MessageType): + MESSAGE_WIRE_TYPE = 703 + + def __init__( + self, + public_key: bytes = None, + ) -> None: + self.public_key = public_key + + @classmethod + def get_fields(cls): + return { + 1: ('public_key', p.BytesType, 0), + } diff --git a/src/trezor/messages/BinanceSignTx.py b/src/trezor/messages/BinanceSignTx.py new file mode 100644 index 000000000..689088c04 --- /dev/null +++ b/src/trezor/messages/BinanceSignTx.py @@ -0,0 +1,43 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + +if __debug__: + try: + from typing import List + except ImportError: + List = None # type: ignore + + +class BinanceSignTx(p.MessageType): + MESSAGE_WIRE_TYPE = 704 + + def __init__( + self, + address_n: List[int] = None, + msg_count: int = None, + account_number: int = None, + chain_id: str = None, + memo: str = None, + sequence: int = None, + source: int = None, + ) -> None: + self.address_n = address_n if address_n is not None else [] + self.msg_count = msg_count + self.account_number = account_number + self.chain_id = chain_id + self.memo = memo + self.sequence = sequence + self.source = source + + @classmethod + def get_fields(cls): + return { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('msg_count', p.UVarintType, 0), + 3: ('account_number', p.SVarintType, 0), + 4: ('chain_id', p.UnicodeType, 0), + 5: ('memo', p.UnicodeType, 0), + 6: ('sequence', p.SVarintType, 0), + 7: ('source', p.SVarintType, 0), + } diff --git a/src/trezor/messages/BinanceSignedTx.py b/src/trezor/messages/BinanceSignedTx.py new file mode 100644 index 000000000..d9905050d --- /dev/null +++ b/src/trezor/messages/BinanceSignedTx.py @@ -0,0 +1,25 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class BinanceSignedTx(p.MessageType): + MESSAGE_WIRE_TYPE = 709 + + def __init__( + self, + signature: bytes = None, + public_key: bytes = None, + json: str = None, + ) -> None: + self.signature = signature + self.public_key = public_key + self.json = json + + @classmethod + def get_fields(cls): + return { + 1: ('signature', p.BytesType, 0), + 2: ('public_key', p.BytesType, 0), + 3: ('json', p.UnicodeType, 0), + } diff --git a/src/trezor/messages/BinanceTransferMsg.py b/src/trezor/messages/BinanceTransferMsg.py new file mode 100644 index 000000000..7c32e26a6 --- /dev/null +++ b/src/trezor/messages/BinanceTransferMsg.py @@ -0,0 +1,30 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + +from .InputOutput import InputOutput + +if __debug__: + try: + from typing import List + except ImportError: + List = None # type: ignore + + +class BinanceTransferMsg(p.MessageType): + MESSAGE_WIRE_TYPE = 706 + + def __init__( + self, + inputs: List[InputOutput] = None, + outputs: List[InputOutput] = None, + ) -> None: + self.inputs = inputs if inputs is not None else [] + self.outputs = outputs if outputs is not None else [] + + @classmethod + def get_fields(cls): + return { + 1: ('inputs', InputOutput, p.FLAG_REPEATED), + 2: ('outputs', InputOutput, p.FLAG_REPEATED), + } diff --git a/src/trezor/messages/BinanceTxRequest.py b/src/trezor/messages/BinanceTxRequest.py new file mode 100644 index 000000000..dac5a433a --- /dev/null +++ b/src/trezor/messages/BinanceTxRequest.py @@ -0,0 +1,7 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class BinanceTxRequest(p.MessageType): + MESSAGE_WIRE_TYPE = 705 diff --git a/src/trezor/messages/Coin.py b/src/trezor/messages/Coin.py new file mode 100644 index 000000000..e07ab8aef --- /dev/null +++ b/src/trezor/messages/Coin.py @@ -0,0 +1,21 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + + +class Coin(p.MessageType): + + def __init__( + self, + amount: int = None, + denom: str = None, + ) -> None: + self.amount = amount + self.denom = denom + + @classmethod + def get_fields(cls): + return { + 1: ('amount', p.SVarintType, 0), + 2: ('denom', p.UnicodeType, 0), + } diff --git a/src/trezor/messages/DebugLinkState.py b/src/trezor/messages/DebugLinkState.py index 3616e2e3c..c9f2b3e7c 100644 --- a/src/trezor/messages/DebugLinkState.py +++ b/src/trezor/messages/DebugLinkState.py @@ -13,7 +13,7 @@ class DebugLinkState(p.MessageType): layout: bytes = None, pin: str = None, matrix: str = None, - mnemonic: str = None, + mnemonic_secret: bytes = None, node: HDNodeType = None, passphrase_protection: bool = None, reset_word: str = None, @@ -21,11 +21,12 @@ class DebugLinkState(p.MessageType): recovery_fake_word: str = None, recovery_word_pos: int = None, reset_word_pos: int = None, + mnemonic_type: int = None, ) -> None: self.layout = layout self.pin = pin self.matrix = matrix - self.mnemonic = mnemonic + self.mnemonic_secret = mnemonic_secret self.node = node self.passphrase_protection = passphrase_protection self.reset_word = reset_word @@ -33,6 +34,7 @@ class DebugLinkState(p.MessageType): self.recovery_fake_word = recovery_fake_word self.recovery_word_pos = recovery_word_pos self.reset_word_pos = reset_word_pos + self.mnemonic_type = mnemonic_type @classmethod def get_fields(cls): @@ -40,7 +42,7 @@ class DebugLinkState(p.MessageType): 1: ('layout', p.BytesType, 0), 2: ('pin', p.UnicodeType, 0), 3: ('matrix', p.UnicodeType, 0), - 4: ('mnemonic', p.UnicodeType, 0), + 4: ('mnemonic_secret', p.BytesType, 0), 5: ('node', HDNodeType, 0), 6: ('passphrase_protection', p.BoolType, 0), 7: ('reset_word', p.UnicodeType, 0), @@ -48,4 +50,5 @@ class DebugLinkState(p.MessageType): 9: ('recovery_fake_word', p.UnicodeType, 0), 10: ('recovery_word_pos', p.UVarintType, 0), 11: ('reset_word_pos', p.UVarintType, 0), + 12: ('mnemonic_type', p.UVarintType, 0), } diff --git a/src/trezor/messages/InputOutput.py b/src/trezor/messages/InputOutput.py new file mode 100644 index 000000000..33556eefc --- /dev/null +++ b/src/trezor/messages/InputOutput.py @@ -0,0 +1,29 @@ +# Automatically generated by pb2py +# fmt: off +import protobuf as p + +from .Coin import Coin + +if __debug__: + try: + from typing import List + except ImportError: + List = None # type: ignore + + +class InputOutput(p.MessageType): + + def __init__( + self, + address: str = None, + coins: List[Coin] = None, + ) -> None: + self.address = address + self.coins = coins if coins is not None else [] + + @classmethod + def get_fields(cls): + return { + 1: ('address', p.UnicodeType, 0), + 2: ('coins', Coin, p.FLAG_REPEATED), + } diff --git a/src/trezor/messages/MessageType.py b/src/trezor/messages/MessageType.py index 87b0cde0d..e7a21ff7d 100644 --- a/src/trezor/messages/MessageType.py +++ b/src/trezor/messages/MessageType.py @@ -183,3 +183,13 @@ EosSignTx = 602 EosTxActionRequest = 603 EosTxActionAck = 604 EosSignedTx = 605 +BinanceGetAddress = 700 +BinanceAddress = 701 +BinanceGetPublicKey = 702 +BinancePublicKey = 703 +BinanceSignTx = 704 +BinanceTxRequest = 705 +BinanceTransferMsg = 706 +BinanceOrderMsg = 707 +BinanceCancelMsg = 708 +BinanceSignedTx = 709 diff --git a/src/trezor/messages/OrderSide.py b/src/trezor/messages/OrderSide.py new file mode 100644 index 000000000..454fff0fe --- /dev/null +++ b/src/trezor/messages/OrderSide.py @@ -0,0 +1,5 @@ +# Automatically generated by pb2py +# fmt: off +SIDE_UNKNOWN = 0 +BUY = 1 +SELL = 2 diff --git a/src/trezor/messages/OrderType.py b/src/trezor/messages/OrderType.py new file mode 100644 index 000000000..3349a5fdb --- /dev/null +++ b/src/trezor/messages/OrderType.py @@ -0,0 +1,6 @@ +# Automatically generated by pb2py +# fmt: off +OT_UNKNOWN = 0 +MARKET = 1 +LIMIT = 2 +OT_RESERVED = 3 diff --git a/src/trezor/messages/PublicKey.py b/src/trezor/messages/PublicKey.py index d39778d58..589342231 100644 --- a/src/trezor/messages/PublicKey.py +++ b/src/trezor/messages/PublicKey.py @@ -19,6 +19,6 @@ class PublicKey(p.MessageType): @classmethod def get_fields(cls): return { - 1: ('node', HDNodeType, 0), # required + 1: ('node', HDNodeType, 0), 2: ('xpub', p.UnicodeType, 0), } diff --git a/src/trezor/messages/TimeInForce.py b/src/trezor/messages/TimeInForce.py new file mode 100644 index 000000000..fa6e5f420 --- /dev/null +++ b/src/trezor/messages/TimeInForce.py @@ -0,0 +1,6 @@ +# Automatically generated by pb2py +# fmt: off +TIF_UNKNOWN = 0 +GTE = 1 +TIF_RESERVED = 2 +IOC = 3 diff --git a/vendor/trezor-common b/vendor/trezor-common index cb238cb1f..c5e54d753 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit cb238cb1f134accc4200217d9511115a8f61c6cb +Subproject commit c5e54d7535c8772b9a75ff90c506a28526f94267