take offer funded from available balance

This commit is contained in:
woodser 2022-12-21 22:53:37 +00:00
parent 2b7beff84e
commit 06c2ce432b
10 changed files with 105 additions and 78 deletions

View file

@ -664,7 +664,7 @@ public class XmrWalletService {
for (XmrBalanceListener balanceListener : balanceListeners) { for (XmrBalanceListener balanceListener : balanceListeners) {
Coin balance; Coin balance;
if (balanceListener.getSubaddressIndex() != null && balanceListener.getSubaddressIndex() != 0) balance = getBalanceForSubaddress(balanceListener.getSubaddressIndex()); if (balanceListener.getSubaddressIndex() != null && balanceListener.getSubaddressIndex() != 0) balance = getBalanceForSubaddress(balanceListener.getSubaddressIndex());
else balance = getAvailableConfirmedBalance(); else balance = getAvailableBalance();
UserThread.execute(new Runnable() { // TODO (woodser): don't execute on UserThread UserThread.execute(new Runnable() { // TODO (woodser): don't execute on UserThread
@Override @Override
public void run() { public void run() {
@ -940,12 +940,16 @@ public class XmrWalletService {
return HavenoUtils.atomicUnitsToCoin(wallet.getBalance(0, subaddressIndex)); return HavenoUtils.atomicUnitsToCoin(wallet.getBalance(0, subaddressIndex));
} }
public Coin getAvailableConfirmedBalance() { public Coin getAvailableBalanceForSubaddress(int subaddressIndex) {
return wallet != null ? HavenoUtils.atomicUnitsToCoin(wallet.getUnlockedBalance(0)) : Coin.ZERO; return HavenoUtils.atomicUnitsToCoin(wallet.getUnlockedBalance(0, subaddressIndex));
} }
public Coin getSavingWalletBalance() { public Coin getBalance() {
return wallet != null ? Coin.valueOf(wallet.getBalance(0).longValueExact()) : Coin.ZERO; return wallet != null ? HavenoUtils.atomicUnitsToCoin(wallet.getBalance(0)) : Coin.ZERO;
}
public Coin getAvailableBalance() {
return wallet != null ? HavenoUtils.atomicUnitsToCoin(wallet.getUnlockedBalance(0)) : Coin.ZERO;
} }
public Stream<XmrAddressEntry> getAddressEntriesForAvailableBalanceStream() { public Stream<XmrAddressEntry> getAddressEntriesForAvailableBalanceStream() {

View file

@ -80,7 +80,7 @@ public class TakeOfferModel implements Model {
@Getter @Getter
private Coin totalAvailableBalance; private Coin totalAvailableBalance;
@Getter @Getter
private Coin balance; private Coin availableBalance;
@Getter @Getter
private boolean isXmrWalletFunded; private boolean isXmrWalletFunded;
@Getter @Getter
@ -154,10 +154,10 @@ public class TakeOfferModel implements Model {
} }
private void updateBalance() { private void updateBalance() {
totalAvailableBalance = xmrWalletService.getSavingWalletBalance(); totalAvailableBalance = xmrWalletService.getAvailableBalance();
if (totalToPayAsCoin != null) balance = minCoin(totalToPayAsCoin, totalAvailableBalance); if (totalToPayAsCoin != null) availableBalance = minCoin(totalToPayAsCoin, totalAvailableBalance);
missingCoin = offerUtil.getBalanceShortage(totalToPayAsCoin, balance); missingCoin = offerUtil.getBalanceShortage(totalToPayAsCoin, availableBalance);
isXmrWalletFunded = offerUtil.isBalanceSufficient(totalToPayAsCoin, balance); isXmrWalletFunded = offerUtil.isBalanceSufficient(totalToPayAsCoin, availableBalance);
} }
private long getMaxTradeLimit() { private long getMaxTradeLimit() {
@ -184,7 +184,7 @@ public class TakeOfferModel implements Model {
private void clearModel() { private void clearModel() {
this.addressEntry = null; this.addressEntry = null;
this.amount = null; this.amount = null;
this.balance = null; this.availableBalance = null;
this.isXmrWalletFunded = false; this.isXmrWalletFunded = false;
this.missingCoin = ZERO; this.missingCoin = ZERO;
this.offer = null; this.offer = null;
@ -212,7 +212,7 @@ public class TakeOfferModel implements Model {
", totalToPayAsCoin=" + totalToPayAsCoin + "\n" + ", totalToPayAsCoin=" + totalToPayAsCoin + "\n" +
", missingCoin=" + missingCoin + "\n" + ", missingCoin=" + missingCoin + "\n" +
", totalAvailableBalance=" + totalAvailableBalance + "\n" + ", totalAvailableBalance=" + totalAvailableBalance + "\n" +
", balance=" + balance + "\n" + ", availableBalance=" + availableBalance + "\n" +
", volume=" + volume + "\n" + ", volume=" + volume + "\n" +
", fundsNeededForTrade=" + getFundsNeededForTrade() + "\n" + ", fundsNeededForTrade=" + getFundsNeededForTrade() + "\n" +
", isXmrWalletFunded=" + isXmrWalletFunded + "\n" + ", isXmrWalletFunded=" + isXmrWalletFunded + "\n" +

View file

@ -403,7 +403,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
void fundFromSavingsWallet() { void fundFromSavingsWallet() {
this.useSavingsWallet = true; this.useSavingsWallet = true;
updateBalance(); updateBalance();
if (!isBtcWalletFunded.get()) { if (!isXmrWalletFunded.get()) {
this.useSavingsWallet = false; this.useSavingsWallet = false;
updateBalance(); updateBalance();
} }

View file

@ -124,7 +124,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
protected final Navigation navigation; protected final Navigation navigation;
private final Preferences preferences; private final Preferences preferences;
private final OfferDetailsWindow offerDetailsWindow; private final OfferDetailsWindow offerDetailsWindow;
private final CoinFormatter btcFormatter; private final CoinFormatter xmrFormatter;
private ScrollPane scrollPane; private ScrollPane scrollPane;
protected GridPane gridPane; protected GridPane gridPane;
@ -190,7 +190,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
this.navigation = navigation; this.navigation = navigation;
this.preferences = preferences; this.preferences = preferences;
this.offerDetailsWindow = offerDetailsWindow; this.offerDetailsWindow = offerDetailsWindow;
this.btcFormatter = btcFormatter; this.xmrFormatter = btcFormatter;
} }
@Override @Override
@ -565,11 +565,11 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
buyerSecurityDepositInputTextField.validationResultProperty().bind(model.buyerSecurityDepositValidationResult); buyerSecurityDepositInputTextField.validationResultProperty().bind(model.buyerSecurityDepositValidationResult);
// funding // funding
fundingHBox.visibleProperty().bind(model.getDataModel().getIsBtcWalletFunded().not().and(model.showPayFundsScreenDisplayed)); fundingHBox.visibleProperty().bind(model.getDataModel().getIsXmrWalletFunded().not().and(model.showPayFundsScreenDisplayed));
fundingHBox.managedProperty().bind(model.getDataModel().getIsBtcWalletFunded().not().and(model.showPayFundsScreenDisplayed)); fundingHBox.managedProperty().bind(model.getDataModel().getIsXmrWalletFunded().not().and(model.showPayFundsScreenDisplayed));
waitingForFundsLabel.textProperty().bind(model.waitingForFundsText); waitingForFundsLabel.textProperty().bind(model.waitingForFundsText);
placeOfferBox.visibleProperty().bind(model.getDataModel().getIsBtcWalletFunded().and(model.showPayFundsScreenDisplayed)); placeOfferBox.visibleProperty().bind(model.getDataModel().getIsXmrWalletFunded().and(model.showPayFundsScreenDisplayed));
placeOfferBox.managedProperty().bind(model.getDataModel().getIsBtcWalletFunded().and(model.showPayFundsScreenDisplayed)); placeOfferBox.managedProperty().bind(model.getDataModel().getIsXmrWalletFunded().and(model.showPayFundsScreenDisplayed));
placeOfferButton.disableProperty().bind(model.isPlaceOfferButtonDisabled); placeOfferButton.disableProperty().bind(model.isPlaceOfferButtonDisabled);
cancelButton2.disableProperty().bind(model.cancelButtonDisabled); cancelButton2.disableProperty().bind(model.cancelButtonDisabled);
@ -736,7 +736,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
if (newValue) { if (newValue) {
Notification walletFundedNotification = new Notification() Notification walletFundedNotification = new Notification()
.headLine(Res.get("notification.walletUpdate.headline")) .headLine(Res.get("notification.walletUpdate.headline"))
.notification(Res.get("notification.walletUpdate.msg", btcFormatter.formatCoinWithCode(model.getDataModel().getTotalToPayAsCoin().get()))) .notification(Res.get("notification.walletUpdate.msg", xmrFormatter.formatCoinWithCode(model.getDataModel().getTotalToPayAsCoin().get())))
.autoClose(); .autoClose();
walletFundedNotification.show(); walletFundedNotification.show();
@ -1149,7 +1149,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
cancelButton2.setOnAction(e -> { cancelButton2.setOnAction(e -> {
String key = "CreateOfferCancelAndFunded"; String key = "CreateOfferCancelAndFunded";
if (model.getDataModel().getIsBtcWalletFunded().get() && if (model.getDataModel().getIsXmrWalletFunded().get() &&
preferences.showAgain(key)) { preferences.showAgain(key)) {
new Popup().backgroundInfo(Res.get("createOffer.warnCancelOffer")) new Popup().backgroundInfo(Res.get("createOffer.warnCancelOffer"))
.closeButtonText(Res.get("shared.no")) .closeButtonText(Res.get("shared.no"))

View file

@ -536,7 +536,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
dataModel.getBuyerSecurityDeposit().addListener(securityDepositAsDoubleListener); dataModel.getBuyerSecurityDeposit().addListener(securityDepositAsDoubleListener);
// dataModel.feeFromFundingTxProperty.addListener(feeFromFundingTxListener); // dataModel.feeFromFundingTxProperty.addListener(feeFromFundingTxListener);
dataModel.getIsBtcWalletFunded().addListener(isWalletFundedListener); dataModel.getIsXmrWalletFunded().addListener(isWalletFundedListener);
priceFeedService.updateCounterProperty().addListener(currenciesUpdateListener); priceFeedService.updateCounterProperty().addListener(currenciesUpdateListener);
} }
@ -558,7 +558,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
dataModel.getBuyerSecurityDeposit().removeListener(securityDepositAsDoubleListener); dataModel.getBuyerSecurityDeposit().removeListener(securityDepositAsDoubleListener);
//dataModel.feeFromFundingTxProperty.removeListener(feeFromFundingTxListener); //dataModel.feeFromFundingTxProperty.removeListener(feeFromFundingTxListener);
dataModel.getIsBtcWalletFunded().removeListener(isWalletFundedListener); dataModel.getIsXmrWalletFunded().removeListener(isWalletFundedListener);
if (offer != null && errorMessageListener != null) if (offer != null && errorMessageListener != null)
offer.getErrorMessageProperty().removeListener(errorMessageListener); offer.getErrorMessageProperty().removeListener(errorMessageListener);
@ -655,12 +655,12 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
void fundFromSavingsWallet() { void fundFromSavingsWallet() {
dataModel.fundFromSavingsWallet(); dataModel.fundFromSavingsWallet();
if (dataModel.getIsBtcWalletFunded().get()) { if (dataModel.getIsXmrWalletFunded().get()) {
updateButtonDisableState(); updateButtonDisableState();
} else { } else {
new Popup().warning(Res.get("shared.notEnoughFunds", new Popup().warning(Res.get("shared.notEnoughFunds",
btcFormatter.formatCoinWithCode(dataModel.totalToPayAsCoinProperty().get()), btcFormatter.formatCoinWithCode(dataModel.totalToPayAsCoinProperty().get()),
btcFormatter.formatCoinWithCode(dataModel.getTotalAvailableBalance()))) btcFormatter.formatCoinWithCode(dataModel.getTotalBalance())))
.actionButtonTextWithGoTo("navigation.funds.depositFunds") .actionButtonTextWithGoTo("navigation.funds.depositFunds")
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class))
.show(); .show();
@ -1205,7 +1205,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
errorMessage.get() != null || errorMessage.get() != null ||
showTransactionPublishedScreen.get()) { showTransactionPublishedScreen.get()) {
waitingForFundsText.set(""); waitingForFundsText.set("");
} else if (dataModel.getIsBtcWalletFunded().get()) { } else if (dataModel.getIsXmrWalletFunded().get()) {
waitingForFundsText.set(""); waitingForFundsText.set("");
} else { } else {
waitingForFundsText.set(Res.get("shared.waitingForFunds")); waitingForFundsText.set(Res.get("shared.waitingForFunds"));
@ -1246,7 +1246,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
} }
isNextButtonDisabled.set(!inputDataValid); isNextButtonDisabled.set(!inputDataValid);
isPlaceOfferButtonDisabled.set(createOfferRequested || !inputDataValid || !dataModel.getIsBtcWalletFunded().get()); isPlaceOfferButtonDisabled.set(createOfferRequested || !inputDataValid || !dataModel.getIsXmrWalletFunded().get());
} }
private CoinFormatter getFormatterForMakerFee() { private CoinFormatter getFormatterForMakerFee() {

View file

@ -46,16 +46,20 @@ public abstract class OfferDataModel extends ActivatableDataModel {
protected final OfferUtil offerUtil; protected final OfferUtil offerUtil;
@Getter @Getter
protected final BooleanProperty isBtcWalletFunded = new SimpleBooleanProperty(); protected final BooleanProperty isXmrWalletFunded = new SimpleBooleanProperty();
@Getter @Getter
protected final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>(); protected final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
@Getter @Getter
protected final ObjectProperty<Coin> balance = new SimpleObjectProperty<>(); protected final ObjectProperty<Coin> balance = new SimpleObjectProperty<>();
@Getter @Getter
protected final ObjectProperty<Coin> availableBalance = new SimpleObjectProperty<>();
@Getter
protected final ObjectProperty<Coin> missingCoin = new SimpleObjectProperty<>(Coin.ZERO); protected final ObjectProperty<Coin> missingCoin = new SimpleObjectProperty<>(Coin.ZERO);
@Getter @Getter
protected final BooleanProperty showWalletFundedNotification = new SimpleBooleanProperty(); protected final BooleanProperty showWalletFundedNotification = new SimpleBooleanProperty();
@Getter @Getter
protected Coin totalBalance;
@Getter
protected Coin totalAvailableBalance; protected Coin totalAvailableBalance;
protected XmrAddressEntry addressEntry; protected XmrAddressEntry addressEntry;
protected boolean useSavingsWallet; protected boolean useSavingsWallet;
@ -68,17 +72,35 @@ public abstract class OfferDataModel extends ActivatableDataModel {
protected void updateBalance() { protected void updateBalance() {
Coin tradeWalletBalance = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex()); Coin tradeWalletBalance = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
if (useSavingsWallet) { if (useSavingsWallet) {
Coin savingWalletBalance = xmrWalletService.getSavingWalletBalance(); Coin walletBalance = xmrWalletService.getBalance();
totalAvailableBalance = savingWalletBalance.add(tradeWalletBalance); totalBalance = walletBalance.add(tradeWalletBalance);
if (totalToPayAsCoin.get() != null) { if (totalToPayAsCoin.get() != null) {
balance.set(minCoin(totalToPayAsCoin.get(), totalAvailableBalance)); balance.set(minCoin(totalToPayAsCoin.get(), totalBalance));
} }
} else { } else {
balance.set(tradeWalletBalance); balance.set(tradeWalletBalance);
} }
missingCoin.set(offerUtil.getBalanceShortage(totalToPayAsCoin.get(), balance.get())); missingCoin.set(offerUtil.getBalanceShortage(totalToPayAsCoin.get(), balance.get()));
isBtcWalletFunded.set(offerUtil.isBalanceSufficient(totalToPayAsCoin.get(), balance.get())); isXmrWalletFunded.set(offerUtil.isBalanceSufficient(totalToPayAsCoin.get(), balance.get()));
if (totalToPayAsCoin.get() != null && isBtcWalletFunded.get() && !showWalletFundedNotification.get()) { if (totalToPayAsCoin.get() != null && isXmrWalletFunded.get() && !showWalletFundedNotification.get()) {
showWalletFundedNotification.set(true);
}
}
protected void updateAvailableBalance() {
Coin tradeWalletBalance = xmrWalletService.getAvailableBalanceForSubaddress(addressEntry.getSubaddressIndex());
if (useSavingsWallet) {
Coin walletAvailableBalance = xmrWalletService.getAvailableBalance();
totalAvailableBalance = walletAvailableBalance.add(tradeWalletBalance);
if (totalToPayAsCoin.get() != null) {
availableBalance.set(minCoin(totalToPayAsCoin.get(), totalAvailableBalance));
}
} else {
availableBalance.set(tradeWalletBalance);
}
missingCoin.set(offerUtil.getBalanceShortage(totalToPayAsCoin.get(), availableBalance.get()));
isXmrWalletFunded.set(offerUtil.isBalanceSufficient(totalToPayAsCoin.get(), availableBalance.get()));
if (totalToPayAsCoin.get() != null && isXmrWalletFunded.get() && !showWalletFundedNotification.get()) {
showWalletFundedNotification.set(true); showWalletFundedNotification.set(true);
} }
} }

View file

@ -153,7 +153,7 @@ class TakeOfferDataModel extends OfferDataModel {
addListeners(); addListeners();
updateBalance(); updateAvailableBalance();
// TODO In case that we have funded but restarted, or canceled but took again the offer we would need to // TODO In case that we have funded but restarted, or canceled but took again the offer we would need to
// store locally the result when we received the funding tx(s). // store locally the result when we received the funding tx(s).
@ -219,7 +219,7 @@ class TakeOfferDataModel extends OfferDataModel {
balanceListener = new XmrBalanceListener(addressEntry.getSubaddressIndex()) { balanceListener = new XmrBalanceListener(addressEntry.getSubaddressIndex()) {
@Override @Override
public void onBalanceChanged(BigInteger balance) { public void onBalanceChanged(BigInteger balance) {
updateBalance(); updateAvailableBalance();
} }
}; };
@ -309,10 +309,10 @@ class TakeOfferDataModel extends OfferDataModel {
void fundFromSavingsWallet() { void fundFromSavingsWallet() {
useSavingsWallet = true; useSavingsWallet = true;
updateBalance(); updateAvailableBalance();
if (!isBtcWalletFunded.get()) { if (!isXmrWalletFunded.get()) {
this.useSavingsWallet = false; this.useSavingsWallet = false;
updateBalance(); updateAvailableBalance();
} }
} }
@ -394,7 +394,7 @@ class TakeOfferDataModel extends OfferDataModel {
volume.set(volumeByAmount); volume.set(volumeByAmount);
updateBalance(); updateAvailableBalance();
} }
} }
@ -415,7 +415,7 @@ class TakeOfferDataModel extends OfferDataModel {
totalToPayAsCoin.set(feeAndSecDeposit.add(amount.get())); totalToPayAsCoin.set(feeAndSecDeposit.add(amount.get()));
else else
totalToPayAsCoin.set(feeAndSecDeposit); totalToPayAsCoin.set(feeAndSecDeposit);
updateBalance(); updateAvailableBalance();
log.debug("totalToPayAsCoin {}", totalToPayAsCoin.get().toFriendlyString()); log.debug("totalToPayAsCoin {}", totalToPayAsCoin.get().toFriendlyString());
} }
} }

View file

@ -197,7 +197,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addOfferAvailabilityLabel(); addOfferAvailabilityLabel();
addFundingGroup(); addFundingGroup();
balanceTextField.setFormatter(model.getBtcFormatter()); balanceTextField.setFormatter(model.getXmrFormatter());
amountFocusedListener = (o, oldValue, newValue) -> { amountFocusedListener = (o, oldValue, newValue) -> {
model.onFocusOutAmountTextField(oldValue, newValue, amountTextField.getText()); model.onFocusOutAmountTextField(oldValue, newValue, amountTextField.getText());
@ -359,8 +359,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
// Called from parent as the view does not get notified when the tab is closed // Called from parent as the view does not get notified when the tab is closed
public void onClose() { public void onClose() {
Coin balance = model.dataModel.getBalance().get(); Coin availableBalance = model.dataModel.getAvailableBalance().get();
if (balance != null && balance.isPositive() && !model.takeOfferCompleted.get() && !DevEnv.isDevMode()) { if (availableBalance != null && availableBalance.isPositive() && !model.takeOfferCompleted.get() && !DevEnv.isDevMode()) {
model.dataModel.swapTradeToSavings(); model.dataModel.swapTradeToSavings();
} }
} }
@ -477,7 +477,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
model.getSecurityDepositWithCode(), model.getTakerFeePercentage())); model.getSecurityDepositWithCode(), model.getTakerFeePercentage()));
totalToPayTextField.setContentForInfoPopOver(createInfoPopover()); totalToPayTextField.setContentForInfoPopOver(createInfoPopover());
if (model.dataModel.getIsBtcWalletFunded().get()) { if (model.dataModel.getIsXmrWalletFunded().get()) {
if (walletFundedNotification == null) { if (walletFundedNotification == null) {
walletFundedNotification = new Notification() walletFundedNotification = new Notification()
.headLine(Res.get("notification.walletUpdate.headline")) .headLine(Res.get("notification.walletUpdate.headline"))
@ -554,11 +554,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
tradeFeeDescriptionLabel.managedProperty().bind(tradeFeeDescriptionLabel.visibleProperty()); tradeFeeDescriptionLabel.managedProperty().bind(tradeFeeDescriptionLabel.visibleProperty());
// funding // funding
fundingHBox.visibleProperty().bind(model.dataModel.getIsBtcWalletFunded().not().and(model.showPayFundsScreenDisplayed)); fundingHBox.visibleProperty().bind(model.dataModel.getIsXmrWalletFunded().not().and(model.showPayFundsScreenDisplayed));
fundingHBox.managedProperty().bind(model.dataModel.getIsBtcWalletFunded().not().and(model.showPayFundsScreenDisplayed)); fundingHBox.managedProperty().bind(model.dataModel.getIsXmrWalletFunded().not().and(model.showPayFundsScreenDisplayed));
waitingForFundsLabel.textProperty().bind(model.spinnerInfoText); waitingForFundsLabel.textProperty().bind(model.spinnerInfoText);
takeOfferBox.visibleProperty().bind(model.dataModel.getIsBtcWalletFunded().and(model.showPayFundsScreenDisplayed)); takeOfferBox.visibleProperty().bind(model.dataModel.getIsXmrWalletFunded().and(model.showPayFundsScreenDisplayed));
takeOfferBox.managedProperty().bind(model.dataModel.getIsBtcWalletFunded().and(model.showPayFundsScreenDisplayed)); takeOfferBox.managedProperty().bind(model.dataModel.getIsXmrWalletFunded().and(model.showPayFundsScreenDisplayed));
takeOfferButton.disableProperty().bind(model.isTakeOfferButtonDisabled); takeOfferButton.disableProperty().bind(model.isTakeOfferButtonDisabled);
} }
@ -674,7 +674,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
} }
}); });
balanceSubscription = EasyBind.subscribe(model.dataModel.getBalance(), balanceTextField::setBalance); balanceSubscription = EasyBind.subscribe(model.dataModel.getAvailableBalance(), balanceTextField::setBalance);
} }
private void removeSubscriptions() { private void removeSubscriptions() {
@ -929,7 +929,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
cancelButton2.setOnAction(e -> { cancelButton2.setOnAction(e -> {
String key = "CreateOfferCancelAndFunded"; String key = "CreateOfferCancelAndFunded";
if (model.dataModel.getIsBtcWalletFunded().get() && if (model.dataModel.getIsXmrWalletFunded().get() &&
model.dataModel.preferences.showAgain(key)) { model.dataModel.preferences.showAgain(key)) {
new Popup().backgroundInfo(Res.get("takeOffer.alreadyFunded.askCancel")) new Popup().backgroundInfo(Res.get("takeOffer.alreadyFunded.askCancel"))
.closeButtonText(Res.get("shared.no")) .closeButtonText(Res.get("shared.no"))

View file

@ -85,7 +85,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private final P2PService p2PService; private final P2PService p2PService;
private final AccountAgeWitnessService accountAgeWitnessService; private final AccountAgeWitnessService accountAgeWitnessService;
private final Navigation navigation; private final Navigation navigation;
private final CoinFormatter btcFormatter; private final CoinFormatter xmrFormatter;
private String amountRange; private String amountRange;
private String paymentLabel; private String paymentLabel;
@ -148,7 +148,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
this.p2PService = p2PService; this.p2PService = p2PService;
this.accountAgeWitnessService = accountAgeWitnessService; this.accountAgeWitnessService = accountAgeWitnessService;
this.navigation = navigation; this.navigation = navigation;
this.btcFormatter = btcFormatter; this.xmrFormatter = btcFormatter;
createListeners(); createListeners();
} }
@ -168,7 +168,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
volumeDescriptionLabel.set(Res.get(sellVolumeDescriptionKey, dataModel.getCurrencyCode())); volumeDescriptionLabel.set(Res.get(sellVolumeDescriptionKey, dataModel.getCurrencyCode()));
} }
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get())); amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
showTransactionPublishedScreen.set(false); showTransactionPublishedScreen.set(false);
// when getting back to an open screen we want to re-check again // when getting back to an open screen we want to re-check again
@ -209,7 +209,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
? Res.get(buyAmountDescriptionKey) ? Res.get(buyAmountDescriptionKey)
: Res.get(sellAmountDescriptionKey); : Res.get(sellAmountDescriptionKey);
amountRange = btcFormatter.formatCoin(offer.getMinAmount()) + " - " + btcFormatter.formatCoin(offer.getAmount()); amountRange = xmrFormatter.formatCoin(offer.getMinAmount()) + " - " + xmrFormatter.formatCoin(offer.getAmount());
price = FormattingUtils.formatPrice(dataModel.tradePrice); price = FormattingUtils.formatPrice(dataModel.tradePrice);
marketPriceMargin = FormattingUtils.formatToPercent(offer.getMarketPriceMarginPct()); marketPriceMargin = FormattingUtils.formatToPercent(offer.getMarketPriceMarginPct());
paymentLabel = Res.get("takeOffer.fundsBox.paymentLabel", offer.getShortId()); paymentLabel = Res.get("takeOffer.fundsBox.paymentLabel", offer.getShortId());
@ -260,13 +260,13 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
boolean fundFromSavingsWallet() { boolean fundFromSavingsWallet() {
dataModel.fundFromSavingsWallet(); dataModel.fundFromSavingsWallet();
if (dataModel.getIsBtcWalletFunded().get()) { if (dataModel.getIsXmrWalletFunded().get()) {
updateButtonDisableState(); updateButtonDisableState();
return true; return true;
} else { } else {
new Popup().warning(Res.get("shared.notEnoughFunds", new Popup().warning(Res.get("shared.notEnoughFunds",
btcFormatter.formatCoinWithCode(dataModel.getTotalToPayAsCoin().get()), xmrFormatter.formatCoinWithCode(dataModel.getTotalToPayAsCoin().get()),
btcFormatter.formatCoinWithCode(dataModel.getTotalAvailableBalance()))) xmrFormatter.formatCoinWithCode(dataModel.getTotalAvailableBalance())))
.actionButtonTextWithGoTo("navigation.funds.depositFunds") .actionButtonTextWithGoTo("navigation.funds.depositFunds")
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class))
.show(); .show();
@ -285,7 +285,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
tradeFee.set(getFormatterForTakerFee().formatCoin(takerFeeAsCoin)); tradeFee.set(getFormatterForTakerFee().formatCoin(takerFeeAsCoin));
tradeFeeInBtcWithFiat.set(OfferViewModelUtil.getTradeFeeWithFiatEquivalent(offerUtil, tradeFeeInBtcWithFiat.set(OfferViewModelUtil.getTradeFeeWithFiatEquivalent(offerUtil,
dataModel.getTakerFeeInBtc(), dataModel.getTakerFeeInBtc(),
btcFormatter)); xmrFormatter));
} }
@ -299,11 +299,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
InputValidator.ValidationResult result = isBtcInputValid(amount.get()); InputValidator.ValidationResult result = isBtcInputValid(amount.get());
amountValidationResult.set(result); amountValidationResult.set(result);
if (result.isValid) { if (result.isValid) {
showWarningInvalidBtcDecimalPlaces.set(!DisplayUtils.hasBtcValidDecimals(userInput, btcFormatter)); showWarningInvalidBtcDecimalPlaces.set(!DisplayUtils.hasBtcValidDecimals(userInput, xmrFormatter));
// only allow max 4 decimal places for btc values // only allow max 4 decimal places for btc values
setAmountToModel(); setAmountToModel();
// reformat input // reformat input
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get())); amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
calculateVolume(); calculateVolume();
@ -314,7 +314,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
tradePrice, tradePrice,
maxTradeLimit); maxTradeLimit);
dataModel.applyAmount(adjustedAmountForHalCash); dataModel.applyAmount(adjustedAmountForHalCash);
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get())); amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
} else if (dataModel.getOffer().isFiatOffer()) { } else if (dataModel.getOffer().isFiatOffer()) {
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) { if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
// We only apply the rounding if the amount is variable (minAmount is lower as amount). // We only apply the rounding if the amount is variable (minAmount is lower as amount).
@ -323,7 +323,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
maxTradeLimit); maxTradeLimit);
dataModel.applyAmount(roundedAmount); dataModel.applyAmount(roundedAmount);
} }
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get())); amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
} }
if (!dataModel.isMinAmountLessOrEqualAmount()) if (!dataModel.isMinAmountLessOrEqualAmount())
@ -340,13 +340,13 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
} else if (btcValidator.getMaxTradeLimit() != null && btcValidator.getMaxTradeLimit().value == OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.value) { } else if (btcValidator.getMaxTradeLimit() != null && btcValidator.getMaxTradeLimit().value == OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.value) {
if (dataModel.getDirection() == OfferDirection.BUY) { if (dataModel.getDirection() == OfferDirection.BUY) {
new Popup().information(Res.get("popup.warning.tradeLimitDueAccountAgeRestriction.seller", new Popup().information(Res.get("popup.warning.tradeLimitDueAccountAgeRestriction.seller",
btcFormatter.formatCoinWithCode(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT), xmrFormatter.formatCoinWithCode(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT),
Res.get("offerbook.warning.newVersionAnnouncement"))) Res.get("offerbook.warning.newVersionAnnouncement")))
.width(900) .width(900)
.show(); .show();
} else { } else {
new Popup().information(Res.get("popup.warning.tradeLimitDueAccountAgeRestriction.buyer", new Popup().information(Res.get("popup.warning.tradeLimitDueAccountAgeRestriction.buyer",
btcFormatter.formatCoinWithCode(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT), xmrFormatter.formatCoinWithCode(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT),
Res.get("offerbook.warning.newVersionAnnouncement"))) Res.get("offerbook.warning.newVersionAnnouncement")))
.width(900) .width(900)
.show(); .show();
@ -459,7 +459,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
&& isOfferAvailable.get() && isOfferAvailable.get()
&& !dataModel.wouldCreateDustForMaker(); && !dataModel.wouldCreateDustForMaker();
isNextButtonDisabled.set(!inputDataValid); isNextButtonDisabled.set(!inputDataValid);
isTakeOfferButtonDisabled.set(takeOfferRequested || !inputDataValid || !dataModel.getIsBtcWalletFunded().get()); isTakeOfferButtonDisabled.set(takeOfferRequested || !inputDataValid || !dataModel.getIsXmrWalletFunded().get());
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -468,7 +468,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private void addBindings() { private void addBindings() {
volume.bind(createStringBinding(() -> VolumeUtil.formatVolume(dataModel.volume.get()), dataModel.volume)); volume.bind(createStringBinding(() -> VolumeUtil.formatVolume(dataModel.volume.get()), dataModel.volume));
totalToPay.bind(createStringBinding(() -> btcFormatter.formatCoinWithCode(dataModel.getTotalToPayAsCoin().get()), dataModel.getTotalToPayAsCoin())); totalToPay.bind(createStringBinding(() -> xmrFormatter.formatCoinWithCode(dataModel.getTotalToPayAsCoin().get()), dataModel.getTotalToPayAsCoin()));
} }
@ -489,7 +489,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
updateButtonDisableState(); updateButtonDisableState();
}; };
amountAsCoinListener = (ov, oldValue, newValue) -> { amountAsCoinListener = (ov, oldValue, newValue) -> {
amount.set(btcFormatter.formatCoin(newValue)); amount.set(xmrFormatter.formatCoin(newValue));
applyTakerFee(); applyTakerFee();
}; };
isWalletFundedListener = (ov, oldValue, newValue) -> updateButtonDisableState(); isWalletFundedListener = (ov, oldValue, newValue) -> updateButtonDisableState();
@ -530,7 +530,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
errorMessage.get() != null || errorMessage.get() != null ||
showTransactionPublishedScreen.get()) { showTransactionPublishedScreen.get()) {
spinnerInfoText.set(""); spinnerInfoText.set("");
} else if (dataModel.getIsBtcWalletFunded().get()) { } else if (dataModel.getIsXmrWalletFunded().get()) {
spinnerInfoText.set(""); spinnerInfoText.set("");
/* if (dataModel.isFeeFromFundingTxSufficient.get()) { /* if (dataModel.isFeeFromFundingTxSufficient.get()) {
spinnerInfoText.set(""); spinnerInfoText.set("");
@ -553,7 +553,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding // Binding with Bindings.createObjectBinding does not work because of bi-directional binding
dataModel.getAmount().addListener(amountAsCoinListener); dataModel.getAmount().addListener(amountAsCoinListener);
dataModel.getIsBtcWalletFunded().addListener(isWalletFundedListener); dataModel.getIsXmrWalletFunded().addListener(isWalletFundedListener);
dataModel.getMempoolStatus().addListener(getMempoolStatusListener); dataModel.getMempoolStatus().addListener(getMempoolStatusListener);
p2PService.getNetworkNode().addConnectionListener(connectionListener); p2PService.getNetworkNode().addConnectionListener(connectionListener);
/* isFeeSufficientSubscription = EasyBind.subscribe(dataModel.isFeeFromFundingTxSufficient, newValue -> { /* isFeeSufficientSubscription = EasyBind.subscribe(dataModel.isFeeFromFundingTxSufficient, newValue -> {
@ -569,7 +569,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
dataModel.getAmount().removeListener(amountAsCoinListener); dataModel.getAmount().removeListener(amountAsCoinListener);
dataModel.getMempoolStatus().removeListener(getMempoolStatusListener); dataModel.getMempoolStatus().removeListener(getMempoolStatusListener);
dataModel.getIsBtcWalletFunded().removeListener(isWalletFundedListener); dataModel.getIsXmrWalletFunded().removeListener(isWalletFundedListener);
if (offer != null) { if (offer != null) {
offer.stateProperty().removeListener(offerStateListener); offer.stateProperty().removeListener(offerStateListener);
} }
@ -592,7 +592,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private void setAmountToModel() { private void setAmountToModel() {
if (amount.get() != null && !amount.get().isEmpty()) { if (amount.get() != null && !amount.get().isEmpty()) {
Coin amount = DisplayUtils.parseToCoinWith4Decimals(this.amount.get(), btcFormatter); Coin amount = DisplayUtils.parseToCoinWith4Decimals(this.amount.get(), xmrFormatter);
long maxTradeLimit = dataModel.getMaxTradeLimit(); long maxTradeLimit = dataModel.getMaxTradeLimit();
Price price = dataModel.tradePrice; Price price = dataModel.tradePrice;
if (price != null) { if (price != null) {
@ -621,8 +621,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
CoinFormatter getBtcFormatter() { CoinFormatter getXmrFormatter() {
return btcFormatter; return xmrFormatter;
} }
boolean isSeller() { boolean isSeller() {
@ -671,27 +671,27 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
String getTradeAmount() { String getTradeAmount() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalent(offerUtil, return OfferViewModelUtil.getTradeFeeWithFiatEquivalent(offerUtil,
dataModel.getAmount().get(), dataModel.getAmount().get(),
btcFormatter); xmrFormatter);
} }
public String getSecurityDepositInfo() { public String getSecurityDepositInfo() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil, return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil,
dataModel.getSecurityDeposit(), dataModel.getSecurityDeposit(),
dataModel.getAmount().get(), dataModel.getAmount().get(),
btcFormatter, xmrFormatter,
Restrictions.getMinBuyerSecurityDepositAsCoin() Restrictions.getMinBuyerSecurityDepositAsCoin()
); );
} }
public String getSecurityDepositWithCode() { public String getSecurityDepositWithCode() {
return btcFormatter.formatCoinWithCode(dataModel.getSecurityDeposit()); return xmrFormatter.formatCoinWithCode(dataModel.getSecurityDeposit());
} }
public String getTradeFee() { public String getTradeFee() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil, return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil,
dataModel.getTakerFeeInBtc(), dataModel.getTakerFeeInBtc(),
dataModel.getAmount().get(), dataModel.getAmount().get(),
btcFormatter, xmrFormatter,
HavenoUtils.getMinMakerFee()); HavenoUtils.getMinMakerFee());
} }
@ -726,7 +726,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
} }
private CoinFormatter getFormatterForTakerFee() { private CoinFormatter getFormatterForTakerFee() {
return btcFormatter; return xmrFormatter;
} }
public Callback<ListView<PaymentAccount>, ListCell<PaymentAccount>> getPaymentAccountListCellFactory( public Callback<ListView<PaymentAccount>, ListCell<PaymentAccount>> getPaymentAccountListCellFactory(

View file

@ -415,6 +415,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
// update trade state progress // update trade state progress
UserThread.runAfter(() -> { UserThread.runAfter(() -> {
Trade trade = tradeManager.getTrade(offer.getId()); Trade trade = tradeManager.getTrade(offer.getId());
if (trade == null) return;
tradeStateSubscription = EasyBind.subscribe(trade.stateProperty(), newState -> { tradeStateSubscription = EasyBind.subscribe(trade.stateProperty(), newState -> {
String progress = (newState.ordinal() + 1) + "/" + (lastState.ordinal()); String progress = (newState.ordinal() + 1) + "/" + (lastState.ordinal());
spinnerInfoLabel.setText(Res.get("takeOffer.fundsBox.takeOfferSpinnerInfo") + " " + progress); spinnerInfoLabel.setText(Res.get("takeOffer.fundsBox.takeOfferSpinnerInfo") + " " + progress);