Skip to content

Commit 39d3e58

Browse files
committed
Add Ledger signer provider
1 parent d6fd484 commit 39d3e58

File tree

23 files changed

+370
-90
lines changed

23 files changed

+370
-90
lines changed

node-gui/Cargo.toml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ license.workspace = true
55
version.workspace = true
66
edition.workspace = true
77
rust-version.workspace = true
8-
authors = ["Samer Afach <samer.afach@mintlayer.org>", "Ben Marsh <benjamin.marsh@mintlayer.org>", "Enrico Rubboli <enrico.rubboli@mintlayer.org>"]
8+
authors = [
9+
"Samer Afach <samer.afach@mintlayer.org>",
10+
"Ben Marsh <benjamin.marsh@mintlayer.org>",
11+
"Enrico Rubboli <enrico.rubboli@mintlayer.org>",
12+
]
913

1014
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1115

@@ -23,7 +27,7 @@ utils = { path = "../utils" }
2327
wallet = { path = "../wallet" }
2428
wallet-controller = { path = "../wallet/wallet-controller" }
2529
wallet-types = { path = "../wallet/types" }
26-
wallet-cli-commands = { path = "../wallet/wallet-cli-commands"}
30+
wallet-cli-commands = { path = "../wallet/wallet-cli-commands" }
2731
wallet-storage = { path = "../wallet/storage" }
2832

2933
anyhow.workspace = true
@@ -42,5 +46,16 @@ tokio.workspace = true
4246
winres = "0.1"
4347

4448
[features]
45-
trezor = ["wallet-controller/trezor", "wallet-types/trezor", "wallet-cli-commands/trezor", "node-gui-backend/trezor"]
46-
default = ["trezor"]
49+
trezor = [
50+
"wallet-controller/trezor",
51+
"wallet-types/trezor",
52+
"wallet-cli-commands/trezor",
53+
"node-gui-backend/trezor",
54+
]
55+
ledger = [
56+
"wallet-controller/ledger",
57+
"wallet-types/ledger",
58+
"wallet-cli-commands/ledger",
59+
"node-gui-backend/ledger",
60+
]
61+
default = ["trezor", "ledger"]

node-gui/backend/Cargo.toml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ license.workspace = true
55
version.workspace = true
66
edition.workspace = true
77
rust-version.workspace = true
8-
authors = ["Samer Afach <samer.afach@mintlayer.org>", "Ben Marsh <benjamin.marsh@mintlayer.org>", "Enrico Rubboli <enrico.rubboli@mintlayer.org>"]
8+
authors = [
9+
"Samer Afach <samer.afach@mintlayer.org>",
10+
"Ben Marsh <benjamin.marsh@mintlayer.org>",
11+
"Enrico Rubboli <enrico.rubboli@mintlayer.org>",
12+
]
913

1014
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1115

@@ -24,9 +28,9 @@ utils = { path = "../../utils" }
2428
wallet = { path = "../../wallet" }
2529
wallet-controller = { path = "../../wallet/wallet-controller" }
2630
wallet-types = { path = "../../wallet/types" }
27-
wallet-rpc-lib = { path = "../../wallet/wallet-rpc-lib"}
28-
wallet-rpc-client = { path = "../../wallet/wallet-rpc-client"}
29-
wallet-cli-commands = { path = "../../wallet/wallet-cli-commands"}
31+
wallet-rpc-lib = { path = "../../wallet/wallet-rpc-lib" }
32+
wallet-rpc-client = { path = "../../wallet/wallet-rpc-client" }
33+
wallet-cli-commands = { path = "../../wallet/wallet-cli-commands" }
3034

3135
anyhow.workspace = true
3236
chrono.workspace = true
@@ -45,4 +49,19 @@ test-utils = { path = "../../test-utils" }
4549
rstest.workspace = true
4650

4751
[features]
48-
trezor = ["wallet/trezor", "wallet-controller/trezor", "wallet-types/trezor", "wallet-rpc-lib/trezor", "wallet-rpc-client/trezor", "wallet-cli-commands/trezor"]
52+
trezor = [
53+
"wallet/trezor",
54+
"wallet-controller/trezor",
55+
"wallet-types/trezor",
56+
"wallet-rpc-lib/trezor",
57+
"wallet-rpc-client/trezor",
58+
"wallet-cli-commands/trezor",
59+
]
60+
ledger = [
61+
"wallet/ledger",
62+
"wallet-controller/ledger",
63+
"wallet-types/ledger",
64+
"wallet-rpc-lib/ledger",
65+
"wallet-rpc-client/ledger",
66+
"wallet-cli-commands/ledger",
67+
]

node-gui/src/main_window/main_widget/tabs/wallet/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ impl Tab for WalletTab {
471471
Some(wallet_info) => match wallet_info.extra_info {
472472
wallet_controller::types::WalletExtraInfo::SoftwareWallet => "Software wallet",
473473
wallet_controller::types::WalletExtraInfo::TrezorWallet { .. } => "Trezor wallet",
474+
wallet_controller::types::WalletExtraInfo::LedgerWallet { .. } => "Ledger wallet",
474475
},
475476
None => "No wallet",
476477
};

node-gui/src/main_window/main_widget/tabs/wallet/status_bar.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ pub fn estimate_status_bar_height(wallet_info: &WalletExtraInfo) -> f32 {
3636
// For some reason, the status bar gets a bit of additional height.
3737
+ 4.
3838
}
39+
WalletExtraInfo::LedgerWallet { .. } => {
40+
TEXT_SIZE + 2. * VERTICAL_PADDING
41+
// Same as Trezor
42+
+ 4.
43+
}
3944
}
4045
}
4146

@@ -67,6 +72,16 @@ pub fn view_status_bar(wallet_info: &WalletExtraInfo) -> Option<Element<'static,
6772
.size(TEXT_SIZE),
6873
]
6974
}
75+
#[cfg(feature = "ledger")]
76+
WalletExtraInfo::LedgerWallet { firmware_version } => {
77+
use iced::widget::{rich_text, span};
78+
79+
row![rich_text([
80+
span("Firmware version: ").font(bold_font),
81+
span(firmware_version.clone())
82+
])
83+
.size(TEXT_SIZE),]
84+
}
7085
};
7186

7287
let status_bar = Container::new(

wallet/src/key_chain/master_key_chain/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crypto::vrf::ExtendedVRFPrivateKey;
2222
use std::sync::Arc;
2323
use wallet_storage::{
2424
StoreTxRwUnlocked, WalletStorageReadLocked, WalletStorageReadUnlocked,
25-
WalletStorageWriteUnlocked,
25+
WalletStorageWriteLocked, WalletStorageWriteUnlocked,
2626
};
2727
use wallet_types::seed_phrase::{SerializableSeedPhrase, StoreSeedPhrase};
2828

@@ -131,7 +131,7 @@ impl MasterKeyChain {
131131

132132
pub fn create_account_key_chain(
133133
&self,
134-
db_tx: &mut impl WalletStorageWriteUnlocked,
134+
db_tx: &mut (impl WalletStorageWriteLocked + WalletStorageReadUnlocked),
135135
account_index: U31,
136136
lookahead_size: u32,
137137
) -> KeyChainResult<AccountKeyChainImplSoftware> {

wallet/src/signer/ledger_signer/ledger_messages.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use crypto::key::{
3030
};
3131
use serialization::{Decode, DecodeAll, Encode};
3232
use utils::ensure;
33+
use wallet_types::hw_data::LedgerDataFullInfo;
3334

3435
use ledger_lib::Exchange;
3536

@@ -57,6 +58,7 @@ impl From<LedgerAddrType> for u8 {
5758
struct Ins {}
5859

5960
impl Ins {
61+
const APP_VER: u8 = 0x03;
6062
const APP_NAME: u8 = 0x04;
6163
const PUB_KEY: u8 = 0x05;
6264
const SIGN_TX: u8 = 0x06;
@@ -199,8 +201,13 @@ pub async fn get_app_name<L: Exchange>(ledger: &mut L) -> Result<Vec<u8>, ledger
199201
ledger.exchange(&msg_buf, Duration::from_millis(100)).await
200202
}
201203

204+
async fn get_app_version<L: Exchange>(ledger: &mut L) -> Result<Vec<u8>, ledger_lib::Error> {
205+
let msg_buf = [CLA, Ins::APP_VER, 0, P2::DONE];
206+
ledger.exchange(&msg_buf, Duration::from_millis(100)).await
207+
}
208+
202209
#[allow(dead_code)]
203-
pub async fn check_current_app<L: Exchange>(ledger: &mut L) -> SignerResult<()> {
210+
pub async fn check_current_app<L: Exchange>(ledger: &mut L) -> SignerResult<LedgerDataFullInfo> {
204211
let resp = get_app_name(ledger)
205212
.await
206213
.map_err(|err| LedgerError::DeviceError(err.to_string()))?;
@@ -212,7 +219,19 @@ pub async fn check_current_app<L: Exchange>(ledger: &mut L) -> SignerResult<()>
212219
LedgerError::DifferentActiveApp(name)
213220
);
214221

215-
Ok(())
222+
let ver = get_app_version(ledger)
223+
.await
224+
.map_err(|err| LedgerError::DeviceError(err.to_string()))?;
225+
let firmware_version = match ver.as_slice() {
226+
[major, minor, patch] => common::primitives::semver::SemVer {
227+
major: *major,
228+
minor: *minor,
229+
patch: *patch as u16,
230+
},
231+
_ => return Err(SignerError::LedgerError(LedgerError::InvalidResponse)),
232+
};
233+
234+
Ok(LedgerDataFullInfo { firmware_version })
216235
}
217236

218237
pub async fn get_extended_public_key<L: Exchange>(

0 commit comments

Comments
 (0)