Skip to content

Commit

Permalink
make extended pubkey of hd wallet generic
Browse files Browse the repository at this point in the history
  • Loading branch information
shamardy authored and onur-ozkan committed Jul 9, 2024
1 parent 947a7ab commit bde2077
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 54 deletions.
5 changes: 2 additions & 3 deletions mm2src/coins/coin_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,7 @@ pub enum AddressBalanceStatus<Balance> {
pub mod common_impl {
use super::*;
use crate::hd_wallet::{create_new_account, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps, HDAddressOps,
HDWalletOps};
use crypto::Secp256k1ExtendedPublicKey;
HDCoinExtendedPubkey, HDWalletOps};

pub(crate) async fn enable_hd_account<Coin>(
coin: &Coin,
Expand Down Expand Up @@ -466,7 +465,7 @@ pub mod common_impl {
path_to_address: &HDPathAccountToAddressId,
) -> MmResult<HDWalletBalance<HDWalletBalanceObject<Coin>>, EnableCoinBalanceError>
where
Coin: ExtractExtendedPubkey<ExtendedPublicKey = Secp256k1ExtendedPublicKey>
Coin: ExtractExtendedPubkey<ExtendedPublicKey = HDCoinExtendedPubkey<Coin>>
+ HDWalletBalanceOps
+ MarketCoinOps
+ Sync,
Expand Down
8 changes: 4 additions & 4 deletions mm2src/coins/eth/eth_hd_wallet.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use super::*;
use crate::coin_balance::HDAddressBalanceScanner;
use crate::hd_wallet::{ExtractExtendedPubkey, HDAccount, HDAddress, HDExtractPubkeyError, HDWallet, HDXPubExtractor,
TrezorCoinError};
use crate::hd_wallet::{ExtractExtendedPubkey, HDAccount, HDAddress, HDCoinExtendedPubkey, HDExtractPubkeyError,
HDWallet, HDXPubExtractor, TrezorCoinError};
use async_trait::async_trait;
use bip32::DerivationPath;
use crypto::Secp256k1ExtendedPublicKey;
use ethereum_types::{Address, Public};

pub type EthHDAddress = HDAddress<Address, Public>;
pub type EthHDAccount = HDAccount<EthHDAddress>;
pub type EthHDAccount = HDAccount<EthHDAddress, Secp256k1ExtendedPublicKey>;
pub type EthHDWallet = HDWallet<EthHDAccount>;

#[async_trait]
Expand All @@ -35,7 +35,7 @@ impl HDWalletCoinOps for EthCoin {

fn address_from_extended_pubkey(
&self,
extended_pubkey: &Secp256k1ExtendedPublicKey,
extended_pubkey: &HDCoinExtendedPubkey<Self>,
derivation_path: DerivationPath,
) -> HDCoinHDAddress<Self> {
let pubkey = pubkey_from_extended(extended_pubkey);
Expand Down
11 changes: 7 additions & 4 deletions mm2src/coins/hd_wallet/account_ops.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{HDAddressOps, HDAddressesCache, InvalidBip44ChainError};
use crypto::{Bip44Chain, DerivationPath, HDPathToAccount, Secp256k1ExtendedPublicKey};
use super::{ExtendedPublicKeyOps, HDAddressOps, HDAddressesCache, InvalidBip44ChainError};
use crypto::{Bip44Chain, DerivationPath, HDPathToAccount};
use mm2_err_handle::prelude::*;

/// `HDAccountOps` Trait
Expand All @@ -13,11 +13,14 @@ use mm2_err_handle::prelude::*;
/// Implementors of this trait should provide details about such HD account like its specific derivation path, known addresses, and its index.
pub trait HDAccountOps {
type HDAddress: HDAddressOps + Clone + Send;
/// Any type that represents an extended public key, whether it's secp256k1, ed25519, Schnorr, etc.
/// This type should implement the `ExtendedPublicKeyOps` trait.
type ExtendedPublicKey: ExtendedPublicKeyOps;

/// A constructor for any type that implements `HDAccountOps`.
fn new(
account_id: u32,
account_extended_pubkey: Secp256k1ExtendedPublicKey,
account_extended_pubkey: Self::ExtendedPublicKey,
account_derivation_path: HDPathToAccount,
) -> Self;

Expand Down Expand Up @@ -47,5 +50,5 @@ pub trait HDAccountOps {
fn derived_addresses(&self) -> &HDAddressesCache<Self::HDAddress>;

/// Fetches the extended public key associated with this account.
fn extended_pubkey(&self) -> &Secp256k1ExtendedPublicKey;
fn extended_pubkey(&self) -> &Self::ExtendedPublicKey;
}
10 changes: 5 additions & 5 deletions mm2src/coins/hd_wallet/coin_ops.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use super::{inner_impl, AccountUpdatingError, AddressDerivingError, AddressDerivingResult, HDAccountOps,
HDCoinAddress, HDCoinHDAccount, HDCoinHDAddress, HDConfirmAddress, HDWalletOps,
NewAddressDeriveConfirmError, NewAddressDerivingError};
use super::{inner_impl, AccountUpdatingError, AddressDerivingError, AddressDerivingResult, ExtendedPublicKeyOps,
HDAccountOps, HDCoinAddress, HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress, HDConfirmAddress,
HDWalletOps, NewAddressDeriveConfirmError, NewAddressDerivingError};
use crate::hd_wallet::{HDAddressOps, HDWalletStorageOps, TrezorCoinError};
use async_trait::async_trait;
use bip32::{ChildNumber, DerivationPath};
use crypto::{Bip44Chain, Secp256k1ExtendedPublicKey};
use crypto::Bip44Chain;
use itertools::Itertools;
use mm2_err_handle::mm_error::{MmError, MmResult};
use std::collections::HashMap;
Expand Down Expand Up @@ -33,7 +33,7 @@ pub trait HDWalletCoinOps {
/// Derives an address for the coin that implements this trait from an extended public key and a derivation path.
fn address_from_extended_pubkey(
&self,
extended_pubkey: &Secp256k1ExtendedPublicKey,
extended_pubkey: &HDCoinExtendedPubkey<Self>,
derivation_path: DerivationPath,
) -> HDCoinHDAddress<Self>;

Expand Down
34 changes: 22 additions & 12 deletions mm2src/coins/hd_wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub use errors::{AccountUpdatingError, AddressDerivingError, HDExtractPubkeyErro
NewAddressDerivingError, TrezorCoinError};

mod pubkey;
pub use pubkey::{ExtractExtendedPubkey, HDXPubExtractor, RpcTaskXPubExtractor};
pub use pubkey::{ExtendedPublicKeyOps, ExtractExtendedPubkey, HDXPubExtractor, RpcTaskXPubExtractor};

mod storage;
#[cfg(target_arch = "wasm32")]
Expand All @@ -58,8 +58,10 @@ pub(crate) type HDWalletAddress<T> =
<<<T as HDWalletOps>::HDAccount as HDAccountOps>::HDAddress as HDAddressOps>::Address;
pub(crate) type HDWalletPubKey<T> =
<<<T as HDWalletOps>::HDAccount as HDAccountOps>::HDAddress as HDAddressOps>::Pubkey;
pub(crate) type HDWalletExtendedPubkey<T> = <<T as HDWalletOps>::HDAccount as HDAccountOps>::ExtendedPublicKey;
pub(crate) type HDCoinAddress<T> = HDWalletAddress<<T as HDWalletCoinOps>::HDWallet>;
pub(crate) type HDCoinPubKey<T> = HDWalletPubKey<<T as HDWalletCoinOps>::HDWallet>;
pub(crate) type HDCoinExtendedPubkey<T> = HDWalletExtendedPubkey<<T as HDWalletCoinOps>::HDWallet>;
pub(crate) type HDWalletHDAddress<T> = <<T as HDWalletOps>::HDAccount as HDAccountOps>::HDAddress;
pub(crate) type HDCoinHDAddress<T> = HDWalletHDAddress<<T as HDWalletCoinOps>::HDWallet>;
pub(crate) type HDWalletHDAccount<T> = <T as HDWalletOps>::HDAccount;
Expand Down Expand Up @@ -119,14 +121,15 @@ impl<HDAddress> HDAddressesCache<HDAddress> {

/// A generic HD account that can be used with any HD wallet.
#[derive(Clone, Debug)]
pub struct HDAccount<HDAddress>
pub struct HDAccount<HDAddress, ExtendedPublicKey>
where
HDAddress: HDAddressOps + Send,
ExtendedPublicKey: ExtendedPublicKeyOps,
{
pub account_id: u32,
/// [Extended public key](https://learnmeabitcoin.com/technical/extended-keys) that corresponds to the derivation path:
/// `m/purpose'/coin_type'/account'`.
pub extended_pubkey: Secp256k1ExtendedPublicKey,
pub extended_pubkey: ExtendedPublicKey,
/// [`HDWallet::derivation_path`] derived by [`HDAccount::account_id`].
pub account_derivation_path: HDPathToAccount,
/// The number of addresses that we know have been used by the user.
Expand All @@ -142,15 +145,17 @@ where
pub derived_addresses: HDAddressesCache<HDAddress>,
}

impl<HDAddress> HDAccountOps for HDAccount<HDAddress>
impl<HDAddress, ExtendedPublicKey> HDAccountOps for HDAccount<HDAddress, ExtendedPublicKey>
where
HDAddress: HDAddressOps + Clone + Send,
ExtendedPublicKey: ExtendedPublicKeyOps,
{
type HDAddress = HDAddress;
type ExtendedPublicKey = ExtendedPublicKey;

fn new(
account_id: u32,
extended_pubkey: Secp256k1ExtendedPublicKey,
extended_pubkey: Self::ExtendedPublicKey,
account_derivation_path: HDPathToAccount,
) -> Self {
HDAccount {
Expand Down Expand Up @@ -194,12 +199,14 @@ where

fn derived_addresses(&self) -> &HDAddressesCache<Self::HDAddress> { &self.derived_addresses }

fn extended_pubkey(&self) -> &Secp256k1ExtendedPublicKey { &self.extended_pubkey }
fn extended_pubkey(&self) -> &Self::ExtendedPublicKey { &self.extended_pubkey }
}

impl<HDAddress> HDAccountStorageOps for HDAccount<HDAddress>
impl<HDAddress, ExtendedPublicKey> HDAccountStorageOps for HDAccount<HDAddress, ExtendedPublicKey>
where
HDAddress: HDAddressOps + Send,
ExtendedPublicKey: ExtendedPublicKeyOps,
<ExtendedPublicKey as FromStr>::Err: Display,
{
fn try_from_storage_item(
wallet_der_path: &HDPathToCoin,
Expand All @@ -214,7 +221,8 @@ where
let account_derivation_path = wallet_der_path
.derive(account_child)
.map_to_mm(StandardHDPathError::from)?;
let extended_pubkey = Secp256k1ExtendedPublicKey::from_str(&account_info.account_xpub)?;
let extended_pubkey = ExtendedPublicKey::from_str(&account_info.account_xpub)
.map_err(|e| HDWalletStorageError::ErrorDeserializing(e.to_string()))?;
let capacity =
account_info.external_addresses_number + account_info.internal_addresses_number + DEFAULT_GAP_LIMIT;
Ok(HDAccount {
Expand All @@ -237,15 +245,17 @@ where
}
}

pub async fn load_hd_accounts_from_storage<HDAddress>(
pub async fn load_hd_accounts_from_storage<HDAddress, ExtendedPublicKey>(
hd_wallet_storage: &HDWalletCoinStorage,
derivation_path: &HDPathToCoin,
) -> HDWalletStorageResult<HDAccountsMap<HDAccount<HDAddress>>>
) -> HDWalletStorageResult<HDAccountsMap<HDAccount<HDAddress, ExtendedPublicKey>>>
where
HDAddress: HDAddressOps + Send,
ExtendedPublicKey: ExtendedPublicKeyOps,
<ExtendedPublicKey as FromStr>::Err: Display,
{
let accounts = hd_wallet_storage.load_all_accounts().await?;
let res: HDWalletStorageResult<HDAccountsMap<HDAccount<HDAddress>>> = accounts
let res: HDWalletStorageResult<HDAccountsMap<HDAccount<HDAddress, ExtendedPublicKey>>> = accounts
.iter()
.map(|account_info| {
let account = HDAccount::try_from_storage_item(derivation_path, account_info)?;
Expand Down Expand Up @@ -380,7 +390,7 @@ pub async fn create_new_account<'a, Coin, XPubExtractor, HDWallet, HDAccount>(
account_id: Option<u32>,
) -> MmResult<HDAccountMut<'a, HDWalletHDAccount<HDWallet>>, NewAccountCreationError>
where
Coin: ExtractExtendedPubkey<ExtendedPublicKey = Secp256k1ExtendedPublicKey> + Sync,
Coin: ExtractExtendedPubkey<ExtendedPublicKey = HDWalletExtendedPubkey<HDWallet>> + Sync,
HDWallet: HDWalletOps<HDAccount = HDAccount> + HDWalletStorageOps + Sync,
XPubExtractor: HDXPubExtractor + Send,
HDAccount: 'a + HDAccountOps + HDAccountStorageOps,
Expand Down
16 changes: 16 additions & 0 deletions mm2src/coins/hd_wallet/pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::CoinProtocol;

use super::*;
use async_trait::async_trait;
use bip32::Prefix;
use crypto::hw_rpc_task::HwConnectStatuses;
use crypto::trezor::trezor_rpc_task::{TrezorRpcTaskProcessor, TryIntoUserAction};
use crypto::trezor::utxo::IGNORE_XPUB_MAGIC;
Expand All @@ -14,6 +15,21 @@ use std::sync::Arc;

const SHOW_PUBKEY_ON_DISPLAY: bool = false;

/// A trait that should be implemented by any extended public key type
/// to allow it to work with the HD wallet traits.
pub trait ExtendedPublicKeyOps: FromStr + Sized {
/// Derives a child extended public key from the current one.
fn derive_child(&self, child_number: ChildNumber) -> Result<Self, Bip32Error>;
/// Converts the extended public key to a string.
fn to_string(&self, prefix: Prefix) -> String;
}

impl ExtendedPublicKeyOps for Secp256k1ExtendedPublicKey {
fn derive_child(&self, child_number: ChildNumber) -> Result<Self, Bip32Error> { self.derive_child(child_number) }

fn to_string(&self, prefix: Prefix) -> String { self.to_string(prefix) }
}

/// This trait should be implemented for coins
/// to support extracting extended public keys from any depth.
/// The extraction can be from either an internal or external wallet.
Expand Down
10 changes: 9 additions & 1 deletion mm2src/coins/hd_wallet/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use async_trait::async_trait;
use crypto::{CryptoCtx, CryptoCtxError, HDPathToCoin, XPub};
use crypto::{Bip32Error, CryptoCtx, CryptoCtxError, HDPathToCoin, StandardHDPathError, XPub};
use derive_more::Display;
use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
Expand Down Expand Up @@ -47,10 +47,18 @@ pub enum HDWalletStorageError {
Internal(String),
}

impl From<Bip32Error> for HDWalletStorageError {
fn from(e: Bip32Error) -> Self { HDWalletStorageError::ErrorDeserializing(e.to_string()) }
}

impl From<CryptoCtxError> for HDWalletStorageError {
fn from(e: CryptoCtxError) -> Self { HDWalletStorageError::Internal(e.to_string()) }
}

impl From<StandardHDPathError> for HDWalletStorageError {
fn from(e: StandardHDPathError) -> Self { HDWalletStorageError::ErrorDeserializing(e.to_string()) }
}

impl HDWalletStorageError {
pub fn is_deserializing_err(&self) -> bool { matches!(self, HDWalletStorageError::ErrorDeserializing(_)) }
}
Expand Down
5 changes: 2 additions & 3 deletions mm2src/coins/rpc_command/init_create_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,7 @@ pub(crate) mod common_impl {
use super::*;
use crate::coin_balance::{HDWalletBalanceObject, HDWalletBalanceOps};
use crate::hd_wallet::{create_new_account, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps,
HDCoinHDAccount, HDWalletOps};
use crypto::Secp256k1ExtendedPublicKey;
HDCoinExtendedPubkey, HDCoinHDAccount, HDWalletOps};

pub async fn init_create_new_account_rpc<'a, Coin, XPubExtractor>(
coin: &Coin,
Expand All @@ -398,7 +397,7 @@ pub(crate) mod common_impl {
xpub_extractor: Option<XPubExtractor>,
) -> MmResult<HDAccountBalance<HDWalletBalanceObject<Coin>>, CreateAccountRpcError>
where
Coin: ExtractExtendedPubkey<ExtendedPublicKey = Secp256k1ExtendedPublicKey>
Coin: ExtractExtendedPubkey<ExtendedPublicKey = HDCoinExtendedPubkey<Coin>>
+ HDWalletBalanceOps
+ CoinWithDerivationMethod
+ Send
Expand Down
13 changes: 2 additions & 11 deletions mm2src/coins/utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use common::first_char_to_upper;
use common::jsonrpc_client::JsonRpcError;
use common::log::LogOnError;
use common::{now_sec, now_sec_u32};
use crypto::{Bip32Error, DerivationPath, HDPathToCoin, Secp256k1ExtendedPublicKey, StandardHDPathError};
use crypto::{DerivationPath, HDPathToCoin, Secp256k1ExtendedPublicKey};
use derive_more::Display;
#[cfg(not(target_arch = "wasm32"))] use dirs::home_dir;
use futures::channel::mpsc::{Receiver as AsyncReceiver, Sender as AsyncSender, UnboundedReceiver, UnboundedSender};
Expand Down Expand Up @@ -110,8 +110,7 @@ use super::{big_decimal_from_sat_unsigned, BalanceError, BalanceFut, BalanceResu
TransactionEnum, TransactionErr, UnexpectedDerivationMethod, VerificationError, WithdrawError,
WithdrawRequest};
use crate::coin_balance::{EnableCoinScanPolicy, EnabledCoinBalanceParams, HDAddressBalanceScanner};
use crate::hd_wallet::{HDAccountOps, HDAddressOps, HDPathAccountToAddressId, HDWalletCoinOps, HDWalletOps,
HDWalletStorageError};
use crate::hd_wallet::{HDAccountOps, HDAddressOps, HDPathAccountToAddressId, HDWalletCoinOps, HDWalletOps};
use crate::utxo::tx_cache::UtxoVerboseCacheShared;
use crate::{ParseCoinAssocTypes, ToBytes};

Expand Down Expand Up @@ -243,14 +242,6 @@ impl From<UtxoRpcError> for TxProviderError {
}
}

impl From<StandardHDPathError> for HDWalletStorageError {
fn from(e: StandardHDPathError) -> Self { HDWalletStorageError::ErrorDeserializing(e.to_string()) }
}

impl From<Bip32Error> for HDWalletStorageError {
fn from(e: Bip32Error) -> Self { HDWalletStorageError::ErrorDeserializing(e.to_string()) }
}

#[async_trait]
impl TxProvider for UtxoRpcClientEnum {
async fn get_rpc_transaction(&self, tx_hash: &H256Json) -> Result<RpcTransaction, MmError<TxProviderError>> {
Expand Down
7 changes: 4 additions & 3 deletions mm2src/coins/utxo/bch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use super::*;
use crate::coin_balance::{EnableCoinBalanceError, HDAddressBalance, HDBalanceAddress, HDWalletBalance,
HDWalletBalanceOps};
use crate::coin_errors::{MyAddressError, ValidatePaymentResult};
use crate::hd_wallet::{ExtractExtendedPubkey, HDCoinAddress, HDCoinHDAccount, HDCoinHDAddress, HDCoinWithdrawOps,
HDExtractPubkeyError, HDXPubExtractor, TrezorCoinError, WithdrawSenderAddress};
use crate::hd_wallet::{ExtractExtendedPubkey, HDCoinAddress, HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress,
HDCoinWithdrawOps, HDExtractPubkeyError, HDXPubExtractor, TrezorCoinError,
WithdrawSenderAddress};
use crate::my_tx_history_v2::{CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxDetailsBuilder,
TxHistoryStorage};
use crate::tx_history_storage::{GetTxHistoryFilters, WalletId};
Expand Down Expand Up @@ -1414,7 +1415,7 @@ impl HDWalletCoinOps for BchCoin {

fn address_from_extended_pubkey(
&self,
extended_pubkey: &Secp256k1ExtendedPublicKey,
extended_pubkey: &HDCoinExtendedPubkey<Self>,
derivation_path: DerivationPath,
) -> HDCoinHDAddress<Self> {
utxo_common::address_from_extended_pubkey(self, extended_pubkey, derivation_path)
Expand Down
7 changes: 4 additions & 3 deletions mm2src/coins/utxo/qtum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use super::*;
use crate::coin_balance::{self, EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance,
HDBalanceAddress, HDWalletBalance, HDWalletBalanceOps};
use crate::coin_errors::{MyAddressError, ValidatePaymentResult};
use crate::hd_wallet::{ExtractExtendedPubkey, HDCoinAddress, HDCoinHDAccount, HDCoinHDAddress, HDCoinWithdrawOps,
HDConfirmAddress, HDExtractPubkeyError, HDXPubExtractor, TrezorCoinError, WithdrawSenderAddress};
use crate::hd_wallet::{ExtractExtendedPubkey, HDCoinAddress, HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress,
HDCoinWithdrawOps, HDConfirmAddress, HDExtractPubkeyError, HDXPubExtractor, TrezorCoinError,
WithdrawSenderAddress};
use crate::my_tx_history_v2::{CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxHistoryStorage};
use crate::rpc_command::account_balance::{self, AccountBalanceParams, AccountBalanceRpcOps, HDAccountBalanceResponse};
use crate::rpc_command::get_new_address::{self, GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError,
Expand Down Expand Up @@ -1066,7 +1067,7 @@ impl HDWalletCoinOps for QtumCoin {

fn address_from_extended_pubkey(
&self,
extended_pubkey: &Secp256k1ExtendedPublicKey,
extended_pubkey: &HDCoinExtendedPubkey<Self>,
derivation_path: DerivationPath,
) -> HDCoinHDAddress<Self> {
utxo_common::address_from_extended_pubkey(self, extended_pubkey, derivation_path)
Expand Down
4 changes: 2 additions & 2 deletions mm2src/coins/utxo/utxo_hd_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use crate::hd_wallet::{HDAccount, HDAccountMut, HDAccountOps, HDAccountsMap, HDA
HDAddress, HDWallet, HDWalletCoinStorage, HDWalletOps, HDWalletStorageOps,
WithdrawSenderAddress};
use async_trait::async_trait;
use crypto::{Bip44Chain, HDPathToCoin};
use crypto::{Bip44Chain, HDPathToCoin, Secp256k1ExtendedPublicKey};
use keys::{Address, AddressFormat as UtxoAddressFormat, Public};

pub type UtxoHDAddress = HDAddress<Address, Public>;
pub type UtxoHDAccount = HDAccount<UtxoHDAddress>;
pub type UtxoHDAccount = HDAccount<UtxoHDAddress, Secp256k1ExtendedPublicKey>;
pub type UtxoWithdrawSender = WithdrawSenderAddress<Address, Public>;

/// A struct to encapsulate the types needed for a UTXO HD wallet.
Expand Down
Loading

0 comments on commit bde2077

Please sign in to comment.