Search in sources :

Example 1 with TransactionEntry

use of com.sparrowwallet.sparrow.wallet.TransactionEntry in project sparrow by sparrowwallet.

the class BalanceChart method update.

public void update(WalletTransactionsEntry walletTransactionsEntry) {
    setVisible(!walletTransactionsEntry.getChildren().isEmpty());
    balanceSeries.getData().clear();
    List<Data<Number, Number>> balanceDataList = getTransactionEntries(walletTransactionsEntry).map(entry -> (TransactionEntry) entry).filter(txEntry -> txEntry.getBlockTransaction().getHeight() > 0).map(txEntry -> new XYChart.Data<>((Number) txEntry.getBlockTransaction().getDate().getTime(), (Number) txEntry.getBalance(), txEntry)).collect(Collectors.toList());
    int size = balanceDataList.size() * 2;
    for (int i = 0; i < size; i += 2) {
        Data<Number, Number> data = balanceDataList.get(i);
        if (i + 1 < balanceDataList.size()) {
            Data<Number, Number> nextData = balanceDataList.get(i + 1);
            Data<Number, Number> interstitialData = new Data<>(nextData.getXValue(), data.getYValue(), null);
            balanceDataList.add(i + 1, interstitialData);
        } else {
            Date now = new Date();
            Data<Number, Number> interstitialData = new Data<>(now.getTime(), data.getYValue(), null);
            balanceDataList.add(interstitialData);
        }
    }
    if (!balanceDataList.isEmpty()) {
        long min = balanceDataList.stream().map(data -> data.getXValue().longValue()).min(Long::compare).get();
        long max = balanceDataList.stream().map(data -> data.getXValue().longValue()).max(Long::compare).get();
        DateAxisFormatter dateAxisFormatter = new DateAxisFormatter(max - min);
        NumberAxis xAxis = (NumberAxis) getXAxis();
        xAxis.setTickLabelFormatter(dateAxisFormatter);
    }
    balanceSeries.getData().addAll(balanceDataList);
    if (selectedEntry != null) {
        select(selectedEntry);
    }
}
Also used : NamedArg(javafx.beans.NamedArg) Wallet(com.sparrowwallet.drongo.wallet.Wallet) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) Date(java.util.Date) Node(javafx.scene.Node) Set(java.util.Set) Config(com.sparrowwallet.sparrow.io.Config) Collectors(java.util.stream.Collectors) Entry(com.sparrowwallet.sparrow.wallet.Entry) ArrayList(java.util.ArrayList) BitcoinUnit(com.sparrowwallet.drongo.BitcoinUnit) List(java.util.List) Lists(com.google.common.collect.Lists) Stream(java.util.stream.Stream) WalletTransactionsEntry(com.sparrowwallet.sparrow.wallet.WalletTransactionsEntry) javafx.scene.chart(javafx.scene.chart) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) Date(java.util.Date)

Example 2 with TransactionEntry

use of com.sparrowwallet.sparrow.wallet.TransactionEntry in project sparrow by sparrowwallet.

the class CoinCell method updateItem.

@Override
protected void updateItem(Number amount, boolean empty) {
    super.updateItem(amount, empty);
    if (empty || amount == null) {
        setText(null);
        setGraphic(null);
        setTooltip(null);
    } else {
        Entry entry = getTreeTableView().getTreeItem(getIndex()).getValue();
        EntryCell.applyRowStyles(this, entry);
        CoinTreeTable coinTreeTable = (CoinTreeTable) getTreeTableView();
        BitcoinUnit unit = coinTreeTable.getBitcoinUnit();
        String satsValue = String.format(Locale.ENGLISH, "%,d", amount.longValue());
        DecimalFormat decimalFormat = (amount.longValue() == 0L ? CoinLabel.getBTCFormat() : TABLE_BTC_FORMAT);
        final String btcValue = decimalFormat.format(amount.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN);
        if (unit.equals(BitcoinUnit.BTC)) {
            tooltip.setText(satsValue + " " + BitcoinUnit.SATOSHIS.getLabel());
            setText(btcValue);
        } else {
            tooltip.setText(btcValue + " " + BitcoinUnit.BTC.getLabel());
            setText(satsValue);
        }
        setTooltip(tooltip);
        String tooltipValue = tooltip.getText();
        if (entry instanceof TransactionEntry) {
            TransactionEntry transactionEntry = (TransactionEntry) entry;
            tooltip.setText(tooltipValue + " (" + transactionEntry.getConfirmationsDescription() + ")");
            transactionEntry.confirmationsProperty().addListener((observable, oldValue, newValue) -> {
                tooltip.setText(tooltipValue + " (" + transactionEntry.getConfirmationsDescription() + ")");
            });
            if (transactionEntry.isConfirming()) {
                ConfirmationProgressIndicator arc = new ConfirmationProgressIndicator(transactionEntry.getConfirmations());
                arc.confirmationsProperty().bind(transactionEntry.confirmationsProperty());
                setGraphic(arc);
                setContentDisplay(ContentDisplay.LEFT);
            } else {
                setGraphic(null);
            }
            if (amount.longValue() < 0) {
                getStyleClass().add("negative-amount");
            }
        } else if (entry instanceof UtxoEntry) {
            setGraphic(null);
        } else if (entry instanceof HashIndexEntry) {
            Region node = new Region();
            node.setPrefWidth(10);
            setGraphic(node);
            setContentDisplay(ContentDisplay.RIGHT);
            if (((HashIndexEntry) entry).getType() == HashIndexEntry.Type.INPUT) {
                satsValue = "-" + satsValue;
            }
        } else {
            setGraphic(null);
        }
    }
}
Also used : BitcoinUnit(com.sparrowwallet.drongo.BitcoinUnit) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) Entry(com.sparrowwallet.sparrow.wallet.Entry) UtxoEntry(com.sparrowwallet.sparrow.wallet.UtxoEntry) HashIndexEntry(com.sparrowwallet.sparrow.wallet.HashIndexEntry) DecimalFormat(java.text.DecimalFormat) Region(javafx.scene.layout.Region) UtxoEntry(com.sparrowwallet.sparrow.wallet.UtxoEntry) HashIndexEntry(com.sparrowwallet.sparrow.wallet.HashIndexEntry) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry)

Example 3 with TransactionEntry

use of com.sparrowwallet.sparrow.wallet.TransactionEntry in project sparrow by sparrowwallet.

the class PayNymController method walletHistoryChanged.

@Subscribe
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
    List<Entry> changedLabelEntries = new ArrayList<>();
    for (Map.Entry<Sha256Hash, PayNym> notificationTx : notificationTransactions.entrySet()) {
        BlockTransaction blockTransaction = event.getWallet().getWalletTransaction(notificationTx.getKey());
        if (blockTransaction != null && blockTransaction.getLabel() == null) {
            blockTransaction.setLabel("Link " + notificationTx.getValue().nymName());
            changedLabelEntries.add(new TransactionEntry(event.getWallet(), blockTransaction, Collections.emptyMap(), Collections.emptyMap()));
        }
    }
    if (!changedLabelEntries.isEmpty()) {
        Platform.runLater(() -> EventManager.get().post(new WalletEntryLabelsChangedEvent(event.getWallet(), changedLabelEntries)));
    }
}
Also used : TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) Entry(com.sparrowwallet.sparrow.wallet.Entry) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) Subscribe(com.google.common.eventbus.Subscribe)

Example 4 with TransactionEntry

use of com.sparrowwallet.sparrow.wallet.TransactionEntry in project sparrow by sparrowwallet.

the class PayNymController method addWalletIfNotificationTransactionPresent.

private void addWalletIfNotificationTransactionPresent(Wallet decryptedWallet, Map<BlockTransaction, PayNym> unlinkedPayNyms, Map<BlockTransaction, WalletNode> unlinkedNotifications) {
    List<Wallet> addedWallets = new ArrayList<>();
    for (BlockTransaction blockTransaction : unlinkedNotifications.keySet()) {
        try {
            PayNym payNym = unlinkedPayNyms.get(blockTransaction);
            PaymentCode externalPaymentCode = payNym.paymentCode();
            WalletNode input0Node = unlinkedNotifications.get(blockTransaction);
            Keystore keystore = input0Node.getWallet().isNested() ? decryptedWallet.getChildWallet(input0Node.getWallet().getName()).getKeystores().get(0) : decryptedWallet.getKeystores().get(0);
            ECKey input0Key = keystore.getKey(input0Node);
            TransactionOutPoint input0Outpoint = PaymentCode.getDesignatedInput(blockTransaction.getTransaction()).getOutpoint();
            SecretPoint secretPoint = new SecretPoint(input0Key.getPrivKeyBytes(), externalPaymentCode.getNotificationKey().getPubKey());
            byte[] blindingMask = PaymentCode.getMask(secretPoint.ECDHSecretAsBytes(), input0Outpoint.bitcoinSerialize());
            byte[] blindedPaymentCode = PaymentCode.blind(getMasterWallet().getPaymentCode().getPayload(), blindingMask);
            byte[] opReturnData = PaymentCode.getOpReturnData(blockTransaction.getTransaction());
            if (Arrays.equals(opReturnData, blindedPaymentCode)) {
                addedWallets.addAll(addChildWallets(payNym, externalPaymentCode));
            } else {
                blockTransaction.setLabel(INVALID_PAYMENT_CODE_LABEL);
                EventManager.get().post(new WalletEntryLabelsChangedEvent(input0Node.getWallet(), new TransactionEntry(input0Node.getWallet(), blockTransaction, Collections.emptyMap(), Collections.emptyMap())));
            }
        } catch (Exception e) {
            log.error("Error adding linked contact from notification transaction", e);
        }
    }
    if (!addedWallets.isEmpty()) {
        Wallet masterWallet = getMasterWallet();
        Storage storage = AppServices.get().getOpenWallets().get(masterWallet);
        EventManager.get().post(new ChildWalletsAddedEvent(storage, masterWallet, addedWallets));
        followingList.refresh();
    }
}
Also used : PaymentCode(com.sparrowwallet.drongo.bip47.PaymentCode) ECKey(com.sparrowwallet.drongo.crypto.ECKey) Storage(com.sparrowwallet.sparrow.io.Storage) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) SecretPoint(com.sparrowwallet.drongo.bip47.SecretPoint)

Example 5 with TransactionEntry

use of com.sparrowwallet.sparrow.wallet.TransactionEntry 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)

Aggregations

TransactionEntry (com.sparrowwallet.sparrow.wallet.TransactionEntry)6 Entry (com.sparrowwallet.sparrow.wallet.Entry)4 Subscribe (com.google.common.eventbus.Subscribe)2 BitcoinUnit (com.sparrowwallet.drongo.BitcoinUnit)2 SecureString (com.sparrowwallet.drongo.SecureString)2 PaymentCode (com.sparrowwallet.drongo.bip47.PaymentCode)2 SecretPoint (com.sparrowwallet.drongo.bip47.SecretPoint)2 ECKey (com.sparrowwallet.drongo.crypto.ECKey)2 Storage (com.sparrowwallet.sparrow.io.Storage)2 HashIndexEntry (com.sparrowwallet.sparrow.wallet.HashIndexEntry)2 Lists (com.google.common.collect.Lists)1 PSBT (com.sparrowwallet.drongo.psbt.PSBT)1 Wallet (com.sparrowwallet.drongo.wallet.Wallet)1 Config (com.sparrowwallet.sparrow.io.Config)1 ElectrumServer (com.sparrowwallet.sparrow.net.ElectrumServer)1 UtxoEntry (com.sparrowwallet.sparrow.wallet.UtxoEntry)1 WalletTransactionsEntry (com.sparrowwallet.sparrow.wallet.WalletTransactionsEntry)1 DecimalFormat (java.text.DecimalFormat)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1