Exemple #1
0
async def bootscreen() -> None:
    ui.display.orientation(storage.device.get_rotation())

    while True:
        try:
            if storage.sd_salt.is_enabled() or config.has_pin():
                await lockscreen()

            salt = await request_sd_salt()

            if not config.has_pin():
                config.unlock(pin_to_int(""), salt)
                storage.init_unlocked()
                return

            label = "Enter your PIN"
            while True:
                pin = await request_pin(label, config.get_pin_rem())
                if config.unlock(pin_to_int(pin), salt):
                    storage.init_unlocked()
                    return
                else:
                    label = "Wrong PIN, enter again"
        except (OSError, PinCancelled, SdCardUnavailable) as e:
            if __debug__:
                log.exception(__name__, e)
        except BaseException as e:
            if __debug__:
                log.exception(__name__, e)
            utils.halt(e.__class__.__name__)
Exemple #2
0
def _step(task: Task, value: Any) -> None:
    try:
        if isinstance(value, BaseException):
            result = task.throw(value)  # type: ignore
            # error: Argument 1 to "throw" of "Coroutine" has incompatible type "Exception"; expected "Type[BaseException]"
            # rationale: In micropython, generator.throw() accepts the exception object directly.
        else:
            result = task.send(value)
    except StopIteration as e:  # as e:
        if __debug__:
            log.debug(__name__, "finish: %s", task)
        finalize(task, e.value)
    except Exception as e:
        if __debug__:
            log.exception(__name__, e)
        finalize(task, e)
    else:
        if isinstance(result, Syscall):
            result.handle(task)
        elif result is None:
            schedule(task)
        else:
            if __debug__:
                log.error(__name__, "unknown syscall: %s", result)
        if after_step_hook:
            after_step_hook()
Exemple #3
0
async def cardano_get_address(ctx, msg):
    mnemonic = storage.get_mnemonic()
    root_node = bip32.from_mnemonic_cardano(mnemonic)

    try:
        address, _ = derive_address_and_node(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving address failed")
    mnemonic = None
    root_node = None

    if msg.show_display:
        if not await show_swipable_with_confirmation(ctx,
                                                     address,
                                                     "Export address",
                                                     icon=ui.ICON_SEND,
                                                     icon_color=ui.GREEN):
            raise wire.ActionCancelled("Exporting cancelled")
        else:
            lines = _break_address_n_to_lines(msg.address_n)
            if not await show_swipable_with_confirmation(ctx,
                                                         lines,
                                                         "For BIP32 path",
                                                         icon=ui.ICON_SEND,
                                                         icon_color=ui.GREEN):
                raise wire.ActionCancelled("Exporting cancelled")

    return CardanoAddress(address=address)
Exemple #4
0
async def get_address(ctx, msg):
    await paths.validate_path(ctx, validate_full_path, path=msg.address_n)

    mnemonic = storage.get_mnemonic()
    passphrase = await seed._get_cached_passphrase(ctx)
    root_node = bip32.from_mnemonic_cardano(mnemonic, passphrase)

    try:
        address, _ = derive_address_and_node(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving address failed")
    mnemonic = None
    root_node = None

    if msg.show_display:
        if not await confirm_with_pagination(ctx,
                                             address,
                                             "Export address",
                                             icon=ui.ICON_SEND,
                                             icon_color=ui.GREEN):
            raise wire.ActionCancelled("Exporting cancelled")

    return CardanoAddress(address=address)
Exemple #5
0
async def sign_tx(ctx, msg):
    keychain = await seed.get_keychain(ctx)

    progress.init(msg.transactions_count, "Loading data")

    try:
        attested = len(msg.inputs) * [False]
        input_coins_sum = 0
        # request transactions
        tx_req = CardanoTxRequest()

        for index in range(msg.transactions_count):
            progress.advance()
            tx_ack = await request_transaction(ctx, tx_req, index)
            tx_hash = hashlib.blake2b(data=bytes(tx_ack.transaction),
                                      outlen=32).digest()
            tx_decoded = cbor.decode(tx_ack.transaction)
            for i, input in enumerate(msg.inputs):
                if not attested[i] and input.prev_hash == tx_hash:
                    attested[i] = True
                    outputs = tx_decoded[1]
                    amount = outputs[input.prev_index][1]
                    input_coins_sum += amount

        if not all(attested):
            raise wire.ProcessError("No tx data sent for input " +
                                    str(attested.index(False)))

        transaction = Transaction(msg.inputs, msg.outputs, keychain,
                                  msg.protocol_magic, input_coins_sum)

        # clear progress bar
        display_homescreen()

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, keychain, i.address_n,
                                CURVE)

        # sign the transaction bundle and prepare the result
        tx_body, tx_hash = transaction.serialise_tx()
        tx = CardanoSignedTx(tx_body=tx_body, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    # display the transaction in UI
    if not await show_tx(
            ctx,
            transaction.output_addresses,
            transaction.outgoing_coins,
            transaction.fee,
            transaction.network_name,
            transaction.inputs,
            transaction.outputs,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return tx
Exemple #6
0
async def _sign_stake_pool_registration_tx(
    ctx: wire.Context, msg: CardanoSignTx, keychain: seed.Keychain
) -> CardanoSignedTx:
    """
    We have a separate tx signing flow for stake pool registration because it's a
    transaction where the witnessable entries (i.e. inputs, withdrawals, etc.)
    in the transaction are not supposed to be controlled by the HW wallet, which
    means the user is vulnerable to unknowingly supplying a witness for an UTXO
    or other tx entry they think is external, resulting in the co-signers
    gaining control over their funds (Something SLIP-0019 is dealing with for
    BTC but no similar standard is currently available for Cardano). Hence we
    completely forbid witnessing inputs and other entries of the transaction
    except the stake pool certificate itself and we provide a witness only to the
    user's staking key in the list of pool owners.
    """
    try:
        _validate_stake_pool_registration_tx_structure(msg)

        _ensure_no_signing_inputs(msg.inputs)
        _validate_outputs(keychain, msg.outputs, msg.protocol_magic, msg.network_id)
        _validate_certificates(msg.certificates, msg.protocol_magic, msg.network_id)
        _validate_metadata(msg.metadata)

        await _show_stake_pool_registration_tx(ctx, keychain, msg)

        # sign the transaction bundle and prepare the result
        serialized_tx, tx_hash = _serialize_tx(keychain, msg)
        tx = CardanoSignedTx(serialized_tx=serialized_tx, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    return tx
Exemple #7
0
async def _sign_standard_tx(ctx: wire.Context, msg: CardanoSignTx,
                            keychain: seed.Keychain) -> CardanoSignedTx:
    try:
        for i in msg.inputs:
            await validate_path(ctx, keychain, i.address_n,
                                SCHEMA_ADDRESS.match(i.address_n))

        _validate_outputs(keychain, msg.outputs, msg.protocol_magic,
                          msg.network_id)
        _validate_certificates(msg.certificates, msg.protocol_magic,
                               msg.network_id)
        _validate_withdrawals(msg.withdrawals)
        _validate_metadata(msg.metadata)

        # display the transaction in UI
        await _show_standard_tx(ctx, keychain, msg)

        # sign the transaction bundle and prepare the result
        serialized_tx, tx_hash = _serialize_tx(keychain, msg)
        tx = CardanoSignedTx(serialized_tx=serialized_tx, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    return tx
Exemple #8
0
async def cardano_sign_message(ctx, msg):
    mnemonic = storage.get_mnemonic()
    root_node = bip32.from_mnemonic_cardano(mnemonic)

    try:
        signature = _sign_message(root_node, msg.message, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")
    mnemonic = None
    root_node = None

    if not await show_swipable_with_confirmation(
        ctx, msg.message, "Signing message", ui.ICON_RECEIVE, ui.GREEN
    ):
        raise wire.ActionCancelled("Signing cancelled")

    if not await show_swipable_with_confirmation(
        ctx,
        _break_address_n_to_lines(msg.address_n),
        "With address",
        ui.ICON_RECEIVE,
        ui.GREEN,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return signature
Exemple #9
0
async def sign_tx(
    ctx: wire.Context, msg: CardanoSignTx, keychain: seed.Keychain
) -> CardanoSignedTx:
    try:
        if msg.fee > LOVELACE_MAX_SUPPLY:
            raise wire.ProcessError("Fee is out of range!")

        _validate_network_info(msg.network_id, msg.protocol_magic)

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, keychain, i.address_n, CURVE)

        _validate_outputs(keychain, msg.outputs, msg.protocol_magic, msg.network_id)
        _validate_certificates(msg.certificates)
        _validate_withdrawals(msg.withdrawals)
        _validate_metadata(msg.metadata)

        # display the transaction in UI
        await _show_tx(ctx, keychain, msg)

        # sign the transaction bundle and prepare the result
        serialized_tx, tx_hash = _serialize_tx(keychain, msg)
        tx = CardanoSignedTx(serialized_tx=serialized_tx, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    return tx
Exemple #10
0
async def sign_tx(ctx: wire.Context, msg: messages.CardanoSignTxInit,
                  keychain: seed.Keychain) -> messages.CardanoSignTxFinished:
    signer_type: Type[Signer]
    if msg.signing_mode == CardanoTxSigningMode.ORDINARY_TRANSACTION:
        from .ordinary_signer import OrdinarySigner

        signer_type = OrdinarySigner
    elif msg.signing_mode == CardanoTxSigningMode.POOL_REGISTRATION_AS_OWNER:
        from .pool_owner_signer import PoolOwnerSigner

        signer_type = PoolOwnerSigner
    elif msg.signing_mode == CardanoTxSigningMode.MULTISIG_TRANSACTION:
        from .multisig_signer import MultisigSigner

        signer_type = MultisigSigner
    elif msg.signing_mode == CardanoTxSigningMode.PLUTUS_TRANSACTION:
        from .plutus_signer import PlutusSigner

        signer_type = PlutusSigner
    else:
        raise RuntimeError  # should be unreachable

    signer = signer_type(ctx, msg, keychain)

    try:
        await signer.sign()
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    return messages.CardanoSignTxFinished()
Exemple #11
0
async def session_handler(iface, sid):
    reader = None
    ctx = Context(iface, sid)
    while True:
        try:
            # wait for new message, if needed, and find handler
            if not reader:
                reader = ctx.getreader()
                await reader.aopen()
            try:
                handler, args = workflow_handlers[reader.type]
            except KeyError:
                handler, args = unexpected_msg, ()

            w = handler(ctx, reader, *args)
            try:
                workflow.onstart(w)
                await w
            finally:
                workflow.onclose(w)

        except UnexpectedMessageError as exc:
            # retry with opened reader from the exception
            reader = exc.reader
            continue
        except FailureError as exc:
            # we log FailureError as warning, not as exception
            log.warning(__name__, 'failure: %s', exc.message)
        except Exception as exc:
            # sessions are never closed by raised exceptions
            log.exception(__name__, exc)

        # read new message in next iteration
        reader = None
Exemple #12
0
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)

    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)
Exemple #13
0
async def bootscreen() -> None:
    ui.display.orientation(storage_device.get_rotation())
    salt_auth_key = storage_device.get_sd_salt_auth_key()

    while True:
        try:
            if salt_auth_key is not None or config.has_pin():
                await lockscreen()

            if salt_auth_key is not None:
                salt = await request_sd_salt(None, salt_auth_key
                                             )  # type: Optional[bytearray]
            else:
                salt = None

            if not config.has_pin():
                config.unlock(pin_to_int(""), salt)
                storage.init_unlocked()
                return

            label = "Enter your PIN"
            while True:
                pin = await request_pin(label, config.get_pin_rem())
                if config.unlock(pin_to_int(pin), salt):
                    storage.init_unlocked()
                    return
                else:
                    label = "Wrong PIN, enter again"
        except (OSError, PinCancelled, SdProtectCancelled) as e:
            if __debug__:
                log.exception(__name__, e)
        except BaseException as e:
            utils.halt(e.__class__.__name__)
Exemple #14
0
def dispatch(report, open_callback, close_callback, unknown_callback):
    '''
    Dispatches payloads of reports adhering to one of the wire codecs.
    '''

    if codec_v1.detect(report):
        marker, session_id, report_data = codec_v1.parse_report(report)
    else:
        marker, session_id, report_data = codec_v2.parse_report(report)

        if marker == codec_v2.REP_MARKER_OPEN:
            log.debug(__name__, 'request for new session')
            open_callback()
            return
        elif marker == codec_v2.REP_MARKER_CLOSE:
            log.debug(__name__, 'request for closing session %x', session_id)
            close_callback(session_id)
            return

    if session_id not in readers:
        log.warning(__name__, 'report on unknown session %x', session_id)
        unknown_callback(session_id, report_data)
        return

    log.debug(__name__, 'report on session %x', session_id)
    reader = readers[session_id]

    try:
        reader.send(report_data)
    except StopIteration:
        readers.pop(session_id)
    except Exception as e:
        log.exception(__name__, e)
Exemple #15
0
async def sign_tx(ctx: wire.Context, msg: CardanoSignTx,
                  keychain: seed.Keychain) -> CardanoSignedTx:
    if msg.fee > LOVELACE_MAX_SUPPLY:
        raise wire.ProcessError("Fee is out of range!")

    validate_network_info(msg.network_id, msg.protocol_magic)

    try:
        if _has_stake_pool_registration(msg):
            cborized_tx, tx_hash = await _sign_stake_pool_registration_tx(
                ctx, msg, keychain)
        else:
            cborized_tx, tx_hash = await _sign_ordinary_tx(ctx, msg, keychain)

        signed_tx_chunks = cbor.encode_chunked(cborized_tx, MAX_TX_CHUNK_SIZE)

        for signed_tx_chunk in signed_tx_chunks:
            response = CardanoSignedTxChunk(signed_tx_chunk=signed_tx_chunk)
            await ctx.call(response, CardanoSignedTxChunkAck)

        return CardanoSignedTx(tx_hash=tx_hash, serialized_tx=None)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")
Exemple #16
0
async def handle_session(iface: WireInterface,
                         session_id: int,
                         is_debug_session: bool = False) -> None:
    if __debug__ and is_debug_session:
        ctx_buffer = WIRE_BUFFER_DEBUG
    else:
        ctx_buffer = WIRE_BUFFER
    ctx = Context(iface, session_id, ctx_buffer)
    next_msg: codec_v1.Message | None = None

    if __debug__ and is_debug_session:
        import apps.debug

        apps.debug.DEBUG_CONTEXT = ctx

    # Take a mark of modules that are imported at this point, so we can
    # roll back and un-import any others.
    modules = utils.unimport_begin()
    while True:
        try:
            if next_msg is None:
                # If the previous run did not keep an unprocessed message for us,
                # wait for a new one coming from the wire.
                try:
                    msg = await ctx.read_from_wire()
                except codec_v1.CodecError as exc:
                    if __debug__:
                        log.exception(__name__, exc)
                    await ctx.write(failure(exc))
                    continue

            else:
                # Process the message from previous run.
                msg = next_msg
                next_msg = None

            try:
                next_msg = await _handle_single_message(
                    ctx, msg, use_workflow=not is_debug_session)
            finally:
                if not __debug__ or not is_debug_session:
                    # Unload modules imported by the workflow.  Should not raise.
                    # This is not done for the debug session because the snapshot taken
                    # in a debug session would clear modules which are in use by the
                    # workflow running on wire.
                    utils.unimport_end(modules)

                    if next_msg is None:
                        # Shut down the loop if there is no next message waiting.
                        # Let the session be restarted from `main`.
                        loop.clear()
                        return

        except Exception as exc:
            # Log and try again. The session handler can only exit explicitly via
            # loop.clear() above.
            if __debug__:
                log.exception(__name__, exc)
Exemple #17
0
 async def _wait(self, child, index):
     try:
         result = await child
     except Exception as e:
         self._finish(child, index, e)
         if __debug__:
             log.exception(__name__, e)
     else:
         self._finish(child, index, result)
Exemple #18
0
async def handle_reports(iface: io.HID):
    while True:
        try:
            req = await read_cmd(iface)
            if req is None:
                continue
            resp = dispatch_cmd(req)
            send_cmd(resp, iface)
        except Exception as e:
            log.exception(__name__, e)
Exemple #19
0
    def load_icon(self, rp_id_hash: bytes) -> None:
        from trezor import res
        from apps.webauthn.knownapps import knownapps

        try:
            namepart = knownapps[rp_id_hash]["label"].lower().replace(" ", "_")
            icon = res.load("apps/webauthn/res/icon_%s.toif" % namepart)
        except Exception as e:
            icon = res.load("apps/webauthn/res/icon_webauthn.toif")
            if __debug__:
                log.exception(__name__, e)
        self.app_icon = icon
Exemple #20
0
async def sign_tx(ctx: wire.Context, msg: CardanoSignTxInit,
                  keychain: seed.Keychain) -> CardanoSignTxFinished:
    await show_transaction_signing_mode(ctx, msg.signing_mode)

    is_network_id_verifiable = await _validate_tx_signing_request(ctx, msg)

    # inputs, outputs and fee are mandatory fields, count the number of optional fields present
    tx_body_map_item_count = 3 + sum((
        msg.ttl is not None,
        msg.certificates_count > 0,
        msg.withdrawals_count > 0,
        msg.has_auxiliary_data,
        msg.validity_interval_start is not None,
        msg.minting_asset_groups_count > 0,
        msg.include_network_id,
        msg.script_data_hash is not None,
        msg.collateral_inputs_count > 0,
        msg.required_signers_count > 0,
    ))

    account_path_checker = AccountPathChecker()

    hash_fn = hashlib.blake2b(outlen=32)
    tx_dict: HashBuilderDict[int, Any] = HashBuilderDict(
        tx_body_map_item_count, INVALID_TX_SIGNING_REQUEST)
    tx_dict.start(hash_fn)
    with tx_dict:
        await _process_transaction(ctx, msg, keychain, tx_dict,
                                   account_path_checker)

    tx_hash = hash_fn.digest()
    await _confirm_transaction(ctx, msg, is_network_id_verifiable, tx_hash)

    try:
        response_after_witness_requests = await _process_witness_requests(
            ctx,
            keychain,
            tx_hash,
            msg.witness_requests_count,
            msg.signing_mode,
            msg.minting_asset_groups_count > 0,
            account_path_checker,
        )

        await ctx.call(response_after_witness_requests, CardanoTxHostAck)

        await ctx.call(CardanoTxBodyHash(tx_hash=tx_hash), CardanoTxHostAck)
        return CardanoSignTxFinished()

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")
Exemple #21
0
def _wrap_protobuf_load(
    buffer: bytes,
    expected_type: type[LoadedMessageType],
) -> LoadedMessageType:
    try:
        return protobuf.decode(buffer, expected_type, experimental_enabled)
    except Exception as e:
        if __debug__:
            log.exception(__name__, e)
        if e.args:
            raise DataError("Failed to decode message: {}".format(e.args[0]))
        else:
            raise DataError("Failed to decode message")
Exemple #22
0
async def cardano_get_public_key(ctx, msg):
    mnemonic = storage.get_mnemonic()
    root_node = bip32.from_mnemonic_cardano(mnemonic)

    try:
        key = _get_public_key(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving public key failed")
    mnemonic = None
    root_node = None

    return key
Exemple #23
0
async def sign_tx(ctx, msg):
    mnemonic = storage.get_mnemonic()
    passphrase = await seed._get_cached_passphrase(ctx)
    root_node = bip32.from_mnemonic_cardano(mnemonic, passphrase)

    progress.init(msg.transactions_count, "Loading data")

    try:
        # request transactions
        transactions = []
        tx_req = CardanoTxRequest()
        for index in range(msg.transactions_count):
            progress.advance()
            tx_ack = await request_transaction(ctx, tx_req, index)
            transactions.append(tx_ack.transaction)

        # clear progress bar
        display_homescreen()

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, path=i.address_n)

        # sign the transaction bundle and prepare the result
        transaction = Transaction(msg.inputs, msg.outputs, transactions,
                                  root_node, msg.network)
        tx_body, tx_hash = transaction.serialise_tx()
        tx = CardanoSignedTx(tx_body=tx_body, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    # display the transaction in UI
    if not await show_tx(
            ctx,
            transaction.output_addresses,
            transaction.outgoing_coins,
            transaction.change_derivation_paths,
            transaction.change_coins,
            transaction.fee,
            len(tx_body),
            transaction.network_name,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return tx
Exemple #24
0
async def get_public_key(ctx, msg):
    keychain = await seed.get_keychain(ctx)

    await paths.validate_path(
        ctx, paths.validate_path_for_get_public_key, path=msg.address_n, slip44_id=1815
    )

    try:
        key = _get_public_key(keychain, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving public key failed")

    if msg.show_display:
        await layout.show_pubkey(ctx, key.node.public_key)
    return key
async def get_public_key(ctx, msg):
    mnemonic = storage.get_mnemonic()
    passphrase = await seed._get_cached_passphrase(ctx)
    root_node = bip32.from_mnemonic_cardano(mnemonic, passphrase)

    try:
        key = _get_public_key(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving public key failed")
    mnemonic = None
    root_node = None

    if msg.show_display:
        await layout.show_pubkey(ctx, key.node.public_key)
    return key
Exemple #26
0
async def bootscreen():
    while True:
        try:
            if not config.has_pin():
                config.unlock(pin_to_int(""), show_pin_timeout)
                return
            await lockscreen()
            label = None
            while True:
                pin = await request_pin(label)
                if config.unlock(pin_to_int(pin), show_pin_timeout):
                    return
                else:
                    label = "Wrong PIN, enter again"
        except Exception as e:
            if __debug__:
                log.exception(__name__, e)
Exemple #27
0
async def sign_tx(ctx, msg):
    keychain = await seed.get_keychain(ctx)

    progress.init(msg.transactions_count, "Loading data")

    try:
        # request transactions
        transactions = []
        tx_req = CardanoTxRequest()
        for index in range(msg.transactions_count):
            progress.advance()
            tx_ack = await request_transaction(ctx, tx_req, index)
            transactions.append(tx_ack.transaction)

        # clear progress bar
        display_homescreen()

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, keychain, i.address_n,
                                CURVE)

        # sign the transaction bundle and prepare the result
        transaction = Transaction(msg.inputs, msg.outputs, transactions,
                                  keychain, msg.protocol_magic)
        tx_body, tx_hash = transaction.serialise_tx()
        tx = CardanoSignedTx(tx_body=tx_body, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    # display the transaction in UI
    if not await show_tx(
            ctx,
            transaction.output_addresses,
            transaction.outgoing_coins,
            transaction.fee,
            transaction.network_name,
            transaction.inputs,
            transaction.outputs,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return tx
Exemple #28
0
def _wrap_protobuf_load(
    buffer: bytes,
    expected_type: type[LoadedMessageType],
) -> LoadedMessageType:
    try:
        msg = protobuf.decode(buffer, expected_type, experimental_enabled)
        if __debug__ and utils.EMULATOR:
            log.debug(
                __name__, "received message contents:\n%s", utils.dump_protobuf(msg)
            )
        return msg
    except Exception as e:
        if __debug__:
            log.exception(__name__, e)
        if e.args:
            raise DataError("Failed to decode message: " + " ".join(e.args))
        else:
            raise DataError("Failed to decode message")
async def get_address(ctx, msg, keychain: seed.Keychain):
    await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n,
                              CURVE)

    try:
        address, _ = derive_address_and_node(keychain, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving address failed")
    if msg.show_display:
        desc = address_n_to_str(msg.address_n)
        while True:
            if await show_address(ctx, address, desc=desc):
                break
            if await show_qr(ctx, address, desc=desc):
                break

    return CardanoAddress(address=address)
Exemple #30
0
async def bootscreen():
    while True:
        try:
            if not config.has_pin():
                config.unlock(pin_to_int(""))
                storage.init_unlocked()
                return
            await lockscreen()
            label = None
            while True:
                pin = await request_pin(label, config.get_pin_rem())
                if config.unlock(pin_to_int(pin)):
                    storage.init_unlocked()
                    return
                else:
                    label = "Wrong PIN, enter again"
        except Exception as e:
            if __debug__:
                log.exception(__name__, e)