set default derivation for mnemonic and xprv imports to current keystore derivation

This commit is contained in:
Craig Raw 2024-04-04 14:05:41 +02:00
parent 33d9f260c4
commit 8ac642b09c
7 changed files with 43 additions and 18 deletions

View file

@ -29,7 +29,7 @@ public class FileKeystoreImportPane extends FileImportPane {
}
if(requiredDerivation != null && !requiredDerivation.getDerivation().equals(keystore.getKeyDerivation().getDerivation())) {
setError("Incorrect derivation", "This account requires a derivation of " + requiredDerivation.getDerivationPath() + ", but the imported keystore has a derivation of " + keystore.getKeyDerivation().getDerivationPath() + ".");
setError("Incorrect derivation", "This account requires a derivation of " + requiredDerivation.getDerivationPath() + ", but the imported keystore has a derivation of " + KeyDerivation.writePath(keystore.getKeyDerivation().getDerivation()) + ".");
} else {
EventManager.get().post(new KeystoreImportEvent(keystore));
}

View file

@ -33,6 +33,7 @@ import java.util.Optional;
public class MnemonicKeystoreImportPane extends MnemonicKeystorePane {
protected final Wallet wallet;
private final KeystoreMnemonicImport importer;
private final KeyDerivation defaultDerivation;
private SplitMenuButton importButton;
@ -43,10 +44,11 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane {
private Button confirmButton;
private List<String> generatedMnemonicCode;
public MnemonicKeystoreImportPane(Wallet wallet, KeystoreMnemonicImport importer) {
public MnemonicKeystoreImportPane(Wallet wallet, KeystoreMnemonicImport importer, KeyDerivation defaultDerivation) {
super(importer.getName(), "Create or enter seed", importer.getKeystoreImportDescription(), "image/" + importer.getWalletModel().getType() + ".png");
this.wallet = wallet;
this.importer = importer;
this.defaultDerivation = defaultDerivation;
createImportButton();
buttonBox.getChildren().add(importButton);
@ -59,7 +61,7 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane {
importButton.getStyleClass().add("default-button");
importButton.setOnAction(event -> {
importButton.setDisable(true);
importKeystore(wallet.getScriptType().getDefaultDerivation(), false);
importKeystore(getDefaultDerivation(), false);
});
String[] accounts = new String[] {"Import Default Account #0", "Import Account #1", "Import Account #2", "Import Account #3", "Import Account #4", "Import Account #5", "Import Account #6", "Import Account #7", "Import Account #8", "Import Account #9"};
int scriptAccountsLength = ScriptType.P2SH.equals(wallet.getScriptType()) ? 1 : accounts.length;
@ -77,6 +79,10 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane {
importButton.setVisible(false);
}
private List<ChildNumber> getDefaultDerivation() {
return defaultDerivation == null || defaultDerivation.getDerivation().isEmpty() ? wallet.getScriptType().getDefaultDerivation() : defaultDerivation.getDerivation();
}
protected void enterMnemonic(int numWords) {
generatedMnemonicCode = null;
super.enterMnemonic(numWords);
@ -243,7 +249,7 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane {
setDescription("Ready to import");
showHideLink.setText("Show Derivation...");
showHideLink.setVisible(false);
setContent(getDerivationEntry(wallet.getScriptType().getDefaultDerivation()));
setContent(getDerivationEntry(getDefaultDerivation()));
}
}

View file

@ -28,16 +28,18 @@ import java.util.List;
public class XprvKeystoreImportPane extends TitledDescriptionPane {
protected final Wallet wallet;
protected final KeystoreXprvImport importer;
protected final KeyDerivation defaultDerivation;
private Button enterXprvButton;
private SplitMenuButton importButton;
private ExtendedKey xprv;
public XprvKeystoreImportPane(Wallet wallet, KeystoreXprvImport importer) {
public XprvKeystoreImportPane(Wallet wallet, KeystoreXprvImport importer, KeyDerivation defaultDerivation) {
super(importer.getName(), "Extended key import", importer.getKeystoreImportDescription(), "image/" + importer.getWalletModel().getType() + ".png");
this.wallet = wallet;
this.importer = importer;
this.defaultDerivation = defaultDerivation;
createImportButton();
buttonBox.getChildren().add(importButton);
@ -47,6 +49,7 @@ public class XprvKeystoreImportPane extends TitledDescriptionPane {
super("Master Private Key", "BIP32 key", "", "image/" + WalletModel.SEED.getType() + ".png");
this.wallet = null;
this.importer = null;
this.defaultDerivation = keystore.getKeyDerivation();
try {
this.xprv = keystore.getExtendedMasterPrivateKey();
@ -79,7 +82,7 @@ public class XprvKeystoreImportPane extends TitledDescriptionPane {
importButton.getStyleClass().add("default-button");
importButton.setOnAction(event -> {
importButton.setDisable(true);
importKeystore(wallet.getScriptType().getDefaultDerivation());
importKeystore(getDefaultDerivation());
});
String[] accounts = new String[] {"Import Default Account #0", "Import Account #1", "Import Account #2", "Import Account #3", "Import Account #4", "Import Account #5", "Import Account #6", "Import Account #7", "Import Account #8", "Import Account #9"};
int scriptAccountsLength = ScriptType.P2SH.equals(wallet.getScriptType()) ? 1 : accounts.length;
@ -97,6 +100,10 @@ public class XprvKeystoreImportPane extends TitledDescriptionPane {
importButton.setVisible(false);
}
private List<ChildNumber> getDefaultDerivation() {
return defaultDerivation == null || defaultDerivation.getDerivation().isEmpty() ? wallet.getScriptType().getDefaultDerivation() : defaultDerivation.getDerivation();
}
private void enterXprv() {
setDescription("Enter master private key");
showHideLink.setVisible(false);
@ -149,7 +156,7 @@ public class XprvKeystoreImportPane extends TitledDescriptionPane {
importButton.setVisible(true);
setDescription("Ready to import");
xprv = ExtendedKey.fromDescriptor(xprvField.getText());
setContent(getDerivationEntry(wallet.getScriptType().getDefaultDerivation()));
setContent(getDerivationEntry(getDefaultDerivation()));
});
xprvField.textProperty().addListener((observable, oldValue, newValue) -> {

View file

@ -31,6 +31,7 @@ public class KeystoreImportController implements Initializable {
@FXML
private StackPane importPane;
private KeyDerivation defaultDerivation;
private KeyDerivation requiredDerivation;
private WalletModel requiredModel;
@ -110,6 +111,14 @@ public class KeystoreImportController implements Initializable {
}
}
public KeyDerivation getDefaultDerivation() {
return defaultDerivation;
}
public void setDefaultDerivation(KeyDerivation defaultDerivation) {
this.defaultDerivation = defaultDerivation;
}
public KeyDerivation getRequiredDerivation() {
return requiredDerivation;
}

View file

@ -29,7 +29,7 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
this(wallet, initialSource, null, null, false);
}
public KeystoreImportDialog(Wallet wallet, KeystoreSource initialSource, KeyDerivation requiredDerivation, WalletModel requiredModel, boolean restrictSource) {
public KeystoreImportDialog(Wallet wallet, KeystoreSource initialSource, KeyDerivation currentDerivation, WalletModel currentModel, boolean restrictImport) {
EventManager.get().register(this);
setOnCloseRequest(event -> {
EventManager.get().unregister(this);
@ -43,12 +43,15 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
dialogPane.setContent(Borders.wrap(ksiLoader.load()).emptyBorder().buildAll());
keystoreImportController = ksiLoader.getController();
keystoreImportController.initializeView(wallet);
keystoreImportController.selectSource(initialSource, restrictSource);
keystoreImportController.setRequiredDerivation(requiredDerivation);
keystoreImportController.setRequiredModel(requiredModel);
keystoreImportController.selectSource(initialSource, restrictImport);
keystoreImportController.setDefaultDerivation(currentDerivation);
if(restrictImport) {
keystoreImportController.setRequiredDerivation(currentDerivation);
keystoreImportController.setRequiredModel(currentModel);
}
final ButtonType watchOnlyButtonType = new javafx.scene.control.ButtonType(Network.get().getXpubHeader().getDisplayName() + " / Watch Only Wallet", ButtonBar.ButtonData.LEFT);
if(!restrictSource) {
if(!restrictImport) {
dialogPane.getButtonTypes().add(watchOnlyButtonType);
}
final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);

View file

@ -27,9 +27,9 @@ public class SwController extends KeystoreImportDetailController {
if(importer instanceof KeystoreFileImport) {
importPane = new FileKeystoreImportPane(getMasterController().getWallet(), (KeystoreFileImport)importer, getMasterController().getRequiredDerivation());
} else if(importer instanceof KeystoreMnemonicImport) {
importPane = new MnemonicKeystoreImportPane(getMasterController().getWallet(), (KeystoreMnemonicImport)importer);
importPane = new MnemonicKeystoreImportPane(getMasterController().getWallet(), (KeystoreMnemonicImport)importer, getMasterController().getDefaultDerivation());
} else if(importer instanceof KeystoreXprvImport) {
importPane = new XprvKeystoreImportPane(getMasterController().getWallet(), (KeystoreXprvImport)importer);
importPane = new XprvKeystoreImportPane(getMasterController().getWallet(), (KeystoreXprvImport)importer, getMasterController().getDefaultDerivation());
} else {
throw new IllegalArgumentException("Could not create ImportPane for importer of type " + importer.getClass());
}

View file

@ -367,10 +367,10 @@ public class KeystoreController extends WalletFormController implements Initiali
}
private void launchImportDialog(KeystoreSource initialSource) {
boolean restrictSource = keystore.getSource() != KeystoreSource.SW_WATCH && keystoreSourceToggleGroup.getToggles().stream().anyMatch(toggle -> ((ToggleButton)toggle).isDisabled());
KeyDerivation requiredDerivation = restrictSource ? keystore.getKeyDerivation() : null;
WalletModel requiredModel = restrictSource ? keystore.getWalletModel() : null;
KeystoreImportDialog dlg = new KeystoreImportDialog(getWalletForm().getWallet(), initialSource, requiredDerivation, requiredModel, restrictSource);
boolean restrictImport = keystore.getSource() != KeystoreSource.SW_WATCH && keystoreSourceToggleGroup.getToggles().stream().anyMatch(toggle -> ((ToggleButton)toggle).isDisabled());
KeyDerivation currentDerivation = keystore.getKeyDerivation();
WalletModel currentModel = keystore.getWalletModel();
KeystoreImportDialog dlg = new KeystoreImportDialog(getWalletForm().getWallet(), initialSource, currentDerivation, currentModel, restrictImport);
dlg.initOwner(selectSourcePane.getScene().getWindow());
Optional<Keystore> result = dlg.showAndWait();
if(result.isPresent()) {