diff --git a/core/embed/extmod/modtrezormintlayer/modtrezormintlayer.h b/core/embed/extmod/modtrezormintlayer/modtrezormintlayer.h index e339a0667..3a63e5cb7 100644 --- a/core/embed/extmod/modtrezormintlayer/modtrezormintlayer.h +++ b/core/embed/extmod/modtrezormintlayer/modtrezormintlayer.h @@ -625,7 +625,7 @@ STATIC mp_obj_t mod_trezormintlayer_utils_mintlayer_encode_htlc_output( } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( - mod_trezormintlayer_utils_mintlayer_encode_htlc_output_obj, 5, 5, + mod_trezormintlayer_utils_mintlayer_encode_htlc_output_obj, 7, 7, mod_trezormintlayer_utils_mintlayer_encode_htlc_output); /// def encode_anyone_can_take_output(destination: bytes, ask_amount: bytes, diff --git a/core/embed/rust/src/mintlayer/mod.rs b/core/embed/rust/src/mintlayer/mod.rs index 141e81e34..4b10a4bf6 100644 --- a/core/embed/rust/src/mintlayer/mod.rs +++ b/core/embed/rust/src/mintlayer/mod.rs @@ -463,11 +463,10 @@ extern "C" fn mintlayer_encode_create_stake_pool_output( let vrf_public_key = unsafe { core::slice::from_raw_parts(vrf_public_key_data, vrf_public_key_data_len as usize) }; - let vrf_public_key = - VRFPublicKeyHolder::Schnorrkel(VRFPublicKey(match vrf_public_key.try_into() { - Ok(res) => res, - Err(_) => return MintlayerErrorCode::InvalidVrfPublicKey.into(), - })); + let vrf_public_key = match VRFPublicKeyHolder::decode_all(&mut vrf_public_key.as_ref()) { + Ok(res) => res, + Err(_) => return MintlayerErrorCode::InvalidVrfPublicKey.into(), + }; let destination_bytes = unsafe { core::slice::from_raw_parts( @@ -786,14 +785,16 @@ extern "C" fn mintlayer_encode_issue_nft_output( }; let issuance = NftIssuance::V0(NftIssuanceV0 { - creator, - name, - description, - ticker, - icon_uri, - additional_metadata_uri, - media_uri, - media_hash, + metadata: Metadata { + creator, + name, + description, + ticker, + icon_uri, + additional_metadata_uri, + media_uri, + media_hash, + }, }); let txo = TxOutput::IssueNft(token_id, issuance, destination); @@ -883,7 +884,7 @@ extern "C" fn mintlayer_encode_htlc_output( let hash = unsafe { core::slice::from_raw_parts(secret_hash_data, secret_hash_data_len as usize) }; - let secret_hash = H256(match hash.try_into() { + let secret_hash = HtlcSecretHash(match hash.try_into() { Ok(hash) => hash, Err(_) => return MintlayerErrorCode::WrongHashSize.into(), }); @@ -1333,6 +1334,11 @@ enum NftIssuance { #[derive(Encode)] struct NftIssuanceV0 { + pub metadata: Metadata, +} + +#[derive(Encode)] +struct Metadata { pub creator: Option, pub name: parity_scale_codec::alloc::vec::Vec, pub description: parity_scale_codec::alloc::vec::Vec, @@ -1398,7 +1404,7 @@ enum TxOutput { #[derive(Encode)] pub struct HashedTimelockContract { // can be spent either by a specific address that knows the secret - secret_hash: H256, + secret_hash: HtlcSecretHash, spend_key: Destination, // or by a multisig after timelock expires making it possible to refund @@ -1409,6 +1415,9 @@ pub struct HashedTimelockContract { #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Encode, Decode)] struct H256(pub [u8; 32]); +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Encode, Decode)] +struct HtlcSecretHash(pub [u8; 20]); + #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Ord, PartialOrd)] enum OutPointSourceId { #[codec(index = 0)] diff --git a/core/src/apps/mintlayer/sign_tx/layout.py b/core/src/apps/mintlayer/sign_tx/layout.py index eddeff99d..505f3bef6 100644 --- a/core/src/apps/mintlayer/sign_tx/layout.py +++ b/core/src/apps/mintlayer/sign_tx/layout.py @@ -92,7 +92,15 @@ async def confirm_output( elif output.create_stake_pool: x = output.create_stake_pool assert x.staker is not None and x.decommission_key is not None - address_short = f"staker: {x.staker}, decommission_key: {x.decommission_key}" + data = convertbits(x.pool_id, 8, 5) + pool_id_address = bech32_encode(POOL_HRP, data, Encoding.BECH32M) + address_short = f"""Pool ID: {pool_id_address} +staker: {x.staker} +decommission_key: {x.decommission_key}" +VFT public key: {x.vrf_public_key} +Margin ratio per thousand: {x.margin_ratio_per_thousand} +Cost per block: {int.from_bytes(x.cost_per_block, "big")} +""" amount = format_coin_amount(x.pledge, None) address_label = "Create stake pool" elif output.produce_block_from_stake: @@ -128,20 +136,19 @@ async def confirm_output( elif x.total_supply.type == MintlayerTokenTotalSupplyType.FIXED: if not x.total_supply.fixed_amount: raise ValueError("Token Fixed supply without amount") - amount = int.from_bytes(x.total_supply.fixed_amount, "big") - formated_amount = format_amount(amount, x.number_of_decimals) + fixed_amount = int.from_bytes(x.total_supply.fixed_amount, "big") + formated_amount = format_amount(fixed_amount, x.number_of_decimals) total_supply = f"FIXED {formated_amount}" else: raise ValueError("Unhandled Token total supply type") is_freezable = "Yes" if x.is_freezable else "No" address_short = f"""Ticker: {ticker} - Authority: {x.authority} - Metadata URI: {metadata_uri} - Total token supply: {total_supply} - Number of Decimals: {x.number_of_decimals} - Is Freezable: {is_freezable} - """ - amount = "amount" +Authority: {x.authority} +Metadata URI: {metadata_uri} +Total token supply: {total_supply} +Number of Decimals: {x.number_of_decimals} +Is Freezable: {is_freezable}""" + amount = "" address_label = "Issue fungible token" elif output.issue_nft: x = output.issue_nft @@ -155,13 +162,12 @@ async def confirm_output( ) media_uri = x.media_uri.decode("utf-8") if x.media_uri else None address_short = f"""Name: {name} - Creator: {x.creator} - ticker: {ticker} - Address: {x.destination} - Icon URI: {icon_uri} - Additional medatada URI: {additional_metadata_uri} - Media URI: {media_uri} - """ +Creator: {x.creator} +ticker: {ticker} +Address: {x.destination} +Icon URI: {icon_uri} +Additional medatada URI: {additional_metadata_uri} +Media URI: {media_uri}""" amount = "" address_label = "Issue NFT token" elif output.data_deposit: @@ -172,11 +178,11 @@ async def confirm_output( elif output.htlc: x = output.htlc lock = lock_to_string(x.refund_timelock) - address_short = f"""Secret Hash: {x.secret_hash.hex()} - Spend Key: {x.spend_key} - Refund Key: {x.refund_key} - Refund Time Lock: {lock} - """ + hexidied_secret_hash = hexlify(x.secret_hash).decode() + address_short = f"""Secret Hash: {hexidied_secret_hash} +Spend Key: {x.spend_key} +Refund Key: {x.refund_key} +Refund Time Lock: {lock}""" amount = format_coin_amount(x.value.amount, x.value.token) address_label = "HTLC" elif output.anyone_can_take: @@ -184,9 +190,8 @@ async def confirm_output( ask_amount = format_coin_amount(x.ask.amount, x.ask.token) give_amount = format_coin_amount(x.give.amount, x.give.token) address_short = f"""Conclude Key: {x.conclude_key} - Ask: {ask_amount} - Give: {give_amount}" - """ +Ask: {ask_amount} +Give: {give_amount}""" amount = "" address_label = "Anyone can take" else: diff --git a/core/src/apps/mintlayer/sign_tx/signer.py b/core/src/apps/mintlayer/sign_tx/signer.py index de1d68bb8..553d5f335 100644 --- a/core/src/apps/mintlayer/sign_tx/signer.py +++ b/core/src/apps/mintlayer/sign_tx/signer.py @@ -393,8 +393,8 @@ def serialize_output(self, out: MintlayerTxOutput) -> bytes: x.token_ticker, x.number_of_decimals, x.metadata_uri, - x.total_supply.type, - x.total_supply.fixed_amount, + int(x.total_supply.type), + x.total_supply.fixed_amount or b"", authority, int(x.is_freezable), ) @@ -406,7 +406,7 @@ def serialize_output(self, out: MintlayerTxOutput) -> bytes: x.token_id, creator, x.name, - x.destination, + x.description, x.ticker, x.icon_uri, x.additional_metadata_uri, @@ -434,10 +434,11 @@ def serialize_output(self, out: MintlayerTxOutput) -> bytes: ) elif out.anyone_can_take: x = out.anyone_can_take + conclude_key = mintlayer_decode_address_to_bytes(x.conclude_key) ask_token_id = b"" if not x.ask.token else x.ask.token.token_id give_token_id = b"" if not x.give.token else x.give.token.token_id encoded_out = mintlayer_utils.encode_anyone_can_take_output( - x.conclude_key, x.ask.amount, ask_token_id, x.give.amount, give_token_id + conclude_key, x.ask.amount, ask_token_id, x.give.amount, give_token_id ) else: raise Exception("unhandled tx output type") @@ -525,6 +526,9 @@ def update(value: MintlayerOutputValue): else: totals[token_or_coin] = amount + if ML_COIN not in totals: + totals[ML_COIN] = 0 + if txo.transfer: update(txo.transfer.value) elif txo.lock_then_transfer: @@ -532,7 +536,11 @@ def update(value: MintlayerOutputValue): elif txo.burn: update(txo.burn.value) elif txo.issue_nft: - totals[txo.issue_nft.ticker.decode("utf-8")] += 1 + token_or_coin = txo.issue_nft.ticker.decode("utf-8") + if token_or_coin in totals: + totals[token_or_coin] += 1 + else: + totals[token_or_coin] = 1 elif txo.create_stake_pool: amount = int.from_bytes(txo.create_stake_pool.pledge, "big") totals[ML_COIN] += amount