support funding make or take offer directly

QR code encodes payment URI
security deposit absorbs miner fee up to 5%
use binary search to maximize security deposit and minimize dust
show itemized funding popup on create offer
This commit is contained in:
woodser 2022-12-03 14:33:55 +00:00
parent 4dbbcd6217
commit dd0a307a84
44 changed files with 263 additions and 353 deletions

View file

@ -71,8 +71,7 @@ public class AddressTextField extends AnchorPane {
textField.setOnMousePressed(event -> wasPrimaryButtonDown = event.isPrimaryButtonDown());
textField.setOnMouseReleased(event -> {
if (wasPrimaryButtonDown)
GUIUtil.showFeeInfoBeforeExecute(AddressTextField.this::openWallet);
if (wasPrimaryButtonDown) openWallet();
wasPrimaryButtonDown = false;
});
@ -83,17 +82,17 @@ public class AddressTextField extends AnchorPane {
extWalletIcon.getStyleClass().addAll("icon", "highlight");
extWalletIcon.setTooltip(new Tooltip(tooltipText));
AwesomeDude.setIcon(extWalletIcon, AwesomeIcon.SIGNIN);
extWalletIcon.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(this::openWallet));
extWalletIcon.setOnMouseClicked(e -> openWallet());
Label copyIcon = new Label();
copyIcon.setLayoutY(3);
copyIcon.getStyleClass().addAll("icon", "highlight");
Tooltip.install(copyIcon, new Tooltip(Res.get("addressTextField.copyToClipboard")));
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
copyIcon.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(() -> {
copyIcon.setOnMouseClicked(e -> {
if (address.get() != null && address.get().length() > 0)
Utilities.copyToClipboard(address.get());
}));
});
AnchorPane.setRightAnchor(copyIcon, 30.0);
AnchorPane.setRightAnchor(extWalletIcon, 5.0);

View file

@ -21,7 +21,7 @@ import bisq.core.btc.listeners.XmrBalanceListener;
import bisq.core.btc.model.XmrAddressEntry;
import bisq.core.btc.wallet.XmrWalletService;
import bisq.core.locale.Res;
import bisq.core.util.ParsingUtils;
import bisq.core.trade.HavenoUtils;
import bisq.core.util.coin.CoinFormatter;
import bisq.desktop.components.indicator.TxConfidenceIndicator;
import bisq.desktop.util.GUIUtil;
@ -66,15 +66,14 @@ class DepositListItem {
balanceListener = new XmrBalanceListener(addressEntry.getSubaddressIndex()) {
@Override
public void onBalanceChanged(BigInteger balance) {
DepositListItem.this.balanceAsCoin = ParsingUtils.atomicUnitsToCoin(balance);
DepositListItem.this.balanceAsCoin = HavenoUtils.atomicUnitsToCoin(balance);
DepositListItem.this.balance.set(formatter.formatCoin(balanceAsCoin));
updateUsage(addressEntry.getSubaddressIndex());
}
};
xmrWalletService.addBalanceListener(balanceListener);
balanceAsCoin = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex()); // TODO: Coin represents centineros everywhere, but here it's atomic units. reconcile
balanceAsCoin = Coin.valueOf(ParsingUtils.atomicUnitsToCentineros(balanceAsCoin.longValue())); // in centineros
balanceAsCoin = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
balance.set(formatter.formatCoin(balanceAsCoin));
updateUsage(addressEntry.getSubaddressIndex());

View file

@ -34,6 +34,7 @@ import bisq.core.btc.listeners.XmrBalanceListener;
import bisq.core.btc.model.XmrAddressEntry;
import bisq.core.btc.wallet.XmrWalletService;
import bisq.core.locale.Res;
import bisq.core.trade.HavenoUtils;
import bisq.core.user.Preferences;
import bisq.core.util.FormattingUtils;
import bisq.core.util.ParsingUtils;
@ -166,10 +167,9 @@ public class DepositView extends ActivatableView<VBox, Void> {
qrCodeImageView = new ImageView();
qrCodeImageView.getStyleClass().add("qr-code");
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
() -> UserThread.runAfter(
qrCodeImageView.setOnMouseClicked(e -> UserThread.runAfter(
() -> new QRCodeWindow(getPaymentUri()).show(),
200, TimeUnit.MILLISECONDS)));
200, TimeUnit.MILLISECONDS));
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setRowSpan(qrCodeImageView, 4);
GridPane.setColumnIndex(qrCodeImageView, 1);
@ -308,7 +308,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
private String getPaymentUri() {
return xmrWalletService.getWallet().getPaymentUri(new MoneroTxConfig()
.setAddress(addressTextField.getAddress())
.setAmount(ParsingUtils.coinToAtomicUnits(getAmountAsCoin()))
.setAmount(HavenoUtils.coinToAtomicUnits(getAmountAsCoin()))
.setNote(paymentLabelString));
}

View file

@ -21,9 +21,9 @@ import bisq.core.btc.wallet.XmrWalletService;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.offer.OpenOffer;
import bisq.core.trade.HavenoUtils;
import bisq.core.trade.Tradable;
import bisq.core.trade.Trade;
import bisq.core.util.ParsingUtils;
import bisq.core.util.coin.CoinFormatter;
import bisq.desktop.components.indicator.TxConfidenceIndicator;
import bisq.desktop.util.DisplayUtils;
@ -94,8 +94,8 @@ class TransactionsListItem {
Optional<Tradable> optionalTradable = Optional.ofNullable(transactionAwareTradable)
.map(TransactionAwareTradable::asTradable);
Coin valueSentToMe = ParsingUtils.atomicUnitsToCoin(tx.getIncomingAmount() == null ? new BigInteger("0") : tx.getIncomingAmount());
Coin valueSentFromMe = ParsingUtils.atomicUnitsToCoin(tx.getOutgoingAmount() == null ? new BigInteger("0") : tx.getOutgoingAmount());
Coin valueSentToMe = HavenoUtils.atomicUnitsToCoin(tx.getIncomingAmount() == null ? new BigInteger("0") : tx.getIncomingAmount());
Coin valueSentFromMe = HavenoUtils.atomicUnitsToCoin(tx.getOutgoingAmount() == null ? new BigInteger("0") : tx.getOutgoingAmount());
if (tx.getTransfers().get(0).isIncoming()) {
addressString = ((MoneroIncomingTransfer) tx.getTransfers().get(0)).getAddress();

View file

@ -72,8 +72,7 @@ class WithdrawalListItem {
}
private void updateBalance() {
balance = walletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex()); // TODO: Coin represents centineros everywhere, but here it's atomic units. reconcile
balance = Coin.valueOf(ParsingUtils.atomicUnitsToCentineros(balance.longValue())); // in centineros
balance = walletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
if (balance != null)
balanceLabel.setText(formatter.formatCoin(this.balance));
}

View file

@ -32,6 +32,7 @@ import bisq.core.btc.setup.WalletsSetup;
import bisq.core.btc.wallet.XmrWalletService;
import bisq.core.locale.Res;
import bisq.core.provider.fee.FeeService;
import bisq.core.trade.HavenoUtils;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
import bisq.core.user.DontShowAgainLookup;
@ -191,12 +192,12 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
// create tx
MoneroTxWallet tx = xmrWalletService.getWallet().createTx(new MoneroTxConfig()
.setAccountIndex(0)
.setAmount(ParsingUtils.coinToAtomicUnits(receiverAmount)) // TODO: rename to centinerosToAtomicUnits()?
.setAmount(HavenoUtils.coinToAtomicUnits(receiverAmount)) // TODO: rename to centinerosToAtomicUnits()?
.setAddress(withdrawToAddress)
.setNote(withdrawMemoTextField.getText()));
// create confirmation message
Coin fee = ParsingUtils.atomicUnitsToCoin(tx.getFee());
Coin fee = HavenoUtils.atomicUnitsToCoin(tx.getFee());
Coin sendersAmount = receiverAmount.add(fee);
String messageText = Res.get("shared.sendFundsDetailsWithFee",
formatter.formatCoinWithCode(sendersAmount),

View file

@ -260,10 +260,6 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
priceFeedService.setCurrencyCode(tradeCurrencyCode.get());
// Set the default values (in rare cases if the fee request was not done yet we get the hard coded default values)
// But offer creation happens usually after that so we should have already the value from the estimation service.
txFeeFromFeeService = feeService.getTxFee(feeTxVsize);
calculateVolume();
calculateTotalToPay();
updateBalance();
@ -557,8 +553,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
// The mining fee for the createOfferFee tx is deducted from the createOfferFee and not visible to the trader
final Coin makerFee = getMakerFee();
if (direction != null && amount.get() != null && makerFee != null) {
Coin feeAndSecDeposit = getTxFee().add(getSecurityDeposit());
feeAndSecDeposit = feeAndSecDeposit.add(makerFee);
Coin feeAndSecDeposit = getSecurityDeposit().add(makerFee);
Coin total = isBuyOffer() ? feeAndSecDeposit : feeAndSecDeposit.add(amount.get());
totalToPayAsCoin.set(total);
updateBalance();
@ -569,10 +564,6 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
return isBuyOffer() ? getBuyerSecurityDepositAsCoin() : getSellerSecurityDepositAsCoin();
}
public Coin getTxFee() {
return txFeeFromFeeService;
}
void swapTradeToSavings() {
xmrWalletService.resetAddressEntriesForOpenOffer(offerId);
}

View file

@ -22,7 +22,6 @@ import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.components.AddressTextField;
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.AutoTooltipSlideToggleButton;
import bisq.desktop.components.BalanceTextField;
import bisq.desktop.components.BusyAnimation;
import bisq.desktop.components.FundsTextField;
@ -32,10 +31,6 @@ import bisq.desktop.components.TitledGroupBg;
import bisq.desktop.main.MainView;
import bisq.desktop.main.account.AccountView;
import bisq.desktop.main.account.content.fiataccounts.FiatAccountsView;
import bisq.desktop.main.offer.ClosableView;
import bisq.desktop.main.offer.OfferView;
import bisq.desktop.main.offer.OfferViewUtil;
import bisq.desktop.main.offer.SelectableView;
import bisq.desktop.main.overlays.notifications.Notification;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
@ -391,8 +386,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
model.getTotalToPayInfo(),
tradeAmountText,
model.getSecurityDepositInfo(),
model.getTradeFee(),
model.getTxFee()
model.getTradeFee()
);
new Popup().headLine(Res.get("createOffer.createOfferFundWalletInfo.headline"))
.instruction(message)
@ -770,7 +764,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
missingCoinListener = (observable, oldValue, newValue) -> {
if (!newValue.toString().equals("")) {
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.from(getMoneroURI())
.withSize(98, 98) // code has 41 elements 8 px is border with 98 we get double scale and min. border
.to(ImageType.PNG)
.stream()
@ -1080,10 +1074,9 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
qrCodeImageView.setFitWidth(150);
qrCodeImageView.getStyleClass().add("qr-code");
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
() -> UserThread.runAfter(
() -> new QRCodeWindow(getBitcoinURI()).show(),
200, TimeUnit.MILLISECONDS)));
qrCodeImageView.setOnMouseClicked(e -> UserThread.runAfter(
() -> new QRCodeWindow(getMoneroURI()).show(),
200, TimeUnit.MILLISECONDS));
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 1);
GridPane.setRowSpan(qrCodeImageView, 3);
@ -1111,7 +1104,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
label.setPadding(new Insets(5, 0, 0, 0));
Button fundFromExternalWalletButton = new AutoTooltipButton(Res.get("shared.fundFromExternalWalletButton"));
fundFromExternalWalletButton.setDefaultButton(false);
fundFromExternalWalletButton.setOnAction(e -> GUIUtil.showFeeInfoBeforeExecute(this::openWallet));
fundFromExternalWalletButton.setOnAction(e -> openWallet());
waitingForFundsSpinner = new BusyAnimation(false);
waitingForFundsLabel = new AutoTooltipLabel();
waitingForFundsLabel.setPadding(new Insets(5, 0, 0, 0));
@ -1178,7 +1171,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
private void openWallet() {
try {
Utilities.openURI(URI.create(getBitcoinURI()));
Utilities.openURI(URI.create(getMoneroURI()));
} catch (Exception ex) {
log.warn(ex.getMessage());
new Popup().warning(Res.get("shared.openDefaultWalletFailed")).show();
@ -1186,10 +1179,12 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
}
@NotNull
private String getBitcoinURI() {
return "TODO"; // TODO (woodser): wallet.createPaymentUri();
// return GUIUtil.getBitcoinURI(addressTextField.getAddress(), model.getDataModel().getMissingCoin().get(),
// model.getPaymentLabel());
private String getMoneroURI() {
return GUIUtil.getMoneroURI(
addressTextField.getAddress(),
model.getDataModel().getMissingCoin().get(),
model.getPaymentLabel(),
model.dataModel.getXmrWalletService().getWallet());
}
private void addAmountPriceFields() {
@ -1274,6 +1269,9 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
firstRowHBox.getChildren().add(2, fixedPriceBox);
if (!secondRowHBox.getChildren().contains(percentagePriceBox))
secondRowHBox.getChildren().add(2, percentagePriceBox);
model.triggerPrice.set("");
model.onTriggerPriceTextFieldChanged();
} else {
firstRowHBox.getChildren().remove(fixedPriceBox);
secondRowHBox.getChildren().remove(percentagePriceBox);
@ -1394,7 +1392,6 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
addPayInfoEntry(infoGridPane, i++, Res.getWithCol("shared.yourSecurityDeposit"), model.getSecurityDepositInfo());
addPayInfoEntry(infoGridPane, i++, Res.getWithCol("createOffer.fundsBox.offerFee"), model.getTradeFee());
addPayInfoEntry(infoGridPane, i++, Res.getWithCol("createOffer.fundsBox.networkFee"), model.getTxFee());
Separator separator = new Separator();
separator.setOrientation(Orientation.HORIZONTAL);
separator.getStyleClass().add("offer-separator");

View file

@ -648,6 +648,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
}
void onShowPayFundsScreen(Runnable actionHandler) {
actionHandler.run();
showPayFundsScreenDisplayed.set(true);
updateSpinnerInfo();
}
@ -1015,24 +1016,10 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
public String getFundsStructure() {
String fundsStructure;
fundsStructure = Res.get("createOffer.fundsBox.fundsStructure",
getSecurityDepositWithCode(), getMakerFeePercentage(), getTxFeePercentage());
getSecurityDepositWithCode(), getMakerFeePercentage());
return fundsStructure;
}
public String getTxFee() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil,
dataModel.getTxFee(),
dataModel.getAmount().get(),
btcFormatter,
Coin.ZERO
);
}
public String getTxFeePercentage() {
Coin txFeeAsCoin = dataModel.getTxFee();
return GUIUtil.getPercentage(txFeeAsCoin, dataModel.getAmount().get());
}
public PaymentAccount getPaymentAccount() {
return dataModel.getPaymentAccount();
}

View file

@ -41,6 +41,7 @@ import static bisq.core.util.coin.CoinUtil.minCoin;
* needed in that UI element.
*/
public abstract class OfferDataModel extends ActivatableDataModel {
@Getter
protected final XmrWalletService xmrWalletService;
protected final OfferUtil offerUtil;

View file

@ -454,12 +454,11 @@ class TakeOfferDataModel extends OfferDataModel {
// The mining fee for the takeOfferFee tx is deducted from the createOfferFee and not visible to the trader
final Coin takerFee = getTakerFee();
if (offer != null && amount.get() != null && takerFee != null) {
Coin feeAndSecDeposit = getTotalTxFee().add(securityDeposit).add(takerFee);
Coin feeAndSecDeposit = securityDeposit.add(takerFee);
if (isBuyOffer())
totalToPayAsCoin.set(feeAndSecDeposit.add(amount.get()));
else
totalToPayAsCoin.set(feeAndSecDeposit);
updateBalance();
log.debug("totalToPayAsCoin {}", totalToPayAsCoin.get().toFriendlyString());
}
@ -556,10 +555,6 @@ class TakeOfferDataModel extends OfferDataModel {
return CurrencyUtil.getNameByCode(offer.getCurrencyCode());
}
public Coin getTotalTxFee() {
return txFeeFromFeeService.add(getTxFeeForDepositTx()).add(getTxFeeForPayoutTx());
}
@NotNull
private Coin getFundsNeededForTrade() {
return getSecurityDeposit().add(getTxFeeForDepositTx()).add(getTxFeeForPayoutTx());

View file

@ -23,7 +23,6 @@ import bisq.desktop.common.view.FxmlView;
import bisq.desktop.components.AddressTextField;
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.AutoTooltipSlideToggleButton;
import bisq.desktop.components.BalanceTextField;
import bisq.desktop.components.BusyAnimation;
import bisq.desktop.components.FundsTextField;
@ -88,7 +87,6 @@ import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
@ -455,8 +453,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
model.getTotalToPayInfo(),
tradeAmountText,
model.getSecurityDepositInfo(),
model.getTradeFee(),
model.getTxFee()
model.getTradeFee()
);
String key = "takeOfferFundWalletInfo";
new Popup().headLine(Res.get("takeOffer.takeOfferFundWalletInfo.headline"))
@ -477,7 +474,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
balanceTextField.setVisible(true);
totalToPayTextField.setFundsStructure(Res.get("takeOffer.fundsBox.fundsStructure",
model.getSecurityDepositWithCode(), model.getTakerFeePercentage(), model.getTxFeePercentage()));
model.getSecurityDepositWithCode(), model.getTakerFeePercentage()));
totalToPayTextField.setContentForInfoPopOver(createInfoPopover());
if (model.dataModel.getIsBtcWalletFunded().get()) {
@ -491,7 +488,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.from(getMoneroURI())
.withSize(98, 98) // code has 41 elements 8 px is border with 98 we get double scale and min. border
.to(ImageType.PNG)
.stream()
@ -861,10 +858,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
qrCodeImageView.setFitWidth(150);
qrCodeImageView.getStyleClass().add("qr-code");
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
() -> UserThread.runAfter(
() -> new QRCodeWindow(getBitcoinURI()).show(),
200, TimeUnit.MILLISECONDS)));
qrCodeImageView.setOnMouseClicked(e -> UserThread.runAfter(
() -> new QRCodeWindow(getMoneroURI()).show(),
200, TimeUnit.MILLISECONDS));
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 1);
GridPane.setRowSpan(qrCodeImageView, 3);
@ -890,7 +886,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
label.setPadding(new Insets(5, 0, 0, 0));
Button fundFromExternalWalletButton = new AutoTooltipButton(Res.get("shared.fundFromExternalWalletButton"));
fundFromExternalWalletButton.setDefaultButton(false);
fundFromExternalWalletButton.setOnAction(e -> GUIUtil.showFeeInfoBeforeExecute(this::openWallet));
fundFromExternalWalletButton.setOnAction(e -> openWallet());
waitingForFundsBusyAnimation = new BusyAnimation(false);
waitingForFundsLabel = new AutoTooltipLabel();
waitingForFundsLabel.setPadding(new Insets(5, 0, 0, 0));
@ -955,7 +951,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private void openWallet() {
try {
Utilities.openURI(URI.create(getBitcoinURI()));
Utilities.openURI(URI.create(getMoneroURI()));
} catch (Exception ex) {
log.warn(ex.getMessage());
new Popup().warning(Res.get("shared.openDefaultWalletFailed")).show();
@ -963,11 +959,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
@NotNull
private String getBitcoinURI() {
return "TODO";
// return GUIUtil.getBitcoinURI(model.dataModel.getAddressEntry().getAddressString(),
// model.dataModel.getMissingCoin().get(),
// model.getPaymentLabel());
private String getMoneroURI() {
return GUIUtil.getMoneroURI(
model.dataModel.getAddressEntry().getAddressString(),
model.dataModel.getMissingCoin().get(),
model.getPaymentLabel(),
model.dataModel.getXmrWalletService().getWallet());
}
private void addAmountPriceFields() {
@ -1165,7 +1162,6 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addPayInfoEntry(infoGridPane, i++, Res.getWithCol("shared.yourSecurityDeposit"), model.getSecurityDepositInfo());
addPayInfoEntry(infoGridPane, i++, Res.get("takeOffer.fundsBox.offerFee"), model.getTradeFee());
addPayInfoEntry(infoGridPane, i++, Res.get("takeOffer.fundsBox.networkFee"), model.getTxFee());
Separator separator = new Separator();
separator.setOrientation(Orientation.HORIZONTAL);
separator.getStyleClass().add("offer-separator");

View file

@ -51,7 +51,6 @@ import bisq.network.p2p.network.CloseConnectionReason;
import bisq.network.p2p.network.Connection;
import bisq.network.p2p.network.ConnectionListener;
import bisq.common.UserThread;
import bisq.common.app.DevEnv;
import org.bitcoinj.core.Coin;
@ -706,20 +705,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
return totalToPay;
}
public String getTxFee() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil,
dataModel.getTotalTxFee(),
dataModel.getAmount().get(),
btcFormatter,
Coin.ZERO
);
}
public String getTxFeePercentage() {
Coin txFeeAsCoin = dataModel.getTotalTxFee();
return GUIUtil.getPercentage(txFeeAsCoin, dataModel.getAmount().get());
}
ObservableList<PaymentAccount> getPossiblePaymentAccounts() {
return dataModel.getPossiblePaymentAccounts();
}

View file

@ -42,11 +42,13 @@ import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountList;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.provider.fee.FeeService;
import bisq.core.trade.HavenoUtils;
import bisq.core.trade.txproof.AssetTxProofResult;
import bisq.core.user.DontShowAgainLookup;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.FormattingUtils;
import bisq.core.util.ParsingUtils;
import bisq.core.util.coin.CoinFormatter;
import bisq.network.p2p.P2PService;
@ -135,6 +137,9 @@ import java.util.function.Consumer;
import lombok.extern.slf4j.Slf4j;
import monero.daemon.model.MoneroTx;
import monero.wallet.MoneroWallet;
import monero.wallet.model.MoneroTxConfig;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
@ -190,19 +195,6 @@ public class GUIUtil {
});
}
public static void showFeeInfoBeforeExecute(Runnable runnable) {
String key = "miningFeeInfo";
if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) {
new Popup().attention(Res.get("guiUtil.miningFeeInfo", String.valueOf(GUIUtil.feeService.getTxFeePerVbyte().value)))
.onClose(runnable)
.useIUnderstandButton()
.show();
DontShowAgainLookup.dontShowAgain(key, true);
} else {
runnable.run();
}
}
public static void exportAccounts(ArrayList<PaymentAccount> accounts,
String fileName,
Preferences preferences,
@ -715,6 +707,13 @@ public class GUIUtil {
.show();
}
public static String getMoneroURI(String address, Coin amount, String label, MoneroWallet wallet) {
return wallet.getPaymentUri(new MoneroTxConfig()
.setAddress(address)
.setAmount(HavenoUtils.coinToAtomicUnits(amount))
.setNote(label));
}
public static String getBitcoinURI(String address, Coin amount, String label) {
return address != null ?
BitcoinURI.convertToBitcoinURI(Address.fromString(Config.baseCurrencyNetworkParameters(),