use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.
the class PayNymService method getSignature.
public String getSignature(Wallet wallet, String authToken) {
Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet();
Keystore keystore = masterWallet.getKeystores().get(0);
List<ChildNumber> derivation = keystore.getKeyDerivation().getDerivation();
ChildNumber derivationStart = derivation.isEmpty() ? ChildNumber.ZERO_HARDENED : derivation.get(derivation.size() - 1);
ECKey notificationPrivKey = keystore.getBip47ExtendedPrivateKey().getKey(List.of(derivationStart, new ChildNumber(0)));
return notificationPrivKey.signMessage(authToken, ScriptType.P2PKH);
}
use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.
the class PaymentController method getRecipientAddress.
private Address getRecipientAddress() throws InvalidAddressException {
if (payNymProperty.get() == null) {
return Address.fromString(address.getText());
}
try {
Wallet recipientBip47Wallet = getWalletForPayNym(payNymProperty.get());
if (recipientBip47Wallet != null) {
WalletNode sendNode = recipientBip47Wallet.getFreshNode(KeyPurpose.SEND);
ECKey pubKey = sendNode.getPubKey();
Address address = recipientBip47Wallet.getScriptType().getAddress(pubKey);
if (sendController.getPaymentTabs().getTabs().size() > 1 || (getRecipientValueSats() != null && getRecipientValueSats() > getRecipientDustThreshold(address)) || maxButton.isSelected()) {
return address;
}
}
} catch (InvalidPaymentCodeException e) {
log.error("Error creating payment code from PayNym", e);
}
return new PayNymAddress(payNymProperty.get());
}
use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.
the class PayNymController method broadcastNotificationTransaction.
private void broadcastNotificationTransaction(Wallet decryptedWallet, WalletTransaction walletTransaction, PaymentCode paymentCode, PayNym payNym) {
try {
PaymentCode externalPaymentCode = payNym.paymentCode();
WalletNode input0Node = walletTransaction.getSelectedUtxos().entrySet().iterator().next().getValue();
Keystore keystore = input0Node.getWallet().isNested() ? decryptedWallet.getChildWallet(input0Node.getWallet().getName()).getKeystores().get(0) : decryptedWallet.getKeystores().get(0);
ECKey input0Key = keystore.getKey(input0Node);
TransactionOutPoint input0Outpoint = walletTransaction.getTransaction().getInputs().iterator().next().getOutpoint();
SecretPoint secretPoint = new SecretPoint(input0Key.getPrivKeyBytes(), externalPaymentCode.getNotificationKey().getPubKey());
byte[] blindingMask = PaymentCode.getMask(secretPoint.ECDHSecretAsBytes(), input0Outpoint.bitcoinSerialize());
byte[] blindedPaymentCode = PaymentCode.blind(paymentCode.getPayload(), blindingMask);
WalletTransaction finalWalletTx = getWalletTransaction(decryptedWallet, payNym, blindedPaymentCode, walletTransaction.getSelectedUtxos().keySet());
PSBT psbt = finalWalletTx.createPSBT();
decryptedWallet.sign(psbt);
decryptedWallet.finalise(psbt);
Transaction transaction = psbt.extractTransaction();
ElectrumServer.BroadcastTransactionService broadcastTransactionService = new ElectrumServer.BroadcastTransactionService(transaction);
broadcastTransactionService.setOnSucceeded(successEvent -> {
ElectrumServer.TransactionMempoolService transactionMempoolService = new ElectrumServer.TransactionMempoolService(walletTransaction.getWallet(), transaction.getTxId(), new HashSet<>(walletTransaction.getSelectedUtxos().values()));
transactionMempoolService.setDelay(Duration.seconds(2));
transactionMempoolService.setPeriod(Duration.seconds(5));
transactionMempoolService.setRestartOnFailure(false);
transactionMempoolService.setOnSucceeded(mempoolWorkerStateEvent -> {
Set<String> scriptHashes = transactionMempoolService.getValue();
if (!scriptHashes.isEmpty()) {
transactionMempoolService.cancel();
List<Wallet> addedWallets = addChildWallets(payNym, externalPaymentCode);
Wallet masterWallet = getMasterWallet();
Storage storage = AppServices.get().getOpenWallets().get(masterWallet);
EventManager.get().post(new ChildWalletsAddedEvent(storage, masterWallet, addedWallets));
retrievePayNymProgress.setVisible(false);
followingList.refresh();
BlockTransaction blockTransaction = walletTransaction.getWallet().getWalletTransaction(transaction.getTxId());
if (blockTransaction != null && blockTransaction.getLabel() == null) {
blockTransaction.setLabel("Link " + payNym.nymName());
TransactionEntry transactionEntry = new TransactionEntry(walletTransaction.getWallet(), blockTransaction, Collections.emptyMap(), Collections.emptyMap());
EventManager.get().post(new WalletEntryLabelsChangedEvent(walletTransaction.getWallet(), List.of(transactionEntry)));
}
}
if (transactionMempoolService.getIterationCount() > 5 && transactionMempoolService.isRunning()) {
transactionMempoolService.cancel();
retrievePayNymProgress.setVisible(false);
followingList.refresh();
log.error("Timeout searching for broadcasted notification transaction");
AppServices.showErrorDialog("Timeout searching for broadcasted transaction", "The transaction was broadcast but the server did not register it in the mempool. It is safe to try linking again.");
}
});
transactionMempoolService.setOnFailed(mempoolWorkerStateEvent -> {
transactionMempoolService.cancel();
log.error("Error searching for broadcasted notification transaction", mempoolWorkerStateEvent.getSource().getException());
retrievePayNymProgress.setVisible(false);
followingList.refresh();
AppServices.showErrorDialog("Timeout searching for broadcasted transaction", "The transaction was broadcast but the server did not register it in the mempool. It is safe to try linking again.");
});
transactionMempoolService.start();
});
broadcastTransactionService.setOnFailed(failedEvent -> {
log.error("Error broadcasting notification transaction", failedEvent.getSource().getException());
retrievePayNymProgress.setVisible(false);
followingList.refresh();
AppServices.showErrorDialog("Error broadcasting notification transaction", failedEvent.getSource().getException().getMessage());
});
retrievePayNymProgress.setVisible(true);
notificationTransactions.put(transaction.getTxId(), payNym);
broadcastTransactionService.start();
} catch (Exception e) {
log.error("Error creating notification transaction", e);
retrievePayNymProgress.setVisible(false);
followingList.refresh();
AppServices.showErrorDialog("Error creating notification transaction", e.getMessage());
}
}
use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.
the class InputController method describeScriptChunk.
@Override
protected String describeScriptChunk(ScriptChunk chunk) {
String chunkString = super.describeScriptChunk(chunk);
ECKey pubKey = null;
if (chunk.isSignature()) {
if (inputForm.getPsbtInput() != null) {
TransactionSignature signature = chunk.getSignature();
pubKey = inputForm.getPsbtInput().getKeyForSignature(signature);
}
} else if (chunk.isPubKey()) {
pubKey = chunk.getPubKey();
}
if (inputForm.getPsbtInput() != null) {
KeyDerivation derivation = inputForm.getPsbtInput().getKeyDerivation(pubKey);
if (derivation != null) {
return "[" + derivation.toString() + "] " + chunkString;
}
}
return chunkString;
}
use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.
the class VersionCheckService method verifySignature.
private boolean verifySignature(VersionCheck versionCheck) {
try {
for (String addressString : versionCheck.signatures.keySet()) {
if (!addressString.equals("1LiJx1HQ49L2LzhBwbgwXdHiGodvPg5YaV")) {
log.warn("Invalid address for version check " + addressString);
continue;
}
String signature = versionCheck.signatures.get(addressString);
ECKey signedMessageKey = ECKey.signedMessageToKey(versionCheck.version, signature, false);
Address providedAddress = Address.fromString(addressString);
Address signedMessageAddress = ScriptType.P2PKH.getAddress(signedMessageKey);
if (providedAddress.equals(signedMessageAddress)) {
return true;
} else {
log.warn("Invalid signature for version check " + signature + " from address " + addressString);
}
}
} catch (SignatureException e) {
log.error("Error in version check signature", e);
} catch (InvalidAddressException e) {
log.error("Error in version check address", e);
}
return false;
}
Aggregations