support finding signing nodes from provided psbt input derivation paths

This commit is contained in:
Craig Raw 2024-04-30 11:54:43 +02:00
parent 143d28166a
commit d4bdd9f385
2 changed files with 31 additions and 2 deletions

View file

@ -242,6 +242,24 @@ public class Keystore extends Persistable {
return getKeyDerivation().extend(keyPurpose.getPathIndex()).extend(new ChildNumber(keyIndex)); return getKeyDerivation().extend(keyPurpose.getPathIndex()).extend(new ChildNumber(keyIndex));
} }
public ECKey getPubKeyForDerivation(KeyDerivation keyDerivation) {
if(keyDerivation != null) {
List<ChildNumber> derivation = keyDerivation.getDerivation();
if(derivation.size() > this.keyDerivation.getDerivation().size()) {
List<ChildNumber> xpubDerivation = derivation.subList(0, this.keyDerivation.getDerivation().size());
if(xpubDerivation.equals(this.keyDerivation.getDerivation())) {
derivation = derivation.subList(this.keyDerivation.getDerivation().size(), derivation.size());
}
}
if(derivation.size() == 2) {
return getPubKey(new WalletNode(KeyDerivation.writePath(derivation)));
}
}
return null;
}
public boolean isValid() { public boolean isValid() {
try { try {
checkKeystore(); checkKeystore();

View file

@ -1490,8 +1490,8 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
return signingNodes; return signingNodes;
} }
public List<Keystore> getSigningKeystores(PSBT psbt) { public Collection<Keystore> getSigningKeystores(PSBT psbt) {
List<Keystore> signingKeystores = new ArrayList<>(); Set<Keystore> signingKeystores = new LinkedHashSet<>();
for(Map.Entry<ExtendedKey, KeyDerivation> entry : psbt.getExtendedPublicKeys().entrySet()) { for(Map.Entry<ExtendedKey, KeyDerivation> entry : psbt.getExtendedPublicKeys().entrySet()) {
for(Keystore keystore : getKeystores()) { for(Keystore keystore : getKeystores()) {
@ -1501,6 +1501,17 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
} }
} }
for(PSBTInput psbtInput : psbt.getPsbtInputs()) {
for(Map.Entry<ECKey, KeyDerivation> entry : psbtInput.getDerivedPublicKeys().entrySet()) {
for(Keystore keystore : getKeystores().stream().filter(k -> !signingKeystores.contains(k)).toList()) {
ECKey derivedKey = keystore.getPubKeyForDerivation(entry.getValue());
if(derivedKey != null && Arrays.equals(entry.getKey().getPubKey(), derivedKey.getPubKey())) {
signingKeystores.add(keystore);
}
}
}
}
return signingKeystores; return signingKeystores;
} }