use of com.sparrowwallet.drongo.KeyDerivation in project drongo by sparrowwallet.
the class PSBT method parseGlobalEntries.
private void parseGlobalEntries(List<PSBTEntry> globalEntries) throws PSBTParseException {
PSBTEntry duplicate = findDuplicateKey(globalEntries);
if (duplicate != null) {
throw new PSBTParseException("Found duplicate key for PSBT global: " + Utils.bytesToHex(duplicate.getKey()));
}
for (PSBTEntry entry : globalEntries) {
switch(entry.getKeyType()) {
case PSBT_GLOBAL_UNSIGNED_TX:
entry.checkOneByteKey();
Transaction transaction = new Transaction(entry.getData());
transaction.verify();
inputs = transaction.getInputs().size();
outputs = transaction.getOutputs().size();
log.debug("Transaction with txid: " + transaction.getTxId() + " version " + transaction.getVersion() + " size " + transaction.getMessageSize() + " locktime " + transaction.getLocktime());
for (TransactionInput input : transaction.getInputs()) {
if (input.getScriptSig().getProgram().length != 0) {
throw new PSBTParseException("Unsigned tx input does not have empty scriptSig");
}
log.debug(" Transaction input references txid: " + input.getOutpoint().getHash() + " vout " + input.getOutpoint().getIndex() + " with script " + input.getScriptSig());
}
for (TransactionOutput output : transaction.getOutputs()) {
try {
log.debug(" Transaction output value: " + output.getValue() + " to addresses " + Arrays.asList(output.getScript().getToAddresses()) + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
} catch (NonStandardScriptException e) {
log.debug(" Transaction output value: " + output.getValue() + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
}
}
this.transaction = transaction;
break;
case PSBT_GLOBAL_BIP32_PUBKEY:
entry.checkOneBytePlusXpubKey();
KeyDerivation keyDerivation = parseKeyDerivation(entry.getData());
ExtendedKey pubKey = ExtendedKey.fromDescriptor(Base58.encodeChecked(entry.getKeyData()));
this.extendedPublicKeys.put(pubKey, keyDerivation);
log.debug("Pubkey with master fingerprint " + keyDerivation.getMasterFingerprint() + " at path " + keyDerivation.getDerivationPath() + ": " + pubKey.getExtendedKey());
break;
case PSBT_GLOBAL_VERSION:
entry.checkOneByteKey();
int version = (int) Utils.readUint32(entry.getData(), 0);
this.version = version;
log.debug("PSBT version: " + version);
break;
case PSBT_GLOBAL_PROPRIETARY:
globalProprietary.put(Utils.bytesToHex(entry.getKeyData()), Utils.bytesToHex(entry.getData()));
log.debug("PSBT global proprietary data: " + Utils.bytesToHex(entry.getData()));
break;
default:
log.warn("PSBT global not recognized key type: " + entry.getKeyType());
}
}
}
use of com.sparrowwallet.drongo.KeyDerivation in project drongo by sparrowwallet.
the class PSBTTest method creatorBip.
@Test
public void creatorBip() throws PSBTParseException {
Transaction transaction = new Transaction();
transaction.setVersion(2);
transaction.addOutput(149990000L, new Script(Utils.hexToBytes("0014d85c2b71d0060b09c9886aeb815e50991dda124d")));
transaction.addOutput(100000000L, new Script(Utils.hexToBytes("001400aea9a2e5f0f876a588df5546e8742d1d87008f")));
transaction.addInput(Sha256Hash.wrap("75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858"), 0, new Script(new byte[0]));
transaction.addInput(Sha256Hash.wrap("1dea7cd05979072a3578cab271c02244ea8a090bbb46aa680a65ecd027048d83"), 1, new Script(new byte[0]));
PSBT psbt = new PSBT(transaction);
Assert.assertEquals("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000000000000000000", psbt.toString());
psbt.getPsbtInputs().get(0).setRedeemScript(new Script(Utils.hexToBytes("5221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae")));
psbt.getPsbtInputs().get(1).setRedeemScript(new Script(Utils.hexToBytes("00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903")));
psbt.getPsbtInputs().get(1).setWitnessScript(new Script(Utils.hexToBytes("522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae")));
Transaction utxo1 = new Transaction(Utils.hexToBytes("0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000"));
psbt.getPsbtInputs().get(0).setNonWitnessUtxo(utxo1);
Transaction utxo2 = new Transaction(Utils.hexToBytes("0200000000010158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88702483045022100a22edcc6e5bc511af4cc4ae0de0fcd75c7e04d8c1c3a8aa9d820ed4b967384ec02200642963597b9b1bc22c75e9f3e117284a962188bf5e8a74c895089046a20ad770121035509a48eb623e10aace8bfd0212fdb8a8e5af3c94b0b133b95e114cab89e4f7965000000"));
psbt.getPsbtInputs().get(1).setWitnessUtxo(utxo2.getOutputs().get(1));
psbt.getPsbtInputs().get(0).getDerivedPublicKeys().put(ECKey.fromPublicOnly(Utils.hexToBytes("029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f")), new KeyDerivation("d90c6a4f", "m/0'/0'/0'"));
psbt.getPsbtInputs().get(0).getDerivedPublicKeys().put(ECKey.fromPublicOnly(Utils.hexToBytes("02dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7")), new KeyDerivation("d90c6a4f", "m/0'/0'/1'"));
psbt.getPsbtInputs().get(1).getDerivedPublicKeys().put(ECKey.fromPublicOnly(Utils.hexToBytes("023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73")), new KeyDerivation("d90c6a4f", "m/0'/0'/3'"));
psbt.getPsbtInputs().get(1).getDerivedPublicKeys().put(ECKey.fromPublicOnly(Utils.hexToBytes("03089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc")), new KeyDerivation("d90c6a4f", "m/0'/0'/2'"));
psbt.getPsbtOutputs().get(0).getDerivedPublicKeys().put(ECKey.fromPublicOnly(Utils.hexToBytes("03a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca58771")), new KeyDerivation("d90c6a4f", "m/0'/0'/4'"));
psbt.getPsbtOutputs().get(1).getDerivedPublicKeys().put(ECKey.fromPublicOnly(Utils.hexToBytes("027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b50051096")), new KeyDerivation("d90c6a4f", "m/0'/0'/5'"));
Assert.assertEquals("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88701042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", psbt.toString());
for (PSBTInput psbtInput : psbt.getPsbtInputs()) {
psbtInput.setSigHash(SigHash.ALL);
}
Assert.assertEquals("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000", psbt.toString());
}
use of com.sparrowwallet.drongo.KeyDerivation in project sparrow by sparrowwallet.
the class MessageSignDialog method signUsbKeystore.
private void signUsbKeystore(Wallet usbWallet) {
List<String> fingerprints = List.of(usbWallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint());
KeyDerivation fullDerivation = usbWallet.getKeystores().get(0).getKeyDerivation().extend(walletNode.getDerivation());
DeviceSignMessageDialog deviceSignMessageDialog = new DeviceSignMessageDialog(fingerprints, usbWallet, message.getText().trim(), fullDerivation);
Optional<String> optSignature = deviceSignMessageDialog.showAndWait();
if (optSignature.isPresent()) {
signature.clear();
signature.appendText(optSignature.get());
}
}
use of com.sparrowwallet.drongo.KeyDerivation in project sparrow by sparrowwallet.
the class CaravanMultisig method importWallet.
@Override
public Wallet importWallet(InputStream inputStream, String password) throws ImportException {
try {
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
CaravanFile cf = JsonPersistence.getGson().fromJson(reader, CaravanFile.class);
Wallet wallet = new Wallet();
wallet.setName(cf.name);
wallet.setPolicyType(PolicyType.MULTI);
ScriptType scriptType = ScriptType.valueOf(cf.addressType.replace('-', '_'));
for (ExtPublicKey extKey : cf.extendedPublicKeys) {
Keystore keystore = new Keystore(extKey.name);
try {
keystore.setKeyDerivation(new KeyDerivation(extKey.xfp, extKey.bip32Path));
} catch (NumberFormatException e) {
keystore.setKeyDerivation(new KeyDerivation(extKey.xfp, scriptType.getDefaultDerivationPath()));
}
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(extKey.xpub));
WalletModel walletModel = WalletModel.fromType(extKey.method);
if (walletModel == null) {
keystore.setWalletModel(WalletModel.SPARROW);
keystore.setSource(KeystoreSource.SW_WATCH);
} else {
keystore.setWalletModel(walletModel);
keystore.setSource(KeystoreSource.HW_USB);
}
wallet.getKeystores().add(keystore);
}
wallet.setScriptType(scriptType);
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), cf.quorum.requiredSigners));
return wallet;
} catch (Exception e) {
throw new ImportException("Error importing " + getName() + " wallet", e);
}
}
use of com.sparrowwallet.drongo.KeyDerivation in project sparrow by sparrowwallet.
the class CoboVaultSinglesig method getKeystore.
@Override
public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException {
try {
Gson gson = new Gson();
CoboVaultSinglesigKeystore coboKeystore = gson.fromJson(new InputStreamReader(inputStream, StandardCharsets.UTF_8), CoboVaultSinglesigKeystore.class);
if (coboKeystore.MasterFingerprint == null || coboKeystore.AccountKeyPath == null || coboKeystore.ExtPubKey == null) {
throw new ImportException("Not a valid " + getName() + " keystore export");
}
Keystore keystore = new Keystore();
keystore.setLabel(getName());
keystore.setSource(KeystoreSource.HW_AIRGAPPED);
keystore.setWalletModel(WalletModel.COBO_VAULT);
keystore.setKeyDerivation(new KeyDerivation(coboKeystore.MasterFingerprint.toLowerCase(), "m/" + coboKeystore.AccountKeyPath));
keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(coboKeystore.ExtPubKey));
ExtendedKey.Header header = ExtendedKey.Header.fromExtendedKey(coboKeystore.ExtPubKey);
if (header.getDefaultScriptType() != scriptType) {
throw new ImportException("This wallet's script type (" + scriptType + ") does not match the " + getName() + " script type (" + header.getDefaultScriptType() + ")");
}
return keystore;
} catch (Exception e) {
throw new ImportException("Error getting " + getName() + " keystore", e);
}
}
Aggregations