diff --git a/python/src/trezorlib/cardano.py b/python/src/trezorlib/cardano.py index f67ae42e54..a99adc6ecf 100644 --- a/python/src/trezorlib/cardano.py +++ b/python/src/trezorlib/cardano.py @@ -24,6 +24,8 @@ NETWORK_IDS = {"mainnet": 1, "testnet": 0} REQUIRED_FIELDS_TRANSACTION = ("inputs", "outputs") REQUIRED_FIELDS_INPUT = ("path", "prev_hash", "prev_index") +REQUIRED_FIELDS_CERTIFICATE = ("path", "type") +REQUIRED_FIELDS_WITHDRAWAL = ("path", "amount") INCOMPLETE_OUTPUT_ERROR_MESSAGE = "The output is missing some fields" @@ -128,6 +130,44 @@ def _create_change_output(output) -> messages.CardanoTxOutputType: ) +def create_certificate(certificate) -> messages.CardanoTxCertificateType: + if not all(certificate.get(k) is not None for k in REQUIRED_FIELDS_CERTIFICATE): + raise ValueError("The certificate is missing some fields") + + path = certificate["path"] + certificate_type = certificate["type"] + + if certificate_type == messages.CardanoCertificateType.STAKE_DELEGATION: + if certificate.get("pool") is None: + raise ValueError("The certificate is missing some fields") + + pool = certificate["pool"] + return messages.CardanoTxCertificateType( + type=certificate_type, + path=tools.parse_path(path), + pool=bytes.fromhex(pool), + ) + elif ( + certificate_type == messages.CardanoCertificateType.STAKE_REGISTRATION + or certificate_type == messages.CardanoCertificateType.STAKE_DEREGISTRATION + ): + return messages.CardanoTxCertificateType( + type=certificate_type, path=tools.parse_path(path), + ) + else: + raise ValueError("Unknown certificate type") + + +def create_withdrawal(withdrawal) -> messages.CardanoTxWithdrawalType: + if not all(withdrawal.get(k) is not None for k in REQUIRED_FIELDS_WITHDRAWAL): + raise ValueError("Withdrawal is missing some fields") + + path = withdrawal["path"] + return messages.CardanoTxWithdrawalType( + path=tools.parse_path(path), amount=int(withdrawal["amount"]), + ) + + # ====== Client functions ====== # @@ -161,6 +201,9 @@ def sign_tx( outputs: List[messages.CardanoTxOutputType], fee: int, ttl: int, + certificates: List[messages.CardanoTxCertificateType], + withdrawals: List[messages.CardanoTxWithdrawalType], + metadata_hash: bytes, protocol_magic: int, network_id: int, ) -> messages.CardanoSignedTx: @@ -170,6 +213,9 @@ def sign_tx( outputs=outputs, fee=fee, ttl=ttl, + certificates=certificates, + withdrawals=withdrawals, + metadata_hash=metadata_hash, protocol_magic=protocol_magic, network_id=network_id, ) diff --git a/python/src/trezorlib/cli/cardano.py b/python/src/trezorlib/cli/cardano.py index 9937bbba08..f0a6ce4db7 100644 --- a/python/src/trezorlib/cli/cardano.py +++ b/python/src/trezorlib/cli/cardano.py @@ -63,9 +63,29 @@ def sign_tx(client, file, protocol_magic, network_id, testnet): outputs = [cardano.create_output(output) for output in transaction["outputs"]] fee = transaction["fee"] ttl = transaction["ttl"] + certificates = [ + cardano.create_certificate(certificate) + for certificate in transaction.get("certificates", ()) + ] + withdrawals = [ + cardano.create_withdrawal(withdrawal) + for withdrawal in transaction.get("withdrawals", ()) + ] + metadata_hash = None + if transaction.get("metadata_hash"): + metadata_hash = bytes.fromhex(transaction["metadata_hash"]) signed_transaction = cardano.sign_tx( - client, inputs, outputs, fee, ttl, protocol_magic, network_id + client, + inputs, + outputs, + fee, + ttl, + certificates, + withdrawals, + metadata_hash, + protocol_magic, + network_id, ) return {