# This file is part of the Trezor project. # # Copyright (C) 2012-2019 SatoshiLabs and contributors # # This library is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License version 3 # as published by the Free Software Foundation. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the License along with this library. # If not, see . import json import click from .. import cardano, messages, tools from . import ChoiceType, with_client PATH_HELP = "BIP-32 path to key, e.g. m/44'/1815'/0'/0/0" @click.group(name="cardano") def cli(): """Cardano commands.""" @cli.command() @click.argument("file", type=click.File("r")) @click.option("-f", "--file", "_ignore", is_flag=True, hidden=True, expose_value=False) @click.option( "-s", "--signing-mode", required=True, type=ChoiceType({m.name: m for m in messages.CardanoTxSigningMode}), ) @click.option( "-p", "--protocol-magic", type=int, default=cardano.PROTOCOL_MAGICS["mainnet"] ) @click.option("-N", "--network-id", type=int, default=cardano.NETWORK_IDS["mainnet"]) @click.option("-t", "--testnet", is_flag=True) @with_client def sign_tx(client, file, signing_mode, protocol_magic, network_id, testnet): """Sign Cardano transaction.""" transaction = json.load(file) if testnet: protocol_magic = cardano.PROTOCOL_MAGICS["testnet"] network_id = cardano.NETWORK_IDS["testnet"] inputs = [cardano.parse_input(input) for input in transaction["inputs"]] outputs = [cardano.parse_output(output) for output in transaction["outputs"]] fee = transaction["fee"] ttl = transaction.get("ttl") validity_interval_start = transaction.get("validity_interval_start") certificates = [ cardano.parse_certificate(certificate) for certificate in transaction.get("certificates", ()) ] withdrawals = [ cardano.parse_withdrawal(withdrawal) for withdrawal in transaction.get("withdrawals", ()) ] auxiliary_data = cardano.parse_auxiliary_data(transaction.get("auxiliary_data")) mint = cardano.parse_mint(transaction.get("mint", ())) additional_witness_requests = [ cardano.parse_additional_witness_request(p) for p in transaction["additional_witness_requests"] ] sign_tx_response = cardano.sign_tx( client, signing_mode, inputs, outputs, fee, ttl, validity_interval_start, certificates, withdrawals, protocol_magic, network_id, auxiliary_data, mint, additional_witness_requests, ) sign_tx_response["tx_hash"] = sign_tx_response["tx_hash"].hex() sign_tx_response["witnesses"] = [ { "type": witness["type"], "pub_key": witness["pub_key"].hex(), "signature": witness["signature"].hex(), "chain_code": witness["chain_code"].hex() if witness["chain_code"] is not None else None, } for witness in sign_tx_response["witnesses"] ] auxiliary_data_supplement = sign_tx_response.get("auxiliary_data_supplement") if auxiliary_data_supplement: auxiliary_data_supplement["auxiliary_data_hash"] = auxiliary_data_supplement[ "auxiliary_data_hash" ].hex() catalyst_signature = auxiliary_data_supplement.get("catalyst_signature") if catalyst_signature: auxiliary_data_supplement["catalyst_signature"] = catalyst_signature.hex() sign_tx_response["auxiliary_data_supplement"] = auxiliary_data_supplement return sign_tx_response @cli.command() @click.option("-n", "--address", type=str, default=None, help=PATH_HELP) @click.option("-d", "--show-display", is_flag=True) @click.option( "-t", "--address-type", type=ChoiceType({m.name: m for m in messages.CardanoAddressType}), default="BASE", ) @click.option("-s", "--staking-address", type=str, default=None) @click.option("-h", "--staking-key-hash", type=str, default=None) @click.option("-b", "--block_index", type=int, default=None) @click.option("-x", "--tx_index", type=int, default=None) @click.option("-c", "--certificate_index", type=int, default=None) @click.option("--script-payment-hash", type=str, default=None) @click.option("--script-staking-hash", type=str, default=None) @click.option( "-p", "--protocol-magic", type=int, default=cardano.PROTOCOL_MAGICS["mainnet"] ) @click.option("-N", "--network-id", type=int, default=cardano.NETWORK_IDS["mainnet"]) @click.option("-e", "--testnet", is_flag=True) @with_client def get_address( client, address, address_type, staking_address, staking_key_hash, block_index, tx_index, certificate_index, script_payment_hash, script_staking_hash, protocol_magic, network_id, show_display, testnet, ): """ Get Cardano address. All address types require the address, address_type, protocol_magic and network_id parameters. When deriving a base address you can choose to include staking info as staking_address or staking_key_hash - one has to be chosen. When deriving a pointer address you need to specify the block_index, tx_index and certificate_index parameters. Byron, enterprise and reward addresses only require the general parameters. """ if testnet: protocol_magic = cardano.PROTOCOL_MAGICS["testnet"] network_id = cardano.NETWORK_IDS["testnet"] staking_key_hash_bytes = cardano.parse_optional_bytes(staking_key_hash) script_payment_hash_bytes = cardano.parse_optional_bytes(script_payment_hash) script_staking_hash_bytes = cardano.parse_optional_bytes(script_staking_hash) address_parameters = cardano.create_address_parameters( address_type, tools.parse_path(address), tools.parse_path(staking_address), staking_key_hash_bytes, block_index, tx_index, certificate_index, script_payment_hash_bytes, script_staking_hash_bytes, ) return cardano.get_address( client, address_parameters, protocol_magic, network_id, show_display ) @cli.command() @click.option("-n", "--address", required=True, help=PATH_HELP) @with_client def get_public_key(client, address): """Get Cardano public key.""" address_n = tools.parse_path(address) return cardano.get_public_key(client, address_n) @cli.command() @click.argument("file", type=click.File("r")) @click.option( "-d", "--display-format", type=ChoiceType({m.name: m for m in messages.CardanoNativeScriptHashDisplayFormat}), default="HIDE", ) @with_client def get_native_script_hash(client, file, display_format): """Get Cardano native script hash.""" native_script_json = json.load(file) native_script = cardano.parse_native_script(native_script_json) return cardano.get_native_script_hash(client, native_script, display_format)