Skip to content

Commit 7cb1ae9

Browse files
committed
Trezor firmware versioning
1 parent 3503b80 commit 7cb1ae9

29 files changed

Lines changed: 451 additions & 154 deletions

File tree

Cargo.lock

Lines changed: 5 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: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ rlimit = "0.10"
211211
rstest = "0.24"
212212
rusqlite = "0.33"
213213
schnorrkel = "0.11"
214+
semver = "1.0"
214215
serde = "1.0"
215216
serde_json = "1.0"
216217
serde_test = "1.0"
@@ -248,8 +249,8 @@ zeroize = "1.5"
248249

249250
[workspace.dependencies.trezor-client]
250251
git = "https://github.com/mintlayer/mintlayer-trezor-firmware"
251-
# The commit "Remove destination from MintlayerFillOrderV1; fail if the host asks to sign a FillOrder input"
252-
rev = "198346c2f731e7ff34be03b7a16818008eeeae0d"
252+
# The commit "Mintlayer firmware versioning"
253+
rev = "397155e26660993a044e78447dad893852fa44d1"
253254
features = ["bitcoin", "mintlayer"]
254255

255256
[workspace.metadata.dist.dependencies.apt]

node-gui/backend/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ wallet-cli-commands = { path = "../../wallet/wallet-cli-commands"}
3131
anyhow.workspace = true
3232
chrono.workspace = true
3333
futures.workspace = true
34+
itertools.workspace = true
35+
semver.workspace = true
3436
serde = { workspace = true, features = ["derive"] }
3537
serde_json.workspace = true
3638
serde_with.workspace = true

node-gui/backend/src/backend_impl.rs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,30 @@
1515

1616
use std::{collections::BTreeMap, fmt::Debug, path::PathBuf, str::FromStr, sync::Arc};
1717

18+
use futures::{stream::FuturesOrdered, TryStreamExt};
19+
use tokio::{
20+
sync::mpsc::{UnboundedReceiver, UnboundedSender},
21+
task::JoinHandle,
22+
};
23+
1824
use common::{
1925
address::{Address, RpcAddress},
2026
chain::{ChainConfig, GenBlock, SignedTransaction},
2127
primitives::{per_thousand::PerThousand, BlockHeight, Id},
2228
};
2329
use crypto::key::hdkd::{child_number::ChildNumber, u31::U31};
24-
use futures::{stream::FuturesOrdered, TryStreamExt};
2530
use logging::log;
2631
use node_comm::rpc_client::ColdWalletClient;
2732
use node_lib::node_controller::NodeController;
2833
use serialization::hex_encoded::HexEncoded;
29-
use tokio::{
30-
sync::mpsc::{UnboundedReceiver, UnboundedSender},
31-
task::JoinHandle,
32-
};
3334
use wallet::{account::transaction_list::TransactionList, wallet::Error, WalletError};
3435
use wallet_cli_commands::{
3536
get_repl_command, parse_input, CommandHandler, ConsoleCommand, ManageableWalletCommand,
3637
WalletCommand,
3738
};
3839
use wallet_controller::{
3940
make_cold_wallet_rpc_client,
40-
types::{Balances, WalletCreationOptions, WalletTypeArgs},
41+
types::{Balances, WalletCreationOptions, WalletExtraInfo, WalletTypeArgs},
4142
ControllerConfig, NodeInterface, UtxoState, WalletHandlesClient,
4243
};
4344
use wallet_rpc_client::handles_client::WalletRpcHandlesClient;
@@ -361,6 +362,7 @@ impl Backend {
361362
};
362363

363364
let encryption = EncryptionState::Disabled;
365+
let wallet_extra_info = Self::get_wallet_extra_info(&wallet_data.controller).await?;
364366

365367
let wallet_info = WalletInfo {
366368
wallet_id,
@@ -369,13 +371,31 @@ impl Backend {
369371
accounts: accounts_info,
370372
best_block,
371373
wallet_type,
374+
extra_info: wallet_extra_info,
372375
};
373376

374377
self.wallets.insert(wallet_id, wallet_data);
375378

376379
Ok(wallet_info)
377380
}
378381

382+
async fn get_wallet_extra_info(
383+
controller: &GuiHotColdController,
384+
) -> Result<WalletExtraInfo, BackendError> {
385+
let wallet_info_from_rpc = match controller {
386+
GuiHotColdController::Hot(wallet_rpc, _) => wallet_rpc
387+
.wallet_info()
388+
.await
389+
.map_err(|err| BackendError::WalletError(err.to_string()))?,
390+
GuiHotColdController::Cold(wallet_rpc, _) => wallet_rpc
391+
.wallet_info()
392+
.await
393+
.map_err(|err| BackendError::WalletError(err.to_string()))?,
394+
};
395+
396+
Ok(wallet_info_from_rpc.extra_info)
397+
}
398+
379399
async fn create_wallet<N>(
380400
&mut self,
381401
handles_client: N,
@@ -414,10 +434,18 @@ impl Backend {
414434
overwrite_wallet_file: true,
415435
scan_blockchain: import.should_scan_blockchain(),
416436
};
417-
wallet_rpc
437+
let created_wallet = wallet_rpc
418438
.create_wallet(file_path, wallet_args, options)
419439
.await
420440
.map_err(|err| BackendError::WalletError(err.to_string()))?;
441+
match created_wallet {
442+
wallet_controller::types::CreatedWallet::UserProvidedMnemonic
443+
| wallet_controller::types::CreatedWallet::NewlyGeneratedMnemonic(_) => {}
444+
#[cfg(feature = "trezor")]
445+
wallet_controller::types::CreatedWallet::TrezorDeviceSelection(found_devices) => {
446+
return Err(BackendError::MultipleTrezorDevicesFound(found_devices))
447+
}
448+
}
421449
tokio::spawn(forward_events(
422450
wallet_events,
423451
wallet_service
@@ -572,13 +600,16 @@ impl Backend {
572600
}
573601
};
574602

603+
let wallet_extra_info = Self::get_wallet_extra_info(&wallet_data.controller).await?;
604+
575605
let wallet_info = WalletInfo {
576606
wallet_id,
577607
path: file_path,
578608
encryption,
579609
accounts: accounts_info,
580610
best_block,
581611
wallet_type,
612+
extra_info: wallet_extra_info,
582613
};
583614

584615
self.wallets.insert(wallet_id, wallet_data);
@@ -619,7 +650,7 @@ impl Backend {
619650
let node_rpc = wallet_service.node_rpc().clone();
620651
let chain_config = wallet_service.chain_config().clone();
621652
let wallet_rpc = WalletRpc::new(wallet_handle, node_rpc.clone(), chain_config.clone());
622-
wallet_rpc
653+
let opened_wallet = wallet_rpc
623654
.open_wallet(
624655
file_path,
625656
None,
@@ -629,6 +660,13 @@ impl Backend {
629660
)
630661
.await
631662
.map_err(|err| BackendError::WalletError(err.to_string()))?;
663+
match opened_wallet {
664+
| wallet_controller::types::OpenedWallet::Opened => {}
665+
#[cfg(feature = "trezor")]
666+
wallet_controller::types::OpenedWallet::TrezorDeviceSelection(found_devices) => {
667+
return Err(BackendError::MultipleTrezorDevicesFound(found_devices))
668+
}
669+
}
632670
tokio::spawn(forward_events(
633671
wallet_events,
634672
wallet_service

node-gui/backend/src/error.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16+
use itertools::Itertools as _;
17+
18+
#[cfg(feature = "trezor")]
19+
use wallet::signer::trezor_signer;
20+
1621
use super::{account_id::AccountId, messages::WalletId};
1722

1823
#[derive(thiserror::Error, Debug, Clone)]
@@ -47,4 +52,18 @@ pub enum BackendError {
4752
InvalidConsoleCommand(String),
4853
#[error("Empty console command")]
4954
EmptyConsoleCommand,
55+
56+
#[cfg(feature = "trezor")]
57+
#[error(
58+
"Multiple Trezor devices found: {}.\nLeave only one of them connected and try again.",
59+
format_multiple_trezor_devices_err(_0)
60+
)]
61+
MultipleTrezorDevicesFound(Vec<trezor_signer::FoundDevice>),
62+
}
63+
64+
fn format_multiple_trezor_devices_err(devices: &[trezor_signer::FoundDevice]) -> String {
65+
devices
66+
.iter()
67+
.map(|device| format!("{} (device id = {})", device.device_name, device.device_id))
68+
.join(", ")
5069
}

node-gui/backend/src/messages.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use p2p::P2pEvent;
3333
use serialization::hex_encoded::hex_encoded_serialization;
3434
use wallet::account::transaction_list::TransactionList;
3535
use wallet_cli_commands::ConsoleCommand;
36-
use wallet_controller::types::{Balances, WalletTypeArgs};
36+
use wallet_controller::types::{Balances, WalletExtraInfo, WalletTypeArgs};
3737
use wallet_rpc_lib::types::PoolInfo;
3838
use wallet_types::wallet_type::WalletType;
3939

@@ -58,6 +58,7 @@ pub struct WalletInfo {
5858
pub accounts: BTreeMap<AccountId, AccountInfo>,
5959
pub best_block: (Id<GenBlock>, BlockHeight),
6060
pub wallet_type: WalletType,
61+
pub extra_info: WalletExtraInfo,
6162
}
6263

6364
#[derive(Debug, Clone, Serialize)]

node-gui/src/main_window/main_menu.rs

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,16 @@ fn labeled_button<'a>(label: &'a str, msg: MenuMessage) -> button::Button<'a, Me
9696
}
9797

9898
fn menu_item(label: &str, msg: MenuMessage) -> Item<'_, MenuMessage, Theme, iced::Renderer> {
99-
Item::new(labeled_button(label, msg).width(Length::Fixed(230.0)))
99+
// 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)))
100101
}
101102

102103
fn make_menu_file<'a>(wallet_mode: WalletMode) -> Item<'a, MenuMessage, Theme, iced::Renderer> {
103104
let root = Item::with_menu(
104105
labeled_button("File", MenuMessage::NoOp),
105106
Menu::new(match wallet_mode {
106107
WalletMode::Hot => {
107-
let menu = vec![
108+
let mut menu = vec![
108109
menu_item(
109110
"Create new Software wallet",
110111
MenuMessage::CreateNewWallet {
@@ -123,43 +124,31 @@ fn make_menu_file<'a>(wallet_mode: WalletMode) -> Item<'a, MenuMessage, Theme, i
123124
wallet_type: WalletType::Hot,
124125
},
125126
),
126-
// TODO: enable setting when needed
127-
// menu_item("Settings", MenuMessage::NoOp),
128-
menu_item("Exit", MenuMessage::Exit),
129127
];
130128
#[cfg(feature = "trezor")]
131129
{
132-
let mut menu = menu;
133-
menu.insert(
134-
1,
135-
menu_item(
136-
"Create new Trezor wallet",
137-
MenuMessage::CreateNewWallet {
138-
wallet_type: WalletType::Trezor,
139-
},
140-
),
141-
);
142-
menu.insert(
143-
3,
144-
menu_item(
145-
"Recover from Trezor wallet",
146-
MenuMessage::RecoverWallet {
147-
wallet_type: WalletType::Trezor,
148-
},
149-
),
150-
);
151-
menu.insert(
152-
5,
153-
menu_item(
154-
"Open Trezor wallet",
155-
MenuMessage::OpenWallet {
156-
wallet_type: WalletType::Trezor,
157-
},
158-
),
159-
);
160-
menu
130+
menu.push(menu_item(
131+
"(Beta) Create new Trezor wallet",
132+
MenuMessage::CreateNewWallet {
133+
wallet_type: WalletType::Trezor,
134+
},
135+
));
136+
menu.push(menu_item(
137+
"(Beta) Recover from Trezor wallet",
138+
MenuMessage::RecoverWallet {
139+
wallet_type: WalletType::Trezor,
140+
},
141+
));
142+
menu.push(menu_item(
143+
"(Beta) Open Trezor wallet",
144+
MenuMessage::OpenWallet {
145+
wallet_type: WalletType::Trezor,
146+
},
147+
));
161148
}
162-
#[cfg(not(feature = "trezor"))]
149+
// TODO: enable setting when needed
150+
// menu.push(menu_item("Settings", MenuMessage::NoOp));
151+
menu.push(menu_item("Exit", MenuMessage::Exit));
163152
menu
164153
}
165154
WalletMode::Cold => {
@@ -188,7 +177,7 @@ fn make_menu_file<'a>(wallet_mode: WalletMode) -> Item<'a, MenuMessage, Theme, i
188177
]
189178
}
190179
})
191-
.width(260),
180+
.width(300),
192181
);
193182

194183
root

node-gui/src/main_window/main_widget/tabs/cold_wallet.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,11 @@ fn get_network_type_capitalized(chain_config: &ChainConfig) -> String {
4040
impl Tab for ColdWalletTab {
4141
type Message = TabsMessage;
4242

43-
fn title(&self) -> String {
44-
String::from("Cold wallet summary")
45-
}
46-
47-
fn tab_label(&self) -> TabLabel {
48-
TabLabel::IconText(iced_fonts::Bootstrap::Info.into(), self.title())
43+
fn tab_label(&self, _node_state: &NodeState) -> TabLabel {
44+
TabLabel::IconText(
45+
iced_fonts::Bootstrap::Info.into(),
46+
String::from("Cold wallet summary"),
47+
)
4948
}
5049

5150
fn content(&self, node_state: &NodeState) -> Element<Self::Message> {

0 commit comments

Comments
 (0)