Search in sources :

Example 21 with ECKey

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);
}
Also used : Keystore(com.sparrowwallet.drongo.wallet.Keystore) Wallet(com.sparrowwallet.drongo.wallet.Wallet) ECKey(com.sparrowwallet.drongo.crypto.ECKey) ChildNumber(com.sparrowwallet.drongo.crypto.ChildNumber)

Example 22 with ECKey

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());
}
Also used : InvalidPaymentCodeException(com.sparrowwallet.drongo.bip47.InvalidPaymentCodeException) PayNymAddress(com.sparrowwallet.sparrow.paynym.PayNymAddress) Address(com.sparrowwallet.drongo.address.Address) P2PKHAddress(com.sparrowwallet.drongo.address.P2PKHAddress) PayNymAddress(com.sparrowwallet.sparrow.paynym.PayNymAddress) ECKey(com.sparrowwallet.drongo.crypto.ECKey)

Example 23 with ECKey

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());
    }
}
Also used : ECKey(com.sparrowwallet.drongo.crypto.ECKey) SecureString(com.sparrowwallet.drongo.SecureString) SecretPoint(com.sparrowwallet.drongo.bip47.SecretPoint) PaymentCode(com.sparrowwallet.drongo.bip47.PaymentCode) PSBT(com.sparrowwallet.drongo.psbt.PSBT) ElectrumServer(com.sparrowwallet.sparrow.net.ElectrumServer) Storage(com.sparrowwallet.sparrow.io.Storage) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry)

Example 24 with ECKey

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;
}
Also used : KeyDerivation(com.sparrowwallet.drongo.KeyDerivation) ECKey(com.sparrowwallet.drongo.crypto.ECKey)

Example 25 with ECKey

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;
}
Also used : Address(com.sparrowwallet.drongo.address.Address) ECKey(com.sparrowwallet.drongo.crypto.ECKey) SignatureException(java.security.SignatureException) InvalidAddressException(com.sparrowwallet.drongo.address.InvalidAddressException)

Aggregations

ECKey (com.sparrowwallet.drongo.crypto.ECKey)45 Test (org.junit.Test)22 ByteArrayOutputStream (java.io.ByteArrayOutputStream)7 Address (com.sparrowwallet.drongo.address.Address)6 ChildNumber (com.sparrowwallet.drongo.crypto.ChildNumber)6 PaymentCode (com.sparrowwallet.drongo.bip47.PaymentCode)5 PSBT (com.sparrowwallet.drongo.psbt.PSBT)5 PSBTInput (com.sparrowwallet.drongo.psbt.PSBTInput)5 InvalidAddressException (com.sparrowwallet.drongo.address.InvalidAddressException)4 ScriptType (com.sparrowwallet.drongo.protocol.ScriptType)4 SecureString (com.sparrowwallet.drongo.SecureString)3 SecretPoint (com.sparrowwallet.drongo.bip47.SecretPoint)3 DeterministicKey (com.sparrowwallet.drongo.crypto.DeterministicKey)3 SchnorrSignature (com.sparrowwallet.drongo.crypto.SchnorrSignature)3 PSBTOutput (com.sparrowwallet.drongo.psbt.PSBTOutput)3 StandardCharsets (java.nio.charset.StandardCharsets)3 java.util (java.util)3 Collectors (java.util.stream.Collectors)3 Subscribe (com.google.common.eventbus.Subscribe)2 Files (com.google.common.io.Files)2