mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-27 02:26:44 +00:00
determine signing status from psbt
This commit is contained in:
parent
dcd4218ba1
commit
f6dcdb6d26
2 changed files with 48 additions and 5 deletions
|
@ -104,9 +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 getKey(WalletNode walletNode) {
|
||||||
|
return getKey(walletNode.getKeyPurpose(), walletNode.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
public DeterministicKey getKey(KeyPurpose keyPurpose, int keyIndex) {
|
public DeterministicKey getKey(KeyPurpose keyPurpose, int keyIndex) {
|
||||||
List<ChildNumber> receivingDerivation = List.of(extendedPublicKey.getKeyChildNumber(), keyPurpose.getPathIndex(), new ChildNumber(keyIndex));
|
List<ChildNumber> derivation = List.of(extendedPublicKey.getKeyChildNumber(), keyPurpose.getPathIndex(), new ChildNumber(keyIndex));
|
||||||
return extendedPublicKey.getKey(receivingDerivation);
|
return extendedPublicKey.getKey(derivation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyDerivation getDerivation(KeyPurpose keyPurpose, int keyIndex) {
|
public KeyDerivation getDerivation(KeyPurpose keyPurpose, int keyIndex) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
@ -569,6 +570,19 @@ public class Wallet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canSign(PSBT psbt) {
|
public boolean canSign(PSBT psbt) {
|
||||||
|
return !getSigningNodes(psbt).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which nodes in this wallet can sign which inputs in the provided PSBT
|
||||||
|
*
|
||||||
|
* @param psbt The PSBT to be signed
|
||||||
|
* @return A map if the PSBT inputs and the nodes that can sign them
|
||||||
|
*/
|
||||||
|
public Map<PSBTInput, WalletNode> getSigningNodes(PSBT psbt) {
|
||||||
|
Map<PSBTInput, WalletNode> signingNodes = new LinkedHashMap<>();
|
||||||
|
Map<Script, WalletNode> walletOutputScripts = getWalletOutputScripts();
|
||||||
|
|
||||||
for(int inputIndex = 0; inputIndex < psbt.getTransaction().getInputs().size(); inputIndex++) {
|
for(int inputIndex = 0; inputIndex < psbt.getTransaction().getInputs().size(); inputIndex++) {
|
||||||
TransactionInput txInput = psbt.getTransaction().getInputs().get(inputIndex);
|
TransactionInput txInput = psbt.getTransaction().getInputs().get(inputIndex);
|
||||||
PSBTInput psbtInput = psbt.getPsbtInputs().get(inputIndex);
|
PSBTInput psbtInput = psbt.getPsbtInputs().get(inputIndex);
|
||||||
|
@ -580,13 +594,38 @@ public class Wallet {
|
||||||
|
|
||||||
if(utxo != null) {
|
if(utxo != null) {
|
||||||
Script scriptPubKey = utxo.getScript();
|
Script scriptPubKey = utxo.getScript();
|
||||||
if(isWalletOutputScript(scriptPubKey)) {
|
WalletNode signingNode = walletOutputScripts.get(scriptPubKey);
|
||||||
return true;
|
if(signingNode != null) {
|
||||||
|
signingNodes.put(psbtInput, signingNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return signingNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which keystores have signed a partially signed (unfinalized) PSBT
|
||||||
|
*
|
||||||
|
* @param psbt The partially signed PSBT
|
||||||
|
*/
|
||||||
|
public Map<PSBTInput, List<Keystore>> getSignedKeystores(PSBT psbt) {
|
||||||
|
Map<PSBTInput, WalletNode> signingNodes = getSigningNodes(psbt);
|
||||||
|
Map<PSBTInput, List<Keystore>> signedKeystores = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
for(PSBTInput psbtInput : signingNodes.keySet()) {
|
||||||
|
WalletNode walletNode = signingNodes.get(psbtInput);
|
||||||
|
Map<ECKey, Keystore> keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> keystore.getKey(walletNode), Function.identity(),
|
||||||
|
(u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode.getDerivationPath()); },
|
||||||
|
LinkedHashMap::new));
|
||||||
|
|
||||||
|
keystoreKeysForNode.keySet().retainAll(psbtInput.getPartialSignatures().keySet());
|
||||||
|
|
||||||
|
List<Keystore> inputSignedKeystores = new ArrayList<>(keystoreKeysForNode.values());
|
||||||
|
signedKeystores.put(psbtInput, inputSignedKeystores);
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedKeystores;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitcoinUnit getAutoUnit() {
|
public BitcoinUnit getAutoUnit() {
|
||||||
|
|
Loading…
Reference in a new issue