mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-22 06:41:41 +01:00
Separate fees in trade complete screen. Show withdrawal btc address only after button click
This commit is contained in:
parent
2137522e1f
commit
2b248c5426
4 changed files with 103 additions and 54 deletions
|
@ -560,7 +560,9 @@ portfolio.pending.step3_seller.onPaymentReceived.confirm.headline=Confirm that y
|
|||
portfolio.pending.step3_seller.onPaymentReceived.confirm.yes=Yes, I have received the payment
|
||||
|
||||
portfolio.pending.step5_buyer.groupTitle=Summary of completed trade
|
||||
portfolio.pending.step5_buyer.totalPaid=Total fees paid:
|
||||
portfolio.pending.step5_buyer.tradeFee=Trade fee:
|
||||
portfolio.pending.step5_buyer.makersMiningFee=Mining fee:
|
||||
portfolio.pending.step5_buyer.takersMiningFee=Total mining fees:
|
||||
portfolio.pending.step5_buyer.refunded=Refunded security deposit:
|
||||
portfolio.pending.step5_buyer.withdrawBTC=Withdraw your bitcoin
|
||||
portfolio.pending.step5_buyer.amount=Amount to withdraw:
|
||||
|
|
|
@ -223,24 +223,45 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
return tradeManager.isMyOffer(offer);
|
||||
}
|
||||
|
||||
private boolean isMaker() {
|
||||
public boolean isMaker() {
|
||||
return isMaker;
|
||||
}
|
||||
|
||||
Coin getTotalFees() {
|
||||
Coin getTradeFeeInBTC() {
|
||||
Trade trade = getTrade();
|
||||
if (trade != null) {
|
||||
Offer offer = trade.getOffer();
|
||||
if (isMaker()) {
|
||||
if (offer.isCurrencyForMakerFeeBtc())
|
||||
return offer.getMakerFee();
|
||||
else
|
||||
return Coin.ZERO;// getTradeFeeAsBsq is used for BSQ
|
||||
} else {
|
||||
if (trade.isCurrencyForTakerFeeBtc())
|
||||
return trade.getTakerFee();
|
||||
else
|
||||
return Coin.ZERO; // getTradeFeeAsBsq is used for BSQ
|
||||
}
|
||||
} else {
|
||||
log.error("Trade is null at getTotalFees");
|
||||
return Coin.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
Coin getTxFee() {
|
||||
Trade trade = getTrade();
|
||||
if (trade != null) {
|
||||
if (isMaker()) {
|
||||
Offer offer = trade.getOffer();
|
||||
if (offer.isCurrencyForMakerFeeBtc())
|
||||
return offer.getMakerFee().add(offer.getTxFee());
|
||||
return offer.getTxFee();
|
||||
else
|
||||
return offer.getTxFee().subtract(offer.getMakerFee());
|
||||
return offer.getTxFee().subtract(offer.getMakerFee()); // BSQ will be used as part of the miner fee
|
||||
} else {
|
||||
if (trade.isCurrencyForTakerFeeBtc())
|
||||
return trade.getTakerFee().add(trade.getTxFee().multiply(3));
|
||||
return trade.getTxFee().multiply(3);
|
||||
else
|
||||
return trade.getTxFee().multiply(3).subtract(trade.getTakerFee());
|
||||
return trade.getTxFee().multiply(3).subtract(trade.getTakerFee()); // BSQ will be used as part of the miner fee
|
||||
}
|
||||
} else {
|
||||
log.error("Trade is null at getTotalFees");
|
||||
|
@ -254,12 +275,12 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
if (isMaker()) {
|
||||
Offer offer = trade.getOffer();
|
||||
if (offer.isCurrencyForMakerFeeBtc())
|
||||
return Coin.ZERO;
|
||||
return Coin.ZERO; // getTradeFeeInBTC is used for BTC
|
||||
else
|
||||
return offer.getMakerFee();
|
||||
} else {
|
||||
if (trade.isCurrencyForTakerFeeBtc())
|
||||
return Coin.ZERO;
|
||||
return Coin.ZERO; // getTradeFeeInBTC is used for BTC
|
||||
else
|
||||
return trade.getTakerFee();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,9 @@ import io.bisq.gui.util.BsqFormatter;
|
|||
import io.bisq.gui.util.GUIUtil;
|
||||
import io.bisq.gui.util.validation.BtcAddressValidator;
|
||||
import io.bisq.network.p2p.P2PService;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
|
@ -242,15 +244,24 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
return dataModel.getTrade() != null ? btcFormatter.formatVolumeWithCode(dataModel.getTrade().getTradeVolume()) : "";
|
||||
}
|
||||
|
||||
public String getTotalFees() {
|
||||
Coin totalFees = dataModel.getTotalFees();
|
||||
if (trade != null && totalFees.isPositive()) {
|
||||
Coin tradeFeeAsBsq = dataModel.getTradeFeeAsBsq();
|
||||
String percentage = GUIUtil.getPercentageOfTradeAmount(totalFees, trade.getTradeAmount(), btcFormatter);
|
||||
if (tradeFeeAsBsq.isPositive()) {
|
||||
return btcFormatter.formatCoinWithCode(totalFees) + percentage + " + " + bsqFormatter.formatCoinWithCode(tradeFeeAsBsq);
|
||||
public String getTxFee() {
|
||||
if (trade != null) {
|
||||
Coin txFee = dataModel.getTxFee();
|
||||
String percentage = GUIUtil.getPercentageOfTradeAmount(txFee, trade.getTradeAmount(), btcFormatter);
|
||||
return btcFormatter.formatCoinWithCode(txFee) + percentage;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String getTradeFee() {
|
||||
if (trade != null && dataModel.getOffer() != null) {
|
||||
if (dataModel.getOffer().isCurrencyForMakerFeeBtc()) {
|
||||
Coin tradeFeeInBTC = dataModel.getTradeFeeInBTC();
|
||||
String percentage = GUIUtil.getPercentageOfTradeAmount(tradeFeeInBTC, trade.getTradeAmount(), btcFormatter);
|
||||
return btcFormatter.formatCoinWithCode(tradeFeeInBTC) + percentage;
|
||||
} else {
|
||||
return btcFormatter.formatCoinWithCode(totalFees) + percentage;
|
||||
return bsqFormatter.formatCoinWithCode(dataModel.getTradeFeeAsBsq());
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
|
|
|
@ -23,6 +23,7 @@ import io.bisq.common.app.Log;
|
|||
import io.bisq.common.handlers.FaultHandler;
|
||||
import io.bisq.common.handlers.ResultHandler;
|
||||
import io.bisq.common.locale.Res;
|
||||
import io.bisq.common.util.Tuple2;
|
||||
import io.bisq.core.btc.AddressEntry;
|
||||
import io.bisq.core.btc.AddressEntryException;
|
||||
import io.bisq.core.btc.InsufficientFundsException;
|
||||
|
@ -31,6 +32,7 @@ import io.bisq.core.btc.wallet.BtcWalletService;
|
|||
import io.bisq.core.user.DontShowAgainLookup;
|
||||
import io.bisq.core.util.CoinUtil;
|
||||
import io.bisq.gui.components.InputTextField;
|
||||
import io.bisq.gui.components.TitledGroupBg;
|
||||
import io.bisq.gui.main.MainView;
|
||||
import io.bisq.gui.main.funds.FundsView;
|
||||
import io.bisq.gui.main.funds.transactions.TransactionsView;
|
||||
|
@ -60,6 +62,8 @@ public class BuyerStep4View extends TradeStepView {
|
|||
|
||||
private InputTextField withdrawAddressTextField;
|
||||
private Button withdrawToExternalWalletButton, useSavingsWalletButton;
|
||||
private TitledGroupBg withdrawTitledGroupBg;
|
||||
private Label withdrawAddressLabel;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -114,15 +118,25 @@ public class BuyerStep4View extends TradeStepView {
|
|||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
protected void addContent() {
|
||||
addTitledGroupBg(gridPane, gridRow, 4, Res.get("portfolio.pending.step5_buyer.groupTitle"), 0);
|
||||
addTitledGroupBg(gridPane, gridRow, 5, Res.get("portfolio.pending.step5_buyer.groupTitle"), 0);
|
||||
addLabelTextField(gridPane, gridRow, getBtcTradeAmountLabel(), model.getTradeVolume(), Layout.FIRST_ROW_DISTANCE);
|
||||
|
||||
addLabelTextField(gridPane, ++gridRow, getFiatTradeAmountLabel(), model.getFiatVolume());
|
||||
addLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.totalPaid"), model.getTotalFees());
|
||||
addLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.refunded"), model.getSecurityDeposit());
|
||||
addTitledGroupBg(gridPane, ++gridRow, 2, Res.get("portfolio.pending.step5_buyer.withdrawBTC"), Layout.GROUP_DISTANCE);
|
||||
addLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.tradeFee"), model.getTradeFee());
|
||||
final String miningFee = model.dataModel.isMaker() ?
|
||||
Res.get("portfolio.pending.step5_buyer.makersMiningFee") :
|
||||
Res.get("portfolio.pending.step5_buyer.takersMiningFee");
|
||||
addLabelTextField(gridPane, ++gridRow, miningFee, model.getTxFee());
|
||||
withdrawTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, Res.get("portfolio.pending.step5_buyer.withdrawBTC"), Layout.GROUP_DISTANCE);
|
||||
addLabelTextField(gridPane, gridRow, Res.get("portfolio.pending.step5_buyer.amount"), model.getPayoutAmount(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
withdrawAddressTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.withdrawToAddress")).second;
|
||||
final Tuple2<Label, InputTextField> tuple2 = addLabelInputTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.withdrawToAddress"));
|
||||
withdrawAddressLabel = tuple2.first;
|
||||
withdrawAddressLabel.setManaged(false);
|
||||
withdrawAddressLabel.setVisible(false);
|
||||
withdrawAddressTextField = tuple2.second;
|
||||
withdrawAddressTextField.setManaged(false);
|
||||
withdrawAddressTextField.setVisible(false);
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setSpacing(10);
|
||||
|
@ -142,7 +156,7 @@ public class BuyerStep4View extends TradeStepView {
|
|||
handleTradeCompleted();
|
||||
model.dataModel.tradeManager.addTradeToClosedTrades(trade);
|
||||
});
|
||||
withdrawToExternalWalletButton.setOnAction(e -> reviewWithdrawal());
|
||||
withdrawToExternalWalletButton.setOnAction(e -> onWithdrawal());
|
||||
|
||||
String key = "tradeCompleted" + trade.getId();
|
||||
//noinspection ConstantConditions
|
||||
|
@ -155,6 +169,16 @@ public class BuyerStep4View extends TradeStepView {
|
|||
}
|
||||
}
|
||||
|
||||
private void onWithdrawal() {
|
||||
withdrawAddressLabel.setManaged(true);
|
||||
withdrawAddressLabel.setVisible(true);
|
||||
withdrawAddressTextField.setManaged(true);
|
||||
withdrawAddressTextField.setVisible(true);
|
||||
GridPane.setRowSpan(withdrawTitledGroupBg, 2);
|
||||
withdrawToExternalWalletButton.setDefaultButton(true);
|
||||
withdrawToExternalWalletButton.setOnAction(e -> reviewWithdrawal());
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
private void reviewWithdrawal() {
|
||||
Coin amount = trade.getPayoutAmount();
|
||||
|
@ -177,37 +201,28 @@ public class BuyerStep4View extends TradeStepView {
|
|||
if (toAddresses.isEmpty()) {
|
||||
validateWithdrawAddress();
|
||||
} else if (Restrictions.isAboveDust(amount, fee)) {
|
||||
if (DevEnv.DEV_MODE) {
|
||||
doWithdrawal(amount, fee);
|
||||
} else {
|
||||
BSFormatter formatter = model.btcFormatter;
|
||||
//noinspection ConstantConditions
|
||||
if (!DevEnv.DEV_MODE) {
|
||||
int txSize = feeEstimationTransaction.bitcoinSerialize().length;
|
||||
double feePerByte = CoinUtil.getFeePerByte(fee, txSize);
|
||||
double kb = txSize / 1000d;
|
||||
String recAmount = formatter.formatCoinWithCode(receiverAmount);
|
||||
new Popup<>().headLine(Res.get("portfolio.pending.step5_buyer.confirmWithdrawal"))
|
||||
.confirmation(Res.get("shared.sendFundsDetailsWithFee",
|
||||
formatter.formatCoinWithCode(amount),
|
||||
fromAddresses,
|
||||
toAddresses,
|
||||
formatter.formatCoinWithCode(fee),
|
||||
feePerByte,
|
||||
kb,
|
||||
recAmount))
|
||||
.actionButtonText(Res.get("shared.yes"))
|
||||
.onAction(() -> doWithdrawal(amount, fee))
|
||||
.closeButtonText(Res.get("shared.cancel"))
|
||||
.onClose(() -> {
|
||||
useSavingsWalletButton.setDisable(false);
|
||||
withdrawToExternalWalletButton.setDisable(false);
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
doWithdrawal(amount, fee);
|
||||
}
|
||||
}
|
||||
BSFormatter formatter = model.btcFormatter;
|
||||
int txSize = feeEstimationTransaction.bitcoinSerialize().length;
|
||||
double feePerByte = CoinUtil.getFeePerByte(fee, txSize);
|
||||
double kb = txSize / 1000d;
|
||||
String recAmount = formatter.formatCoinWithCode(receiverAmount);
|
||||
new Popup<>().headLine(Res.get("portfolio.pending.step5_buyer.confirmWithdrawal"))
|
||||
.confirmation(Res.get("shared.sendFundsDetailsWithFee",
|
||||
formatter.formatCoinWithCode(amount),
|
||||
fromAddresses,
|
||||
toAddresses,
|
||||
formatter.formatCoinWithCode(fee),
|
||||
feePerByte,
|
||||
kb,
|
||||
recAmount))
|
||||
.actionButtonText(Res.get("shared.yes"))
|
||||
.onAction(() -> doWithdrawal(amount, fee))
|
||||
.closeButtonText(Res.get("shared.cancel"))
|
||||
.onClose(() -> {
|
||||
useSavingsWalletButton.setDisable(false);
|
||||
withdrawToExternalWalletButton.setDisable(false);
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
new Popup<>().warning(Res.get("portfolio.pending.step5_buyer.amountTooLow")).show();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue