refuse bitbox02 keystore import and discovery for legacy p2sh and p2pkh wallets it cannot sign for, and hide those script types from the device import menus

This commit is contained in:
Craig Raw
2026-09-16 13:18:47 +02:00
parent cc8e97c36f
commit de169b180a
3 changed files with 23 additions and 7 deletions
+1 -1
Submodule lark updated: a34efcc647...b15a676e59
@@ -309,7 +309,9 @@ public class DevicePane extends TitledDescriptionPane {
List<PolicyAndScriptType> types = new ArrayList<>(); List<PolicyAndScriptType> types = new ArrayList<>();
for(PolicyType policyType : List.of(PolicyType.SINGLE_HD, PolicyType.SINGLE_SP)) { for(PolicyType policyType : List.of(PolicyType.SINGLE_HD, PolicyType.SINGLE_SP)) {
for(ScriptType scriptType : ScriptType.getAddressableScriptTypes(policyType)) { for(ScriptType scriptType : ScriptType.getAddressableScriptTypes(policyType)) {
types.add(new PolicyAndScriptType(policyType, scriptType)); if(device.supportsScriptType(scriptType)) {
types.add(new PolicyAndScriptType(policyType, scriptType));
}
} }
} }
for(PolicyAndScriptType type : types) { for(PolicyAndScriptType type : types) {
@@ -323,7 +325,7 @@ public class DevicePane extends TitledDescriptionPane {
importMenuButton.getItems().add(item); importMenuButton.getItems().add(item);
} }
} else { } else {
List<ScriptType> scriptTypes = ScriptType.getScriptTypesForPolicyType(wallet.getPolicyType()); List<ScriptType> scriptTypes = ScriptType.getScriptTypesForPolicyType(wallet.getPolicyType()).stream().filter(device::supportsScriptType).toList();
for(ScriptType scriptType : scriptTypes) { for(ScriptType scriptType : scriptTypes) {
MenuItem item = new MenuItem(scriptType.getDescription()); MenuItem item = new MenuItem(scriptType.getDescription());
final List<ChildNumber> derivation = scriptType.getDefaultDerivation(); final List<ChildNumber> derivation = scriptType.getDefaultDerivation();
@@ -753,6 +755,9 @@ public class DevicePane extends TitledDescriptionPane {
setError("Import Error", e.getMessage()); setError("Import Error", e.getMessage());
importButton.setDisable(false); importButton.setDisable(false);
} }
} else if(wallet.getScriptType() != null && !device.supportsScriptType(wallet.getScriptType())) {
setError("Unsupported script type", "The " + device.getModel().toDisplayString() + " cannot sign for " + wallet.getScriptType().getDescription() + " wallets.");
importButton.setDisable(false);
} else if(device.getFingerprint() == null) { } else if(device.getFingerprint() == null) {
Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(passphrase.get()); Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(passphrase.get());
enumerateService.setOnSucceeded(workerStateEvent -> { enumerateService.setOnSucceeded(workerStateEvent -> {
@@ -997,10 +1002,7 @@ public class DevicePane extends TitledDescriptionPane {
List<StandardAccount> discoveryAccounts = new ArrayList<>(Arrays.asList(StandardAccount.values()).subList(0, optRange.get() + 1)); List<StandardAccount> discoveryAccounts = new ArrayList<>(Arrays.asList(StandardAccount.values()).subList(0, optRange.get() + 1));
Map<Hwi.WalletType, String> derivationPaths = new LinkedHashMap<>(); Map<Hwi.WalletType, String> derivationPaths = new LinkedHashMap<>();
List<ScriptType> scriptTypes = new ArrayList<>(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD)); List<ScriptType> scriptTypes = ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD).stream().filter(device::supportsScriptType).toList();
if(device.getModel() == WalletModel.BITBOX_02) {
scriptTypes.remove(ScriptType.P2PKH);
}
for(ScriptType scriptType : scriptTypes) { for(ScriptType scriptType : scriptTypes) {
for(StandardAccount discoveryAccount : discoveryAccounts) { for(StandardAccount discoveryAccount : discoveryAccounts) {
derivationPaths.put(new Hwi.WalletType(scriptType, discoveryAccount), KeyDerivation.writePath(scriptType.getDefaultDerivation(discoveryAccount.getAccountNumber()))); derivationPaths.put(new Hwi.WalletType(scriptType, discoveryAccount), KeyDerivation.writePath(scriptType.getDefaultDerivation(discoveryAccount.getAccountNumber())));
@@ -1083,6 +1085,11 @@ public class DevicePane extends TitledDescriptionPane {
return; return;
} }
if(!device.supportsScriptType(wallet.getScriptType())) {
setError("Unsupported script type", "The " + device.getModel().toDisplayString() + " cannot sign for " + wallet.getScriptType().getDescription() + " wallets.");
return;
}
discoverKeystoresButton.setDisable(true); discoverKeystoresButton.setDisable(true);
discoverKeystoresButton.setMaxHeight(discoverKeystoresButton.getHeight()); discoverKeystoresButton.setMaxHeight(discoverKeystoresButton.getHeight());
ProgressIndicator progressIndicator = new ProgressIndicator(0); ProgressIndicator progressIndicator = new ProgressIndicator(0);
@@ -1,8 +1,11 @@
package com.sparrowwallet.sparrow.io; package com.sparrowwallet.sparrow.io;
import com.sparrowwallet.drongo.protocol.ScriptType;
import com.sparrowwallet.drongo.wallet.WalletModel; import com.sparrowwallet.drongo.wallet.WalletModel;
import com.sparrowwallet.lark.HardwareClient; import com.sparrowwallet.lark.HardwareClient;
import java.util.Arrays;
import java.util.List;
import java.util.Objects; import java.util.Objects;
public class Device { public class Device {
@@ -15,6 +18,7 @@ public class Device {
private boolean card; private boolean card;
private String[][] warnings; private String[][] warnings;
private String error; private String error;
private List<ScriptType> supportedScriptTypes;
public String getType() { public String getType() {
return type; return type;
@@ -94,6 +98,10 @@ public class Device {
return false; return false;
} }
public boolean supportsScriptType(ScriptType scriptType) {
return supportedScriptTypes == null || supportedScriptTypes.contains(scriptType);
}
public String getError() { public String getError() {
return error; return error;
} }
@@ -135,6 +143,7 @@ public class Device {
device.card = hardwareClient.card(); device.card = hardwareClient.card();
device.warnings = hardwareClient.warnings(); device.warnings = hardwareClient.warnings();
device.error = hardwareClient.error(); device.error = hardwareClient.error();
device.supportedScriptTypes = Arrays.stream(ScriptType.values()).filter(hardwareClient::supportsScriptType).toList();
return device; return device;
} }
} }