refactor(cardano): use module imports for messages, layout

pull/2374/head
David Misiak 2 years ago committed by matejcik
parent 0836e91faa
commit 1ae6b68eaf

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import Any
from trezor import wire from trezor import messages, wire
from trezor.crypto import base58 from trezor.crypto import base58
from trezor.enums import CardanoAddressType from trezor.enums import CardanoAddressType
@ -10,15 +10,6 @@ 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 TYPE_CHECKING:
from typing import Any
from trezor.messages import (
CardanoAddressParametersType,
CardanoBlockchainPointerType,
)
from . import seed
ADDRESS_TYPES_SHELLEY = ( ADDRESS_TYPES_SHELLEY = (
CardanoAddressType.BASE, CardanoAddressType.BASE,
CardanoAddressType.BASE_SCRIPT_KEY, CardanoAddressType.BASE_SCRIPT_KEY,
@ -48,7 +39,9 @@ def assert_address_params_cond(condition: bool) -> None:
raise wire.ProcessError("Invalid address parameters") raise wire.ProcessError("Invalid address parameters")
def validate_address_parameters(parameters: CardanoAddressParametersType) -> None: def validate_address_parameters(
parameters: messages.CardanoAddressParametersType,
) -> None:
_validate_address_parameters_structure(parameters) _validate_address_parameters_structure(parameters)
if parameters.address_type == CardanoAddressType.BYRON: if parameters.address_type == CardanoAddressType.BYRON:
@ -102,7 +95,7 @@ def validate_address_parameters(parameters: CardanoAddressParametersType) -> Non
def _validate_address_parameters_structure( def _validate_address_parameters_structure(
parameters: CardanoAddressParametersType, parameters: messages.CardanoAddressParametersType,
) -> None: ) -> None:
address_n = parameters.address_n address_n = parameters.address_n
address_n_staking = parameters.address_n_staking address_n_staking = parameters.address_n_staking
@ -206,7 +199,7 @@ def _validate_script_hash(script_hash: bytes | None) -> None:
def validate_output_address_parameters( def validate_output_address_parameters(
parameters: CardanoAddressParametersType, parameters: messages.CardanoAddressParametersType,
) -> None: ) -> None:
validate_address_parameters(parameters) validate_address_parameters(parameters)
@ -338,7 +331,7 @@ def _get_address_network_id(address: bytes) -> int:
def derive_human_readable_address( def derive_human_readable_address(
keychain: seed.Keychain, keychain: seed.Keychain,
parameters: CardanoAddressParametersType, parameters: messages.CardanoAddressParametersType,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> str: ) -> str:
@ -364,7 +357,7 @@ def encode_human_readable_address(address_bytes: bytes) -> str:
def derive_address_bytes( def derive_address_bytes(
keychain: seed.Keychain, keychain: seed.Keychain,
parameters: CardanoAddressParametersType, parameters: messages.CardanoAddressParametersType,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> bytes: ) -> bytes:
@ -379,7 +372,9 @@ def derive_address_bytes(
def _derive_shelley_address( def _derive_shelley_address(
keychain: seed.Keychain, parameters: CardanoAddressParametersType, network_id: int keychain: seed.Keychain,
parameters: messages.CardanoAddressParametersType,
network_id: int,
) -> bytes: ) -> bytes:
header = _create_address_header(parameters.address_type, network_id) header = _create_address_header(parameters.address_type, network_id)
@ -394,8 +389,8 @@ def _create_address_header(address_type: CardanoAddressType, network_id: int) ->
return header.to_bytes(1, "little") return header.to_bytes(1, "little")
def _get_address_payment_part( def _get_payment_part(
keychain: seed.Keychain, parameters: CardanoAddressParametersType keychain: seed.Keychain, parameters: messages.CardanoAddressParametersType
) -> bytes: ) -> bytes:
if parameters.address_n: if parameters.address_n:
return get_public_key_hash(keychain, parameters.address_n) return get_public_key_hash(keychain, parameters.address_n)
@ -405,8 +400,8 @@ def _get_address_payment_part(
return bytes() return bytes()
def _get_address_staking_part( def _get_staking_part(
keychain: seed.Keychain, parameters: CardanoAddressParametersType keychain: seed.Keychain, parameters: messages.CardanoAddressParametersType
) -> bytes: ) -> bytes:
if parameters.staking_key_hash: if parameters.staking_key_hash:
return parameters.staking_key_hash return parameters.staking_key_hash
@ -420,7 +415,9 @@ def _get_address_staking_part(
return bytes() return bytes()
def _encode_certificate_pointer(pointer: CardanoBlockchainPointerType) -> bytes: def _encode_certificate_pointer(
pointer: messages.CardanoBlockchainPointerType,
) -> bytes:
block_index_encoded = variable_length_encode(pointer.block_index) block_index_encoded = variable_length_encode(pointer.block_index)
tx_index_encoded = variable_length_encode(pointer.tx_index) tx_index_encoded = variable_length_encode(pointer.tx_index)
certificate_index_encoded = variable_length_encode(pointer.certificate_index) certificate_index_encoded = variable_length_encode(pointer.certificate_index)

@ -1,10 +1,9 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import wire from trezor import messages, wire
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
from trezor.messages import CardanoTxAuxiliaryDataSupplement
from apps.common import cbor from apps.common import cbor
@ -20,11 +19,6 @@ 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 TYPE_CHECKING: if TYPE_CHECKING:
from trezor.messages import (
CardanoCatalystRegistrationParametersType,
CardanoTxAuxiliaryData,
)
CatalystRegistrationPayload = dict[int, bytes | int] CatalystRegistrationPayload = dict[int, bytes | int]
SignedCatalystRegistrationPayload = tuple[CatalystRegistrationPayload, bytes] SignedCatalystRegistrationPayload = tuple[CatalystRegistrationPayload, bytes]
CatalystRegistrationSignature = dict[int, bytes] CatalystRegistrationSignature = dict[int, bytes]
@ -42,7 +36,7 @@ METADATA_KEY_CATALYST_REGISTRATION = 61284
METADATA_KEY_CATALYST_REGISTRATION_SIGNATURE = 61285 METADATA_KEY_CATALYST_REGISTRATION_SIGNATURE = 61285
def validate_auxiliary_data(auxiliary_data: CardanoTxAuxiliaryData) -> None: def validate(auxiliary_data: messages.CardanoTxAuxiliaryData) -> None:
fields_provided = 0 fields_provided = 0
if auxiliary_data.hash: if auxiliary_data.hash:
fields_provided += 1 fields_provided += 1
@ -63,7 +57,7 @@ def _validate_auxiliary_data_hash(auxiliary_data_hash: bytes) -> None:
def _validate_catalyst_registration_parameters( def _validate_catalyst_registration_parameters(
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType, catalyst_registration_parameters: messages.CardanoCatalystRegistrationParametersType,
) -> None: ) -> None:
if ( if (
len(catalyst_registration_parameters.voting_public_key) len(catalyst_registration_parameters.voting_public_key)
@ -87,7 +81,8 @@ async def show_auxiliary_data(
ctx: wire.Context, ctx: wire.Context,
keychain: seed.Keychain, keychain: seed.Keychain,
auxiliary_data_hash: bytes, auxiliary_data_hash: bytes,
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType | None, catalyst_registration_parameters: messages.CardanoCatalystRegistrationParametersType
| None,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> None: ) -> None:
@ -106,7 +101,7 @@ async def show_auxiliary_data(
async def _show_catalyst_registration( async def _show_catalyst_registration(
ctx: wire.Context, ctx: wire.Context,
keychain: seed.Keychain, keychain: seed.Keychain,
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType, catalyst_registration_parameters: messages.CardanoCatalystRegistrationParametersType,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> None: ) -> None:
@ -128,10 +123,10 @@ async def _show_catalyst_registration(
def get_auxiliary_data_hash_and_supplement( def get_auxiliary_data_hash_and_supplement(
keychain: seed.Keychain, keychain: seed.Keychain,
auxiliary_data: CardanoTxAuxiliaryData, auxiliary_data: messages.CardanoTxAuxiliaryData,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> tuple[bytes, CardanoTxAuxiliaryDataSupplement]: ) -> tuple[bytes, messages.CardanoTxAuxiliaryDataSupplement]:
if parameters := auxiliary_data.catalyst_registration_parameters: if parameters := auxiliary_data.catalyst_registration_parameters:
( (
catalyst_registration_payload, catalyst_registration_payload,
@ -142,7 +137,7 @@ def get_auxiliary_data_hash_and_supplement(
auxiliary_data_hash = _get_catalyst_registration_auxiliary_data_hash( auxiliary_data_hash = _get_catalyst_registration_auxiliary_data_hash(
catalyst_registration_payload, catalyst_signature catalyst_registration_payload, catalyst_signature
) )
auxiliary_data_supplement = CardanoTxAuxiliaryDataSupplement( auxiliary_data_supplement = messages.CardanoTxAuxiliaryDataSupplement(
type=CardanoTxAuxiliaryDataSupplementType.CATALYST_REGISTRATION_SIGNATURE, type=CardanoTxAuxiliaryDataSupplementType.CATALYST_REGISTRATION_SIGNATURE,
auxiliary_data_hash=auxiliary_data_hash, auxiliary_data_hash=auxiliary_data_hash,
catalyst_signature=catalyst_signature, catalyst_signature=catalyst_signature,
@ -150,7 +145,7 @@ def get_auxiliary_data_hash_and_supplement(
return auxiliary_data_hash, auxiliary_data_supplement return auxiliary_data_hash, auxiliary_data_supplement
else: else:
assert auxiliary_data.hash is not None # validate_auxiliary_data assert auxiliary_data.hash is not None # validate_auxiliary_data
return auxiliary_data.hash, CardanoTxAuxiliaryDataSupplement( return auxiliary_data.hash, messages.CardanoTxAuxiliaryDataSupplement(
type=CardanoTxAuxiliaryDataSupplementType.NONE type=CardanoTxAuxiliaryDataSupplementType.NONE
) )
@ -182,7 +177,7 @@ def _cborize_catalyst_registration(
def _get_signed_catalyst_registration_payload( def _get_signed_catalyst_registration_payload(
keychain: seed.Keychain, keychain: seed.Keychain,
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType, catalyst_registration_parameters: messages.CardanoCatalystRegistrationParametersType,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> SignedCatalystRegistrationPayload: ) -> SignedCatalystRegistrationPayload:

@ -13,14 +13,7 @@ from .helpers.utils import get_public_key_hash, validate_stake_credential
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
from trezor.messages import ( from trezor import messages
CardanoPoolMetadataType,
CardanoPoolOwner,
CardanoPoolParametersType,
CardanoPoolRelayParameters,
CardanoTxCertificate,
)
from apps.common.cbor import CborSequence from apps.common.cbor import CborSequence
from . import seed from . import seed
@ -37,7 +30,7 @@ MAX_PORT_NUMBER = 65535
def validate_certificate( def validate_certificate(
certificate: CardanoTxCertificate, certificate: messages.CardanoTxCertificate,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
account_path_checker: AccountPathChecker, account_path_checker: AccountPathChecker,
@ -70,7 +63,7 @@ def validate_certificate(
account_path_checker.add_certificate(certificate) account_path_checker.add_certificate(certificate)
def _validate_certificate_structure(certificate: CardanoTxCertificate) -> None: def _validate_certificate_structure(certificate: messages.CardanoTxCertificate) -> None:
pool = certificate.pool pool = certificate.pool
pool_parameters = certificate.pool_parameters pool_parameters = certificate.pool_parameters
@ -93,7 +86,7 @@ def _validate_certificate_structure(certificate: CardanoTxCertificate) -> None:
def cborize_certificate( def cborize_certificate(
keychain: seed.Keychain, certificate: CardanoTxCertificate keychain: seed.Keychain, certificate: messages.CardanoTxCertificate
) -> CborSequence: ) -> CborSequence:
if certificate.type in ( if certificate.type in (
CardanoCertificateType.STAKE_REGISTRATION, CardanoCertificateType.STAKE_REGISTRATION,
@ -140,7 +133,7 @@ def cborize_certificate_stake_credential(
def cborize_initial_pool_registration_certificate_fields( def cborize_initial_pool_registration_certificate_fields(
certificate: CardanoTxCertificate, certificate: messages.CardanoTxCertificate,
) -> CborSequence: ) -> CborSequence:
assert certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION assert certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION
@ -172,7 +165,9 @@ def assert_certificate_cond(condition: bool) -> None:
def _validate_pool_parameters( def _validate_pool_parameters(
pool_parameters: CardanoPoolParametersType, protocol_magic: int, network_id: int pool_parameters: messages.CardanoPoolParametersType,
protocol_magic: int,
network_id: int,
) -> None: ) -> None:
assert_certificate_cond(len(pool_parameters.pool_id) == POOL_HASH_SIZE) assert_certificate_cond(len(pool_parameters.pool_id) == POOL_HASH_SIZE)
assert_certificate_cond(len(pool_parameters.vrf_key_hash) == VRF_KEY_HASH_SIZE) assert_certificate_cond(len(pool_parameters.vrf_key_hash) == VRF_KEY_HASH_SIZE)
@ -192,7 +187,7 @@ def _validate_pool_parameters(
def validate_pool_owner( def validate_pool_owner(
owner: CardanoPoolOwner, account_path_checker: AccountPathChecker owner: messages.CardanoPoolOwner, account_path_checker: AccountPathChecker
) -> None: ) -> None:
assert_certificate_cond( assert_certificate_cond(
owner.staking_key_hash is not None or owner.staking_key_path is not None owner.staking_key_hash is not None or owner.staking_key_path is not None
@ -207,7 +202,7 @@ def validate_pool_owner(
account_path_checker.add_pool_owner(owner) account_path_checker.add_pool_owner(owner)
def validate_pool_relay(pool_relay: CardanoPoolRelayParameters) -> None: def validate_pool_relay(pool_relay: messages.CardanoPoolRelayParameters) -> None:
if pool_relay.type == CardanoPoolRelayType.SINGLE_HOST_IP: if pool_relay.type == CardanoPoolRelayType.SINGLE_HOST_IP:
assert_certificate_cond( assert_certificate_cond(
pool_relay.ipv4_address is not None or pool_relay.ipv6_address is not None pool_relay.ipv4_address is not None or pool_relay.ipv6_address is not None
@ -236,13 +231,15 @@ def validate_pool_relay(pool_relay: CardanoPoolRelayParameters) -> None:
raise RuntimeError # should be unreachable raise RuntimeError # should be unreachable
def _validate_pool_metadata(pool_metadata: CardanoPoolMetadataType) -> None: def _validate_pool_metadata(pool_metadata: messages.CardanoPoolMetadataType) -> None:
assert_certificate_cond(len(pool_metadata.url) <= MAX_URL_LENGTH) assert_certificate_cond(len(pool_metadata.url) <= MAX_URL_LENGTH)
assert_certificate_cond(len(pool_metadata.hash) == POOL_METADATA_HASH_SIZE) assert_certificate_cond(len(pool_metadata.hash) == POOL_METADATA_HASH_SIZE)
assert_certificate_cond(all((32 <= ord(c) < 127) for c in pool_metadata.url)) assert_certificate_cond(all((32 <= ord(c) < 127) for c in pool_metadata.url))
def cborize_pool_owner(keychain: seed.Keychain, pool_owner: CardanoPoolOwner) -> bytes: def cborize_pool_owner(
keychain: seed.Keychain, pool_owner: messages.CardanoPoolOwner
) -> bytes:
if pool_owner.staking_key_path: if pool_owner.staking_key_path:
return get_public_key_hash(keychain, pool_owner.staking_key_path) return get_public_key_hash(keychain, pool_owner.staking_key_path)
elif pool_owner.staking_key_hash: elif pool_owner.staking_key_hash:
@ -266,7 +263,7 @@ def _cborize_ipv6_address(ipv6_address: bytes | None) -> bytes | None:
def cborize_pool_relay( def cborize_pool_relay(
pool_relay: CardanoPoolRelayParameters, pool_relay: messages.CardanoPoolRelayParameters,
) -> CborSequence: ) -> CborSequence:
if pool_relay.type == CardanoPoolRelayType.SINGLE_HOST_IP: if pool_relay.type == CardanoPoolRelayType.SINGLE_HOST_IP:
return ( return (
@ -291,7 +288,7 @@ def cborize_pool_relay(
def cborize_pool_metadata( def cborize_pool_metadata(
pool_metadata: CardanoPoolMetadataType | None, pool_metadata: messages.CardanoPoolMetadataType | None,
) -> CborSequence | None: ) -> CborSequence | None:
if not pool_metadata: if not pool_metadata:
return None return None

@ -1,7 +1,4 @@
from typing import TYPE_CHECKING from trezor import log, messages, wire
from trezor import log, wire
from trezor.messages import CardanoAddress
from . import seed from . import seed
from .address import derive_human_readable_address, validate_address_parameters from .address import derive_human_readable_address, validate_address_parameters
@ -9,17 +6,11 @@ from .helpers.credential import Credential, should_show_address_credentials
from .helpers.utils import validate_network_info from .helpers.utils import validate_network_info
from .layout import show_address_credentials, show_cardano_address from .layout import show_address_credentials, show_cardano_address
if TYPE_CHECKING:
from trezor.messages import (
CardanoAddressParametersType,
CardanoGetAddress,
)
@seed.with_keychain @seed.with_keychain
async def get_address( async def get_address(
ctx: wire.Context, msg: CardanoGetAddress, keychain: seed.Keychain ctx: wire.Context, msg: messages.CardanoGetAddress, keychain: seed.Keychain
) -> CardanoAddress: ) -> messages.CardanoAddress:
address_parameters = msg.address_parameters address_parameters = msg.address_parameters
validate_network_info(msg.network_id, msg.protocol_magic) validate_network_info(msg.network_id, msg.protocol_magic)
@ -37,12 +28,12 @@ async def get_address(
if msg.show_display: if msg.show_display:
await _display_address(ctx, address_parameters, address, msg.protocol_magic) await _display_address(ctx, address_parameters, address, msg.protocol_magic)
return CardanoAddress(address=address) return messages.CardanoAddress(address=address)
async def _display_address( async def _display_address(
ctx: wire.Context, ctx: wire.Context,
address_parameters: CardanoAddressParametersType, address_parameters: messages.CardanoAddressParametersType,
address: str, address: str,
protocol_magic: int, protocol_magic: int,
) -> None: ) -> None:

@ -1,26 +1,19 @@
from typing import TYPE_CHECKING from trezor import messages, wire
from trezor import wire
from trezor.enums import CardanoNativeScriptHashDisplayFormat from trezor.enums import CardanoNativeScriptHashDisplayFormat
from trezor.messages import CardanoNativeScriptHash
from . import native_script, seed
from .layout import show_native_script, show_script_hash
if TYPE_CHECKING: from . import layout, native_script, seed
from trezor.messages import CardanoGetNativeScriptHash
@seed.with_keychain @seed.with_keychain
async def get_native_script_hash( async def get_native_script_hash(
ctx: wire.Context, msg: CardanoGetNativeScriptHash, keychain: seed.Keychain ctx: wire.Context, msg: messages.CardanoGetNativeScriptHash, keychain: seed.Keychain
) -> CardanoNativeScriptHash: ) -> messages.CardanoNativeScriptHash:
native_script.validate_native_script(msg.script) native_script.validate_native_script(msg.script)
script_hash = native_script.get_native_script_hash(keychain, msg.script) script_hash = native_script.get_native_script_hash(keychain, msg.script)
if msg.display_format != CardanoNativeScriptHashDisplayFormat.HIDE: if msg.display_format != CardanoNativeScriptHashDisplayFormat.HIDE:
await show_native_script(ctx, msg.script) await layout.show_native_script(ctx, msg.script)
await show_script_hash(ctx, script_hash, msg.display_format) await layout.show_script_hash(ctx, script_hash, msg.display_format)
return CardanoNativeScriptHash(script_hash=script_hash) return messages.CardanoNativeScriptHash(script_hash=script_hash)

@ -1,8 +1,6 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify from ubinascii import hexlify
from trezor import log, wire from trezor import log, messages, wire
from trezor.messages import CardanoPublicKey, HDNodeType
from trezor.ui.layouts import show_pubkey from trezor.ui.layouts import show_pubkey
from apps.common import paths from apps.common import paths
@ -11,14 +9,11 @@ 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 TYPE_CHECKING:
from trezor.messages import CardanoGetPublicKey
@seed.with_keychain @seed.with_keychain
async def get_public_key( async def get_public_key(
ctx: wire.Context, msg: CardanoGetPublicKey, keychain: seed.Keychain ctx: wire.Context, msg: messages.CardanoGetPublicKey, keychain: seed.Keychain
) -> CardanoPublicKey: ) -> messages.CardanoPublicKey:
await paths.validate_path( await paths.validate_path(
ctx, ctx,
keychain, keychain,
@ -41,14 +36,14 @@ async def get_public_key(
def _get_public_key( def _get_public_key(
keychain: seed.Keychain, derivation_path: list[int] keychain: seed.Keychain, derivation_path: list[int]
) -> CardanoPublicKey: ) -> messages.CardanoPublicKey:
node = keychain.derive(derivation_path) node = keychain.derive(derivation_path)
public_key = hexlify(derive_public_key(keychain, derivation_path)).decode() public_key = hexlify(derive_public_key(keychain, derivation_path)).decode()
chain_code = hexlify(node.chain_code()).decode() chain_code = hexlify(node.chain_code()).decode()
xpub_key = public_key + chain_code xpub_key = public_key + chain_code
node_type = HDNodeType( node_type = messages.HDNodeType(
depth=node.depth(), depth=node.depth(),
child_num=node.child_num(), child_num=node.child_num(),
fingerprint=node.fingerprint(), fingerprint=node.fingerprint(),
@ -56,4 +51,4 @@ def _get_public_key(
public_key=derive_public_key(keychain, derivation_path), public_key=derive_public_key(keychain, derivation_path),
) )
return CardanoPublicKey(node=node_type, xpub=xpub_key) return messages.CardanoPublicKey(node=node_type, xpub=xpub_key)

@ -7,10 +7,7 @@ from .paths import CHAIN_STAKING_KEY, SCHEMA_PAYMENT, SCHEMA_STAKING
from .utils import bech32, to_account_path from .utils import bech32, to_account_path
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.messages import ( from trezor import messages
CardanoBlockchainPointerType,
CardanoAddressParametersType,
)
from trezor.ui.layouts import PropertyType from trezor.ui.layouts import PropertyType
CREDENTIAL_TYPE_PAYMENT: str = "payment" CREDENTIAL_TYPE_PAYMENT: str = "payment"
@ -30,7 +27,7 @@ class Credential:
path: list[int] path: list[int]
key_hash: bytes | None key_hash: bytes | None
script_hash: bytes | None script_hash: bytes | None
pointer: CardanoBlockchainPointerType | None pointer: messages.CardanoBlockchainPointerType | None
is_reward: bool = False is_reward: bool = False
is_no_staking: bool = False is_no_staking: bool = False
@ -45,7 +42,7 @@ class Credential:
path: list[int], path: list[int],
key_hash: bytes | None, key_hash: bytes | None,
script_hash: bytes | None, script_hash: bytes | None,
pointer: CardanoBlockchainPointerType | None, pointer: messages.CardanoBlockchainPointerType | None,
): ):
self.type_name = type_name self.type_name = type_name
self.address_type = address_type self.address_type = address_type
@ -56,7 +53,7 @@ class Credential:
@classmethod @classmethod
def payment_credential( def payment_credential(
cls, address_params: CardanoAddressParametersType cls, address_params: messages.CardanoAddressParametersType
) -> "Credential": ) -> "Credential":
address_type = address_params.address_type address_type = address_params.address_type
credential = cls( credential = cls(
@ -99,7 +96,7 @@ class Credential:
@classmethod @classmethod
def stake_credential( def stake_credential(
cls, address_params: CardanoAddressParametersType cls, address_params: messages.CardanoAddressParametersType
) -> "Credential": ) -> "Credential":
address_type = address_params.address_type address_type = address_params.address_type
credential = cls( credential = cls(
@ -207,7 +204,7 @@ class Credential:
def should_show_address_credentials( def should_show_address_credentials(
address_parameters: CardanoAddressParametersType, address_parameters: messages.CardanoAddressParametersType,
) -> bool: ) -> bool:
return not ( return not (
address_parameters.address_type == CardanoAddressType.BASE address_parameters.address_type == CardanoAddressType.BASE

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import ui from trezor import messages, ui
from trezor.enums import ( from trezor.enums import (
ButtonRequestType, ButtonRequestType,
CardanoAddressType, CardanoAddressType,
@ -8,7 +8,6 @@ from trezor.enums import (
CardanoNativeScriptHashDisplayFormat, CardanoNativeScriptHashDisplayFormat,
CardanoNativeScriptType, CardanoNativeScriptType,
) )
from trezor.messages import CardanoAddressParametersType
from trezor.strings import format_amount from trezor.strings import format_amount
from trezor.ui.layouts import ( from trezor.ui.layouts import (
confirm_blob, confirm_blob,
@ -36,18 +35,6 @@ from .seed import is_minting_path, is_multisig_path
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor import wire from trezor import wire
from trezor.messages import (
CardanoNativeScript,
CardanoTxCertificate,
CardanoTxCollateralInput,
CardanoTxInput,
CardanoTxRequiredSigner,
CardanoTxWithdrawal,
CardanoPoolParametersType,
CardanoPoolOwner,
CardanoPoolMetadataType,
CardanoToken,
)
from trezor.ui.layouts import PropertyType from trezor.ui.layouts import PropertyType
from .helpers.credential import Credential from .helpers.credential import Credential
@ -95,7 +82,7 @@ def is_printable_ascii_bytestring(bytestr: bytes) -> bool:
async def show_native_script( async def show_native_script(
ctx: wire.Context, ctx: wire.Context,
script: CardanoNativeScript, script: messages.CardanoNativeScript,
indices: list[int] | None = None, indices: list[int] | None = None,
) -> None: ) -> None:
script_heading = "Script" script_heading = "Script"
@ -213,7 +200,7 @@ async def show_plutus_transaction(ctx: wire.Context) -> None:
) )
async def confirm_input(ctx: wire.Context, input: CardanoTxInput) -> None: async def confirm_input(ctx: wire.Context, input: messages.CardanoTxInput) -> None:
await confirm_properties( await confirm_properties(
ctx, ctx,
"confirm_input", "confirm_input",
@ -249,7 +236,7 @@ async def confirm_sending(
async def confirm_sending_token( async def confirm_sending_token(
ctx: wire.Context, policy_id: bytes, token: CardanoToken ctx: wire.Context, policy_id: bytes, token: messages.CardanoToken
) -> None: ) -> None:
assert token.amount is not None # _validate_token assert token.amount is not None # _validate_token
@ -490,7 +477,7 @@ async def confirm_transaction(
async def confirm_certificate( async def confirm_certificate(
ctx: wire.Context, certificate: CardanoTxCertificate ctx: wire.Context, certificate: messages.CardanoTxCertificate
) -> None: ) -> None:
# stake pool registration requires custom confirmation logic not covered # stake pool registration requires custom confirmation logic not covered
# in this call # in this call
@ -517,7 +504,9 @@ async def confirm_certificate(
async def confirm_stake_pool_parameters( async def confirm_stake_pool_parameters(
ctx: wire.Context, pool_parameters: CardanoPoolParametersType, network_id: int ctx: wire.Context,
pool_parameters: messages.CardanoPoolParametersType,
network_id: int,
) -> None: ) -> None:
margin_percentage = ( margin_percentage = (
100.0 * pool_parameters.margin_numerator / pool_parameters.margin_denominator 100.0 * pool_parameters.margin_numerator / pool_parameters.margin_denominator
@ -547,7 +536,7 @@ async def confirm_stake_pool_parameters(
async def confirm_stake_pool_owner( async def confirm_stake_pool_owner(
ctx: wire.Context, ctx: wire.Context,
keychain: seed.Keychain, keychain: seed.Keychain,
owner: CardanoPoolOwner, owner: messages.CardanoPoolOwner,
protocol_magic: int, protocol_magic: int,
network_id: int, network_id: int,
) -> None: ) -> None:
@ -558,7 +547,7 @@ async def confirm_stake_pool_owner(
( (
derive_human_readable_address( derive_human_readable_address(
keychain, keychain,
CardanoAddressParametersType( messages.CardanoAddressParametersType(
address_type=CardanoAddressType.REWARD, address_type=CardanoAddressType.REWARD,
address_n=owner.staking_key_path, address_n=owner.staking_key_path,
), ),
@ -575,7 +564,7 @@ async def confirm_stake_pool_owner(
"Pool owner:", "Pool owner:",
derive_human_readable_address( derive_human_readable_address(
keychain, keychain,
CardanoAddressParametersType( messages.CardanoAddressParametersType(
address_type=CardanoAddressType.REWARD, address_type=CardanoAddressType.REWARD,
staking_key_hash=owner.staking_key_hash, staking_key_hash=owner.staking_key_hash,
), ),
@ -596,7 +585,7 @@ async def confirm_stake_pool_owner(
async def confirm_stake_pool_metadata( async def confirm_stake_pool_metadata(
ctx: wire.Context, ctx: wire.Context,
metadata: CardanoPoolMetadataType | None, metadata: messages.CardanoPoolMetadataType | None,
) -> None: ) -> None:
if metadata is None: if metadata is None:
await confirm_properties( await confirm_properties(
@ -643,7 +632,7 @@ async def confirm_stake_pool_registration_final(
async def confirm_withdrawal( async def confirm_withdrawal(
ctx: wire.Context, ctx: wire.Context,
withdrawal: CardanoTxWithdrawal, withdrawal: messages.CardanoTxWithdrawal,
reward_address_bytes: bytes, reward_address_bytes: bytes,
network_id: int, network_id: int,
) -> None: ) -> None:
@ -726,7 +715,7 @@ async def show_auxiliary_data_hash(
async def confirm_token_minting( async def confirm_token_minting(
ctx: wire.Context, policy_id: bytes, token: CardanoToken ctx: wire.Context, policy_id: bytes, token: messages.CardanoToken
) -> None: ) -> None:
assert token.mint_amount is not None # _validate_token assert token.mint_amount is not None # _validate_token
await confirm_properties( await confirm_properties(
@ -777,7 +766,7 @@ async def confirm_script_data_hash(ctx: wire.Context, script_data_hash: bytes) -
async def confirm_collateral_input( async def confirm_collateral_input(
ctx: wire.Context, collateral_input: CardanoTxCollateralInput ctx: wire.Context, collateral_input: messages.CardanoTxCollateralInput
) -> None: ) -> None:
await confirm_properties( await confirm_properties(
ctx, ctx,
@ -792,7 +781,7 @@ async def confirm_collateral_input(
async def confirm_required_signer( async def confirm_required_signer(
ctx: wire.Context, required_signer: CardanoTxRequiredSigner ctx: wire.Context, required_signer: messages.CardanoTxRequiredSigner
) -> None: ) -> None:
assert ( assert (
required_signer.key_hash is not None or required_signer.key_path required_signer.key_hash is not None or required_signer.key_path
@ -814,7 +803,7 @@ async def confirm_required_signer(
async def show_cardano_address( async def show_cardano_address(
ctx: wire.Context, ctx: wire.Context,
address_parameters: CardanoAddressParametersType, address_parameters: messages.CardanoAddressParametersType,
address: str, address: str,
protocol_magic: int, protocol_magic: int,
) -> None: ) -> None:

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import wire from trezor import messages, wire
from trezor.crypto import hashlib from trezor.crypto import hashlib
from trezor.enums import CardanoNativeScriptType from trezor.enums import CardanoNativeScriptType
@ -14,12 +14,10 @@ from .seed import Keychain, is_multisig_path
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
from trezor.messages import CardanoNativeScript
from apps.common.cbor import CborSequence from apps.common.cbor import CborSequence
def validate_native_script(script: CardanoNativeScript | None) -> None: def validate_native_script(script: messages.CardanoNativeScript | None) -> None:
INVALID_NATIVE_SCRIPT = wire.ProcessError("Invalid native script") INVALID_NATIVE_SCRIPT = wire.ProcessError("Invalid native script")
if not script: if not script:
@ -61,7 +59,7 @@ def validate_native_script(script: CardanoNativeScript | None) -> None:
raise INVALID_NATIVE_SCRIPT raise INVALID_NATIVE_SCRIPT
def _validate_native_script_structure(script: CardanoNativeScript) -> None: def _validate_native_script_structure(script: messages.CardanoNativeScript) -> None:
key_hash = script.key_hash key_hash = script.key_hash
key_path = script.key_path key_path = script.key_path
scripts = script.scripts scripts = script.scripts
@ -114,14 +112,16 @@ def _validate_native_script_structure(script: CardanoNativeScript) -> None:
raise wire.ProcessError("Invalid native script") raise wire.ProcessError("Invalid native script")
def get_native_script_hash(keychain: Keychain, script: CardanoNativeScript) -> bytes: def get_native_script_hash(
keychain: seed.Keychain, script: messages.CardanoNativeScript
) -> bytes:
script_cbor = cbor.encode(cborize_native_script(keychain, script)) script_cbor = cbor.encode(cborize_native_script(keychain, script))
prefixed_script_cbor = b"\00" + script_cbor prefixed_script_cbor = b"\00" + script_cbor
return hashlib.blake2b(data=prefixed_script_cbor, outlen=SCRIPT_HASH_SIZE).digest() return hashlib.blake2b(data=prefixed_script_cbor, outlen=SCRIPT_HASH_SIZE).digest()
def cborize_native_script( def cborize_native_script(
keychain: Keychain, script: CardanoNativeScript keychain: seed.Keychain, script: messages.CardanoNativeScript
) -> CborSequence: ) -> CborSequence:
script_content: CborSequence script_content: CborSequence
if script.type == CardanoNativeScriptType.PUB_KEY: if script.type == CardanoNativeScriptType.PUB_KEY:

@ -16,18 +16,13 @@ if TYPE_CHECKING:
from apps.common.paths import Bip32Path from apps.common.paths import Bip32Path
from apps.common.keychain import MsgOut, Handler from apps.common.keychain import MsgOut, Handler
from trezor.messages import ( from trezor import messages
CardanoGetAddress,
CardanoGetPublicKey,
CardanoGetNativeScriptHash,
CardanoSignTxInit,
)
CardanoMessages = ( CardanoMessages = (
CardanoGetAddress messages.CardanoGetAddress
| CardanoGetPublicKey | messages.CardanoGetPublicKey
| CardanoGetNativeScriptHash | messages.CardanoGetNativeScriptHash
| CardanoSignTxInit | messages.CardanoSignTxInit
) )
MsgIn = TypeVar("MsgIn", bound=CardanoMessages) MsgIn = TypeVar("MsgIn", bound=CardanoMessages)

@ -1,8 +1,7 @@
from typing import Type from typing import Type
from trezor import log, wire from trezor import log, messages, wire
from trezor.enums import CardanoTxSigningMode from trezor.enums import CardanoTxSigningMode
from trezor.messages import CardanoSignTxFinished, CardanoSignTxInit
from .. import seed from .. import seed
from .signer import Signer from .signer import Signer
@ -41,4 +40,4 @@ async def sign_tx(
log.exception(__name__, e) log.exception(__name__, e)
raise wire.ProcessError("Signing failed") raise wire.ProcessError("Signing failed")
return CardanoSignTxFinished() return messages.CardanoSignTxFinished()

@ -1,16 +1,8 @@
from trezor import wire from trezor import messages, wire
from trezor.enums import CardanoCertificateType from trezor.enums import CardanoCertificateType
from trezor.messages import (
CardanoSignTxInit,
CardanoTxCertificate,
CardanoTxOutput,
CardanoTxWithdrawal,
CardanoTxWitnessRequest,
)
from .. import seed from .. import layout, seed
from ..helpers.paths import SCHEMA_MINT from ..helpers.paths import SCHEMA_MINT
from ..layout import show_multisig_transaction
from ..seed import is_multisig_path from ..seed import is_multisig_path
from .signer import Signer from .signer import Signer
@ -21,7 +13,10 @@ class MultisigSigner(Signer):
""" """
def __init__( def __init__(
self, ctx: wire.Context, msg: CardanoSignTxInit, keychain: seed.Keychain self,
ctx: wire.Context,
msg: messages.CardanoSignTxInit,
keychain: seed.Keychain,
) -> None: ) -> None:
super().__init__(ctx, msg, keychain) super().__init__(ctx, msg, keychain)
@ -34,7 +29,7 @@ class MultisigSigner(Signer):
raise wire.ProcessError("Invalid tx signing request") raise wire.ProcessError("Invalid tx signing request")
async def _show_tx_signing_request(self) -> None: async def _show_tx_signing_request(self) -> None:
await show_multisig_transaction(self.ctx) await layout.show_multisig_transaction(self.ctx)
await super()._show_tx_signing_request() await super()._show_tx_signing_request()
async def _confirm_tx(self, tx_hash: bytes) -> None: async def _confirm_tx(self, tx_hash: bytes) -> None:
@ -56,20 +51,20 @@ class MultisigSigner(Signer):
if output.address_parameters is not None: if output.address_parameters is not None:
raise wire.ProcessError("Invalid output") raise wire.ProcessError("Invalid output")
def _validate_certificate(self, certificate: CardanoTxCertificate) -> None: def _validate_certificate(self, certificate: messages.CardanoTxCertificate) -> None:
super()._validate_certificate(certificate) super()._validate_certificate(certificate)
if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION: if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION:
raise wire.ProcessError("Invalid certificate") raise wire.ProcessError("Invalid certificate")
if certificate.path or certificate.key_hash: if certificate.path or certificate.key_hash:
raise wire.ProcessError("Invalid certificate") raise wire.ProcessError("Invalid certificate")
def _validate_withdrawal(self, withdrawal: CardanoTxWithdrawal) -> None: def _validate_withdrawal(self, withdrawal: messages.CardanoTxWithdrawal) -> None:
super()._validate_withdrawal(withdrawal) super()._validate_withdrawal(withdrawal)
if withdrawal.path or withdrawal.key_hash: if withdrawal.path or withdrawal.key_hash:
raise wire.ProcessError("Invalid withdrawal") raise wire.ProcessError("Invalid withdrawal")
def _validate_witness_request( def _validate_witness_request(
self, witness_request: CardanoTxWitnessRequest self, witness_request: messages.CardanoTxWitnessRequest
) -> None: ) -> None:
super()._validate_witness_request(witness_request) super()._validate_witness_request(witness_request)
is_minting = SCHEMA_MINT.match(witness_request.path) is_minting = SCHEMA_MINT.match(witness_request.path)

@ -1,20 +1,13 @@
from trezor import wire from trezor import messages, wire
from trezor.enums import CardanoCertificateType from trezor.enums import CardanoCertificateType
from trezor.messages import (
CardanoSignTxInit,
CardanoTxCertificate,
CardanoTxWithdrawal,
CardanoTxWitnessRequest,
)
from .. import seed from .. import layout, seed
from ..helpers.paths import ( from ..helpers.paths import (
SCHEMA_MINT, SCHEMA_MINT,
SCHEMA_PAYMENT, SCHEMA_PAYMENT,
SCHEMA_STAKING, SCHEMA_STAKING,
WITNESS_PATH_NAME, WITNESS_PATH_NAME,
) )
from ..layout import confirm_witness_request
from ..seed import is_byron_path, is_shelley_path from ..seed import is_byron_path, is_shelley_path
from .signer import Signer from .signer import Signer
@ -26,7 +19,10 @@ class OrdinarySigner(Signer):
""" """
def __init__( def __init__(
self, ctx: wire.Context, msg: CardanoSignTxInit, keychain: seed.Keychain self,
ctx: wire.Context,
msg: messages.CardanoSignTxInit,
keychain: seed.Keychain,
) -> None: ) -> None:
super().__init__(ctx, msg, keychain) super().__init__(ctx, msg, keychain)
@ -59,13 +55,13 @@ class OrdinarySigner(Signer):
if certificate.script_hash or certificate.key_hash: if certificate.script_hash or certificate.key_hash:
raise wire.ProcessError("Invalid certificate") raise wire.ProcessError("Invalid certificate")
def _validate_withdrawal(self, withdrawal: CardanoTxWithdrawal) -> None: def _validate_withdrawal(self, withdrawal: messages.CardanoTxWithdrawal) -> None:
super()._validate_withdrawal(withdrawal) super()._validate_withdrawal(withdrawal)
if withdrawal.script_hash or withdrawal.key_hash: if withdrawal.script_hash or withdrawal.key_hash:
raise wire.ProcessError("Invalid withdrawal") raise wire.ProcessError("Invalid withdrawal")
def _validate_witness_request( def _validate_witness_request(
self, witness_request: CardanoTxWitnessRequest self, witness_request: messages.CardanoTxWitnessRequest
) -> None: ) -> None:
super()._validate_witness_request(witness_request) super()._validate_witness_request(witness_request)
is_minting = SCHEMA_MINT.match(witness_request.path) is_minting = SCHEMA_MINT.match(witness_request.path)
@ -89,6 +85,6 @@ class OrdinarySigner(Signer):
is_minting = SCHEMA_MINT.match(witness_path) is_minting = SCHEMA_MINT.match(witness_path)
if is_minting: if is_minting:
await confirm_witness_request(self.ctx, witness_path) await layout.confirm_witness_request(self.ctx, witness_path)
elif not is_payment and not is_staking: elif not is_payment and not is_staking:
await self._fail_or_warn_path(witness_path, WITNESS_PATH_NAME) await self._fail_or_warn_path(witness_path, WITNESS_PATH_NAME)

@ -1,25 +1,9 @@
from trezor import wire from trezor import messages, wire
from trezor.enums import CardanoCertificateType from trezor.enums import CardanoCertificateType
from trezor.messages import (
CardanoAddressParametersType,
CardanoSignTxInit,
CardanoTxCertificate,
CardanoTxInput,
CardanoTxOutput,
CardanoTxWitnessRequest,
)
from .. import seed from .. import layout, seed
from ..helpers.credential import Credential, should_show_address_credentials from ..helpers.credential import Credential, should_show_address_credentials
from ..helpers.paths import SCHEMA_MINT from ..helpers.paths import SCHEMA_MINT
from ..layout import (
confirm_input,
confirm_transaction,
show_device_owned_output_credentials,
show_plutus_transaction,
show_warning_no_collateral_inputs,
show_warning_no_script_data_hash,
)
from ..seed import is_multisig_path, is_shelley_path from ..seed import is_multisig_path, is_shelley_path
from .signer import Signer from .signer import Signer
@ -31,18 +15,21 @@ class PlutusSigner(Signer):
""" """
def __init__( def __init__(
self, ctx: wire.Context, msg: CardanoSignTxInit, keychain: seed.Keychain self,
ctx: wire.Context,
msg: messages.CardanoSignTxInit,
keychain: seed.Keychain,
) -> None: ) -> None:
super().__init__(ctx, msg, keychain) super().__init__(ctx, msg, keychain)
async def _show_tx_signing_request(self) -> None: async def _show_tx_signing_request(self) -> None:
await show_plutus_transaction(self.ctx) await layout.show_plutus_transaction(self.ctx)
await super()._show_tx_signing_request() await super()._show_tx_signing_request()
# These items should be present if a Plutus script is to be executed. # These items should be present if a Plutus script is to be executed.
if self.msg.script_data_hash is None: if self.msg.script_data_hash is None:
await show_warning_no_script_data_hash(self.ctx) await layout.show_warning_no_script_data_hash(self.ctx)
if self.msg.collateral_inputs_count == 0: if self.msg.collateral_inputs_count == 0:
await show_warning_no_collateral_inputs(self.ctx) await layout.show_warning_no_collateral_inputs(self.ctx)
async def _confirm_transaction(self, tx_hash: bytes) -> None: async def _confirm_transaction(self, tx_hash: bytes) -> None:
# super() omitted intentionally # super() omitted intentionally
@ -50,7 +37,7 @@ class PlutusSigner(Signer):
# computed by a trusted device (in case the tx contains many items which are # computed by a trusted device (in case the tx contains many items which are
# tedious to check one by one on the Trezor screen). # tedious to check one by one on the Trezor screen).
is_network_id_verifiable = self._is_network_id_verifiable() is_network_id_verifiable = self._is_network_id_verifiable()
await confirm_transaction( await layout.confirm_transaction(
self.ctx, self.ctx,
self.msg.fee, self.msg.fee,
self.msg.network_id, self.msg.network_id,
@ -61,43 +48,43 @@ class PlutusSigner(Signer):
tx_hash, tx_hash,
) )
async def _show_input(self, input: CardanoTxInput) -> None: async def _show_input(self, input: messages.CardanoTxInput) -> None:
# super() omitted intentionally # super() omitted intentionally
# The inputs are not interchangeable (because of datums), so we must show them. # The inputs are not interchangeable (because of datums), so we must show them.
await confirm_input(self.ctx, input) await layout.confirm_input(self.ctx, input)
async def _show_output_credentials( async def _show_output_credentials(
self, address_parameters: CardanoAddressParametersType self, address_parameters: messages.CardanoAddressParametersType
) -> None: ) -> None:
# In ordinary txs, change outputs with matching payment and staking paths can be # In ordinary txs, change outputs with matching payment and staking paths can be
# hidden, but we need to show them in Plutus txs because of the script # hidden, but we need to show them in Plutus txs because of the script
# evaluation. We at least hide the staking path if it matches the payment path. # evaluation. We at least hide the staking path if it matches the payment path.
show_both_credentials = should_show_address_credentials(address_parameters) show_both_credentials = should_show_address_credentials(address_parameters)
await show_device_owned_output_credentials( await layout.show_device_owned_output_credentials(
self.ctx, self.ctx,
Credential.payment_credential(address_parameters), Credential.payment_credential(address_parameters),
Credential.stake_credential(address_parameters), Credential.stake_credential(address_parameters),
show_both_credentials, show_both_credentials,
) )
def _should_show_output(self, output: CardanoTxOutput) -> bool: def _should_show_output(self, output: messages.CardanoTxOutput) -> bool:
# super() omitted intentionally # super() omitted intentionally
# All outputs need to be shown (even device-owned), because they might influence # All outputs need to be shown (even device-owned), because they might influence
# the script evaluation. # the script evaluation.
return True return True
def _is_change_output(self, output: CardanoTxOutput) -> bool: def _is_change_output(self, output: messages.CardanoTxOutput) -> bool:
# super() omitted intentionally # super() omitted intentionally
# In Plutus txs, we don't call device-owned outputs "change" outputs. # In Plutus txs, we don't call device-owned outputs "change" outputs.
return False return False
def _validate_certificate(self, certificate: CardanoTxCertificate) -> None: def _validate_certificate(self, certificate: messages.CardanoTxCertificate) -> None:
super()._validate_certificate(certificate) super()._validate_certificate(certificate)
if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION: if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION:
raise wire.ProcessError("Invalid certificate") raise wire.ProcessError("Invalid certificate")
def _validate_witness_request( def _validate_witness_request(
self, witness_request: CardanoTxWitnessRequest self, witness_request: messages.CardanoTxWitnessRequest
) -> None: ) -> None:
super()._validate_witness_request(witness_request) super()._validate_witness_request(witness_request)
is_minting = SCHEMA_MINT.match(witness_request.path) is_minting = SCHEMA_MINT.match(witness_request.path)

@ -1,15 +1,8 @@
from trezor import wire from trezor import messages, wire
from trezor.enums import CardanoCertificateType from trezor.enums import CardanoCertificateType
from trezor.messages import (
CardanoSignTxInit,
CardanoTxCertificate,
CardanoTxOutput,
CardanoTxWitnessRequest,
)
from .. import seed from .. import layout, seed
from ..helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT from ..helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT
from ..layout import confirm_stake_pool_registration_final
from .signer import Signer from .signer import Signer
@ -27,7 +20,10 @@ class PoolOwnerSigner(Signer):
""" """
def __init__( def __init__(
self, ctx: wire.Context, msg: CardanoSignTxInit, keychain: seed.Keychain self,
ctx: wire.Context,
msg: messages.CardanoSignTxInit,
keychain: seed.Keychain,
) -> None: ) -> None:
super().__init__(ctx, msg, keychain) super().__init__(ctx, msg, keychain)
@ -51,30 +47,30 @@ class PoolOwnerSigner(Signer):
async def _confirm_transaction(self, tx_hash: bytes) -> None: async def _confirm_transaction(self, tx_hash: bytes) -> None:
# super() omitted intentionally # super() omitted intentionally
await confirm_stake_pool_registration_final( await layout.confirm_stake_pool_registration_final(
self.ctx, self.ctx,
self.msg.protocol_magic, self.msg.protocol_magic,
self.msg.ttl, self.msg.ttl,
self.msg.validity_interval_start, self.msg.validity_interval_start,
) )
def _validate_output(self, output: CardanoTxOutput) -> None: def _validate_output(self, output: messages.CardanoTxOutput) -> None:
super()._validate_output(output) super()._validate_output(output)
if output.address_parameters is not None or output.datum_hash is not None: if output.address_parameters is not None or output.datum_hash is not None:
raise wire.ProcessError("Invalid output") raise wire.ProcessError("Invalid output")
def _should_show_output(self, output: CardanoTxOutput) -> bool: def _should_show_output(self, output: messages.CardanoTxOutput) -> bool:
# super() omitted intentionally # super() omitted intentionally
# There are no spending witnesses, it is thus safe to hide outputs. # There are no spending witnesses, it is thus safe to hide outputs.
return False return False
def _validate_certificate(self, certificate: CardanoTxCertificate) -> None: def _validate_certificate(self, certificate: messages.CardanoTxCertificate) -> None:
super()._validate_certificate(certificate) super()._validate_certificate(certificate)
if certificate.type != CardanoCertificateType.STAKE_POOL_REGISTRATION: if certificate.type != CardanoCertificateType.STAKE_POOL_REGISTRATION:
raise wire.ProcessError("Invalid certificate") raise wire.ProcessError("Invalid certificate")
def _validate_witness_request( def _validate_witness_request(
self, witness_request: CardanoTxWitnessRequest self, witness_request: messages.CardanoTxWitnessRequest
) -> None: ) -> None:
super()._validate_witness_request(witness_request) super()._validate_witness_request(witness_request)
if not SCHEMA_STAKING_ANY_ACCOUNT.match(witness_request.path): if not SCHEMA_STAKING_ANY_ACCOUNT.match(witness_request.path):

@ -1,7 +1,7 @@
from micropython import const from micropython import const
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import wire from trezor import messages, wire
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 ( from trezor.enums import (
@ -9,31 +9,10 @@ from trezor.enums import (
CardanoCertificateType, CardanoCertificateType,
CardanoTxWitnessType, CardanoTxWitnessType,
) )
from trezor.messages import (
CardanoAddressParametersType,
CardanoAssetGroup,
CardanoPoolOwner,
CardanoPoolRelayParameters,
CardanoSignTxInit,
CardanoToken,
CardanoTxAuxiliaryData,
CardanoTxBodyHash,
CardanoTxCertificate,
CardanoTxCollateralInput,
CardanoTxHostAck,
CardanoTxInput,
CardanoTxItemAck,
CardanoTxMint,
CardanoTxOutput,
CardanoTxRequiredSigner,
CardanoTxWithdrawal,
CardanoTxWitnessRequest,
CardanoTxWitnessResponse,
)
from apps.common import cbor, safety_checks from apps.common import cbor, safety_checks
from .. import seed from .. import layout
from ..address import ( from ..address import (
ADDRESS_TYPES_PAYMENT_SCRIPT, ADDRESS_TYPES_PAYMENT_SCRIPT,
derive_address_bytes, derive_address_bytes,
@ -82,35 +61,17 @@ from ..helpers.utils import (
validate_network_info, validate_network_info,
validate_stake_credential, validate_stake_credential,
) )
from ..layout import (
confirm_certificate,
confirm_collateral_input,
confirm_required_signer,
confirm_script_data_hash,
confirm_sending,
confirm_sending_token,
confirm_stake_pool_metadata,
confirm_stake_pool_owner,
confirm_stake_pool_parameters,
confirm_token_minting,
confirm_transaction,
confirm_withdrawal,
confirm_witness_request,
show_change_output_credentials,
show_warning_path,
show_warning_tx_contains_mint,
show_warning_tx_network_unverifiable,
show_warning_tx_output_contains_datum_hash,
show_warning_tx_output_contains_tokens,
show_warning_tx_output_no_datum_hash,
)
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
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
from apps.common.paths import PathSchema from apps.common.paths import PathSchema
CardanoTxResponseType = CardanoTxItemAck | CardanoTxWitnessResponse from .. import seed
CardanoTxResponseType = (
messages.CardanoTxItemAck | messages.CardanoTxWitnessResponse
)
MINTING_POLICY_ID_LENGTH = 28 MINTING_POLICY_ID_LENGTH = 28
MAX_ASSET_NAME_LENGTH = 32 MAX_ASSET_NAME_LENGTH = 32
@ -142,7 +103,10 @@ class Signer:
""" """
def __init__( def __init__(
self, ctx: wire.Context, msg: CardanoSignTxInit, keychain: seed.Keychain self,
ctx: wire.Context,
msg: messages.CardanoSignTxInit,
keychain: seed.Keychain,
) -> None: ) -> None:
self.ctx = ctx self.ctx = ctx
self.msg = msg self.msg = msg
@ -179,8 +143,10 @@ class Signer:
await self._confirm_transaction(tx_hash) await self._confirm_transaction(tx_hash)
response_after_witness_requests = await self._process_witness_requests(tx_hash) response_after_witness_requests = await self._process_witness_requests(tx_hash)
await self.ctx.call(response_after_witness_requests, CardanoTxHostAck) await self.ctx.call(response_after_witness_requests, messages.CardanoTxHostAck)
await self.ctx.call(CardanoTxBodyHash(tx_hash=tx_hash), CardanoTxHostAck) await self.ctx.call(
messages.CardanoTxBodyHash(tx_hash=tx_hash), messages.CardanoTxHostAck
)
# signing request # signing request
@ -262,7 +228,7 @@ class Signer:
async def _show_tx_signing_request(self) -> None: async def _show_tx_signing_request(self) -> None:
if not self._is_network_id_verifiable(): if not self._is_network_id_verifiable():
await show_warning_tx_network_unverifiable(self.ctx) await layout.show_warning_tx_network_unverifiable(self.ctx)
async def _confirm_tx(self, tx_hash: bytes) -> None: async def _confirm_tx(self, tx_hash: bytes) -> None:
# Final signing confirmation is handled separately in each signing mode. # Final signing confirmation is handled separately in each signing mode.
@ -274,18 +240,18 @@ class Signer:
self, inputs_list: HashBuilderList[tuple[bytes, int]] self, inputs_list: HashBuilderList[tuple[bytes, int]]
) -> None: ) -> None:
for _ in range(self.msg.inputs_count): for _ in range(self.msg.inputs_count):
input: CardanoTxInput = await self.ctx.call( input: messages.CardanoTxInput = await self.ctx.call(
CardanoTxItemAck(), CardanoTxInput messages.CardanoTxItemAck(), messages.CardanoTxInput
) )
self._validate_input(input) self._validate_input(input)
await self._show_input(input) await self._show_input(input)
inputs_list.append((input.prev_hash, input.prev_index)) inputs_list.append((input.prev_hash, input.prev_index))
def _validate_input(self, input: CardanoTxInput) -> None: def _validate_input(self, input: messages.CardanoTxInput) -> None:
if len(input.prev_hash) != INPUT_PREV_HASH_SIZE: if len(input.prev_hash) != INPUT_PREV_HASH_SIZE:
raise wire.ProcessError("Invalid input") raise wire.ProcessError("Invalid input")
async def _show_input(self, input: CardanoTxInput) -> None: async def _show_input(self, input: messages.CardanoTxInput) -> None:
# We never show the inputs, except for Plutus txs. # We never show the inputs, except for Plutus txs.
pass pass
@ -294,8 +260,8 @@ class Signer:
async def _process_outputs(self, outputs_list: HashBuilderList) -> None: async def _process_outputs(self, outputs_list: HashBuilderList) -> None:
total_amount = 0 total_amount = 0
for _ in range(self.msg.outputs_count): for _ in range(self.msg.outputs_count):
output: CardanoTxOutput = await self.ctx.call( output: messages.CardanoTxOutput = await self.ctx.call(
CardanoTxItemAck(), CardanoTxOutput messages.CardanoTxItemAck(), messages.CardanoTxOutput
) )
self._validate_output(output) self._validate_output(output)
await self._show_output(output) await self._show_output(output)
@ -334,7 +300,7 @@ class Signer:
if total_amount > LOVELACE_MAX_SUPPLY: if total_amount > LOVELACE_MAX_SUPPLY:
raise wire.ProcessError("Total transaction amount is out of range!") raise wire.ProcessError("Total transaction amount is out of range!")
def _validate_output(self, output: CardanoTxOutput) -> None: def _validate_output(self, output: messages.CardanoTxOutput) -> None:
if output.address_parameters is not None and output.address is not None: if output.address_parameters is not None and output.address is not None:
raise wire.ProcessError("Invalid output") raise wire.ProcessError("Invalid output")
@ -357,21 +323,21 @@ class Signer:
self.account_path_checker.add_output(output) self.account_path_checker.add_output(output)
async def _show_output(self, output: CardanoTxOutput) -> None: async def _show_output(self, output: messages.CardanoTxOutput) -> None:
if not self._should_show_output(output): if not self._should_show_output(output):
return return
if output.datum_hash is not None: if output.datum_hash is not None:
await show_warning_tx_output_contains_datum_hash( await layout.show_warning_tx_output_contains_datum_hash(
self.ctx, output.datum_hash self.ctx, output.datum_hash
) )
address_type = self._get_output_address_type(output) address_type = self._get_output_address_type(output)
if output.datum_hash is None and address_type in ADDRESS_TYPES_PAYMENT_SCRIPT: if output.datum_hash is None and address_type in ADDRESS_TYPES_PAYMENT_SCRIPT:
await show_warning_tx_output_no_datum_hash(self.ctx) await layout.show_warning_tx_output_no_datum_hash(self.ctx)
if output.asset_groups_count > 0: if output.asset_groups_count > 0:
await show_warning_tx_output_contains_tokens(self.ctx) await layout.show_warning_tx_output_contains_tokens(self.ctx)
if output.address_parameters is not None: if output.address_parameters is not None:
address = derive_human_readable_address( address = derive_human_readable_address(
@ -385,7 +351,7 @@ class Signer:
assert output.address is not None # _validate_output assert output.address is not None # _validate_output
address = output.address address = output.address
await confirm_sending( await layout.confirm_sending(
self.ctx, self.ctx,
output.amount, output.amount,
address, address,
@ -394,15 +360,15 @@ class Signer:
) )
async def _show_output_credentials( async def _show_output_credentials(
self, address_parameters: CardanoAddressParametersType self, address_parameters: messages.CardanoAddressParametersType
) -> None: ) -> None:
await show_change_output_credentials( await layout.show_change_output_credentials(
self.ctx, self.ctx,
Credential.payment_credential(address_parameters), Credential.payment_credential(address_parameters),
Credential.stake_credential(address_parameters), Credential.stake_credential(address_parameters),
) )
def _should_show_output(self, output: CardanoTxOutput) -> bool: def _should_show_output(self, output: messages.CardanoTxOutput) -> bool:
""" """
Determines whether the output should be shown. Extracted from _show_output because Determines whether the output should be shown. Extracted from _show_output because
of readability and because the same decision is made when displaying output tokens. of readability and because the same decision is made when displaying output tokens.
@ -424,7 +390,7 @@ class Signer:
return True return True
def _is_change_output(self, output: CardanoTxOutput) -> bool: def _is_change_output(self, output: messages.CardanoTxOutput) -> bool:
"""Used only to determine what message to show to the user when confirming sending.""" """Used only to determine what message to show to the user when confirming sending."""
return output.address_parameters is not None return output.address_parameters is not None
@ -437,8 +403,8 @@ class Signer:
should_show_tokens: bool, should_show_tokens: bool,
) -> None: ) -> None:
for _ in range(asset_groups_count): for _ in range(asset_groups_count):
asset_group: CardanoAssetGroup = await self.ctx.call( asset_group: messages.CardanoAssetGroup = await self.ctx.call(
CardanoTxItemAck(), CardanoAssetGroup messages.CardanoTxItemAck(), messages.CardanoAssetGroup
) )
self._validate_asset_group(asset_group) self._validate_asset_group(asset_group)
@ -455,7 +421,7 @@ class Signer:
) )
def _validate_asset_group( def _validate_asset_group(
self, asset_group: CardanoAssetGroup, is_mint: bool = False self, asset_group: messages.CardanoAssetGroup, is_mint: bool = False
) -> None: ) -> None:
INVALID_TOKEN_BUNDLE = ( INVALID_TOKEN_BUNDLE = (
wire.ProcessError("Invalid mint token bundle") wire.ProcessError("Invalid mint token bundle")
@ -478,15 +444,19 @@ class Signer:
should_show_tokens: bool, should_show_tokens: bool,
) -> None: ) -> None:
for _ in range(tokens_count): for _ in range(tokens_count):
token: CardanoToken = await self.ctx.call(CardanoTxItemAck(), CardanoToken) token: messages.CardanoToken = await self.ctx.call(
messages.CardanoTxItemAck(), messages.CardanoToken
)
self._validate_token(token) self._validate_token(token)
if should_show_tokens: if should_show_tokens:
await confirm_sending_token(self.ctx, policy_id, token) await layout.confirm_sending_token(self.ctx, policy_id, token)
assert token.amount is not None # _validate_token assert token.amount is not None # _validate_token
tokens_dict.add(token.asset_name_bytes, token.amount) tokens_dict.add(token.asset_name_bytes, token.amount)
def _validate_token(self, token: CardanoToken, is_mint: bool = False) -> None: def _validate_token(
self, token: messages.CardanoToken, is_mint: bool = False
) -> None:
INVALID_TOKEN_BUNDLE = ( INVALID_TOKEN_BUNDLE = (
wire.ProcessError("Invalid mint token bundle") wire.ProcessError("Invalid mint token bundle")
if is_mint if is_mint
@ -507,8 +477,8 @@ class Signer:
async def _process_certificates(self, certificates_list: HashBuilderList) -> None: async def _process_certificates(self, certificates_list: HashBuilderList) -> None:
for _ in range(self.msg.certificates_count): for _ in range(self.msg.certificates_count):
certificate: CardanoTxCertificate = await self.ctx.call( certificate: messages.CardanoTxCertificate = await self.ctx.call(
CardanoTxItemAck(), CardanoTxCertificate messages.CardanoTxItemAck(), messages.CardanoTxCertificate
) )
self._validate_certificate(certificate) self._validate_certificate(certificate)
await self._show_certificate(certificate) await self._show_certificate(certificate)
@ -550,7 +520,7 @@ class Signer:
cborize_certificate(self.keychain, certificate) cborize_certificate(self.keychain, certificate)
) )
def _validate_certificate(self, certificate: CardanoTxCertificate) -> None: def _validate_certificate(self, certificate: messages.CardanoTxCertificate) -> None:
validate_certificate( validate_certificate(
certificate, certificate,
self.msg.protocol_magic, self.msg.protocol_magic,
@ -558,7 +528,9 @@ class Signer:
self.account_path_checker, self.account_path_checker,
) )
async def _show_certificate(self, certificate: CardanoTxCertificate) -> None: async def _show_certificate(
self, certificate: messages.CardanoTxCertificate
) -> None:
if certificate.path: if certificate.path:
await self._fail_or_warn_if_invalid_path( await self._fail_or_warn_if_invalid_path(
SCHEMA_STAKING, certificate.path, CERTIFICATE_PATH_NAME SCHEMA_STAKING, certificate.path, CERTIFICATE_PATH_NAME
@ -566,14 +538,14 @@ class Signer:
if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION: if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION:
assert certificate.pool_parameters is not None assert certificate.pool_parameters is not None
await confirm_stake_pool_parameters( await layout.confirm_stake_pool_parameters(
self.ctx, certificate.pool_parameters, self.msg.network_id self.ctx, certificate.pool_parameters, self.msg.network_id
) )
await confirm_stake_pool_metadata( await layout.confirm_stake_pool_metadata(
self.ctx, certificate.pool_parameters.metadata self.ctx, certificate.pool_parameters.metadata
) )
else: else:
await confirm_certificate(self.ctx, certificate) await layout.confirm_certificate(self.ctx, certificate)
# pool owners # pool owners
@ -582,8 +554,8 @@ class Signer:
) -> None: ) -> None:
owners_as_path_count = 0 owners_as_path_count = 0
for _ in range(owners_count): for _ in range(owners_count):
owner: CardanoPoolOwner = await self.ctx.call( owner: messages.CardanoPoolOwner = await self.ctx.call(
CardanoTxItemAck(), CardanoPoolOwner messages.CardanoTxItemAck(), messages.CardanoPoolOwner
) )
validate_pool_owner(owner, self.account_path_checker) validate_pool_owner(owner, self.account_path_checker)
await self._show_pool_owner(owner) await self._show_pool_owner(owner)
@ -594,13 +566,13 @@ class Signer:
assert_certificate_cond(owners_as_path_count == 1) assert_certificate_cond(owners_as_path_count == 1)
async def _show_pool_owner(self, owner: CardanoPoolOwner) -> None: async def _show_pool_owner(self, owner: messages.CardanoPoolOwner) -> None:
if owner.staking_key_path: if owner.staking_key_path:
await self._fail_or_warn_if_invalid_path( await self._fail_or_warn_if_invalid_path(
SCHEMA_STAKING, owner.staking_key_path, POOL_OWNER_STAKING_PATH_NAME SCHEMA_STAKING, owner.staking_key_path, POOL_OWNER_STAKING_PATH_NAME
) )
await confirm_stake_pool_owner( await layout.confirm_stake_pool_owner(
self.ctx, self.keychain, owner, self.msg.protocol_magic, self.msg.network_id self.ctx, self.keychain, owner, self.msg.protocol_magic, self.msg.network_id
) )
@ -612,8 +584,8 @@ class Signer:
relays_count: int, relays_count: int,
) -> None: ) -> None:
for _ in range(relays_count): for _ in range(relays_count):
relay: CardanoPoolRelayParameters = await self.ctx.call( relay: messages.CardanoPoolRelayParameters = await self.ctx.call(
CardanoTxItemAck(), CardanoPoolRelayParameters messages.CardanoTxItemAck(), messages.CardanoPoolRelayParameters
) )
validate_pool_relay(relay) validate_pool_relay(relay)
relays_list.append(cborize_pool_relay(relay)) relays_list.append(cborize_pool_relay(relay))
@ -624,19 +596,19 @@ class Signer:
self, withdrawals_dict: HashBuilderDict[bytes, int] self, withdrawals_dict: HashBuilderDict[bytes, int]
) -> None: ) -> None:
for _ in range(self.msg.withdrawals_count): for _ in range(self.msg.withdrawals_count):
withdrawal: CardanoTxWithdrawal = await self.ctx.call( withdrawal: messages.CardanoTxWithdrawal = await self.ctx.call(
CardanoTxItemAck(), CardanoTxWithdrawal messages.CardanoTxItemAck(), messages.CardanoTxWithdrawal
) )
self._validate_withdrawal(withdrawal) self._validate_withdrawal(withdrawal)
reward_address_bytes = self._derive_withdrawal_reward_address_bytes( reward_address_bytes = self._derive_withdrawal_reward_address_bytes(
withdrawal withdrawal
) )
await confirm_withdrawal( await layout.confirm_withdrawal(
self.ctx, withdrawal, reward_address_bytes, self.msg.network_id self.ctx, withdrawal, reward_address_bytes, self.msg.network_id
) )
withdrawals_dict.add(reward_address_bytes, withdrawal.amount) withdrawals_dict.add(reward_address_bytes, withdrawal.amount)
def _validate_withdrawal(self, withdrawal: CardanoTxWithdrawal) -> None: def _validate_withdrawal(self, withdrawal: messages.CardanoTxWithdrawal) -> None:
validate_stake_credential( validate_stake_credential(
withdrawal.path, withdrawal.path,
withdrawal.script_hash, withdrawal.script_hash,
@ -652,8 +624,8 @@ class Signer:
# auxiliary data # auxiliary data
async def _process_auxiliary_data(self) -> None: async def _process_auxiliary_data(self) -> None:
auxiliary_data: CardanoTxAuxiliaryData = await self.ctx.call( auxiliary_data: messages.CardanoTxAuxiliaryData = await self.ctx.call(
CardanoTxItemAck(), CardanoTxAuxiliaryData messages.CardanoTxItemAck(), messages.CardanoTxAuxiliaryData
) )
validate_auxiliary_data(auxiliary_data) validate_auxiliary_data(auxiliary_data)
@ -673,22 +645,22 @@ class Signer:
) )
self.tx_dict.add(TX_BODY_KEY_AUXILIARY_DATA, auxiliary_data_hash) self.tx_dict.add(TX_BODY_KEY_AUXILIARY_DATA, auxiliary_data_hash)
await self.ctx.call(auxiliary_data_supplement, CardanoTxHostAck) await self.ctx.call(auxiliary_data_supplement, messages.CardanoTxHostAck)
# minting # minting
async def _process_minting( async def _process_minting(
self, minting_dict: HashBuilderDict[bytes, HashBuilderDict] self, minting_dict: HashBuilderDict[bytes, HashBuilderDict]
) -> None: ) -> None:
token_minting: CardanoTxMint = await self.ctx.call( token_minting: messages.CardanoTxMint = await self.ctx.call(
CardanoTxItemAck(), CardanoTxMint messages.CardanoTxItemAck(), messages.CardanoTxMint
) )
await show_warning_tx_contains_mint(self.ctx) await layout.show_warning_tx_contains_mint(self.ctx)
for _ in range(token_minting.asset_groups_count): for _ in range(token_minting.asset_groups_count):
asset_group: CardanoAssetGroup = await self.ctx.call( asset_group: messages.CardanoAssetGroup = await self.ctx.call(
CardanoTxItemAck(), CardanoAssetGroup messages.CardanoTxItemAck(), messages.CardanoAssetGroup
) )
self._validate_asset_group(asset_group, is_mint=True) self._validate_asset_group(asset_group, is_mint=True)
@ -711,9 +683,11 @@ class Signer:
tokens_count: int, tokens_count: int,
) -> None: ) -> None:
for _ in range(tokens_count): for _ in range(tokens_count):
token: CardanoToken = await self.ctx.call(CardanoTxItemAck(), CardanoToken) token: messages.CardanoToken = await self.ctx.call(
messages.CardanoTxItemAck(), messages.CardanoToken
)
self._validate_token(token, is_mint=True) self._validate_token(token, is_mint=True)
await confirm_token_minting(self.ctx, policy_id, token) await layout.confirm_token_minting(self.ctx, policy_id, token)
assert token.mint_amount is not None # _validate_token assert token.mint_amount is not None # _validate_token
tokens.add(token.asset_name_bytes, token.mint_amount) tokens.add(token.asset_name_bytes, token.mint_amount)
@ -723,7 +697,7 @@ class Signer:
async def _process_script_data_hash(self) -> None: async def _process_script_data_hash(self) -> None:
assert self.msg.script_data_hash is not None assert self.msg.script_data_hash is not None
self._validate_script_data_hash() self._validate_script_data_hash()
await confirm_script_data_hash(self.ctx, self.msg.script_data_hash) await layout.confirm_script_data_hash(self.ctx, self.msg.script_data_hash)
self.tx_dict.add(TX_BODY_KEY_SCRIPT_DATA_HASH, self.msg.script_data_hash) self.tx_dict.add(TX_BODY_KEY_SCRIPT_DATA_HASH, self.msg.script_data_hash)
def _validate_script_data_hash(self) -> None: def _validate_script_data_hash(self) -> None:
@ -737,17 +711,17 @@ class Signer:
self, collateral_inputs_list: HashBuilderList[tuple[bytes, int]] self, collateral_inputs_list: HashBuilderList[tuple[bytes, int]]
) -> None: ) -> None:
for _ in range(self.msg.collateral_inputs_count): for _ in range(self.msg.collateral_inputs_count):
collateral_input: CardanoTxCollateralInput = await self.ctx.call( collateral_input: messages.CardanoTxCollateralInput = await self.ctx.call(
CardanoTxItemAck(), CardanoTxCollateralInput messages.CardanoTxItemAck(), messages.CardanoTxCollateralInput
) )
self._validate_collateral_input(collateral_input) self._validate_collateral_input(collateral_input)
await confirm_collateral_input(self.ctx, collateral_input) await layout.confirm_collateral_input(self.ctx, collateral_input)
collateral_inputs_list.append( collateral_inputs_list.append(
(collateral_input.prev_hash, collateral_input.prev_index) (collateral_input.prev_hash, collateral_input.prev_index)
) )
def _validate_collateral_input( def _validate_collateral_input(
self, collateral_input: CardanoTxCollateralInput self, collateral_input: messages.CardanoTxCollateralInput
) -> None: ) -> None:
if len(collateral_input.prev_hash) != INPUT_PREV_HASH_SIZE: if len(collateral_input.prev_hash) != INPUT_PREV_HASH_SIZE:
raise wire.ProcessError("Invalid collateral input") raise wire.ProcessError("Invalid collateral input")
@ -758,11 +732,11 @@ class Signer:
self, required_signers_list: HashBuilderList[bytes] self, required_signers_list: HashBuilderList[bytes]
) -> None: ) -> None:
for _ in range(self.msg.required_signers_count): for _ in range(self.msg.required_signers_count):
required_signer: CardanoTxRequiredSigner = await self.ctx.call( required_signer: messages.CardanoTxRequiredSigner = await self.ctx.call(
CardanoTxItemAck(), CardanoTxRequiredSigner messages.CardanoTxItemAck(), messages.CardanoTxRequiredSigner
) )
self._validate_required_signer(required_signer) self._validate_required_signer(required_signer)
await confirm_required_signer(self.ctx, required_signer) await layout.confirm_required_signer(self.ctx, required_signer)
key_hash = required_signer.key_hash or get_public_key_hash( key_hash = required_signer.key_hash or get_public_key_hash(
self.keychain, required_signer.key_path self.keychain, required_signer.key_path
@ -770,7 +744,7 @@ class Signer:
required_signers_list.append(key_hash) required_signers_list.append(key_hash)
def _validate_required_signer( def _validate_required_signer(
self, required_signer: CardanoTxRequiredSigner self, required_signer: messages.CardanoTxRequiredSigner
) -> None: ) -> None:
INVALID_REQUIRED_SIGNER = wire.ProcessError("Invalid required signer") INVALID_REQUIRED_SIGNER = wire.ProcessError("Invalid required signer")
@ -793,10 +767,12 @@ class Signer:
# witness requests # witness requests
async def _process_witness_requests(self, tx_hash: bytes) -> CardanoTxResponseType: async def _process_witness_requests(self, tx_hash: bytes) -> CardanoTxResponseType:
response: CardanoTxResponseType = CardanoTxItemAck() response: CardanoTxResponseType = messages.CardanoTxItemAck()
for _ in range(self.msg.witness_requests_count): for _ in range(self.msg.witness_requests_count):
witness_request = await self.ctx.call(response, CardanoTxWitnessRequest) witness_request = await self.ctx.call(
response, messages.CardanoTxWitnessRequest
)
self._validate_witness_request(witness_request) self._validate_witness_request(witness_request)
path = witness_request.path path = witness_request.path
await self._show_witness_request(path) await self._show_witness_request(path)
@ -808,7 +784,7 @@ class Signer:
return response return response
def _validate_witness_request( def _validate_witness_request(
self, witness_request: CardanoTxWitnessRequest self, witness_request: messages.CardanoTxWitnessRequest
) -> None: ) -> None:
self.account_path_checker.add_witness_request(witness_request) self.account_path_checker.add_witness_request(witness_request)
@ -816,7 +792,7 @@ class Signer:
self, self,
witness_path: list[int], witness_path: list[int],
) -> None: ) -> None:
await confirm_witness_request(self.ctx, witness_path) await layout.confirm_witness_request(self.ctx, witness_path)
# helpers # helpers
@ -836,7 +812,7 @@ class Signer:
or self.msg.withdrawals_count != 0 or self.msg.withdrawals_count != 0
) )
def _get_output_address(self, output: CardanoTxOutput) -> bytes: def _get_output_address(self, output: messages.CardanoTxOutput) -> bytes:
if output.address_parameters: if output.address_parameters:
return derive_address_bytes( return derive_address_bytes(
self.keychain, self.keychain,
@ -848,14 +824,16 @@ class Signer:
assert output.address is not None # _validate_output assert output.address is not None # _validate_output
return get_address_bytes_unsafe(output.address) return get_address_bytes_unsafe(output.address)
def _get_output_address_type(self, output: CardanoTxOutput) -> CardanoAddressType: def _get_output_address_type(
self, output: messages.CardanoTxOutput
) -> CardanoAddressType:
if output.address_parameters: if output.address_parameters:
return output.address_parameters.address_type return output.address_parameters.address_type
assert output.address is not None # _validate_output assert output.address is not None # _validate_output
return get_address_type(get_address_bytes_unsafe(output.address)) return get_address_type(get_address_bytes_unsafe(output.address))
def _derive_withdrawal_reward_address_bytes( def _derive_withdrawal_reward_address_bytes(
self, withdrawal: CardanoTxWithdrawal self, withdrawal: messages.CardanoTxWithdrawal
) -> bytes: ) -> bytes:
reward_address_type = ( reward_address_type = (
CardanoAddressType.REWARD CardanoAddressType.REWARD
@ -864,7 +842,7 @@ class Signer:
) )
return derive_address_bytes( return derive_address_bytes(
self.keychain, self.keychain,
CardanoAddressParametersType( messages.CardanoAddressParametersType(
address_type=reward_address_type, address_type=reward_address_type,
address_n_staking=withdrawal.path, address_n_staking=withdrawal.path,
staking_key_hash=withdrawal.key_hash, staking_key_hash=withdrawal.key_hash,
@ -876,9 +854,9 @@ class Signer:
def _get_byron_witness( def _get_byron_witness(
self, path: list[int], tx_hash: bytes self, path: list[int], tx_hash: bytes
) -> CardanoTxWitnessResponse: ) -> messages.CardanoTxWitnessResponse:
node = self.keychain.derive(path) node = self.keychain.derive(path)
return CardanoTxWitnessResponse( return messages.CardanoTxWitnessResponse(
type=CardanoTxWitnessType.BYRON_WITNESS, type=CardanoTxWitnessType.BYRON_WITNESS,
pub_key=derive_public_key(self.keychain, path), pub_key=derive_public_key(self.keychain, path),
signature=self._sign_tx_hash(tx_hash, path), signature=self._sign_tx_hash(tx_hash, path),
@ -887,8 +865,8 @@ class Signer:
def _get_shelley_witness( def _get_shelley_witness(
self, path: list[int], tx_hash: bytes self, path: list[int], tx_hash: bytes
) -> CardanoTxWitnessResponse: ) -> messages.CardanoTxWitnessResponse:
return CardanoTxWitnessResponse( return messages.CardanoTxWitnessResponse(
type=CardanoTxWitnessType.SHELLEY_WITNESS, type=CardanoTxWitnessType.SHELLEY_WITNESS,
pub_key=derive_public_key(self.keychain, path), pub_key=derive_public_key(self.keychain, path),
signature=self._sign_tx_hash(tx_hash, path), signature=self._sign_tx_hash(tx_hash, path),
@ -910,10 +888,10 @@ class Signer:
if safety_checks.is_strict(): if safety_checks.is_strict():
raise wire.DataError(f"Invalid {path_name.lower()}") raise wire.DataError(f"Invalid {path_name.lower()}")
else: else:
await show_warning_path(self.ctx, path, path_name) await layout.show_warning_path(self.ctx, path, path_name)
def _fail_if_strict_and_unusual( def _fail_if_strict_and_unusual(
self, address_parameters: CardanoAddressParametersType self, address_parameters: messages.CardanoAddressParametersType
) -> None: ) -> None:
if not safety_checks.is_strict(): if not safety_checks.is_strict():
return return

Loading…
Cancel
Save