properly pass hardwareWalletType for all credentials (#3150)
What changed, and why it matters
This commit fixes a wiring bug: when restoring a Bitcoin/Litecoin or Monero wallet from public keys/address rather than a seed phrase, the app was not telling the wallet-creation code whether a hardware wallet (like Ledger) was being used. The change threads the optional hardwareWalletType parameter through every restore-from-keys credential path so the correct wallet type is consistently known during restore.
Treat as a functional bug fix with possible security-adjacent side effects. Review downstream consumers of hardwareWalletType to confirm that missing the value previously caused incorrect behavior (e.g., wrong derivation path, missing hardware flag, or UI mislabeling). Validate restore flows for Ledger/Trezor-based Litecoin and Monero wallets after applying the patch. No immediate incident response is indicated from the diff alone.
Security signals we found
Incomplete parameter propagation for hardware wallet type during wallet restore
Potential mismatch between intended hardware-wallet restore and generated wallet credentials
No input validation, cryptographic, or authorization changes present
Evidence from the diff
The diff adds the missing HardwareWalletType? parameter to LitecoinWalletFromKeysCredentials, MoneroRestoreWalletFromKeysCredentials, and their corresponding factory methods in CWBitcoin, CWMonero, and the abstract Bitcoin/Monero interfaces in tool/configure.dart. WalletRestoreViewModelBase now passes hardwareWalletType into both the Litecoin and Monero restore-from-keys branches. This is a completeness fix for hardware-wallet metadata propagation; no cryptographic or access-control logic is changed.
Changed components
cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dartcw_monero/lib/monero_wallet_service.dartlib/bitcoin/cw_bitcoin.dartlib/monero/cw_monero.dartlib/view_model/wallet_restore_view_model.darttool/configure.dartInspect captured patch +10 / −1
diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
index a0ac214..479cf64 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
@@ -78,6 +78,7 @@ class LitecoinWalletFromKeysCredentials extends WalletCredentials {
required this.scanSecret,
required this.spendPubkey,
WalletInfo? walletInfo,
+ super.hardwareWalletType
}) : super(name: name, password: password, walletInfo: walletInfo);
final String xpub;
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index 83f8b46..2a153c5 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -79,6 +79,7 @@ class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
required this.address,
required this.viewKey,
required this.spendKey,
+ super.hardwareWalletType,
int height = 0})
: super(name: name, password: password, height: height);
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index cf061a3..848a93a 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -35,6 +35,7 @@ class CWBitcoin extends Bitcoin {
required String xpub,
required String scanSecret,
required String spendPubkey,
+ HardwareWalletType? hardwareWalletType,
}) =>
LitecoinWalletFromKeysCredentials(
name: name,
@@ -42,6 +43,7 @@ class CWBitcoin extends Bitcoin {
xpub: xpub,
scanSecret: scanSecret,
spendPubkey: spendPubkey,
+ hardwareWalletType: hardwareWalletType,
);
@override
diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart
index bb2f508..d7be8fb 100644
--- a/lib/monero/cw_monero.dart
+++ b/lib/monero/cw_monero.dart
@@ -219,6 +219,7 @@ class CWMonero extends Monero {
required String address,
required String password,
required String language,
+ HardwareWalletType? hardwareWalletType,
required int height}) =>
MoneroRestoreWalletFromKeysCredentials(
name: name,
@@ -227,6 +228,7 @@ class CWMonero extends Monero {
address: address,
password: password,
language: language,
+ hardwareWalletType: hardwareWalletType,
height: height);
@override
diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart
index 4fdfc62..a453c97 100644
--- a/lib/view_model/wallet_restore_view_model.dart
+++ b/lib/view_model/wallet_restore_view_model.dart
@@ -250,6 +250,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
xpub: viewKey!,
scanSecret: scanSecret!,
spendPubkey: spendPubkey!,
+ hardwareWalletType: hardwareWalletType,
);
case WalletType.monero:
@@ -261,6 +262,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
address: address!,
password: password,
language: 'English',
+ hardwareWalletType: hardwareWalletType
);
case WalletType.nano:
diff --git a/tool/configure.dart b/tool/configure.dart
index d951002..31fa172 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -191,7 +191,7 @@ abstract class Bitcoin {
});
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
WalletCredentials createBitcoinWalletFromKeys({required String name, required String password, required String xpub, HardwareWalletType? hardwareWalletType});
- WalletCredentials createLitecoinWalletFromKeys({required String name, required String password, required String xpub, required String scanSecret, required String spendPubkey});
+ WalletCredentials createLitecoinWalletFromKeys({required String name, required String password, required String xpub, required String scanSecret, required String spendPubkey, HardwareWalletType? hardwareWalletType});
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
List<String> getWordList();
@@ -456,6 +456,7 @@ abstract class Monero {
required String address,
required String password,
required String language,
+ HardwareWalletType? hardwareWalletType,
required int height});
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required ledger.LedgerConnection ledgerConnection});
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.