mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-27 02:26:44 +00:00
refactor to parametrize with keypurpose
This commit is contained in:
parent
de70f44535
commit
c871bf829a
4 changed files with 44 additions and 35 deletions
15
src/main/java/com/sparrowwallet/drongo/KeyPurpose.java
Normal file
15
src/main/java/com/sparrowwallet/drongo/KeyPurpose.java
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package com.sparrowwallet.drongo;
|
||||||
|
|
||||||
|
public enum KeyPurpose {
|
||||||
|
RECEIVE(0), CHANGE(1);
|
||||||
|
|
||||||
|
private final int pathIndex;
|
||||||
|
|
||||||
|
KeyPurpose(int pathIndex) {
|
||||||
|
this.pathIndex = pathIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPathIndex() {
|
||||||
|
return pathIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.sparrowwallet.drongo.wallet;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.ExtendedKey;
|
import com.sparrowwallet.drongo.ExtendedKey;
|
||||||
import com.sparrowwallet.drongo.KeyDerivation;
|
import com.sparrowwallet.drongo.KeyDerivation;
|
||||||
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
import com.sparrowwallet.drongo.Utils;
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.crypto.*;
|
import com.sparrowwallet.drongo.crypto.*;
|
||||||
|
|
||||||
|
@ -103,22 +104,13 @@ public class Keystore {
|
||||||
return new ExtendedKey(derivedKey, derivedKey.getParentFingerprint(), derivation.get(derivation.size() - 1));
|
return new ExtendedKey(derivedKey, derivedKey.getParentFingerprint(), derivation.get(derivation.size() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeterministicKey getReceivingKey(int keyIndex) {
|
public DeterministicKey getKey(KeyPurpose keyPurpose, int keyIndex) {
|
||||||
List<ChildNumber> receivingDerivation = List.of(extendedPublicKey.getKeyChildNumber(), new ChildNumber(0), new ChildNumber(keyIndex));
|
List<ChildNumber> receivingDerivation = List.of(extendedPublicKey.getKeyChildNumber(), new ChildNumber(keyPurpose.getPathIndex()), new ChildNumber(keyIndex));
|
||||||
return extendedPublicKey.getKey(receivingDerivation);
|
return extendedPublicKey.getKey(receivingDerivation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyDerivation getReceivingDerivation(int keyIndex) {
|
public KeyDerivation getDerivation(KeyPurpose keyPurpose, int keyIndex) {
|
||||||
return getKeyDerivation().extend(new ChildNumber(0)).extend(new ChildNumber(keyIndex));
|
return getKeyDerivation().extend(new ChildNumber(keyPurpose.getPathIndex())).extend(new ChildNumber(keyIndex));
|
||||||
}
|
|
||||||
|
|
||||||
public DeterministicKey getChangeKey(int keyIndex) {
|
|
||||||
List<ChildNumber> receivingDerivation = List.of(extendedPublicKey.getKeyChildNumber(), new ChildNumber(1), new ChildNumber(keyIndex));
|
|
||||||
return extendedPublicKey.getKey(receivingDerivation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyDerivation getChangeDerivation(int keyIndex) {
|
|
||||||
return getKeyDerivation().extend(new ChildNumber(1)).extend(new ChildNumber(keyIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.sparrowwallet.drongo.wallet;
|
package com.sparrowwallet.drongo.wallet;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
import com.sparrowwallet.drongo.address.Address;
|
import com.sparrowwallet.drongo.address.Address;
|
||||||
import com.sparrowwallet.drongo.crypto.DeterministicKey;
|
import com.sparrowwallet.drongo.crypto.DeterministicKey;
|
||||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||||
|
@ -75,31 +76,31 @@ public class Wallet {
|
||||||
this.keystores = keystores;
|
this.keystores = keystores;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address getReceivingAddress(int index) {
|
public Address getAddress(KeyPurpose keyPurpose, int index) {
|
||||||
if(policyType == PolicyType.SINGLE) {
|
if(policyType == PolicyType.SINGLE) {
|
||||||
Keystore keystore = getKeystores().get(0);
|
Keystore keystore = getKeystores().get(0);
|
||||||
DeterministicKey key = keystore.getReceivingKey(index);
|
DeterministicKey key = keystore.getKey(keyPurpose, index);
|
||||||
return scriptType.getAddress(key);
|
return scriptType.getAddress(key);
|
||||||
} else if(policyType == PolicyType.MULTI) {
|
} else if(policyType == PolicyType.MULTI) {
|
||||||
List<ECKey> pubKeys = getKeystores().stream().map(keystore -> keystore.getReceivingKey(index)).collect(Collectors.toList());
|
List<ECKey> pubKeys = getKeystores().stream().map(keystore -> keystore.getKey(keyPurpose, index)).collect(Collectors.toList());
|
||||||
Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys);
|
Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys);
|
||||||
return scriptType.getAddress(script);
|
return scriptType.getAddress(script);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException("Cannot determine receiving addresses for custom policies");
|
throw new UnsupportedOperationException("Cannot determine addresses for custom policies");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address getChangeAddress(int index) {
|
public Script getOutputScript(KeyPurpose keyPurpose, int index) {
|
||||||
if(policyType == PolicyType.SINGLE) {
|
if(policyType == PolicyType.SINGLE) {
|
||||||
Keystore keystore = getKeystores().get(0);
|
Keystore keystore = getKeystores().get(0);
|
||||||
DeterministicKey key = keystore.getChangeKey(index);
|
DeterministicKey key = keystore.getKey(keyPurpose, index);
|
||||||
return scriptType.getAddress(key);
|
return scriptType.getOutputScript(key);
|
||||||
} else if(policyType == PolicyType.MULTI) {
|
} else if(policyType == PolicyType.MULTI) {
|
||||||
List<ECKey> pubKeys = getKeystores().stream().map(keystore -> keystore.getChangeKey(index)).collect(Collectors.toList());
|
List<ECKey> pubKeys = getKeystores().stream().map(keystore -> keystore.getKey(keyPurpose, index)).collect(Collectors.toList());
|
||||||
Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys);
|
Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys);
|
||||||
return scriptType.getAddress(script);
|
return scriptType.getOutputScript(script);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException("Cannot determine change addresses for custom policies");
|
throw new UnsupportedOperationException("Cannot determine output script for custom policies");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.sparrowwallet.drongo.wallet;
|
package com.sparrowwallet.drongo.wallet;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
import com.sparrowwallet.drongo.crypto.Argon2KeyDeriver;
|
import com.sparrowwallet.drongo.crypto.Argon2KeyDeriver;
|
||||||
import com.sparrowwallet.drongo.crypto.Key;
|
import com.sparrowwallet.drongo.crypto.Key;
|
||||||
import com.sparrowwallet.drongo.crypto.KeyDeriver;
|
import com.sparrowwallet.drongo.crypto.KeyDeriver;
|
||||||
|
@ -78,8 +79,8 @@ public class WalletTest {
|
||||||
wallet.getKeystores().add(keystore);
|
wallet.getKeystores().add(keystore);
|
||||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, wallet.getKeystores(), 1));
|
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, wallet.getKeystores(), 1));
|
||||||
|
|
||||||
Assert.assertEquals("12kTQjuWDp7Uu6PwY6CsS1KLTt3d1DBHZa", wallet.getReceivingAddress(0).toString());
|
Assert.assertEquals("12kTQjuWDp7Uu6PwY6CsS1KLTt3d1DBHZa", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString());
|
||||||
Assert.assertEquals("1HbQwQCitHQxVtP39isXmUdHx7hQCZovrK", wallet.getReceivingAddress(1).toString());
|
Assert.assertEquals("1HbQwQCitHQxVtP39isXmUdHx7hQCZovrK", wallet.getAddress(KeyPurpose.RECEIVE, 1).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -93,8 +94,8 @@ public class WalletTest {
|
||||||
wallet.getKeystores().add(keystore);
|
wallet.getKeystores().add(keystore);
|
||||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2SH_P2WPKH, wallet.getKeystores(), 1));
|
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2SH_P2WPKH, wallet.getKeystores(), 1));
|
||||||
|
|
||||||
Assert.assertEquals("3NZLE4TntsjtcZ5MbrfxwtYo9meBVybVQj", wallet.getReceivingAddress(0).toString());
|
Assert.assertEquals("3NZLE4TntsjtcZ5MbrfxwtYo9meBVybVQj", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString());
|
||||||
Assert.assertEquals("32YBBuRsp8XTeLx4T6BmD2L4nANGaNDkSg", wallet.getReceivingAddress(1).toString());
|
Assert.assertEquals("32YBBuRsp8XTeLx4T6BmD2L4nANGaNDkSg", wallet.getAddress(KeyPurpose.RECEIVE, 1).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -108,8 +109,8 @@ public class WalletTest {
|
||||||
wallet.getKeystores().add(keystore);
|
wallet.getKeystores().add(keystore);
|
||||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), 1));
|
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), 1));
|
||||||
|
|
||||||
Assert.assertEquals("bc1quvxdut936uswuxwxrk6nvjmgwxh463r0fjwn55", wallet.getReceivingAddress(0).toString());
|
Assert.assertEquals("bc1quvxdut936uswuxwxrk6nvjmgwxh463r0fjwn55", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString());
|
||||||
Assert.assertEquals("bc1q95j2862dz7mqpraw6qdjc70gumyu5z7adgq9x9", wallet.getReceivingAddress(1).toString());
|
Assert.assertEquals("bc1q95j2862dz7mqpraw6qdjc70gumyu5z7adgq9x9", wallet.getAddress(KeyPurpose.RECEIVE, 1).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -133,8 +134,8 @@ public class WalletTest {
|
||||||
wallet.getKeystores().add(keystore2);
|
wallet.getKeystores().add(keystore2);
|
||||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH, wallet.getKeystores(), 2));
|
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH, wallet.getKeystores(), 2));
|
||||||
|
|
||||||
Assert.assertEquals("38kq6yz4VcYymTExQPY3gppbz38mtPLveK", wallet.getReceivingAddress(0).toString());
|
Assert.assertEquals("38kq6yz4VcYymTExQPY3gppbz38mtPLveK", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString());
|
||||||
Assert.assertEquals("3EdKaNsnjBTBggWcSMRyVju6GbHWy68mAH", wallet.getChangeAddress(1).toString());
|
Assert.assertEquals("3EdKaNsnjBTBggWcSMRyVju6GbHWy68mAH", wallet.getAddress(KeyPurpose.CHANGE, 1).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -158,8 +159,8 @@ public class WalletTest {
|
||||||
wallet.getKeystores().add(keystore2);
|
wallet.getKeystores().add(keystore2);
|
||||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH_P2WSH, wallet.getKeystores(), 2));
|
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH_P2WSH, wallet.getKeystores(), 2));
|
||||||
|
|
||||||
Assert.assertEquals("3Mw8xqAHh8g3eBvh7q1UEUmoexqdXDK9Tf", wallet.getReceivingAddress(0).toString());
|
Assert.assertEquals("3Mw8xqAHh8g3eBvh7q1UEUmoexqdXDK9Tf", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString());
|
||||||
Assert.assertEquals("35dFo1ivJ8jyHpyf42MWvnYf5LBU8Siren", wallet.getChangeAddress(1).toString());
|
Assert.assertEquals("35dFo1ivJ8jyHpyf42MWvnYf5LBU8Siren", wallet.getAddress(KeyPurpose.CHANGE, 1).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -183,7 +184,7 @@ public class WalletTest {
|
||||||
wallet.getKeystores().add(keystore2);
|
wallet.getKeystores().add(keystore2);
|
||||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2WSH, wallet.getKeystores(), 2));
|
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2WSH, wallet.getKeystores(), 2));
|
||||||
|
|
||||||
Assert.assertEquals("bc1q20e4vm656h5lvmngz9ztz6hjzftvh39yzngqhuqzk8qzj7tqnzaqgclrwc", wallet.getReceivingAddress(0).toString());
|
Assert.assertEquals("bc1q20e4vm656h5lvmngz9ztz6hjzftvh39yzngqhuqzk8qzj7tqnzaqgclrwc", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString());
|
||||||
Assert.assertEquals("bc1q2epdx7dplwaas2jucfrzmxm8350rqh68hs6vqreysku80ye44mfqla85f2", wallet.getChangeAddress(1).toString());
|
Assert.assertEquals("bc1q2epdx7dplwaas2jucfrzmxm8350rqh68hs6vqreysku80ye44mfqla85f2", wallet.getAddress(KeyPurpose.CHANGE, 1).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue