mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
handle support for multiple payments in a tx
This commit is contained in:
parent
4ea5ec6c0a
commit
ee9247c066
4 changed files with 59 additions and 25 deletions
|
@ -52,7 +52,9 @@ dependencies {
|
||||||
exclude group: 'org.slf4j'
|
exclude group: 'org.slf4j'
|
||||||
}
|
}
|
||||||
implementation('com.sparrowwallet:hummingbird:1.2')
|
implementation('com.sparrowwallet:hummingbird:1.2')
|
||||||
implementation('com.nativelibs4java:bridj:0.7-20140918-3')
|
implementation('com.nativelibs4java:bridj:0.7-20140918-3') {
|
||||||
|
exclude group: 'com.google.android.tools', module: 'dx'
|
||||||
|
}
|
||||||
implementation('com.github.sarxos:webcam-capture:0.3.13-SNAPSHOT') {
|
implementation('com.github.sarxos:webcam-capture:0.3.13-SNAPSHOT') {
|
||||||
exclude group: 'com.nativelibs4java', module: 'bridj'
|
exclude group: 'com.nativelibs4java', module: 'bridj'
|
||||||
}
|
}
|
||||||
|
|
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 661e88447f232e44f96f69ee795f151233099ed6
|
Subproject commit 8b07336d71f32094acb8eb8c162ebd8621ffc4aa
|
|
@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Payment;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletTransaction;
|
import com.sparrowwallet.drongo.wallet.WalletTransaction;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
@ -26,6 +27,7 @@ import java.util.*;
|
||||||
|
|
||||||
public class TransactionDiagram extends GridPane {
|
public class TransactionDiagram extends GridPane {
|
||||||
private static final int MAX_UTXOS = 8;
|
private static final int MAX_UTXOS = 8;
|
||||||
|
private static final int MAX_PAYMENTS = 6;
|
||||||
private static final double DIAGRAM_HEIGHT = 230.0;
|
private static final double DIAGRAM_HEIGHT = 230.0;
|
||||||
private static final int TOOLTIP_SHOW_DELAY = 50;
|
private static final int TOOLTIP_SHOW_DELAY = 50;
|
||||||
|
|
||||||
|
@ -55,10 +57,12 @@ public class TransactionDiagram extends GridPane {
|
||||||
Pane txPane = getTransactionPane();
|
Pane txPane = getTransactionPane();
|
||||||
GridPane.setConstraints(txPane, 3, 0);
|
GridPane.setConstraints(txPane, 3, 0);
|
||||||
|
|
||||||
Pane outputsLinesPane = getOutputsLines();
|
List<Payment> displayedPayments = getDisplayedPayments();
|
||||||
|
|
||||||
|
Pane outputsLinesPane = getOutputsLines(displayedPayments);
|
||||||
GridPane.setConstraints(outputsLinesPane, 4, 0);
|
GridPane.setConstraints(outputsLinesPane, 4, 0);
|
||||||
|
|
||||||
Pane outputsPane = getOutputsLabels();
|
Pane outputsPane = getOutputsLabels(displayedPayments);
|
||||||
GridPane.setConstraints(outputsPane, 5, 0);
|
GridPane.setConstraints(outputsPane, 5, 0);
|
||||||
|
|
||||||
getChildren().clear();
|
getChildren().clear();
|
||||||
|
@ -241,7 +245,28 @@ public class TransactionDiagram extends GridPane {
|
||||||
return value * (1.0 - scaleFactor) + additional;
|
return value * (1.0 - scaleFactor) + additional;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pane getOutputsLines() {
|
private List<Payment> getDisplayedPayments() {
|
||||||
|
List<Payment> payments = walletTx.getPayments();
|
||||||
|
|
||||||
|
if(payments.size() > MAX_PAYMENTS) {
|
||||||
|
List<Payment> displayedPayments = new ArrayList<>();
|
||||||
|
List<Payment> additional = new ArrayList<>();
|
||||||
|
for(Payment payment : payments) {
|
||||||
|
if(displayedPayments.size() < MAX_PAYMENTS) {
|
||||||
|
displayedPayments.add(payment);
|
||||||
|
} else {
|
||||||
|
additional.add(payment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displayedPayments.add(new AdditionalPayment(additional));
|
||||||
|
return displayedPayments;
|
||||||
|
} else {
|
||||||
|
return payments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pane getOutputsLines(List<Payment> displayedPayments) {
|
||||||
VBox pane = new VBox();
|
VBox pane = new VBox();
|
||||||
Group group = new Group();
|
Group group = new Group();
|
||||||
VBox.setVgrow(group, Priority.ALWAYS);
|
VBox.setVgrow(group, Priority.ALWAYS);
|
||||||
|
@ -255,7 +280,7 @@ public class TransactionDiagram extends GridPane {
|
||||||
group.getChildren().add(yaxisLine);
|
group.getChildren().add(yaxisLine);
|
||||||
|
|
||||||
double width = 140.0;
|
double width = 140.0;
|
||||||
int numOutputs = (walletTx.getChangeNode() == null ? 2 : 3);
|
int numOutputs = displayedPayments.size() + (walletTx.getChangeNode() == null ? 1 : 2);
|
||||||
for(int i = 1; i <= numOutputs; i++) {
|
for(int i = 1; i <= numOutputs; i++) {
|
||||||
CubicCurve curve = new CubicCurve();
|
CubicCurve curve = new CubicCurve();
|
||||||
curve.getStyleClass().add("output-line");
|
curve.getStyleClass().add("output-line");
|
||||||
|
@ -280,23 +305,25 @@ public class TransactionDiagram extends GridPane {
|
||||||
return pane;
|
return pane;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pane getOutputsLabels() {
|
private Pane getOutputsLabels(List<Payment> displayedPayments) {
|
||||||
VBox outputsBox = new VBox();
|
VBox outputsBox = new VBox();
|
||||||
outputsBox.setMaxWidth(150);
|
outputsBox.setMaxWidth(150);
|
||||||
outputsBox.setPadding(new Insets(0, 20, 0, 10));
|
outputsBox.setPadding(new Insets(0, 20, 0, 10));
|
||||||
outputsBox.setAlignment(Pos.CENTER_LEFT);
|
outputsBox.setAlignment(Pos.CENTER_LEFT);
|
||||||
outputsBox.getChildren().add(createSpacer());
|
outputsBox.getChildren().add(createSpacer());
|
||||||
|
|
||||||
boolean isConsolidation = walletTx.isConsolidationSend();
|
for(Payment payment : displayedPayments) {
|
||||||
String recipientDesc = walletTx.getRecipientAddress().toString().substring(0, 8) + "...";
|
boolean isConsolidation = walletTx.isConsolidationSend(payment);
|
||||||
Label recipientLabel = new Label(recipientDesc, isConsolidation ? getConsolidationGlyph() : getPaymentGlyph());
|
String recipientDesc = payment instanceof AdditionalPayment ? payment.getLabel() : payment.getAddress().toString().substring(0, 8) + "...";
|
||||||
recipientLabel.getStyleClass().addAll("output-label", "recipient-label");
|
Label recipientLabel = new Label(recipientDesc, isConsolidation ? getConsolidationGlyph() : getPaymentGlyph());
|
||||||
Tooltip recipientTooltip = new Tooltip((isConsolidation ? "Consolidate " : "Pay ") + getSatsValue(walletTx.getRecipientAmount()) + " sats to\n" + walletTx.getRecipientAddress().toString());
|
recipientLabel.getStyleClass().addAll("output-label", "recipient-label");
|
||||||
recipientTooltip.getStyleClass().add("recipient-label");
|
Tooltip recipientTooltip = new Tooltip((isConsolidation ? "Consolidate " : "Pay ") + getSatsValue(payment.getAmount()) + " sats to\n" + payment.getAddress().toString());
|
||||||
recipientTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY));
|
recipientTooltip.getStyleClass().add("recipient-label");
|
||||||
recipientLabel.setTooltip(recipientTooltip);
|
recipientTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY));
|
||||||
outputsBox.getChildren().add(recipientLabel);
|
recipientLabel.setTooltip(recipientTooltip);
|
||||||
outputsBox.getChildren().add(createSpacer());
|
outputsBox.getChildren().add(recipientLabel);
|
||||||
|
outputsBox.getChildren().add(createSpacer());
|
||||||
|
}
|
||||||
|
|
||||||
if(walletTx.getChangeNode() != null) {
|
if(walletTx.getChangeNode() != null) {
|
||||||
String changeDesc = walletTx.getChangeAddress().toString().substring(0, 8) + "...";
|
String changeDesc = walletTx.getChangeAddress().toString().substring(0, 8) + "...";
|
||||||
|
@ -412,4 +439,10 @@ public class TransactionDiagram extends GridPane {
|
||||||
return additionalInputs;
|
return additionalInputs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class AdditionalPayment extends Payment {
|
||||||
|
public AdditionalPayment(List<Payment> additionalPayments) {
|
||||||
|
super(null, additionalPayments.size() + " more...", additionalPayments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,9 +275,9 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
|
|
||||||
walletTransactionProperty.addListener((observable, oldValue, walletTransaction) -> {
|
walletTransactionProperty.addListener((observable, oldValue, walletTransaction) -> {
|
||||||
if(walletTransaction != null) {
|
if(walletTransaction != null) {
|
||||||
if(getRecipientValueSats() == null || walletTransaction.getRecipientAmount() != getRecipientValueSats()) {
|
if(getRecipientValueSats() == null || walletTransaction.getPayments().get(0).getAmount() != getRecipientValueSats()) {
|
||||||
setRecipientValueSats(walletTransaction.getRecipientAmount());
|
setRecipientValueSats(walletTransaction.getPayments().get(0).getAmount());
|
||||||
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), walletTransaction.getRecipientAmount());
|
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), walletTransaction.getPayments().get(0).getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
double feeRate = walletTransaction.getFeeRate();
|
double feeRate = walletTransaction.getFeeRate();
|
||||||
|
@ -329,11 +329,12 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
Long recipientAmount = sendAll ? Long.valueOf(recipientDustThreshold + 1) : getRecipientValueSats();
|
Long recipientAmount = sendAll ? Long.valueOf(recipientDustThreshold + 1) : getRecipientValueSats();
|
||||||
if(recipientAmount != null && recipientAmount > recipientDustThreshold && (!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0))) {
|
if(recipientAmount != null && recipientAmount > recipientDustThreshold && (!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0))) {
|
||||||
Wallet wallet = getWalletForm().getWallet();
|
Wallet wallet = getWalletForm().getWallet();
|
||||||
|
List<Payment> payments = List.of(new Payment(recipientAddress, label.getText(), recipientAmount, sendAll));
|
||||||
Long userFee = userFeeSet.get() ? getFeeValueSats() : null;
|
Long userFee = userFeeSet.get() ? getFeeValueSats() : null;
|
||||||
Integer currentBlockHeight = AppController.getCurrentBlockHeight();
|
Integer currentBlockHeight = AppController.getCurrentBlockHeight();
|
||||||
boolean groupByAddress = Config.get().isGroupByAddress();
|
boolean groupByAddress = Config.get().isGroupByAddress();
|
||||||
boolean includeMempoolChange = Config.get().isIncludeMempoolChange();
|
boolean includeMempoolChange = Config.get().isIncludeMempoolChange();
|
||||||
WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), recipientAddress, recipientAmount, getFeeRate(), getMinimumFeeRate(), userFee, currentBlockHeight, sendAll, groupByAddress, includeMempoolChange);
|
WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), payments, getFeeRate(), getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolChange);
|
||||||
walletTransactionProperty.setValue(walletTransaction);
|
walletTransactionProperty.setValue(walletTransaction);
|
||||||
insufficientInputsProperty.set(false);
|
insufficientInputsProperty.set(false);
|
||||||
|
|
||||||
|
@ -611,10 +612,8 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
WalletTransaction walletTransaction = walletTransactionProperty.get();
|
WalletTransaction walletTransaction = walletTransactionProperty.get();
|
||||||
Set<WalletNode> nodes = new LinkedHashSet<>(walletTransaction.getSelectedUtxos().values());
|
Set<WalletNode> nodes = new LinkedHashSet<>(walletTransaction.getSelectedUtxos().values());
|
||||||
nodes.add(walletTransaction.getChangeNode());
|
nodes.add(walletTransaction.getChangeNode());
|
||||||
WalletNode consolidationNode = walletTransaction.getConsolidationSendNode();
|
List<WalletNode> consolidationNodes = walletTransaction.getConsolidationSendNodes();
|
||||||
if(consolidationNode != null) {
|
nodes.addAll(consolidationNodes);
|
||||||
nodes.add(consolidationNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
//All wallet nodes applicable to this transaction are stored so when the subscription status for one is updated, the history for all can be fetched in one atomic update
|
//All wallet nodes applicable to this transaction are stored so when the subscription status for one is updated, the history for all can be fetched in one atomic update
|
||||||
walletForm.addWalletTransactionNodes(nodes);
|
walletForm.addWalletTransactionNodes(nodes);
|
||||||
|
|
Loading…
Reference in a new issue