Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions mm2src/coins/hd_wallet/confirm_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use async_trait::async_trait;
use bip32::DerivationPath;
use crypto::hw_rpc_task::HwConnectStatuses;
use crypto::trezor::trezor_rpc_task::{TrezorRequestStatuses, TrezorRpcTaskProcessor, TryIntoUserAction};
use crypto::trezor::utxo::TrezorInputScriptType;
use crypto::trezor::{ProcessTrezorResponse, TrezorError, TrezorMessageType, TrezorProcessingError};
use crypto::{CryptoCtx, CryptoCtxError, HardwareWalletArc, HwError, HwProcessingError};
use enum_derives::{EnumFromInner, EnumFromStringify};
Expand Down Expand Up @@ -77,6 +78,7 @@ pub(crate) enum RpcTaskConfirmAddress<Task: RpcTask> {
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
trezor_message_type: TrezorMessageType,
trezor_script_type: Option<TrezorInputScriptType>,
},
}

Expand All @@ -99,6 +101,7 @@ where
task_handle,
statuses,
trezor_message_type,
trezor_script_type,
} => {
Self::confirm_address_with_trezor(
hw_ctx,
Expand All @@ -108,6 +111,7 @@ where
derivation_path,
expected_address,
trezor_message_type,
*trezor_script_type,
)
.await
},
Expand All @@ -126,6 +130,7 @@ where
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
trezor_message_type: TrezorMessageType,
trezor_script_type: Option<TrezorInputScriptType>,
) -> MmResult<RpcTaskConfirmAddress<Task>, HDConfirmAddressError> {
let crypto_ctx = CryptoCtx::from_ctx(ctx).map_mm_err()?;
let hw_ctx = crypto_ctx
Expand All @@ -136,9 +141,11 @@ where
task_handle,
statuses,
trezor_message_type,
trezor_script_type,
})
}

#[allow(clippy::too_many_arguments)]
async fn confirm_address_with_trezor(
hw_ctx: &HardwareWalletArc,
task_handle: RpcTaskHandleShared<Task>,
Expand All @@ -147,6 +154,7 @@ where
derivation_path: DerivationPath,
expected_address: String,
trezor_message_type: &TrezorMessageType,
trezor_script_type: Option<TrezorInputScriptType>,
) -> MmResult<(), HDConfirmAddressError> {
let confirm_statuses = TrezorRequestStatuses {
on_button_request: Task::InProgressStatus::confirm_addr_status(expected_address.clone()),
Expand All @@ -158,14 +166,19 @@ where
let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await.map_mm_err()?;
let address = match trezor_message_type {
TrezorMessageType::Bitcoin => trezor_session
.get_utxo_address(derivation_path, trezor_coin, SHOW_ADDRESS_ON_DISPLAY)
.get_utxo_address(
derivation_path,
trezor_coin,
SHOW_ADDRESS_ON_DISPLAY,
trezor_script_type,
)
.await
.map_mm_err()?
.process(pubkey_processor.clone())
.await
.map_mm_err()?,
TrezorMessageType::Ethereum => trezor_session
.get_eth_address(derivation_path, SHOW_ADDRESS_ON_DISPLAY)
.get_eth_address(&derivation_path, SHOW_ADDRESS_ON_DISPLAY)
.await
.map_mm_err()?
.process(pubkey_processor.clone())
Expand Down
2 changes: 2 additions & 0 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4300,6 +4300,8 @@ impl CoinsContext {
}

/// This enum is used in coin activation requests.
/// TODO: should we use #[serde(tag = "type", content = "params")] for this PrivKeyActivationPolicy like for the Eth policy,
/// to have them identical in activation requests
Comment on lines +4303 to +4304
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an issue for this #2522

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe fix this in a separate PR
(will be a breaking change for the API)

#[derive(Clone, Debug, Deserialize, Serialize, Default)]
pub enum PrivKeyActivationPolicy {
#[default]
Expand Down
69 changes: 48 additions & 21 deletions mm2src/coins/rpc_command/get_new_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::hd_wallet::{
AddressDerivingError, ConfirmAddressStatus, HDConfirmAddress, HDConfirmAddressError, InvalidBip44ChainError,
NewAddressDeriveConfirmError, NewAddressDerivingError, RpcTaskConfirmAddress,
};
use crate::utxo::UtxoCommonOps;
use crate::{
lp_coinfind_or_err, BalanceError, CoinBalance, CoinBalanceMap, CoinFindError, CoinsContext, MmCoinEnum,
UnexpectedDerivationMethod,
Expand All @@ -12,11 +13,13 @@ use common::{HttpStatusCode, SuccessResponse};
use crypto::hw_rpc_task::{
HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction, HwRpcTaskUserActionRequest,
};
use crypto::trezor::utxo::TrezorInputScriptType;
use crypto::trezor::TrezorMessageType;
use crypto::{from_hw_error, Bip44Chain, HwError, HwRpcError, WithHwRpcError};
use derive_more::Display;
use enum_derives::EnumFromTrait;
use http::StatusCode;
use keys::AddressFormat;
use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use rpc_task::rpc_common::{
Expand Down Expand Up @@ -310,12 +313,14 @@ impl RpcTask for InitGetNewAddressTask {
async fn cancel(self) {}

async fn run(&mut self, task_handle: RpcTaskHandleShared<Self>) -> Result<Self::Item, MmError<Self::Error>> {
/// Caller to get and confirm a new HD address for an HD wallet
async fn get_new_address_helper<Coin>(
ctx: &MmArc,
coin: &Coin,
params: GetNewAddressParams,
task_handle: GetNewAddressTaskHandleShared,
trezor_message_type: TrezorMessageType,
trezor_script_type: Option<TrezorInputScriptType>,
) -> MmResult<GetNewAddressResponse<<Coin as GetNewAddressRpcOps>::BalanceObject>, GetNewAddressRpcError>
where
Coin: GetNewAddressRpcOps + Send + Sync,
Expand All @@ -330,38 +335,60 @@ impl RpcTask for InitGetNewAddressTask {
on_ready: GetNewAddressInProgressStatus::RequestingAccountBalance,
};
let confirm_address: RpcTaskConfirmAddress<InitGetNewAddressTask> =
RpcTaskConfirmAddress::new(ctx, task_handle, hw_statuses, trezor_message_type).map_mm_err()?;
RpcTaskConfirmAddress::new(ctx, task_handle, hw_statuses, trezor_message_type, trezor_script_type)
.map_mm_err()?;
coin.get_new_address_rpc(params, &confirm_address).await
}

match self.coin {
MmCoinEnum::UtxoCoin(ref utxo) => Ok(GetNewAddressResponseEnum::Map(
get_new_address_helper(
&self.ctx,
utxo,
self.req.params.clone(),
task_handle,
TrezorMessageType::Bitcoin,
)
.await?,
)),
MmCoinEnum::QtumCoin(ref qtum) => Ok(GetNewAddressResponseEnum::Map(
get_new_address_helper(
&self.ctx,
qtum,
self.req.params.clone(),
task_handle,
TrezorMessageType::Bitcoin,
)
.await?,
)),
MmCoinEnum::UtxoCoin(ref utxo) => {
// Set script type to enable Trezor to correctly validate the derivation path
let trezor_script_type = match utxo.addr_format() {
AddressFormat::Standard | AddressFormat::CashAddress { .. } => {
Some(TrezorInputScriptType::SpendAddress)
},
AddressFormat::Segwit => Some(TrezorInputScriptType::SpendWitness),
};
Ok(GetNewAddressResponseEnum::Map(
get_new_address_helper(
&self.ctx,
utxo,
self.req.params.clone(),
task_handle,
TrezorMessageType::Bitcoin,
trezor_script_type,
)
.await?,
))
},
MmCoinEnum::QtumCoin(ref qtum) => {
// Set script type to enable Trezor to correctly validate the derivation path
let trezor_script_type = match qtum.addr_format() {
AddressFormat::Standard | AddressFormat::CashAddress { .. } => {
Some(TrezorInputScriptType::SpendAddress)
},
AddressFormat::Segwit => Some(TrezorInputScriptType::SpendWitness),
};
Ok(GetNewAddressResponseEnum::Map(
get_new_address_helper(
&self.ctx,
qtum,
self.req.params.clone(),
task_handle,
TrezorMessageType::Bitcoin,
trezor_script_type,
)
.await?,
))
},
MmCoinEnum::EthCoin(ref eth) => Ok(GetNewAddressResponseEnum::Map(
get_new_address_helper(
&self.ctx,
eth,
self.req.params.clone(),
task_handle,
TrezorMessageType::Ethereum,
None,
)
.await?,
)),
Expand Down
1 change: 1 addition & 0 deletions mm2src/coins/utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ pub struct UtxoCoinConf {
pub tx_version: i32,
/// Defines if Segwit is enabled for this coin.
/// https://en.bitcoin.it/wiki/Segregated_Witness
/// NOTE: this does not make the coin itself 'segwit'. This just tells that segwit addresses are supported for this coin
pub segwit: bool,
/// Does coin require transactions to be notarized to be considered as confirmed?
/// https://komodoplatform.com/security-delayed-proof-of-work-dpow/
Expand Down
3 changes: 3 additions & 0 deletions mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@ pub trait UtxoCoinBuilderCommonOps {

fn ticker(&self) -> &str;

/// This function basically defines 'my address' format (so whether a coin is segwit or not)
/// For that it looks for the "address_format" property first in the activation request then in the coins file.
/// This fn is called to set the address format in the derivaion_method in UtxoCoinFields, which creates my address.
fn address_format(&self) -> UtxoCoinBuildResult<UtxoAddressFormat> {
let format_from_req = self.activation_params().address_format.clone();
let format_from_conf = json::from_value::<Option<UtxoAddressFormat>>(self.conf()["address_format"].clone())
Expand Down
22 changes: 17 additions & 5 deletions mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6768,8 +6768,16 @@ mod trezor_tests {
.unwrap();
let _ = init_trezor_user_action(ctx.clone(), pin_req).await;
},
_ => {
panic!("Trezor passphrase is not supported in tests");
HwRpcTaskAwaitingStatus::EnterTrezorPassphrase => {
let empty_passphrase = serde_json::from_value(json!({
"task_id": task_id,
"user_action": {
"action_type": "TrezorPassphrase",
"passphrase": ""
}
}))
.unwrap();
let _ = init_trezor_user_action(ctx.clone(), empty_passphrase).await;
},
}
},
Expand Down Expand Up @@ -6841,7 +6849,7 @@ mod trezor_tests {
"method": "electrum",
"coin": ticker,
"servers": tbtc_electrums(),
"priv_key_policy": { "type": "Trezor" },
"priv_key_policy": "Trezor",
});
let activation_params = UtxoActivationParams::from_legacy_req(&enable_req).unwrap();
let request: InitStandaloneCoinReq<UtxoActivationParams> = json::from_value(json!({
Expand Down Expand Up @@ -6899,8 +6907,12 @@ mod trezor_tests {
});
let _ = init_trezor_user_action_rpc(mm, init.result.task_id, pin_action).await;
},
_ => {
panic!("Trezor passphrase is not supported in tests");
HwRpcTaskAwaitingStatus::EnterTrezorPassphrase => {
let empty_passphrase = json!({
"action_type": "TrezorPassphrase",
"passphrase": ""
});
let _ = init_trezor_user_action_rpc(mm, init.result.task_id, empty_passphrase).await;
},
}
},
Expand Down
Loading
Loading