style(core): full pyright-based type-checking

Changes many fields to required -- as far as we were able to figure out,
signing would fail if these fields aren't provided anyway, so this
should not pose a compatibility problem.

Co-authored-by: matejcik <ja@matejcik.cz>
pull/2054/head
grdddj 2 years ago committed by matejcik
parent 9c5945a888
commit 9fc5bb546b

@ -5,6 +5,14 @@ package hw.trezor.messages.binance;
option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageBinance"; option java_outer_classname = "TrezorMessageBinance";
/** XXX
Most likely, ALL fields in this file should be `required`. We are leaving some optionals
in place, in cases where the field value continues to the JSON as a string -- on the off
chance that somebody is relying on the behavior.
*/
/** /**
* Request: Ask the device for a Binance address. * Request: Ask the device for a Binance address.
* @start * @start
@ -52,12 +60,12 @@ message BinancePublicKey {
*/ */
message BinanceSignTx { message BinanceSignTx {
repeated uint32 address_n = 1; // BIP-32-style path to derive the key from master node repeated uint32 address_n = 1; // BIP-32-style path to derive the key from master node
optional uint32 msg_count = 2; // count of Binance<Any>Msg to be included in this tx required uint32 msg_count = 2; // count of Binance<Any>Msg to be included in this tx
optional sint64 account_number = 3; required sint64 account_number = 3;
optional string chain_id = 4; optional string chain_id = 4;
optional string memo = 5; optional string memo = 5;
optional sint64 sequence = 6; required sint64 sequence = 6;
optional sint64 source = 7; required sint64 source = 7;
} }
/** /**
@ -79,13 +87,13 @@ message BinanceTransferMsg {
repeated BinanceInputOutput outputs = 2; repeated BinanceInputOutput outputs = 2;
message BinanceInputOutput { message BinanceInputOutput {
optional string address = 1; required string address = 1;
repeated BinanceCoin coins = 2; repeated BinanceCoin coins = 2;
} }
message BinanceCoin { message BinanceCoin {
optional sint64 amount = 1; required sint64 amount = 1;
optional string denom = 2; required string denom = 2;
} }
} }
@ -96,13 +104,13 @@ message BinanceTransferMsg {
*/ */
message BinanceOrderMsg { message BinanceOrderMsg {
optional string id = 1; optional string id = 1;
optional BinanceOrderType ordertype = 2; required BinanceOrderType ordertype = 2;
optional sint64 price = 3; required sint64 price = 3;
optional sint64 quantity = 4; required sint64 quantity = 4;
optional string sender = 5; optional string sender = 5;
optional BinanceOrderSide side = 6; required BinanceOrderSide side = 6;
optional string symbol = 7; optional string symbol = 7;
optional BinanceTimeInForce timeinforce = 8; required BinanceTimeInForce timeinforce = 8;
enum BinanceOrderType { enum BinanceOrderType {
OT_UNKNOWN = 0; OT_UNKNOWN = 0;

@ -33,9 +33,9 @@ message EosPublicKey {
*/ */
message EosSignTx { message EosSignTx {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node 44'/194'/0' repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node 44'/194'/0'
optional bytes chain_id = 2; // 256-bit long chain id required bytes chain_id = 2; // 256-bit long chain id
optional EosTxHeader header = 3; // EOS transaction header required EosTxHeader header = 3; // EOS transaction header
optional uint32 num_actions = 4; // number of actions required uint32 num_actions = 4; // number of actions
/** /**
* Structure representing EOS transaction header * Structure representing EOS transaction header
@ -65,7 +65,7 @@ message EosTxActionRequest {
* @next Failure * @next Failure
*/ */
message EosTxActionAck { message EosTxActionAck {
optional EosActionCommon common = 1; required EosActionCommon common = 1;
optional EosActionTransfer transfer = 2; optional EosActionTransfer transfer = 2;
optional EosActionDelegate delegate = 3; optional EosActionDelegate delegate = 3;
optional EosActionUndelegate undelegate = 4; optional EosActionUndelegate undelegate = 4;
@ -85,16 +85,16 @@ message EosTxActionAck {
* Structure representing asset type * Structure representing asset type
*/ */
message EosAsset { message EosAsset {
optional sint64 amount = 1; required sint64 amount = 1;
optional uint64 symbol = 2; // Lowest 8 bits used for precision. required uint64 symbol = 2; // Lowest 8 bits used for precision.
} }
/** /**
* Structure representing action permission level * Structure representing action permission level
*/ */
message EosPermissionLevel { message EosPermissionLevel {
optional uint64 actor = 1; required uint64 actor = 1;
optional uint64 permission = 2; required uint64 permission = 2;
} }
/** /**
@ -111,23 +111,23 @@ message EosTxActionAck {
* Structure representing auth account * Structure representing auth account
*/ */
message EosAuthorizationAccount { message EosAuthorizationAccount {
optional EosPermissionLevel account = 1; required EosPermissionLevel account = 1;
optional uint32 weight = 2; required uint32 weight = 2;
} }
/** /**
* Structure representing auth delays * Structure representing auth delays
*/ */
message EosAuthorizationWait { message EosAuthorizationWait {
optional uint32 wait_sec = 1; required uint32 wait_sec = 1;
optional uint32 weight = 2; required uint32 weight = 2;
} }
/** /**
* Structure representing authorization settings * Structure representing authorization settings
*/ */
message EosAuthorization { message EosAuthorization {
optional uint32 threshold = 1; required uint32 threshold = 1;
repeated EosAuthorizationKey keys = 2; repeated EosAuthorizationKey keys = 2;
repeated EosAuthorizationAccount accounts = 3; repeated EosAuthorizationAccount accounts = 3;
repeated EosAuthorizationWait waits = 4; repeated EosAuthorizationWait waits = 4;
@ -137,8 +137,8 @@ message EosTxActionAck {
* Structure representing the common part of every action * Structure representing the common part of every action
*/ */
message EosActionCommon { message EosActionCommon {
optional uint64 account = 1; // Contract name required uint64 account = 1; // Contract name
optional uint64 name = 2; // Action name required uint64 name = 2; // Action name
repeated EosPermissionLevel authorization = 3; repeated EosPermissionLevel authorization = 3;
} }
@ -146,72 +146,72 @@ message EosTxActionAck {
* Structure representing transfer data structure * Structure representing transfer data structure
*/ */
message EosActionTransfer { message EosActionTransfer {
optional uint64 sender = 1; // Asset sender required uint64 sender = 1; // Asset sender
optional uint64 receiver = 2; required uint64 receiver = 2;
optional EosAsset quantity = 3; required EosAsset quantity = 3;
optional string memo = 4; required string memo = 4;
} }
/** /**
* Structure representing delegation data structure * Structure representing delegation data structure
*/ */
message EosActionDelegate { message EosActionDelegate {
optional uint64 sender = 1; required uint64 sender = 1;
optional uint64 receiver = 2; required uint64 receiver = 2;
optional EosAsset net_quantity = 3; // Asset format '1.0000 EOS' required EosAsset net_quantity = 3; // Asset format '1.0000 EOS'
optional EosAsset cpu_quantity = 4; // Asset format '1.0000 EOS' required EosAsset cpu_quantity = 4; // Asset format '1.0000 EOS'
optional bool transfer = 5; // Transfer delegated tokens or not. required bool transfer = 5; // Transfer delegated tokens or not.
} }
/** /**
* Structure representing the removal of delegated resources from `sender` * Structure representing the removal of delegated resources from `sender`
*/ */
message EosActionUndelegate { message EosActionUndelegate {
optional uint64 sender = 1; required uint64 sender = 1;
optional uint64 receiver = 2; required uint64 receiver = 2;
optional EosAsset net_quantity = 3; // Asset format '1.0000 EOS' required EosAsset net_quantity = 3; // Asset format '1.0000 EOS'
optional EosAsset cpu_quantity = 4; // Asset format '1.0000 EOS' required EosAsset cpu_quantity = 4; // Asset format '1.0000 EOS'
} }
/** /**
* Structure representing fallback if undelegate wasnt executed automaticaly. * Structure representing fallback if undelegate wasnt executed automaticaly.
*/ */
message EosActionRefund { message EosActionRefund {
optional uint64 owner = 1; required uint64 owner = 1;
} }
/** /**
* Structure representing buying RAM operation for EOS tokens * Structure representing buying RAM operation for EOS tokens
*/ */
message EosActionBuyRam { message EosActionBuyRam {
optional uint64 payer = 1; required uint64 payer = 1;
optional uint64 receiver = 2; required uint64 receiver = 2;
optional EosAsset quantity = 3; // Asset format '1.0000 EOS' required EosAsset quantity = 3; // Asset format '1.0000 EOS'
} }
/** /**
* Structure representing buying bytes according to RAM market price. * Structure representing buying bytes according to RAM market price.
*/ */
message EosActionBuyRamBytes { message EosActionBuyRamBytes {
optional uint64 payer = 1; required uint64 payer = 1;
optional uint64 receiver = 2; required uint64 receiver = 2;
optional uint32 bytes = 3; // Number of bytes required uint32 bytes = 3; // Number of bytes
} }
/** /**
* Structure representing sell RAM * Structure representing sell RAM
*/ */
message EosActionSellRam { message EosActionSellRam {
optional uint64 account = 1; required uint64 account = 1;
optional uint64 bytes = 2; // Number of bytes required uint64 bytes = 2; // Number of bytes
} }
/** /**
* Structure representing voting. Currently, there could be up to 30 producers. * Structure representing voting. Currently, there could be up to 30 producers.
*/ */
message EosActionVoteProducer { message EosActionVoteProducer {
optional uint64 voter = 1; // Voter account required uint64 voter = 1; // Voter account
optional uint64 proxy = 2; // Proxy voter account required uint64 proxy = 2; // Proxy voter account
repeated uint64 producers = 3; // List of producers repeated uint64 producers = 3; // List of producers
} }
@ -219,47 +219,47 @@ message EosTxActionAck {
* Structure representing update authorization. * Structure representing update authorization.
*/ */
message EosActionUpdateAuth { message EosActionUpdateAuth {
optional uint64 account = 1; required uint64 account = 1;
optional uint64 permission = 2; required uint64 permission = 2;
optional uint64 parent = 3; required uint64 parent = 3;
optional EosAuthorization auth = 4; required EosAuthorization auth = 4;
} }
/** /**
* Structure representing delete authorization. * Structure representing delete authorization.
*/ */
message EosActionDeleteAuth { message EosActionDeleteAuth {
optional uint64 account = 1; required uint64 account = 1;
optional uint64 permission = 2; required uint64 permission = 2;
} }
/** /**
* Structure representing link authorization to action. * Structure representing link authorization to action.
*/ */
message EosActionLinkAuth { message EosActionLinkAuth {
optional uint64 account = 1; required uint64 account = 1;
optional uint64 code = 2; required uint64 code = 2;
optional uint64 type = 3; required uint64 type = 3;
optional uint64 requirement = 4; required uint64 requirement = 4;
} }
/** /**
* Structure representing unlink authorization from action. * Structure representing unlink authorization from action.
*/ */
message EosActionUnlinkAuth { message EosActionUnlinkAuth {
optional uint64 account = 1; required uint64 account = 1;
optional uint64 code = 2; required uint64 code = 2;
optional uint64 type = 3; required uint64 type = 3;
} }
/** /**
* Structure representing creation of a new account. * Structure representing creation of a new account.
*/ */
message EosActionNewAccount { message EosActionNewAccount {
optional uint64 creator = 1; required uint64 creator = 1;
optional uint64 name = 2; required uint64 name = 2;
optional EosAuthorization owner = 3; required EosAuthorization owner = 3;
optional EosAuthorization active = 4; required EosAuthorization active = 4;
} }
/** /**
@ -267,7 +267,7 @@ message EosTxActionAck {
*/ */
message EosActionUnknown { message EosActionUnknown {
required uint32 data_size = 1; required uint32 data_size = 1;
optional bytes data_chunk = 2; required bytes data_chunk = 2;
} }
} }

@ -12,9 +12,9 @@ option java_outer_classname = "TrezorMessageNem";
* @next Failure * @next Failure
*/ */
message NEMGetAddress { message NEMGetAddress {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) optional uint32 network = 2 [default=0x68]; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin)
optional bool show_display = 3; // Optionally show on display before sending the result optional bool show_display = 3; // Optionally show on display before sending the result
} }
/** /**
@ -32,7 +32,7 @@ message NEMAddress {
* @next Failure * @next Failure
*/ */
message NEMSignTx { message NEMSignTx {
optional NEMTransactionCommon transaction = 1; // Common part of transaction required NEMTransactionCommon transaction = 1; // Common part of transaction
optional NEMTransactionCommon multisig = 2; // Common part of inner transaction for multisig transactions optional NEMTransactionCommon multisig = 2; // Common part of inner transaction for multisig transactions
optional NEMTransfer transfer = 3; // Transfer transaction part optional NEMTransfer transfer = 3; // Transfer transaction part
optional bool cosigning = 4; // Whether cosigning or initiating the multisig transaction optional bool cosigning = 4; // Whether cosigning or initiating the multisig transaction
@ -45,55 +45,55 @@ message NEMSignTx {
* Structure representing the common part for NEM transactions * Structure representing the common part for NEM transactions
*/ */
message NEMTransactionCommon { message NEMTransactionCommon {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) optional uint32 network = 2 [default=0x68]; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin)
optional uint32 timestamp = 3; // Number of seconds elapsed since the creation of the nemesis block required uint32 timestamp = 3; // Number of seconds elapsed since the creation of the nemesis block
optional uint64 fee = 4; // Fee for the transaction required uint64 fee = 4; // Fee for the transaction
optional uint32 deadline = 5; // Deadline of the transaction required uint32 deadline = 5; // Deadline of the transaction
optional bytes signer = 6; // Public key of the account (for multisig transactions) optional bytes signer = 6; // Public key of the account (for multisig transactions)
} }
/** /**
* Structure representing the transfer transaction part for NEM transactions * Structure representing the transfer transaction part for NEM transactions
*/ */
message NEMTransfer { message NEMTransfer {
optional string recipient = 1; // Address of the recipient required string recipient = 1; // Address of the recipient
optional uint64 amount = 2; // Amount of micro NEM that is transferred required uint64 amount = 2; // Amount of micro NEM that is transferred
optional bytes payload = 3; // Actual message data (unencrypted) optional bytes payload = 3 [default=""]; // Actual message data (unencrypted)
optional bytes public_key = 4; // Public key of the recipient (for encrypted payloads) optional bytes public_key = 4; // Public key of the recipient (for encrypted payloads)
repeated NEMMosaic mosaics = 5; // Attached mosaics repeated NEMMosaic mosaics = 5; // Attached mosaics
/** /**
* Structure representing the mosaic attachment for NEM transfer transactions * Structure representing the mosaic attachment for NEM transfer transactions
*/ */
message NEMMosaic { message NEMMosaic {
optional string namespace = 1; // Fully qualified name of the namespace required string namespace = 1; // Fully qualified name of the namespace
optional string mosaic = 2; // Name of the mosaic definition required string mosaic = 2; // Name of the mosaic definition
optional uint64 quantity = 3; // Mosaic quantity, always given in smallest units required uint64 quantity = 3; // Mosaic quantity, always given in smallest units
} }
} }
/** /**
* Structure representing the provision namespace part for NEM transactions * Structure representing the provision namespace part for NEM transactions
*/ */
message NEMProvisionNamespace { message NEMProvisionNamespace {
optional string namespace = 1; // New part concatenated to the parent required string namespace = 1; // New part concatenated to the parent
optional string parent = 2; // Parent namespace (for child namespaces) optional string parent = 2; // Parent namespace (for child namespaces)
optional string sink = 3; // Rental fee sink address required string sink = 3; // Rental fee sink address
optional uint64 fee = 4; // Rental fee required uint64 fee = 4; // Rental fee
} }
/** /**
* Structure representing the mosaic definition creation part for NEM transactions * Structure representing the mosaic definition creation part for NEM transactions
*/ */
message NEMMosaicCreation { message NEMMosaicCreation {
optional NEMMosaicDefinition definition = 1; // Mosaic definition required NEMMosaicDefinition definition = 1; // Mosaic definition
optional string sink = 2; // Creation fee sink address required string sink = 2; // Creation fee sink address
optional uint64 fee = 3; // Creation fee required uint64 fee = 3; // Creation fee
/** /**
* Structure representing a mosaic definition * Structure representing a mosaic definition
*/ */
message NEMMosaicDefinition { message NEMMosaicDefinition {
optional string name = 1; // User-friendly name of the mosaic (for whitelisted mosaics) optional string name = 1; // User-friendly name of the mosaic (for whitelisted mosaics)
optional string ticker = 2; // Ticker of the mosaic (for whitelisted mosaics) optional string ticker = 2; // Ticker of the mosaic (for whitelisted mosaics)
optional string namespace = 3; // Fully qualified name of the namespace required string namespace = 3; // Fully qualified name of the namespace
optional string mosaic = 4; // Name of the mosaic definition required string mosaic = 4; // Name of the mosaic definition
optional uint32 divisibility = 5; // Number of decimal places that a mosaic can be divided into optional uint32 divisibility = 5; // Number of decimal places that a mosaic can be divided into
optional NEMMosaicLevy levy = 6; // Levy type optional NEMMosaicLevy levy = 6; // Levy type
optional uint64 fee = 7; // Levy fee (interpretation depends on levy type) optional uint64 fee = 7; // Levy fee (interpretation depends on levy type)
@ -103,7 +103,7 @@ message NEMSignTx {
optional uint64 supply = 11; // Initial supply to create, always given in entire units optional uint64 supply = 11; // Initial supply to create, always given in entire units
optional bool mutable_supply = 12; // Mutable supply optional bool mutable_supply = 12; // Mutable supply
optional bool transferable = 13; // Mosaic allows transfers among accounts other than the creator optional bool transferable = 13; // Mosaic allows transfers among accounts other than the creator
optional string description = 14; // Mosaic description required string description = 14; // Mosaic description
repeated uint32 networks = 15; // Networks that the mosaic is valid on (for whitelisted mosaics) repeated uint32 networks = 15; // Networks that the mosaic is valid on (for whitelisted mosaics)
/** /**
* Type of levy which will be used for mosaic * Type of levy which will be used for mosaic
@ -118,10 +118,10 @@ message NEMSignTx {
* Structure representing the mosaic supply change part for NEM transactions * Structure representing the mosaic supply change part for NEM transactions
*/ */
message NEMMosaicSupplyChange { message NEMMosaicSupplyChange {
optional string namespace = 1; // Fully qualified name of the namespace required string namespace = 1; // Fully qualified name of the namespace
optional string mosaic = 2; // Name of the mosaic definition required string mosaic = 2; // Name of the mosaic definition
optional NEMSupplyChangeType type = 3; // Type of supply change required NEMSupplyChangeType type = 3; // Type of supply change
optional uint64 delta = 4; // Supply delta required uint64 delta = 4; // Supply delta
/** /**
* Type of supply change which will be applied to mosaic * Type of supply change which will be applied to mosaic
*/ */
@ -140,8 +140,8 @@ message NEMSignTx {
* Structure representing the cosignatory modification for aggregate modification transactions * Structure representing the cosignatory modification for aggregate modification transactions
*/ */
message NEMCosignatoryModification { message NEMCosignatoryModification {
optional NEMModificationType type = 1; // Type of cosignatory modification required NEMModificationType type = 1; // Type of cosignatory modification
optional bytes public_key = 2; // Public key of the cosignatory required bytes public_key = 2; // Public key of the cosignatory
/** /**
* Type of cosignatory modification * Type of cosignatory modification
*/ */
@ -155,8 +155,8 @@ message NEMSignTx {
* Structure representing the importance transfer part for NEM transactions * Structure representing the importance transfer part for NEM transactions
*/ */
message NEMImportanceTransfer { message NEMImportanceTransfer {
optional NEMImportanceTransferMode mode = 1; // Mode of importance transfer required NEMImportanceTransferMode mode = 1; // Mode of importance transfer
optional bytes public_key = 2; // Public key of the remote account required bytes public_key = 2; // Public key of the remote account
/** /**
* Mode of importance transfer * Mode of importance transfer
*/ */

@ -30,11 +30,11 @@ message RippleAddress {
*/ */
message RippleSignTx { message RippleSignTx {
repeated uint32 address_n = 1; // BIP-32 path. For compatibility with other wallets, must be m/44'/144'/index' repeated uint32 address_n = 1; // BIP-32 path. For compatibility with other wallets, must be m/44'/144'/index'
optional uint64 fee = 2; // fee (in drops) for the transaction required uint64 fee = 2; // fee (in drops) for the transaction
optional uint32 flags = 3; // transaction flags optional uint32 flags = 3 [default=0]; // transaction flags
optional uint32 sequence = 4; // transaction sequence number required uint32 sequence = 4; // transaction sequence number
optional uint32 last_ledger_sequence = 5; // see https://developers.ripple.com/reliable-transaction-submission.html#lastledgersequence optional uint32 last_ledger_sequence = 5; // see https://developers.ripple.com/reliable-transaction-submission.html#lastledgersequence
optional RipplePayment payment = 6; // Payment transaction type required RipplePayment payment = 6; // Payment transaction type
/** /**
* Payment transaction type * Payment transaction type

@ -102,8 +102,8 @@ message TezosSignTx {
optional TezosManagerTransfer transfer = 3; optional TezosManagerTransfer transfer = 3;
message TezosManagerTransfer { message TezosManagerTransfer {
optional TezosContractID destination = 1; required TezosContractID destination = 1;
optional uint64 amount = 2; required uint64 amount = 2;
} }
} }
} }
@ -138,18 +138,18 @@ message TezosSignTx {
* Structure representing information for proposal * Structure representing information for proposal
*/ */
message TezosProposalOp { message TezosProposalOp {
optional bytes source = 1; //Contains only public_key_hash, not to be confused with TezosContractID required bytes source = 1; //Contains only public_key_hash, not to be confused with TezosContractID
optional uint64 period = 2; required uint64 period = 2;
repeated bytes proposals = 4; repeated bytes proposals = 4;
} }
/** /**
* Structure representing information for ballot * Structure representing information for ballot
*/ */
message TezosBallotOp { message TezosBallotOp {
optional bytes source = 1; //Contains only public_key_hash, not to be confused with TezosContractID required bytes source = 1; //Contains only public_key_hash, not to be confused with TezosContractID
optional uint64 period = 2; required uint64 period = 2;
optional bytes proposal = 3; required bytes proposal = 3;
optional TezosBallotType ballot = 4; required TezosBallotType ballot = 4;
enum TezosBallotType { enum TezosBallotType {
Yay = 0; Yay = 0;

1
core/.gitignore vendored

@ -7,3 +7,4 @@ tests/trezor_monero_tests*
.coverage .coverage
.coverage.* .coverage.*
htmlcov/ htmlcov/
mypy_report

@ -110,14 +110,19 @@ pylint: ## run pylint on application sources and tests
mypy: mypy:
mypy --config-file ../setup.cfg \ mypy --config-file ../setup.cfg \
src/main.py \ src/main.py \
src/apps/bitcoin \ src/apps \
src/apps/cardano \ src/trezor \
src/apps/ethereum \ src/storage \
src/apps/management \ --exclude src/apps/monero
src/apps/misc \
src/apps/stellar \ mypy_report:
src/apps/webauthn \ mypy --config-file ../setup.cfg \
src/trezor/ui src/main.py \
src/apps \
src/trezor \
src/storage \
--exclude src/apps/monero \
--html-report mypy_report
clippy: clippy:
cd embed/rust ; cargo clippy cd embed/rust ; cargo clippy

@ -26,12 +26,12 @@
/// from trezor.protobuf import MessageType /// from trezor.protobuf import MessageType
/// T = TypeVar("T", bound=MessageType) /// T = TypeVar("T", bound=MessageType)
/// def type_for_name(name: str) -> Type[MessageType]: /// def type_for_name(name: str) -> type[T]:
/// """Find the message definition for the given protobuf name.""" /// """Find the message definition for the given protobuf name."""
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorutils_protobuf_type_for_name_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorutils_protobuf_type_for_name_obj,
protobuf_type_for_name); protobuf_type_for_name);
/// def type_for_wire(wire_type: int) -> Type[MessageType]: /// def type_for_wire(wire_type: int) -> type[T]:
/// """Find the message definition for the given wire type (numeric /// """Find the message definition for the given wire type (numeric
/// identifier).""" /// identifier)."""
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorutils_protobuf_type_for_wire_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorutils_protobuf_type_for_wire_obj,

@ -4,12 +4,12 @@ T = TypeVar("T", bound=MessageType)
# extmod/rustmods/modtrezorproto.c # extmod/rustmods/modtrezorproto.c
def type_for_name(name: str) -> Type[MessageType]: def type_for_name(name: str) -> type[T]:
"""Find the message definition for the given protobuf name.""" """Find the message definition for the given protobuf name."""
# extmod/rustmods/modtrezorproto.c # extmod/rustmods/modtrezorproto.c
def type_for_wire(wire_type: int) -> Type[MessageType]: def type_for_wire(wire_type: int) -> type[T]:
"""Find the message definition for the given wire type (numeric """Find the message definition for the given wire type (numeric
identifier).""" identifier)."""

@ -24,7 +24,9 @@ FLOAT32: int
class struct: class struct:
def __init__(self, addr: int, descriptor: dict, layout_type: int = ...) -> None: ... def __init__(self, addr: int, descriptor: dict, layout_type: int = ...) -> None: ...
def sizeof(struct: struct) -> int: ... StructDict = dict[str, int | tuple[int, int]]
def sizeof(struct: struct | bytearray | StructDict, endianity: int = LITTLE_ENDIAN, /) -> int: ...
def addressof(obj: bytes) -> int: ... def addressof(obj: bytes) -> int: ...
def bytes_at(addr: int, size: int) -> bytes: ... def bytes_at(addr: int, size: int) -> bytes: ...
def bytearray_at(addr: int, size: int) -> bytearray: ... def bytearray_at(addr: int, size: int) -> bytearray: ...

@ -0,0 +1,14 @@
{
"include": [
"src"
],
"exclude": [
"src/apps/monero",
"src/typing.py",
"src/all_modules.py"
],
"stubPath": "mocks/generated",
"typeCheckingMode": "basic",
"pythonVersion": "3.10",
"reportMissingModuleSource": false
}

@ -38,6 +38,8 @@ main
import main import main
session session
import session import session
typing
import typing
usb usb
import usb import usb
storage storage

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage.cache import storage.cache
import storage.device import storage.device
from trezor import config, utils, wire, workflow from trezor import config, utils, wire, workflow
@ -6,9 +8,8 @@ from trezor.messages import Success
from . import workflow_handlers from . import workflow_handlers
if False: if TYPE_CHECKING:
from trezor import protobuf from trezor import protobuf
from typing import NoReturn
from trezor.messages import ( from trezor.messages import (
Features, Features,
Initialize, Initialize,
@ -25,6 +26,7 @@ if False:
def get_features() -> Features: def get_features() -> Features:
import storage.recovery import storage.recovery
import storage.sd_salt import storage.sd_salt
import storage # workaround for https://github.com/microsoft/pyright/issues/2685
from trezor import sdcard from trezor import sdcard
from trezor.enums import Capability from trezor.enums import Capability
@ -130,7 +132,7 @@ async def handle_GetFeatures(ctx: wire.Context, msg: GetFeatures) -> Features:
return get_features() return get_features()
async def handle_Cancel(ctx: wire.Context, msg: Cancel) -> NoReturn: async def handle_Cancel(ctx: wire.Context, msg: Cancel) -> Success:
raise wire.ActionCancelled raise wire.ActionCancelled
@ -262,8 +264,6 @@ def get_pinlocked_handler(
return orig_handler return orig_handler
async def wrapper(ctx: wire.Context, msg: wire.Msg) -> protobuf.MessageType: async def wrapper(ctx: wire.Context, msg: wire.Msg) -> protobuf.MessageType:
# mypy limitation: orig_handler is not recognized as non-None
assert orig_handler is not None
await unlock_device(ctx) await unlock_device(ctx)
return await orig_handler(ctx, msg) return await orig_handler(ctx, msg)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.messages import BinanceAddress, BinanceGetAddress from trezor.messages import BinanceAddress, BinanceGetAddress
from trezor.ui.layouts import show_address from trezor.ui.layouts import show_address
@ -6,9 +8,14 @@ from apps.common.keychain import Keychain, auto_keychain
from .helpers import address_from_public_key from .helpers import address_from_public_key
if TYPE_CHECKING:
from trezor.wire import Context
@auto_keychain(__name__) @auto_keychain(__name__)
async def get_address(ctx, msg: BinanceGetAddress, keychain: Keychain): async def get_address(
ctx: Context, msg: BinanceGetAddress, keychain: Keychain
) -> BinanceAddress:
HRP = "bnb" HRP = "bnb"
await paths.validate_path(ctx, keychain, msg.address_n) await paths.validate_path(ctx, keychain, msg.address_n)

@ -1,3 +1,4 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor.messages import BinanceGetPublicKey, BinancePublicKey from trezor.messages import BinanceGetPublicKey, BinancePublicKey
@ -6,9 +7,14 @@ from trezor.ui.layouts import show_pubkey
from apps.common import paths from apps.common import paths
from apps.common.keychain import Keychain, auto_keychain from apps.common.keychain import Keychain, auto_keychain
if TYPE_CHECKING:
from trezor.wire import Context
@auto_keychain(__name__) @auto_keychain(__name__)
async def get_public_key(ctx, msg: BinanceGetPublicKey, keychain: Keychain): async def get_public_key(
ctx: Context, msg: BinanceGetPublicKey, keychain: Keychain
) -> BinancePublicKey:
await paths.validate_path(ctx, keychain, msg.address_n) await paths.validate_path(ctx, keychain, msg.address_n)
node = keychain.derive(msg.address_n) node = keychain.derive(msg.address_n)
pubkey = node.public_key() pubkey = node.public_key()

@ -1,5 +1,7 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire
from trezor.crypto import bech32 from trezor.crypto import bech32
from trezor.crypto.scripts import sha256_ripemd160 from trezor.crypto.scripts import sha256_ripemd160
from trezor.messages import ( from trezor.messages import (
@ -10,6 +12,9 @@ from trezor.messages import (
BinanceTransferMsg, BinanceTransferMsg,
) )
if TYPE_CHECKING:
from trezor.protobuf import MessageType
ENVELOPE_BLUEPRINT = '{{"account_number":"{account_number}","chain_id":"{chain_id}","data":null,"memo":"{memo}","msgs":[{msgs}],"sequence":"{sequence}","source":"{source}"}}' ENVELOPE_BLUEPRINT = '{{"account_number":"{account_number}","chain_id":"{chain_id}","data":null,"memo":"{memo}","msgs":[{msgs}],"sequence":"{sequence}","source":"{source}"}}'
MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{inputs}],"outputs":[{outputs}]}}' MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{inputs}],"outputs":[{outputs}]}}'
MSG_NEWORDER_BLUEPRINT = '{{"id":"{id}","ordertype":{ordertype},"price":{price},"quantity":{quantity},"sender":"{sender}","side":{side},"symbol":"{symbol}","timeinforce":{timeinforce}}}' MSG_NEWORDER_BLUEPRINT = '{{"id":"{id}","ordertype":{ordertype},"price":{price},"quantity":{quantity},"sender":"{sender}","side":{side},"symbol":"{symbol}","timeinforce":{timeinforce}}}'
@ -21,7 +26,7 @@ COIN_BLUEPRINT = '{{"amount":{amount},"denom":"{denom}"}}'
DECIMALS = const(8) DECIMALS = const(8)
def produce_json_for_signing(envelope: BinanceSignTx, msg) -> str: def produce_json_for_signing(envelope: BinanceSignTx, msg: MessageType) -> str:
if BinanceTransferMsg.is_type_of(msg): if BinanceTransferMsg.is_type_of(msg):
json_msg = produce_transfer_json(msg) json_msg = produce_transfer_json(msg)
elif BinanceOrderMsg.is_type_of(msg): elif BinanceOrderMsg.is_type_of(msg):
@ -29,12 +34,10 @@ def produce_json_for_signing(envelope: BinanceSignTx, msg) -> str:
elif BinanceCancelMsg.is_type_of(msg): elif BinanceCancelMsg.is_type_of(msg):
json_msg = produce_cancel_json(msg) json_msg = produce_cancel_json(msg)
else: else:
raise ValueError("input message unrecognized, is of type " + type(msg).__name__) raise wire.ProcessError("input message unrecognized")
if envelope.source is None or envelope.source < 0:
raise ValueError("source missing or invalid")
source = envelope.source if envelope.source < 0:
raise wire.DataError("Source is invalid")
return ENVELOPE_BLUEPRINT.format( return ENVELOPE_BLUEPRINT.format(
account_number=envelope.account_number, account_number=envelope.account_number,
@ -42,12 +45,12 @@ def produce_json_for_signing(envelope: BinanceSignTx, msg) -> str:
memo=envelope.memo, memo=envelope.memo,
msgs=json_msg, msgs=json_msg,
sequence=envelope.sequence, sequence=envelope.sequence,
source=source, source=envelope.source,
) )
def produce_transfer_json(msg: BinanceTransferMsg) -> str: def produce_transfer_json(msg: BinanceTransferMsg) -> str:
def make_input_output(input_output: BinanceInputOutput): def make_input_output(input_output: BinanceInputOutput) -> str:
coins = ",".join( coins = ",".join(
COIN_BLUEPRINT.format(amount=c.amount, denom=c.denom) COIN_BLUEPRINT.format(amount=c.amount, denom=c.denom)
for c in input_output.coins for c in input_output.coins
@ -89,5 +92,6 @@ def address_from_public_key(pubkey: bytes, hrp: str) -> str:
h = sha256_ripemd160(pubkey).digest() h = sha256_ripemd160(pubkey).digest()
convertedbits = bech32.convertbits(h, 8, 5, False) convertedbits = bech32.convertbits(h, 8, 5, False)
assert convertedbits is not None
return bech32.bech32_encode(hrp, convertedbits, bech32.Encoding.BECH32) return bech32.bech32_encode(hrp, convertedbits, bech32.Encoding.BECH32)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.enums import BinanceOrderSide, ButtonRequestType from trezor.enums import BinanceOrderSide, ButtonRequestType
from trezor.messages import ( from trezor.messages import (
BinanceCancelMsg, BinanceCancelMsg,
@ -11,11 +13,14 @@ from trezor.ui.layouts.tt.altcoin import confirm_transfer_binance
from . import helpers from . import helpers
if TYPE_CHECKING:
from trezor.wire import Context
async def require_confirm_transfer(ctx, msg: BinanceTransferMsg): async def require_confirm_transfer(ctx: Context, msg: BinanceTransferMsg) -> None:
items = [] items = []
def make_input_output_pages(msg: BinanceInputOutput, direction): def make_input_output_pages(msg: BinanceInputOutput, direction: str) -> None:
for coin in msg.coins: for coin in msg.coins:
items.append( items.append(
( (
@ -34,36 +39,36 @@ async def require_confirm_transfer(ctx, msg: BinanceTransferMsg):
await confirm_transfer_binance(ctx, items) await confirm_transfer_binance(ctx, items)
async def require_confirm_cancel(ctx, msg: BinanceCancelMsg): async def require_confirm_cancel(ctx: Context, msg: BinanceCancelMsg) -> None:
await confirm_properties( await confirm_properties(
ctx, ctx,
"confirm_cancel", "confirm_cancel",
title="Confirm cancel", title="Confirm cancel",
props=[ props=[
("Sender address:", msg.sender), ("Sender address:", str(msg.sender)),
("Pair:", msg.symbol), ("Pair:", str(msg.symbol)),
("Order ID:", msg.refid), ("Order ID:", str(msg.refid)),
], ],
hold=True, hold=True,
br_code=ButtonRequestType.SignTx, br_code=ButtonRequestType.SignTx,
) )
async def require_confirm_order(ctx, msg: BinanceOrderMsg): async def require_confirm_order(ctx: Context, msg: BinanceOrderMsg) -> None:
if msg.side == BinanceOrderSide.BUY: if msg.side == BinanceOrderSide.BUY:
side = "Buy" side = "Buy"
elif msg.side == BinanceOrderSide.SELL: elif msg.side == BinanceOrderSide.SELL:
side = "Sell" side = "Sell"
else: else:
side = "?" side = "Unknown"
await confirm_properties( await confirm_properties(
ctx, ctx,
"confirm_order", "confirm_order",
title="Confirm order", title="Confirm order",
props=[ props=[
("Sender address:", msg.sender), ("Sender address:", str(msg.sender)),
("Pair:", msg.symbol), ("Pair:", str(msg.symbol)),
("Side:", side), ("Side:", side),
("Quantity:", format_amount(msg.quantity, helpers.DECIMALS)), ("Quantity:", format_amount(msg.quantity, helpers.DECIMALS)),
("Price:", format_amount(msg.price, helpers.DECIMALS)), ("Price:", format_amount(msg.price, helpers.DECIMALS)),

@ -6,6 +6,7 @@ from trezor.messages import (
BinanceCancelMsg, BinanceCancelMsg,
BinanceOrderMsg, BinanceOrderMsg,
BinanceSignedTx, BinanceSignedTx,
BinanceSignTx,
BinanceTransferMsg, BinanceTransferMsg,
BinanceTxRequest, BinanceTxRequest,
) )
@ -17,7 +18,9 @@ from . import helpers, layout
@auto_keychain(__name__) @auto_keychain(__name__)
async def sign_tx(ctx, envelope, keychain: Keychain): async def sign_tx(
ctx: wire.Context, envelope: BinanceSignTx, keychain: Keychain
) -> BinanceSignedTx:
# create transaction message -> sign it -> create signature/pubkey message -> serialize all # create transaction message -> sign it -> create signature/pubkey message -> serialize all
if envelope.msg_count > 1: if envelope.msg_count > 1:
raise wire.DataError("Multiple messages not supported.") raise wire.DataError("Multiple messages not supported.")
@ -34,8 +37,8 @@ async def sign_tx(ctx, envelope, keychain: Keychain):
MessageType.BinanceTransferMsg, MessageType.BinanceTransferMsg,
) )
if envelope.source is None or envelope.source < 0: if envelope.source < 0:
raise wire.DataError("Source missing or invalid.") raise wire.DataError("Source is invalid.")
msg_json = helpers.produce_json_for_signing(envelope, msg) msg_json = helpers.produce_json_for_signing(envelope, msg)
@ -46,7 +49,7 @@ async def sign_tx(ctx, envelope, keychain: Keychain):
elif BinanceCancelMsg.is_type_of(msg): elif BinanceCancelMsg.is_type_of(msg):
await layout.require_confirm_cancel(ctx, msg) await layout.require_confirm_cancel(ctx, msg)
else: else:
raise ValueError("input message unrecognized, is of type " + type(msg).__name__) raise wire.ProcessError("input message unrecognized")
signature_bytes = generate_content_signature(msg_json.encode(), node.private_key()) signature_bytes = generate_content_signature(msg_json.encode(), node.private_key())

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto import base58, cashaddr from trezor.crypto import base58, cashaddr
from trezor.crypto.curve import bip340 from trezor.crypto.curve import bip340
@ -13,7 +15,7 @@ from .common import ecdsa_hash_pubkey, encode_bech32_address
from .multisig import multisig_get_pubkeys, multisig_pubkey_index from .multisig import multisig_get_pubkeys, multisig_pubkey_index
from .scripts import output_script_native_segwit, write_output_script_multisig from .scripts import output_script_native_segwit, write_output_script_multisig
if False: if TYPE_CHECKING:
from trezor.crypto import bip32 from trezor.crypto import bip32

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.messages import AuthorizeCoinJoin from trezor.messages import AuthorizeCoinJoin
@ -7,7 +8,7 @@ from apps.common import authorization
from .common import BIP32_WALLET_DEPTH from .common import BIP32_WALLET_DEPTH
if False: if TYPE_CHECKING:
from trezor.messages import ( from trezor.messages import (
GetOwnershipProof, GetOwnershipProof,
SignTx, SignTx,

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import ui from trezor import ui
from trezor.messages import AuthorizeCoinJoin, Success from trezor.messages import AuthorizeCoinJoin, Success
@ -13,7 +14,7 @@ from .common import BIP32_WALLET_DEPTH
from .keychain import validate_path_against_script_type, with_keychain from .keychain import validate_path_against_script_type, with_keychain
from .sign_tx.layout import format_coin_amount from .sign_tx.layout import format_coin_amount
if False: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
from apps.common.keychain import Keychain from apps.common.keychain import Keychain

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto import bech32, bip32, der from trezor.crypto import bech32, bip32, der
@ -7,9 +8,9 @@ from trezor.crypto.hashlib import sha256
from trezor.enums import InputScriptType, OutputScriptType from trezor.enums import InputScriptType, OutputScriptType
from trezor.utils import HashWriter, ensure from trezor.utils import HashWriter, ensure
if False: if TYPE_CHECKING:
from enum import IntEnum
from typing import Tuple from typing import Tuple
from enum import IntEnum
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
from trezor.messages import TxInput from trezor.messages import TxInput
else: else:
@ -131,6 +132,7 @@ def decode_bech32_address(prefix: str, address: str) -> Tuple[int, bytes]:
witver, raw = bech32.decode(prefix, address) witver, raw = bech32.decode(prefix, address)
if witver not in _BECH32_WITVERS: if witver not in _BECH32_WITVERS:
raise wire.ProcessError("Invalid address witness program") raise wire.ProcessError("Invalid address witness program")
assert witver is not None
assert raw is not None assert raw is not None
return witver, bytes(raw) return witver, bytes(raw)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto import bip32 from trezor.crypto import bip32
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
from trezor.messages import Address from trezor.messages import Address
@ -9,7 +11,7 @@ from . import addresses
from .keychain import validate_path_against_script_type, with_keychain from .keychain import validate_path_against_script_type, with_keychain
from .multisig import multisig_pubkey_index from .multisig import multisig_pubkey_index
if False: if TYPE_CHECKING:
from trezor.messages import GetAddress from trezor.messages import GetAddress
from trezor.messages import HDNodeType from trezor.messages import HDNodeType
from trezor import wire from trezor import wire
@ -62,8 +64,8 @@ async def get_address(
else: else:
address_qr = address # base58 address address_qr = address # base58 address
multisig_xpub_magic = coin.xpub_magic
if msg.multisig: if msg.multisig:
multisig_xpub_magic = coin.xpub_magic
if coin.segwit and not msg.ignore_xpub_magic: if coin.segwit and not msg.ignore_xpub_magic:
if ( if (
msg.script_type == InputScriptType.SPENDWITNESS msg.script_type == InputScriptType.SPENDWITNESS

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
from trezor.messages import GetOwnershipId, OwnershipId from trezor.messages import GetOwnershipId, OwnershipId
@ -8,7 +10,7 @@ from . import addresses, common, scripts
from .keychain import validate_path_against_script_type, with_keychain from .keychain import validate_path_against_script_type, with_keychain
from .ownership import get_identifier from .ownership import get_identifier
if False: if TYPE_CHECKING:
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
from apps.common.keychain import Keychain from apps.common.keychain import Keychain

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import ui, wire from trezor import ui, wire
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
from trezor.messages import GetOwnershipProof, OwnershipProof from trezor.messages import GetOwnershipProof, OwnershipProof
@ -9,7 +11,7 @@ from . import addresses, common, scripts
from .keychain import validate_path_against_script_type, with_keychain from .keychain import validate_path_against_script_type, with_keychain
from .ownership import generate_proof, get_identifier from .ownership import generate_proof, get_identifier
if False: if TYPE_CHECKING:
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
from apps.common.keychain import Keychain from apps.common.keychain import Keychain
from .authorization import CoinJoinAuthorization from .authorization import CoinJoinAuthorization

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
from trezor.messages import HDNodeType, PublicKey from trezor.messages import HDNodeType, PublicKey
@ -5,7 +7,7 @@ from trezor.messages import HDNodeType, PublicKey
from apps.common import coininfo, paths from apps.common import coininfo, paths
from apps.common.keychain import get_keychain from apps.common.keychain import get_keychain
if False: if TYPE_CHECKING:
from trezor.messages import GetPublicKey from trezor.messages import GetPublicKey
@ -34,18 +36,18 @@ async def get_public_key(ctx: wire.Context, msg: GetPublicKey) -> PublicKey:
and script_type == InputScriptType.SPENDP2SHWITNESS and script_type == InputScriptType.SPENDP2SHWITNESS
and (msg.ignore_xpub_magic or coin.xpub_magic_segwit_p2sh is not None) and (msg.ignore_xpub_magic or coin.xpub_magic_segwit_p2sh is not None)
): ):
# TODO: resolve type: ignore below assert coin.xpub_magic_segwit_p2sh is not None
node_xpub = node.serialize_public( node_xpub = node.serialize_public(
coin.xpub_magic if msg.ignore_xpub_magic else coin.xpub_magic_segwit_p2sh # type: ignore coin.xpub_magic if msg.ignore_xpub_magic else coin.xpub_magic_segwit_p2sh
) )
elif ( elif (
coin.segwit coin.segwit
and script_type == InputScriptType.SPENDWITNESS and script_type == InputScriptType.SPENDWITNESS
and (msg.ignore_xpub_magic or coin.xpub_magic_segwit_native is not None) and (msg.ignore_xpub_magic or coin.xpub_magic_segwit_native is not None)
): ):
# TODO: resolve type: ignore below assert coin.xpub_magic_segwit_native is not None
node_xpub = node.serialize_public( node_xpub = node.serialize_public(
coin.xpub_magic if msg.ignore_xpub_magic else coin.xpub_magic_segwit_native # type: ignore coin.xpub_magic if msg.ignore_xpub_magic else coin.xpub_magic_segwit_native
) )
else: else:
raise wire.DataError("Invalid combination of coin and script_type") raise wire.DataError("Invalid combination of coin and script_type")

@ -1,5 +1,6 @@
import gc import gc
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
@ -11,27 +12,44 @@ from apps.common.paths import PATTERN_BIP44, PathSchema
from . import authorization from . import authorization
from .common import BITCOIN_NAMES from .common import BITCOIN_NAMES
if False: if TYPE_CHECKING:
from typing import Awaitable, Callable, Iterable, TypeVar from typing import Awaitable, Callable, Iterable, TypeVar, Union
from typing_extensions import Protocol from typing_extensions import Protocol
from trezor.protobuf import MessageType from trezor.protobuf import MessageType
from trezor.messages import (
AuthorizeCoinJoin,
GetAddress,
GetOwnershipId,
GetOwnershipProof,
GetPublicKey,
SignMessage,
SignTx,
VerifyMessage,
)
from apps.common.keychain import Keychain, MsgOut, Handler from apps.common.keychain import Keychain, MsgOut, Handler
from apps.common.paths import Bip32Path from apps.common.paths import Bip32Path
class MsgWithCoinName(Protocol): BitcoinMessage = Union[
coin_name: str AuthorizeCoinJoin,
GetAddress,
GetOwnershipId,
GetOwnershipProof,
GetPublicKey,
SignMessage,
SignTx,
VerifyMessage,
]
class MsgWithAddressScriptType(Protocol): class MsgWithAddressScriptType(Protocol):
# XXX should be Bip32Path but that fails address_n: Bip32Path
address_n: list[int] = ... script_type: InputScriptType
script_type: InputScriptType = ...
MsgIn = TypeVar("MsgIn", bound=MsgWithCoinName) MsgIn = TypeVar("MsgIn", bound=BitcoinMessage)
HandlerWithCoinInfo = Callable[..., Awaitable[MsgOut]] HandlerWithCoinInfo = Callable[..., Awaitable[MsgOut]]
# BIP-45 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki # BIP-45 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki
PATTERN_BIP45 = "m/45'/[0-100]/change/address_index" PATTERN_BIP45 = "m/45'/[0-100]/change/address_index"

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import utils, wire from trezor import utils, wire
from trezor.crypto import bip32, hashlib, hmac from trezor.crypto import bip32, hashlib, hmac
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
@ -10,7 +12,7 @@ from . import common
from .scripts import read_bip322_signature_proof, write_bip322_signature_proof from .scripts import read_bip322_signature_proof, write_bip322_signature_proof
from .verification import SignatureVerifier from .verification import SignatureVerifier
if False: if TYPE_CHECKING:
from trezor.messages import MultisigRedeemScriptType from trezor.messages import MultisigRedeemScriptType
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import utils, wire from trezor import utils, wire
from trezor.crypto import base58, cashaddr from trezor.crypto import base58, cashaddr
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
@ -23,7 +25,7 @@ from .writers import (
write_op_push, write_op_push,
) )
if False: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from trezor.messages import MultisigRedeemScriptType, TxInput from trezor.messages import MultisigRedeemScriptType, TxInput
@ -172,7 +174,7 @@ def parse_input_script_p2pkh(
if len(pubkey) != n: if len(pubkey) != n:
raise ValueError raise ValueError
except (ValueError, EOFError): except (ValueError, EOFError):
wire.DataError("Invalid scriptSig.") raise wire.DataError("Invalid scriptSig.")
return pubkey, signature, sighash_type return pubkey, signature, sighash_type

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import utils, wire from trezor import utils, wire
from trezor.crypto import base58 from trezor.crypto import base58
from trezor.crypto.base58 import blake256d_32 from trezor.crypto.base58 import blake256d_32
@ -15,7 +17,7 @@ from .scripts import ( # noqa: F401
) )
from .writers import op_push_length, write_bitcoin_varint, write_op_push from .writers import op_push_length, write_bitcoin_varint, write_op_push
if False: if TYPE_CHECKING:
from trezor.messages import MultisigRedeemScriptType from trezor.messages import MultisigRedeemScriptType
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
@ -10,7 +12,7 @@ from apps.common.signverify import decode_message, message_digest
from .addresses import address_short, get_address from .addresses import address_short, get_address
from .keychain import validate_path_against_script_type, with_keychain from .keychain import validate_path_against_script_type, with_keychain
if False: if TYPE_CHECKING:
from trezor.messages import SignMessage from trezor.messages import SignMessage
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import utils, wire from trezor import utils, wire
from trezor.enums import RequestType from trezor.enums import RequestType
from trezor.messages import TxRequest from trezor.messages import TxRequest
@ -9,7 +11,7 @@ from . import approvers, bitcoin, helpers, progress
if not utils.BITCOIN_ONLY: if not utils.BITCOIN_ONLY:
from . import bitcoinlike, decred, zcash from . import bitcoinlike, decred, zcash
if False: if TYPE_CHECKING:
from typing import Protocol, Union from typing import Protocol, Union
from trezor.messages import ( from trezor.messages import (

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.enums import OutputScriptType from trezor.enums import OutputScriptType
@ -10,7 +11,7 @@ from ..keychain import validate_path_against_script_type
from . import helpers, tx_weight from . import helpers, tx_weight
from .tx_info import OriginalTxInfo, TxInfo from .tx_info import OriginalTxInfo, TxInfo
if False: if TYPE_CHECKING:
from trezor.messages import SignTx from trezor.messages import SignTx
from trezor.messages import TxInput from trezor.messages import TxInput
from trezor.messages import TxOutput from trezor.messages import TxOutput

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
@ -22,7 +23,7 @@ from . import approvers, helpers, progress
from .sig_hasher import BitcoinSigHasher from .sig_hasher import BitcoinSigHasher
from .tx_info import OriginalTxInfo, TxInfo from .tx_info import OriginalTxInfo, TxInfo
if False: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from trezor.crypto import bip32 from trezor.crypto import bip32
@ -611,6 +612,8 @@ class Bitcoin:
self.write_tx_header(h_sign, tx_info.tx, witness_marker=False) self.write_tx_header(h_sign, tx_info.tx, witness_marker=False)
write_bitcoin_varint(h_sign, tx_info.tx.inputs_count) write_bitcoin_varint(h_sign, tx_info.tx.inputs_count)
txi_sign = None
node = None
for i in range(tx_info.tx.inputs_count): for i in range(tx_info.tx.inputs_count):
# STAGE_REQUEST_4_INPUT in legacy # STAGE_REQUEST_4_INPUT in legacy
txi = await helpers.request_tx_input(self.tx_req, i, self.coin, tx_hash) txi = await helpers.request_tx_input(self.tx_req, i, self.coin, tx_hash)
@ -618,7 +621,6 @@ class Bitcoin:
# Only the previous UTXO's scriptPubKey is included in h_sign. # Only the previous UTXO's scriptPubKey is included in h_sign.
if i == index: if i == index:
txi_sign = txi txi_sign = txi
node = None
if not script_pubkey: if not script_pubkey:
self.tx_info.check_input(txi) self.tx_info.check_input(txi)
node = self.keychain.derive(txi.address_n) node = self.keychain.derive(txi.address_n)
@ -643,6 +645,9 @@ class Bitcoin:
else: else:
self.write_tx_input(h_sign, txi, bytes()) self.write_tx_input(h_sign, txi, bytes())
if txi_sign is None:
raise RuntimeError # index >= tx_info.tx.inputs_count
write_bitcoin_varint(h_sign, tx_info.tx.outputs_count) write_bitcoin_varint(h_sign, tx_info.tx.outputs_count)
for i in range(tx_info.tx.outputs_count): for i in range(tx_info.tx.outputs_count):
@ -712,6 +717,7 @@ class Bitcoin:
write_bitcoin_varint(txh, tx.outputs_count) write_bitcoin_varint(txh, tx.outputs_count)
script_pubkey: bytes | None = None
for i in range(tx.outputs_count): for i in range(tx.outputs_count):
# STAGE_REQUEST_3_PREV_OUTPUT in legacy # STAGE_REQUEST_3_PREV_OUTPUT in legacy
txo_bin = await helpers.request_tx_prev_output( txo_bin = await helpers.request_tx_prev_output(
@ -723,6 +729,8 @@ class Bitcoin:
script_pubkey = txo_bin.script_pubkey script_pubkey = txo_bin.script_pubkey
self.check_prevtx_output(txo_bin) self.check_prevtx_output(txo_bin)
assert script_pubkey is not None # prev_index < tx.outputs_count
await self.write_prev_tx_footer(txh, tx, prev_hash) await self.write_prev_tx_footer(txh, tx, prev_hash)
if ( if (

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.messages import PrevTx, SignTx, TxInput from trezor.messages import PrevTx, SignTx, TxInput
@ -8,7 +10,7 @@ from ..common import NONSEGWIT_INPUT_SCRIPT_TYPES, SigHashType
from . import helpers from . import helpers
from .bitcoin import Bitcoin from .bitcoin import Bitcoin
if False: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from .tx_info import OriginalTxInfo, TxInfo from .tx_info import OriginalTxInfo, TxInfo

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.hashlib import blake256 from trezor.crypto.hashlib import blake256
@ -22,7 +23,7 @@ OUTPUT_SCRIPT_NULL_SSTXCHANGE = (
b"\xBD\x76\xA9\x14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\xAC" b"\xBD\x76\xA9\x14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\xAC"
) )
if False: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from trezor.messages import ( from trezor.messages import (

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import utils, wire from trezor import utils, wire
from trezor.enums import InputScriptType, OutputScriptType, RequestType from trezor.enums import InputScriptType, OutputScriptType, RequestType
from trezor.messages import ( from trezor.messages import (
@ -23,7 +25,7 @@ from .. import common
from ..writers import TX_HASH_SIZE from ..writers import TX_HASH_SIZE
from . import layout from . import layout
if False: if TYPE_CHECKING:
from typing import Any, Awaitable from typing import Any, Awaitable
from trezor.enums import AmountUnit from trezor.enums import AmountUnit
@ -36,6 +38,8 @@ class UiConfirm:
def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]:
raise NotImplementedError raise NotImplementedError
__eq__ = utils.obj_eq # type: ignore
class UiConfirmOutput(UiConfirm): class UiConfirmOutput(UiConfirm):
def __init__(self, output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit): def __init__(self, output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit):
@ -46,8 +50,6 @@ class UiConfirmOutput(UiConfirm):
def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]:
return layout.confirm_output(ctx, self.output, self.coin, self.amount_unit) return layout.confirm_output(ctx, self.output, self.coin, self.amount_unit)
__eq__ = utils.obj_eq
class UiConfirmDecredSSTXSubmission(UiConfirm): class UiConfirmDecredSSTXSubmission(UiConfirm):
def __init__(self, output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit): def __init__(self, output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit):
@ -60,8 +62,6 @@ class UiConfirmDecredSSTXSubmission(UiConfirm):
ctx, self.output, self.coin, self.amount_unit ctx, self.output, self.coin, self.amount_unit
) )
__eq__ = utils.obj_eq
class UiConfirmReplacement(UiConfirm): class UiConfirmReplacement(UiConfirm):
def __init__(self, description: str, txid: bytes): def __init__(self, description: str, txid: bytes):
@ -71,8 +71,6 @@ class UiConfirmReplacement(UiConfirm):
def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]:
return layout.confirm_replacement(ctx, self.description, self.txid) return layout.confirm_replacement(ctx, self.description, self.txid)
__eq__ = utils.obj_eq
class UiConfirmModifyOutput(UiConfirm): class UiConfirmModifyOutput(UiConfirm):
def __init__( def __init__(
@ -92,8 +90,6 @@ class UiConfirmModifyOutput(UiConfirm):
ctx, self.txo, self.orig_txo, self.coin, self.amount_unit ctx, self.txo, self.orig_txo, self.coin, self.amount_unit
) )
__eq__ = utils.obj_eq
class UiConfirmModifyFee(UiConfirm): class UiConfirmModifyFee(UiConfirm):
def __init__( def __init__(
@ -113,8 +109,6 @@ class UiConfirmModifyFee(UiConfirm):
ctx, self.user_fee_change, self.total_fee_new, self.coin, self.amount_unit ctx, self.user_fee_change, self.total_fee_new, self.coin, self.amount_unit
) )
__eq__ = utils.obj_eq
class UiConfirmTotal(UiConfirm): class UiConfirmTotal(UiConfirm):
def __init__( def __init__(
@ -130,8 +124,6 @@ class UiConfirmTotal(UiConfirm):
ctx, self.spending, self.fee, self.coin, self.amount_unit ctx, self.spending, self.fee, self.coin, self.amount_unit
) )
__eq__ = utils.obj_eq
class UiConfirmJointTotal(UiConfirm): class UiConfirmJointTotal(UiConfirm):
def __init__( def __init__(
@ -147,8 +139,6 @@ class UiConfirmJointTotal(UiConfirm):
ctx, self.spending, self.total, self.coin, self.amount_unit ctx, self.spending, self.total, self.coin, self.amount_unit
) )
__eq__ = utils.obj_eq
class UiConfirmFeeOverThreshold(UiConfirm): class UiConfirmFeeOverThreshold(UiConfirm):
def __init__(self, fee: int, coin: CoinInfo, amount_unit: AmountUnit): def __init__(self, fee: int, coin: CoinInfo, amount_unit: AmountUnit):
@ -161,8 +151,6 @@ class UiConfirmFeeOverThreshold(UiConfirm):
ctx, self.fee, self.coin, self.amount_unit ctx, self.fee, self.coin, self.amount_unit
) )
__eq__ = utils.obj_eq
class UiConfirmChangeCountOverThreshold(UiConfirm): class UiConfirmChangeCountOverThreshold(UiConfirm):
def __init__(self, change_count: int): def __init__(self, change_count: int):
@ -171,8 +159,6 @@ class UiConfirmChangeCountOverThreshold(UiConfirm):
def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]:
return layout.confirm_change_count_over_threshold(ctx, self.change_count) return layout.confirm_change_count_over_threshold(ctx, self.change_count)
__eq__ = utils.obj_eq
class UiConfirmForeignAddress(UiConfirm): class UiConfirmForeignAddress(UiConfirm):
def __init__(self, address_n: list): def __init__(self, address_n: list):
@ -181,8 +167,6 @@ class UiConfirmForeignAddress(UiConfirm):
def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]:
return paths.show_path_warning(ctx, self.address_n) return paths.show_path_warning(ctx, self.address_n)
__eq__ = utils.obj_eq
class UiConfirmNonDefaultLocktime(UiConfirm): class UiConfirmNonDefaultLocktime(UiConfirm):
def __init__(self, lock_time: int, lock_time_disabled: bool): def __init__(self, lock_time: int, lock_time_disabled: bool):
@ -194,8 +178,6 @@ class UiConfirmNonDefaultLocktime(UiConfirm):
ctx, self.lock_time, self.lock_time_disabled ctx, self.lock_time, self.lock_time_disabled
) )
__eq__ = utils.obj_eq
def confirm_output(output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[None]: # type: ignore def confirm_output(output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[None]: # type: ignore
return (yield UiConfirmOutput(output, coin, amount_unit)) return (yield UiConfirmOutput(output, coin, amount_unit))
@ -250,9 +232,9 @@ def request_tx_meta(tx_req: TxRequest, coin: CoinInfo, tx_hash: bytes | None = N
return sanitize_tx_meta(ack.tx, coin) return sanitize_tx_meta(ack.tx, coin)
def request_tx_extra_data( # type: ignore def request_tx_extra_data(
tx_req: TxRequest, offset: int, size: int, tx_hash: bytes | None = None tx_req: TxRequest, offset: int, size: int, tx_hash: bytes | None = None
) -> Awaitable[bytearray]: ) -> Awaitable[bytearray]: # type: ignore
assert tx_req.details is not None assert tx_req.details is not None
tx_req.request_type = RequestType.TXEXTRADATA tx_req.request_type = RequestType.TXEXTRADATA
tx_req.details.extra_data_offset = offset tx_req.details.extra_data_offset = offset
@ -327,7 +309,8 @@ def _clear_tx_request(tx_req: TxRequest) -> None:
tx_req.details.extra_data_offset = None tx_req.details.extra_data_offset = None
tx_req.serialized.signature = None tx_req.serialized.signature = None
tx_req.serialized.signature_index = None tx_req.serialized.signature_index = None
# mypy thinks serialized_tx is `bytes`, which doesn't support indexed assignment # typechecker thinks serialized_tx is `bytes`, which is immutable
# we know that it is `bytearray` in reality
tx_req.serialized.serialized_tx[:] = bytes() # type: ignore tx_req.serialized.serialized_tx[:] = bytes() # type: ignore

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor import utils from trezor import utils
@ -13,7 +14,7 @@ if not utils.BITCOIN_ONLY:
from trezor.ui.layouts.tt import altcoin from trezor.ui.layouts.tt import altcoin
if False: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from trezor.messages import TxOutput from trezor.messages import TxOutput
from trezor.ui.layouts import LayoutType from trezor.ui.layouts import LayoutType

@ -1,17 +1,19 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.utils import ensure from trezor.utils import ensure
from .. import multisig from .. import multisig
from ..common import BIP32_WALLET_DEPTH from ..common import BIP32_WALLET_DEPTH
if False: if TYPE_CHECKING:
from typing import Any, Generic, TypeVar from typing import Any, Generic, TypeVar
from trezor.messages import TxInput, TxOutput from trezor.messages import TxInput, TxOutput
T = TypeVar("T") T = TypeVar("T")
else: else:
# mypy cheat: Generic[T] will be `object` which is a valid parent type # typechecker cheat: Generic[T] will be `object` which is a valid parent type
Generic = [object] # type: ignore Generic = [object] # type: ignore
T = 0 # type: ignore T = 0 # type: ignore

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.messages import PrevTx, SignTx, TxInput, TxOutput from trezor.messages import PrevTx, SignTx, TxInput, TxOutput
from trezor.utils import HashWriter from trezor.utils import HashWriter
@ -7,7 +9,7 @@ from apps.common import coininfo
from .. import scripts, writers from .. import scripts, writers
from ..common import tagged_hashwriter from ..common import tagged_hashwriter
if False: if TYPE_CHECKING:
from typing import Protocol, Sequence from typing import Protocol, Sequence
from ..common import SigHashType from ..common import SigHashType

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
@ -8,7 +9,7 @@ from .. import common, writers
from ..common import BIP32_WALLET_DEPTH, input_is_external from ..common import BIP32_WALLET_DEPTH, input_is_external
from .matchcheck import MultisigFingerprintChecker, WalletPathChecker from .matchcheck import MultisigFingerprintChecker, WalletPathChecker
if False: if TYPE_CHECKING:
from typing import Protocol from typing import Protocol
from trezor.messages import ( from trezor.messages import (
PrevTx, PrevTx,
@ -21,7 +22,7 @@ if False:
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
class Signer(Protocol): class Signer(Protocol):
coin = ... # type: CoinInfo coin: CoinInfo
def create_hash_writer(self) -> HashWriter: def create_hash_writer(self) -> HashWriter:
... ...

@ -6,13 +6,14 @@
# https://github.com/trezor/trezor-mcu/commit/e1fa7af1da79e86ccaae5f3cd2a6c4644f546f8a # https://github.com/trezor/trezor-mcu/commit/e1fa7af1da79e86ccaae5f3cd2a6c4644f546f8a
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
from .. import common, ownership from .. import common, ownership
if False: if TYPE_CHECKING:
from trezor.messages import TxInput from trezor.messages import TxInput
# transaction header size: 4 byte version # transaction header size: 4 byte version

@ -1,5 +1,6 @@
import ustruct as struct import ustruct as struct
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.hashlib import blake2b from trezor.crypto.hashlib import blake2b
@ -23,7 +24,7 @@ from ..writers import (
from . import approvers, helpers from . import approvers, helpers
from .bitcoinlike import Bitcoinlike from .bitcoinlike import Bitcoinlike
if False: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from apps.common import coininfo from apps.common import coininfo
from .sig_hasher import SigHasher from .sig_hasher import SigHasher
@ -119,7 +120,7 @@ class Zcashlike(Bitcoinlike):
tx: SignTx, tx: SignTx,
keychain: Keychain, keychain: Keychain,
coin: CoinInfo, coin: CoinInfo,
approver: approvers.Approver, approver: approvers.Approver | None,
) -> None: ) -> None:
ensure(coin.overwintered) ensure(coin.overwintered)
super().__init__(tx, keychain, coin, approver) super().__init__(tx, keychain, coin, approver)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import utils, wire from trezor import utils, wire
from trezor.crypto import der from trezor.crypto import der
from trezor.crypto.curve import bip340, secp256k1 from trezor.crypto.curve import bip340, secp256k1
@ -19,7 +21,7 @@ from .scripts import (
write_input_script_p2wsh_in_p2sh, write_input_script_p2wsh_in_p2sh,
) )
if False: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.enums import InputScriptType from trezor.enums import InputScriptType
@ -15,7 +17,7 @@ from .addresses import (
address_to_cashaddr, address_to_cashaddr,
) )
if False: if TYPE_CHECKING:
from trezor.messages import VerifyMessage from trezor.messages import VerifyMessage

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.utils import ensure from trezor.utils import ensure
@ -14,7 +15,7 @@ from apps.common.writers import ( # noqa: F401
write_uint64_le, write_uint64_le,
) )
if False: if TYPE_CHECKING:
from trezor.messages import ( from trezor.messages import (
PrevInput, PrevInput,
PrevOutput, PrevOutput,

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto import base58 from trezor.crypto import base58
from trezor.enums import CardanoAddressType from trezor.enums import CardanoAddressType
@ -15,7 +17,7 @@ from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT
from .helpers.utils import get_public_key_hash, variable_length_encode from .helpers.utils import get_public_key_hash, variable_length_encode
from .seed import is_byron_path, is_shelley_path from .seed import is_byron_path, is_shelley_path
if False: if TYPE_CHECKING:
from typing import Any from typing import Any
from trezor.messages import ( from trezor.messages import (

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto import hashlib from trezor.crypto import hashlib
from trezor.crypto.curve import ed25519 from trezor.crypto.curve import ed25519
from trezor.enums import CardanoAddressType, CardanoTxAuxiliaryDataSupplementType from trezor.enums import CardanoAddressType, CardanoTxAuxiliaryDataSupplementType
@ -16,7 +18,7 @@ from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT
from .helpers.utils import derive_public_key from .helpers.utils import derive_public_key
from .layout import confirm_catalyst_registration, show_auxiliary_data_hash from .layout import confirm_catalyst_registration, show_auxiliary_data_hash
if False: if TYPE_CHECKING:
from typing import Union from typing import Union
from trezor import wire from trezor import wire

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import log from trezor import log
from trezor.crypto import crc, hashlib from trezor.crypto import crc, hashlib
@ -6,7 +8,7 @@ from apps.common import cbor
from .helpers import INVALID_ADDRESS, NETWORK_MISMATCH, protocol_magics from .helpers import INVALID_ADDRESS, NETWORK_MISMATCH, protocol_magics
from .helpers.utils import derive_public_key from .helpers.utils import derive_public_key
if False: if TYPE_CHECKING:
from . import seed from . import seed
PROTOCOL_MAGIC_KEY = 2 PROTOCOL_MAGIC_KEY = 2

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.enums import ( from trezor.enums import (
CardanoCertificateType, CardanoCertificateType,
CardanoPoolRelayType, CardanoPoolRelayType,
@ -15,7 +17,7 @@ from .helpers import ADDRESS_KEY_HASH_SIZE, INVALID_CERTIFICATE, LOVELACE_MAX_SU
from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT
from .helpers.utils import validate_stake_credential from .helpers.utils import validate_stake_credential
if False: if TYPE_CHECKING:
from typing import Any from typing import Any
from trezor.messages import ( from trezor.messages import (

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import log, wire from trezor import log, wire
from trezor.messages import CardanoAddress from trezor.messages import CardanoAddress
@ -7,7 +9,7 @@ from .helpers.credential import Credential, should_show_address_credentials
from .layout import show_cardano_address, show_credentials from .layout import show_cardano_address, show_credentials
from .sign_tx import validate_network_info from .sign_tx import validate_network_info
if False: if TYPE_CHECKING:
from trezor.messages import ( from trezor.messages import (
CardanoAddressParametersType, CardanoAddressParametersType,
CardanoGetAddress, CardanoGetAddress,

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.enums import CardanoNativeScriptHashDisplayFormat from trezor.enums import CardanoNativeScriptHashDisplayFormat
from trezor.messages import CardanoNativeScriptHash from trezor.messages import CardanoNativeScriptHash
@ -5,7 +7,7 @@ from trezor.messages import CardanoNativeScriptHash
from . import native_script, seed from . import native_script, seed
from .layout import show_native_script, show_script_hash from .layout import show_native_script, show_script_hash
if False: if TYPE_CHECKING:
from trezor.messages import CardanoGetNativeScriptHash from trezor.messages import CardanoGetNativeScriptHash

@ -1,3 +1,4 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor import log, wire from trezor import log, wire
@ -10,7 +11,7 @@ from . import seed
from .helpers.paths import SCHEMA_MINT, SCHEMA_PUBKEY from .helpers.paths import SCHEMA_MINT, SCHEMA_PUBKEY
from .helpers.utils import derive_public_key from .helpers.utils import derive_public_key
if False: if TYPE_CHECKING:
from trezor.messages import CardanoGetPublicKey from trezor.messages import CardanoGetPublicKey

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from ...common.paths import HARDENED from ...common.paths import HARDENED
from ..seed import is_byron_path, is_minting_path, is_multisig_path, is_shelley_path from ..seed import is_byron_path, is_minting_path, is_multisig_path, is_shelley_path
from . import ( from . import (
@ -9,7 +11,7 @@ from . import (
from .paths import ACCOUNT_PATH_INDEX, ACCOUNT_PATH_LENGTH from .paths import ACCOUNT_PATH_INDEX, ACCOUNT_PATH_LENGTH
from .utils import to_account_path from .utils import to_account_path
if False: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from trezor.messages import ( from trezor.messages import (
CardanoPoolOwner, CardanoPoolOwner,

@ -1,10 +1,12 @@
from typing import TYPE_CHECKING
from trezor.enums import CardanoAddressType from trezor.enums import CardanoAddressType
from ...common.paths import address_n_to_str from ...common.paths import address_n_to_str
from .paths import CHAIN_STAKING_KEY, SCHEMA_PAYMENT, SCHEMA_STAKING from .paths import CHAIN_STAKING_KEY, SCHEMA_PAYMENT, SCHEMA_STAKING
from .utils import format_key_hash, format_script_hash, to_account_path from .utils import format_key_hash, format_script_hash, to_account_path
if False: if TYPE_CHECKING:
from trezor.messages import ( from trezor.messages import (
CardanoBlockchainPointerType, CardanoBlockchainPointerType,
CardanoAddressParametersType, CardanoAddressParametersType,

@ -1,6 +1,8 @@
from typing import TYPE_CHECKING
from apps.common import cbor from apps.common import cbor
if False: if TYPE_CHECKING:
from typing import Any, Generic, TypeVar from typing import Any, Generic, TypeVar
from trezor.utils import HashContext from trezor.utils import HashContext

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto import hashlib from trezor.crypto import hashlib
from trezor.enums import CardanoTxSigningMode from trezor.enums import CardanoTxSigningMode
@ -10,7 +12,7 @@ from apps.common.seed import remove_ed25519_prefix
from . import ADDRESS_KEY_HASH_SIZE, SCRIPT_HASH_SIZE, bech32 from . import ADDRESS_KEY_HASH_SIZE, SCRIPT_HASH_SIZE, bech32
if False: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from .. import seed from .. import seed

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import ui from trezor import ui
from trezor.enums import ( from trezor.enums import (
ButtonRequestType, ButtonRequestType,
@ -35,7 +37,7 @@ from .helpers.utils import (
) )
from .seed import is_minting_path, is_multisig_path from .seed import is_minting_path, is_multisig_path
if False: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from trezor.messages import ( from trezor.messages import (
CardanoNativeScript, CardanoNativeScript,

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto import hashlib from trezor.crypto import hashlib
from trezor.enums import CardanoAddressType, CardanoNativeScriptType from trezor.enums import CardanoAddressType, CardanoNativeScriptType
@ -12,7 +14,7 @@ from .helpers.paths import SCHEMA_MINT
from .helpers.utils import get_public_key_hash from .helpers.utils import get_public_key_hash
from .seed import Keychain, is_multisig_path from .seed import Keychain, is_multisig_path
if False: if TYPE_CHECKING:
from typing import Any from typing import Any
from trezor.messages import CardanoNativeScript from trezor.messages import CardanoNativeScript

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from storage import cache, device from storage import cache, device
from trezor import wire from trezor import wire
from trezor.crypto import bip32, cardano from trezor.crypto import bip32, cardano
@ -8,7 +10,7 @@ from apps.common.seed import derive_and_store_roots, get_seed
from .helpers import paths from .helpers import paths
if False: if TYPE_CHECKING:
from typing import Callable, Awaitable, TypeVar, Union from typing import Callable, Awaitable, TypeVar, Union
from apps.common.paths import Bip32Path from apps.common.paths import Bip32Path

@ -1,4 +1,5 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import log, wire from trezor import log, wire
from trezor.crypto import hashlib from trezor.crypto import hashlib
@ -105,7 +106,7 @@ from .layout import (
) )
from .seed import is_byron_path, is_multisig_path, is_shelley_path from .seed import is_byron_path, is_multisig_path, is_shelley_path
if False: if TYPE_CHECKING:
from typing import Any, Union from typing import Any, Union
from apps.common.paths import PathSchema from apps.common.paths import PathSchema

@ -1,11 +1,10 @@
from typing import Iterable
import storage.cache import storage.cache
from trezor import protobuf from trezor import protobuf
from trezor.enums import MessageType from trezor.enums import MessageType
from trezor.utils import ensure from trezor.utils import ensure
if False:
from typing import Iterable
WIRE_TYPES: dict[int, tuple[int, ...]] = { WIRE_TYPES: dict[int, tuple[int, ...]] = {
MessageType.AuthorizeCoinJoin: (MessageType.SignTx, MessageType.GetOwnershipProof), MessageType.AuthorizeCoinJoin: (MessageType.SignTx, MessageType.GetOwnershipProof),
} }
@ -21,7 +20,7 @@ def set(auth_message: protobuf.MessageType) -> None:
# only wire-level messages can be stored as authorization # only wire-level messages can be stored as authorization
# (because only wire-level messages have wire_type, which we use as identifier) # (because only wire-level messages have wire_type, which we use as identifier)
ensure(auth_message.MESSAGE_WIRE_TYPE is not None) ensure(auth_message.MESSAGE_WIRE_TYPE is not None)
assert auth_message.MESSAGE_WIRE_TYPE is not None # so that mypy knows as well assert auth_message.MESSAGE_WIRE_TYPE is not None # so that typechecker knows too
storage.cache.set( storage.cache.set(
storage.cache.APP_COMMON_AUTHORIZATION_TYPE, storage.cache.APP_COMMON_AUTHORIZATION_TYPE,
auth_message.MESSAGE_WIRE_TYPE.to_bytes(2, "big"), auth_message.MESSAGE_WIRE_TYPE.to_bytes(2, "big"),

@ -4,12 +4,13 @@ Minimalistic CBOR implementation, supports only what we need in cardano.
import ustruct as struct import ustruct as struct
from micropython import const from micropython import const
from typing import TYPE_CHECKING
from trezor import log, utils from trezor import log, utils
from . import readers from . import readers
if False: if TYPE_CHECKING:
from typing import Any, Generic, Iterator, Tuple, TypeVar, Union from typing import Any, Generic, Iterator, Tuple, TypeVar, Union
K = TypeVar("K") K = TypeVar("K")
@ -17,7 +18,7 @@ if False:
Value = Any Value = Any
CborSequence = Union[list[Value], Tuple[Value, ...]] CborSequence = Union[list[Value], Tuple[Value, ...]]
else: else:
# mypy cheat: Generic[K, V] will be `object` which is a valid parent type # typechecker cheat: Generic[K, V] will be `object` which is a valid parent type
Generic = {(0, 0): object} # type: ignore Generic = {(0, 0): object} # type: ignore
K = V = 0 # type: ignore K = V = 0 # type: ignore

@ -1,12 +1,11 @@
# generated from coininfo.py.mako # generated from coininfo.py.mako
# do not edit manually! # do not edit manually!
from typing import Any
from trezor import utils from trezor import utils
from trezor.crypto.base58 import blake256d_32, groestl512d_32, keccak_32, sha256d_32 from trezor.crypto.base58 import blake256d_32, groestl512d_32, keccak_32, sha256d_32
from trezor.crypto.scripts import blake256_ripemd160, sha256_ripemd160 from trezor.crypto.scripts import blake256_ripemd160, sha256_ripemd160
if False:
from typing import Any, Type
# flake8: noqa # flake8: noqa
@ -69,7 +68,7 @@ class CoinInfo:
if curve_name == "secp256k1-groestl": if curve_name == "secp256k1-groestl":
self.b58_hash = groestl512d_32 self.b58_hash = groestl512d_32
self.sign_hash_double = False self.sign_hash_double = False
self.script_hash: Type[utils.HashContext] = sha256_ripemd160 self.script_hash: type[utils.HashContext] = sha256_ripemd160
elif curve_name == "secp256k1-decred": elif curve_name == "secp256k1-decred":
self.b58_hash = blake256d_32 self.b58_hash = blake256d_32
self.sign_hash_double = False self.sign_hash_double = False

@ -1,12 +1,11 @@
# generated from coininfo.py.mako # generated from coininfo.py.mako
# do not edit manually! # do not edit manually!
from typing import Any
from trezor import utils from trezor import utils
from trezor.crypto.base58 import blake256d_32, groestl512d_32, keccak_32, sha256d_32 from trezor.crypto.base58 import blake256d_32, groestl512d_32, keccak_32, sha256d_32
from trezor.crypto.scripts import blake256_ripemd160, sha256_ripemd160 from trezor.crypto.scripts import blake256_ripemd160, sha256_ripemd160
if False:
from typing import Any, Type
# flake8: noqa # flake8: noqa
@ -69,7 +68,7 @@ class CoinInfo:
if curve_name == "secp256k1-groestl": if curve_name == "secp256k1-groestl":
self.b58_hash = groestl512d_32 self.b58_hash = groestl512d_32
self.sign_hash_double = False self.sign_hash_double = False
self.script_hash: Type[utils.HashContext] = sha256_ripemd160 self.script_hash: type[utils.HashContext] = sha256_ripemd160
elif curve_name == "secp256k1-decred": elif curve_name == "secp256k1-decred":
self.b58_hash = blake256d_32 self.b58_hash = blake256d_32
self.sign_hash_double = False self.sign_hash_double = False

@ -1,4 +1,5 @@
import sys import sys
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto import bip32 from trezor.crypto import bip32
@ -6,7 +7,7 @@ from trezor.crypto import bip32
from . import paths, safety_checks from . import paths, safety_checks
from .seed import Slip21Node, get_seed from .seed import Slip21Node, get_seed
if False: if TYPE_CHECKING:
from typing import ( from typing import (
Any, Any,
Awaitable, Awaitable,

@ -1,8 +1,9 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING
HARDENED = const(0x8000_0000) HARDENED = const(0x8000_0000)
if False: if TYPE_CHECKING:
from typing import ( from typing import (
Any, Any,
Callable, Callable,
@ -17,7 +18,7 @@ if False:
Bip32Path = Sequence[int] Bip32Path = Sequence[int]
Slip21Path = Sequence[bytes] Slip21Path = Sequence[bytes]
PathType = TypeVar("PathType", Bip32Path, Slip21Path) PathType = TypeVar("PathType", Bip32Path, Slip21Path, contravariant=True)
class PathSchemaType(Protocol): class PathSchemaType(Protocol):
def match(self, path: Bip32Path) -> bool: def match(self, path: Bip32Path) -> bool:
@ -105,7 +106,7 @@ class PathSchema:
_EMPTY_TUPLE = () _EMPTY_TUPLE = ()
@staticmethod @staticmethod
def _parse_hardened(s: str) -> int: def _parse_hardened(s: str | int) -> int:
return int(s) | HARDENED return int(s) | HARDENED
@staticmethod @staticmethod
@ -259,7 +260,8 @@ class PathSchema:
prime = "'" if a & HARDENED else "" prime = "'" if a & HARDENED else ""
components.append(f"[{unharden(a)}-{unharden(b)}]{prime}") components.append(f"[{unharden(a)}-{unharden(b)}]{prime}")
else: else:
# mypy thinks component is a Contanier but we're using it as a Collection. # typechecker thinks component is a Contanier but we're using it
# as a Collection.
# Which in practice it is, the only non-Collection is Interval. # Which in practice it is, the only non-Collection is Interval.
# But we're not going to introduce an additional type requirement # But we're not going to introduce an additional type requirement
# for the sake of __repr__ that doesn't exist in production anyway # for the sake of __repr__ that doesn't exist in production anyway
@ -282,25 +284,18 @@ class PathSchema:
return "<schema:" + "/".join(components) + ">" return "<schema:" + "/".join(components) + ">"
class _AlwaysMatchingSchema: class AlwaysMatchingSchema:
@staticmethod @staticmethod
def match(path: Bip32Path) -> bool: def match(path: Bip32Path) -> bool:
return True return True
class _NeverMatchingSchema: class NeverMatchingSchema:
@staticmethod @staticmethod
def match(path: Bip32Path) -> bool: def match(path: Bip32Path) -> bool:
return False return False
# type objects _AlwaysMatchingSchema and _NeverMatching schema conform to the
# PathSchemaType protocol, but mypy fails to recognize this due to:
# https://github.com/python/mypy/issues/4536,
# hence the following trickery
AlwaysMatchingSchema: PathSchemaType = _AlwaysMatchingSchema # type: ignore
NeverMatchingSchema: PathSchemaType = _NeverMatchingSchema # type: ignore
# BIP-44 for basic (legacy) Bitcoin accounts, and widely used for other currencies: # BIP-44 for basic (legacy) Bitcoin accounts, and widely used for other currencies:
# https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki # https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
PATTERN_BIP44 = "m/44'/coin_type'/account'/change/address_index" PATTERN_BIP44 = "m/44'/coin_type'/account'/change/address_index"

@ -1,4 +1,5 @@
import utime import utime
from typing import Any, NoReturn
import storage.cache import storage.cache
import storage.sd_salt import storage.sd_salt
@ -6,9 +7,6 @@ from trezor import config, wire
from .sdcard import SdCardUnavailable, request_sd_salt from .sdcard import SdCardUnavailable, request_sd_salt
if False:
from typing import Any, NoReturn
def can_lock_device() -> bool: def can_lock_device() -> bool:
"""Return True if the device has a PIN set or SD-protect enabled.""" """Return True if the device has a PIN set or SD-protect enabled."""
@ -108,7 +106,8 @@ async def verify_user_pin(
raise RuntimeError raise RuntimeError
while retry: while retry:
pin = await request_pin_on_device( # request_pin_on_device possibly unbound
pin = await request_pin_on_device( # type: ignore
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
) )
if config.unlock(pin, salt): if config.unlock(pin, salt):

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from storage import cache, device from storage import cache, device
from trezor import utils, wire from trezor import utils, wire
from trezor.crypto import bip32, hmac from trezor.crypto import bip32, hmac
@ -5,7 +7,7 @@ from trezor.crypto import bip32, hmac
from . import mnemonic from . import mnemonic
from .passphrase import get as get_passphrase from .passphrase import get as get_passphrase
if False: if TYPE_CHECKING:
from .paths import Bip32Path, Slip21Path from .paths import Bip32Path, Slip21Path

@ -1,3 +1,4 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor import utils, wire from trezor import utils, wire
@ -5,7 +6,7 @@ from trezor.crypto.hashlib import blake256, sha256
from apps.common.writers import write_bitcoin_varint from apps.common.writers import write_bitcoin_varint
if False: if TYPE_CHECKING:
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo

@ -1,6 +1,8 @@
from typing import TYPE_CHECKING
from trezor.utils import ensure from trezor.utils import ensure
if False: if TYPE_CHECKING:
from typing import Union from typing import Union
from trezor.utils import Writer from trezor.utils import Writer

@ -16,7 +16,9 @@ if __debug__:
from apps import workflow_handlers from apps import workflow_handlers
if False: from typing import TYPE_CHECKING
if TYPE_CHECKING:
from trezor.ui import Layout from trezor.ui import Layout
from trezor.messages import ( from trezor.messages import (
DebugLinkDecision, DebugLinkDecision,

@ -3,13 +3,13 @@ import storage.device
from trezor import config, wire from trezor import config, wire
from trezor.crypto import bip39, slip39 from trezor.crypto import bip39, slip39
from trezor.enums import BackupType from trezor.enums import BackupType
from trezor.messages import Success from trezor.messages import LoadDevice, Success
from trezor.ui.layouts import confirm_action from trezor.ui.layouts import confirm_action
from apps.management import backup_types from apps.management import backup_types
async def load_device(ctx, msg): async def load_device(ctx: wire.Context, msg: LoadDevice) -> Success:
word_count = _validate(msg) word_count = _validate(msg)
is_slip39 = backup_types.is_slip39_word_count(word_count) is_slip39 = backup_types.is_slip39_word_count(word_count)
@ -42,7 +42,7 @@ async def load_device(ctx, msg):
needs_backup=msg.needs_backup is True, needs_backup=msg.needs_backup is True,
no_backup=msg.no_backup is True, no_backup=msg.no_backup is True,
) )
storage.device.set_passphrase_enabled(msg.passphrase_protection) storage.device.set_passphrase_enabled(bool(msg.passphrase_protection))
storage.device.set_label(msg.label or "") storage.device.set_label(msg.label or "")
if msg.pin: if msg.pin:
config.change_pin("", msg.pin, None, None) config.change_pin("", msg.pin, None, None)
@ -50,7 +50,7 @@ async def load_device(ctx, msg):
return Success(message="Device loaded") return Success(message="Device loaded")
def _validate(msg) -> int: def _validate(msg: LoadDevice) -> int:
if storage.device.is_initialized(): if storage.device.is_initialized():
raise wire.UnexpectedMessage("Already initialized") raise wire.UnexpectedMessage("Already initialized")
@ -67,7 +67,7 @@ def _validate(msg) -> int:
return word_count return word_count
async def _warn(ctx: wire.Context): async def _warn(ctx: wire.Context) -> None:
await confirm_action( await confirm_action(
ctx, ctx,
"warn_loading_seed", "warn_loading_seed",

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.messages import EosTxActionAck, EosTxActionRequest from trezor.messages import EosTxActionAck, EosTxActionRequest
from trezor.utils import HashWriter from trezor.utils import HashWriter
@ -5,7 +7,7 @@ from trezor.utils import HashWriter
from .. import helpers, writers from .. import helpers, writers
from . import layout from . import layout
if False: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from trezor.utils import Writer from trezor.utils import Writer
@ -22,44 +24,57 @@ async def process_action(
w = bytearray() w = bytearray()
if account == "eosio": if account == "eosio":
if name == "buyram": if name == "buyram":
assert action.buy_ram is not None # check_action
await layout.confirm_action_buyram(ctx, action.buy_ram) await layout.confirm_action_buyram(ctx, action.buy_ram)
writers.write_action_buyram(w, action.buy_ram) writers.write_action_buyram(w, action.buy_ram)
elif name == "buyrambytes": elif name == "buyrambytes":
assert action.buy_ram_bytes is not None # check_action
await layout.confirm_action_buyrambytes(ctx, action.buy_ram_bytes) await layout.confirm_action_buyrambytes(ctx, action.buy_ram_bytes)
writers.write_action_buyrambytes(w, action.buy_ram_bytes) writers.write_action_buyrambytes(w, action.buy_ram_bytes)
elif name == "sellram": elif name == "sellram":
assert action.sell_ram is not None # check_action
await layout.confirm_action_sellram(ctx, action.sell_ram) await layout.confirm_action_sellram(ctx, action.sell_ram)
writers.write_action_sellram(w, action.sell_ram) writers.write_action_sellram(w, action.sell_ram)
elif name == "delegatebw": elif name == "delegatebw":
assert action.delegate is not None # check_action
await layout.confirm_action_delegate(ctx, action.delegate) await layout.confirm_action_delegate(ctx, action.delegate)
writers.write_action_delegate(w, action.delegate) writers.write_action_delegate(w, action.delegate)
elif name == "undelegatebw": elif name == "undelegatebw":
assert action.undelegate is not None # check_action
await layout.confirm_action_undelegate(ctx, action.undelegate) await layout.confirm_action_undelegate(ctx, action.undelegate)
writers.write_action_undelegate(w, action.undelegate) writers.write_action_undelegate(w, action.undelegate)
elif name == "refund": elif name == "refund":
assert action.refund is not None # check_action
await layout.confirm_action_refund(ctx, action.refund) await layout.confirm_action_refund(ctx, action.refund)
writers.write_action_refund(w, action.refund) writers.write_action_refund(w, action.refund)
elif name == "voteproducer": elif name == "voteproducer":
assert action.vote_producer is not None # check_action
await layout.confirm_action_voteproducer(ctx, action.vote_producer) await layout.confirm_action_voteproducer(ctx, action.vote_producer)
writers.write_action_voteproducer(w, action.vote_producer) writers.write_action_voteproducer(w, action.vote_producer)
elif name == "updateauth": elif name == "updateauth":
assert action.update_auth is not None # check_action
await layout.confirm_action_updateauth(ctx, action.update_auth) await layout.confirm_action_updateauth(ctx, action.update_auth)
writers.write_action_updateauth(w, action.update_auth) writers.write_action_updateauth(w, action.update_auth)
elif name == "deleteauth": elif name == "deleteauth":
assert action.delete_auth is not None # check_action
await layout.confirm_action_deleteauth(ctx, action.delete_auth) await layout.confirm_action_deleteauth(ctx, action.delete_auth)
writers.write_action_deleteauth(w, action.delete_auth) writers.write_action_deleteauth(w, action.delete_auth)
elif name == "linkauth": elif name == "linkauth":
assert action.link_auth is not None # check_action
await layout.confirm_action_linkauth(ctx, action.link_auth) await layout.confirm_action_linkauth(ctx, action.link_auth)
writers.write_action_linkauth(w, action.link_auth) writers.write_action_linkauth(w, action.link_auth)
elif name == "unlinkauth": elif name == "unlinkauth":
assert action.unlink_auth is not None # check_action
await layout.confirm_action_unlinkauth(ctx, action.unlink_auth) await layout.confirm_action_unlinkauth(ctx, action.unlink_auth)
writers.write_action_unlinkauth(w, action.unlink_auth) writers.write_action_unlinkauth(w, action.unlink_auth)
elif name == "newaccount": elif name == "newaccount":
assert action.new_account is not None # check_action
await layout.confirm_action_newaccount(ctx, action.new_account) await layout.confirm_action_newaccount(ctx, action.new_account)
writers.write_action_newaccount(w, action.new_account) writers.write_action_newaccount(w, action.new_account)
else: else:
raise ValueError("Unrecognized action type for eosio") raise ValueError("Unrecognized action type for eosio")
elif name == "transfer": elif name == "transfer":
assert action.transfer is not None # check_action
await layout.confirm_action_transfer(ctx, action.transfer, account) await layout.confirm_action_transfer(ctx, action.transfer, account)
writers.write_action_transfer(w, action.transfer) writers.write_action_transfer(w, action.transfer)
else: else:
@ -72,6 +87,7 @@ async def process_action(
async def process_unknown_action( async def process_unknown_action(
ctx: wire.Context, w: Writer, action: EosTxActionAck ctx: wire.Context, w: Writer, action: EosTxActionAck
) -> None: ) -> None:
assert action.unknown is not None
checksum = HashWriter(sha256()) checksum = HashWriter(sha256())
writers.write_uvarint(checksum, action.unknown.data_size) writers.write_uvarint(checksum, action.unknown.data_size)
checksum.extend(action.unknown.data_chunk) checksum.extend(action.unknown.data_chunk)

@ -1,11 +1,12 @@
from trezor import ui from typing import TYPE_CHECKING
from trezor import ui, wire
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType
from trezor.ui.layouts import confirm_properties from trezor.ui.layouts import confirm_properties
from .. import helpers from .. import helpers
if False: if TYPE_CHECKING:
from trezor import wire
from trezor.messages import ( from trezor.messages import (
EosActionBuyRam, EosActionBuyRam,
EosActionBuyRamBytes, EosActionBuyRamBytes,
@ -23,6 +24,7 @@ if False:
EosActionVoteProducer, EosActionVoteProducer,
EosAuthorization, EosAuthorization,
) )
from trezor.ui.layouts import PropertyType
async def confirm_action_buyram(ctx: wire.Context, msg: EosActionBuyRam) -> None: async def confirm_action_buyram(ctx: wire.Context, msg: EosActionBuyRam) -> None:
@ -194,7 +196,7 @@ async def confirm_action_transfer(
async def confirm_action_updateauth( async def confirm_action_updateauth(
ctx: wire.Context, msg: EosActionUpdateAuth ctx: wire.Context, msg: EosActionUpdateAuth
) -> None: ) -> None:
props = [ props: list[PropertyType] = [
("Account:", helpers.eos_name_to_string(msg.account)), ("Account:", helpers.eos_name_to_string(msg.account)),
("Permission:", helpers.eos_name_to_string(msg.permission)), ("Permission:", helpers.eos_name_to_string(msg.permission)),
("Parent:", helpers.eos_name_to_string(msg.parent)), ("Parent:", helpers.eos_name_to_string(msg.parent)),
@ -262,7 +264,7 @@ async def confirm_action_unlinkauth(
async def confirm_action_newaccount( async def confirm_action_newaccount(
ctx: wire.Context, msg: EosActionNewAccount ctx: wire.Context, msg: EosActionNewAccount
) -> None: ) -> None:
props = [ props: list[PropertyType] = [
("Creator:", helpers.eos_name_to_string(msg.creator)), ("Creator:", helpers.eos_name_to_string(msg.creator)),
("Name:", helpers.eos_name_to_string(msg.name)), ("Name:", helpers.eos_name_to_string(msg.name)),
] ]
@ -296,11 +298,14 @@ async def confirm_action_unknown(
) )
def authorization_fields(auth: EosAuthorization) -> list[tuple[str, str | None]]: def authorization_fields(auth: EosAuthorization) -> list[PropertyType]:
fields = [] fields: list[PropertyType] = []
fields.append(("Threshold:", str(auth.threshold))) fields.append(("Threshold:", str(auth.threshold)))
for i, key in enumerate(auth.keys, 1): for i, key in enumerate(auth.keys, 1):
if key.key is None:
raise wire.DataError("Key must be provided explicitly.")
_key = helpers.public_key_to_wif(bytes(key.key)) _key = helpers.public_key_to_wif(bytes(key.key))
_weight = str(key.weight) _weight = str(key.weight)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.messages import EosGetPublicKey, EosPublicKey from trezor.messages import EosGetPublicKey, EosPublicKey
@ -8,7 +10,7 @@ from apps.common.keychain import Keychain, auto_keychain
from .helpers import public_key_to_wif from .helpers import public_key_to_wif
from .layout import require_get_public_key from .layout import require_get_public_key
if False: if TYPE_CHECKING:
from trezor.crypto import bip32 from trezor.crypto import bip32

@ -15,11 +15,7 @@ from .layout import require_sign_tx
@auto_keychain(__name__) @auto_keychain(__name__)
async def sign_tx(ctx: wire.Context, msg: EosSignTx, keychain: Keychain) -> EosSignedTx: async def sign_tx(ctx: wire.Context, msg: EosSignTx, keychain: Keychain) -> EosSignedTx:
if msg.chain_id is None: if not msg.num_actions:
raise wire.DataError("No chain id")
if msg.header is None:
raise wire.DataError("No header")
if msg.num_actions is None or msg.num_actions == 0:
raise wire.DataError("No actions") raise wire.DataError("No actions")
await paths.validate_path(ctx, keychain, msg.address_n) await paths.validate_path(ctx, keychain, msg.address_n)

@ -1,3 +1,7 @@
from typing import TYPE_CHECKING
from trezor import wire
from apps.common.writers import ( from apps.common.writers import (
write_bytes_fixed, write_bytes_fixed,
write_bytes_unchecked, write_bytes_unchecked,
@ -8,7 +12,7 @@ from apps.common.writers import (
write_uvarint, write_uvarint,
) )
if False: if TYPE_CHECKING:
from trezor.messages import ( from trezor.messages import (
EosActionBuyRam, EosActionBuyRam,
EosActionBuyRamBytes, EosActionBuyRamBytes,
@ -16,6 +20,7 @@ if False:
EosActionDelegate, EosActionDelegate,
EosActionDeleteAuth, EosActionDeleteAuth,
EosActionLinkAuth, EosActionLinkAuth,
EosActionUnlinkAuth,
EosActionNewAccount, EosActionNewAccount,
EosActionRefund, EosActionRefund,
EosActionSellRam, EosActionSellRam,
@ -34,6 +39,8 @@ def write_auth(w: Writer, auth: EosAuthorization) -> None:
write_uint32_le(w, auth.threshold) write_uint32_le(w, auth.threshold)
write_uvarint(w, len(auth.keys)) write_uvarint(w, len(auth.keys))
for key in auth.keys: for key in auth.keys:
if key.key is None:
raise wire.DataError("Key must be provided explicitly.")
write_uvarint(w, key.type) write_uvarint(w, key.type)
write_bytes_fixed(w, key.key, 33) write_bytes_fixed(w, key.key, 33)
write_uint16_le(w, key.weight) write_uint16_le(w, key.weight)
@ -63,7 +70,7 @@ def write_action_transfer(w: Writer, msg: EosActionTransfer) -> None:
write_uint64_le(w, msg.sender) write_uint64_le(w, msg.sender)
write_uint64_le(w, msg.receiver) write_uint64_le(w, msg.receiver)
write_asset(w, msg.quantity) write_asset(w, msg.quantity)
write_bytes_prefixed(w, msg.memo) write_bytes_prefixed(w, msg.memo.encode())
def write_action_buyram(w: Writer, msg: EosActionBuyRam) -> None: def write_action_buyram(w: Writer, msg: EosActionBuyRam) -> None:
@ -129,7 +136,7 @@ def write_action_linkauth(w: Writer, msg: EosActionLinkAuth) -> None:
write_uint64_le(w, msg.requirement) write_uint64_le(w, msg.requirement)
def write_action_unlinkauth(w: Writer, msg: EosActionLinkAuth) -> None: def write_action_unlinkauth(w: Writer, msg: EosActionUnlinkAuth) -> None:
write_uint64_le(w, msg.account) write_uint64_le(w, msg.account)
write_uint64_le(w, msg.code) write_uint64_le(w, msg.code)
write_uint64_le(w, msg.type) write_uint64_le(w, msg.type)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.messages import EthereumAddress from trezor.messages import EthereumAddress
from trezor.ui.layouts import show_address from trezor.ui.layouts import show_address
@ -7,7 +9,7 @@ from . import networks
from .helpers import address_from_bytes from .helpers import address_from_bytes
from .keychain import PATTERNS_ADDRESS, with_keychain_from_path from .keychain import PATTERNS_ADDRESS, with_keychain_from_path
if False: if TYPE_CHECKING:
from trezor.messages import EthereumGetAddress from trezor.messages import EthereumGetAddress
from trezor.wire import Context from trezor.wire import Context

@ -1,3 +1,4 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor.messages import EthereumPublicKey, HDNodeType from trezor.messages import EthereumPublicKey, HDNodeType
@ -7,7 +8,7 @@ from apps.common import coins, paths
from .keychain import with_keychain_from_path from .keychain import with_keychain_from_path
if False: if TYPE_CHECKING:
from trezor.messages import EthereumGetPublicKey from trezor.messages import EthereumGetPublicKey
from trezor.wire import Context from trezor.wire import Context

@ -1,10 +1,11 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify, unhexlify from ubinascii import hexlify, unhexlify
from trezor import wire from trezor import wire
from trezor.enums import EthereumDataType from trezor.enums import EthereumDataType
from trezor.messages import EthereumFieldType from trezor.messages import EthereumFieldType
if False: if TYPE_CHECKING:
from .networks import NetworkInfo from .networks import NetworkInfo

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from apps.common import paths from apps.common import paths
@ -5,7 +7,7 @@ from apps.common.keychain import get_keychain
from . import CURVE, networks from . import CURVE, networks
if False: if TYPE_CHECKING:
from typing import Callable, Iterable, TypeVar, Union from typing import Callable, Iterable, TypeVar, Union
from trezor.messages import ( from trezor.messages import (

@ -1,3 +1,4 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor import ui from trezor import ui
@ -17,8 +18,9 @@ from trezor.ui.layouts.tt.altcoin import confirm_total_ethereum
from . import networks, tokens from . import networks, tokens
from .helpers import address_from_bytes, decode_typed_data, get_type_name from .helpers import address_from_bytes, decode_typed_data, get_type_name
if False: if TYPE_CHECKING:
from typing import Awaitable, Iterable, Optional from typing import Awaitable, Iterable, Optional
from trezor.wire import Context from trezor.wire import Context

@ -1,11 +1,9 @@
# generated from networks.py.mako # generated from networks.py.mako
# do not edit manually! # do not edit manually!
from typing import Iterator
from apps.common.paths import HARDENED from apps.common.paths import HARDENED
if False:
from typing import Iterator
def shortcut_by_chain_id(chain_id: int) -> str: def shortcut_by_chain_id(chain_id: int) -> str:
n = by_chain_id(chain_id) n = by_chain_id(chain_id)

@ -1,11 +1,9 @@
# generated from networks.py.mako # generated from networks.py.mako
# do not edit manually! # do not edit manually!
from typing import Iterator
from apps.common.paths import HARDENED from apps.common.paths import HARDENED
if False:
from typing import Iterator
def shortcut_by_chain_id(chain_id: int) -> str: def shortcut_by_chain_id(chain_id: int) -> str:
n = by_chain_id(chain_id) n = by_chain_id(chain_id)

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha3_256 from trezor.crypto.hashlib import sha3_256
from trezor.messages import EthereumMessageSignature from trezor.messages import EthereumMessageSignature
@ -10,7 +12,7 @@ from apps.common.signverify import decode_message
from .helpers import address_from_bytes from .helpers import address_from_bytes
from .keychain import PATTERNS_ADDRESS, with_keychain_from_path from .keychain import PATTERNS_ADDRESS, with_keychain_from_path
if False: if TYPE_CHECKING:
from trezor.messages import EthereumSignMessage from trezor.messages import EthereumSignMessage
from trezor.wire import Context from trezor.wire import Context

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto import rlp from trezor.crypto import rlp
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
@ -17,7 +19,7 @@ from .layout import (
require_confirm_unknown_token, require_confirm_unknown_token,
) )
if False: if TYPE_CHECKING:
from typing import Tuple from typing import Tuple
from apps.common.keychain import Keychain from apps.common.keychain import Keychain

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto import rlp from trezor.crypto import rlp
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
@ -16,7 +18,7 @@ from .layout import (
) )
from .sign_tx import check_common_fields, handle_erc20, send_request_chunk from .sign_tx import check_common_fields, handle_erc20, send_request_chunk
if False: if TYPE_CHECKING:
from typing import Tuple from typing import Tuple
from trezor.messages import EthereumSignTxEIP1559 from trezor.messages import EthereumSignTxEIP1559

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha3_256 from trezor.crypto.hashlib import sha3_256
@ -25,7 +27,7 @@ from .layout import (
should_show_struct, should_show_struct,
) )
if False: if TYPE_CHECKING:
from apps.common.keychain import Keychain from apps.common.keychain import Keychain
from trezor.wire import Context from trezor.wire import Context

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from trezor import wire from trezor import wire
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha3_256 from trezor.crypto.hashlib import sha3_256
@ -9,7 +11,7 @@ from apps.common.signverify import decode_message
from .helpers import address_from_bytes, bytes_from_address from .helpers import address_from_bytes, bytes_from_address
from .sign_message import message_digest from .sign_message import message_digest
if False: if TYPE_CHECKING:
from trezor.messages import EthereumVerifyMessage from trezor.messages import EthereumVerifyMessage
from trezor.wire import Context from trezor.wire import Context

@ -1,3 +1,5 @@
from typing import Any
import storage.cache import storage.cache
import storage.device import storage.device
from trezor import res, ui from trezor import res, ui
@ -16,7 +18,7 @@ class HomescreenBase(ui.Layout):
"apps/homescreen/res/bg.toif" "apps/homescreen/res/bg.toif"
) )
async def __iter__(self) -> ui.ResultValue: async def __iter__(self) -> Any:
# We need to catch the ui.Cancelled exception that kills us, because that means # We need to catch the ui.Cancelled exception that kills us, because that means
# that we will need to draw on screen again after restart. # that we will need to draw on screen again after restart.
try: try:

@ -1,9 +1,11 @@
from typing import TYPE_CHECKING
import storage.device import storage.device
from storage.device import set_flags from storage.device import set_flags
from trezor import wire from trezor import wire
from trezor.messages import Success from trezor.messages import Success
if False: if TYPE_CHECKING:
from trezor.messages import ApplyFlags from trezor.messages import ApplyFlags

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage.device import storage.device
from trezor import ui, wire from trezor import ui, wire
from trezor.enums import ButtonRequestType, SafetyCheckLevel from trezor.enums import ButtonRequestType, SafetyCheckLevel
@ -8,7 +10,7 @@ from trezor.ui.layouts import confirm_action
from apps.base import reload_settings_from_storage from apps.base import reload_settings_from_storage
from apps.common import safety_checks from apps.common import safety_checks
if False: if TYPE_CHECKING:
from trezor.messages import ApplySettings from trezor.messages import ApplySettings

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage import storage
import storage.device import storage.device
from trezor import wire from trezor import wire
@ -7,7 +9,7 @@ from apps.common import mnemonic
from .reset_device import backup_seed, layout from .reset_device import backup_seed, layout
if False: if TYPE_CHECKING:
from trezor.messages import BackupDevice from trezor.messages import BackupDevice

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from storage.device import is_initialized from storage.device import is_initialized
from trezor import config, wire from trezor import config, wire
from trezor.messages import Success from trezor.messages import Success
@ -10,7 +12,7 @@ from apps.common.request_pin import (
request_pin_confirm, request_pin_confirm,
) )
if False: if TYPE_CHECKING:
from typing import Awaitable from typing import Awaitable
from trezor.messages import ChangePin from trezor.messages import ChangePin

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
from storage.device import is_initialized from storage.device import is_initialized
from trezor import config, ui, wire from trezor import config, ui, wire
from trezor.messages import Success from trezor.messages import Success
@ -9,7 +11,7 @@ from apps.common.request_pin import (
request_pin_and_sd_salt, request_pin_and_sd_salt,
) )
if False: if TYPE_CHECKING:
from typing import Awaitable from typing import Awaitable
from trezor.messages import ChangeWipeCode from trezor.messages import ChangeWipeCode

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage import storage
import storage.device import storage.device
import storage.recovery import storage.recovery
@ -14,7 +16,7 @@ from apps.common.request_pin import (
from .homescreen import recovery_homescreen, recovery_process from .homescreen import recovery_homescreen, recovery_process
if False: if TYPE_CHECKING:
from trezor.messages import RecoveryDevice from trezor.messages import RecoveryDevice

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage.recovery import storage.recovery
from trezor import ui, wire from trezor import ui, wire
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType
@ -15,7 +17,7 @@ from .. import backup_types
from . import word_validity from . import word_validity
from .recover import RecoveryAborted from .recover import RecoveryAborted
if False: if TYPE_CHECKING:
from typing import Callable from typing import Callable
from trezor.enums import BackupType from trezor.enums import BackupType

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage.recovery import storage.recovery
import storage.recovery_shares import storage.recovery_shares
from trezor.crypto import bip39, slip39 from trezor.crypto import bip39, slip39
@ -5,7 +7,7 @@ from trezor.errors import MnemonicError
from .. import backup_types from .. import backup_types
if False: if TYPE_CHECKING:
from trezor.enums import BackupType from trezor.enums import BackupType
from typing import Union from typing import Union
@ -91,7 +93,7 @@ def process_slip39(words: str) -> tuple[bytes | None, slip39.Share]:
return secret, share return secret, share
if False: if TYPE_CHECKING:
Slip39State = Union[tuple[int, BackupType], tuple[None, None]] Slip39State = Union[tuple[int, BackupType], tuple[None, None]]

@ -1,3 +1,5 @@
from typing import TYPE_CHECKING
import storage import storage
import storage.device import storage.device
from trezor import config, wire from trezor import config, wire
@ -14,7 +16,7 @@ from . import layout
if __debug__: if __debug__:
import storage.debug import storage.debug
if False: if TYPE_CHECKING:
from trezor.messages import ResetDevice from trezor.messages import ResetDevice
_DEFAULT_BACKUP_TYPE = BackupType.Bip39 _DEFAULT_BACKUP_TYPE = BackupType.Bip39

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save