Skip to content

Commit 1bcd08f

Browse files
committed
fix comments
1 parent df98f63 commit 1bcd08f

File tree

11 files changed

+266
-313
lines changed

11 files changed

+266
-313
lines changed

Cargo.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,14 @@ zeroize = "1.5"
270270
git = "https://github.com/ledger-community/rust-ledger.git"
271271
rev = "510bb3ca30639af4bdb12a918b6bbbdb75fa5f52"
272272

273+
[workspace.dependencies.ledger-proto]
274+
git = "https://github.com/ledger-community/rust-ledger.git"
275+
rev = "510bb3ca30639af4bdb12a918b6bbbdb75fa5f52"
276+
273277
[workspace.dependencies.mintlayer-ledger-messages]
274278
git = "https://github.com/mintlayer/mintlayer-ledger-app"
275-
# The commit "Fix comments"
276-
rev = "78bd2e2514be3a6db83e7493eaaa03c40acc5409"
279+
# The commit "Remove App name and version instructions"
280+
rev = "d65b5200a4499c5ebdcf95903cc3a5579f611c6f"
277281
package = "messages"
278282

279283
[workspace.dependencies.trezor-client]
@@ -292,7 +296,7 @@ features = ["bitcoin", "mintlayer"]
292296
panic = "abort" # prevent panic catching (mostly for the tokio runtime)
293297

294298
[profile.release]
295-
panic = "abort" # prevent panic catching (mostly for the tokio runtime)
299+
panic = "abort" # prevent panic catching (mostly for the tokio runtime)
296300
overflow-checks = true
297301

298302
# "Release" profile with debug info enabled.

node-gui/backend/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub enum BackendError {
4646
ColdWallet,
4747
#[error("Cannot interact with a hot wallet when in Cold wallet mode")]
4848
HotNotSupported,
49-
#[error("Cannot use a Hardware wallet in a Cold wallet mode")]
49+
#[error("Cannot use a hardware wallet in a Cold wallet mode")]
5050
HardwareWalletNotSupportedInColdMode,
5151
#[error("Invalid console command: {0}")]
5252
InvalidConsoleCommand(String),

node-gui/src/main_window/main_menu.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fn base_button<'a>(
8888
fn labeled_button<'a>(label: &'a str, msg: MenuMessage) -> button::Button<'a, MenuMessage> {
8989
base_button::<'a>(
9090
text(label)
91-
.width(Length::Fixed(220.0))
91+
.width(Length::Fixed(270.0))
9292
.height(Length::Fixed(25.0))
9393
.align_y(alignment::Vertical::Center),
9494
msg,
@@ -97,7 +97,7 @@ fn labeled_button<'a>(label: &'a str, msg: MenuMessage) -> button::Button<'a, Me
9797

9898
fn menu_item(label: &str, msg: MenuMessage) -> Item<'_, MenuMessage, Theme, iced::Renderer> {
9999
// Note: if this width is smaller than the text, the menu item will drop the whole last word.
100-
Item::new(labeled_button(label, msg).width(Length::Fixed(270.0)))
100+
Item::new(labeled_button(label, msg).width(Length::Fixed(300.0)))
101101
}
102102

103103
fn make_menu_file<'a>(wallet_mode: WalletMode) -> Item<'a, MenuMessage, Theme, iced::Renderer> {

wallet/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ tokio = { workspace = true, default-features = false, features = [
4747
] }
4848
trezor-client = { workspace = true, optional = true }
4949
ledger-lib = { workspace = true, optional = true }
50+
ledger-proto = { workspace = true, optional = true }
5051
mintlayer-ledger-messages = { workspace = true, optional = true }
5152
zeroize.workspace = true
5253

@@ -85,6 +86,7 @@ enable-ledger-device-tests = []
8586
use-deterministic-signatures-in-software-signer-for-regtest = []
8687
ledger = [
8788
"dep:ledger-lib",
89+
"dep:ledger-proto",
8890
"dep:mintlayer-ledger-messages",
8991
"wallet-types/ledger",
9092
]

wallet/src/signer/ledger_signer/ledger_messages.rs

Lines changed: 99 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,18 @@ use serialization::Encode;
2929
use utils::ensure;
3030
use wallet_types::hw_data::LedgerFullInfo;
3131

32-
use ledger_lib::Exchange;
32+
use ledger_lib::{Device, Exchange};
33+
use ledger_proto::StatusCode;
3334
use mintlayer_ledger_messages::{
34-
decode_all as ledger_decode_all, encode as ledger_encode, AddrType, Amount as LAmount,
35-
Bip32Path as LedgerBip32Path, CoinType, GetPublicKeyRespones, GetVersionRespones,
36-
InputAdditionalInfoReq, Ins, MsgSignature, OutputValue as LOutputValue, P1SignTx, PubKeyP1,
37-
PublicKeyReq, SignMessageReq, SignTxReq, Signature as LedgerSignature, TxInput as LTxInput,
38-
TxInputReq, TxMetadataReq, TxOutput as LTxOutput, TxOutputReq, APDU_CLASS, H256 as LH256,
39-
P1_APP_NAME, P1_GET_VERSION, P1_SIGN_NEXT, P1_SIGN_START, P2_DONE, P2_SIGN_MORE,
35+
decode_all as ledger_decode_all, encode as ledger_encode, AddrType, Amount as LAmount, Apdu,
36+
Bip32Path as LedgerBip32Path, CoinType, GetPublicKeyRespones, InputAdditionalInfoReq, Ins,
37+
MsgSignature, OutputValue as LOutputValue, P1SignTx, PubKeyP1, PublicKeyReq, SignMessageReq,
38+
SignTxReq, Signature as LedgerSignature, TxInput as LTxInput, TxInputReq, TxMetadataReq,
39+
TxOutput as LTxOutput, TxOutputReq, APDU_CLASS, H256 as LH256, P1_SIGN_NEXT, P1_SIGN_START,
40+
P2_DONE, P2_SIGN_MORE,
4041
};
4142

42-
const MAX_ADPU_LEN: usize = (u8::MAX - 5) as usize; // 4 bytes for the header + 1 for len
4343
const TIMEOUT_DUR: Duration = Duration::from_secs(100);
44-
const OK_RESPONSE: u16 = 0x9000;
4544
const TX_VERSION: u8 = 1;
4645

4746
struct SignatureResult {
@@ -55,13 +54,16 @@ pub fn ok_response(mut resp: Vec<u8>) -> SignerResult<Vec<u8>> {
5554
let (_, status_code) = resp.split_last_chunk().ok_or(LedgerError::InvalidResponse)?;
5655
let response_status = u16::from_be_bytes(*status_code);
5756

58-
ensure!(
59-
response_status == OK_RESPONSE,
60-
LedgerError::ErrorResponse(response_status)
61-
);
57+
let code = StatusCode::try_from(response_status)
58+
.map_err(|_| LedgerError::ErrorResponse(format!("Unknown error: {response_status}")))?;
6259

63-
resp.truncate(resp.len() - size_of_val(&response_status));
64-
Ok(resp)
60+
match code {
61+
StatusCode::Ok => {
62+
resp.truncate(resp.len() - size_of_val(&response_status));
63+
Ok(resp)
64+
}
65+
err => Err(LedgerError::ErrorResponse(err.to_string()).into()),
66+
}
6567
}
6668

6769
/// Send a message to the Ledger and check the response status code is ok
@@ -84,26 +86,30 @@ async fn send_chunked<L: Exchange>(
8486
message: &[u8],
8587
) -> Result<Vec<u8>, SignerError> {
8688
let mut msg_buf = vec![];
87-
let mut chunks = message.chunks(MAX_ADPU_LEN).peekable();
89+
let chunks = Apdu::new_chunks(ins, p1, message);
8890
let mut resp = vec![];
89-
while let Some(chunk) = chunks.next() {
91+
for chunk in chunks {
9092
msg_buf.clear();
93+
msg_buf.reserve(chunk.bytes_count());
94+
chunk.write_bytes(&mut msg_buf);
9195

92-
let p2 = if chunks.peek().is_some() {
93-
P2_SIGN_MORE
94-
} else {
95-
P2_DONE
96-
};
97-
98-
msg_buf.extend([APDU_CLASS, ins, p1, p2]);
99-
msg_buf.push(chunk.len() as u8);
100-
msg_buf.extend(chunk);
10196
resp = exchange_message(ledger, &msg_buf).await?;
10297
}
10398

10499
Ok(resp)
105100
}
106101

102+
async fn send_chunked_expect_empty_ok_response<L: Exchange>(
103+
ledger: &mut L,
104+
ins: u8,
105+
p1: u8,
106+
message: &[u8],
107+
) -> Result<(), SignerError> {
108+
let resp = send_chunked(ledger, ins, p1, message).await?;
109+
ensure!(resp.is_empty(), LedgerError::InvalidResponse);
110+
Ok(())
111+
}
112+
107113
pub async fn sign_challenge<L: Exchange>(
108114
ledger: &mut L,
109115
coin: CoinType,
@@ -117,7 +123,13 @@ pub async fn sign_challenge<L: Exchange>(
117123
path,
118124
};
119125

120-
send_chunked(ledger, Ins::SIGN_MSG, P1_SIGN_START, &ledger_encode(req)).await?;
126+
send_chunked_expect_empty_ok_response(
127+
ledger,
128+
Ins::SIGN_MSG,
129+
P1_SIGN_START,
130+
&ledger_encode(req),
131+
)
132+
.await?;
121133

122134
let resp = send_chunked(ledger, Ins::SIGN_MSG, P1_SIGN_NEXT, message).await?;
123135

@@ -126,43 +138,48 @@ pub async fn sign_challenge<L: Exchange>(
126138
Ok(sig.signature.to_vec())
127139
}
128140

129-
pub async fn get_app_name<L: Exchange>(ledger: &mut L) -> Result<Vec<u8>, ledger_lib::Error> {
130-
let msg_buf = [APDU_CLASS, Ins::APP_NAME, P1_APP_NAME, P2_DONE];
131-
ledger.exchange(&msg_buf, Duration::from_millis(500)).await
132-
}
133-
134-
async fn get_app_version<L: Exchange>(ledger: &mut L) -> Result<Vec<u8>, ledger_lib::Error> {
135-
let msg_buf = [APDU_CLASS, Ins::GET_VERSION, P1_GET_VERSION, P2_DONE];
136-
ledger.exchange(&msg_buf, Duration::from_millis(500)).await
137-
}
138-
139-
pub async fn check_current_app<L: Exchange>(ledger: &mut L) -> SignerResult<LedgerFullInfo> {
140-
let resp = get_app_name(ledger)
141+
pub async fn check_current_app<L: Exchange + Device + Send>(
142+
ledger: &mut L,
143+
) -> SignerResult<LedgerFullInfo> {
144+
let info = ledger
145+
.app_info(TIMEOUT_DUR)
141146
.await
142147
.map_err(|err| LedgerError::DeviceError(err.to_string()))?;
143-
let resp = ok_response(resp)?;
144-
let name = String::from_utf8(resp).map_err(|_| LedgerError::InvalidResponse)?;
148+
let name = info.name;
149+
let app_version = info.version;
145150

146151
ensure!(
147152
name == "mintlayer-app",
148153
LedgerError::DifferentActiveApp(name)
149154
);
150155

151-
let resp = get_app_version(ledger)
152-
.await
153-
.map_err(|err| LedgerError::DeviceError(err.to_string()))?;
154-
let ver = ok_response(resp)?;
155-
let app_version_resp: GetVersionRespones =
156-
ledger_decode_all(&ver).ok_or(LedgerError::InvalidResponse)?;
157-
let app_version = common::primitives::semver::SemVer {
158-
major: app_version_resp.major,
159-
minor: app_version_resp.minor,
160-
patch: app_version_resp.patch as u16,
161-
};
162-
163156
Ok(LedgerFullInfo { app_version })
164157
}
165158

159+
pub async fn get_extended_public_key_raw<L: Exchange>(
160+
ledger: &mut L,
161+
coin_type: CoinType,
162+
derivation_path: &DerivationPath,
163+
) -> Result<Vec<u8>, ledger_lib::Error> {
164+
let path = LedgerBip32Path(
165+
derivation_path.as_slice().iter().map(|c| c.into_encoded_index()).collect(),
166+
);
167+
let req = PublicKeyReq { coin_type, path };
168+
let encoded_req = ledger_encode(req);
169+
170+
let apdu = Apdu::new_with_data(
171+
Ins::PUB_KEY,
172+
PubKeyP1::NoDisplayAddress.into(),
173+
&encoded_req,
174+
)
175+
.expect("ok size");
176+
177+
let mut msg_buf = Vec::with_capacity(apdu.bytes_count());
178+
apdu.write_bytes(&mut msg_buf);
179+
180+
ledger.exchange(&msg_buf, TIMEOUT_DUR).await
181+
}
182+
166183
pub async fn get_extended_public_key<L: Exchange>(
167184
ledger: &mut L,
168185
coin_type: CoinType,
@@ -206,10 +223,16 @@ pub async fn sign_tx<L: Exchange>(
206223
num_inputs: inputs.len() as u32,
207224
num_outputs: outputs.len() as u32,
208225
});
209-
send_chunked(ledger, Ins::SIGN_TX, P1SignTx::Metadata.into(), &metadata).await?;
226+
send_chunked_expect_empty_ok_response(
227+
ledger,
228+
Ins::SIGN_TX,
229+
P1SignTx::Metadata.into(),
230+
&metadata,
231+
)
232+
.await?;
210233

211234
for inp in inputs {
212-
send_chunked(
235+
send_chunked_expect_empty_ok_response(
213236
ledger,
214237
Ins::SIGN_TX,
215238
P1SignTx::Input.into(),
@@ -219,7 +242,7 @@ pub async fn sign_tx<L: Exchange>(
219242
}
220243

221244
for info in input_additional_infos {
222-
send_chunked(
245+
send_chunked_expect_empty_ok_response(
223246
ledger,
224247
Ins::SIGN_TX,
225248
P1SignTx::InputAdditionalInfo.into(),
@@ -228,16 +251,27 @@ pub async fn sign_tx<L: Exchange>(
228251
.await?;
229252
}
230253

231-
// the response from the last output will have the first signature returned
232254
let mut resp = vec![];
233-
for o in outputs {
234-
resp = send_chunked(
235-
ledger,
236-
Ins::SIGN_TX,
237-
P1SignTx::Output.into(),
238-
&ledger_encode(SignTxReq::Output(o)),
239-
)
240-
.await?;
255+
let num_outputs = outputs.len();
256+
for (idx, o) in outputs.into_iter().enumerate() {
257+
if idx < num_outputs - 1 {
258+
send_chunked_expect_empty_ok_response(
259+
ledger,
260+
Ins::SIGN_TX,
261+
P1SignTx::Output.into(),
262+
&ledger_encode(SignTxReq::Output(o)),
263+
)
264+
.await?;
265+
} else {
266+
// the response from the last output will have the first signature returned
267+
resp = send_chunked(
268+
ledger,
269+
Ins::SIGN_TX,
270+
P1SignTx::Output.into(),
271+
&ledger_encode(SignTxReq::Output(o)),
272+
)
273+
.await?;
274+
}
241275
}
242276

243277
let mut signatures: BTreeMap<_, Vec<_>> = BTreeMap::new();

0 commit comments

Comments
 (0)