Esempio n. 1
0
    async def _process_collateral_return(self) -> None:
        output: messages.CardanoTxOutput = await self.ctx.call(
            messages.CardanoTxItemAck(), messages.CardanoTxOutput)
        self._validate_collateral_return(output)
        should_show_init = self._should_show_collateral_return_init(output)
        should_show_tokens = self._should_show_collateral_return_tokens(output)
        if should_show_init:
            await self._show_collateral_return_init(output)

        # Datums and reference scripts are forbidden, see _validate_collateral_return.
        output_items_count = 2
        if output.format == CardanoTxOutputSerializationFormat.ARRAY_LEGACY:
            output_list: HashBuilderList = HashBuilderList(output_items_count)
            with self.tx_dict.add(TX_BODY_KEY_COLLATERAL_RETURN, output_list):
                await self._process_legacy_output(output_list, output,
                                                  should_show_tokens)
        elif output.format == CardanoTxOutputSerializationFormat.MAP_BABBAGE:
            output_dict: HashBuilderDict[int, Any] = HashBuilderDict(
                output_items_count,
                wire.ProcessError("Invalid collateral return"))
            with self.tx_dict.add(TX_BODY_KEY_COLLATERAL_RETURN, output_dict):
                await self._process_babbage_output(output_dict, output,
                                                   should_show_tokens)
        else:
            raise RuntimeError  # should be unreachable
Esempio n. 2
0
 async def _process_inputs(
         self, inputs_list: HashBuilderList[tuple[bytes, int]]) -> None:
     for _ in range(self.msg.inputs_count):
         input: messages.CardanoTxInput = await self.ctx.call(
             messages.CardanoTxItemAck(), messages.CardanoTxInput)
         self._validate_input(input)
         await self._show_input(input)
         inputs_list.append((input.prev_hash, input.prev_index))
Esempio n. 3
0
 async def _process_reference_inputs(
         self, reference_inputs_list: HashBuilderList[tuple[bytes,
                                                            int]]) -> None:
     for _ in range(self.msg.reference_inputs_count):
         reference_input: messages.CardanoTxReferenceInput = await self.ctx.call(
             messages.CardanoTxItemAck(), messages.CardanoTxReferenceInput)
         self._validate_reference_input(reference_input)
         await self._show_if_showing_details(
             layout.confirm_reference_input(self.ctx, reference_input))
         reference_inputs_list.append(
             (reference_input.prev_hash, reference_input.prev_index))
Esempio n. 4
0
 async def _process_pool_relays(
     self,
     relays_list: HashBuilderList[cbor.CborSequence],
     relays_count: int,
 ) -> None:
     for _ in range(relays_count):
         relay: messages.CardanoPoolRelayParameters = await self.ctx.call(
             messages.CardanoTxItemAck(),
             messages.CardanoPoolRelayParameters)
         certificates.validate_pool_relay(relay)
         relays_list.append(certificates.cborize_pool_relay(relay))
Esempio n. 5
0
 async def _process_withdrawals(
         self, withdrawals_dict: HashBuilderDict[bytes, int]) -> None:
     for _ in range(self.msg.withdrawals_count):
         withdrawal: messages.CardanoTxWithdrawal = await self.ctx.call(
             messages.CardanoTxItemAck(), messages.CardanoTxWithdrawal)
         self._validate_withdrawal(withdrawal)
         address_bytes = self._derive_withdrawal_address_bytes(withdrawal)
         await self._show_if_showing_details(
             layout.confirm_withdrawal(self.ctx, withdrawal, address_bytes,
                                       self.msg.network_id))
         withdrawals_dict.add(address_bytes, withdrawal.amount)
Esempio n. 6
0
    async def _process_required_signers(
            self, required_signers_list: HashBuilderList[bytes]) -> None:
        for _ in range(self.msg.required_signers_count):
            required_signer: messages.CardanoTxRequiredSigner = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoTxRequiredSigner)
            self._validate_required_signer(required_signer)
            await self._show_if_showing_details(
                layout.confirm_required_signer(self.ctx, required_signer))

            key_hash = required_signer.key_hash or get_public_key_hash(
                self.keychain, required_signer.key_path)
            required_signers_list.append(key_hash)
Esempio n. 7
0
    async def _process_outputs(self, outputs_list: HashBuilderList) -> None:
        total_amount = 0
        for _ in range(self.msg.outputs_count):
            output: messages.CardanoTxOutput = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoTxOutput)
            await self._process_output(outputs_list, output)

            total_amount += output.amount

        if total_amount > LOVELACE_MAX_SUPPLY:
            raise wire.ProcessError(
                "Total transaction amount is out of range!")
Esempio n. 8
0
    async def _process_minting(
            self, minting_dict: HashBuilderDict[bytes,
                                                HashBuilderDict]) -> None:
        token_minting: messages.CardanoTxMint = await self.ctx.call(
            messages.CardanoTxItemAck(), messages.CardanoTxMint)

        await layout.warn_tx_contains_mint(self.ctx)

        for _ in range(token_minting.asset_groups_count):
            asset_group: messages.CardanoAssetGroup = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoAssetGroup)
            self._validate_asset_group(asset_group, is_mint=True)

            tokens: HashBuilderDict[bytes, int] = HashBuilderDict(
                asset_group.tokens_count,
                wire.ProcessError("Invalid mint token bundle"))
            with minting_dict.add(asset_group.policy_id, tokens):
                await self._process_minting_tokens(
                    tokens,
                    asset_group.policy_id,
                    asset_group.tokens_count,
                )
Esempio n. 9
0
    async def _process_minting_tokens(
        self,
        tokens: HashBuilderDict[bytes, int],
        policy_id: bytes,
        tokens_count: int,
    ) -> None:
        for _ in range(tokens_count):
            token: messages.CardanoToken = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoToken)
            self._validate_token(token, is_mint=True)
            await layout.confirm_token_minting(self.ctx, policy_id, token)

            assert token.mint_amount is not None  # _validate_token
            tokens.add(token.asset_name_bytes, token.mint_amount)
Esempio n. 10
0
    async def _process_pool_owners(self,
                                   pool_owners_list: HashBuilderList[bytes],
                                   owners_count: int) -> None:
        owners_as_path_count = 0
        for _ in range(owners_count):
            owner: messages.CardanoPoolOwner = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoPoolOwner)
            certificates.validate_pool_owner(owner, self.account_path_checker)
            await self._show_pool_owner(owner)
            pool_owners_list.append(
                certificates.cborize_pool_owner(self.keychain, owner))

            if owner.staking_key_path:
                owners_as_path_count += 1

        certificates.assert_cond(owners_as_path_count == 1)
Esempio n. 11
0
    async def _process_witness_requests(
            self, tx_hash: bytes) -> CardanoTxResponseType:
        response: CardanoTxResponseType = messages.CardanoTxItemAck()

        for _ in range(self.msg.witness_requests_count):
            witness_request = await self.ctx.call(
                response, messages.CardanoTxWitnessRequest)
            self._validate_witness_request(witness_request)
            path = witness_request.path
            await self._show_witness_request(path)
            if seed.is_byron_path(path):
                response = self._get_byron_witness(path, tx_hash)
            else:
                response = self._get_shelley_witness(path, tx_hash)

        return response
Esempio n. 12
0
    async def _process_tokens(
        self,
        tokens_dict: HashBuilderDict[bytes, int],
        policy_id: bytes,
        tokens_count: int,
        should_show_tokens: bool,
    ) -> None:
        for _ in range(tokens_count):
            token: messages.CardanoToken = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoToken)
            self._validate_token(token)
            if should_show_tokens:
                await layout.confirm_sending_token(self.ctx, policy_id, token)

            assert token.amount is not None  # _validate_token
            tokens_dict.add(token.asset_name_bytes, token.amount)
Esempio n. 13
0
    async def _process_asset_groups(
        self,
        asset_groups_dict: HashBuilderDict[bytes, HashBuilderDict[bytes, int]],
        asset_groups_count: int,
        should_show_tokens: bool,
    ) -> None:
        for _ in range(asset_groups_count):
            asset_group: messages.CardanoAssetGroup = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoAssetGroup)
            self._validate_asset_group(asset_group)

            tokens: HashBuilderDict[bytes, int] = HashBuilderDict(
                asset_group.tokens_count,
                wire.ProcessError("Invalid token bundle in output"),
            )
            with asset_groups_dict.add(asset_group.policy_id, tokens):
                await self._process_tokens(
                    tokens,
                    asset_group.policy_id,
                    asset_group.tokens_count,
                    should_show_tokens,
                )
Esempio n. 14
0
    async def _process_certificates(
            self, certificates_list: HashBuilderList) -> None:
        for _ in range(self.msg.certificates_count):
            certificate: messages.CardanoTxCertificate = await self.ctx.call(
                messages.CardanoTxItemAck(), messages.CardanoTxCertificate)
            self._validate_certificate(certificate)
            await self._show_certificate(certificate)

            if certificate.type == CardanoCertificateType.STAKE_POOL_REGISTRATION:
                pool_parameters = certificate.pool_parameters
                assert pool_parameters is not None  # _validate_certificate

                pool_items_list: HashBuilderList = HashBuilderList(
                    POOL_REGISTRATION_CERTIFICATE_ITEMS_COUNT)
                with certificates_list.append(pool_items_list):
                    for item in certificates.cborize_pool_registration_init(
                            certificate):
                        pool_items_list.append(item)

                    pool_owners_list: HashBuilderList[bytes] = HashBuilderList(
                        pool_parameters.owners_count)
                    with pool_items_list.append(pool_owners_list):
                        await self._process_pool_owners(
                            pool_owners_list, pool_parameters.owners_count)

                    relays_list: HashBuilderList[
                        cbor.CborSequence] = HashBuilderList(
                            pool_parameters.relays_count)
                    with pool_items_list.append(relays_list):
                        await self._process_pool_relays(
                            relays_list, pool_parameters.relays_count)

                    pool_items_list.append(
                        certificates.cborize_pool_metadata(
                            pool_parameters.metadata))
            else:
                certificates_list.append(
                    certificates.cborize(self.keychain, certificate))
Esempio n. 15
0
    async def _process_auxiliary_data(self) -> None:
        data: messages.CardanoTxAuxiliaryData = await self.ctx.call(
            messages.CardanoTxItemAck(), messages.CardanoTxAuxiliaryData)
        auxiliary_data.validate(data)

        (
            auxiliary_data_hash,
            auxiliary_data_supplement,
        ) = auxiliary_data.get_hash_and_supplement(self.keychain, data,
                                                   self.msg.protocol_magic,
                                                   self.msg.network_id)
        await auxiliary_data.show(
            self.ctx,
            self.keychain,
            auxiliary_data_hash,
            data.catalyst_registration_parameters,
            self.msg.protocol_magic,
            self.msg.network_id,
            self.should_show_details,
        )
        self.tx_dict.add(TX_BODY_KEY_AUXILIARY_DATA, auxiliary_data_hash)

        await self.ctx.call(auxiliary_data_supplement,
                            messages.CardanoTxHostAck)
Esempio n. 16
0
    async def _process_reference_script(
        self,
        reference_script_cbor: HashBuilderEmbeddedCBOR,
        reference_script_size: int,
        should_show: bool,
    ) -> None:
        assert reference_script_size > 0

        chunks_count = self._get_chunks_count(reference_script_size)
        for chunk_number in range(chunks_count):
            chunk: messages.CardanoTxReferenceScriptChunk = await self.ctx.call(
                messages.CardanoTxItemAck(),
                messages.CardanoTxReferenceScriptChunk)
            self._validate_chunk(
                chunk.data,
                chunk_number,
                chunks_count,
                wire.ProcessError("Invalid reference script chunk"),
            )
            if chunk_number == 0 and should_show:
                await self._show_if_showing_details(
                    layout.confirm_reference_script(self.ctx, chunk.data,
                                                    reference_script_size))
            reference_script_cbor.add(chunk.data)
Esempio n. 17
0
    async def _process_inline_datum(
        self,
        inline_datum_cbor: HashBuilderEmbeddedCBOR,
        inline_datum_size: int,
        should_show: bool,
    ) -> None:
        assert inline_datum_size > 0

        chunks_count = self._get_chunks_count(inline_datum_size)
        for chunk_number in range(chunks_count):
            chunk: messages.CardanoTxInlineDatumChunk = await self.ctx.call(
                messages.CardanoTxItemAck(),
                messages.CardanoTxInlineDatumChunk)
            self._validate_chunk(
                chunk.data,
                chunk_number,
                chunks_count,
                wire.ProcessError("Invalid inline datum chunk"),
            )
            if chunk_number == 0 and should_show:
                await self._show_if_showing_details(
                    layout.confirm_inline_datum(self.ctx, chunk.data,
                                                inline_datum_size))
            inline_datum_cbor.add(chunk.data)