From 813781902b8914fbac20c5a36ef230a44639ecbc Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sun, 19 Apr 2020 19:07:06 +0200 Subject: [PATCH] wallet copying --- .../drongo/ExtendedPublicKey.java | 5 ++++ .../sparrowwallet/drongo/KeyDerivation.java | 6 ++++- .../drongo/crypto/DeterministicKey.java | 5 ++-- .../drongo/policy/Miniscript.java | 4 ++++ .../sparrowwallet/drongo/policy/Policy.java | 4 ++++ .../sparrowwallet/drongo/wallet/Keystore.java | 17 +++++++++++++ .../sparrowwallet/drongo/wallet/Wallet.java | 24 +++++++++++++++++++ src/main/java/module-info.java | 2 +- 8 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/ExtendedPublicKey.java b/src/main/java/com/sparrowwallet/drongo/ExtendedPublicKey.java index dada7f3..a6ca0e6 100644 --- a/src/main/java/com/sparrowwallet/drongo/ExtendedPublicKey.java +++ b/src/main/java/com/sparrowwallet/drongo/ExtendedPublicKey.java @@ -111,6 +111,11 @@ public class ExtendedPublicKey { return true; } + public ExtendedPublicKey copy() { + //DeterministicKey is effectively final + return new ExtendedPublicKey(pubKey, Arrays.copyOf(parentFingerprint, parentFingerprint.length), pubKeyChildNumber); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java index 9d76c0a..46882f6 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java @@ -9,7 +9,7 @@ import java.util.List; public class KeyDerivation { private final String masterFingerprint; private final String derivationPath; - private final List derivation; + private final transient List derivation; public KeyDerivation(String masterFingerprint, String derivationPath) { this.masterFingerprint = masterFingerprint; @@ -73,6 +73,10 @@ public class KeyDerivation { return true; } + public KeyDerivation copy() { + return new KeyDerivation(masterFingerprint, derivationPath); + } + public String toString() { return masterFingerprint + (derivationPath != null ? derivationPath.replace("m", "") : ""); } diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/DeterministicKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/DeterministicKey.java index 80555b1..3f242ef 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/DeterministicKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/DeterministicKey.java @@ -6,13 +6,14 @@ import com.sparrowwallet.drongo.protocol.Base58; import com.sparrowwallet.drongo.protocol.Sha256Hash; import java.util.Arrays; +import java.util.Collections; import java.util.List; public class DeterministicKey extends ECKey { private final DeterministicKey parent; private final List childNumberPath; private final int depth; - private byte[] parentFingerprint; // 0 if this key is root node of key hierarchy + private final byte[] parentFingerprint; // 0 if this key is root node of key hierarchy /** 32 bytes */ private final byte[] chainCode; @@ -80,7 +81,7 @@ public class DeterministicKey extends ECKey { * the first child of that node. */ public List getPath() { - return childNumberPath; + return Collections.unmodifiableList(childNumberPath); } public DeterministicKey getParent() { diff --git a/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java b/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java index ff46930..38da855 100644 --- a/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java +++ b/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java @@ -35,4 +35,8 @@ public class Miniscript { throw new IllegalArgumentException("Could not find multisig threshold in " + this); } } + + public Miniscript copy() { + return new Miniscript(script); + } } diff --git a/src/main/java/com/sparrowwallet/drongo/policy/Policy.java b/src/main/java/com/sparrowwallet/drongo/policy/Policy.java index 350100c..a4c9071 100644 --- a/src/main/java/com/sparrowwallet/drongo/policy/Policy.java +++ b/src/main/java/com/sparrowwallet/drongo/policy/Policy.java @@ -55,4 +55,8 @@ public class Policy { throw new PolicyException("No standard policy for " + policyType + " policy with script type " + scriptType); } + + public Policy copy() { + return new Policy(name, miniscript.copy()); + } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java index e1eb9f6..67dc3aa 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java @@ -4,10 +4,16 @@ import com.sparrowwallet.drongo.ExtendedPublicKey; import com.sparrowwallet.drongo.KeyDerivation; public class Keystore { + public static final String DEFAULT_LABEL = "Keystore 1"; + private String label; private KeyDerivation keyDerivation; private ExtendedPublicKey extendedPublicKey; + public Keystore() { + this(DEFAULT_LABEL); + } + public Keystore(String label) { this.label = label; } @@ -39,4 +45,15 @@ public class Keystore { public void setExtendedPublicKey(ExtendedPublicKey extendedPublicKey) { this.extendedPublicKey = extendedPublicKey; } + + public Keystore copy() { + Keystore copy = new Keystore(label); + if(keyDerivation != null) { + copy.setKeyDerivation(keyDerivation.copy()); + } + if(extendedPublicKey != null) { + copy.setExtendedPublicKey(extendedPublicKey.copy()); + } + return copy; + } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index c777dbf..6726710 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -5,14 +5,27 @@ import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ScriptType; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Wallet { + private PolicyType policyType; private ScriptType scriptType; private Policy defaultPolicy; private List keystores = new ArrayList<>(); + public Wallet() { + + } + + public Wallet(PolicyType policyType, ScriptType scriptType) { + this.policyType = policyType; + this.scriptType = scriptType; + this.keystores = Collections.singletonList(new Keystore()); + this.defaultPolicy = Policy.getPolicy(policyType, scriptType, keystores, null); + } + public PolicyType getPolicyType() { return policyType; } @@ -44,4 +57,15 @@ public class Wallet { public void setKeystores(List keystores) { this.keystores = keystores; } + + public Wallet copy() { + Wallet copy = new Wallet(); + copy.setPolicyType(policyType); + copy.setScriptType(scriptType); + copy.setDefaultPolicy(defaultPolicy.copy()); + for(Keystore keystore : keystores) { + copy.getKeystores().add(keystore.copy()); + } + return copy; + } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index bb71417..3f38cad 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,4 +1,4 @@ -module com.sparrowwallet.drongo { +open module com.sparrowwallet.drongo { requires org.bouncycastle.provider; requires slf4j.api; exports com.sparrowwallet.drongo;