Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(trezor): add segwit support for withdraw with trezor #1984

Merged
merged 17 commits into from
Dec 21, 2023
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
1 change: 1 addition & 0 deletions Cargo.lock

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

26 changes: 14 additions & 12 deletions mm2src/coins/hd_confirm_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crypto::{CryptoCtx, CryptoCtxError, HardwareWalletArc, HwError, HwProcessing
use enum_from::{EnumFromInner, EnumFromStringify};
use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandle};
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandleShared};
use std::sync::Arc;

const SHOW_ADDRESS_ON_DISPLAY: bool = true;

Expand Down Expand Up @@ -43,6 +44,7 @@ impl From<HwProcessingError<RpcTaskError>> for HDConfirmAddressError {
match e {
HwProcessingError::HwError(hw) => HDConfirmAddressError::from(hw),
HwProcessingError::ProcessorError(rpc) => HDConfirmAddressError::RpcTaskError(rpc),
HwProcessingError::InternalError(err) => HDConfirmAddressError::Internal(err),
}
}
}
Expand All @@ -66,16 +68,16 @@ pub trait HDConfirmAddress: Sync {
) -> MmResult<(), HDConfirmAddressError>;
}

pub enum RpcTaskConfirmAddress<'task, Task: RpcTask> {
pub enum RpcTaskConfirmAddress<Task: RpcTask> {
Trezor {
hw_ctx: HardwareWalletArc,
task_handle: &'task RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
},
}

#[async_trait]
impl<'task, Task> HDConfirmAddress for RpcTaskConfirmAddress<'task, Task>
impl<Task> HDConfirmAddress for RpcTaskConfirmAddress<Task>
where
Task: RpcTask,
Task::InProgressStatus: ConfirmAddressStatus,
Expand All @@ -95,7 +97,7 @@ where
} => {
Self::confirm_utxo_address_with_trezor(
hw_ctx,
task_handle,
task_handle.clone(),
statuses,
trezor_utxo_coin,
derivation_path,
Expand All @@ -107,17 +109,17 @@ where
}
}

impl<'task, Task> RpcTaskConfirmAddress<'task, Task>
impl<Task> RpcTaskConfirmAddress<Task>
where
Task: RpcTask,
Task::InProgressStatus: ConfirmAddressStatus,
Task::UserAction: TryIntoUserAction + Send,
{
pub fn new(
ctx: &MmArc,
task_handle: &'task RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
) -> MmResult<RpcTaskConfirmAddress<'task, Task>, HDConfirmAddressError> {
) -> MmResult<RpcTaskConfirmAddress<Task>, HDConfirmAddressError> {
let crypto_ctx = CryptoCtx::from_ctx(ctx)?;
let hw_ctx = crypto_ctx
.hw_ctx()
Expand All @@ -131,24 +133,24 @@ where

async fn confirm_utxo_address_with_trezor(
hw_ctx: &HardwareWalletArc,
task_handle: &RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
connect_statuses: &HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
trezor_coin: String,
derivation_path: DerivationPath,
expected_address: String,
) -> MmResult<(), HDConfirmAddressError> {
let mut trezor_session = hw_ctx.trezor().await?;

let confirm_statuses = TrezorRequestStatuses {
on_button_request: Task::InProgressStatus::confirm_addr_status(expected_address.clone()),
..connect_statuses.to_trezor_request_statuses()
};

let pubkey_processor = TrezorRpcTaskProcessor::new(task_handle, confirm_statuses);
let pubkey_processor = Arc::new(pubkey_processor);
let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await?;
let address = trezor_session
.get_utxo_address(derivation_path, trezor_coin, SHOW_ADDRESS_ON_DISPLAY)
.await?
.process(&pubkey_processor)
.process(pubkey_processor.clone())
.await?;

if address != expected_address {
Expand Down
39 changes: 24 additions & 15 deletions mm2src/coins/hd_pubkey.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::Arc;

use crate::hd_wallet::NewAccountCreatingError;
use async_trait::async_trait;
use crypto::hw_rpc_task::HwConnectStatuses;
Expand All @@ -8,7 +10,7 @@ use crypto::{CryptoCtx, CryptoCtxError, DerivationPath, EcdsaCurve, HardwareWall
XPub, XPubConverter, XpubError};
use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandle};
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandleShared};

const SHOW_PUBKEY_ON_DISPLAY: bool = false;

Expand Down Expand Up @@ -48,6 +50,7 @@ impl From<HwProcessingError<RpcTaskError>> for HDExtractPubkeyError {
match e {
HwProcessingError::HwError(hw) => HDExtractPubkeyError::from(hw),
HwProcessingError::ProcessorError(rpc) => HDExtractPubkeyError::RpcTaskError(rpc),
HwProcessingError::InternalError(err) => HDExtractPubkeyError::Internal(err),
}
}
}
Expand Down Expand Up @@ -93,16 +96,16 @@ pub trait HDXPubExtractor: Sync {
) -> MmResult<XPub, HDExtractPubkeyError>;
}

pub enum RpcTaskXPubExtractor<'task, Task: RpcTask> {
pub enum RpcTaskXPubExtractor<Task: RpcTask> {
Trezor {
hw_ctx: HardwareWalletArc,
task_handle: &'task RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
},
}

#[async_trait]
impl<'task, Task> HDXPubExtractor for RpcTaskXPubExtractor<'task, Task>
impl<Task> HDXPubExtractor for RpcTaskXPubExtractor<Task>
where
Task: RpcTask,
Task::UserAction: TryIntoUserAction + Send,
Expand All @@ -118,23 +121,29 @@ where
task_handle,
statuses,
} => {
Self::extract_utxo_xpub_from_trezor(hw_ctx, task_handle, statuses, trezor_utxo_coin, derivation_path)
.await
Self::extract_utxo_xpub_from_trezor(
hw_ctx,
task_handle.clone(),
statuses,
trezor_utxo_coin,
derivation_path,
)
.await
},
}
}
}

impl<'task, Task> RpcTaskXPubExtractor<'task, Task>
impl<Task> RpcTaskXPubExtractor<Task>
where
Task: RpcTask,
Task::UserAction: TryIntoUserAction + Send,
{
pub fn new(
ctx: &MmArc,
task_handle: &'task RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
) -> MmResult<RpcTaskXPubExtractor<'task, Task>, HDExtractPubkeyError> {
) -> MmResult<RpcTaskXPubExtractor<Task>, HDExtractPubkeyError> {
let crypto_ctx = CryptoCtx::from_ctx(ctx)?;
let hw_ctx = crypto_ctx
.hw_ctx()
Expand All @@ -149,22 +158,22 @@ where
/// Constructs an Xpub extractor without checking if the MarketMaker is initialized with a hardware wallet.
pub fn new_unchecked(
ctx: &MmArc,
task_handle: &'task RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
statuses: HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
) -> XPubExtractorUnchecked<RpcTaskXPubExtractor<'task, Task>> {
) -> XPubExtractorUnchecked<RpcTaskXPubExtractor<Task>> {
XPubExtractorUnchecked(Self::new(ctx, task_handle, statuses))
}

async fn extract_utxo_xpub_from_trezor(
hw_ctx: &HardwareWalletArc,
task_handle: &RpcTaskHandle<Task>,
task_handle: RpcTaskHandleShared<Task>,
statuses: &HwConnectStatuses<Task::InProgressStatus, Task::AwaitingStatus>,
trezor_coin: String,
derivation_path: DerivationPath,
) -> MmResult<XPub, HDExtractPubkeyError> {
let mut trezor_session = hw_ctx.trezor().await?;

let pubkey_processor = TrezorRpcTaskProcessor::new(task_handle, statuses.to_trezor_request_statuses());
let pubkey_processor = Arc::new(pubkey_processor);
let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await?;
let xpub = trezor_session
.get_public_key(
derivation_path,
Expand All @@ -174,7 +183,7 @@ where
IGNORE_XPUB_MAGIC,
)
.await?
.process(&pubkey_processor)
.process(pubkey_processor.clone())
.await?;

// Despite we pass `IGNORE_XPUB_MAGIC` to the [`TrezorSession::get_public_key`] method,
Expand Down
14 changes: 8 additions & 6 deletions mm2src/coins/rpc_command/get_new_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError,
RpcTaskStatusRequest, RpcTaskUserActionError};
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandle, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes};
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus,
RpcTaskTypes};
use std::time::Duration;

pub type GetNewAddressUserAction = HwRpcTaskUserAction;
pub type GetNewAddressAwaitingStatus = HwRpcTaskAwaitingStatus;
pub type GetNewAddressTaskManager = RpcTaskManager<InitGetNewAddressTask>;
pub type GetNewAddressTaskManagerShared = RpcTaskManagerShared<InitGetNewAddressTask>;
pub type GetNewAddressTaskHandle = RpcTaskHandle<InitGetNewAddressTask>;
pub type GetNewAddressTaskHandleShared = RpcTaskHandleShared<InitGetNewAddressTask>;
pub type GetNewAddressRpcTaskStatus = RpcTaskStatus<
GetNewAddressResponse,
GetNewAddressRpcError,
Expand Down Expand Up @@ -193,7 +194,7 @@ impl HttpStatusCode for GetNewAddressRpcError {
}
}

#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct GetNewAddressRequest {
coin: String,
#[serde(flatten)]
Expand Down Expand Up @@ -254,6 +255,7 @@ pub trait GetNewAddressRpcOps {
ConfirmAddress: HDConfirmAddress;
}

#[derive(Clone)]
pub struct InitGetNewAddressTask {
ctx: MmArc,
coin: MmCoinEnum,
Expand All @@ -275,12 +277,12 @@ impl RpcTask for InitGetNewAddressTask {
// Do nothing if the task has been cancelled.
async fn cancel(self) {}

async fn run(&mut self, task_handle: &RpcTaskHandle<Self>) -> Result<Self::Item, MmError<Self::Error>> {
async fn run(&mut self, task_handle: RpcTaskHandleShared<Self>) -> Result<Self::Item, MmError<Self::Error>> {
async fn get_new_address_helper<Coin>(
ctx: &MmArc,
coin: &Coin,
params: GetNewAddressParams,
task_handle: &GetNewAddressTaskHandle,
task_handle: GetNewAddressTaskHandleShared,
) -> MmResult<GetNewAddressResponse, GetNewAddressRpcError>
where
Coin: GetNewAddressRpcOps + Send + Sync,
Expand All @@ -294,7 +296,7 @@ impl RpcTask for InitGetNewAddressTask {
on_passphrase_request: GetNewAddressAwaitingStatus::EnterTrezorPassphrase,
on_ready: GetNewAddressInProgressStatus::RequestingAccountBalance,
};
let confirm_address: RpcTaskConfirmAddress<'_, InitGetNewAddressTask> =
let confirm_address: RpcTaskConfirmAddress<InitGetNewAddressTask> =
RpcTaskConfirmAddress::new(ctx, task_handle, hw_statuses)?;
coin.get_new_address_rpc(params, &confirm_address).await
}
Expand Down
9 changes: 6 additions & 3 deletions mm2src/coins/rpc_command/init_account_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError,
RpcTaskStatusRequest};
use rpc_task::{RpcTask, RpcTaskHandle, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes};
use rpc_task::{RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes};

pub type AccountBalanceUserAction = SerdeInfallible;
pub type AccountBalanceAwaitingStatus = SerdeInfallible;
pub type AccountBalanceTaskManager = RpcTaskManager<InitAccountBalanceTask>;
pub type AccountBalanceTaskManagerShared = RpcTaskManagerShared<InitAccountBalanceTask>;
pub type InitAccountBalanceTaskHandle = RpcTaskHandle<InitAccountBalanceTask>;
pub type InitAccountBalanceTaskHandleShared = RpcTaskHandleShared<InitAccountBalanceTask>;
pub type AccountBalanceRpcTaskStatus = RpcTaskStatus<
HDAccountBalance,
HDAccountBalanceRpcError,
Expand Down Expand Up @@ -66,7 +66,10 @@ impl RpcTask for InitAccountBalanceTask {
// Do nothing if the task has been cancelled.
async fn cancel(self) {}

async fn run(&mut self, _task_handle: &InitAccountBalanceTaskHandle) -> Result<Self::Item, MmError<Self::Error>> {
async fn run(
&mut self,
_task_handle: InitAccountBalanceTaskHandleShared,
) -> Result<Self::Item, MmError<Self::Error>> {
match self.coin {
MmCoinEnum::UtxoCoin(ref utxo) => utxo.init_account_balance_rpc(self.req.params.clone()).await,
MmCoinEnum::QtumCoin(ref qtum) => qtum.init_account_balance_rpc(self.req.params.clone()).await,
Expand Down
14 changes: 8 additions & 6 deletions mm2src/coins/rpc_command/init_create_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ use mm2_err_handle::prelude::*;
use parking_lot::Mutex as PaMutex;
use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError,
RpcTaskStatusRequest, RpcTaskUserActionError};
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandle, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes};
use rpc_task::{RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus,
RpcTaskTypes};
use std::sync::Arc;
use std::time::Duration;

pub type CreateAccountUserAction = HwRpcTaskUserAction;
pub type CreateAccountAwaitingStatus = HwRpcTaskAwaitingStatus;
pub type CreateAccountTaskManager = RpcTaskManager<InitCreateAccountTask>;
pub type CreateAccountTaskManagerShared = RpcTaskManagerShared<InitCreateAccountTask>;
pub type CreateAccountTaskHandle = RpcTaskHandle<InitCreateAccountTask>;
pub type CreateAccountTaskHandleShared = RpcTaskHandleShared<InitCreateAccountTask>;
pub type CreateAccountRpcTaskStatus =
RpcTaskStatus<HDAccountBalance, CreateAccountRpcError, CreateAccountInProgressStatus, CreateAccountAwaitingStatus>;

type CreateAccountXPubExtractor<'task> = RpcTaskXPubExtractor<'task, InitCreateAccountTask>;
type CreateAccountXPubExtractor = RpcTaskXPubExtractor<InitCreateAccountTask>;

#[derive(Clone, Debug, Display, EnumFromTrait, Serialize, SerializeErrorType)]
#[serde(tag = "error_type", content = "error_data")]
Expand Down Expand Up @@ -155,7 +156,7 @@ impl HttpStatusCode for CreateAccountRpcError {
}
}

#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct CreateNewAccountRequest {
coin: String,
#[serde(flatten)]
Expand Down Expand Up @@ -210,6 +211,7 @@ pub trait InitCreateAccountRpcOps {
async fn revert_creating_account(&self, account_id: u32);
}

#[derive(Clone)]
pub struct InitCreateAccountTask {
ctx: MmArc,
coin: MmCoinEnum,
Expand Down Expand Up @@ -241,13 +243,13 @@ impl RpcTask for InitCreateAccountTask {
};
}

async fn run(&mut self, task_handle: &CreateAccountTaskHandle) -> Result<Self::Item, MmError<Self::Error>> {
async fn run(&mut self, task_handle: CreateAccountTaskHandleShared) -> Result<Self::Item, MmError<Self::Error>> {
async fn create_new_account_helper<Coin>(
ctx: &MmArc,
coin: &Coin,
params: CreateNewAccountParams,
state: CreateAccountState,
task_handle: &CreateAccountTaskHandle,
task_handle: CreateAccountTaskHandleShared,
) -> MmResult<HDAccountBalance, CreateAccountRpcError>
where
Coin: InitCreateAccountRpcOps + Send + Sync,
Expand Down
6 changes: 3 additions & 3 deletions mm2src/coins/rpc_command/init_scan_for_new_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError,
RpcTaskStatusRequest};
use rpc_task::{RpcTask, RpcTaskHandle, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes};
use rpc_task::{RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes};

pub type ScanAddressesUserAction = SerdeInfallible;
pub type ScanAddressesAwaitingStatus = SerdeInfallible;
pub type ScanAddressesTaskManager = RpcTaskManager<InitScanAddressesTask>;
pub type ScanAddressesTaskManagerShared = RpcTaskManagerShared<InitScanAddressesTask>;
pub type ScanAddressesTaskHandle = RpcTaskHandle<InitScanAddressesTask>;
pub type ScanAddressesTaskHandleShared = RpcTaskHandleShared<InitScanAddressesTask>;
pub type ScanAddressesRpcTaskStatus = RpcTaskStatus<
ScanAddressesResponse,
HDAccountBalanceRpcError,
Expand Down Expand Up @@ -78,7 +78,7 @@ impl RpcTask for InitScanAddressesTask {
// Do nothing if the task has been cancelled.
async fn cancel(self) {}

async fn run(&mut self, _task_handle: &ScanAddressesTaskHandle) -> Result<Self::Item, MmError<Self::Error>> {
async fn run(&mut self, _task_handle: ScanAddressesTaskHandleShared) -> Result<Self::Item, MmError<Self::Error>> {
match self.coin {
MmCoinEnum::UtxoCoin(ref utxo) => utxo.init_scan_for_new_addresses_rpc(self.req.params.clone()).await,
MmCoinEnum::QtumCoin(ref qtum) => qtum.init_scan_for_new_addresses_rpc(self.req.params.clone()).await,
Expand Down
Loading
Loading