From bb37cc0aae8ab89d481d110f54da535646596493 Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Wed, 8 Jan 2025 10:09:43 +0100 Subject: [PATCH] change tx additional info to handle orders --- Cargo.lock | 1 + .../chain/transaction/output/output_value.rs | 18 +- wallet/Cargo.toml | 5 +- wallet/src/account/mod.rs | 9 +- wallet/src/send_request/mod.rs | 93 +------- wallet/src/signer/mod.rs | 6 +- wallet/src/signer/software_signer/mod.rs | 3 +- wallet/src/signer/software_signer/tests.rs | 4 +- wallet/src/signer/trezor_signer/mod.rs | 202 +++++++++++++----- wallet/src/signer/trezor_signer/tests.rs | 95 ++++---- wallet/src/wallet/mod.rs | 75 ++++--- wallet/src/wallet/tests.rs | 163 +++++++------- .../types/src/partially_signed_transaction.rs | 69 +++--- wallet/wallet-cli-lib/src/lib.rs | 7 +- wallet/wallet-controller/src/helpers.rs | 135 +++++++++--- wallet/wallet-controller/src/lib.rs | 41 ++-- .../wallet-controller/src/runtime_wallet.rs | 29 +-- .../src/synced_controller.rs | 50 ++--- wallet/wallet-rpc-lib/src/rpc/mod.rs | 9 +- 19 files changed, 549 insertions(+), 465 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14d9f391e..e440c933a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8354,6 +8354,7 @@ dependencies = [ [[package]] name = "trezor-client" version = "0.1.4" +source = "git+https://github.com/mintlayer/mintlayer-trezor-firmware?branch=feature/mintlayer-pk#1768ae882544791239303dbe2e25e82f6dda0c81" dependencies = [ "bitcoin", "byteorder", diff --git a/common/src/chain/transaction/output/output_value.rs b/common/src/chain/transaction/output/output_value.rs index 167c9954b..55e275f73 100644 --- a/common/src/chain/transaction/output/output_value.rs +++ b/common/src/chain/transaction/output/output_value.rs @@ -75,7 +75,14 @@ impl From for OutputValue { } #[derive( - Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, rpc_description::HasValueHint, + Debug, + Clone, + Copy, + PartialEq, + Eq, + serde::Serialize, + serde::Deserialize, + rpc_description::HasValueHint, )] #[serde(tag = "type", content = "content")] pub enum RpcOutputValue { @@ -107,3 +114,12 @@ impl RpcOutputValue { } } } + +impl From for OutputValue { + fn from(value: RpcOutputValue) -> Self { + match value { + RpcOutputValue::Coin { amount } => OutputValue::Coin(amount), + RpcOutputValue::Token { id, amount } => OutputValue::TokenV1(id, amount), + } + } +} diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 384409e34..082851319 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -26,8 +26,7 @@ utils-networking = { path = "../utils/networking" } utxo = { path = "../utxo" } wallet-storage = { path = "./storage" } wallet-types = { path = "./types" } -# trezor-client = { git = "https://github.com/mintlayer/mintlayer-trezor-firmware", branch = "feature/mintlayer-pk", features = ["bitcoin", "mintlayer"], optional = true } -trezor-client = { path = "../../trezor-firmware/rust/trezor-client", features = ["bitcoin", "mintlayer"], optional = true } +trezor-client = { git = "https://github.com/mintlayer/mintlayer-trezor-firmware", branch = "feature/mintlayer-pk", features = ["bitcoin", "mintlayer"], optional = true } bip39 = { workspace = true, default-features = false, features = ["std", "zeroize"] } hex.workspace = true @@ -46,5 +45,3 @@ tempfile.workspace = true [features] trezor = ["dep:trezor-client", "wallet-types/trezor"] trezor-emulator = [] - -default = ["trezor"] diff --git a/wallet/src/account/mod.rs b/wallet/src/account/mod.rs index 0b8254d61..b840a5605 100644 --- a/wallet/src/account/mod.rs +++ b/wallet/src/account/mod.rs @@ -38,7 +38,9 @@ use utils::ensure; pub use utxo_selector::UtxoSelectorError; use wallet_types::account_id::AccountPrefixedId; use wallet_types::account_info::{StandaloneAddressDetails, StandaloneAddresses}; -use wallet_types::partially_signed_transaction::{PartiallySignedTransaction, UtxoAdditionalInfo}; +use wallet_types::partially_signed_transaction::{ + InfoId, PartiallySignedTransaction, TxAdditionalInfo, +}; use wallet_types::with_locked::WithLocked; use crate::account::utxo_selector::{select_coins, OutputGroup}; @@ -47,8 +49,7 @@ use crate::key_chain::{AccountKeyChains, KeyChainError, VRFAccountKeyChains}; use crate::send_request::{ make_address_output, make_address_output_from_delegation, make_address_output_token, make_decommission_stake_pool_output, make_mint_token_outputs, make_stake_output, - make_unmint_token_outputs, IssueNftArguments, PoolOrTokenId, SelectedInputs, - StakePoolDataArguments, + make_unmint_token_outputs, IssueNftArguments, SelectedInputs, StakePoolDataArguments, }; use crate::wallet::WalletPoolsFilter; use crate::wallet_events::{WalletEvents, WalletEventsNoOp}; @@ -633,7 +634,7 @@ impl Account { change_addresses: BTreeMap>, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(PartiallySignedTransaction, BTreeMap)> { let mut request = self.select_inputs_for_send_request( request, diff --git a/wallet/src/send_request/mod.rs b/wallet/src/send_request/mod.rs index 1c21f2410..8c4d4f8bb 100644 --- a/wallet/src/send_request/mod.rs +++ b/wallet/src/send_request/mod.rs @@ -20,7 +20,7 @@ use common::address::Address; use common::chain::output_value::OutputValue; use common::chain::stakelock::StakePoolData; use common::chain::timelock::OutputTimeLock::ForBlockCount; -use common::chain::tokens::{Metadata, NftIssuance, TokenId, TokenIssuance}; +use common::chain::tokens::{Metadata, TokenId, TokenIssuance}; use common::chain::{ ChainConfig, Destination, PoolId, Transaction, TxInput, TxOutput, UtxoOutPoint, }; @@ -30,19 +30,13 @@ use crypto::vrf::VRFPublicKey; use utils::ensure; use wallet_types::currency::Currency; use wallet_types::partially_signed_transaction::{ - PartiallySignedTransaction, TokenAdditionalInfo, UtxoAdditionalInfo, UtxoWithAdditionalInfo, + InfoId, PartiallySignedTransaction, TxAdditionalInfo, }; use crate::account::PoolData; use crate::destination_getters::{get_tx_output_destination, HtlcSpendingCondition}; use crate::{WalletError, WalletResult}; -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum PoolOrTokenId { - PoolId(PoolId), - TokenId(TokenId), -} - /// The `SendRequest` struct provides the necessary information to the wallet /// on the precise method of sending funds to a designated destination. #[derive(Debug, Clone)] @@ -298,26 +292,11 @@ impl SendRequest { pub fn into_partially_signed_tx( self, - additional_info: &BTreeMap, + additional_info: BTreeMap, ) -> WalletResult { let num_inputs = self.inputs.len(); let destinations = self.destinations.into_iter().map(Some).collect(); - let utxos = self - .utxos - .into_iter() - .map(|utxo| { - utxo.map(|utxo| { - let additional_info = find_additional_info(&utxo, additional_info)?; - Ok(UtxoWithAdditionalInfo::new(utxo, additional_info)) - }) - .transpose() - }) - .collect::>>()?; - let output_additional_infos = self - .outputs - .iter() - .map(|utxo| find_additional_info(utxo, additional_info)) - .collect::>>()?; + let utxos = self.utxos; let tx = Transaction::new(self.flags, self.inputs, self.outputs)?; let ptx = PartiallySignedTransaction::new( @@ -326,74 +305,12 @@ impl SendRequest { utxos, destinations, None, - output_additional_infos, + additional_info, )?; Ok(ptx) } } -/// Find additional data for TxOutput, mainly for UI purposes -fn find_additional_info( - utxo: &TxOutput, - additional_info: &BTreeMap, -) -> Result, WalletError> { - let additional_info = match utxo { - TxOutput::Burn(value) - | TxOutput::Htlc(value, _) - | TxOutput::Transfer(value, _) - | TxOutput::LockThenTransfer(value, _, _) => { - find_token_additional_info(value, additional_info)?.map(UtxoAdditionalInfo::TokenInfo) - } - TxOutput::CreateOrder(data) => { - let ask = find_token_additional_info(data.ask(), additional_info)?; - let give = find_token_additional_info(data.give(), additional_info)?; - - Some(UtxoAdditionalInfo::CreateOrder { ask, give }) - } - TxOutput::IssueNft(_, data, _) => { - Some(UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { - num_decimals: 0, - ticker: match data.as_ref() { - NftIssuance::V0(data) => data.metadata.ticker().clone(), - }, - })) - } - TxOutput::CreateStakePool(_, data) => Some(UtxoAdditionalInfo::PoolInfo { - staker_balance: data.pledge(), - }), - TxOutput::ProduceBlockFromStake(_, pool_id) => additional_info - .get(&PoolOrTokenId::PoolId(*pool_id)) - .ok_or(WalletError::MissingPoolAdditionalData(*pool_id)) - .map(Some)? - .cloned(), - TxOutput::DataDeposit(_) - | TxOutput::IssueFungibleToken(_) - | TxOutput::DelegateStaking(_, _) - | TxOutput::CreateDelegationId(_, _) => None, - }; - Ok(additional_info) -} - -fn find_token_additional_info( - value: &OutputValue, - additional_info: &BTreeMap, -) -> WalletResult> { - match value { - OutputValue::Coin(_) | OutputValue::TokenV0(_) => Ok(None), - OutputValue::TokenV1(token_id, _) => additional_info - .get(&PoolOrTokenId::TokenId(*token_id)) - .ok_or(WalletError::MissingTokenAdditionalData(*token_id)) - .cloned() - .map(|data| match data { - UtxoAdditionalInfo::TokenInfo(data) => Ok(Some(data.clone())), - UtxoAdditionalInfo::PoolInfo { staker_balance: _ } - | UtxoAdditionalInfo::CreateOrder { ask: _, give: _ } => { - Err(WalletError::MismatchedTokenAdditionalData(*token_id)) - } - })?, - } -} - pub enum SelectedInputs { Utxos(Vec), Inputs(Vec<(UtxoOutPoint, TxOutput)>), diff --git a/wallet/src/signer/mod.rs b/wallet/src/signer/mod.rs index 0e2f62174..f4e3473cc 100644 --- a/wallet/src/signer/mod.rs +++ b/wallet/src/signer/mod.rs @@ -83,8 +83,8 @@ pub enum SignerError { MissingDestinationInTransaction, #[error("Partially signed tx is missing UTXO type input's UTXO")] MissingUtxo, - #[error("Partially signed tx is missing extra info for UTXO")] - MissingUtxoExtraInfo, + #[error("Partially signed tx is missing extra info")] + MissingTxExtraInfo, #[error("Tokens V0 are not supported")] UnsupportedTokensV0, #[error("Invalid TxOutput type as UTXO, cannot be spent")] @@ -93,6 +93,8 @@ pub enum SignerError { AddressError(#[from] AddressError), #[error("Signature error: {0}")] SignatureError(#[from] SignatureError), + #[error("Order was filled more than the available balance")] + OrderFillUnderflow, } type SignerResult = Result; diff --git a/wallet/src/signer/software_signer/mod.rs b/wallet/src/signer/software_signer/mod.rs index dad8908f9..c0c545e4d 100644 --- a/wallet/src/signer/software_signer/mod.rs +++ b/wallet/src/signer/software_signer/mod.rs @@ -264,8 +264,7 @@ impl Signer for SoftwareSigner { Vec, Vec, )> { - let inputs_utxo_refs: Vec<_> = - ptx.input_utxos().iter().map(|u| u.as_ref().map(|x| &x.utxo)).collect(); + let inputs_utxo_refs: Vec<_> = ptx.input_utxos().iter().map(|u| u.as_ref()).collect(); let (witnesses, prev_statuses, new_statuses) = ptx .witnesses() diff --git a/wallet/src/signer/software_signer/tests.rs b/wallet/src/signer/software_signer/tests.rs index 96838e610..edc07aadc 100644 --- a/wallet/src/signer/software_signer/tests.rs +++ b/wallet/src/signer/software_signer/tests.rs @@ -437,7 +437,7 @@ fn sign_transaction(#[case] seed: Seed) { .with_outputs(outputs); let destinations = req.destinations().to_vec(); let additional_info = BTreeMap::new(); - let ptx = req.into_partially_signed_tx(&additional_info).unwrap(); + let ptx = req.into_partially_signed_tx(additional_info).unwrap(); let mut signer = SoftwareSigner::new(chain_config.clone(), DEFAULT_ACCOUNT_INDEX); let (ptx, _, _) = signer.sign_tx(ptx, account.key_chain(), &db_tx).unwrap(); @@ -688,7 +688,7 @@ fn fixed_signatures() { .with_outputs(outputs); let destinations = req.destinations().to_vec(); let additional_info = BTreeMap::new(); - let ptx = req.into_partially_signed_tx(&additional_info).unwrap(); + let ptx = req.into_partially_signed_tx(additional_info).unwrap(); let utxos_ref = utxos .iter() diff --git a/wallet/src/signer/trezor_signer/mod.rs b/wallet/src/signer/trezor_signer/mod.rs index adff053df..de89affba 100644 --- a/wallet/src/signer/trezor_signer/mod.rs +++ b/wallet/src/signer/trezor_signer/mod.rs @@ -40,7 +40,7 @@ use common::{ DestinationSigError, }, timelock::OutputTimeLock, - tokens::{NftIssuance, TokenIssuance, TokenTotalSupply}, + tokens::{NftIssuance, TokenId, TokenIssuance, TokenTotalSupply}, AccountCommand, AccountSpending, ChainConfig, Destination, OutPointSourceId, SignedTransactionIntent, Transaction, TxInput, TxOutput, }, @@ -83,7 +83,7 @@ use wallet_storage::{ use wallet_types::{ account_info::DEFAULT_ACCOUNT_INDEX, partially_signed_transaction::{ - PartiallySignedTransaction, TokenAdditionalInfo, UtxoAdditionalInfo, + InfoId, PartiallySignedTransaction, TokenAdditionalInfo, TxAdditionalInfo, }, signature_status::SignatureStatus, AccountId, @@ -245,10 +245,7 @@ impl TrezorSigner { .tx() .outputs() .iter() - .zip(ptx.output_additional_infos()) - .map(|(out, additional_info)| { - to_trezor_output_msg(&self.chain_config, out, additional_info) - }) + .map(|out| to_trezor_output_msg(&self.chain_config, out, ptx.additional_infos())) .collect(); outputs } @@ -277,8 +274,7 @@ impl Signer for TrezorSigner { .mintlayer_sign_tx(coin_name, inputs, outputs, utxos) .map_err(|err| TrezorError::DeviceError(err.to_string()))?; - let inputs_utxo_refs: Vec<_> = - ptx.input_utxos().iter().map(|u| u.as_ref().map(|x| &x.utxo)).collect(); + let inputs_utxo_refs: Vec<_> = ptx.input_utxos().iter().map(|u| u.as_ref()).collect(); let (witnesses, prev_statuses, new_statuses) = ptx .witnesses() @@ -540,7 +536,14 @@ fn to_trezor_input_msgs( to_trezor_account_input(chain_config, dest, key_chain, outpoint) } (TxInput::AccountCommand(nonce, command), _, Some(dest)) => { - to_trezor_account_command_input(chain_config, dest, key_chain, nonce, command) + to_trezor_account_command_input( + chain_config, + dest, + key_chain, + nonce, + command, + ptx.additional_infos(), + ) } (_, _, None) => Err(SignerError::MissingDestinationInTransaction), (TxInput::Utxo(_), _, _) => Err(SignerError::MissingUtxo), @@ -554,6 +557,7 @@ fn to_trezor_account_command_input( key_chain: &impl AccountKeyChains, nonce: &common::chain::AccountNonce, command: &AccountCommand, + additional_infos: &BTreeMap, ) -> SignerResult { let mut inp_req = MintlayerAccountCommandTxInput::new(); inp_req.addresses = destination_to_address_paths(key_chain, dest); @@ -609,6 +613,50 @@ fn to_trezor_account_command_input( let mut req = MintlayerConcludeOrder::new(); req.set_order_id(Address::new(chain_config, *order_id)?.into_string()); + match additional_infos.get(&InfoId::OrderId(*order_id)) { + Some(TxAdditionalInfo::OrderInfo { + initially_asked, + initially_given, + ask_balance, + give_balance, + }) => { + let filled_value = match initially_asked { + OutputValue::Coin(amount) => OutputValue::Coin( + (*amount - *ask_balance).ok_or(SignerError::OrderFillUnderflow)?, + ), + OutputValue::TokenV1(id, amount) => OutputValue::TokenV1( + *id, + (*amount - *ask_balance).ok_or(SignerError::OrderFillUnderflow)?, + ), + OutputValue::TokenV0(_) => return Err(SignerError::UnsupportedTokensV0), + }; + let give_value = match initially_given { + OutputValue::Coin(_) => OutputValue::Coin(*give_balance), + OutputValue::TokenV1(id, _) => OutputValue::TokenV1(*id, *give_balance), + OutputValue::TokenV0(_) => return Err(SignerError::UnsupportedTokensV0), + }; + + req.filled_ask_amount = Some(to_trezor_output_value( + &filled_value, + additional_infos, + chain_config, + )?) + .into(); + + req.give_balance = Some(to_trezor_output_value( + &give_value, + additional_infos, + chain_config, + )?) + .into(); + } + Some( + TxAdditionalInfo::TokenInfo(_) + | TxAdditionalInfo::PoolInfo { staker_balance: _ }, + ) + | None => return Err(SignerError::MissingTxExtraInfo), + } + inp_req.conclude_order = Some(req).into(); } AccountCommand::FillOrder(order_id, amount, dest) => { @@ -617,6 +665,45 @@ fn to_trezor_account_command_input( req.set_amount(amount.into_atoms().to_be_bytes().to_vec()); req.set_destination(Address::new(chain_config, dest.clone())?.into_string()); + match additional_infos.get(&InfoId::OrderId(*order_id)) { + Some(TxAdditionalInfo::OrderInfo { + initially_asked, + initially_given, + ask_balance, + give_balance, + }) => { + let ask_value = match initially_asked { + OutputValue::Coin(_) => OutputValue::Coin(*ask_balance), + OutputValue::TokenV1(id, _) => OutputValue::TokenV1(*id, *ask_balance), + OutputValue::TokenV0(_) => return Err(SignerError::UnsupportedTokensV0), + }; + let give_value = match initially_given { + OutputValue::Coin(_) => OutputValue::Coin(*give_balance), + OutputValue::TokenV1(id, _) => OutputValue::TokenV1(*id, *give_balance), + OutputValue::TokenV0(_) => return Err(SignerError::UnsupportedTokensV0), + }; + + req.ask_balance = Some(to_trezor_output_value( + &ask_value, + additional_infos, + chain_config, + )?) + .into(); + + req.give_balance = Some(to_trezor_output_value( + &give_value, + additional_infos, + chain_config, + )?) + .into(); + } + Some( + TxAdditionalInfo::TokenInfo(_) + | TxAdditionalInfo::PoolInfo { staker_balance: _ }, + ) + | None => return Err(SignerError::MissingTxExtraInfo), + } + inp_req.fill_order = Some(req).into(); } } @@ -732,16 +819,25 @@ fn destination_to_address_paths( fn to_trezor_output_value( output_value: &OutputValue, - additional_info: &Option, + additional_info: &BTreeMap, chain_config: &ChainConfig, ) -> SignerResult { - let token_info = additional_info.as_ref().and_then(|info| match info { - UtxoAdditionalInfo::TokenInfo(token_info) => Some(token_info), - UtxoAdditionalInfo::PoolInfo { staker_balance: _ } - | UtxoAdditionalInfo::CreateOrder { ask: _, give: _ } => None, - }); - - to_trezor_output_value_with_token_info(output_value, &token_info, chain_config) + to_trezor_output_value_with_token_info( + output_value, + |token_id| { + additional_info.get(&InfoId::TokenId(token_id)).and_then(|info| match info { + TxAdditionalInfo::TokenInfo(info) => Some(info), + TxAdditionalInfo::PoolInfo { staker_balance: _ } + | TxAdditionalInfo::OrderInfo { + initially_asked: _, + initially_given: _, + ask_balance: _, + give_balance: _, + } => None, + }) + }, + chain_config, + ) } fn to_trezor_utxo_msgs( @@ -758,7 +854,7 @@ fn to_trezor_utxo_msgs( OutPointSourceId::Transaction(id) => id.to_hash().0, OutPointSourceId::BlockReward(id) => id.to_hash().0, }; - let out = to_trezor_output_msg(chain_config, &utxo.utxo, &utxo.additional_info)?; + let out = to_trezor_output_msg(chain_config, utxo, ptx.additional_infos())?; utxos.entry(id).or_default().insert(outpoint.output_index(), out); } TxInput::Account(_) | TxInput::AccountCommand(_, _) => {} @@ -771,7 +867,7 @@ fn to_trezor_utxo_msgs( fn to_trezor_output_msg( chain_config: &ChainConfig, out: &TxOutput, - additional_info: &Option, + additional_info: &BTreeMap, ) -> SignerResult { let res = match out { TxOutput::Transfer(value, dest) => { @@ -861,13 +957,18 @@ fn to_trezor_output_msg( out_req.set_pool_id(Address::new(chain_config, *pool_id)?.into_string()); out_req.set_destination(Address::new(chain_config, dest.clone())?.into_string()); let staker_balance = additional_info - .as_ref() + .get(&InfoId::PoolId(*pool_id)) .and_then(|info| match info { - UtxoAdditionalInfo::PoolInfo { staker_balance } => Some(staker_balance), - UtxoAdditionalInfo::TokenInfo(_) - | UtxoAdditionalInfo::CreateOrder { ask: _, give: _ } => None, + TxAdditionalInfo::PoolInfo { staker_balance } => Some(staker_balance), + TxAdditionalInfo::TokenInfo(_) + | TxAdditionalInfo::OrderInfo { + initially_asked: _, + initially_given: _, + ask_balance: _, + give_balance: _, + } => None, }) - .ok_or(SignerError::MissingUtxoExtraInfo)?; + .ok_or(SignerError::MissingTxExtraInfo)?; out_req.set_staker_balance(staker_balance.into_atoms().to_be_bytes().to_vec()); let mut out = MintlayerTxOutput::new(); out.produce_block_from_stake = Some(out_req).into(); @@ -981,27 +1082,18 @@ fn to_trezor_output_msg( Address::new(chain_config, data.conclude_key().clone())?.into_string(), ); - match additional_info { - Some(UtxoAdditionalInfo::CreateOrder { ask, give }) => { - out_req.ask = Some(to_trezor_output_value_with_token_info( - data.ask(), - &ask.as_ref(), - chain_config, - )?) - .into(); - out_req.give = Some(to_trezor_output_value_with_token_info( - data.give(), - &give.as_ref(), - chain_config, - )?) - .into(); - } - Some( - UtxoAdditionalInfo::PoolInfo { staker_balance: _ } - | UtxoAdditionalInfo::TokenInfo(_), - ) - | None => return Err(SignerError::MissingUtxoExtraInfo), - } + out_req.ask = Some(to_trezor_output_value( + data.ask(), + additional_info, + chain_config, + )?) + .into(); + out_req.give = Some(to_trezor_output_value( + data.give(), + additional_info, + chain_config, + )?) + .into(); let mut out = MintlayerTxOutput::new(); out.create_order = Some(out_req).into(); @@ -1011,11 +1103,14 @@ fn to_trezor_output_msg( Ok(res) } -fn to_trezor_output_value_with_token_info( +fn to_trezor_output_value_with_token_info<'a, F>( value: &OutputValue, - token_info: &Option<&TokenAdditionalInfo>, + additional_info: F, chain_config: &ChainConfig, -) -> Result { +) -> Result +where + F: Fn(TokenId) -> Option<&'a TokenAdditionalInfo>, +{ match value { OutputValue::Coin(amount) => { let mut value = MintlayerOutputValue::new(); @@ -1025,15 +1120,12 @@ fn to_trezor_output_value_with_token_info( OutputValue::TokenV1(token_id, amount) => { let mut value = MintlayerOutputValue::new(); value.set_amount(amount.into_atoms().to_be_bytes().to_vec()); + let info = additional_info(*token_id).ok_or(SignerError::MissingTxExtraInfo)?; + let mut token_value = MintlayerTokenOutputValue::new(); token_value.set_token_id(Address::new(chain_config, *token_id)?.into_string()); - match &token_info { - Some(info) => { - token_value.set_number_of_decimals(info.num_decimals as u32); - token_value.set_token_ticker(info.ticker.clone()); - } - None => return Err(SignerError::MissingUtxoExtraInfo), - } + token_value.set_number_of_decimals(info.num_decimals as u32); + token_value.set_token_ticker(info.ticker.clone()); value.token = Some(token_value).into(); Ok(value) } diff --git a/wallet/src/signer/trezor_signer/tests.rs b/wallet/src/signer/trezor_signer/tests.rs index 70b7b4c68..7c371679e 100644 --- a/wallet/src/signer/trezor_signer/tests.rs +++ b/wallet/src/signer/trezor_signer/tests.rs @@ -14,34 +14,37 @@ // limitations under the License. use core::panic; -use std::ops::{Add, Div, Mul, Sub}; +use std::ops::{Add, Div, Sub}; use super::*; -use crate::key_chain::{MasterKeyChain, LOOKAHEAD_SIZE}; -use crate::send_request::PoolOrTokenId; -use crate::{Account, SendRequest}; -use common::chain::config::create_regtest; -use common::chain::htlc::HashedTimelockContract; -use common::chain::output_value::OutputValue; -use common::chain::signature::inputsig::arbitrary_message::produce_message_challenge; -use common::chain::stakelock::StakePoolData; -use common::chain::timelock::OutputTimeLock; -use common::chain::tokens::{NftIssuanceV0, TokenId}; +use crate::{ + key_chain::{MasterKeyChain, LOOKAHEAD_SIZE}, + Account, SendRequest, +}; use common::chain::{ + config::create_regtest, + htlc::HashedTimelockContract, + output_value::OutputValue, + signature::inputsig::arbitrary_message::produce_message_challenge, + stakelock::StakePoolData, + timelock::OutputTimeLock, + tokens::{NftIssuanceV0, TokenId}, AccountNonce, AccountOutPoint, DelegationId, Destination, GenBlock, OrderData, PoolId, Transaction, TxInput, }; -use common::primitives::per_thousand::PerThousand; -use common::primitives::{Amount, BlockHeight, Id, H256}; +use common::primitives::{per_thousand::PerThousand, Amount, BlockHeight, Id, H256}; use crypto::key::{KeyKind, PrivateKey}; use randomness::{Rng, RngCore}; use rstest::rstest; use test_utils::random::{make_seedable_rng, Seed}; use trezor_client::find_devices; use wallet_storage::{DefaultBackend, Store, Transactional}; -use wallet_types::account_info::DEFAULT_ACCOUNT_INDEX; -use wallet_types::seed_phrase::StoreSeedPhrase; -use wallet_types::KeyPurpose::{Change, ReceiveFunds}; +use wallet_types::{ + account_info::DEFAULT_ACCOUNT_INDEX, + partially_signed_transaction::InfoId, + seed_phrase::StoreSeedPhrase, + KeyPurpose::{Change, ReceiveFunds}, +}; const MNEMONIC: &str = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; @@ -195,7 +198,7 @@ fn sign_transaction(#[case] seed: Seed) { let mut account = Account::new(chain_config.clone(), &mut db_tx, key_chain, None).unwrap(); let amounts: Vec = (0..(2 + rng.next_u32() % 5)) - .map(|_| Amount::from_atoms(rng.gen_range(1..10) as UnsignedIntType)) + .map(|_| Amount::from_atoms(rng.gen_range(10..100) as UnsignedIntType)) .collect(); let total_amount = amounts.iter().fold(Amount::ZERO, |acc, a| acc.add(*a).unwrap()); @@ -263,36 +266,44 @@ fn sign_transaction(#[case] seed: Seed) { let multisig_utxo = TxOutput::Transfer(OutputValue::Coin(Amount::from_atoms(1)), multisig_dest); let token_id = TokenId::new(H256::random_using(&mut rng)); + let order_id = OrderId::new(H256::random_using(&mut rng)); + + let dest_amount = total_amount.div(10).unwrap(); + let lock_amount = total_amount.div(10).unwrap(); + let burn_amount = total_amount.div(10).unwrap(); + let change_amount = total_amount.div(10).unwrap(); + let outputs_amounts_sum = [dest_amount, lock_amount, burn_amount, change_amount] + .iter() + .fold(Amount::ZERO, |acc, a| acc.add(*a).unwrap()); + let _fee_amount = total_amount.sub(outputs_amounts_sum).unwrap(); + let acc_inputs = vec![ TxInput::Account(AccountOutPoint::new( AccountNonce::new(1), AccountSpending::DelegationBalance( DelegationId::new(H256::random_using(&mut rng)), - Amount::from_atoms(1 as u128), + Amount::from_atoms(1_u128), ), )), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::MintTokens(token_id, Amount::from_atoms(100)), + AccountCommand::MintTokens(token_id, (dest_amount + Amount::from_atoms(100)).unwrap()), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::UnmintTokens(TokenId::new(H256::random_using(&mut rng))), + AccountCommand::UnmintTokens(token_id), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::LockTokenSupply(TokenId::new(H256::random_using(&mut rng))), + AccountCommand::LockTokenSupply(token_id), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::FreezeToken( - TokenId::new(H256::random_using(&mut rng)), - IsTokenUnfreezable::Yes, - ), + AccountCommand::FreezeToken(token_id, IsTokenUnfreezable::Yes), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::UnfreezeToken(TokenId::new(H256::random_using(&mut rng))), + AccountCommand::UnfreezeToken(token_id), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), @@ -303,15 +314,11 @@ fn sign_transaction(#[case] seed: Seed) { ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::ConcludeOrder(OrderId::new(H256::random_using(&mut rng))), + AccountCommand::ConcludeOrder(order_id), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), - AccountCommand::FillOrder( - OrderId::new(H256::random_using(&mut rng)), - Amount::from_atoms(123), - Destination::AnyoneCanSpend, - ), + AccountCommand::FillOrder(order_id, Amount::from_atoms(1), Destination::AnyoneCanSpend), ), TxInput::AccountCommand( AccountNonce::new(rng.next_u64()), @@ -334,15 +341,6 @@ fn sign_transaction(#[case] seed: Seed) { }) .collect(); - let dest_amount = total_amount.div(10).unwrap().mul(5).unwrap(); - let lock_amount = total_amount.div(10).unwrap().mul(1).unwrap(); - let burn_amount = total_amount.div(10).unwrap().mul(1).unwrap(); - let change_amount = total_amount.div(10).unwrap().mul(2).unwrap(); - let outputs_amounts_sum = [dest_amount, lock_amount, burn_amount, change_amount] - .iter() - .fold(Amount::ZERO, |acc, a| acc.add(*a).unwrap()); - let _fee_amount = total_amount.sub(outputs_amounts_sum).unwrap(); - let (_dest_prv, dest_pub) = PrivateKey::new_from_rng(&mut rng, KeyKind::Secp256k1Schnorr); let (_, vrf_public_key) = VRFPrivateKey::new_from_entropy(crypto::vrf::VRFKeyKind::Schnorrkel); @@ -437,13 +435,22 @@ fn sign_transaction(#[case] seed: Seed) { let destinations = req.destinations().to_vec(); let mut additional_info = BTreeMap::new(); additional_info.insert( - PoolOrTokenId::TokenId(token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: 1, ticker: "TKN".as_bytes().to_vec(), }), ); - let ptx = req.into_partially_signed_tx(&additional_info).unwrap(); + additional_info.insert( + InfoId::OrderId(order_id), + TxAdditionalInfo::OrderInfo { + ask_balance: Amount::from_atoms(10), + give_balance: Amount::from_atoms(100), + initially_asked: OutputValue::Coin(Amount::from_atoms(20)), + initially_given: OutputValue::TokenV1(token_id, Amount::from_atoms(200)), + }, + ); + let ptx = req.into_partially_signed_tx(additional_info).unwrap(); let mut devices = find_devices(false); assert!(!devices.is_empty()); diff --git a/wallet/src/wallet/mod.rs b/wallet/src/wallet/mod.rs index 03f29f888..ce828bc11 100644 --- a/wallet/src/wallet/mod.rs +++ b/wallet/src/wallet/mod.rs @@ -26,8 +26,7 @@ use crate::key_chain::{ MasterKeyChain, LOOKAHEAD_SIZE, VRF_INDEX, }; use crate::send_request::{ - make_issue_token_outputs, IssueNftArguments, PoolOrTokenId, SelectedInputs, - StakePoolDataArguments, + make_issue_token_outputs, IssueNftArguments, SelectedInputs, StakePoolDataArguments, }; use crate::signer::{Signer, SignerError, SignerProvider}; use crate::wallet_events::{WalletEvents, WalletEventsNoOp}; @@ -75,8 +74,8 @@ use wallet_storage::{ use wallet_types::account_info::{StandaloneAddressDetails, StandaloneAddresses}; use wallet_types::chain_info::ChainInfo; use wallet_types::partially_signed_transaction::{ - PartiallySignedTransaction, PartiallySignedTransactionCreationError, TokenAdditionalInfo, - UtxoAdditionalInfo, + InfoId, PartiallySignedTransaction, PartiallySignedTransactionCreationError, + TokenAdditionalInfo, TxAdditionalInfo, }; use wallet_types::seed_phrase::SerializableSeedPhrase; use wallet_types::signature_status::SignatureStatus; @@ -1042,7 +1041,7 @@ where fn for_account_rw_unlocked_and_check_tx_generic( &mut self, account_index: U31, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, f: impl FnOnce( &mut Account, &mut StoreTxRwUnlocked, @@ -1063,7 +1062,7 @@ where let ptx = signer.sign_tx(ptx, account.key_chain(), db_tx).map(|(ptx, _, _)| ptx)?; let inputs_utxo_refs: Vec<_> = - ptx.input_utxos().iter().map(|u| u.as_ref().map(|x| &x.utxo)).collect(); + ptx.input_utxos().iter().map(|u| u.as_ref()).collect(); let is_fully_signed = ptx.destinations().iter().enumerate().zip(ptx.witnesses()).all( |((i, destination), witness)| match (witness, destination) { @@ -1100,7 +1099,7 @@ where fn for_account_rw_unlocked_and_check_tx( &mut self, account_index: U31, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, f: impl FnOnce(&mut Account, &mut StoreTxRwUnlocked) -> WalletResult, ) -> WalletResult { Ok(self @@ -1424,7 +1423,7 @@ where change_addresses: BTreeMap>, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { Ok(self .create_transaction_to_addresses_impl( @@ -1452,7 +1451,7 @@ where intent: String, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(SignedTransaction, SignedTransactionIntent)> { let (signed_tx, input_destinations) = self.create_transaction_to_addresses_impl( account_index, @@ -1494,7 +1493,7 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_data_getter: impl Fn(&SendRequest) -> AddlData, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(SignedTransaction, AddlData)> { let request = SendRequest::new().with_outputs(outputs); let latest_median_time = self.latest_median_time; @@ -1531,7 +1530,7 @@ where change_addresses: BTreeMap>, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(PartiallySignedTransaction, BTreeMap)> { let request = SendRequest::new().with_outputs(outputs); let latest_median_time = self.latest_median_time; @@ -1558,7 +1557,7 @@ where destination: Destination, inputs: Vec<(UtxoOutPoint, TxOutput)>, current_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { let request = SendRequest::new().with_inputs( inputs.into_iter().map(|(outpoint, output)| (TxInput::Utxo(outpoint), output)), @@ -1580,7 +1579,7 @@ where delegation_share: Amount, current_fee_rate: FeeRate, ) -> WalletResult { - self.for_account_rw_unlocked_and_check_tx(account_index, &BTreeMap::new(), |account, _| { + self.for_account_rw_unlocked_and_check_tx(account_index, BTreeMap::new(), |account, _| { account.sweep_delegation(address, delegation_id, delegation_share, current_fee_rate) }) } @@ -1594,7 +1593,7 @@ where delegation_share: Amount, current_fee_rate: FeeRate, ) -> WalletResult { - self.for_account_rw_unlocked_and_check_tx(account_index, &BTreeMap::new(), |account, _| { + self.for_account_rw_unlocked_and_check_tx(account_index, BTreeMap::new(), |account, _| { account.spend_from_delegation( address, amount, @@ -1618,7 +1617,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.mint_tokens( db_tx, @@ -1647,7 +1646,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.unmint_tokens( db_tx, @@ -1674,7 +1673,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.lock_token_supply( db_tx, @@ -1701,7 +1700,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.freeze_token( db_tx, @@ -1728,7 +1727,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.unfreeze_token( db_tx, @@ -1755,7 +1754,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.change_token_authority( db_tx, @@ -1783,7 +1782,7 @@ where let additional_utxo_infos = to_token_additional_info(token_info); self.for_account_rw_unlocked_and_check_tx( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { account.change_token_metadata_uri( db_tx, @@ -1830,7 +1829,7 @@ where BTreeMap::new(), current_fee_rate, consolidate_fee_rate, - &BTreeMap::new(), + BTreeMap::new(), )?; let input0_outpoint = crate::utils::get_first_utxo_outpoint(tx.transaction().inputs())?; let delegation_id = make_delegation_id(input0_outpoint); @@ -1853,7 +1852,7 @@ where BTreeMap::new(), current_fee_rate, consolidate_fee_rate, - &BTreeMap::new(), + BTreeMap::new(), )?; let token_id = make_token_id(tx.transaction().inputs()).ok_or(WalletError::MissingTokenId)?; @@ -1873,7 +1872,7 @@ where let signed_transaction = self.for_account_rw_unlocked_and_check_tx( account_index, - &BTreeMap::new(), + BTreeMap::new(), |account, db_tx| { account.create_issue_nft_tx( db_tx, @@ -1904,13 +1903,13 @@ where current_fee_rate: FeeRate, ) -> WalletResult { let additional_utxo_infos = BTreeMap::from_iter([( - PoolOrTokenId::PoolId(pool_id), - UtxoAdditionalInfo::PoolInfo { staker_balance }, + InfoId::PoolId(pool_id), + TxAdditionalInfo::PoolInfo { staker_balance }, )]); Ok(self .for_account_rw_unlocked_and_check_tx_generic( account_index, - &additional_utxo_infos, + additional_utxo_infos, |account, db_tx| { Ok(( account.decommission_stake_pool( @@ -1937,8 +1936,8 @@ where current_fee_rate: FeeRate, ) -> WalletResult { let additional_utxo_infos = BTreeMap::from_iter([( - PoolOrTokenId::PoolId(pool_id), - UtxoAdditionalInfo::PoolInfo { staker_balance }, + InfoId::PoolId(pool_id), + TxAdditionalInfo::PoolInfo { staker_balance }, )]); self.for_account_rw_unlocked( account_index, @@ -1951,7 +1950,7 @@ where current_fee_rate, )?; - let ptx = request.into_partially_signed_tx(&additional_utxo_infos)?; + let ptx = request.into_partially_signed_tx(additional_utxo_infos)?; let mut signer = signer_provider.provide(Arc::new(chain_config.clone()), account_index); @@ -1972,7 +1971,7 @@ where htlc: HashedTimelockContract, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { let latest_median_time = self.latest_median_time; self.for_account_rw_unlocked_and_check_tx( @@ -2002,7 +2001,7 @@ where conclude_key: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(OrderId, SignedTransaction)> { let latest_median_time = self.latest_median_time; let tx = self.for_account_rw_unlocked_and_check_tx( @@ -2036,7 +2035,7 @@ where output_address: Option, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { let latest_median_time = self.latest_median_time; self.for_account_rw_unlocked_and_check_tx( @@ -2068,7 +2067,7 @@ where output_address: Option, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { let latest_median_time = self.latest_median_time; self.for_account_rw_unlocked_and_check_tx( @@ -2299,10 +2298,10 @@ where fn to_token_additional_info( token_info: &UnconfirmedTokenInfo, -) -> BTreeMap { +) -> BTreeMap { BTreeMap::from_iter([( - PoolOrTokenId::TokenId(token_info.token_id()), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_info.token_id()), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.num_decimals(), ticker: token_info.token_ticker().to_vec(), }), @@ -2349,7 +2348,7 @@ where let latest_median_time = self.latest_median_time; self.for_account_rw_unlocked_and_check_tx( account_index, - &BTreeMap::new(), + BTreeMap::new(), |account, db_tx| { account.create_stake_pool_tx( db_tx, diff --git a/wallet/src/wallet/tests.rs b/wallet/src/wallet/tests.rs index 7cbaf2945..b1ab9af46 100644 --- a/wallet/src/wallet/tests.rs +++ b/wallet/src/wallet/tests.rs @@ -55,8 +55,7 @@ use wallet_storage::{schema, WalletStorageEncryptionRead}; use wallet_types::{ account_info::DEFAULT_ACCOUNT_INDEX, partially_signed_transaction::{ - PartiallySignedTransaction, PartiallySignedTransactionCreationError, UtxoAdditionalInfo, - UtxoWithAdditionalInfo, + PartiallySignedTransaction, PartiallySignedTransactionCreationError, TxAdditionalInfo, }, seed_phrase::{PassPhrase, StoreSeedPhrase}, utxo_types::{UtxoState, UtxoType}, @@ -999,7 +998,7 @@ fn wallet_accounts_creation() { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -1159,7 +1158,7 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ), Err(WalletError::DatabaseError( wallet_storage::Error::WalletLocked @@ -1177,7 +1176,7 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); } else { @@ -1207,7 +1206,7 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); } @@ -1235,7 +1234,7 @@ fn wallet_get_transaction(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -1295,7 +1294,7 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -1318,7 +1317,7 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); let spend_from_tx_id = tx.transaction().get_id(); @@ -1373,7 +1372,7 @@ fn wallet_transaction_with_fees(#[case] seed: Seed) { BTreeMap::new(), very_big_feerate, very_big_feerate, - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap_err(); @@ -1401,7 +1400,7 @@ fn wallet_transaction_with_fees(#[case] seed: Seed) { BTreeMap::new(), feerate, feerate, - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -1488,7 +1487,7 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap_err(); assert_eq!(err, WalletError::CannotFindUtxo(missing_utxo.clone())); @@ -1515,7 +1514,7 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -1553,7 +1552,7 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap_err(); @@ -1851,7 +1850,7 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -1999,7 +1998,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -2266,7 +2265,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); wallet @@ -2331,7 +2330,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); (issued_token_id, vec![nft_issuance_transaction, transfer_tx]) @@ -2370,8 +2369,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { ); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(*token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(*token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: number_of_decimals, ticker: token_ticker.clone(), }), @@ -2384,7 +2383,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info.clone(), ) .unwrap(); wallet @@ -2438,7 +2437,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .err() .unwrap(); @@ -2502,7 +2501,7 @@ fn check_tokens_v0_are_ignored(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ); matches!( @@ -2721,8 +2720,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { ); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -2735,7 +2734,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -3583,7 +3582,7 @@ fn lock_then_transfer(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); wallet @@ -3705,7 +3704,7 @@ fn wallet_multiple_transactions_in_single_block(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -3797,7 +3796,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -3833,7 +3832,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -3873,7 +3872,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap_err(); assert_eq!( @@ -3900,7 +3899,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -3985,7 +3984,7 @@ fn wallet_abandone_transactions(#[case] seed: Seed) { BTreeMap::new(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); wallet @@ -4357,14 +4356,13 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { // remove the signatures and try to sign it again let tx = stake_pool_transaction.transaction().clone(); let inps = tx.inputs().len(); - let outs = tx.outputs().len(); let ptx = PartiallySignedTransaction::new( tx, vec![None; inps], - vec![Some(UtxoWithAdditionalInfo::new(utxo, None))], + vec![Some(utxo)], vec![Some(addr.into_object())], None, - vec![None; outs], + BTreeMap::new(), ) .unwrap(); let stake_pool_transaction = wallet @@ -4653,7 +4651,7 @@ fn sign_send_request_cold_wallet(#[case] seed: Seed) { [(Currency::Coin, cold_wallet_address.clone())].into(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); @@ -4756,7 +4754,7 @@ fn test_not_exhaustion_of_keys(#[case] seed: Seed) { [].into(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); } @@ -4890,14 +4888,13 @@ fn test_add_standalone_multisig(#[case] seed: Seed) { )], ) .unwrap(); - let outs = tx.outputs().len(); let spend_multisig_tx = PartiallySignedTransaction::new( spend_multisig_tx, vec![None; 1], - vec![Some(UtxoWithAdditionalInfo::new(tx.outputs()[0].clone(), None))], + vec![Some(tx.outputs()[0].clone())], vec![Some(multisig_address.as_object().clone())], None, - vec![None; outs], + BTreeMap::new(), ) .unwrap(); @@ -4991,7 +4988,7 @@ fn create_htlc_and_spend(#[case] seed: Seed) { htlc.clone(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); let create_htlc_tx_id = create_htlc_tx.transaction().get_id(); @@ -5043,20 +5040,14 @@ fn create_htlc_and_spend(#[case] seed: Seed) { vec![TxOutput::Transfer(output_value, address2.into_object())], ) .unwrap(); - let spend_utxos = vec![create_htlc_tx - .transaction() - .outputs() - .first() - .cloned() - .map(|out| UtxoWithAdditionalInfo::new(out, None))]; - let outs = create_htlc_tx.outputs().len(); + let spend_utxos = vec![create_htlc_tx.transaction().outputs().first().cloned()]; let spend_ptx = PartiallySignedTransaction::new( spend_tx, vec![None], spend_utxos, vec![Some(spend_key.into_object())], Some(vec![Some(secret)]), - vec![None; outs], + BTreeMap::new(), ) .unwrap(); @@ -5137,7 +5128,7 @@ fn create_htlc_and_refund(#[case] seed: Seed) { htlc.clone(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &BTreeMap::new(), + BTreeMap::new(), ) .unwrap(); let create_htlc_tx_id = create_htlc_tx.transaction().get_id(); @@ -5148,20 +5139,14 @@ fn create_htlc_and_refund(#[case] seed: Seed) { vec![TxOutput::Transfer(output_value, address1.into_object())], ) .unwrap(); - let refund_utxos = vec![create_htlc_tx - .transaction() - .outputs() - .first() - .cloned() - .map(|out| UtxoWithAdditionalInfo::new(out, None))]; - let outs = create_htlc_tx.outputs().len(); + let refund_utxos = vec![create_htlc_tx.transaction().outputs().first().cloned()]; let refund_ptx = PartiallySignedTransaction::new( refund_tx, vec![None], refund_utxos, vec![Some(refund_key)], None, - vec![None; outs], + BTreeMap::new(), ) .unwrap(); @@ -5331,8 +5316,8 @@ fn create_order(#[case] seed: Seed) { let ask_value = OutputValue::Coin(Amount::from_atoms(111)); let give_value = OutputValue::TokenV1(issued_token_id, token_amount_to_mint); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5345,7 +5330,7 @@ fn create_order(#[case] seed: Seed) { address2.clone(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -5457,8 +5442,8 @@ fn create_order_and_conclude(#[case] seed: Seed) { let ask_value = OutputValue::Coin(Amount::from_atoms(111)); let give_value = OutputValue::TokenV1(issued_token_id, token_amount_to_mint); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5471,7 +5456,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { address2.clone(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); let order_info = RpcOrderInfo { @@ -5501,8 +5486,8 @@ fn create_order_and_conclude(#[case] seed: Seed) { assert!(token_balances.is_empty()); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5515,7 +5500,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -5646,8 +5631,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { let sell_amount = Amount::from_atoms(1000); let give_value = OutputValue::Coin(sell_amount); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5660,7 +5645,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { address1.clone(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); let order_info = RpcOrderInfo { @@ -5704,8 +5689,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { ); } let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5721,7 +5706,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -5770,8 +5755,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { }; let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5785,7 +5770,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -5827,8 +5812,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { nonce: Some(AccountNonce::new(1)), }; let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5841,7 +5826,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -5983,8 +5968,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { let sell_amount = Amount::from_atoms(1000); let give_value = OutputValue::Coin(sell_amount); let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -5997,7 +5982,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { address1.clone(), FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); let order_info = RpcOrderInfo { @@ -6042,8 +6027,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { } let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -6058,7 +6043,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); @@ -6107,8 +6092,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { }; let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(issued_token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(issued_token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: unconfirmed_token_info.num_decimals(), ticker: unconfirmed_token_info.token_ticker().to_vec(), }), @@ -6121,7 +6106,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), - &additional_info, + additional_info, ) .unwrap(); diff --git a/wallet/types/src/partially_signed_transaction.rs b/wallet/types/src/partially_signed_transaction.rs index 44e7336f0..eeed7254e 100644 --- a/wallet/types/src/partially_signed_transaction.rs +++ b/wallet/types/src/partially_signed_transaction.rs @@ -13,11 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::collections::BTreeMap; + use common::{ chain::{ htlc::HtlcSecret, + output_value::OutputValue, signature::{inputsig::InputWitness, Signable, Transactable}, - Destination, SignedTransaction, Transaction, TransactionCreationError, TxInput, TxOutput, + tokens::TokenId, + Destination, OrderId, PoolId, SignedTransaction, Transaction, TransactionCreationError, + TxInput, TxOutput, }, primitives::Amount, }; @@ -30,8 +35,6 @@ use utils::ensure; pub enum PartiallySignedTransactionCreationError { #[error("Failed to convert partially signed tx to signed")] FailedToConvertPartiallySignedTx(PartiallySignedTransaction), - #[error("The number of output additional infos does not match the number of outputs")] - InvalidOutputAdditionalInfoCount, #[error("Failed to create transaction: {0}")] TxCreationError(#[from] TransactionCreationError), #[error("The number of input utxos does not match the number of inputs")] @@ -42,60 +45,55 @@ pub enum PartiallySignedTransactionCreationError { InvalidHtlcSecretsCount, } +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)] +pub enum InfoId { + PoolId(PoolId), + TokenId(TokenId), + OrderId(OrderId), +} + #[derive(Debug, Eq, PartialEq, Clone, Encode, Decode)] pub struct TokenAdditionalInfo { pub num_decimals: u8, pub ticker: Vec, } -/// Additional info for UTXOs +/// Additional info for a partially signed Tx mainly used by hardware wallets to show info to the +/// user #[derive(Debug, Eq, PartialEq, Clone, Encode, Decode)] -pub enum UtxoAdditionalInfo { +pub enum TxAdditionalInfo { TokenInfo(TokenAdditionalInfo), PoolInfo { staker_balance: Amount, }, - CreateOrder { - ask: Option, - give: Option, + OrderInfo { + initially_asked: OutputValue, + initially_given: OutputValue, + ask_balance: Amount, + give_balance: Amount, }, } -#[derive(Debug, Eq, PartialEq, Clone, Encode, Decode)] -pub struct UtxoWithAdditionalInfo { - pub utxo: TxOutput, - pub additional_info: Option, -} - -impl UtxoWithAdditionalInfo { - pub fn new(utxo: TxOutput, additional_info: Option) -> Self { - Self { - utxo, - additional_info, - } - } -} - #[derive(Debug, Eq, PartialEq, Clone, Encode, Decode)] pub struct PartiallySignedTransaction { tx: Transaction, witnesses: Vec>, - input_utxos: Vec>, + input_utxos: Vec>, destinations: Vec>, htlc_secrets: Vec>, - output_additional_infos: Vec>, + additional_infos: BTreeMap, } impl PartiallySignedTransaction { pub fn new( tx: Transaction, witnesses: Vec>, - input_utxos: Vec>, + input_utxos: Vec>, destinations: Vec>, htlc_secrets: Option>>, - output_additional_infos: Vec>, + additional_infos: BTreeMap, ) -> Result { let htlc_secrets = htlc_secrets.unwrap_or_else(|| vec![None; tx.inputs().len()]); @@ -105,7 +103,7 @@ impl PartiallySignedTransaction { input_utxos, destinations, htlc_secrets, - output_additional_infos, + additional_infos, }; this.ensure_consistency()?; @@ -134,11 +132,6 @@ impl PartiallySignedTransaction { PartiallySignedTransactionCreationError::InvalidHtlcSecretsCount ); - ensure!( - self.tx.outputs().len() == self.output_additional_infos.len(), - PartiallySignedTransactionCreationError::InvalidOutputAdditionalInfoCount - ); - Ok(()) } @@ -155,7 +148,7 @@ impl PartiallySignedTransaction { self.tx } - pub fn input_utxos(&self) -> &[Option] { + pub fn input_utxos(&self) -> &[Option] { self.input_utxos.as_ref() } @@ -175,10 +168,6 @@ impl PartiallySignedTransaction { self.tx.inputs().len() } - pub fn output_additional_infos(&self) -> &[Option] { - &self.output_additional_infos - } - pub fn all_signatures_available(&self) -> bool { self.witnesses .iter() @@ -203,6 +192,10 @@ impl PartiallySignedTransaction { Err(PartiallySignedTransactionCreationError::FailedToConvertPartiallySignedTx(self)) } } + + pub fn additional_infos(&self) -> &BTreeMap { + &self.additional_infos + } } impl Signable for PartiallySignedTransaction { diff --git a/wallet/wallet-cli-lib/src/lib.rs b/wallet/wallet-cli-lib/src/lib.rs index 385b0ad53..d947591d3 100644 --- a/wallet/wallet-cli-lib/src/lib.rs +++ b/wallet/wallet-cli-lib/src/lib.rs @@ -36,11 +36,12 @@ use node_comm::{make_cold_wallet_rpc_client, make_rpc_client, rpc_client::ColdWa use rpc::RpcAuthData; use tokio::sync::mpsc; use utils::{cookie::COOKIE_FILENAME, default_data_dir::default_data_dir_for_chain, ensure}; -use wallet_cli_commands::{ - CliHardwareWalletType, ManageableWalletCommand, WalletCommand, WalletManagementCommand, -}; +use wallet_cli_commands::{ManageableWalletCommand, WalletCommand, WalletManagementCommand}; use wallet_rpc_lib::{cmdline::make_wallet_config, config::WalletRpcConfig, types::NodeInterface}; +#[cfg(feature = "trezor")] +use wallet_cli_commands::CliHardwareWalletType; + enum Mode { Interactive { logger: repl::interactive::log::InteractiveLogger, diff --git a/wallet/wallet-controller/src/helpers.rs b/wallet/wallet-controller/src/helpers.rs index f0d3134b9..542e13836 100644 --- a/wallet/wallet-controller/src/helpers.rs +++ b/wallet/wallet-controller/src/helpers.rs @@ -22,7 +22,8 @@ use common::{ chain::{ output_value::OutputValue, tokens::{RPCTokenInfo, TokenId}, - ChainConfig, Destination, PoolId, Transaction, TxInput, TxOutput, UtxoOutPoint, + AccountCommand, ChainConfig, Destination, PoolId, Transaction, TxInput, TxOutput, + UtxoOutPoint, }, primitives::{amount::RpcAmountOut, Amount}, }; @@ -37,7 +38,7 @@ use wallet::{ }; use wallet_types::{ partially_signed_transaction::{ - PartiallySignedTransaction, TokenAdditionalInfo, UtxoAdditionalInfo, UtxoWithAdditionalInfo, + InfoId, PartiallySignedTransaction, TokenAdditionalInfo, TxAdditionalInfo, }, Currency, }; @@ -138,10 +139,12 @@ fn pool_id_from_txo(utxo: &TxOutput) -> Option { } } +pub type AdditionalInfos = BTreeMap; + async fn fetch_token_extra_info( rpc_client: &T, value: &OutputValue, -) -> Result, ControllerError> +) -> Result, ControllerError> where T: NodeInterface, { @@ -149,10 +152,13 @@ where OutputValue::Coin(_) | OutputValue::TokenV0(_) => Ok(None), OutputValue::TokenV1(token_id, _) => { let info = fetch_token_info(rpc_client, *token_id).await?; - Ok(Some(TokenAdditionalInfo { - num_decimals: info.token_number_of_decimals(), - ticker: info.token_ticker().to_vec(), - })) + Ok(Some(( + InfoId::TokenId(*token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { + num_decimals: info.token_number_of_decimals(), + ticker: info.token_ticker().to_vec(), + }), + ))) } } } @@ -160,7 +166,7 @@ where pub async fn fetch_utxo_extra_info( rpc_client: &T, utxo: TxOutput, -) -> Result> +) -> Result<(TxOutput, AdditionalInfos), ControllerError> where T: NodeInterface, { @@ -169,34 +175,35 @@ where | TxOutput::Transfer(value, _) | TxOutput::LockThenTransfer(value, _, _) | TxOutput::Htlc(value, _) => { - let additional_info = fetch_token_extra_info(rpc_client, value) - .await? - .map(UtxoAdditionalInfo::TokenInfo); - Ok(UtxoWithAdditionalInfo::new(utxo, additional_info)) + let additional_info = fetch_token_extra_info(rpc_client, value).await?; + Ok((utxo, additional_info.into_iter().collect())) } TxOutput::CreateOrder(order) => { - let ask = fetch_token_extra_info(rpc_client, order.ask()).await?; - let give = fetch_token_extra_info(rpc_client, order.ask()).await?; - let additional_info = Some(UtxoAdditionalInfo::CreateOrder { ask, give }); - Ok(UtxoWithAdditionalInfo::new(utxo, additional_info)) + let ask_info = fetch_token_extra_info(rpc_client, order.ask()).await?; + let give_info = fetch_token_extra_info(rpc_client, order.ask()).await?; + let additional_info = ask_info.into_iter().chain(give_info).collect(); + Ok((utxo, additional_info)) } TxOutput::ProduceBlockFromStake(_, pool_id) => { - let staker_balance = rpc_client + let additional_infos = rpc_client .get_staker_balance(*pool_id) .await .map_err(ControllerError::NodeCallError)? + .map(|staker_balance| { + BTreeMap::from([( + InfoId::PoolId(*pool_id), + TxAdditionalInfo::PoolInfo { staker_balance }, + )]) + }) .ok_or(WalletError::UnknownPoolId(*pool_id))?; - Ok(UtxoWithAdditionalInfo::new( - utxo, - Some(UtxoAdditionalInfo::PoolInfo { staker_balance }), - )) + Ok((utxo, additional_infos)) } TxOutput::IssueNft(_, _, _) | TxOutput::IssueFungibleToken(_) | TxOutput::CreateStakePool(_, _) | TxOutput::DelegateStaking(_, _) | TxOutput::CreateDelegationId(_, _) - | TxOutput::DataDeposit(_) => Ok(UtxoWithAdditionalInfo::new(utxo, None)), + | TxOutput::DataDeposit(_) => Ok((utxo, BTreeMap::new())), } } @@ -238,7 +245,17 @@ pub async fn tx_to_partially_signed_tx( .iter() .map(|inp| into_utxo_and_destination(rpc_client, wallet, inp)) .collect(); - let (input_utxos, destinations) = tasks.try_collect::>().await?.into_iter().unzip(); + let (input_utxos, additional_infos, destinations) = + tasks.try_collect::>().await?.into_iter().fold( + (Vec::new(), BTreeMap::new(), Vec::new()), + |(mut input_utxos, mut additional_infos, mut destinations), (x, y, z)| { + input_utxos.push(x); + additional_infos.extend(y); + destinations.push(z); + (input_utxos, additional_infos, destinations) + }, + ); + let num_inputs = tx.inputs().len(); let tasks: FuturesOrdered<_> = tx @@ -246,12 +263,13 @@ pub async fn tx_to_partially_signed_tx( .iter() .map(|out| fetch_utxo_extra_info(rpc_client, out.clone())) .collect(); - let output_additional_infos = tasks - .try_collect::>() - .await? - .into_iter() - .map(|x| x.additional_info) - .collect(); + let additional_infos = tasks.try_collect::>().await?.into_iter().fold( + additional_infos, + |mut acc, (_, info)| { + acc.extend(info); + acc + }, + ); let ptx = PartiallySignedTransaction::new( tx, @@ -259,7 +277,7 @@ pub async fn tx_to_partially_signed_tx( input_utxos, destinations, None, - output_additional_infos, + additional_infos, ) .map_err(WalletError::PartiallySignedTransactionCreation)?; Ok(ptx) @@ -269,12 +287,12 @@ async fn into_utxo_and_destination( rpc_client: &T, wallet: &RuntimeWallet, tx_inp: &TxInput, -) -> Result<(Option, Option), ControllerError> { +) -> Result<(Option, AdditionalInfos, Option), ControllerError> { Ok(match tx_inp { TxInput::Utxo(outpoint) => { let (utxo, dest) = fetch_utxo_with_destination(rpc_client, outpoint, wallet).await?; - let utxo_with_extra_info = fetch_utxo_extra_info(rpc_client, utxo).await?; - (Some(utxo_with_extra_info), Some(dest)) + let (utxo, additional_infos) = fetch_utxo_extra_info(rpc_client, utxo).await?; + (Some(utxo), additional_infos, Some(dest)) } TxInput::Account(acc_outpoint) => { // find delegation destination @@ -283,7 +301,7 @@ async fn into_utxo_and_destination( #[cfg(feature = "trezor")] RuntimeWallet::Trezor(w) => w.find_account_destination(acc_outpoint), }; - (None, dest) + (None, BTreeMap::new(), dest) } TxInput::AccountCommand(_, cmd) => { // find authority of the token @@ -292,7 +310,54 @@ async fn into_utxo_and_destination( #[cfg(feature = "trezor")] RuntimeWallet::Trezor(w) => w.find_account_command_destination(cmd), }; - (None, dest) + + let additional_infos = match cmd { + AccountCommand::FillOrder(order_id, _, _) + | AccountCommand::ConcludeOrder(order_id) => { + let order_info = rpc_client + .get_order_info(*order_id) + .await + .map_err(ControllerError::NodeCallError)? + .ok_or(ControllerError::WalletError(WalletError::OrderInfoMissing( + *order_id, + )))?; + + let ask_token_info = fetch_token_extra_info( + rpc_client, + &Currency::from_rpc_output_value(&order_info.initially_asked) + .into_output_value(order_info.ask_balance), + ) + .await?; + let give_token_info = fetch_token_extra_info( + rpc_client, + &Currency::from_rpc_output_value(&order_info.initially_given) + .into_output_value(order_info.give_balance), + ) + .await?; + + ask_token_info + .into_iter() + .chain(give_token_info) + .chain([( + InfoId::OrderId(*order_id), + TxAdditionalInfo::OrderInfo { + initially_asked: order_info.initially_asked.into(), + initially_given: order_info.initially_given.into(), + ask_balance: order_info.ask_balance, + give_balance: order_info.give_balance, + }, + )]) + .collect() + } + AccountCommand::MintTokens(_, _) + | AccountCommand::UnmintTokens(_) + | AccountCommand::FreezeToken(_, _) + | AccountCommand::UnfreezeToken(_) + | AccountCommand::LockTokenSupply(_) + | AccountCommand::ChangeTokenAuthority(_, _) + | AccountCommand::ChangeTokenMetadataUri(_, _) => BTreeMap::new(), + }; + (None, additional_infos, dest) } }) } diff --git a/wallet/wallet-controller/src/lib.rs b/wallet/wallet-controller/src/lib.rs index 3674aa21c..a4f2b708f 100644 --- a/wallet/wallet-controller/src/lib.rs +++ b/wallet/wallet-controller/src/lib.rs @@ -31,7 +31,9 @@ use chainstate::tx_verifier::{ self, error::ScriptError, input_check::signature_only_check::SignatureOnlyVerifiable, }; use futures::{never::Never, stream::FuturesOrdered, TryStreamExt}; -use helpers::{fetch_token_info, fetch_utxo, fetch_utxo_extra_info, into_balances}; +use helpers::{ + fetch_token_info, fetch_utxo, fetch_utxo_extra_info, into_balances, AdditionalInfos, +}; use node_comm::rpc_client::ColdWalletClient; use runtime_wallet::RuntimeWallet; use std::{ @@ -100,7 +102,7 @@ pub use wallet_types::{ utxo_types::{UtxoState, UtxoStates, UtxoType, UtxoTypes}, }; use wallet_types::{ - partially_signed_transaction::{PartiallySignedTransaction, UtxoWithAdditionalInfo}, + partially_signed_transaction::PartiallySignedTransaction, signature_status::SignatureStatus, wallet_type::{WalletControllerMode, WalletType}, with_locked::WithLocked, @@ -912,14 +914,9 @@ where &self, ptx: PartiallySignedTransaction, ) -> Result> { - let input_utxos: Vec<_> = - ptx.input_utxos().iter().flatten().map(|utxo| &utxo.utxo).cloned().collect(); + let input_utxos: Vec<_> = ptx.input_utxos().iter().flatten().cloned().collect(); let fees = self.get_fees(&input_utxos, ptx.tx().outputs()).await?; - let inputs_utxos_refs: Vec<_> = ptx - .input_utxos() - .iter() - .map(|out| out.as_ref().map(|utxo| &utxo.utxo)) - .collect(); + let inputs_utxos_refs: Vec<_> = ptx.input_utxos().iter().map(|out| out.as_ref()).collect(); let signature_statuses: Vec<_> = ptx .witnesses() .iter() @@ -1056,20 +1053,31 @@ where .collect::, WalletError>>() .map_err(ControllerError::WalletError)?; - let input_utxos = self.fetch_utxos_extra_info(input_utxos).await?; - let output_additional_infos = self + let (input_utxos, additional_infos) = + self.fetch_utxos_extra_info(input_utxos).await?.into_iter().fold( + (Vec::new(), BTreeMap::new()), + |(mut input_utxos, mut additional_infos), (x, y)| { + input_utxos.push(x); + additional_infos.extend(y); + (input_utxos, additional_infos) + }, + ); + + let additional_infos = self .fetch_utxos_extra_info(tx.outputs().to_vec()) .await? .into_iter() - .map(|x| x.additional_info) - .collect(); + .fold(additional_infos, |mut acc, (_, info)| { + acc.extend(info); + acc + }); let tx = PartiallySignedTransaction::new( tx, vec![None; num_inputs], input_utxos.into_iter().map(Option::Some).collect(), destinations.into_iter().map(Option::Some).collect(), htlc_secrets, - output_additional_infos, + additional_infos, ) .map_err(WalletError::PartiallySignedTransactionCreation)?; @@ -1155,13 +1163,12 @@ where async fn fetch_utxos_extra_info( &self, inputs: Vec, - ) -> Result, ControllerError> { + ) -> Result, ControllerError> { let tasks: FuturesOrdered<_> = inputs .into_iter() .map(|input| fetch_utxo_extra_info(&self.rpc_client, input)) .collect(); - let input_utxos: Vec = tasks.try_collect().await?; - Ok(input_utxos) + tasks.try_collect().await } async fn fetch_opt_utxo( diff --git a/wallet/wallet-controller/src/runtime_wallet.rs b/wallet/wallet-controller/src/runtime_wallet.rs index f883de2de..fc9ad5ef9 100644 --- a/wallet/wallet-controller/src/runtime_wallet.rs +++ b/wallet/wallet-controller/src/runtime_wallet.rs @@ -35,19 +35,22 @@ use crypto::vrf::VRFPublicKey; use mempool::FeeRate; use wallet::account::transaction_list::TransactionList; use wallet::account::{CoinSelectionAlgo, DelegationData, PoolData, TxInfo, UnconfirmedTokenInfo}; -use wallet::send_request::{PoolOrTokenId, SelectedInputs, StakePoolDataArguments}; +use wallet::send_request::{SelectedInputs, StakePoolDataArguments}; use wallet::signer::software_signer::SoftwareSignerProvider; use wallet::wallet::WalletPoolsFilter; use wallet::wallet_events::WalletEvents; use wallet::{Wallet, WalletError, WalletResult}; -use wallet_types::account_info::{StandaloneAddressDetails, StandaloneAddresses}; -use wallet_types::partially_signed_transaction::{PartiallySignedTransaction, UtxoAdditionalInfo}; +use wallet_types::partially_signed_transaction::{PartiallySignedTransaction, TxAdditionalInfo}; use wallet_types::seed_phrase::SerializableSeedPhrase; use wallet_types::signature_status::SignatureStatus; use wallet_types::utxo_types::{UtxoStates, UtxoTypes}; use wallet_types::wallet_tx::TxData; use wallet_types::with_locked::WithLocked; +use wallet_types::{ + account_info::{StandaloneAddressDetails, StandaloneAddresses}, + partially_signed_transaction::InfoId, +}; use wallet_types::{Currency, KeychainUsageState}; #[cfg(feature = "trezor")] @@ -784,7 +787,7 @@ impl RuntimeWallet { change_addresses: BTreeMap>, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_transaction_to_addresses( @@ -815,7 +818,7 @@ impl RuntimeWallet { destination_address: Destination, filtered_inputs: Vec<(UtxoOutPoint, TxOutput)>, current_fee_rate: FeeRate, - additional_utxo_infos: BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_sweep_transaction( @@ -823,7 +826,7 @@ impl RuntimeWallet { destination_address, filtered_inputs, current_fee_rate, - &additional_utxo_infos, + additional_utxo_infos, ), #[cfg(feature = "trezor")] RuntimeWallet::Trezor(w) => w.create_sweep_transaction( @@ -831,7 +834,7 @@ impl RuntimeWallet { destination_address, filtered_inputs, current_fee_rate, - &additional_utxo_infos, + additional_utxo_infos, ), } } @@ -885,7 +888,7 @@ impl RuntimeWallet { change_addresses: BTreeMap>, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(PartiallySignedTransaction, BTreeMap)> { match self { RuntimeWallet::Software(w) => w.create_unsigned_transaction_to_addresses( @@ -1046,7 +1049,7 @@ impl RuntimeWallet { htlc: HashedTimelockContract, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_htlc_tx( @@ -1078,7 +1081,7 @@ impl RuntimeWallet { conclude_key: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(OrderId, SignedTransaction)> { match self { RuntimeWallet::Software(w) => w.create_order_tx( @@ -1112,7 +1115,7 @@ impl RuntimeWallet { output_address: Option, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_conclude_order_tx( @@ -1147,7 +1150,7 @@ impl RuntimeWallet { output_address: Option, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_fill_order_tx( @@ -1213,7 +1216,7 @@ impl RuntimeWallet { intent: String, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> WalletResult<(SignedTransaction, SignedTransactionIntent)> { match self { RuntimeWallet::Software(w) => w.create_transaction_to_addresses_with_intent( diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index bf4ab36c9..8979837a1 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -50,7 +50,7 @@ use wallet::{ destination_getters::{get_tx_output_destination, HtlcSpendingCondition}, send_request::{ make_address_output, make_address_output_token, make_create_delegation_output, - make_data_deposit_output, PoolOrTokenId, SelectedInputs, StakePoolDataArguments, + make_data_deposit_output, SelectedInputs, StakePoolDataArguments, }, wallet::WalletPoolsFilter, wallet_events::WalletEvents, @@ -58,7 +58,7 @@ use wallet::{ }; use wallet_types::{ partially_signed_transaction::{ - PartiallySignedTransaction, TokenAdditionalInfo, UtxoAdditionalInfo, + InfoId, PartiallySignedTransaction, TokenAdditionalInfo, TxAdditionalInfo, }, signature_status::SignatureStatus, utxo_types::{UtxoState, UtxoType}, @@ -161,7 +161,7 @@ where ) -> Result< ( Vec<(UtxoOutPoint, TxOutput)>, - BTreeMap, + BTreeMap, ), ControllerError, > { @@ -197,8 +197,8 @@ where result.push(utxo); for token_info in token_infos { additional_utxo_infos.insert( - PoolOrTokenId::TokenId(token_info.token_id()), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_info.token_id()), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.token_number_of_decimals(), ticker: token_info.token_ticker().to_vec(), }), @@ -531,7 +531,7 @@ where BTreeMap::new(), current_fee_rate, consolidate_fee_rate, - &BTreeMap::new(), + BTreeMap::new(), ) }, ) @@ -563,7 +563,7 @@ where BTreeMap::new(), current_fee_rate, consolidate_fee_rate, - &BTreeMap::new(), + BTreeMap::new(), ) }, ) @@ -694,7 +694,7 @@ where [(Currency::Coin, change_address)].into(), current_fee_rate, consolidate_fee_rate, - &BTreeMap::new(), + BTreeMap::new(), ) .map_err(ControllerError::WalletError)?; @@ -745,8 +745,8 @@ where for (token_id, outputs_vec) in outputs { let token_info = fetch_token_info(&self.rpc_client, token_id).await?; additional_utxo_infos.insert( - PoolOrTokenId::TokenId(token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.token_number_of_decimals(), ticker: token_info.token_ticker().to_vec(), }), @@ -846,7 +846,7 @@ where change_addresses, current_fee_rate, consolidate_fee_rate, - &additional_utxo_infos, + additional_utxo_infos, )?; let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; @@ -899,7 +899,7 @@ where BTreeMap::new(), current_fee_rate, consolidate_fee_rate, - &BTreeMap::new(), + BTreeMap::new(), ) }, ) @@ -961,8 +961,8 @@ where token_info: &UnconfirmedTokenInfo| { token_info.check_can_be_used()?; let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(token_info.token_id()), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_info.token_id()), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.num_decimals(), ticker: token_info.token_ticker().to_vec(), }), @@ -974,7 +974,7 @@ where BTreeMap::new(), current_fee_rate, consolidate_fee_rate, - &additional_info, + additional_info, ) }, ) @@ -999,8 +999,8 @@ where token_info: &UnconfirmedTokenInfo| { token_info.check_can_be_used()?; let additional_info = BTreeMap::from_iter([( - PoolOrTokenId::TokenId(token_info.token_id()), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_info.token_id()), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.num_decimals(), ticker: token_info.token_ticker().to_vec(), }), @@ -1013,7 +1013,7 @@ where intent, current_fee_rate, consolidate_fee_rate, - &additional_info, + additional_info, ) }, ) @@ -1113,7 +1113,7 @@ where &mut self, output_value: OutputValue, htlc: HashedTimelockContract, - additional_utxo_infos: &BTreeMap, + additional_utxo_infos: BTreeMap, ) -> Result> { let (current_fee_rate, consolidate_fee_rate) = self.get_current_and_consolidation_fee_rate().await?; @@ -1150,7 +1150,7 @@ where conclude_key, current_fee_rate, consolidate_fee_rate, - &additional_info, + additional_info, ) }, ) @@ -1177,7 +1177,7 @@ where output_address, current_fee_rate, consolidate_fee_rate, - &additional_info, + additional_info, ) }, ) @@ -1206,7 +1206,7 @@ where output_address, current_fee_rate, consolidate_fee_rate, - &additional_info, + additional_info, ) }, ) @@ -1216,15 +1216,15 @@ where fn additional_token_infos( &mut self, token_infos: Vec, - ) -> Result, ControllerError> { + ) -> Result, ControllerError> { token_infos .into_iter() .map(|token_info| { let token_info = self.unconfiremd_token_info(token_info)?; Ok(( - PoolOrTokenId::TokenId(token_info.token_id()), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_info.token_id()), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.num_decimals(), ticker: token_info.token_ticker().to_vec(), }), diff --git a/wallet/wallet-rpc-lib/src/rpc/mod.rs b/wallet/wallet-rpc-lib/src/rpc/mod.rs index d24f82edc..4a1434283 100644 --- a/wallet/wallet-rpc-lib/src/rpc/mod.rs +++ b/wallet/wallet-rpc-lib/src/rpc/mod.rs @@ -39,7 +39,6 @@ use utils::{ensure, shallow_clone::ShallowClone}; use utils_networking::IpOrSocketAddress; use wallet::{ account::{transaction_list::TransactionList, PoolData, TransactionToSign, TxInfo}, - send_request::PoolOrTokenId, WalletError, }; @@ -79,7 +78,7 @@ use wallet_controller::{ use wallet_types::{ account_info::StandaloneAddressDetails, partially_signed_transaction::{ - PartiallySignedTransaction, TokenAdditionalInfo, UtxoAdditionalInfo, + InfoId, PartiallySignedTransaction, TokenAdditionalInfo, TxAdditionalInfo, }, signature_status::SignatureStatus, wallet_tx::TxData, @@ -1509,8 +1508,8 @@ where .to_amount(token_info.token_number_of_decimals()) .ok_or(RpcError::InvalidCoinAmount)?; additional_utxo_infos.insert( - PoolOrTokenId::TokenId(token_id), - UtxoAdditionalInfo::TokenInfo(TokenAdditionalInfo { + InfoId::TokenId(token_id), + TxAdditionalInfo::TokenInfo(TokenAdditionalInfo { num_decimals: token_info.token_number_of_decimals(), ticker: token_info.token_ticker().to_vec(), }), @@ -1528,7 +1527,7 @@ where controller .synced_controller(account_index, config) .await? - .create_htlc_tx(value, htlc, &additional_utxo_infos) + .create_htlc_tx(value, htlc, additional_utxo_infos) .await .map_err(RpcError::Controller) })