You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/cardano/get_address.py

105 lines
3.2 KiB

from trezor import log, wire
from trezor.messages import CardanoAddress
from apps.common import paths
from apps.common.layout import address_n_to_str, show_qr
from . import seed
from .address import derive_human_readable_address, validate_address_parameters
from .helpers import protocol_magics, staking_use_cases
from .helpers.paths import SCHEMA_ADDRESS
from .helpers.utils import to_account_path
from .layout import (
show_address,
show_warning_address_foreign_staking_key,
show_warning_address_pointer,
)
from .sign_tx import validate_network_info
if False:
from trezor.messages import (
CardanoAddressParametersType,
CardanoGetAddress,
)
@seed.with_keychain
async def get_address(
ctx: wire.Context, msg: CardanoGetAddress, keychain: seed.Keychain
) -> CardanoAddress:
address_parameters = msg.address_parameters
await paths.validate_path(
ctx,
keychain,
address_parameters.address_n,
# path must match the ADDRESS schema
SCHEMA_ADDRESS.match(address_parameters.address_n),
)
validate_network_info(msg.network_id, msg.protocol_magic)
validate_address_parameters(address_parameters)
try:
address = derive_human_readable_address(
keychain, address_parameters, msg.protocol_magic, msg.network_id
)
except ValueError as e:
if __debug__:
log.exception(__name__, e)
raise wire.ProcessError("Deriving address failed")
if msg.show_display:
await _display_address(
ctx, keychain, address_parameters, address, msg.protocol_magic
)
return CardanoAddress(address=address)
async def _display_address(
ctx: wire.Context,
keychain: seed.Keychain,
address_parameters: CardanoAddressParametersType,
address: str,
protocol_magic: int,
) -> None:
await _show_staking_warnings(ctx, keychain, address_parameters)
network_name = None
if not protocol_magics.is_mainnet(protocol_magic):
network_name = protocol_magics.to_ui_string(protocol_magic)
while True:
if await show_address(
ctx,
address,
address_parameters.address_type,
address_parameters.address_n,
network=network_name,
):
break
if await show_qr(
ctx, address, desc=address_n_to_str(address_parameters.address_n)
):
break
async def _show_staking_warnings(
ctx: wire.Context,
keychain: seed.Keychain,
address_parameters: CardanoAddressParametersType,
) -> None:
staking_type = staking_use_cases.get(keychain, address_parameters)
if staking_type == staking_use_cases.MISMATCH:
await show_warning_address_foreign_staking_key(
ctx,
to_account_path(address_parameters.address_n),
to_account_path(address_parameters.address_n_staking),
address_parameters.staking_key_hash,
)
elif staking_type == staking_use_cases.POINTER_ADDRESS:
# ensured in _derive_shelley_address:
assert address_parameters.certificate_pointer is not None
await show_warning_address_pointer(ctx, address_parameters.certificate_pointer)