1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-26 09:28:13 +00:00

Merge pull request #496 from trezor/tsusanka/pre-slip39

Store mnemonic as bytes
This commit is contained in:
Tomas Susanka 2019-03-12 11:23:25 +01:00 committed by GitHub
commit 12dd548938
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 512 additions and 54 deletions

View File

@ -2,7 +2,7 @@ from trezor import wire
from trezor.crypto import bip32 from trezor.crypto import bip32
from apps.cardano import SEED_NAMESPACE 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 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: if passphrase is None:
passphrase = await protect_by_passphrase(ctx) passphrase = await protect_by_passphrase(ctx)
cache.set_passphrase(passphrase) 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 # derive the namespaced root node
for i in SEED_NAMESPACE[0]: for i in SEED_NAMESPACE[0]:

View File

@ -924,6 +924,46 @@ COINS = [
decred=False, decred=False,
curve_name='secp256k1', 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( CoinInfo(
coin_name="Ravencoin", coin_name="Ravencoin",
coin_shortcut="RVN", coin_shortcut="RVN",

View File

@ -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()

View File

@ -1,7 +1,7 @@
from trezor import ui, wire 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 from apps.common.request_passphrase import protect_by_passphrase
allow = list allow = list
@ -66,32 +66,17 @@ async def _compute_seed(ctx: wire.Context) -> bytes:
if passphrase is None: if passphrase is None:
passphrase = await protect_by_passphrase(ctx) passphrase = await protect_by_passphrase(ctx)
cache.set_passphrase(passphrase) cache.set_passphrase(passphrase)
_start_bip39_progress() seed = mnemonic.get_seed(passphrase)
seed = bip39.seed(storage.get_mnemonic(), passphrase, _render_bip39_progress)
cache.set_seed(seed) cache.set_seed(seed)
return 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( def derive_node_without_passphrase(
path: list, curve_name: str = "secp256k1" path: list, curve_name: str = "secp256k1"
) -> bip32.HDNode: ) -> bip32.HDNode:
if not storage.is_initialized(): if not storage.is_initialized():
raise Exception("Device is not 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 = bip32.from_seed(seed, curve_name)
node.derive_path(path) node.derive_path(path)
return node return node

View File

@ -18,7 +18,7 @@ _COUNTER_TAIL_LEN = 8
_APP = const(0x01) # app namespace _APP = const(0x01) # app namespace
_DEVICE_ID = const(0x00) # bytes _DEVICE_ID = const(0x00) # bytes
_VERSION = const(0x01) # int _VERSION = const(0x01) # int
_MNEMONIC = const(0x02) # str _MNEMONIC_SECRET = const(0x02) # bytes
_LANGUAGE = const(0x03) # str _LANGUAGE = const(0x03) # str
_LABEL = const(0x04) # str _LABEL = const(0x04) # str
_USE_PASSPHRASE = const(0x05) # bool (0x01 or empty) _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) _UNFINISHED_BACKUP = const(0x0B) # bool (0x01 or empty)
_AUTOLOCK_DELAY_MS = const(0x0C) # int _AUTOLOCK_DELAY_MS = const(0x0C) # int
_NO_BACKUP = const(0x0D) # bool (0x01 or empty) _NO_BACKUP = const(0x0D) # bool (0x01 or empty)
_MNEMONIC_TYPE = const(0x0E) # int
# fmt: on # 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 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: def _new_device_id() -> str:
return hexlify(random.bytes(12)).decode().upper() return hexlify(random.bytes(12)).decode().upper()
@ -67,11 +79,15 @@ def get_label() -> str:
return label.decode() return label.decode()
def get_mnemonic() -> str: def get_mnemonic_secret() -> bytes:
mnemonic = config.get(_APP, _MNEMONIC) mnemonic = config.get(_APP, _MNEMONIC_SECRET)
if mnemonic is None: if mnemonic is None:
return None return None
return mnemonic.decode() return mnemonic
def get_mnemonic_type() -> int:
return _get_uint8(_APP, _MNEMONIC_TYPE)
def has_passphrase() -> bool: def has_passphrase() -> bool:
@ -82,8 +98,11 @@ def get_homescreen() -> bytes:
return config.get(_APP, _HOMESCREEN, True) # public return config.get(_APP, _HOMESCREEN, True) # public
def load_mnemonic(mnemonic: str, needs_backup: bool, no_backup: bool) -> None: def store_mnemonic(
config.set(_APP, _MNEMONIC, mnemonic.encode()) 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) config.set(_APP, _VERSION, _STORAGE_VERSION)
_set_bool(_APP, _NO_BACKUP, no_backup) _set_bool(_APP, _NO_BACKUP, no_backup)
if not no_backup: if not no_backup:

View File

@ -9,7 +9,7 @@ if __debug__:
from trezor.messages.DebugLinkState import DebugLinkState from trezor.messages.DebugLinkState import DebugLinkState
from trezor.ui import confirm, swipe from trezor.ui import confirm, swipe
from trezor.wire import register, protobuf_workflow from trezor.wire import register, protobuf_workflow
from apps.common import storage from apps.common import storage, mnemonic
reset_internal_entropy = None reset_internal_entropy = None
reset_current_words = None reset_current_words = None
@ -29,7 +29,7 @@ if __debug__:
async def dispatch_DebugLinkGetState(ctx, msg): async def dispatch_DebugLinkGetState(ctx, msg):
m = DebugLinkState() m = DebugLinkState()
m.mnemonic = storage.get_mnemonic() m.mnemonic_secret, m.mnemonic_type = mnemonic.get()
m.passphrase_protection = storage.has_passphrase() m.passphrase_protection = storage.has_passphrase()
m.reset_word_pos = reset_word_index m.reset_word_pos = reset_word_index
m.reset_entropy = reset_internal_entropy m.reset_entropy = reset_internal_entropy

View File

@ -142,6 +142,13 @@ NETWORKS = [
name="Mix", name="Mix",
rskip60=False, rskip60=False,
), ),
NetworkInfo(
chain_id=237,
slip44=237,
shortcut="DXN",
name="DEXON",
rskip60=False,
),
NetworkInfo( NetworkInfo(
chain_id=820, chain_id=820,
slip44=820, slip44=820,

View File

@ -1,7 +1,7 @@
from trezor import wire from trezor import wire
from trezor.messages.Success import Success from trezor.messages.Success import Success
from apps.common import storage from apps.common import mnemonic, storage
from apps.management.reset_device import ( from apps.management.reset_device import (
check_mnemonic, check_mnemonic,
show_mnemonic, show_mnemonic,
@ -16,7 +16,7 @@ async def backup_device(ctx, msg):
if not storage.needs_backup(): if not storage.needs_backup():
raise wire.ProcessError("Seed already backed up") raise wire.ProcessError("Seed already backed up")
mnemonic = storage.get_mnemonic() words = mnemonic.restore()
# warn user about mnemonic safety # warn user about mnemonic safety
await show_warning(ctx) await show_warning(ctx)
@ -26,8 +26,8 @@ async def backup_device(ctx, msg):
while True: while True:
# show mnemonic and require confirmation of a random word # show mnemonic and require confirmation of a random word
await show_mnemonic(ctx, mnemonic) await show_mnemonic(ctx, words)
if await check_mnemonic(ctx, mnemonic): if await check_mnemonic(ctx, words):
break break
await show_wrong_entry(ctx) await show_wrong_entry(ctx)

View File

@ -4,7 +4,7 @@ from trezor.messages.Success import Success
from trezor.pin import pin_to_int from trezor.pin import pin_to_int
from trezor.ui.text import Text from trezor.ui.text import Text
from apps.common import storage from apps.common import mnemonic, storage
from apps.common.confirm import require_confirm 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!") text.normal("Continue only if you", "know what you are doing!")
await require_confirm(ctx, text) 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) storage.load_settings(use_passphrase=msg.passphrase_protection, label=msg.label)
if msg.pin: if msg.pin:
config.change_pin(pin_to_int(""), pin_to_int(msg.pin)) config.change_pin(pin_to_int(""), pin_to_int(msg.pin))

View File

@ -15,7 +15,7 @@ from trezor.ui.text import Text
from trezor.ui.word_select import WordSelector from trezor.ui.word_select import WordSelector
from trezor.utils import consteq, format_ordinal 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.common.confirm import require_confirm
from apps.management.change_pin import request_pin_ack, request_pin_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) wordcount = await request_wordcount(ctx)
# ask for mnemonic words one by one # ask for mnemonic words one by one
mnemonic = await request_mnemonic(ctx, wordcount) words = await request_mnemonic(ctx, wordcount)
# check mnemonic validity # check mnemonic validity
if msg.enforce_wordlist or msg.dry_run: 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") raise wire.ProcessError("Mnemonic is not valid")
# ask for pin repeatedly # ask for pin repeatedly
@ -60,10 +60,13 @@ async def recovery_device(ctx, msg):
else: else:
newpin = "" newpin = ""
secret = mnemonic.process([words], mnemonic.TYPE_BIP39)
# dry run # dry run
if msg.dry_run: if msg.dry_run:
digest_input = sha256(mnemonic).digest() digest_input = sha256(secret).digest()
digest_stored = sha256(storage.get_mnemonic()).digest() stored, _ = mnemonic.get()
digest_stored = sha256(stored).digest()
if consteq(digest_stored, digest_input): if consteq(digest_stored, digest_input):
return Success( return Success(
message="The seed is valid and matches the one in the device" 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)) config.change_pin(pin_to_int(""), pin_to_int(newpin))
storage.set_u2f_counter(msg.u2f_counter) storage.set_u2f_counter(msg.u2f_counter)
storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) 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") return Success(message="Device recovered")

View File

@ -14,7 +14,7 @@ from trezor.ui.scroll import Scrollpage, animate_swipe, paginate
from trezor.ui.text import Text from trezor.ui.text import Text
from trezor.utils import chunks, format_ordinal 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.common.confirm import require_confirm
from apps.management.change_pin import request_pin_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 # request external entropy and compute mnemonic
ent_ack = await ctx.call(EntropyRequest(), MessageType.EntropyAck) 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: if not msg.skip_backup and not msg.no_backup:
# require confirmation of the mnemonic safety # 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 # show mnemonic and require confirmation of a random word
while True: while True:
await show_mnemonic(ctx, mnemonic) await show_mnemonic(ctx, words)
if await check_mnemonic(ctx, mnemonic): if await check_mnemonic(ctx, words):
break break
await show_wrong_entry(ctx) 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)): if not config.change_pin(pin_to_int(""), pin_to_int(newpin)):
raise wire.ProcessError("Could not change PIN") raise wire.ProcessError("Could not change PIN")
secret = mnemonic.process([words], mnemonic.TYPE_BIP39)
# write settings and mnemonic into storage # write settings and mnemonic into storage
storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection)
storage.load_mnemonic( storage.store_mnemonic(
mnemonic=mnemonic, needs_backup=msg.skip_backup, no_backup=msg.no_backup 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 # 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(int_entropy)
ehash.update(ext_entropy) ehash.update(ext_entropy)
entropy = ehash.digest() entropy = ehash.digest()
mnemonic = bip39.from_data(entropy[: strength // 8]) return bip39.from_data(entropy[: strength // 8])
return mnemonic
async def show_warning(ctx): async def show_warning(ctx):

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -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),
}

View File

@ -0,0 +1,7 @@
# Automatically generated by pb2py
# fmt: off
import protobuf as p
class BinanceTxRequest(p.MessageType):
MESSAGE_WIRE_TYPE = 705

View File

@ -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),
}

View File

@ -13,7 +13,7 @@ class DebugLinkState(p.MessageType):
layout: bytes = None, layout: bytes = None,
pin: str = None, pin: str = None,
matrix: str = None, matrix: str = None,
mnemonic: str = None, mnemonic_secret: bytes = None,
node: HDNodeType = None, node: HDNodeType = None,
passphrase_protection: bool = None, passphrase_protection: bool = None,
reset_word: str = None, reset_word: str = None,
@ -21,11 +21,12 @@ class DebugLinkState(p.MessageType):
recovery_fake_word: str = None, recovery_fake_word: str = None,
recovery_word_pos: int = None, recovery_word_pos: int = None,
reset_word_pos: int = None, reset_word_pos: int = None,
mnemonic_type: int = None,
) -> None: ) -> None:
self.layout = layout self.layout = layout
self.pin = pin self.pin = pin
self.matrix = matrix self.matrix = matrix
self.mnemonic = mnemonic self.mnemonic_secret = mnemonic_secret
self.node = node self.node = node
self.passphrase_protection = passphrase_protection self.passphrase_protection = passphrase_protection
self.reset_word = reset_word self.reset_word = reset_word
@ -33,6 +34,7 @@ class DebugLinkState(p.MessageType):
self.recovery_fake_word = recovery_fake_word self.recovery_fake_word = recovery_fake_word
self.recovery_word_pos = recovery_word_pos self.recovery_word_pos = recovery_word_pos
self.reset_word_pos = reset_word_pos self.reset_word_pos = reset_word_pos
self.mnemonic_type = mnemonic_type
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
@ -40,7 +42,7 @@ class DebugLinkState(p.MessageType):
1: ('layout', p.BytesType, 0), 1: ('layout', p.BytesType, 0),
2: ('pin', p.UnicodeType, 0), 2: ('pin', p.UnicodeType, 0),
3: ('matrix', p.UnicodeType, 0), 3: ('matrix', p.UnicodeType, 0),
4: ('mnemonic', p.UnicodeType, 0), 4: ('mnemonic_secret', p.BytesType, 0),
5: ('node', HDNodeType, 0), 5: ('node', HDNodeType, 0),
6: ('passphrase_protection', p.BoolType, 0), 6: ('passphrase_protection', p.BoolType, 0),
7: ('reset_word', p.UnicodeType, 0), 7: ('reset_word', p.UnicodeType, 0),
@ -48,4 +50,5 @@ class DebugLinkState(p.MessageType):
9: ('recovery_fake_word', p.UnicodeType, 0), 9: ('recovery_fake_word', p.UnicodeType, 0),
10: ('recovery_word_pos', p.UVarintType, 0), 10: ('recovery_word_pos', p.UVarintType, 0),
11: ('reset_word_pos', p.UVarintType, 0), 11: ('reset_word_pos', p.UVarintType, 0),
12: ('mnemonic_type', p.UVarintType, 0),
} }

View File

@ -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),
}

View File

@ -183,3 +183,13 @@ EosSignTx = 602
EosTxActionRequest = 603 EosTxActionRequest = 603
EosTxActionAck = 604 EosTxActionAck = 604
EosSignedTx = 605 EosSignedTx = 605
BinanceGetAddress = 700
BinanceAddress = 701
BinanceGetPublicKey = 702
BinancePublicKey = 703
BinanceSignTx = 704
BinanceTxRequest = 705
BinanceTransferMsg = 706
BinanceOrderMsg = 707
BinanceCancelMsg = 708
BinanceSignedTx = 709

View File

@ -0,0 +1,5 @@
# Automatically generated by pb2py
# fmt: off
SIDE_UNKNOWN = 0
BUY = 1
SELL = 2

View File

@ -0,0 +1,6 @@
# Automatically generated by pb2py
# fmt: off
OT_UNKNOWN = 0
MARKET = 1
LIMIT = 2
OT_RESERVED = 3

View File

@ -19,6 +19,6 @@ class PublicKey(p.MessageType):
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
return { return {
1: ('node', HDNodeType, 0), # required 1: ('node', HDNodeType, 0),
2: ('xpub', p.UnicodeType, 0), 2: ('xpub', p.UnicodeType, 0),
} }

View File

@ -0,0 +1,6 @@
# Automatically generated by pb2py
# fmt: off
TIF_UNKNOWN = 0
GTE = 1
TIF_RESERVED = 2
IOC = 3

@ -1 +1 @@
Subproject commit cb238cb1f134accc4200217d9511115a8f61c6cb Subproject commit c5e54d7535c8772b9a75ff90c506a28526f94267