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) {
Coin balance;
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
@Override
public void run() {
@ -940,12 +940,16 @@ public class XmrWalletService {
return HavenoUtils.atomicUnitsToCoin(wallet.getBalance(0, subaddressIndex));
}
public Coin getAvailableConfirmedBalance() {
return wallet != null ? HavenoUtils.atomicUnitsToCoin(wallet.getUnlockedBalance(0)) : Coin.ZERO;
public Coin getAvailableBalanceForSubaddress(int subaddressIndex) {
return HavenoUtils.atomicUnitsToCoin(wallet.getUnlockedBalance(0, subaddressIndex));
}
public Coin getSavingWalletBalance() {
return wallet != null ? Coin.valueOf(wallet.getBalance(0).longValueExact()) : Coin.ZERO;
public Coin getBalance() {
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() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -153,7 +153,7 @@ class TakeOfferDataModel extends OfferDataModel {
addListeners();
updateBalance();
updateAvailableBalance();
// 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).
@ -219,7 +219,7 @@ class TakeOfferDataModel extends OfferDataModel {
balanceListener = new XmrBalanceListener(addressEntry.getSubaddressIndex()) {
@Override
public void onBalanceChanged(BigInteger balance) {
updateBalance();
updateAvailableBalance();
}
};
@ -309,10 +309,10 @@ class TakeOfferDataModel extends OfferDataModel {
void fundFromSavingsWallet() {
useSavingsWallet = true;
updateBalance();
if (!isBtcWalletFunded.get()) {
updateAvailableBalance();
if (!isXmrWalletFunded.get()) {
this.useSavingsWallet = false;
updateBalance();
updateAvailableBalance();
}
}
@ -394,7 +394,7 @@ class TakeOfferDataModel extends OfferDataModel {
volume.set(volumeByAmount);
updateBalance();
updateAvailableBalance();
}
}
@ -415,7 +415,7 @@ class TakeOfferDataModel extends OfferDataModel {
totalToPayAsCoin.set(feeAndSecDeposit.add(amount.get()));
else
totalToPayAsCoin.set(feeAndSecDeposit);
updateBalance();
updateAvailableBalance();
log.debug("totalToPayAsCoin {}", totalToPayAsCoin.get().toFriendlyString());
}
}

View File

@ -197,7 +197,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addOfferAvailabilityLabel();
addFundingGroup();
balanceTextField.setFormatter(model.getBtcFormatter());
balanceTextField.setFormatter(model.getXmrFormatter());
amountFocusedListener = (o, oldValue, newValue) -> {
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
public void onClose() {
Coin balance = model.dataModel.getBalance().get();
if (balance != null && balance.isPositive() && !model.takeOfferCompleted.get() && !DevEnv.isDevMode()) {
Coin availableBalance = model.dataModel.getAvailableBalance().get();
if (availableBalance != null && availableBalance.isPositive() && !model.takeOfferCompleted.get() && !DevEnv.isDevMode()) {
model.dataModel.swapTradeToSavings();
}
}
@ -477,7 +477,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
model.getSecurityDepositWithCode(), model.getTakerFeePercentage()));
totalToPayTextField.setContentForInfoPopOver(createInfoPopover());
if (model.dataModel.getIsBtcWalletFunded().get()) {
if (model.dataModel.getIsXmrWalletFunded().get()) {
if (walletFundedNotification == null) {
walletFundedNotification = new Notification()
.headLine(Res.get("notification.walletUpdate.headline"))
@ -554,11 +554,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
tradeFeeDescriptionLabel.managedProperty().bind(tradeFeeDescriptionLabel.visibleProperty());
// funding
fundingHBox.visibleProperty().bind(model.dataModel.getIsBtcWalletFunded().not().and(model.showPayFundsScreenDisplayed));
fundingHBox.managedProperty().bind(model.dataModel.getIsBtcWalletFunded().not().and(model.showPayFundsScreenDisplayed));
fundingHBox.visibleProperty().bind(model.dataModel.getIsXmrWalletFunded().not().and(model.showPayFundsScreenDisplayed));
fundingHBox.managedProperty().bind(model.dataModel.getIsXmrWalletFunded().not().and(model.showPayFundsScreenDisplayed));
waitingForFundsLabel.textProperty().bind(model.spinnerInfoText);
takeOfferBox.visibleProperty().bind(model.dataModel.getIsBtcWalletFunded().and(model.showPayFundsScreenDisplayed));
takeOfferBox.managedProperty().bind(model.dataModel.getIsBtcWalletFunded().and(model.showPayFundsScreenDisplayed));
takeOfferBox.visibleProperty().bind(model.dataModel.getIsXmrWalletFunded().and(model.showPayFundsScreenDisplayed));
takeOfferBox.managedProperty().bind(model.dataModel.getIsXmrWalletFunded().and(model.showPayFundsScreenDisplayed));
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() {
@ -929,7 +929,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
cancelButton2.setOnAction(e -> {
String key = "CreateOfferCancelAndFunded";
if (model.dataModel.getIsBtcWalletFunded().get() &&
if (model.dataModel.getIsXmrWalletFunded().get() &&
model.dataModel.preferences.showAgain(key)) {
new Popup().backgroundInfo(Res.get("takeOffer.alreadyFunded.askCancel"))
.closeButtonText(Res.get("shared.no"))

View File

@ -85,7 +85,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private final P2PService p2PService;
private final AccountAgeWitnessService accountAgeWitnessService;
private final Navigation navigation;
private final CoinFormatter btcFormatter;
private final CoinFormatter xmrFormatter;
private String amountRange;
private String paymentLabel;
@ -148,7 +148,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
this.p2PService = p2PService;
this.accountAgeWitnessService = accountAgeWitnessService;
this.navigation = navigation;
this.btcFormatter = btcFormatter;
this.xmrFormatter = btcFormatter;
createListeners();
}
@ -168,7 +168,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
volumeDescriptionLabel.set(Res.get(sellVolumeDescriptionKey, dataModel.getCurrencyCode()));
}
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
showTransactionPublishedScreen.set(false);
// 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(sellAmountDescriptionKey);
amountRange = btcFormatter.formatCoin(offer.getMinAmount()) + " - " + btcFormatter.formatCoin(offer.getAmount());
amountRange = xmrFormatter.formatCoin(offer.getMinAmount()) + " - " + xmrFormatter.formatCoin(offer.getAmount());
price = FormattingUtils.formatPrice(dataModel.tradePrice);
marketPriceMargin = FormattingUtils.formatToPercent(offer.getMarketPriceMarginPct());
paymentLabel = Res.get("takeOffer.fundsBox.paymentLabel", offer.getShortId());
@ -260,13 +260,13 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
boolean fundFromSavingsWallet() {
dataModel.fundFromSavingsWallet();
if (dataModel.getIsBtcWalletFunded().get()) {
if (dataModel.getIsXmrWalletFunded().get()) {
updateButtonDisableState();
return true;
} else {
new Popup().warning(Res.get("shared.notEnoughFunds",
btcFormatter.formatCoinWithCode(dataModel.getTotalToPayAsCoin().get()),
btcFormatter.formatCoinWithCode(dataModel.getTotalAvailableBalance())))
xmrFormatter.formatCoinWithCode(dataModel.getTotalToPayAsCoin().get()),
xmrFormatter.formatCoinWithCode(dataModel.getTotalAvailableBalance())))
.actionButtonTextWithGoTo("navigation.funds.depositFunds")
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class))
.show();
@ -285,7 +285,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
tradeFee.set(getFormatterForTakerFee().formatCoin(takerFeeAsCoin));
tradeFeeInBtcWithFiat.set(OfferViewModelUtil.getTradeFeeWithFiatEquivalent(offerUtil,
dataModel.getTakerFeeInBtc(),
btcFormatter));
xmrFormatter));
}
@ -299,11 +299,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
InputValidator.ValidationResult result = isBtcInputValid(amount.get());
amountValidationResult.set(result);
if (result.isValid) {
showWarningInvalidBtcDecimalPlaces.set(!DisplayUtils.hasBtcValidDecimals(userInput, btcFormatter));
showWarningInvalidBtcDecimalPlaces.set(!DisplayUtils.hasBtcValidDecimals(userInput, xmrFormatter));
// only allow max 4 decimal places for btc values
setAmountToModel();
// reformat input
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
calculateVolume();
@ -314,7 +314,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
tradePrice,
maxTradeLimit);
dataModel.applyAmount(adjustedAmountForHalCash);
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
} else if (dataModel.getOffer().isFiatOffer()) {
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
// 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);
dataModel.applyAmount(roundedAmount);
}
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
amount.set(xmrFormatter.formatCoin(dataModel.getAmount().get()));
}
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) {
if (dataModel.getDirection() == OfferDirection.BUY) {
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")))
.width(900)
.show();
} else {
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")))
.width(900)
.show();
@ -459,7 +459,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
&& isOfferAvailable.get()
&& !dataModel.wouldCreateDustForMaker();
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() {
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();
};
amountAsCoinListener = (ov, oldValue, newValue) -> {
amount.set(btcFormatter.formatCoin(newValue));
amount.set(xmrFormatter.formatCoin(newValue));
applyTakerFee();
};
isWalletFundedListener = (ov, oldValue, newValue) -> updateButtonDisableState();
@ -530,7 +530,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
errorMessage.get() != null ||
showTransactionPublishedScreen.get()) {
spinnerInfoText.set("");
} else if (dataModel.getIsBtcWalletFunded().get()) {
} else if (dataModel.getIsXmrWalletFunded().get()) {
spinnerInfoText.set("");
/* if (dataModel.isFeeFromFundingTxSufficient.get()) {
spinnerInfoText.set("");
@ -553,7 +553,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
dataModel.getAmount().addListener(amountAsCoinListener);
dataModel.getIsBtcWalletFunded().addListener(isWalletFundedListener);
dataModel.getIsXmrWalletFunded().addListener(isWalletFundedListener);
dataModel.getMempoolStatus().addListener(getMempoolStatusListener);
p2PService.getNetworkNode().addConnectionListener(connectionListener);
/* isFeeSufficientSubscription = EasyBind.subscribe(dataModel.isFeeFromFundingTxSufficient, newValue -> {
@ -569,7 +569,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
dataModel.getAmount().removeListener(amountAsCoinListener);
dataModel.getMempoolStatus().removeListener(getMempoolStatusListener);
dataModel.getIsBtcWalletFunded().removeListener(isWalletFundedListener);
dataModel.getIsXmrWalletFunded().removeListener(isWalletFundedListener);
if (offer != null) {
offer.stateProperty().removeListener(offerStateListener);
}
@ -592,7 +592,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private void setAmountToModel() {
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();
Price price = dataModel.tradePrice;
if (price != null) {
@ -621,8 +621,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
CoinFormatter getBtcFormatter() {
return btcFormatter;
CoinFormatter getXmrFormatter() {
return xmrFormatter;
}
boolean isSeller() {
@ -671,27 +671,27 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
String getTradeAmount() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalent(offerUtil,
dataModel.getAmount().get(),
btcFormatter);
xmrFormatter);
}
public String getSecurityDepositInfo() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil,
dataModel.getSecurityDeposit(),
dataModel.getAmount().get(),
btcFormatter,
xmrFormatter,
Restrictions.getMinBuyerSecurityDepositAsCoin()
);
}
public String getSecurityDepositWithCode() {
return btcFormatter.formatCoinWithCode(dataModel.getSecurityDeposit());
return xmrFormatter.formatCoinWithCode(dataModel.getSecurityDeposit());
}
public String getTradeFee() {
return OfferViewModelUtil.getTradeFeeWithFiatEquivalentAndPercentage(offerUtil,
dataModel.getTakerFeeInBtc(),
dataModel.getAmount().get(),
btcFormatter,
xmrFormatter,
HavenoUtils.getMinMakerFee());
}
@ -726,7 +726,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
}
private CoinFormatter getFormatterForTakerFee() {
return btcFormatter;
return xmrFormatter;
}
public Callback<ListView<PaymentAccount>, ListCell<PaymentAccount>> getPaymentAccountListCellFactory(

View File

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