diff --git a/Cargo.lock b/Cargo.lock index 9de934274e..7010b06375 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3332,7 +3332,6 @@ dependencies = [ "num-derive", "num-traits", "serde", - "tari_common", "tari_crypto", "thiserror", ] @@ -5981,6 +5980,7 @@ dependencies = [ "borsh", "chacha20poly1305", "digest 0.10.7", + "ledger-transport 0.10.0 (git+https://github.com/Zondax/ledger-rs?rev=20e2a20)", "minotari_ledger_wallet_comms", "newtype-ops", "once_cell", diff --git a/applications/minotari_console_wallet/src/init/mod.rs b/applications/minotari_console_wallet/src/init/mod.rs index 204564d677..b48e9ce240 100644 --- a/applications/minotari_console_wallet/src/init/mod.rs +++ b/applications/minotari_console_wallet/src/init/mod.rs @@ -30,7 +30,7 @@ use log::*; use minotari_app_utilities::{consts, identity_management::setup_node_identity}; use minotari_ledger_wallet_comms::{ error::LedgerDeviceError, - ledger_wallet::{get_transport, Instruction, LedgerWallet}, + ledger_wallet::{get_transport, Instruction}, }; use minotari_wallet::{ error::{WalletError, WalletStorageError}, @@ -56,7 +56,7 @@ use tari_common::{ }; use tari_common_types::{ types::{PrivateKey, PublicKey}, - wallet_types::WalletType, + wallet_types::{LedgerWallet, WalletType}, }; use tari_comms::{ multiaddr::Multiaddr, diff --git a/applications/minotari_ledger_wallet/comms/Cargo.toml b/applications/minotari_ledger_wallet/comms/Cargo.toml index d2146a9d20..b6c83470b6 100644 --- a/applications/minotari_ledger_wallet/comms/Cargo.toml +++ b/applications/minotari_ledger_wallet/comms/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" [dependencies] tari_crypto = { version = "0.20.0", default-features = false } -tari_common = { path = "../../../common", version = "1.0.0-pre.12" } ledger-transport = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20" } ledger-transport-hid = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20" } diff --git a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs index 0fa84bbeab..297b5617ac 100644 --- a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs +++ b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs @@ -20,25 +20,15 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use std::{ - fmt, - fmt::{Display, Formatter}, - ops::Deref, -}; +use std::ops::Deref; use ledger_transport::{APDUAnswer, APDUCommand}; use ledger_transport_hid::{hidapi::HidApi, TransportNativeHID}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; -use serde::{Deserialize, Serialize}; -use tari_common::configuration::Network; -use tari_crypto::ristretto::RistrettoPublicKey; use crate::error::LedgerDeviceError; -const WALLET_CLA: u8 = 0x80; -// const LOG_TARGET: &str = "wallet::ledger_wallet::comms"; - #[repr(u8)] #[derive(FromPrimitive, Debug, Copy, Clone, PartialEq)] pub enum Instruction { @@ -72,6 +62,10 @@ pub struct Command { } impl> Command { + pub fn new(inner: APDUCommand) -> Command { + Self { inner } + } + pub fn execute(&self) -> Result>, LedgerDeviceError> { get_transport()? .exchange(&self.inner) @@ -87,80 +81,3 @@ impl> Command { .map_err(|e| LedgerDeviceError::NativeTransport(e.to_string())) } } - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct LedgerWallet { - account: u64, - pub pubkey: Option, - pub network: Network, -} - -impl Display for LedgerWallet { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "account {}", self.account)?; - write!(f, "pubkey {}", self.pubkey.is_some())?; - Ok(()) - } -} - -impl LedgerWallet { - pub fn new(account: u64, network: Network, pubkey: Option) -> Self { - Self { - account, - pubkey, - network, - } - } - - pub fn account_bytes(&self) -> Vec { - self.account.to_le_bytes().to_vec() - } - - pub fn build_command(&self, instruction: Instruction, data: Vec) -> Command> { - let mut base_data = self.account_bytes(); - base_data.extend_from_slice(&data); - - Command { - inner: APDUCommand { - cla: WALLET_CLA, - ins: instruction.as_byte(), - p1: 0x00, - p2: 0x00, - data: base_data, - }, - } - } - - pub fn chunk_command(&self, instruction: Instruction, data: Vec>) -> Vec>> { - let num_chunks = data.len(); - let mut more; - let mut commands = vec![]; - - for (i, chunk) in data.iter().enumerate() { - if i + 1 == num_chunks { - more = 0; - } else { - more = 1; - } - - // Prepend the account on the first payload - let mut base_data = vec![]; - if i == 0 { - base_data.extend_from_slice(&self.account_bytes()); - } - base_data.extend_from_slice(chunk); - - commands.push(Command { - inner: APDUCommand { - cla: WALLET_CLA, - ins: instruction.as_byte(), - p1: u8::try_from(i).unwrap_or(0), - p2: more, - data: base_data, - }, - }); - } - - commands - } -} diff --git a/base_layer/common_types/Cargo.toml b/base_layer/common_types/Cargo.toml index 54b2f2fb95..b77e1114c6 100644 --- a/base_layer/common_types/Cargo.toml +++ b/base_layer/common_types/Cargo.toml @@ -7,7 +7,7 @@ version = "1.0.0-pre.13" edition = "2018" [dependencies] -minotari_ledger_wallet_comms = { path = "../../applications/minotari_ledger_wallet/comms", version = "1.0.0-pre.13" } +minotari_ledger_wallet_comms = { path = "../../applications/minotari_ledger_wallet/comms", version = "1.0.0-pre.13", optional = true } tari_crypto = { version = "0.20.1" } tari_utilities = { version = "0.7" } tari_common = { path = "../../common", version = "1.0.0-pre.13" } @@ -25,9 +25,10 @@ thiserror = "1.0.29" base64 = "0.21.0" blake2 = "0.10" primitive-types = { version = "0.12", features = ["serde"] } +ledger-transport = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20", optional = true } [features] -ledger = [] +ledger = ["minotari_ledger_wallet_comms", "ledger-transport"] [package.metadata.cargo-machete] ignored = ["strum", "strum_macros"] # this is so we can run cargo machete without getting false positive about macro dependancies diff --git a/base_layer/common_types/src/wallet_types.rs b/base_layer/common_types/src/wallet_types.rs index 7ead057f7e..a152b4bcda 100644 --- a/base_layer/common_types/src/wallet_types.rs +++ b/base_layer/common_types/src/wallet_types.rs @@ -19,16 +19,23 @@ // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - use std::{ + convert::TryFrom, fmt, fmt::{Display, Formatter}, }; use chacha20poly1305::aead::OsRng; -use minotari_ledger_wallet_comms::ledger_wallet::LedgerWallet; +#[cfg(feature = "ledger")] +use ledger_transport::APDUCommand; +#[cfg(feature = "ledger")] +use minotari_ledger_wallet_comms::ledger_wallet::{Command, Instruction}; use serde::{Deserialize, Serialize}; -use tari_crypto::keys::{PublicKey as PublicKeyTrait, SecretKey}; +use tari_common::configuration::Network; +use tari_crypto::{ + keys::{PublicKey as PublicKeyTrait, SecretKey}, + ristretto::RistrettoPublicKey, +}; use crate::types::{PrivateKey, PublicKey}; @@ -53,3 +60,81 @@ impl Default for WalletType { WalletType::Software(k.clone(), PublicKey::from_secret_key(&k)) } } + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LedgerWallet { + account: u64, + pub pubkey: Option, + pub network: Network, +} + +impl Display for LedgerWallet { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "account {}", self.account)?; + write!(f, "pubkey {}", self.pubkey.is_some())?; + Ok(()) + } +} + +#[cfg(feature = "ledger")] +const WALLET_CLA: u8 = 0x80; + +impl LedgerWallet { + pub fn new(account: u64, network: Network, pubkey: Option) -> Self { + Self { + account, + pubkey, + network, + } + } + + pub fn account_bytes(&self) -> Vec { + self.account.to_le_bytes().to_vec() + } + + #[cfg(feature = "ledger")] + pub fn build_command(&self, instruction: Instruction, data: Vec) -> Command> { + let mut base_data = self.account_bytes(); + base_data.extend_from_slice(&data); + + Command::new(APDUCommand { + cla: WALLET_CLA, + ins: instruction.as_byte(), + p1: 0x00, + p2: 0x00, + data: base_data, + }) + } + + #[cfg(feature = "ledger")] + pub fn chunk_command(&self, instruction: Instruction, data: Vec>) -> Vec>> { + let num_chunks = data.len(); + let mut more; + let mut commands = vec![]; + + for (i, chunk) in data.iter().enumerate() { + if i + 1 == num_chunks { + more = 0; + } else { + more = 1; + } + + // Prepend the account on the first payload + let mut base_data = vec![]; + if i == 0 { + base_data.extend_from_slice(&self.account_bytes()); + } + base_data.extend_from_slice(chunk); + + commands.push(Command::new(APDUCommand { + cla: WALLET_CLA, + ins: instruction.as_byte(), + p1: u8::try_from(i).unwrap_or(0), + p2: more, + data: base_data, + })); + } + + commands + } +}