diff --git a/drongo b/drongo index 9c28138c..1468b5d5 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 9c28138cd37694f612d5e1dbca70f9833f9584d7 +Subproject commit 1468b5d50debb0bf1b01a4a02e36dd0447f20fa2 diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CardImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/CardImportPane.java index 92d7f0d2..7cfa4f83 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CardImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CardImportPane.java @@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.control; import com.google.common.base.Throwables; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.wallet.*; @@ -44,6 +45,7 @@ public class CardImportPane extends TitledDescriptionPane { private static final Logger log = LoggerFactory.getLogger(CardImportPane.class); private final KeystoreCardImport importer; + private final PolicyType policyType; private List derivation; protected Button importButton; private final SimpleStringProperty pin = new SimpleStringProperty(""); @@ -51,6 +53,7 @@ public class CardImportPane extends TitledDescriptionPane { public CardImportPane(Wallet wallet, KeystoreCardImport importer, KeyDerivation defaultDerivation, KeyDerivation requiredDerivation) { super(importer.getName(), "Place card on reader", importer.getKeystoreImportDescription(getAccount(wallet, requiredDerivation)), importer.getWalletModel()); this.importer = importer; + this.policyType = wallet.getPolicyType(); this.derivation = requiredDerivation == null ? getDefaultDerivation(wallet, defaultDerivation) : requiredDerivation.getDerivation(); } @@ -59,7 +62,7 @@ public class CardImportPane extends TitledDescriptionPane { return defaultDerivation.getDerivation(); } - return wallet == null || wallet.getScriptType() == null ? ScriptType.P2WPKH.getDefaultDerivation() : wallet.getScriptType().getDefaultDerivation(); + return wallet.getScriptType() == null ? ScriptType.P2WPKH.getDefaultDerivation() : wallet.getScriptType().getDefaultDerivation(); } @Override @@ -111,7 +114,7 @@ public class CardImportPane extends TitledDescriptionPane { return; } - CardImportService cardImportService = new CardImportService(importer, pin.get(), derivation, messageProperty); + CardImportService cardImportService = new CardImportService(importer, policyType, pin.get(), derivation, messageProperty); cardImportService.setOnSucceeded(event -> { EventManager.get().post(new KeystoreImportEvent(cardImportService.getValue())); }); @@ -352,12 +355,14 @@ public class CardImportPane extends TitledDescriptionPane { public static class CardImportService extends Service { private final KeystoreCardImport cardImport; + private final PolicyType policyType; private final String pin; private final List derivation; private final StringProperty messageProperty; - public CardImportService(KeystoreCardImport cardImport, String pin, List derivation, StringProperty messageProperty) { + public CardImportService(KeystoreCardImport cardImport, PolicyType policyType, String pin, List derivation, StringProperty messageProperty) { this.cardImport = cardImport; + this.policyType = policyType; this.pin = pin; this.derivation = derivation; this.messageProperty = messageProperty; @@ -368,7 +373,7 @@ public class CardImportPane extends TitledDescriptionPane { return new Task<>() { @Override protected Keystore call() throws Exception { - return cardImport.getKeystore(pin, derivation, messageProperty); + return cardImport.getKeystore(policyType, pin, derivation, messageProperty); } }; } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CodexKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/CodexKeystoreImportPane.java index deaf96c3..f49d48e5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CodexKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CodexKeystoreImportPane.java @@ -81,7 +81,7 @@ public class CodexKeystoreImportPane extends TitledDescriptionPane { private void importKeystore(List derivation) { importButton.setDisable(true); try { - Keystore keystore = importer.getKeystore(derivation, secretShareProperty.get()); + Keystore keystore = importer.getKeystore(wallet.getPolicyType(), derivation, secretShareProperty.get()); EventManager.get().post(new KeystoreImportEvent(keystore)); } catch(ImportException e) { String errorMessage = e.getMessage(); @@ -125,7 +125,7 @@ public class CodexKeystoreImportPane extends TitledDescriptionPane { private void onInputChange(boolean empty, boolean validChecksum) { if(!empty) { try { - importer.getKeystore(ScriptType.P2WPKH.getDefaultDerivation(), secretShareProperty.get()); + importer.getKeystore(wallet.getPolicyType(), ScriptType.P2WPKH.getDefaultDerivation(), secretShareProperty.get()); validChecksum = true; } catch(ImportException e) { invalidLabel.setText("Invalid checksum"); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java b/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java index 06ca959c..29a69264 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java @@ -711,7 +711,7 @@ public class DevicePane extends TitledDescriptionPane { return; } - Service importService = cardApi.getImportService(derivation, messageProperty); + Service importService = cardApi.getImportService(wallet.getPolicyType(), derivation, messageProperty); handleCardOperation(importService, importButton, "Import", true, event -> { importKeystore(derivation, importService.getValue()); }); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java index bb1a4d42..714a7147 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java @@ -25,7 +25,7 @@ public class FileKeystoreImportPane extends FileImportPane { protected void importFile(String fileName, InputStream inputStream, String password) throws ImportException { Keystore keystore = getScannedKeystore(wallet.getScriptType()); if(keystore == null) { - keystore = importer.getKeystore(wallet.getScriptType(), inputStream, password); + keystore = importer.getKeystore(wallet.getPolicyType(), wallet.getScriptType(), inputStream, password); } if(requiredDerivation != null && !requiredDerivation.getDerivation().equals(keystore.getKeyDerivation().getDerivation())) { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java index ca0be683..f8732290 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java @@ -86,7 +86,7 @@ public class FileWalletKeystoreImportPane extends FileImportPane { EventManager.get().post(new WalletImportEvent(wallet)); } else { ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes); - Keystore keystore = importer.getKeystore(scriptType, bais, password); + Keystore keystore = importer.getKeystore(PolicyType.SINGLE_HD, scriptType, bais, password); Wallet wallet = new Wallet(); wallet.setName(Files.getNameWithoutExtension(fileName)); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java index 8ef08545..70a28b74 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java @@ -141,7 +141,7 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane { protected void onWordChange(boolean empty, boolean validWords, boolean validChecksum) { if(!empty && validWords) { try { - importer.getKeystore(wallet.getScriptType().getDefaultDerivation(), wordEntriesProperty.get(), passphraseProperty.get()); + importer.getKeystore(wallet.getPolicyType(), wallet.getScriptType().getDefaultDerivation(), wordEntriesProperty.get(), passphraseProperty.get()); validChecksum = true; } catch(ImportException e) { if(e.getCause() instanceof MnemonicException.MnemonicTypeException) { @@ -256,7 +256,7 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane { private boolean importKeystore(List derivation, boolean dryrun) { importButton.setDisable(true); try { - Keystore keystore = importer.getKeystore(derivation, wordEntriesProperty.get(), passphraseProperty.get()); + Keystore keystore = importer.getKeystore(wallet.getPolicyType(), derivation, wordEntriesProperty.get(), passphraseProperty.get()); if(!dryrun) { if(passphraseProperty.get() != null && !passphraseProperty.get().isEmpty()) { KeystorePassphraseDialog keystorePassphraseDialog = new KeystorePassphraseDialog(null, keystore, true); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicShareKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicShareKeystoreImportPane.java index a3885f16..bda3ff21 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicShareKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicShareKeystoreImportPane.java @@ -162,7 +162,7 @@ public class MnemonicShareKeystoreImportPane extends MnemonicKeystorePane { existing.add(wordEntriesProperty.get()); } - importer.getKeystore(wallet.getScriptType().getDefaultDerivation(), existing, passphraseProperty.get()); + importer.getKeystore(wallet.getPolicyType(), wallet.getScriptType().getDefaultDerivation(), existing, passphraseProperty.get()); validSet = true; complete = true; } catch(MnemonicException e) { @@ -240,7 +240,7 @@ public class MnemonicShareKeystoreImportPane extends MnemonicKeystorePane { private boolean importKeystore(List derivation, boolean dryrun) { importButton.setDisable(true); try { - Keystore keystore = importer.getKeystore(derivation, mnemonicShares, passphraseProperty.get()); + Keystore keystore = importer.getKeystore(wallet.getPolicyType(), derivation, mnemonicShares, passphraseProperty.get()); if(!dryrun) { if(passphraseProperty.get() != null && !passphraseProperty.get().isEmpty()) { KeystorePassphraseDialog keystorePassphraseDialog = new KeystorePassphraseDialog(null, keystore, true); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java index b361eaf7..bdb8cf7b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java @@ -81,7 +81,7 @@ public class MnemonicWalletKeystoreImportPane extends MnemonicKeystorePane { protected void onWordChange(boolean empty, boolean validWords, boolean validChecksum) { if(!empty && validWords) { try { - importer.getKeystore(ScriptType.P2WPKH.getDefaultDerivation(), wordEntriesProperty.get(), passphraseProperty.get()); + importer.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH.getDefaultDerivation(), wordEntriesProperty.get(), passphraseProperty.get()); validChecksum = true; } catch(ImportException e) { if(e.getCause() instanceof MnemonicException.MnemonicTypeException) { @@ -167,7 +167,7 @@ public class MnemonicWalletKeystoreImportPane extends MnemonicKeystorePane { Wallet wallet = new Wallet(""); wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType); - Keystore keystore = importer.getKeystore(derivation, wordEntriesProperty.get(), passphraseProperty.get()); + Keystore keystore = importer.getKeystore(PolicyType.SINGLE_HD, derivation, wordEntriesProperty.get(), passphraseProperty.get()); wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, scriptType, wallet.getKeystores(), 1)); return wallet; diff --git a/src/main/java/com/sparrowwallet/sparrow/control/XprvKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/XprvKeystoreImportPane.java index 06a16eb7..835bb4da 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/XprvKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/XprvKeystoreImportPane.java @@ -114,7 +114,7 @@ public class XprvKeystoreImportPane extends TitledDescriptionPane { private void importKeystore(List derivation) { importButton.setDisable(true); try { - Keystore keystore = importer.getKeystore(derivation, xprv); + Keystore keystore = importer.getKeystore(wallet.getPolicyType(), derivation, xprv); EventManager.get().post(new KeystoreImportEvent(keystore)); } catch (ImportException e) { String errorMessage = e.getMessage(); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Bip129.java b/src/main/java/com/sparrowwallet/sparrow/io/Bip129.java index cae0bcee..5083a1a5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Bip129.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Bip129.java @@ -4,6 +4,7 @@ import com.google.common.io.CharStreams; import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.OutputDescriptor; import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.crypto.Pbkdf2KeyDeriver; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.protocol.Sha256Hash; @@ -93,7 +94,7 @@ public class Bip129 implements KeystoreFileExport, KeystoreFileImport, WalletExp } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); if(password != null) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Bip32.java b/src/main/java/com/sparrowwallet/sparrow/io/Bip32.java index f144c500..1c660b05 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Bip32.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Bip32.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.MasterPrivateExtendedKey; import com.sparrowwallet.drongo.wallet.WalletModel; @@ -25,10 +26,10 @@ public class Bip32 implements KeystoreXprvImport { } @Override - public Keystore getKeystore(List derivation, ExtendedKey xprv) throws ImportException { + public Keystore getKeystore(PolicyType policyType, List derivation, ExtendedKey xprv) throws ImportException { try { MasterPrivateExtendedKey masterPrivateExtendedKey = new MasterPrivateExtendedKey(xprv.getKey().getPrivKeyBytes(), xprv.getKey().getChainCode()); - return Keystore.fromMasterPrivateExtendedKey(masterPrivateExtendedKey, derivation); + return Keystore.fromMasterPrivateExtendedKey(masterPrivateExtendedKey, policyType, derivation); } catch(Exception e) { throw new ImportException(e); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java b/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java index 9b679b4a..a837984a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.*; import java.util.List; @@ -22,11 +23,11 @@ public class Bip39 implements KeystoreMnemonicImport { } @Override - public Keystore getKeystore(List derivation, List mnemonicWords, String passphrase) throws ImportException { + public Keystore getKeystore(PolicyType policyType, List derivation, List mnemonicWords, String passphrase) throws ImportException { try { Bip39MnemonicCode.INSTANCE.check(mnemonicWords); DeterministicSeed seed = new DeterministicSeed(mnemonicWords, passphrase, System.currentTimeMillis(), DeterministicSeed.Type.BIP39); - return Keystore.fromSeed(seed, derivation); + return Keystore.fromSeed(seed, policyType, derivation); } catch (Exception e) { try { ElectrumMnemonicCode.INSTANCE.check(mnemonicWords); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Bip93.java b/src/main/java/com/sparrowwallet/sparrow/io/Bip93.java index 1502ae6e..64a5b548 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Bip93.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Bip93.java @@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; import com.sparrowwallet.drongo.crypto.DeterministicKey; import com.sparrowwallet.drongo.crypto.HDKeyDerivation; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.MasterPrivateExtendedKey; import com.sparrowwallet.drongo.wallet.MnemonicException; @@ -28,12 +29,12 @@ public class Bip93 implements KeystoreCodexImport { } @Override - public Keystore getKeystore(List derivation, String secretShare) throws ImportException { + public Keystore getKeystore(PolicyType policyType, List derivation, String secretShare) throws ImportException { try { Codex32.Codex32Data secretData = Codex32.decode(secretShare); DeterministicKey key = HDKeyDerivation.createMasterPrivateKey(secretData.payloadToBip32Secret()); MasterPrivateExtendedKey mpek = new MasterPrivateExtendedKey(key); - Keystore keystore = Keystore.fromMasterPrivateExtendedKey(mpek, derivation); + Keystore keystore = Keystore.fromMasterPrivateExtendedKey(mpek, policyType, derivation); keystore.setLabel("BIP93"); return keystore; } catch(MnemonicException e) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/CardApi.java b/src/main/java/com/sparrowwallet/sparrow/io/CardApi.java index e010143e..c1b4531a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/CardApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/CardApi.java @@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.OsType; import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.crypto.ChildNumber; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.wallet.Keystore; @@ -107,7 +108,7 @@ public abstract class CardApi { public abstract Service getInitializationService(byte[] entropy, StringProperty messageProperty); - public abstract Service getImportService(List derivation, StringProperty messageProperty); + public abstract Service getImportService(PolicyType policyType, List derivation, StringProperty messageProperty); public abstract Service getSignService(Wallet wallet, PSBT psbt, StringProperty messageProperty); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultMultisig.java index 4c12168c..28dd8139 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultMultisig.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; @@ -19,10 +20,9 @@ public class CoboVaultMultisig extends ColdcardMultisig { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Keystore keystore = super.getKeystore(scriptType, inputStream, password); + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Keystore keystore = super.getKeystore(policyType, scriptType, inputStream, password); keystore.setLabel("Cobo Vault"); - keystore.setWalletModel(getWalletModel()); return keystore; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java index bc50c8e4..ad1ea3f5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java @@ -35,7 +35,7 @@ public class CoboVaultSinglesig implements KeystoreFileImport, WalletImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { Gson gson = new Gson(); CoboVaultSinglesigKeystore coboKeystore = gson.fromJson(new InputStreamReader(inputStream, StandardCharsets.UTF_8), CoboVaultSinglesigKeystore.class); @@ -47,7 +47,7 @@ public class CoboVaultSinglesig implements KeystoreFileImport, WalletImport { Keystore keystore = new Keystore(); keystore.setLabel(getName()); keystore.setSource(KeystoreSource.HW_AIRGAPPED); - keystore.setWalletModel(WalletModel.COBO_VAULT); + keystore.setWalletModel(getWalletModel()); keystore.setKeyDerivation(new KeyDerivation(coboKeystore.MasterFingerprint.toLowerCase(Locale.ROOT), "m/" + coboKeystore.AccountKeyPath, true)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(coboKeystore.ExtPubKey)); @@ -70,7 +70,7 @@ public class CoboVaultSinglesig implements KeystoreFileImport, WalletImport { @Override public Wallet importWallet(InputStream inputStream, String password) throws ImportException { //Use default of P2WPKH - Keystore keystore = getKeystore(ScriptType.P2WPKH, inputStream, ""); + Keystore keystore = getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, inputStream, ""); Wallet wallet = new Wallet(); wallet.setPolicyType(PolicyType.SINGLE_HD); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java index 91660c57..945f02df 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java @@ -32,7 +32,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); inputStream.transferTo(baos); @@ -41,9 +41,9 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle Keystore keystore; try { - keystore = getKeystoreMultisig(scriptType, firstClone, password); + keystore = getKeystoreMultisig(policyType, scriptType, firstClone, password); } catch(Exception e) { - keystore = getKeystoreSinglesig(scriptType, secondClone, password); + keystore = getKeystoreSinglesig(policyType, scriptType, secondClone, password); } return keystore; @@ -52,18 +52,18 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle } } - private Keystore getKeystoreSinglesig(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + private Keystore getKeystoreSinglesig(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { ColdcardSinglesig coldcardSinglesig = new ColdcardSinglesig(); - return coldcardSinglesig.getKeystore(scriptType, inputStream, password); + return coldcardSinglesig.getKeystore(policyType, scriptType, inputStream, password); } - public Keystore getKeystoreMultisig(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystoreMultisig(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); ColdcardKeystore cck = JsonPersistence.getGson().fromJson(reader, ColdcardKeystore.class); Keystore keystore = new Keystore("Coldcard"); keystore.setSource(KeystoreSource.HW_AIRGAPPED); - keystore.setWalletModel(WalletModel.COLDCARD); + keystore.setWalletModel(getWalletModel()); try { if(cck.xpub != null && cck.path != null) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java index df80e8c2..af639734 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java @@ -8,6 +8,7 @@ import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.policy.Policy; import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.silentpayments.SilentPaymentScanAddress; import com.sparrowwallet.drongo.wallet.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,7 +55,7 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { Gson gson = new Gson(); Type stringStringMap = new TypeToken>() { @@ -67,6 +68,22 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport { String masterFingerprint = map.get("xfp").getAsString(); + if(policyType == PolicyType.SINGLE_SP) { + JsonElement bip352Element = map.get("bip352"); + if(bip352Element == null) { + throw new ImportException("File does not contain an export for silent payments"); + } + + ColdcardKeystore ck = gson.fromJson(bip352Element, ColdcardKeystore.class); + Keystore keystore = new Keystore(); + keystore.setLabel(getName()); + keystore.setSource(KeystoreSource.HW_AIRGAPPED); + keystore.setWalletModel(getWalletModel()); + keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, ck.deriv, true)); + keystore.setSilentPaymentScanAddress(SilentPaymentScanAddress.fromKeyString(ck.spscan)); + return keystore; + } + for (String key : map.keySet()) { if (key.startsWith("bip")) { ColdcardKeystore ck = gson.fromJson(map.get(key), ColdcardKeystore.class); @@ -77,7 +94,7 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport { Keystore keystore = new Keystore(); keystore.setLabel(getName()); keystore.setSource(KeystoreSource.HW_AIRGAPPED); - keystore.setWalletModel(WalletModel.COLDCARD); + keystore.setWalletModel(getWalletModel()); keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, ck.deriv, true)); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(ck.xpub)); @@ -101,7 +118,7 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport { @Override public Wallet importWallet(InputStream inputStream, String password) throws ImportException { //Use default of P2WPKH - Keystore keystore = getKeystore(ScriptType.P2WPKH, inputStream, ""); + Keystore keystore = getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, inputStream, ""); Wallet wallet = new Wallet(); wallet.setPolicyType(PolicyType.SINGLE_HD); @@ -122,6 +139,7 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport { public String deriv; public String name; public String xpub; + public String spscan; public String xfp; } } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java index 4e78ad7f..ab7cc63d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java @@ -40,10 +40,10 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { Wallet wallet = importWallet(inputStream, password); - if(!wallet.getPolicyType().equals(PolicyType.SINGLE_HD) || wallet.getKeystores().size() != 1) { + if(wallet.getPolicyType().equals(PolicyType.MULTI_HD) || wallet.getKeystores().size() != 1) { throw new ImportException("Multisig wallet detected - import it using File > Import Wallet"); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/GordianSeedTool.java b/src/main/java/com/sparrowwallet/sparrow/io/GordianSeedTool.java index 9f03bd56..b2660a4d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/GordianSeedTool.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/GordianSeedTool.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.Network; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; @@ -25,7 +26,7 @@ public class GordianSeedTool implements KeystoreFileImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { throw new ImportException("Only QR imports are supported."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Jade.java b/src/main/java/com/sparrowwallet/sparrow/io/Jade.java index 2f21d150..0905f111 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Jade.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Jade.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; @@ -24,7 +25,7 @@ public class Jade implements KeystoreFileImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { throw new ImportException("Failed to detect a valid " + scriptType.getDescription() + " keystore."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/JadeMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/JadeMultisig.java index 9d5897c8..05665321 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/JadeMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/JadeMultisig.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; @@ -63,14 +64,13 @@ public class JadeMultisig extends ColdcardMultisig { Wallet wallet = super.importWallet(inputStream, password); for(Keystore keystore : wallet.getKeystores()) { keystore.setLabel(keystore.getLabel().replace("Coldcard", "Jade")); - keystore.setWalletModel(WalletModel.JADE); } return wallet; } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { throw new ImportException("Failed to detect a valid " + scriptType.getDescription() + " keystore."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellMultisig.java index 98dd0932..f689490f 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellMultisig.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; @@ -23,10 +24,9 @@ public class KeycardShellMultisig extends ColdcardMultisig { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Keystore keystore = super.getKeystore(scriptType, inputStream, password); + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Keystore keystore = super.getKeystore(policyType, scriptType, inputStream, password); keystore.setLabel("Keycard Shell"); - keystore.setWalletModel(getWalletModel()); return keystore; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellSinglesig.java index dc65b597..d2a32f29 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeycardShellSinglesig.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.Network; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; @@ -24,10 +25,9 @@ public class KeycardShellSinglesig extends KeystoneSinglesig { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Keystore keystore = super.getKeystore(scriptType, inputStream, password); + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Keystore keystore = super.getKeystore(policyType, scriptType, inputStream, password); keystore.setLabel("Keycard Shell"); - keystore.setWalletModel(getWalletModel()); return keystore; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoneMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoneMultisig.java index e3004954..ab19dbf4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoneMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoneMultisig.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; @@ -19,10 +20,9 @@ public class KeystoneMultisig extends ColdcardMultisig { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Keystore keystore = super.getKeystore(scriptType, inputStream, password); + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Keystore keystore = super.getKeystore(policyType, scriptType, inputStream, password); keystore.setLabel("Keystone"); - keystore.setWalletModel(getWalletModel()); return keystore; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java index b8d518ce..c47e8be4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java @@ -36,7 +36,7 @@ public class KeystoneSinglesig implements KeystoreFileImport, WalletImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { String outputDescriptor = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n")); OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(outputDescriptor); @@ -55,7 +55,7 @@ public class KeystoneSinglesig implements KeystoreFileImport, WalletImport { Keystore keystore = new Keystore(); keystore.setLabel(getName()); keystore.setSource(KeystoreSource.HW_AIRGAPPED); - keystore.setWalletModel(WalletModel.KEYSTONE); + keystore.setWalletModel(getWalletModel()); keystore.setKeyDerivation(keyDerivation); keystore.setExtendedPublicKey(xpub); @@ -75,7 +75,7 @@ public class KeystoneSinglesig implements KeystoreFileImport, WalletImport { @Override public Wallet importWallet(InputStream inputStream, String password) throws ImportException { //Use default of P2WPKH - Keystore keystore = getKeystore(ScriptType.P2WPKH, inputStream, ""); + Keystore keystore = getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, inputStream, ""); Wallet wallet = new Wallet(); wallet.setPolicyType(PolicyType.SINGLE_HD); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCardImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCardImport.java index 090e19db..9e2260ea 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCardImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCardImport.java @@ -1,12 +1,13 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import javafx.beans.property.StringProperty; import java.util.List; public interface KeystoreCardImport extends CardImport { - Keystore getKeystore(String pin, List derivation, StringProperty messageProperty) throws ImportException; + Keystore getKeystore(PolicyType policyType, String pin, List derivation, StringProperty messageProperty) throws ImportException; String getKeystoreImportDescription(int account); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCodexImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCodexImport.java index a02c2ec4..553448da 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCodexImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreCodexImport.java @@ -1,10 +1,11 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import java.util.List; public interface KeystoreCodexImport extends KeystoreImport { - Keystore getKeystore(List derivation, String secretShare) throws ImportException; + Keystore getKeystore(PolicyType policyType, List derivation, String secretShare) throws ImportException; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java index ce1dddd4..19cdb72e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java @@ -1,12 +1,13 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import java.io.InputStream; public interface KeystoreFileImport extends KeystoreImport, FileImport { - Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException; + Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException; String getKeystoreImportDescription(int account); default String getKeystoreImportDescription() { return getKeystoreImportDescription(0); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicImport.java index d12aaafb..bbcdca7f 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicImport.java @@ -1,10 +1,11 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import java.util.List; public interface KeystoreMnemonicImport extends KeystoreImport { - Keystore getKeystore(List derivation, List mnemonicWords, String passphrase) throws ImportException; + Keystore getKeystore(PolicyType policyType, List derivation, List mnemonicWords, String passphrase) throws ImportException; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicShareImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicShareImport.java index 3b3866eb..41671e7f 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicShareImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreMnemonicShareImport.java @@ -1,10 +1,11 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import java.util.List; public interface KeystoreMnemonicShareImport extends KeystoreImport { - Keystore getKeystore(List derivation, List> mnemonicShares, String passphrase) throws ImportException; + Keystore getKeystore(PolicyType policyType, List derivation, List> mnemonicShares, String passphrase) throws ImportException; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreXprvImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreXprvImport.java index eb6006f9..41a2095a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreXprvImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreXprvImport.java @@ -2,10 +2,11 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import java.util.List; public interface KeystoreXprvImport extends KeystoreImport { - Keystore getKeystore(List derivation, ExtendedKey xprv) throws ImportException; + Keystore getKeystore(PolicyType policyType, List derivation, ExtendedKey xprv) throws ImportException; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/PassportMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/PassportMultisig.java index 87d99af2..73cf21ce 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/PassportMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/PassportMultisig.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; @@ -19,10 +20,9 @@ public class PassportMultisig extends ColdcardMultisig { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Keystore keystore = super.getKeystore(scriptType, inputStream, password); + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Keystore keystore = super.getKeystore(policyType, scriptType, inputStream, password); keystore.setLabel("Passport"); - keystore.setWalletModel(getWalletModel()); return keystore; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/PassportSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/PassportSinglesig.java index ab4887ca..477e95e8 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/PassportSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/PassportSinglesig.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; @@ -18,10 +19,9 @@ public class PassportSinglesig extends ColdcardSinglesig { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Keystore keystore = super.getKeystore(scriptType, inputStream, password); + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Keystore keystore = super.getKeystore(policyType, scriptType, inputStream, password); keystore.setLabel("Passport"); - keystore.setWalletModel(getWalletModel()); return keystore; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java b/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java index 0ed872ad..6b7e2a9e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java @@ -7,6 +7,7 @@ import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.SamouraiUtil; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.*; @@ -25,7 +26,7 @@ public class Samourai implements KeystoreFileImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { String input = CharStreams.toString(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); @@ -52,7 +53,7 @@ public class Samourai implements KeystoreFileImport { SamouraiBackup backup = new Gson().fromJson(decrypted, SamouraiBackup.class); DeterministicSeed seed = new DeterministicSeed(Utils.hexToBytes(backup.wallet.seed), password, 0); - Keystore keystore = Keystore.fromSeed(seed, scriptType.getDefaultDerivation()); + Keystore keystore = Keystore.fromSeed(seed, PolicyType.SINGLE_HD, scriptType.getDefaultDerivation()); keystore.setLabel(getWalletModel().toDisplayString()); return keystore; } catch(JsonParseException e) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Slip39.java b/src/main/java/com/sparrowwallet/sparrow/io/Slip39.java index e0afd31d..32fe8daa 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Slip39.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Slip39.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.*; import com.sparrowwallet.drongo.wallet.slip39.RecoveryState; import com.sparrowwallet.drongo.wallet.slip39.Share; @@ -25,7 +26,7 @@ public class Slip39 implements KeystoreMnemonicShareImport { } @Override - public Keystore getKeystore(List derivation, List> mnemonicShares, String passphrase) throws ImportException { + public Keystore getKeystore(PolicyType policyType, List derivation, List> mnemonicShares, String passphrase) throws ImportException { try { RecoveryState recoveryState = new RecoveryState(); for(List mnemonicWords : mnemonicShares) { @@ -36,7 +37,7 @@ public class Slip39 implements KeystoreMnemonicShareImport { if(recoveryState.isComplete()) { byte[] secret = recoveryState.recover(passphrase.getBytes(StandardCharsets.UTF_8)); DeterministicSeed seed = new DeterministicSeed(secret, passphrase, System.currentTimeMillis(), DeterministicSeed.Type.SLIP39); - return Keystore.fromSeed(seed, derivation); + return Keystore.fromSeed(seed, policyType, derivation); } else { throw new Slip39ProgressException(recoveryState.getShortStatus(), recoveryState.getStatus()); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/SpecterDIY.java b/src/main/java/com/sparrowwallet/sparrow/io/SpecterDIY.java index 782513d1..ead4e5da 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/SpecterDIY.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/SpecterDIY.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.io; import com.google.common.io.CharStreams; import com.sparrowwallet.drongo.OutputDescriptor; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.KeystoreSource; @@ -17,7 +18,7 @@ public class SpecterDIY implements KeystoreFileImport, WalletExport { private static final Logger log = LoggerFactory.getLogger(SpecterDIY.class); @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(PolicyType policyType, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { String text = CharStreams.toString(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); String outputDesc = "sh(" + text + ")"; diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java index f461754f..1945b08c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java @@ -183,7 +183,7 @@ public class Storage { Keystore keystore = wallet.getKeystores().get(i); if(keystore.hasSeed()) { Keystore copyKeystore = copy.getKeystores().get(i); - Keystore derivedKeystore = Keystore.fromSeed(copyKeystore.getSeed(), copyKeystore.getKeyDerivation().getDerivation()); + Keystore derivedKeystore = Keystore.fromSeed(copyKeystore.getSeed(), wallet.getPolicyType(), copyKeystore.getKeyDerivation().getDerivation()); keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); keystore.getSeed().setPassphrase(copyKeystore.getSeed().getPassphrase()); @@ -192,7 +192,7 @@ public class Storage { copyKeystore.getSeed().clear(); } else if(keystore.hasMasterPrivateExtendedKey()) { Keystore copyKeystore = copy.getKeystores().get(i); - Keystore derivedKeystore = Keystore.fromMasterPrivateExtendedKey(copyKeystore.getMasterPrivateExtendedKey(), copyKeystore.getKeyDerivation().getDerivation()); + Keystore derivedKeystore = Keystore.fromMasterPrivateExtendedKey(copyKeystore.getMasterPrivateExtendedKey(), wallet.getPolicyType(), copyKeystore.getKeyDerivation().getDerivation()); keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); keystore.setBip47ExtendedPrivateKey(derivedKeystore.getBip47ExtendedPrivateKey()); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java index 909c2449..1e4e3475 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java @@ -142,12 +142,12 @@ public class CkCardApi extends CardApi { } @Override - public Service getImportService(List derivation, StringProperty messageProperty) { + public Service getImportService(PolicyType policyType, List derivation, StringProperty messageProperty) { if(cardType == WalletModel.SATSCHIP) { - return new CardImportPane.CardImportService(new Satschip(), cvc, derivation, messageProperty); + return new CardImportPane.CardImportService(new Satschip(), policyType, cvc, derivation, messageProperty); } - return new CardImportPane.CardImportService(new Tapsigner(), cvc, derivation, messageProperty); + return new CardImportPane.CardImportService(new Tapsigner(), policyType, cvc, derivation, messageProperty); } @Override diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/Tapsigner.java b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/Tapsigner.java index b85c0a82..12ab589a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/Tapsigner.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/Tapsigner.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io.ckcard; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; import com.sparrowwallet.sparrow.io.KeystoreCardImport; @@ -52,7 +53,7 @@ public class Tapsigner implements KeystoreCardImport { } @Override - public Keystore getKeystore(String pin, List derivation, StringProperty messageProperty) throws ImportException { + public Keystore getKeystore(PolicyType policyType, String pin, List derivation, StringProperty messageProperty) throws ImportException { if(pin.length() < 6) { throw new ImportException("PIN too short."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/keycard/Keycard.java b/src/main/java/com/sparrowwallet/sparrow/io/keycard/Keycard.java index 1ca147d2..dd9924b6 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/keycard/Keycard.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/keycard/Keycard.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io.keycard; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; import com.sparrowwallet.sparrow.io.ImportException; @@ -52,7 +53,7 @@ public class Keycard implements KeystoreCardImport { } @Override - public Keystore getKeystore(String pin, List derivation, StringProperty messageProperty) throws ImportException { + public Keystore getKeystore(PolicyType policyType, String pin, List derivation, StringProperty messageProperty) throws ImportException { if(!StringUtils.isNumeric(pin)) { throw new ImportException("PIN must be all digits."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/keycard/KeycardApi.java b/src/main/java/com/sparrowwallet/sparrow/io/keycard/KeycardApi.java index c591223b..59c7be44 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/keycard/KeycardApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/keycard/KeycardApi.java @@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.crypto.ChildNumber; import com.sparrowwallet.drongo.crypto.ECDSASignature; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTInput; @@ -145,8 +146,8 @@ public class KeycardApi extends CardApi { } @Override - public Service getImportService(List derivation, StringProperty messageProperty) { - return new CardImportPane.CardImportService(new Keycard(), pin, derivation, messageProperty); + public Service getImportService(PolicyType policyType, List derivation, StringProperty messageProperty) { + return new CardImportPane.CardImportService(new Keycard(), policyType, pin, derivation, messageProperty); } private byte[] compressedPub(byte[] uncompressedPub) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatoCardApi.java b/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatoCardApi.java index c37a5bb1..2d28991e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatoCardApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatoCardApi.java @@ -9,6 +9,7 @@ import com.sparrowwallet.drongo.crypto.ChildNumber; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.crypto.ECDSASignature; import com.sparrowwallet.drongo.crypto.SchnorrSignature; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTInput; @@ -122,8 +123,8 @@ public class SatoCardApi extends CardApi { } @Override - public Service getImportService(List derivation, StringProperty messageProperty) { - return new CardImportPane.CardImportService(new Satochip(), pin, derivation, messageProperty); + public Service getImportService(PolicyType policyType, List derivation, StringProperty messageProperty) { + return new CardImportPane.CardImportService(new Satochip(), policyType, pin, derivation, messageProperty); } /* diff --git a/src/main/java/com/sparrowwallet/sparrow/io/satochip/Satochip.java b/src/main/java/com/sparrowwallet/sparrow/io/satochip/Satochip.java index 8c16150e..29aa6b0c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/satochip/Satochip.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/satochip/Satochip.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io.satochip; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletModel; import com.sparrowwallet.sparrow.io.KeystoreCardImport; @@ -51,7 +52,7 @@ public class Satochip implements KeystoreCardImport { } @Override - public Keystore getKeystore(String pin, List derivation, StringProperty messageProperty) throws ImportException { + public Keystore getKeystore(PolicyType policyType, String pin, List derivation, StringProperty messageProperty) throws ImportException { if(pin.length() < 4) { throw new ImportException("PIN too short."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/keystoreimport/HwAirgappedController.java b/src/main/java/com/sparrowwallet/sparrow/keystoreimport/HwAirgappedController.java index 114c6fb0..39cdeb94 100644 --- a/src/main/java/com/sparrowwallet/sparrow/keystoreimport/HwAirgappedController.java +++ b/src/main/java/com/sparrowwallet/sparrow/keystoreimport/HwAirgappedController.java @@ -30,6 +30,8 @@ public class HwAirgappedController extends KeystoreImportDetailController { fileImporters = List.of(new ColdcardSinglesig(), new CoboVaultSinglesig(), new Jade(), new KeystoneSinglesig(), new PassportSinglesig(), new SeedSigner(), new GordianSeedTool(), new SpecterDIY(), new Krux(), new AirGapVault(), new KeycardShellSinglesig()); } else if(getMasterController().getWallet().getPolicyType().equals(PolicyType.MULTI_HD)) { fileImporters = List.of(new Bip129(), new ColdcardMultisig(), new CoboVaultMultisig(), new JadeMultisig(), new KeystoneMultisig(), new PassportMultisig(), new SeedSigner(), new GordianSeedTool(), new SpecterDIY(), new Krux(), new KeycardShellMultisig()); + } else if(getMasterController().getWallet().getPolicyType().equals(PolicyType.SINGLE_SP)) { + fileImporters = List.of(new ColdcardSinglesig()); } for(KeystoreFileImport importer : fileImporters) { diff --git a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/Bip39Dialog.java b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/Bip39Dialog.java index 1b5b9b17..a1826c5c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/Bip39Dialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/Bip39Dialog.java @@ -74,7 +74,7 @@ public class Bip39Dialog extends NewWalletDialog { seedWords.setTextChangeListener((newText, changedByUserInteraction) -> { try { String[] words = newText.split("[ \n]"); - importer.getKeystore(scriptType.getSelectedItem().scriptType.getDefaultDerivation(), Arrays.asList(words), passphrase.getText()); + importer.getKeystore(PolicyType.SINGLE_HD, scriptType.getSelectedItem().scriptType.getDefaultDerivation(), Arrays.asList(words), passphrase.getText()); createWallet.setEnabled(true); } catch(ImportException e) { createWallet.setEnabled(false); @@ -152,7 +152,7 @@ public class Bip39Dialog extends NewWalletDialog { Wallet wallet = new Wallet(walletName); wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType.getSelectedItem().scriptType); - Keystore keystore = importer.getKeystore(wallet.getScriptType().getDefaultDerivation(), getWords(), passphrase.getText()); + Keystore keystore = importer.getKeystore(PolicyType.SINGLE_HD, wallet.getScriptType().getDefaultDerivation(), getWords(), passphrase.getText()); wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, wallet.getScriptType(), wallet.getKeystores(), 1)); return List.of(wallet); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index e695d05d..e1c2fe72 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -1034,7 +1034,7 @@ public class HeadersController extends TransactionFormController implements Init private void signFromSeed(DeterministicSeed seed) { try { - String masterFingerprint = Keystore.fromSeed(seed, ScriptType.P2PKH.getDefaultDerivation()).getKeyDerivation().getMasterFingerprint(); + String masterFingerprint = Keystore.fromSeed(seed, PolicyType.SINGLE_HD, ScriptType.P2PKH.getDefaultDerivation()).getKeyDerivation().getMasterFingerprint(); Wallet walletCopy = headersForm.getSigningWallet().copy(); OptionalInt optIndex = IntStream.range(0, walletCopy.getKeystores().size()) .filter(i -> walletCopy.getKeystores().get(i).getKeyDerivation().getMasterFingerprint().equals(masterFingerprint)).findFirst(); @@ -1044,7 +1044,7 @@ public class HeadersController extends TransactionFormController implements Init keystore.setMasterPrivateExtendedKey(null); }); Keystore original = walletCopy.getKeystores().get(optIndex.getAsInt()); - Keystore replacement = Keystore.fromSeed(seed, original.getKeyDerivation().getDerivation()); + Keystore replacement = Keystore.fromSeed(seed, walletCopy.getPolicyType(), original.getKeyDerivation().getDerivation()); walletCopy.getKeystores().set(optIndex.getAsInt(), replacement); signUnencryptedKeystores(walletCopy); } else { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java index 61eb2953..827278c1 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java @@ -656,7 +656,7 @@ public class KeystoreController extends WalletFormController implements Initiali AppServices.showErrorDialog("Missing Script Type", "QR Code did not contain any information for the " + getWalletForm().getWallet().getScriptType().getDescription() + " script type."); } else if(result.seed != null) { try { - Keystore keystore = Keystore.fromSeed(result.seed, getWalletForm().getWallet().getScriptType().getDefaultDerivation()); + Keystore keystore = Keystore.fromSeed(result.seed, getWalletForm().getWallet().getPolicyType(), getWalletForm().getWallet().getScriptType().getDefaultDerivation()); fingerprint.setText(keystore.getKeyDerivation().getMasterFingerprint()); derivation.setText(keystore.getKeyDerivation().getDerivationPath()); xpub.setText(keystore.getExtendedPublicKey().toString()); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java index d52759c0..1bdd5bff 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java @@ -125,9 +125,7 @@ public class SettingsController extends WalletFormController implements Initiali walletForm.getWallet().setPolicyType(policyType); scriptType.setItems(FXCollections.observableArrayList(ScriptType.getAddressableScriptTypes(policyType))); - if(!ScriptType.getAddressableScriptTypes(policyType).contains(walletForm.getWallet().getScriptType())) { - scriptType.getSelectionModel().select(policyType.getDefaultScriptType()); - } + scriptType.getSelectionModel().select(policyType.getDefaultScriptType()); if(!initialising) { clearKeystoreTabs(); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesigTest.java index 6a9937b2..42e83e59 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesigTest.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.ExtendedKey; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import org.junit.jupiter.api.Assertions; @@ -10,7 +11,7 @@ public class CoboVaultSinglesigTest extends IoTest { @Test public void testImport() throws ImportException { CoboVaultSinglesig coboSingleSig = new CoboVaultSinglesig(); - Keystore keystore = coboSingleSig.getKeystore(ScriptType.P2WPKH, getInputStream("cobo-singlesig-keystore-1.json"), null); + Keystore keystore = coboSingleSig.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, getInputStream("cobo-singlesig-keystore-1.json"), null); Assertions.assertEquals("Cobo Vault", keystore.getLabel()); Assertions.assertEquals("m/84'/0'/0'", keystore.getKeyDerivation().getDerivationPath()); @@ -22,6 +23,6 @@ public class CoboVaultSinglesigTest extends IoTest { @Test public void testIncorrectScriptType() throws ImportException { CoboVaultSinglesig coboSingleSig = new CoboVaultSinglesig(); - Assertions.assertThrows(ImportException.class, () -> coboSingleSig.getKeystore(ScriptType.P2SH_P2WPKH, getInputStream("cobo-singlesig-keystore-1.json"), null)); + Assertions.assertThrows(ImportException.class, () -> coboSingleSig.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2SH_P2WPKH, getInputStream("cobo-singlesig-keystore-1.json"), null)); } } diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java index 487facfa..713bdef1 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java @@ -19,7 +19,7 @@ public class ColdcardMultisigTest extends IoTest { public void importKeystore1() throws ImportException { Network.set(Network.TESTNET); ColdcardMultisig ccMultisig = new ColdcardMultisig(); - Keystore keystore = ccMultisig.getKeystore(ScriptType.P2SH_P2WSH, getInputStream("cc-multisig-keystore-1.json"), null); + Keystore keystore = ccMultisig.getKeystore(PolicyType.MULTI_HD, ScriptType.P2SH_P2WSH, getInputStream("cc-multisig-keystore-1.json"), null); Assertions.assertEquals("Coldcard", keystore.getLabel()); Assertions.assertEquals("m/48'/1'/0'/1'", keystore.getKeyDerivation().getDerivationPath()); Assertions.assertEquals("0f056943", keystore.getKeyDerivation().getMasterFingerprint()); @@ -30,14 +30,14 @@ public class ColdcardMultisigTest extends IoTest { @Test public void importKeystore1IncorrectScriptType() throws ImportException { ColdcardMultisig ccMultisig = new ColdcardMultisig(); - Assertions.assertThrows(ImportException.class, () -> ccMultisig.getKeystore(ScriptType.P2SH_P2WPKH, getInputStream("cc-multisig-keystore-1.json"), null)); + Assertions.assertThrows(ImportException.class, () -> ccMultisig.getKeystore(PolicyType.MULTI_HD, ScriptType.P2SH_P2WPKH, getInputStream("cc-multisig-keystore-1.json"), null)); } @Test public void importKeystore2() throws ImportException { Network.set(Network.TESTNET); ColdcardMultisig ccMultisig = new ColdcardMultisig(); - Keystore keystore = ccMultisig.getKeystore(ScriptType.P2SH, getInputStream("cc-multisig-keystore-2.json"), null); + Keystore keystore = ccMultisig.getKeystore(PolicyType.MULTI_HD, ScriptType.P2SH, getInputStream("cc-multisig-keystore-2.json"), null); Assertions.assertEquals("Coldcard", keystore.getLabel()); Assertions.assertEquals("m/45'", keystore.getKeyDerivation().getDerivationPath()); Assertions.assertEquals("6ba6cfd0", keystore.getKeyDerivation().getMasterFingerprint()); @@ -49,7 +49,7 @@ public class ColdcardMultisigTest extends IoTest { public void importKeystore2b() throws ImportException { Network.set(Network.TESTNET); ColdcardMultisig ccMultisig = new ColdcardMultisig(); - Keystore keystore = ccMultisig.getKeystore(ScriptType.P2WSH, getInputStream("cc-multisig-keystore-2.json"), null); + Keystore keystore = ccMultisig.getKeystore(PolicyType.MULTI_HD, ScriptType.P2WSH, getInputStream("cc-multisig-keystore-2.json"), null); Assertions.assertEquals("Coldcard", keystore.getLabel()); Assertions.assertEquals("m/48'/1'/0'/2'", keystore.getKeyDerivation().getDerivationPath()); Assertions.assertEquals("6ba6cfd0", keystore.getKeyDerivation().getMasterFingerprint()); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardSinglesigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardSinglesigTest.java index 113c9e55..0393053c 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardSinglesigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardSinglesigTest.java @@ -2,7 +2,9 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.Network; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.silentpayments.SilentPaymentScanAddress; import com.sparrowwallet.drongo.wallet.Keystore; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -13,7 +15,7 @@ public class ColdcardSinglesigTest extends IoTest { public void testImport() throws ImportException { Network.set(Network.TESTNET); ColdcardSinglesig ccSingleSig = new ColdcardSinglesig(); - Keystore keystore = ccSingleSig.getKeystore(ScriptType.P2SH_P2WPKH, getInputStream("cc-singlesig-keystore-1.json"), null); + Keystore keystore = ccSingleSig.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2SH_P2WPKH, getInputStream("cc-singlesig-keystore-1.json"), null); Assertions.assertEquals("Coldcard", keystore.getLabel()); Assertions.assertEquals("m/49'/1'/123'", keystore.getKeyDerivation().getDerivationPath()); @@ -26,7 +28,7 @@ public class ColdcardSinglesigTest extends IoTest { public void testImportWitness() throws ImportException { Network.set(Network.TESTNET); ColdcardSinglesig ccSingleSig = new ColdcardSinglesig(); - Keystore keystore = ccSingleSig.getKeystore(ScriptType.P2WPKH, getInputStream("cc-singlesig-keystore-1.json"), null); + Keystore keystore = ccSingleSig.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, getInputStream("cc-singlesig-keystore-1.json"), null); Assertions.assertEquals("Coldcard", keystore.getLabel()); Assertions.assertEquals("m/84'/1'/123'", keystore.getKeyDerivation().getDerivationPath()); @@ -35,6 +37,22 @@ public class ColdcardSinglesigTest extends IoTest { Assertions.assertTrue(keystore.isValid()); } + @Test + public void testImportSilentPayments() throws ImportException { + Network.set(Network.TESTNET); + ColdcardSinglesig ccSingleSig = new ColdcardSinglesig(); + Keystore keystore = ccSingleSig.getKeystore(PolicyType.SINGLE_SP, ScriptType.P2TR, getInputStream("cc-singlesig-sp-keystore-1.json"), null); + + Assertions.assertEquals("Coldcard", keystore.getLabel()); + Assertions.assertEquals("m/352'/1'/0'", keystore.getKeyDerivation().getDerivationPath()); + Assertions.assertEquals("0f056943", keystore.getKeyDerivation().getMasterFingerprint()); + Assertions.assertNull(keystore.getExtendedPublicKey()); + Assertions.assertNotNull(keystore.getSilentPaymentScanAddress()); + Assertions.assertEquals(SilentPaymentScanAddress.fromKeyString("tspscan1q05wxw5wc7wqmkf8cnfc6ry76qej8vhr3a3mmxmwgv35s0tlw24fs82k0npv2hv6p97s8sd9t7vpf44kluka9w863zjwxzfrym2ay9ccfzt06c4"), + keystore.getSilentPaymentScanAddress()); + Assertions.assertTrue(keystore.isValid()); + } + @AfterEach public void tearDown() throws Exception { Network.set(null); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/KeystoneSinglesigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/KeystoneSinglesigTest.java index c8b8273e..55cd0897 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/KeystoneSinglesigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/KeystoneSinglesigTest.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.ExtendedKey; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import org.junit.jupiter.api.Assertions; @@ -10,7 +11,7 @@ public class KeystoneSinglesigTest extends IoTest { @Test public void testImport() throws ImportException { KeystoneSinglesig keystoneSingleSig = new KeystoneSinglesig(); - Keystore keystore = keystoneSingleSig.getKeystore(ScriptType.P2WPKH, getInputStream("keystone-singlesig-keystore-1.txt"), null); + Keystore keystore = keystoneSingleSig.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, getInputStream("keystone-singlesig-keystore-1.txt"), null); Assertions.assertEquals("Keystone", keystore.getLabel()); Assertions.assertEquals("m/84'/0'/0'", keystore.getKeyDerivation().getDerivationPath()); @@ -22,6 +23,6 @@ public class KeystoneSinglesigTest extends IoTest { @Test public void testIncorrectScriptType() throws ImportException { KeystoneSinglesig keystoneSingleSig = new KeystoneSinglesig(); - Assertions.assertThrows(ImportException.class, () -> keystoneSingleSig.getKeystore(ScriptType.P2SH_P2WPKH, getInputStream("keystone-singlesig-keystore-1.txt"), null)); + Assertions.assertThrows(ImportException.class, () -> keystoneSingleSig.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2SH_P2WPKH, getInputStream("keystone-singlesig-keystore-1.txt"), null)); } } diff --git a/src/test/java/com/sparrowwallet/sparrow/io/SpecterDIYTest.java b/src/test/java/com/sparrowwallet/sparrow/io/SpecterDIYTest.java index da636173..7afeeff2 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/SpecterDIYTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/SpecterDIYTest.java @@ -4,6 +4,7 @@ import com.google.common.io.ByteStreams; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.Network; import com.sparrowwallet.drongo.OutputDescriptor; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; @@ -18,7 +19,7 @@ public class SpecterDIYTest extends IoTest { public void testImport() throws ImportException { Network.set(Network.TESTNET); SpecterDIY specterDIY = new SpecterDIY(); - Keystore keystore = specterDIY.getKeystore(ScriptType.P2WPKH, getInputStream("specter-diy-keystore.txt"), null); + Keystore keystore = specterDIY.getKeystore(PolicyType.SINGLE_HD, ScriptType.P2WPKH, getInputStream("specter-diy-keystore.txt"), null); Assertions.assertEquals("Specter DIY", keystore.getLabel()); Assertions.assertEquals("m/84'/1'/0'", keystore.getKeyDerivation().getDerivationPath()); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java index 1aa89cb6..1361a1d0 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java @@ -34,7 +34,7 @@ public class StorageTest extends IoTest { Keystore keystore = wallet.getKeystores().get(i); if(keystore.hasSeed()) { Keystore copyKeystore = copy.getKeystores().get(i); - Keystore derivedKeystore = Keystore.fromSeed(copyKeystore.getSeed(), copyKeystore.getKeyDerivation().getDerivation()); + Keystore derivedKeystore = Keystore.fromSeed(copyKeystore.getSeed(), wallet.getPolicyType(), copyKeystore.getKeyDerivation().getDerivation()); keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); keystore.getSeed().setPassphrase(copyKeystore.getSeed().getPassphrase()); diff --git a/src/test/resources/com/sparrowwallet/sparrow/io/cc-singlesig-sp-keystore-1.json b/src/test/resources/com/sparrowwallet/sparrow/io/cc-singlesig-sp-keystore-1.json new file mode 100644 index 00000000..58a00c43 --- /dev/null +++ b/src/test/resources/com/sparrowwallet/sparrow/io/cc-singlesig-sp-keystore-1.json @@ -0,0 +1,27 @@ +{ + "chain": "XTN", + "xfp": "0F056943", + "xpub": "tpubD6NzVbkrYhZ4XzL5Dhayo67Gorv1YMS7j8pRUvVMd5odC2LBPLAygka9p7748JtSq82FNGPppFEz5xxZUdasBRCqJqXvUHq6xpnsMcYJzeh", + "account": 0, + "bip84": { + "_pub": "vpub5Y5a91QvDT3yog4bmgbqFo7GPXpRpozogzQeDArSPzsY8SKGHTgjSswhxhGkRonUQ9tyo9ZSQ1ecLKkVUyewWEUJZdwgUQycvG86FV7sdhZ", + "deriv": "m/84'/1'/0'", + "first": "tb1qupyd58ndsh7lut0et0vtrq432jvu9jtdyws9n9", + "name": "p2wpkh", + "xfp": "AB82D43E", + "xpub": "tpubDC7jGaaSE66Pn4dgtbAAstde4bCyhSUs4r3P8WhMVvPByvcRrzrwqSvpF9Ghx83Z1LfVugGRrSBko5UEKELCz9HoMv5qKmGq3fqnnbS5E9r" + }, + "bip86": { + "deriv": "m/86'/1'/0'", + "first": "tb1prlna6c6us6jss2qyemcm8jpzjpuuyx46tz6pe80r6jmpf5dm3z7qnxwucf", + "name": "p2tr", + "xfp": "4A29873A", + "xpub": "tpubDCeEX49avtiXrBTv3JWTtco99Ka499jXdZHBRtm7va2gkMAui11ctZjqNAT9dLVNaEozt2C1kfTM88cnvZCXsWLJN2p4viGvsyGjtKVV7A1" + }, + "bip352": { + "spscan": "tspscan1q05wxw5wc7wqmkf8cnfc6ry76qej8vhr3a3mmxmwgv35s0tlw24fs82k0npv2hv6p97s8sd9t7vpf44kluka9w863zjwxzfrym2ay9ccfzt06c4", + "deriv": "m/352'/1'/0'", + "name": "p2tr", + "xfp": "2A21A78D" + } +}