From 8780e515d58684d52ad8d20c413579be5336d0a3 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 21 Apr 2026 11:34:14 +0200 Subject: [PATCH] initial policy type related changes from drongo --- drongo | 2 +- .../sparrowwallet/sparrow/AppController.java | 4 ++-- .../com/sparrowwallet/sparrow/AppServices.java | 6 +++--- .../sparrowwallet/sparrow/BaseController.java | 3 ++- .../sparrow/control/DevicePane.java | 10 +++++----- .../control/FileWalletKeystoreImportPane.java | 14 +++++++------- .../sparrow/control/MessageSignDialog.java | 14 ++++++-------- .../MnemonicWalletKeystoreImportPane.java | 10 +++++----- .../sparrow/control/PrivateKeySweepDialog.java | 16 ++++++++-------- .../sparrow/control/WalletExportDialog.java | 2 ++ .../sparrow/io/CaravanMultisig.java | 6 +++--- .../sparrow/io/CoboVaultSinglesig.java | 4 ++-- .../sparrow/io/ColdcardMultisig.java | 6 +++--- .../sparrow/io/ColdcardSinglesig.java | 4 ++-- .../com/sparrowwallet/sparrow/io/Electrum.java | 18 +++++++++--------- .../sparrow/io/ElectrumPersonalServer.java | 4 ++++ .../sparrow/io/KeystoneSinglesig.java | 5 ++--- .../com/sparrowwallet/sparrow/io/Storage.java | 3 +++ .../sparrow/io/ckcard/CkCardApi.java | 3 ++- .../sparrowwallet/sparrow/net/LnurlAuth.java | 4 ++-- .../sparrow/net/VersionCheckService.java | 3 ++- .../sparrow/terminal/wallet/Bip39Dialog.java | 6 +++--- .../terminal/wallet/SettingsDialog.java | 2 +- .../terminal/wallet/WatchOnlyDialog.java | 4 ++-- .../sparrow/transaction/HeadersController.java | 2 +- .../sparrow/wallet/PaymentController.java | 3 +-- .../sparrow/io/CaravanMultisigTest.java | 2 +- .../sparrow/io/ColdcardMultisigTest.java | 6 +++--- .../sparrowwallet/sparrow/io/ElectrumTest.java | 12 ++++++------ .../sparrow/io/SpecterDesktopTest.java | 4 ++-- .../sparrowwallet/sparrow/io/StorageTest.java | 2 +- 31 files changed, 96 insertions(+), 88 deletions(-) diff --git a/drongo b/drongo index dad9fe2f..15e5aaa4 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit dad9fe2fccda624566e44324d0da42a3423f8e6e +Subproject commit 15e5aaa4b9846c7d410723a7785198c62ef66248 diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index d6fec7e7..3f972f69 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -1121,7 +1121,7 @@ public class AppController implements Initializable { WalletNameDialog.NameAndBirthDate nameAndBirthDate = optNameAndBirthDate.get(); File walletFile = Storage.getWalletFile(nameAndBirthDate.getName()); Storage storage = new Storage(walletFile); - Wallet wallet = new Wallet(nameAndBirthDate.getName(), PolicyType.SINGLE, ScriptType.P2WPKH, nameAndBirthDate.getBirthDate()); + Wallet wallet = new Wallet(nameAndBirthDate.getName(), PolicyType.SINGLE_HD, ScriptType.P2WPKH, nameAndBirthDate.getBirthDate()); addWalletTabOrWindow(storage, wallet, false); } } @@ -1271,7 +1271,7 @@ public class AppController implements Initializable { List xpubs = wallet.getKeystores().stream().map(Keystore::getExtendedPublicKey).collect(Collectors.toList()); Optional optNewWalletForm = walletTabData.stream() .map(WalletTabData::getWalletForm) - .filter(wf -> wf.getSettingsWalletForm() != null && wf.getSettingsWalletForm().getWallet().getPolicyType() == PolicyType.MULTI && + .filter(wf -> wf.getSettingsWalletForm() != null && wf.getSettingsWalletForm().getWallet().getPolicyType() == PolicyType.MULTI_HD && wf.getSettingsWalletForm().getWallet().getScriptType() == wallet.getScriptType() && !wf.getSettingsWalletForm().getWallet().isValid() && wf.getSettingsWalletForm().getWallet().getKeystores().stream().map(Keystore::getExtendedPublicKey).anyMatch(xpubs::contains)).findFirst(); if(optNewWalletForm.isPresent()) { diff --git a/src/main/java/com/sparrowwallet/sparrow/AppServices.java b/src/main/java/com/sparrowwallet/sparrow/AppServices.java index ec4fafb8..b0a111b9 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppServices.java @@ -1077,7 +1077,7 @@ public class AppServices { try { Auth47 auth47 = new Auth47(uri); List scriptTypes = PaymentCode.SEGWIT_SCRIPT_TYPES; - Wallet wallet = selectWallet(List.of(PolicyType.SINGLE), scriptTypes, false, true, "login to " + auth47.getCallback().getHost(), true); + Wallet wallet = selectWallet(List.of(PolicyType.SINGLE_HD), scriptTypes, false, true, "login to " + auth47.getCallback().getHost(), true); if(wallet != null) { try { @@ -1097,8 +1097,8 @@ public class AppServices { private static void openLnurlAuthUri(URI uri) { try { LnurlAuth lnurlAuth = new LnurlAuth(uri); - List scriptTypes = ScriptType.getAddressableScriptTypes(PolicyType.SINGLE); - Wallet wallet = selectWallet(List.of(PolicyType.SINGLE), scriptTypes, true, true, lnurlAuth.getLoginMessage(), true); + List scriptTypes = ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD); + Wallet wallet = selectWallet(List.of(PolicyType.SINGLE_HD), scriptTypes, true, true, lnurlAuth.getLoginMessage(), true); if(wallet != null) { if(wallet.isEncrypted()) { diff --git a/src/main/java/com/sparrowwallet/sparrow/BaseController.java b/src/main/java/com/sparrowwallet/sparrow/BaseController.java index 7263ef2a..cee2d979 100644 --- a/src/main/java/com/sparrowwallet/sparrow/BaseController.java +++ b/src/main/java/com/sparrowwallet/sparrow/BaseController.java @@ -55,7 +55,8 @@ public abstract class BaseController { descriptorArea.setMouseOverTextDelay(Duration.ofMillis(150)); descriptorArea.addEventHandler(MouseOverTextEvent.MOUSE_OVER_TEXT_BEGIN, e -> { TwoDimensional.Position position = descriptorArea.getParagraph(0).getStyleSpans().offsetToPosition(e.getCharacterIndex(), Backward); - int index = descriptorArea.getWallet().getPolicyType() == PolicyType.SINGLE ? position.getMajor() - 1 : ((position.getMajor() - 1) / 2); + int index = descriptorArea.getWallet().getPolicyType() == PolicyType.SINGLE || descriptorArea.getWallet().getPolicyType() == PolicyType.SINGLE_SILENT_PAYMENTS ? + position.getMajor() - 1 : ((position.getMajor() - 1) / 2); if(position.getMajor() > 0 && index >= 0 && index < descriptorArea.getWallet().getKeystores().size()) { Keystore hoverKeystore = descriptorArea.getWallet().getKeystores().get(index); Point2D pos = e.getScreenPosition(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java b/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java index 0a5d98c5..06ca959c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/DevicePane.java @@ -775,10 +775,10 @@ public class DevicePane extends TitledDescriptionPane { if(wallet.getScriptType() == null) { ScriptType scriptType = Arrays.stream(ScriptType.ADDRESSABLE_TYPES).filter(type -> type.getDefaultDerivation().get(0).equals(derivation.get(0))).findFirst().orElse(ScriptType.P2PKH); wallet.setName(device.getModel().toDisplayString()); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), null)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, scriptType, wallet.getKeystores(), null)); EventManager.get().post(new WalletImportEvent(wallet)); } else { @@ -926,7 +926,7 @@ public class DevicePane extends TitledDescriptionPane { List discoveryAccounts = new ArrayList<>(Arrays.asList(StandardAccount.values()).subList(0, optRange.get() + 1)); Map derivationPaths = new LinkedHashMap<>(); - List scriptTypes = new ArrayList<>(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE)); + List scriptTypes = new ArrayList<>(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD)); if(device.getModel() == WalletModel.BITBOX_02) { scriptTypes.remove(ScriptType.P2PKH); } @@ -943,7 +943,7 @@ public class DevicePane extends TitledDescriptionPane { for(Map.Entry entry : accountXpubs.entrySet()) { try { Wallet wallet = new Wallet(device.getModel().toDisplayString()); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(entry.getKey().scriptType()); Keystore keystore = new Keystore(); keystore.setLabel(device.getModel().toDisplayString()); @@ -952,7 +952,7 @@ public class DevicePane extends TitledDescriptionPane { keystore.setKeyDerivation(new KeyDerivation(device.getFingerprint(), derivationPaths.get(entry.getKey()))); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(entry.getValue())); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, entry.getKey().scriptType(), wallet.getKeystores(), 1)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, entry.getKey().scriptType(), wallet.getKeystores(), 1)); if(entry.getKey().standardAccount().equals(StandardAccount.ACCOUNT_0)) { wallets.add(wallet); } else { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java index c1a0e1b5..ca0be683 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java @@ -50,12 +50,12 @@ public class FileWalletKeystoreImportPane extends FileImportPane { this.fileName = fileName; this.password = password; - List scriptTypes = ScriptType.getAddressableScriptTypes(PolicyType.SINGLE); + List scriptTypes = ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD); if(wallets != null && !wallets.isEmpty()) { if(wallets.size() == 1 && scriptTypes.contains(wallets.get(0).getScriptType())) { Wallet wallet = wallets.get(0); - wallet.setPolicyType(PolicyType.SINGLE); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, wallet.getScriptType(), wallet.getKeystores(), null)); + wallet.setPolicyType(PolicyType.SINGLE_HD); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, wallet.getScriptType(), wallet.getKeystores(), null)); wallet.setName(importer.getName()); EventManager.get().post(new WalletImportEvent(wallets.get(0))); } else { @@ -81,8 +81,8 @@ public class FileWalletKeystoreImportPane extends FileImportPane { if(wallets != null && !wallets.isEmpty()) { Wallet wallet = wallets.stream().filter(wallet1 -> wallet1.getScriptType() == scriptType).findFirst().orElseThrow(ImportException::new); wallet.setName(importer.getName()); - wallet.setPolicyType(PolicyType.SINGLE); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, wallet.getScriptType(), wallet.getKeystores(), null)); + wallet.setPolicyType(PolicyType.SINGLE_HD); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, wallet.getScriptType(), wallet.getKeystores(), null)); EventManager.get().post(new WalletImportEvent(wallet)); } else { ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes); @@ -90,10 +90,10 @@ public class FileWalletKeystoreImportPane extends FileImportPane { Wallet wallet = new Wallet(); wallet.setName(Files.getNameWithoutExtension(fileName)); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), null)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, scriptType, wallet.getKeystores(), null)); EventManager.get().post(new WalletImportEvent(wallet)); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java index 3a6864eb..360d333a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java @@ -25,8 +25,6 @@ import com.sparrowwallet.sparrow.io.Storage; import javafx.application.Platform; import javafx.scene.Node; import javafx.scene.control.*; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import javafx.stage.Stage; @@ -297,8 +295,8 @@ public class MessageSignDialog extends Dialog { } private void checkWalletSigning(Wallet wallet) { - if(wallet.getKeystores().size() != 1) { - throw new IllegalArgumentException("Cannot sign messages using a wallet with multiple keystores - a single key is required"); + if(wallet.getKeystores().size() != 1 || wallet.getPolicyType() != PolicyType.SINGLE_HD) { + throw new IllegalArgumentException("Cannot sign messages using a non-HD wallet or a wallet with multiple keystores"); } } @@ -323,7 +321,7 @@ public class MessageSignDialog extends Dialog { private boolean isValidAddress() { try { Address address = getAddress(); - return address.getScriptType().isAllowed(PolicyType.SINGLE) || address.getScriptType() == ScriptType.P2SH; + return address.getScriptType().isAllowed(PolicyType.SINGLE_HD) || address.getScriptType() == ScriptType.P2SH; } catch (InvalidAddressException e) { return false; } @@ -466,11 +464,11 @@ public class MessageSignDialog extends Dialog { if(scriptType == ScriptType.P2SH) { scriptType = ScriptType.P2SH_P2WPKH; } - if(!ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE).contains(scriptType)) { + if(!ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE_HD).contains(scriptType)) { throw new IllegalArgumentException("Only single signature P2PKH, P2SH-P2WPKH or P2WPKH addresses can verify messages."); } - Address signedMessageAddress = scriptType.getAddress(signedMessageKey); + Address signedMessageAddress = scriptType.getAddress(PolicyType.SINGLE_HD, signedMessageKey); return providedAddress.equals(signedMessageAddress); } @@ -527,7 +525,7 @@ public class MessageSignDialog extends Dialog { psbtInput.setTapInternalKey(pubKey); psbtInput.getTapDerivedPublicKeys().put(ECKey.fromPublicOnly(pubKey.getPubKeyXCoord()), Map.of(fullDerivation, Collections.emptyList())); } else { - psbtInput.getDerivedPublicKeys().put(scriptType.getOutputKey(pubKey), fullDerivation); + psbtInput.getDerivedPublicKeys().put(scriptType.getOutputKey(signingWallet.getPolicyType(), pubKey), fullDerivation); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java index 494f8eba..b361eaf7 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicWalletKeystoreImportPane.java @@ -108,11 +108,11 @@ public class MnemonicWalletKeystoreImportPane extends MnemonicKeystorePane { discoverButton.setGraphic(progressIndicator); List wallets = new ArrayList<>(); - List> derivations = ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE).stream().map(ScriptType::getDefaultDerivation).collect(Collectors.toList()); + List> derivations = ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE_HD).stream().map(ScriptType::getDefaultDerivation).collect(Collectors.toList()); derivations.add(List.of(new ChildNumber(0, true))); derivations.add(ScriptType.P2PKH.getDefaultDerivation(1)); //Bisq segwit misderivation - for(ScriptType scriptType : ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE)) { + for(ScriptType scriptType : ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE_HD)) { for(List derivation : derivations) { try { Wallet wallet = getWallet(scriptType, derivation); @@ -165,11 +165,11 @@ public class MnemonicWalletKeystoreImportPane extends MnemonicKeystorePane { private Wallet getWallet(ScriptType scriptType, List derivation) throws ImportException { Wallet wallet = new Wallet(""); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType); Keystore keystore = importer.getKeystore(derivation, wordEntriesProperty.get(), passphraseProperty.get()); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), 1)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, scriptType, wallet.getKeystores(), 1)); return wallet; } @@ -178,7 +178,7 @@ public class MnemonicWalletKeystoreImportPane extends MnemonicKeystorePane { HBox fieldBox = new HBox(5); fieldBox.setAlignment(Pos.CENTER_RIGHT); - ComboBox scriptTypeComboBox = new ComboBox<>(FXCollections.observableArrayList(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE))); + ComboBox scriptTypeComboBox = new ComboBox<>(FXCollections.observableArrayList(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD))); if(scriptTypeComboBox.getItems().contains(ScriptType.P2WPKH)) { scriptTypeComboBox.setValue(ScriptType.P2WPKH); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java index 2f0da1bf..912d3a82 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java @@ -109,7 +109,7 @@ public class PrivateKeySweepDialog extends Dialog { Field keyScriptTypeField = new Field(); keyScriptTypeField.setText("Script Type:"); keyScriptType = new ComboBox<>(); - keyScriptType.setItems(FXCollections.observableList(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE))); + keyScriptType.setItems(FXCollections.observableList(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD))); keyScriptTypeField.getInputs().add(keyScriptType); keyScriptType.setConverter(new StringConverter() { @@ -287,14 +287,14 @@ public class PrivateKeySweepDialog extends Dialog { private void setFromAddress() { DumpedPrivateKey privateKey = getPrivateKey(); ScriptType scriptType = keyScriptType.getValue(); - Address address = scriptType.getAddress(privateKey.getKey()); + Address address = scriptType.getAddress(PolicyType.SINGLE_HD, privateKey.getKey()); keyAddress.setText(address.toString()); } private void setScriptTypes(boolean isValidKey) { boolean compressed = !isValidKey || getPrivateKey().getKey().isCompressed(); - if(compressed && !keyScriptType.getItems().equals(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE))) { - keyScriptType.getItems().addAll(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE).stream().filter(s -> !keyScriptType.getItems().contains(s)).collect(Collectors.toList())); + if(compressed && !keyScriptType.getItems().equals(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD))) { + keyScriptType.getItems().addAll(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD).stream().filter(s -> !keyScriptType.getItems().contains(s)).collect(Collectors.toList())); } else if(!compressed && !keyScriptType.getItems().equals(List.of(ScriptType.P2PKH))) { keyScriptType.getSelectionModel().select(0); keyScriptType.getItems().removeIf(scriptType -> scriptType != ScriptType.P2PKH); @@ -346,7 +346,7 @@ public class PrivateKeySweepDialog extends Dialog { try { DumpedPrivateKey privateKey = getPrivateKey(); ScriptType scriptType = keyScriptType.getValue(); - Address fromAddress = scriptType.getAddress(privateKey.getKey()); + Address fromAddress = scriptType.getAddress(PolicyType.SINGLE_HD, privateKey.getKey()); Address destAddress = getToAddress(); Date since = null; @@ -389,7 +389,7 @@ public class PrivateKeySweepDialog extends Dialog { Transaction noFeeTransaction = new Transaction(); long total = 0; for(TransactionOutput txOutput : txOutputs) { - scriptType.addSpendingInput(noFeeTransaction, txOutput, pubKey, TransactionSignature.dummy(scriptType == P2TR ? TransactionSignature.Type.SCHNORR : TransactionSignature.Type.ECDSA)); + scriptType.addSpendingInput(PolicyType.SINGLE_HD, noFeeTransaction, txOutput, pubKey, TransactionSignature.dummy(scriptType == P2TR ? TransactionSignature.Type.SCHNORR : TransactionSignature.Type.ECDSA)); total += txOutput.getValue(); } @@ -448,7 +448,7 @@ public class PrivateKeySweepDialog extends Dialog { psbtInput.setWitnessScript(txInput.getWitness().getWitnessScript()); } - if(!psbtInput.sign(scriptType.getOutputKey(privKey))) { + if(!psbtInput.sign(scriptType.getOutputKey(PolicyType.SINGLE_HD, privKey))) { AppServices.showErrorDialog("Failed to sign", "Failed to sign for transaction output " + utxoOutput.getHash() + ":" + utxoOutput.getIndex()); return; } @@ -456,7 +456,7 @@ public class PrivateKeySweepDialog extends Dialog { TransactionSignature signature = psbtInput.isTaproot() ? psbtInput.getTapKeyPathSignature() : psbtInput.getPartialSignature(pubKey); Transaction finalizeTransaction = new Transaction(); - TransactionInput finalizedTxInput = scriptType.addSpendingInput(finalizeTransaction, utxoOutput, pubKey, signature); + TransactionInput finalizedTxInput = scriptType.addSpendingInput(PolicyType.SINGLE_HD, finalizeTransaction, utxoOutput, pubKey, signature); psbtInput.setFinalScriptSig(finalizedTxInput.getScriptSig()); psbtInput.setFinalScriptWitness(finalizedTxInput.getWitness()); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/WalletExportDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/WalletExportDialog.java index dc96f8be..82d12a90 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/WalletExportDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/WalletExportDialog.java @@ -49,6 +49,8 @@ public class WalletExportDialog extends Dialog { } else if(wallet.getPolicyType() == PolicyType.MULTI) { exporters = List.of(new Bip129(), new CaravanMultisig(), new ColdcardMultisig(), new CoboVaultMultisig(), new Electrum(), new ElectrumPersonalServer(), new KeystoneMultisig(), new Descriptor(), new JadeMultisig(), new PassportMultisig(), new SpecterDesktop(), new BlueWalletMultisig(), new SpecterDIY(), new Sparrow(), new WalletLabels(allWalletForms), new WalletTransactions(selectedWalletForm)); + } else if(wallet.getPolicyType() == PolicyType.SINGLE_SILENT_PAYMENTS) { + exporters = List.of(new Sparrow(), new WalletLabels(allWalletForms), new WalletTransactions(selectedWalletForm)); } else { throw new UnsupportedOperationException("Cannot export wallet with policy type " + wallet.getPolicyType()); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/CaravanMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/CaravanMultisig.java index 4fe7b9ce..e4ceca65 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/CaravanMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/CaravanMultisig.java @@ -49,7 +49,7 @@ public class CaravanMultisig implements WalletImport, WalletExport { Wallet wallet = new Wallet(); wallet.setName(cf.name); - wallet.setPolicyType(PolicyType.MULTI); + wallet.setPolicyType(PolicyType.MULTI_HD); ScriptType scriptType = ScriptType.valueOf(cf.addressType.replace('-', '_')); for(ExtPublicKey extKey : cf.extendedPublicKeys) { @@ -80,7 +80,7 @@ public class CaravanMultisig implements WalletImport, WalletExport { } wallet.setScriptType(scriptType); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), cf.quorum.requiredSigners)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI_HD, scriptType, wallet.getKeystores(), cf.quorum.requiredSigners)); return wallet; } catch(Exception e) { @@ -99,7 +99,7 @@ public class CaravanMultisig implements WalletImport, WalletExport { throw new ExportException("Cannot export an incomplete wallet"); } - if(!wallet.getPolicyType().equals(PolicyType.MULTI)) { + if(!wallet.getPolicyType().equals(PolicyType.MULTI_HD)) { throw new ExportException(getName() + " import requires a multisig wallet"); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java index 7e302c16..bc50c8e4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/CoboVaultSinglesig.java @@ -73,10 +73,10 @@ public class CoboVaultSinglesig implements KeystoreFileImport, WalletImport { Keystore keystore = getKeystore(ScriptType.P2WPKH, inputStream, ""); Wallet wallet = new Wallet(); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(ScriptType.P2WPKH); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), null)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, ScriptType.P2WPKH, wallet.getKeystores(), null)); try { wallet.checkWallet(); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java index c21a75b9..91660c57 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java @@ -119,7 +119,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle @Override public Wallet importWallet(InputStream inputStream, String password) throws ImportException { Wallet wallet = new Wallet(); - wallet.setPolicyType(PolicyType.MULTI); + wallet.setPolicyType(PolicyType.MULTI_HD); int threshold = 2; ScriptType scriptType = ScriptType.P2SH; @@ -167,7 +167,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle } - Policy policy = Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), threshold); + Policy policy = Policy.getPolicy(PolicyType.MULTI_HD, scriptType, wallet.getKeystores(), threshold); wallet.setDefaultPolicy(policy); wallet.setScriptType(scriptType); @@ -194,7 +194,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle throw new ExportException("Cannot export an incomplete wallet"); } - if(!wallet.getPolicyType().equals(PolicyType.MULTI)) { + if(!wallet.getPolicyType().equals(PolicyType.MULTI_HD)) { throw new ExportException(getName() + " import requires a multisig wallet"); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java index 0c95d335..df80e8c2 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java @@ -104,10 +104,10 @@ public class ColdcardSinglesig implements KeystoreFileImport, WalletImport { Keystore keystore = getKeystore(ScriptType.P2WPKH, inputStream, ""); Wallet wallet = new Wallet(); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(ScriptType.P2WPKH); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), null)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, ScriptType.P2WPKH, wallet.getKeystores(), null)); try { wallet.checkWallet(); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java index a8d995d1..4e78ad7f 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java @@ -43,7 +43,7 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { Wallet wallet = importWallet(inputStream, password); - if(!wallet.getPolicyType().equals(PolicyType.SINGLE) || wallet.getKeystores().size() != 1) { + if(!wallet.getPolicyType().equals(PolicyType.SINGLE_HD) || wallet.getKeystores().size() != 1) { throw new ImportException("Multisig wallet detected - import it using File > Import Wallet"); } @@ -203,13 +203,13 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport wallet.setScriptType(scriptType); if(ew.wallet_type.equals("standard")) { - wallet.setPolicyType(PolicyType.SINGLE); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), 1)); + wallet.setPolicyType(PolicyType.SINGLE_HD); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, scriptType, wallet.getKeystores(), 1)); } else if(ew.wallet_type.contains("of")) { - wallet.setPolicyType(PolicyType.MULTI); + wallet.setPolicyType(PolicyType.MULTI_HD); String[] mOfn = ew.wallet_type.split("of"); int threshold = Integer.parseInt(mOfn[0]); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), threshold)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI_HD, scriptType, wallet.getKeystores(), threshold)); } else { throw new ImportException("Unknown Electrum wallet type of " + ew.wallet_type); } @@ -308,9 +308,9 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport public void exportWallet(Wallet wallet, OutputStream outputStream, String password) throws ExportException { try { ElectrumJsonWallet ew = new ElectrumJsonWallet(); - if(wallet.getPolicyType().equals(PolicyType.SINGLE)) { + if(wallet.getPolicyType().equals(PolicyType.SINGLE_HD)) { ew.wallet_type = "standard"; - } else if(wallet.getPolicyType().equals(PolicyType.MULTI)) { + } else if(wallet.getPolicyType().equals(PolicyType.MULTI_HD)) { ew.wallet_type = wallet.getDefaultPolicy().getNumSignaturesRequired() + "of" + wallet.getKeystores().size(); } else { throw new ExportException("Could not export a wallet with a " + wallet.getPolicyType() + " policy"); @@ -367,9 +367,9 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport throw new ExportException("Cannot export a keystore of source " + keystore.getSource()); } - if(wallet.getPolicyType().equals(PolicyType.SINGLE)) { + if(wallet.getPolicyType().equals(PolicyType.SINGLE_HD)) { ew.keystores.put("keystore", ek); - } else if(wallet.getPolicyType().equals(PolicyType.MULTI)) { + } else if(wallet.getPolicyType().equals(PolicyType.MULTI_HD)) { ew.keystores.put("x" + index + "/", ek); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ElectrumPersonalServer.java b/src/main/java/com/sparrowwallet/sparrow/io/ElectrumPersonalServer.java index ddcb4cf2..23f95549 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ElectrumPersonalServer.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ElectrumPersonalServer.java @@ -30,6 +30,10 @@ public class ElectrumPersonalServer implements WalletExport { @Override public void exportWallet(Wallet wallet, OutputStream outputStream, String password) throws ExportException { + if(wallet.getPolicyType() == PolicyType.SINGLE_SILENT_PAYMENTS) { + throw new ExportException(getName() + " does not support silent payments wallets."); + } + if(wallet.getScriptType() == ScriptType.P2TR) { throw new ExportException(getName() + " does not support Taproot wallets."); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java index 08c61863..b8d518ce 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoneSinglesig.java @@ -1,6 +1,5 @@ package com.sparrowwallet.sparrow.io; -import com.google.gson.Gson; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.OutputDescriptor; @@ -79,10 +78,10 @@ public class KeystoneSinglesig implements KeystoreFileImport, WalletImport { Keystore keystore = getKeystore(ScriptType.P2WPKH, inputStream, ""); Wallet wallet = new Wallet(); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(ScriptType.P2WPKH); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), null)); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE_HD, ScriptType.P2WPKH, wallet.getKeystores(), null)); try { wallet.checkWallet(); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java index b17b0736..dface642 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.*; import com.sparrowwallet.drongo.crypto.*; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.MnemonicException; import com.sparrowwallet.drongo.wallet.StandardAccount; @@ -187,6 +188,7 @@ public class Storage { keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); keystore.getSeed().setPassphrase(copyKeystore.getSeed().getPassphrase()); keystore.setBip47ExtendedPrivateKey(derivedKeystore.getBip47ExtendedPrivateKey()); + keystore.setSilentPaymentScanAddress(wallet.getPolicyType() == PolicyType.SINGLE_SILENT_PAYMENTS ? derivedKeystore.getSilentPaymentScanAddress() : null); copyKeystore.getSeed().clear(); } else if(keystore.hasMasterPrivateExtendedKey()) { Keystore copyKeystore = copy.getKeystores().get(i); @@ -194,6 +196,7 @@ public class Storage { keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); keystore.setBip47ExtendedPrivateKey(derivedKeystore.getBip47ExtendedPrivateKey()); + keystore.setSilentPaymentScanAddress(wallet.getPolicyType() == PolicyType.SINGLE_SILENT_PAYMENTS ? derivedKeystore.getSilentPaymentScanAddress() : null); copyKeystore.getMasterPrivateKey().clear(); } } 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 6455bf4f..909c2449 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java @@ -6,6 +6,7 @@ import com.sparrowwallet.drongo.Utils; 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.*; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTInput; @@ -300,7 +301,7 @@ public class CkCardApi extends CardApi { } CardRead cardRead = cardProtocol.read(null, currentSlot); - Address address = getDefaultScriptType().getAddress(cardRead.getPubKey()); + Address address = getDefaultScriptType().getAddress(PolicyType.SINGLE_HD, cardRead.getPubKey()); String left = addr.substring(0, addr.indexOf('_')); String right = addr.substring(addr.lastIndexOf('_') + 1); diff --git a/src/main/java/com/sparrowwallet/sparrow/net/LnurlAuth.java b/src/main/java/com/sparrowwallet/sparrow/net/LnurlAuth.java index b15be3a3..3311e0bc 100644 --- a/src/main/java/com/sparrowwallet/sparrow/net/LnurlAuth.java +++ b/src/main/java/com/sparrowwallet/sparrow/net/LnurlAuth.java @@ -151,8 +151,8 @@ public class LnurlAuth { } private ECKey deriveLinkingKey(Wallet wallet) { - if(wallet.getPolicyType() != PolicyType.SINGLE) { - throw new IllegalArgumentException("Only singlesig wallets can authenticate."); + if(wallet.getPolicyType() != PolicyType.SINGLE_HD) { + throw new IllegalArgumentException("Only singlesig HD wallets can authenticate."); } if(wallet.isEncrypted()) { diff --git a/src/main/java/com/sparrowwallet/sparrow/net/VersionCheckService.java b/src/main/java/com/sparrowwallet/sparrow/net/VersionCheckService.java index 55ee45b0..c3896159 100644 --- a/src/main/java/com/sparrowwallet/sparrow/net/VersionCheckService.java +++ b/src/main/java/com/sparrowwallet/sparrow/net/VersionCheckService.java @@ -4,6 +4,7 @@ import com.sparrowwallet.drongo.Version; import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.address.InvalidAddressException; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.SparrowWallet; @@ -66,7 +67,7 @@ public class VersionCheckService extends ScheduledService { String signature = versionCheck.signatures.get(addressString); ECKey signedMessageKey = ECKey.signedMessageToKey(versionCheck.version, signature, false); Address providedAddress = Address.fromString(addressString); - Address signedMessageAddress = ScriptType.P2PKH.getAddress(signedMessageKey); + Address signedMessageAddress = ScriptType.P2PKH.getAddress(PolicyType.SINGLE_HD, signedMessageKey); if(providedAddress.equals(signedMessageAddress)) { return true; 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 17e6945c..1b5b9b17 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/Bip39Dialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/Bip39Dialog.java @@ -68,7 +68,7 @@ public class Bip39Dialog extends NewWalletDialog { buttonPanel.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.END, GridLayout.Alignment.CENTER,false,false)).addTo(mainPanel); setComponent(mainPanel); - ScriptType.getAddressableScriptTypes(PolicyType.SINGLE).stream().map(DisplayScriptType::new).forEach(scriptType::addItem); + ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD).stream().map(DisplayScriptType::new).forEach(scriptType::addItem); scriptType.setSelectedItem(new DisplayScriptType(ScriptType.P2WPKH)); seedWords.setTextChangeListener((newText, changedByUserInteraction) -> { @@ -150,11 +150,11 @@ public class Bip39Dialog extends NewWalletDialog { @Override protected List getWallets() throws ImportException { Wallet wallet = new Wallet(walletName); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType.getSelectedItem().scriptType); Keystore keystore = importer.getKeystore(wallet.getScriptType().getDefaultDerivation(), getWords(), passphrase.getText()); wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, wallet.getScriptType(), wallet.getKeystores(), 1)); + 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/terminal/wallet/SettingsDialog.java b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/SettingsDialog.java index b814200f..fb7f1caa 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/SettingsDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/SettingsDialog.java @@ -75,7 +75,7 @@ public class SettingsDialog extends WalletDialog { Panel leftButtonPanel = new Panel(); leftButtonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1)); leftButtonPanel.addComponent(new Button("Add Account", this::showAddAccount)); - if(getWalletForm().getWallet().getPolicyType() == PolicyType.SINGLE) { + if(getWalletForm().getWallet().getPolicyType() == PolicyType.SINGLE || getWalletForm().getWallet().getPolicyType() == PolicyType.SINGLE_SILENT_PAYMENTS) { leftButtonPanel.addComponent(new Button("Show Seed", this::showSeed)); } else { leftButtonPanel.addComponent(new EmptySpace(TerminalSize.ZERO)); diff --git a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/WatchOnlyDialog.java b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/WatchOnlyDialog.java index b6980277..bd974d47 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/WatchOnlyDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/WatchOnlyDialog.java @@ -113,12 +113,12 @@ public class WatchOnlyDialog extends NewWalletDialog { Set scriptTypes = new LinkedHashSet<>(); scriptTypes.add(ScriptType.P2WPKH); scriptTypes.add(header.getDefaultScriptType()); - scriptTypes.addAll(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE)); + scriptTypes.addAll(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE_HD)); List wallets = new ArrayList<>(); for(ScriptType scriptType : scriptTypes) { Wallet wallet = new Wallet(walletName); - wallet.setPolicyType(PolicyType.SINGLE); + wallet.setPolicyType(PolicyType.SINGLE_HD); wallet.setScriptType(scriptType); Keystore keystore = new Keystore(); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index 8e83e07a..e695d05d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -849,7 +849,7 @@ public class HeadersController extends TransactionFormController implements Init } if(headersForm.getWalletTransaction() != null && headersForm.getWalletTransaction().getWallet() != null - && headersForm.getWalletTransaction().getWallet().getPolicyType() == PolicyType.MULTI + && headersForm.getWalletTransaction().getWallet().getPolicyType() == PolicyType.MULTI_HD && headersForm.getWalletTransaction().getWallet().getDefaultPolicy().getNumSignaturesRequired() < headersForm.getWalletTransaction().getWallet().getKeystores().size()) { signedByField.setVisible(true); Wallet wallet = headersForm.getWalletTransaction().getWallet(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java index 329425b4..11cd8582 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java @@ -61,7 +61,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; import java.util.*; import java.util.concurrent.TimeoutException; @@ -571,7 +570,7 @@ public class PaymentController extends WalletFormController implements Initializ sendNode = recipientBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode); } ECKey pubKey = sendNode.getPubKey(); - return recipientBip47Wallet.getScriptType().getAddress(pubKey); + return recipientBip47Wallet.getScriptType().getAddress(recipientBip47Wallet.getPolicyType(), pubKey); } } catch(InvalidPaymentCodeException e) { log.error("Error creating payment code from PayNym", e); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/CaravanMultisigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/CaravanMultisigTest.java index 0ab22816..294c2c57 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/CaravanMultisigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/CaravanMultisigTest.java @@ -19,7 +19,7 @@ public class CaravanMultisigTest extends IoTest { CaravanMultisig ccMultisig = new CaravanMultisig(); Wallet wallet = ccMultisig.importWallet(getInputStream("caravan-multisig-export-1.json"), null); Assertions.assertEquals("Test Wallet", wallet.getName()); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WSH, wallet.getScriptType()); Assertions.assertEquals(2, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("wsh(sortedmulti(2,mercury,venus,earth))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java index 8978870a..487facfa 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/ColdcardMultisigTest.java @@ -62,7 +62,7 @@ public class ColdcardMultisigTest extends IoTest { ColdcardMultisig ccMultisig = new ColdcardMultisig(); Wallet wallet = ccMultisig.importWallet(getInputStream("cc-multisig-export-1.txt"), null); Assertions.assertEquals("CC-2-of-4", wallet.getName()); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WSH, wallet.getScriptType()); Assertions.assertEquals(2, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("wsh(sortedmulti(2,coldcard1,coldcard2,coldcard3,coldcard4))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -75,7 +75,7 @@ public class ColdcardMultisigTest extends IoTest { ColdcardMultisig ccMultisig = new ColdcardMultisig(); Wallet wallet = ccMultisig.importWallet(getInputStream("cc-multisig-export-2.txt"), null); Assertions.assertEquals("CC-2-of-4", wallet.getName()); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2SH_P2WSH, wallet.getScriptType()); Assertions.assertEquals(2, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("sh(wsh(sortedmulti(2,coldcard1,coldcard2,coldcard3,coldcard4)))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -87,7 +87,7 @@ public class ColdcardMultisigTest extends IoTest { ColdcardMultisig ccMultisig = new ColdcardMultisig(); Wallet wallet = ccMultisig.importWallet(getInputStream("cc-multisig-export-multideriv.txt"), null); Assertions.assertEquals("el-CC-3-of-3-sb-2", wallet.getName()); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WSH, wallet.getScriptType()); Assertions.assertEquals(3, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("wsh(sortedmulti(3,coldcard1,coldcard2,coldcard3))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java b/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java index bf05c30c..9927f9b2 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/ElectrumTest.java @@ -22,7 +22,7 @@ public class ElectrumTest extends IoTest { Electrum electrum = new Electrum(); Wallet wallet = electrum.importWallet(getInputStream("electrum-singlesig-wallet.json"), null); - Assertions.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.SINGLE_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2SH_P2WPKH, wallet.getScriptType()); Assertions.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("sh(wpkh(trezortest))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -42,7 +42,7 @@ public class ElectrumTest extends IoTest { wallet = electrum.importWallet(new ByteArrayInputStream(baos.toByteArray()), null); Assertions.assertTrue(wallet.isValid()); - Assertions.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.SINGLE_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2SH_P2WPKH, wallet.getScriptType()); Assertions.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("sh(wpkh(trezortest))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -57,7 +57,7 @@ public class ElectrumTest extends IoTest { Electrum electrum = new Electrum(); Wallet wallet = electrum.importWallet(getInputStream("electrum-multisig-wallet.json"), null); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2SH_P2WSH, wallet.getScriptType()); Assertions.assertEquals(2, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("sh(wsh(sortedmulti(2,coldcard6ba6cfd,coldcard747b698,coldcard7bb026b,coldcard0f05694)))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -80,7 +80,7 @@ public class ElectrumTest extends IoTest { wallet = electrum.importWallet(new ByteArrayInputStream(baos.toByteArray()), null); Assertions.assertTrue(wallet.isValid()); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2SH_P2WSH, wallet.getScriptType()); Assertions.assertEquals(2, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("sh(wsh(sortedmulti(2,coldcard6ba6cfd,coldcard747b698,coldcard7bb026b,coldcard0f05694)))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -98,7 +98,7 @@ public class ElectrumTest extends IoTest { Wallet wallet = electrum.importWallet(new ByteArrayInputStream(walletBytes), "pass"); Assertions.assertTrue(wallet.isValid()); - Assertions.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.SINGLE_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WPKH, wallet.getScriptType()); Assertions.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("wpkh(electrum)", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -118,7 +118,7 @@ public class ElectrumTest extends IoTest { wallet = electrum.importWallet(new ByteArrayInputStream(baos.toByteArray()), null); Assertions.assertTrue(wallet.isValid()); - Assertions.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.SINGLE_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WPKH, wallet.getScriptType()); Assertions.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("wpkh(electrum)", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/SpecterDesktopTest.java b/src/test/java/com/sparrowwallet/sparrow/io/SpecterDesktopTest.java index 3c60a16e..5a14b62d 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/SpecterDesktopTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/SpecterDesktopTest.java @@ -14,7 +14,7 @@ public class SpecterDesktopTest extends IoTest { SpecterDesktop specterDesktop = new SpecterDesktop(); Wallet wallet = specterDesktop.importWallet(getInputStream("specter-wallet.json"), null); - Assertions.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.SINGLE_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2SH_P2WPKH, wallet.getScriptType()); Assertions.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("sh(wpkh(keystore1))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); @@ -29,7 +29,7 @@ public class SpecterDesktopTest extends IoTest { SpecterDesktop specterDesktop = new SpecterDesktop(); Wallet wallet = specterDesktop.importWallet(getInputStream("specter-multisig-wallet.json"), null); - Assertions.assertEquals(PolicyType.MULTI, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.MULTI_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WSH, wallet.getScriptType()); Assertions.assertEquals(3, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("wsh(sortedmulti(3,keystore1,keystore2,keystore3,keystore4))", wallet.getDefaultPolicy().getMiniscript().getScript().toLowerCase(Locale.ROOT)); diff --git a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java index 4b6ef525..1aa89cb6 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java @@ -45,7 +45,7 @@ public class StorageTest extends IoTest { Assertions.assertTrue(wallet.isValid()); Assertions.assertEquals("testd2", wallet.getName()); - Assertions.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assertions.assertEquals(PolicyType.SINGLE_HD, wallet.getPolicyType()); Assertions.assertEquals(ScriptType.P2WPKH, wallet.getScriptType()); Assertions.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); Assertions.assertEquals("pkh(60bcd3a7)", wallet.getDefaultPolicy().getMiniscript().getScript());