diff --git a/drongo b/drongo index 9e5a7d0e..312143cb 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 9e5a7d0e8d31eb4e21d543081c23f7f0aaef9795 +Subproject commit 312143cb611fefce4e75654266f90cfd3b37b09e diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index d2d3eb63..8888e0a5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -4,14 +4,13 @@ import com.google.common.base.Charsets; import com.google.common.eventbus.Subscribe; import com.google.common.io.ByteSource; import com.sparrowwallet.drongo.Utils; -import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter; -import com.sparrowwallet.drongo.crypto.ECKey; -import com.sparrowwallet.drongo.crypto.InvalidPasswordException; +import com.sparrowwallet.drongo.crypto.*; import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTParseException; +import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.control.*; import com.sparrowwallet.sparrow.event.*; @@ -235,24 +234,65 @@ public class AppController implements Initializable { if(file != null) { try { Wallet wallet; + String password = null; ECKey encryptionPubKey = WalletForm.NO_PASSWORD_KEY; FileType fileType = IOUtils.getFileType(file); if(FileType.JSON.equals(fileType)) { wallet = Storage.getStorage().loadWallet(file); } else if(FileType.BINARY.equals(fileType)) { WalletPasswordDialog dlg = new WalletPasswordDialog(WalletPasswordDialog.PasswordRequirement.LOAD); - Optional password = dlg.showAndWait(); - if(!password.isPresent()) { + Optional optionalPassword = dlg.showAndWait(); + if(!optionalPassword.isPresent()) { return; } - ECKey encryptionFullKey = ECIESKeyCrypter.deriveECKey(password.get()); + password = optionalPassword.get(); + ECKey encryptionFullKey = ECIESKeyCrypter.deriveECKey(password); wallet = Storage.getStorage().loadWallet(file, encryptionFullKey); encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey); } else { throw new IOException("Unsupported file type"); } + if(wallet.containsSeeds()) { + //Derive xpub and master fingerprint from seed, potentially with passphrase + Wallet copy = wallet.copy(); + if(wallet.isEncrypted()) { + if(password == null) { + throw new IllegalStateException("Wallet seeds are encrypted but wallet is not"); + } + + copy.decrypt(password); + } + + for(Keystore copyKeystore : copy.getKeystores()) { + if(copyKeystore.hasSeed()) { + if(copyKeystore.getSeed().needsPassphrase()) { + KeystorePassphraseDialog passphraseDialog = new KeystorePassphraseDialog(copyKeystore); + Optional optionalPassphrase = passphraseDialog.showAndWait(); + if(optionalPassphrase.isPresent()) { + copyKeystore.getSeed().setPassphrase(optionalPassphrase.get()); + } else { + return; + } + } else { + copyKeystore.getSeed().setPassphrase(""); + } + } + } + + for(int i = 0; i < wallet.getKeystores().size(); i++) { + 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.setKeyDerivation(derivedKeystore.getKeyDerivation()); + keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); + keystore.getSeed().setPassphrase(copyKeystore.getSeed().getPassphrase()); + } + } + } + Tab tab = addWalletTab(file, encryptionPubKey, wallet); tabs.getSelectionModel().select(tab); } catch (InvalidPasswordException e) { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java index 8e1fbe18..c5371dec 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java @@ -55,19 +55,7 @@ public class FileWalletExportPane extends TitledDescriptionPane { WalletPasswordDialog dlg = new WalletPasswordDialog(WalletPasswordDialog.PasswordRequirement.LOAD); Optional password = dlg.showAndWait(); if(password.isPresent()) { - copy.decrypt(password.get(), ""); - - for(Keystore keystore : copy.getKeystores()) { - if(keystore.hasSeed() && keystore.getSeed().usesPassphrase()) { - KeystorePassphraseDialog passphraseDialog = new KeystorePassphraseDialog(keystore); - Optional passphrase = passphraseDialog.showAndWait(); - if(passphrase.isPresent()) { - keystore.getSeed().setPassphrase(passphrase.get()); - } else { - return; - } - } - } + copy.decrypt(password.get()); } else { return; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java b/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java index 34943f71..88ac40f6 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Bip39.java @@ -28,7 +28,7 @@ public class Bip39 implements KeystoreMnemonicImport { public Keystore getKeystore(List derivation, List mnemonicWords, String passphrase) throws ImportException { try { Bip39MnemonicCode.INSTANCE.check(mnemonicWords); - DeterministicSeed seed = new DeterministicSeed(mnemonicWords, null, passphrase, System.currentTimeMillis(), DeterministicSeed.Type.BIP39); + DeterministicSeed seed = new DeterministicSeed(mnemonicWords, passphrase, System.currentTimeMillis(), DeterministicSeed.Type.BIP39); return Keystore.fromSeed(seed, derivation); } catch (Exception e) { throw new ImportException(e); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java index c09c6797..0091b3e8 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java @@ -34,7 +34,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle @Override public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { InputStreamReader reader = new InputStreamReader(inputStream); - ColdcardKeystore cck = Storage.getStorage().getGson().fromJson(reader, ColdcardKeystore.class); + ColdcardKeystore cck = Storage.getGson().fromJson(reader, ColdcardKeystore.class); Keystore keystore = new Keystore("Coldcard " + cck.xfp); keystore.setSource(KeystoreSource.HW_AIRGAPPED); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ECIESInputStream.java b/src/main/java/com/sparrowwallet/sparrow/io/ECIESInputStream.java index 0c08667f..082d940a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ECIESInputStream.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ECIESInputStream.java @@ -43,7 +43,7 @@ public class ECIESInputStream extends FilterInputStream { byte[] encryptedBytes = ByteStreams.toByteArray(in); in.close(); ECIESKeyCrypter keyCrypter = new ECIESKeyCrypter(); - byte[] decryptedBytes = keyCrypter.decrypt(new EncryptedData(encryptionMagic, encryptedBytes), decryptionKey); + byte[] decryptedBytes = keyCrypter.decrypt(new EncryptedData(encryptionMagic, encryptedBytes, null), decryptionKey); in = new ByteArrayInputStream(decryptedBytes); decrypted = true; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java index 8a5f2a7b..4f6fb9da 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java @@ -112,17 +112,15 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport throw new ImportException("Electrum does not support exporting BIP39 derived seeds."); } else if(ek.seed != null) { keystore.setSource(KeystoreSource.SW_SEED); - String seed = ek.seed; + String mnemonic = ek.seed; String passphrase = ek.passphrase; if(password != null) { - seed = decrypt(seed, password); + mnemonic = decrypt(mnemonic, password); passphrase = decrypt(passphrase, password); } - keystore.setSeed(new DeterministicSeed(seed, null, passphrase, 0, DeterministicSeed.Type.ELECTRUM)); - keystore.getSeed().setPassphrase(passphrase); - - if(derivationPath == "m/0") { + keystore.setSeed(new DeterministicSeed(mnemonic, passphrase, 0, DeterministicSeed.Type.ELECTRUM)); + if(derivationPath.equals("m/0")) { derivationPath = "m/0'"; } } else { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java index 3437763a..a8272439 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java @@ -4,6 +4,7 @@ import com.google.gson.*; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; import java.io.*; @@ -20,12 +21,7 @@ public class Storage { private final Gson gson; private Storage() { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeySerializer()); - gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeyDeserializer()); - gsonBuilder.registerTypeAdapter(byte[].class, new ByteArraySerializer()); - gsonBuilder.registerTypeAdapter(byte[].class, new ByteArrayDeserializer()); - gson = gsonBuilder.setPrettyPrinting().disableHtmlEscaping().create(); + gson = getGson(); } public static Storage getStorage() { @@ -36,8 +32,21 @@ public class Storage { return SINGLETON; } - public Gson getGson() { - return gson; + public static Gson getGson() { + return getGson(true); + } + + private static Gson getGson(boolean includeKeystoreSerializer) { + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeySerializer()); + gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeyDeserializer()); + gsonBuilder.registerTypeAdapter(byte[].class, new ByteArraySerializer()); + gsonBuilder.registerTypeAdapter(byte[].class, new ByteArrayDeserializer()); + if(includeKeystoreSerializer) { + gsonBuilder.registerTypeAdapter(Keystore.class, new KeystoreSerializer()); + } + + return gsonBuilder.setPrettyPrinting().disableHtmlEscaping().create(); } public Wallet loadWallet(File file) throws IOException { @@ -150,4 +159,18 @@ public class Storage { return Utils.hexToBytes(json.getAsJsonPrimitive().getAsString()); } } + + private static class KeystoreSerializer implements JsonSerializer { + @Override + public JsonElement serialize(Keystore keystore, Type typeOfSrc, JsonSerializationContext context) { + + JsonObject jsonObject = (JsonObject)getGson(false).toJsonTree(keystore); + if(keystore.hasSeed()) { + jsonObject.remove("extendedPublicKey"); + jsonObject.getAsJsonObject("keyDerivation").remove("masterFingerprint"); + } + + return jsonObject; + } + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java index 75c21ce2..1143ea5b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java @@ -152,7 +152,6 @@ public class KeystoreController extends WalletFormController implements Initiali type.setText(getTypeLabel(keystore)); boolean editable = (keystore.getSource() == KeystoreSource.SW_WATCH); - label.setEditable(editable); fingerprint.setEditable(editable); derivation.setEditable(editable); xpub.setEditable(editable); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java index 59924ea1..83b07b88 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java @@ -88,7 +88,7 @@ public class ColdcardMultisigTest extends IoTest { Assert.assertEquals("m/48'/0'/0'/2'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath()); Assert.assertEquals("xpub6EfEGa5isJbQFSswM5Uptw5BSq2Td1ZDJr3QUNUcMySpC7itZ3ccypVHtLPnvMzKQ2qxrAgH49vhVxRcaQLFbixAVRR8RACrYTp88Uv9h8Z", wallet.getKeystores().get(0).getExtendedPublicKey().toString()); Assert.assertEquals("ca9a2b19", wallet.getKeystores().get(2).getKeyDerivation().getMasterFingerprint()); - Assert.assertEquals("m/48'/0'/0'/1'", wallet.getKeystores().get(2).getKeyDerivation().getDerivationPath()); + Assert.assertEquals("m/47'/0'/0'/1'", wallet.getKeystores().get(2).getKeyDerivation().getDerivationPath()); Assert.assertTrue(wallet.isValid()); } diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ECIESInputStreamTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ECIESInputStreamTest.java deleted file mode 100644 index 30b9c323..00000000 --- a/src/test/java/com/sparrowwallet/sparrow/io/ECIESInputStreamTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sparrowwallet.sparrow.io; - -import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter; -import com.sparrowwallet.drongo.crypto.ECKey; -import com.sparrowwallet.drongo.policy.PolicyType; -import com.sparrowwallet.drongo.protocol.ScriptType; -import com.sparrowwallet.drongo.wallet.Wallet; -import org.junit.Assert; -import org.junit.Test; - -import java.util.zip.InflaterInputStream; - -public class ECIESInputStreamTest extends IoTest { - @Test - public void decrypt() throws ImportException { - Electrum electrum = new Electrum(); - ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass"); - Wallet wallet = electrum.importWallet(new InflaterInputStream(new ECIESInputStream(getInputStream("electrum-encrypted"), decryptionKey)), null); - - Assert.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); - Assert.assertEquals(ScriptType.P2WPKH, wallet.getScriptType()); - Assert.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); - Assert.assertEquals("pkh(electrum05aba071)", wallet.getDefaultPolicy().getMiniscript().getScript()); - Assert.assertEquals("05aba071", wallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint()); - Assert.assertEquals("m/0'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath()); - Assert.assertEquals("xpub67vv394epQsLhdjNGx7dfgURicP7XwBMuHPTVAMdXcXhDuC9VP8SqVvh2cYqKWm9xoUd6YynWK8JzRcXpmeuZFRH7i1kt8fR9GXoJSiHk1E", wallet.getKeystores().get(0).getExtendedPublicKey().toString()); - Assert.assertTrue(wallet.isValid()); - } -} diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ECIESOutputStreamTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ECIESOutputStreamTest.java deleted file mode 100644 index f446ddaf..00000000 --- a/src/test/java/com/sparrowwallet/sparrow/io/ECIESOutputStreamTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.sparrowwallet.sparrow.io; - -import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter; -import com.sparrowwallet.drongo.crypto.ECKey; -import com.sparrowwallet.drongo.policy.PolicyType; -import com.sparrowwallet.drongo.protocol.ScriptType; -import com.sparrowwallet.drongo.wallet.Wallet; -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.InflaterInputStream; - -public class ECIESOutputStreamTest extends IoTest { - @Test - public void encrypt() throws ImportException, ExportException { - Electrum electrum = new Electrum(); - ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass"); - Wallet wallet = electrum.importWallet(new InflaterInputStream(new ECIESInputStream(getInputStream("electrum-encrypted"), decryptionKey)), null); - - ECKey encyptionKey = ECKey.fromPublicOnly(decryptionKey); - ByteArrayOutputStream dummyFileOutputStream = new ByteArrayOutputStream(); - electrum.exportWallet(wallet, new DeflaterOutputStream(new ECIESOutputStream(dummyFileOutputStream, encyptionKey))); - - ByteArrayInputStream dummyFileInputStream = new ByteArrayInputStream(dummyFileOutputStream.toByteArray()); - wallet = electrum.importWallet(new InflaterInputStream(new ECIESInputStream(dummyFileInputStream, decryptionKey)), null); - - Assert.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); - Assert.assertEquals(ScriptType.P2WPKH, wallet.getScriptType()); - Assert.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); - Assert.assertEquals("pkh(electrum05aba071)", wallet.getDefaultPolicy().getMiniscript().getScript()); - Assert.assertEquals("05aba071", wallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint()); - Assert.assertEquals("m/0'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath()); - Assert.assertEquals("xpub67vv394epQsLhdjNGx7dfgURicP7XwBMuHPTVAMdXcXhDuC9VP8SqVvh2cYqKWm9xoUd6YynWK8JzRcXpmeuZFRH7i1kt8fR9GXoJSiHk1E", wallet.getKeystores().get(0).getExtendedPublicKey().toString()); - Assert.assertTrue(wallet.isValid()); - } -} diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java index a8350d5c..2d08ab00 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java @@ -4,6 +4,7 @@ import com.google.common.io.ByteStreams; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.wallet.MnemonicException; import com.sparrowwallet.drongo.wallet.Wallet; import org.junit.Assert; import org.junit.Test; @@ -102,7 +103,7 @@ public class ElectrumTest extends IoTest { } @Test - public void testSinglesigSeedExport() throws ImportException, ExportException, IOException { + public void testSinglesigSeedExport() throws ImportException, ExportException, IOException, MnemonicException { Electrum electrum = new Electrum(); byte[] walletBytes = ByteStreams.toByteArray(getInputStream("electrum-singlesig-seed-wallet.json")); Wallet wallet = electrum.importWallet(new ByteArrayInputStream(walletBytes), null); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java index e041a45d..6bf43ab0 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java @@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.wallet.MnemonicException; import com.sparrowwallet.drongo.wallet.Wallet; import org.junit.Assert; import org.junit.Test; @@ -20,7 +21,7 @@ public class StorageTest extends IoTest { } @Test - public void loadSeedWallet() throws IOException { + public void loadSeedWallet() throws IOException, MnemonicException { ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass"); Wallet wallet = Storage.getStorage().loadWallet(getFile("sparrow-single-seed-wallet"), decryptionKey); @@ -34,7 +35,7 @@ public class StorageTest extends IoTest { Assert.assertEquals("60bcd3a7", wallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint()); Assert.assertEquals("m/84'/0'/0'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath()); Assert.assertEquals("xpub6BrhGFTWPd3DQaGP7p5zTQkE5nqVbaRs23HNae8jAoNJYS2NGa9Sgpeqv1dS5ygwD4sQfwqLCk5qXRK45FTgnqHRcrPnts3Qgh78BZrnoMn", wallet.getKeystores().get(0).getExtendedPublicKey().toString()); - Assert.assertEquals("b0e161bff5f589e74b20d9cd260702a6a1e6e1ab3ba4ce764f388dd8f360a1ccdb21099a2f22757ca72f9bde3a34b97a31fb513fb8931c821b0d25798e450b6a57dc106973849ca586b50b2db2840adc", Utils.bytesToHex(wallet.getKeystores().get(0).getSeed().getEncryptedSeedData().getEncryptedBytes())); + Assert.assertEquals("a48767d6b58732a0cad17ed93e23022ec603a177e75461f2aed994713fbbe532b61f6c0758a8aedcf9b2b8102c01c6f3e3e212ca06f13644d4ac8dad66556e164b7eaf79d0b42eadecee8b735e97fc0a", Utils.bytesToHex(wallet.getKeystores().get(0).getSeed().getEncryptedData().getEncryptedBytes())); Assert.assertNull(wallet.getKeystores().get(0).getSeed().getSeedBytes()); } diff --git a/src/test/resources/com/sparrowwallet/sparrow/io/cc-multisig-export-multideriv.txt b/src/test/resources/com/sparrowwallet/sparrow/io/cc-multisig-export-multideriv.txt index a667731f..08c82d41 100644 --- a/src/test/resources/com/sparrowwallet/sparrow/io/cc-multisig-export-multideriv.txt +++ b/src/test/resources/com/sparrowwallet/sparrow/io/cc-multisig-export-multideriv.txt @@ -9,6 +9,6 @@ Format: P2WSH # derivation: m/48'/0'/0'/2' 4B569672: xpub6FFEQVG6QR28giDuML74Y7EMPwqEiKftNjScLzg5WKM41bf6LMP2XspjBgNp28tvkNUZdokmTY4TcRbuGZBSMvNoUECrKW1y3TBPeQJVmAg -# derivation: m/48'/0'/0'/1' +# derivation: m/47'/0'/0'/1' CA9A2B19: xpub6Eb6Z1xtmWRiWKgRpHf6dHiEagGd6FLiBXrnma1nFK4PGRYqSVqVyJaxna5Mb8etSP4ATKVAvKnXG1a9HZauoAawuSDJT5RgH2HqEVHZVHY