mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-11-04 11:06:44 +00:00
store address data on wallet nodes
This commit is contained in:
parent
9ae1f68dc4
commit
5de3abd362
9 changed files with 41 additions and 64 deletions
|
@ -43,9 +43,13 @@ public abstract class Address {
|
||||||
|
|
||||||
public abstract ScriptType getScriptType();
|
public abstract ScriptType getScriptType();
|
||||||
|
|
||||||
public abstract Script getOutputScript();
|
public Script getOutputScript() {
|
||||||
|
return getScriptType().getOutputScript(data);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract byte[] getOutputScriptData();
|
public byte[] getOutputScriptData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String getOutputScriptDataType();
|
public abstract String getOutputScriptDataType();
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,6 @@ public class P2PKAddress extends Address {
|
||||||
return ScriptType.P2PK;
|
return ScriptType.P2PK;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Script getOutputScript() {
|
|
||||||
return getScriptType().getOutputScript(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getOutputScriptData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOutputScriptDataType() {
|
public String getOutputScriptDataType() {
|
||||||
return "Public Key";
|
return "Public Key";
|
||||||
|
|
|
@ -19,16 +19,6 @@ public class P2PKHAddress extends Address {
|
||||||
return ScriptType.P2PKH;
|
return ScriptType.P2PKH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Script getOutputScript() {
|
|
||||||
return getScriptType().getOutputScript(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getOutputScriptData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOutputScriptDataType() {
|
public String getOutputScriptDataType() {
|
||||||
return "Public Key Hash";
|
return "Public Key Hash";
|
||||||
|
|
|
@ -20,16 +20,6 @@ public class P2SHAddress extends Address {
|
||||||
return ScriptType.P2SH;
|
return ScriptType.P2SH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Script getOutputScript() {
|
|
||||||
return getScriptType().getOutputScript(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getOutputScriptData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOutputScriptDataType() {
|
public String getOutputScriptDataType() {
|
||||||
return "Script Hash";
|
return "Script Hash";
|
||||||
|
|
|
@ -25,16 +25,6 @@ public class P2TRAddress extends Address {
|
||||||
return ScriptType.P2TR;
|
return ScriptType.P2TR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Script getOutputScript() {
|
|
||||||
return getScriptType().getOutputScript(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getOutputScriptData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOutputScriptDataType() {
|
public String getOutputScriptDataType() {
|
||||||
return "Taproot";
|
return "Taproot";
|
||||||
|
|
|
@ -25,16 +25,6 @@ public class P2WPKHAddress extends Address {
|
||||||
return ScriptType.P2WPKH;
|
return ScriptType.P2WPKH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Script getOutputScript() {
|
|
||||||
return getScriptType().getOutputScript(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getOutputScriptData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOutputScriptDataType() {
|
public String getOutputScriptDataType() {
|
||||||
return "Witness Public Key Hash";
|
return "Witness Public Key Hash";
|
||||||
|
|
|
@ -23,16 +23,6 @@ public class P2WSHAddress extends Address {
|
||||||
return ScriptType.P2WSH;
|
return ScriptType.P2WSH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Script getOutputScript() {
|
|
||||||
return getScriptType().getOutputScript(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getOutputScriptData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOutputScriptDataType() {
|
public String getOutputScriptDataType() {
|
||||||
return "Witness Script Hash";
|
return "Witness Script Hash";
|
||||||
|
|
|
@ -31,7 +31,10 @@ public class Keystore extends Persistable {
|
||||||
private DeterministicSeed seed;
|
private DeterministicSeed seed;
|
||||||
|
|
||||||
//For BIP47 keystores - not persisted but must be unencrypted to generate keys
|
//For BIP47 keystores - not persisted but must be unencrypted to generate keys
|
||||||
private ExtendedKey bip47ExtendedPrivateKey;
|
private transient ExtendedKey bip47ExtendedPrivateKey;
|
||||||
|
|
||||||
|
//Avoid performing repeated expensive seed derivation checks
|
||||||
|
private transient boolean extendedPublicKeyChecked;
|
||||||
|
|
||||||
public Keystore() {
|
public Keystore() {
|
||||||
this(DEFAULT_LABEL);
|
this(DEFAULT_LABEL);
|
||||||
|
@ -83,6 +86,7 @@ public class Keystore extends Persistable {
|
||||||
|
|
||||||
public void setExtendedPublicKey(ExtendedKey extendedPublicKey) {
|
public void setExtendedPublicKey(ExtendedKey extendedPublicKey) {
|
||||||
this.extendedPublicKey = extendedPublicKey;
|
this.extendedPublicKey = extendedPublicKey;
|
||||||
|
this.extendedPublicKeyChecked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaymentCode getExternalPaymentCode() {
|
public PaymentCode getExternalPaymentCode() {
|
||||||
|
@ -125,6 +129,14 @@ public class Keystore extends Persistable {
|
||||||
return hasMasterPrivateKey() || (source == KeystoreSource.SW_PAYMENT_CODE && bip47ExtendedPrivateKey != null);
|
return hasMasterPrivateKey() || (source == KeystoreSource.SW_PAYMENT_CODE && bip47ExtendedPrivateKey != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean needsPassphrase() {
|
||||||
|
if(seed != null) {
|
||||||
|
return seed.needsPassphrase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public PaymentCode getPaymentCode() {
|
public PaymentCode getPaymentCode() {
|
||||||
DeterministicKey bip47Key = bip47ExtendedPrivateKey.getKey();
|
DeterministicKey bip47Key = bip47ExtendedPrivateKey.getKey();
|
||||||
return new PaymentCode(bip47Key.getPubKey(), bip47Key.getChainCode());
|
return new PaymentCode(bip47Key.getPubKey(), bip47Key.getChainCode());
|
||||||
|
@ -278,7 +290,7 @@ public class Keystore extends Persistable {
|
||||||
throw new InvalidKeystoreException("Source of " + source + " but no seed or master private key is present");
|
throw new InvalidKeystoreException("Source of " + source + " but no seed or master private key is present");
|
||||||
}
|
}
|
||||||
|
|
||||||
if((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted())) {
|
if(!extendedPublicKeyChecked && ((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted()))) {
|
||||||
try {
|
try {
|
||||||
List<ChildNumber> derivation = getKeyDerivation().getDerivation();
|
List<ChildNumber> derivation = getKeyDerivation().getDerivation();
|
||||||
DeterministicKey derivedKey = getExtendedMasterPrivateKey().getKey(derivation);
|
DeterministicKey derivedKey = getExtendedMasterPrivateKey().getKey(derivation);
|
||||||
|
@ -287,6 +299,7 @@ public class Keystore extends Persistable {
|
||||||
if(!xpub.equals(getExtendedPublicKey())) {
|
if(!xpub.equals(getExtendedPublicKey())) {
|
||||||
throw new InvalidKeystoreException("Specified extended public key does not match public key derived from seed");
|
throw new InvalidKeystoreException("Specified extended public key does not match public key derived from seed");
|
||||||
}
|
}
|
||||||
|
extendedPublicKeyChecked = true;
|
||||||
} catch(MnemonicException e) {
|
} catch(MnemonicException e) {
|
||||||
throw new InvalidKeystoreException("Invalid mnemonic specified for seed", e);
|
throw new InvalidKeystoreException("Invalid mnemonic specified for seed", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.stream.Collectors;
|
||||||
public class WalletNode extends Persistable implements Comparable<WalletNode> {
|
public class WalletNode extends Persistable implements Comparable<WalletNode> {
|
||||||
private final String derivationPath;
|
private final String derivationPath;
|
||||||
private String label;
|
private String label;
|
||||||
|
private Address address;
|
||||||
private TreeSet<WalletNode> children = new TreeSet<>();
|
private TreeSet<WalletNode> children = new TreeSet<>();
|
||||||
private TreeSet<BlockTransactionHashIndex> transactionOutputs = new TreeSet<>();
|
private TreeSet<BlockTransactionHashIndex> transactionOutputs = new TreeSet<>();
|
||||||
|
|
||||||
|
@ -267,11 +268,28 @@ public class WalletNode extends Persistable implements Comparable<WalletNode> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address getAddress() {
|
public Address getAddress() {
|
||||||
|
if(address != null) {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wallet.getKeystores().stream().noneMatch(Keystore::needsPassphrase)) {
|
||||||
|
address = wallet.getAddress(this);
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
return wallet.getAddress(this);
|
return wallet.getAddress(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getAddressData() {
|
||||||
|
return address == null ? null : address.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(Address address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
public Script getOutputScript() {
|
public Script getOutputScript() {
|
||||||
return wallet.getOutputScript(this);
|
return getAddress().getOutputScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOutputDescriptor() {
|
public String getOutputDescriptor() {
|
||||||
|
@ -324,6 +342,7 @@ public class WalletNode extends Persistable implements Comparable<WalletNode> {
|
||||||
WalletNode copy = new WalletNode(walletCopy, derivationPath);
|
WalletNode copy = new WalletNode(walletCopy, derivationPath);
|
||||||
copy.setId(getId());
|
copy.setId(getId());
|
||||||
copy.setLabel(label);
|
copy.setLabel(label);
|
||||||
|
copy.setAddress(address);
|
||||||
|
|
||||||
for(WalletNode child : getChildren()) {
|
for(WalletNode child : getChildren()) {
|
||||||
copy.children.add(child.copy(walletCopy));
|
copy.children.add(child.copy(walletCopy));
|
||||||
|
|
Loading…
Reference in a new issue