mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-09 07:02:24 -04:00
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:
parent
4dbbcd6217
commit
dd0a307a84
44 changed files with 263 additions and 353 deletions
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue