mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-22 14:42:37 +01:00
Merge branch 'master' of https://github.com/bisq-network/bisq
This commit is contained in:
commit
ad4be15eea
15 changed files with 104 additions and 59 deletions
|
@ -1354,6 +1354,7 @@ message PreferencesPayload {
|
||||||
string take_offer_selected_payment_account_id = 49;
|
string take_offer_selected_payment_account_id = 49;
|
||||||
double buyer_security_deposit_as_percent = 50;
|
double buyer_security_deposit_as_percent = 50;
|
||||||
int32 ignore_dust_threshold = 51;
|
int32 ignore_dust_threshold = 51;
|
||||||
|
double buyer_security_deposit_as_percent_for_crypto = 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -18,9 +18,13 @@
|
||||||
package bisq.core.btc.wallet;
|
package bisq.core.btc.wallet;
|
||||||
|
|
||||||
import bisq.core.app.BisqEnvironment;
|
import bisq.core.app.BisqEnvironment;
|
||||||
|
import bisq.core.payment.PaymentAccount;
|
||||||
|
import bisq.core.payment.PaymentAccountUtil;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class Restrictions {
|
public class Restrictions {
|
||||||
private static Coin MIN_TRADE_AMOUNT;
|
private static Coin MIN_TRADE_AMOUNT;
|
||||||
private static Coin MIN_BUYER_SECURITY_DEPOSIT;
|
private static Coin MIN_BUYER_SECURITY_DEPOSIT;
|
||||||
|
@ -50,16 +54,25 @@ public class Restrictions {
|
||||||
return MIN_TRADE_AMOUNT;
|
return MIN_TRADE_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getDefaultBuyerSecurityDepositAsPercent() {
|
public static double getDefaultBuyerSecurityDepositAsPercent(@Nullable PaymentAccount paymentAccount) {
|
||||||
|
if (PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount))
|
||||||
|
return 0.02; // 2% of trade amount.
|
||||||
|
else
|
||||||
return 0.1; // 10% of trade amount.
|
return 0.1; // 10% of trade amount.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getMinBuyerSecurityDepositAsPercent() {
|
public static double getMinBuyerSecurityDepositAsPercent(@Nullable PaymentAccount paymentAccount) {
|
||||||
|
if (PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount))
|
||||||
|
return 0.005; // 0.5% of trade amount.
|
||||||
|
else
|
||||||
return 0.05; // 5% of trade amount.
|
return 0.05; // 5% of trade amount.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getMaxBuyerSecurityDepositAsPercent() {
|
public static double getMaxBuyerSecurityDepositAsPercent(@Nullable PaymentAccount paymentAccount) {
|
||||||
return 0.5; // 50% of trade amount. For a 1 BTC trade it is about 800 USD @ 4000 USD/BTC
|
if (PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount))
|
||||||
|
return 0.2; // 20% of trade amount. For a 1 BTC trade it is about 800 USD @ 4000 USD/BTC
|
||||||
|
else
|
||||||
|
return 0.5; // 50% of trade amount. For a 1 BTC trade it is about 2000 USD @ 4000 USD/BTC
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use MIN_BUYER_SECURITY_DEPOSIT as well as lower bound in case of small trade amounts.
|
// We use MIN_BUYER_SECURITY_DEPOSIT as well as lower bound in case of small trade amounts.
|
||||||
|
|
|
@ -353,12 +353,12 @@ public class OfferUtil {
|
||||||
Coin makerFeeAsCoin) {
|
Coin makerFeeAsCoin) {
|
||||||
checkNotNull(makerFeeAsCoin, "makerFee must not be null");
|
checkNotNull(makerFeeAsCoin, "makerFee must not be null");
|
||||||
checkNotNull(p2PService.getAddress(), "Address must not be null");
|
checkNotNull(p2PService.getAddress(), "Address must not be null");
|
||||||
checkArgument(buyerSecurityDeposit <= Restrictions.getMaxBuyerSecurityDepositAsPercent(),
|
checkArgument(buyerSecurityDeposit <= Restrictions.getMaxBuyerSecurityDepositAsPercent(paymentAccount),
|
||||||
"securityDeposit must not exceed " +
|
"securityDeposit must not exceed " +
|
||||||
Restrictions.getMaxBuyerSecurityDepositAsPercent());
|
Restrictions.getMaxBuyerSecurityDepositAsPercent(paymentAccount));
|
||||||
checkArgument(buyerSecurityDeposit >= Restrictions.getMinBuyerSecurityDepositAsPercent(),
|
checkArgument(buyerSecurityDeposit >= Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount),
|
||||||
"securityDeposit must not be less than " +
|
"securityDeposit must not be less than " +
|
||||||
Restrictions.getMinBuyerSecurityDepositAsPercent());
|
Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount));
|
||||||
checkArgument(!filterManager.isCurrencyBanned(currencyCode),
|
checkArgument(!filterManager.isCurrencyBanned(currencyCode),
|
||||||
Res.get("offerbook.warning.currencyBanned"));
|
Res.get("offerbook.warning.currencyBanned"));
|
||||||
checkArgument(!filterManager.isPaymentMethodBanned(paymentAccount.getPaymentMethod()),
|
checkArgument(!filterManager.isPaymentMethodBanned(paymentAccount.getPaymentMethod()),
|
||||||
|
|
|
@ -19,6 +19,7 @@ package bisq.core.payment;
|
||||||
|
|
||||||
import bisq.core.locale.Country;
|
import bisq.core.locale.Country;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
|
import bisq.core.payment.payload.PaymentMethod;
|
||||||
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -114,6 +115,11 @@ public class PaymentAccountUtil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isCryptoCurrencyAccount(PaymentAccount paymentAccount) {
|
||||||
|
return (paymentAccount != null && paymentAccount.getPaymentMethod().equals(PaymentMethod.BLOCK_CHAINS) ||
|
||||||
|
paymentAccount != null && paymentAccount.getPaymentMethod().equals(PaymentMethod.BLOCK_CHAINS_INSTANT));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO no code duplication found in UI code (added for API)
|
// TODO no code duplication found in UI code (added for API)
|
||||||
// That is optional and set to null if not supported (AltCoins,...)
|
// That is optional and set to null if not supported (AltCoins,...)
|
||||||
/* public static String getCountryCode(PaymentAccount paymentAccount) {
|
/* public static String getCountryCode(PaymentAccount paymentAccount) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ import bisq.core.locale.FiatCurrency;
|
||||||
import bisq.core.locale.GlobalSettings;
|
import bisq.core.locale.GlobalSettings;
|
||||||
import bisq.core.locale.TradeCurrency;
|
import bisq.core.locale.TradeCurrency;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
|
import bisq.core.payment.PaymentAccountUtil;
|
||||||
|
|
||||||
import bisq.network.p2p.network.BridgeAddressProvider;
|
import bisq.network.p2p.network.BridgeAddressProvider;
|
||||||
|
|
||||||
|
@ -493,9 +494,13 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
||||||
withdrawalTxFeeInBytesProperty.set(withdrawalTxFeeInBytes);
|
withdrawalTxFeeInBytesProperty.set(withdrawalTxFeeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBuyerSecurityDepositAsPercent(double buyerSecurityDepositAsPercent) {
|
public void setBuyerSecurityDepositAsPercent(double buyerSecurityDepositAsPercent, PaymentAccount paymentAccount) {
|
||||||
double max = Restrictions.getMaxBuyerSecurityDepositAsPercent();
|
double max = Restrictions.getMaxBuyerSecurityDepositAsPercent(paymentAccount);
|
||||||
double min = Restrictions.getMinBuyerSecurityDepositAsPercent();
|
double min = Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount);
|
||||||
|
|
||||||
|
if (PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount))
|
||||||
|
prefPayload.setBuyerSecurityDepositAsPercentForCrypto(Math.min(max, Math.max(min, buyerSecurityDepositAsPercent)));
|
||||||
|
else
|
||||||
prefPayload.setBuyerSecurityDepositAsPercent(Math.min(max, Math.max(min, buyerSecurityDepositAsPercent)));
|
prefPayload.setBuyerSecurityDepositAsPercent(Math.min(max, Math.max(min, buyerSecurityDepositAsPercent)));
|
||||||
persist();
|
persist();
|
||||||
}
|
}
|
||||||
|
@ -715,15 +720,16 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
||||||
return withdrawalTxFeeInBytesProperty;
|
return withdrawalTxFeeInBytesProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getBuyerSecurityDepositAsPercent() {
|
public double getBuyerSecurityDepositAsPercent(PaymentAccount paymentAccount) {
|
||||||
double value = prefPayload.getBuyerSecurityDepositAsPercent();
|
double value = PaymentAccountUtil.isCryptoCurrencyAccount(paymentAccount) ?
|
||||||
|
prefPayload.getBuyerSecurityDepositAsPercentForCrypto() : prefPayload.getBuyerSecurityDepositAsPercent();
|
||||||
|
|
||||||
if (value < Restrictions.getMinBuyerSecurityDepositAsPercent()) {
|
if (value < Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount)) {
|
||||||
value = Restrictions.getMinBuyerSecurityDepositAsPercent();
|
value = Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount);
|
||||||
setBuyerSecurityDepositAsPercent(value);
|
setBuyerSecurityDepositAsPercent(value, paymentAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return value == 0 ? Restrictions.getDefaultBuyerSecurityDepositAsPercent() : value;
|
return value == 0 ? Restrictions.getDefaultBuyerSecurityDepositAsPercent(paymentAccount) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO remove and use isPayFeeInBtc instead
|
//TODO remove and use isPayFeeInBtc instead
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
|
|
||||||
package bisq.core.user;
|
package bisq.core.user;
|
||||||
|
|
||||||
import bisq.core.btc.wallet.Restrictions;
|
|
||||||
import bisq.core.locale.Country;
|
import bisq.core.locale.Country;
|
||||||
import bisq.core.locale.CryptoCurrency;
|
import bisq.core.locale.CryptoCurrency;
|
||||||
import bisq.core.locale.FiatCurrency;
|
import bisq.core.locale.FiatCurrency;
|
||||||
import bisq.core.locale.TradeCurrency;
|
import bisq.core.locale.TradeCurrency;
|
||||||
|
import bisq.core.payment.CryptoCurrencyAccount;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.proto.CoreProtoResolver;
|
import bisq.core.proto.CoreProtoResolver;
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -120,8 +122,9 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
||||||
String rpcPw;
|
String rpcPw;
|
||||||
@Nullable
|
@Nullable
|
||||||
String takeOfferSelectedPaymentAccountId;
|
String takeOfferSelectedPaymentAccountId;
|
||||||
private double buyerSecurityDepositAsPercent = Restrictions.getDefaultBuyerSecurityDepositAsPercent();
|
private double buyerSecurityDepositAsPercent = getDefaultBuyerSecurityDepositAsPercent(null);
|
||||||
private int ignoreDustThreshold = 600;
|
private int ignoreDustThreshold = 600;
|
||||||
|
private double buyerSecurityDepositAsPercentForCrypto = getDefaultBuyerSecurityDepositAsPercent(new CryptoCurrencyAccount());
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -178,8 +181,9 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
||||||
.setUsePriceNotifications(usePriceNotifications)
|
.setUsePriceNotifications(usePriceNotifications)
|
||||||
.setUseStandbyMode(useStandbyMode)
|
.setUseStandbyMode(useStandbyMode)
|
||||||
.setIsDaoFullNode(isDaoFullNode)
|
.setIsDaoFullNode(isDaoFullNode)
|
||||||
.setBuyerSecurityDepositAsPercent(buyerSecurityDepositAsPercent).
|
.setBuyerSecurityDepositAsPercent(buyerSecurityDepositAsPercent)
|
||||||
setIgnoreDustThreshold(ignoreDustThreshold);
|
.setIgnoreDustThreshold(ignoreDustThreshold)
|
||||||
|
.setBuyerSecurityDepositAsPercentForCrypto(buyerSecurityDepositAsPercentForCrypto);
|
||||||
Optional.ofNullable(backupDirectory).ifPresent(builder::setBackupDirectory);
|
Optional.ofNullable(backupDirectory).ifPresent(builder::setBackupDirectory);
|
||||||
Optional.ofNullable(preferredTradeCurrency).ifPresent(e -> builder.setPreferredTradeCurrency((PB.TradeCurrency) e.toProtoMessage()));
|
Optional.ofNullable(preferredTradeCurrency).ifPresent(e -> builder.setPreferredTradeCurrency((PB.TradeCurrency) e.toProtoMessage()));
|
||||||
Optional.ofNullable(offerBookChartScreenCurrencyCode).ifPresent(builder::setOfferBookChartScreenCurrencyCode);
|
Optional.ofNullable(offerBookChartScreenCurrencyCode).ifPresent(builder::setOfferBookChartScreenCurrencyCode);
|
||||||
|
@ -262,6 +266,8 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
||||||
proto.getRpcPw().isEmpty() ? null : proto.getRpcPw(),
|
proto.getRpcPw().isEmpty() ? null : proto.getRpcPw(),
|
||||||
proto.getTakeOfferSelectedPaymentAccountId().isEmpty() ? null : proto.getTakeOfferSelectedPaymentAccountId(),
|
proto.getTakeOfferSelectedPaymentAccountId().isEmpty() ? null : proto.getTakeOfferSelectedPaymentAccountId(),
|
||||||
proto.getBuyerSecurityDepositAsPercent(),
|
proto.getBuyerSecurityDepositAsPercent(),
|
||||||
proto.getIgnoreDustThreshold());
|
proto.getIgnoreDustThreshold(),
|
||||||
|
proto.getBuyerSecurityDepositAsPercentForCrypto());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,6 +493,7 @@ editOffer.confirmEdit=Confirm: Edit offer
|
||||||
editOffer.publishOffer=Publishing your offer.
|
editOffer.publishOffer=Publishing your offer.
|
||||||
editOffer.failed=Editing of offer failed:\n{0}
|
editOffer.failed=Editing of offer failed:\n{0}
|
||||||
editOffer.success=Your offer has been successfully edited.
|
editOffer.success=Your offer has been successfully edited.
|
||||||
|
editOffer.invalidDeposit=The buyer's security deposit is not within the constraints defined by the Bisq DAO and can no longer be edited.
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
# Portfolio
|
# Portfolio
|
||||||
|
|
|
@ -333,6 +333,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList
|
||||||
.show());
|
.show());
|
||||||
bisqSetup.setDisplayAlertHandler(alert -> new DisplayAlertMessageWindow()
|
bisqSetup.setDisplayAlertHandler(alert -> new DisplayAlertMessageWindow()
|
||||||
.alertMessage(alert)
|
.alertMessage(alert)
|
||||||
|
.closeButtonText(Res.get("shared.close"))
|
||||||
.onClose(() -> {
|
.onClose(() -> {
|
||||||
user.setDisplayedAlert(alert);
|
user.setDisplayedAlert(alert);
|
||||||
})
|
})
|
||||||
|
|
|
@ -180,7 +180,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
||||||
addressEntry = btcWalletService.getOrCreateAddressEntry(offerId, AddressEntry.Context.OFFER_FUNDING);
|
addressEntry = btcWalletService.getOrCreateAddressEntry(offerId, AddressEntry.Context.OFFER_FUNDING);
|
||||||
|
|
||||||
useMarketBasedPrice.set(preferences.isUsePercentageBasedPrice());
|
useMarketBasedPrice.set(preferences.isUsePercentageBasedPrice());
|
||||||
buyerSecurityDeposit.set(preferences.getBuyerSecurityDepositAsPercent());
|
buyerSecurityDeposit.set(preferences.getBuyerSecurityDepositAsPercent(null));
|
||||||
sellerSecurityDeposit.set(Restrictions.getSellerSecurityDepositAsPercent());
|
sellerSecurityDeposit.set(Restrictions.getSellerSecurityDepositAsPercent());
|
||||||
|
|
||||||
btcBalanceListener = new BalanceListener(getAddressEntry().getAddress()) {
|
btcBalanceListener = new BalanceListener(getAddressEntry().getAddress()) {
|
||||||
|
@ -436,6 +436,8 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
||||||
|
|
||||||
setTradeCurrencyFromPaymentAccount(paymentAccount);
|
setTradeCurrencyFromPaymentAccount(paymentAccount);
|
||||||
|
|
||||||
|
buyerSecurityDeposit.set(preferences.getBuyerSecurityDepositAsPercent(getPaymentAccount()));
|
||||||
|
|
||||||
long myLimit = accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrencyCode.get());
|
long myLimit = accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrencyCode.get());
|
||||||
if (amount.get() != null)
|
if (amount.get() != null)
|
||||||
this.amount.set(Coin.valueOf(Math.min(amount.get().value, myLimit)));
|
this.amount.set(Coin.valueOf(Math.min(amount.get().value, myLimit)));
|
||||||
|
@ -710,7 +712,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
||||||
|
|
||||||
void setBuyerSecurityDeposit(double value) {
|
void setBuyerSecurityDeposit(double value) {
|
||||||
this.buyerSecurityDeposit.set(value);
|
this.buyerSecurityDeposit.set(value);
|
||||||
preferences.setBuyerSecurityDepositAsPercent(value);
|
preferences.setBuyerSecurityDepositAsPercent(value, getPaymentAccount());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isUseMarketBasedPriceValue() {
|
protected boolean isUseMarketBasedPriceValue() {
|
||||||
|
|
|
@ -84,7 +84,7 @@ import static javafx.beans.binding.Bindings.createStringBinding;
|
||||||
public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> extends ActivatableWithDataModel<M> {
|
public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> extends ActivatableWithDataModel<M> {
|
||||||
private final BtcValidator btcValidator;
|
private final BtcValidator btcValidator;
|
||||||
private final BsqValidator bsqValidator;
|
private final BsqValidator bsqValidator;
|
||||||
private final SecurityDepositValidator securityDepositValidator;
|
protected final SecurityDepositValidator securityDepositValidator;
|
||||||
private final P2PService p2PService;
|
private final P2PService p2PService;
|
||||||
private final WalletsSetup walletsSetup;
|
private final WalletsSetup walletsSetup;
|
||||||
private final PriceFeedService priceFeedService;
|
private final PriceFeedService priceFeedService;
|
||||||
|
@ -104,7 +104,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||||
|
|
||||||
public final StringProperty amount = new SimpleStringProperty();
|
public final StringProperty amount = new SimpleStringProperty();
|
||||||
public final StringProperty minAmount = new SimpleStringProperty();
|
public final StringProperty minAmount = new SimpleStringProperty();
|
||||||
final StringProperty buyerSecurityDeposit = new SimpleStringProperty();
|
protected final StringProperty buyerSecurityDeposit = new SimpleStringProperty();
|
||||||
final StringProperty buyerSecurityDepositInBTC = new SimpleStringProperty();
|
final StringProperty buyerSecurityDepositInBTC = new SimpleStringProperty();
|
||||||
final StringProperty buyerSecurityDepositLabel = new SimpleStringProperty();
|
final StringProperty buyerSecurityDepositLabel = new SimpleStringProperty();
|
||||||
|
|
||||||
|
@ -599,6 +599,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||||
amountDescription = Res.get("createOffer.amountPriceBox.amountDescription",
|
amountDescription = Res.get("createOffer.amountPriceBox.amountDescription",
|
||||||
isBuy ? Res.get("shared.buy") : Res.get("shared.sell"));
|
isBuy ? Res.get("shared.buy") : Res.get("shared.sell"));
|
||||||
|
|
||||||
|
securityDepositValidator.setPaymentAccount(dataModel.paymentAccount);
|
||||||
buyerSecurityDeposit.set(btcFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
buyerSecurityDeposit.set(btcFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||||
buyerSecurityDepositLabel.set(getSecurityDepositLabel());
|
buyerSecurityDepositLabel.set(getSecurityDepositLabel());
|
||||||
|
|
||||||
|
@ -663,6 +664,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||||
|
|
||||||
btcValidator.setMaxValue(dataModel.paymentAccount.getPaymentMethod().getMaxTradeLimitAsCoin(dataModel.getTradeCurrencyCode().get()));
|
btcValidator.setMaxValue(dataModel.paymentAccount.getPaymentMethod().getMaxTradeLimitAsCoin(dataModel.getTradeCurrencyCode().get()));
|
||||||
btcValidator.setMaxTradeLimit(Coin.valueOf(dataModel.getMaxTradeLimit()));
|
btcValidator.setMaxTradeLimit(Coin.valueOf(dataModel.getMaxTradeLimit()));
|
||||||
|
|
||||||
|
securityDepositValidator.setPaymentAccount(paymentAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCurrencySelected(TradeCurrency tradeCurrency) {
|
public void onCurrencySelected(TradeCurrency tradeCurrency) {
|
||||||
|
@ -853,7 +856,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||||
InputValidator.ValidationResult result = securityDepositValidator.validate(buyerSecurityDeposit.get());
|
InputValidator.ValidationResult result = securityDepositValidator.validate(buyerSecurityDeposit.get());
|
||||||
buyerSecurityDepositValidationResult.set(result);
|
buyerSecurityDepositValidationResult.set(result);
|
||||||
if (result.isValid) {
|
if (result.isValid) {
|
||||||
double defaultSecurityDeposit = Restrictions.getDefaultBuyerSecurityDepositAsPercent();
|
double defaultSecurityDeposit = Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount());
|
||||||
String key = "buyerSecurityDepositIsLowerAsDefault";
|
String key = "buyerSecurityDepositIsLowerAsDefault";
|
||||||
double depositAsDouble = btcFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get());
|
double depositAsDouble = btcFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get());
|
||||||
if (preferences.showAgain(key) && depositAsDouble < defaultSecurityDeposit) {
|
if (preferences.showAgain(key) && depositAsDouble < defaultSecurityDeposit) {
|
||||||
|
@ -1121,7 +1124,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||||
if (buyerSecurityDeposit.get() != null && !buyerSecurityDeposit.get().isEmpty()) {
|
if (buyerSecurityDeposit.get() != null && !buyerSecurityDeposit.get().isEmpty()) {
|
||||||
dataModel.setBuyerSecurityDeposit(btcFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get()));
|
dataModel.setBuyerSecurityDeposit(btcFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get()));
|
||||||
} else {
|
} else {
|
||||||
dataModel.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent());
|
dataModel.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package bisq.desktop.main.overlays.windows;
|
package bisq.desktop.main.overlays.windows;
|
||||||
|
|
||||||
import bisq.desktop.components.AutoTooltipButton;
|
|
||||||
import bisq.desktop.components.HyperlinkWithIcon;
|
import bisq.desktop.components.HyperlinkWithIcon;
|
||||||
import bisq.desktop.main.overlays.Overlay;
|
import bisq.desktop.main.overlays.Overlay;
|
||||||
import bisq.desktop.util.FormBuilder;
|
import bisq.desktop.util.FormBuilder;
|
||||||
|
@ -25,13 +24,10 @@ import bisq.desktop.util.FormBuilder;
|
||||||
import bisq.core.alert.Alert;
|
import bisq.core.alert.Alert;
|
||||||
import bisq.core.locale.Res;
|
import bisq.core.locale.Res;
|
||||||
|
|
||||||
import javafx.scene.layout.GridPane;
|
|
||||||
|
|
||||||
import javafx.geometry.Insets;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static bisq.desktop.util.FormBuilder.addMultilineLabel;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class DisplayAlertMessageWindow extends Overlay<DisplayAlertMessageWindow> {
|
public class DisplayAlertMessageWindow extends Overlay<DisplayAlertMessageWindow> {
|
||||||
|
@ -50,10 +46,22 @@ public class DisplayAlertMessageWindow extends Overlay<DisplayAlertMessageWindow
|
||||||
public void show() {
|
public void show() {
|
||||||
width = 768;
|
width = 768;
|
||||||
// need to set headLine, otherwise the fields will not be created in addHeadLine
|
// need to set headLine, otherwise the fields will not be created in addHeadLine
|
||||||
headLine = Res.get("displayAlertMessageWindow.headline");
|
|
||||||
createGridPane();
|
createGridPane();
|
||||||
|
|
||||||
|
checkNotNull(alert, "alertMessage must not be null");
|
||||||
|
|
||||||
|
if (alert.isUpdateInfo()) {
|
||||||
|
information("");
|
||||||
|
headLine = Res.get("displayAlertMessageWindow.update.headline");
|
||||||
|
} else {
|
||||||
|
error("");
|
||||||
|
headLine = Res.get("displayAlertMessageWindow.headline");
|
||||||
|
}
|
||||||
|
|
||||||
|
headLine = Res.get("displayAlertMessageWindow.headline");
|
||||||
addHeadLine();
|
addHeadLine();
|
||||||
addContent();
|
addContent();
|
||||||
|
addButtons();
|
||||||
applyStyles();
|
applyStyles();
|
||||||
display();
|
display();
|
||||||
}
|
}
|
||||||
|
@ -69,28 +77,13 @@ public class DisplayAlertMessageWindow extends Overlay<DisplayAlertMessageWindow
|
||||||
|
|
||||||
private void addContent() {
|
private void addContent() {
|
||||||
checkNotNull(alert, "alertMessage must not be null");
|
checkNotNull(alert, "alertMessage must not be null");
|
||||||
FormBuilder.addMultilineLabel(gridPane, ++rowIndex, alert.getMessage(), 10);
|
addMultilineLabel(gridPane, ++rowIndex, alert.getMessage(), 10);
|
||||||
if (alert.isUpdateInfo()) {
|
if (alert.isUpdateInfo()) {
|
||||||
headLine = Res.get("displayAlertMessageWindow.update.headline");
|
|
||||||
headLineLabel.getStyleClass().addAll("headline-label", "highlight");
|
|
||||||
String url = "https://bisq.network/downloads";
|
String url = "https://bisq.network/downloads";
|
||||||
HyperlinkWithIcon hyperlinkWithIcon = FormBuilder.addLabelHyperlinkWithIcon(gridPane, ++rowIndex,
|
HyperlinkWithIcon hyperlinkWithIcon = FormBuilder.addLabelHyperlinkWithIcon(gridPane, ++rowIndex,
|
||||||
Res.get("displayAlertMessageWindow.update.download"), url, url).second;
|
Res.get("displayAlertMessageWindow.update.download"), url, url).second;
|
||||||
hyperlinkWithIcon.setMaxWidth(550);
|
hyperlinkWithIcon.setMaxWidth(550);
|
||||||
} else {
|
|
||||||
headLine = Res.get("displayAlertMessageWindow.headline");
|
|
||||||
headLineLabel.getStyleClass().addAll("headline-label", "error-text");
|
|
||||||
}
|
}
|
||||||
closeButton = new AutoTooltipButton(Res.get("shared.close"));
|
|
||||||
closeButton.setOnAction(e -> {
|
|
||||||
hide();
|
|
||||||
closeHandlerOptional.ifPresent(Runnable::run);
|
|
||||||
});
|
|
||||||
|
|
||||||
GridPane.setRowIndex(closeButton, ++rowIndex);
|
|
||||||
GridPane.setColumnIndex(closeButton, 1);
|
|
||||||
gridPane.getChildren().add(closeButton);
|
|
||||||
GridPane.setMargin(closeButton, new Insets(10, 0, 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -148,11 +148,15 @@ public class EditOfferView extends MutableOfferView<EditOfferViewModel> {
|
||||||
model.onStartEditOffer(errorMessage -> {
|
model.onStartEditOffer(errorMessage -> {
|
||||||
log.error(errorMessage);
|
log.error(errorMessage);
|
||||||
new Popup<>().warning(Res.get("editOffer.failed", errorMessage))
|
new Popup<>().warning(Res.get("editOffer.failed", errorMessage))
|
||||||
.onClose(() -> {
|
.onClose(this::close)
|
||||||
close();
|
|
||||||
})
|
|
||||||
.show();
|
.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!model.isSecurityDepositValid()) {
|
||||||
|
new Popup<>().warning(Res.get("editOffer.invalidDeposit"))
|
||||||
|
.onClose(this::close)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -80,4 +80,8 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
|
||||||
price.set(btcFormatter.formatPrice(null));
|
price.set(btcFormatter.formatPrice(null));
|
||||||
price.set(btcFormatter.formatPrice(dataModel.getPrice().get()));
|
price.set(btcFormatter.formatPrice(dataModel.getPrice().get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSecurityDepositValid() {
|
||||||
|
return securityDepositValidator.validate(buyerSecurityDeposit.get()).isValid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package bisq.desktop.util.validation;
|
||||||
|
|
||||||
import bisq.core.btc.wallet.Restrictions;
|
import bisq.core.btc.wallet.Restrictions;
|
||||||
import bisq.core.locale.Res;
|
import bisq.core.locale.Res;
|
||||||
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.util.BSFormatter;
|
import bisq.core.util.BSFormatter;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -26,12 +27,16 @@ import javax.inject.Inject;
|
||||||
public class SecurityDepositValidator extends NumberValidator {
|
public class SecurityDepositValidator extends NumberValidator {
|
||||||
|
|
||||||
private final BSFormatter formatter;
|
private final BSFormatter formatter;
|
||||||
|
private PaymentAccount paymentAccount;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SecurityDepositValidator(BSFormatter formatter) {
|
public SecurityDepositValidator(BSFormatter formatter) {
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPaymentAccount(PaymentAccount paymentAccount) {
|
||||||
|
this.paymentAccount = paymentAccount;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validate(String input) {
|
public ValidationResult validate(String input) {
|
||||||
|
@ -54,7 +59,7 @@ public class SecurityDepositValidator extends NumberValidator {
|
||||||
private ValidationResult validateIfNotTooLowPercentageValue(String input) {
|
private ValidationResult validateIfNotTooLowPercentageValue(String input) {
|
||||||
try {
|
try {
|
||||||
double percentage = formatter.parsePercentStringToDouble(input);
|
double percentage = formatter.parsePercentStringToDouble(input);
|
||||||
double minPercentage = Restrictions.getMinBuyerSecurityDepositAsPercent();
|
double minPercentage = Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount);
|
||||||
if (percentage < minPercentage)
|
if (percentage < minPercentage)
|
||||||
return new ValidationResult(false,
|
return new ValidationResult(false,
|
||||||
Res.get("validation.inputTooSmall", formatter.formatToPercentWithSymbol(minPercentage)));
|
Res.get("validation.inputTooSmall", formatter.formatToPercentWithSymbol(minPercentage)));
|
||||||
|
@ -68,7 +73,7 @@ public class SecurityDepositValidator extends NumberValidator {
|
||||||
private ValidationResult validateIfNotTooHighPercentageValue(String input) {
|
private ValidationResult validateIfNotTooHighPercentageValue(String input) {
|
||||||
try {
|
try {
|
||||||
double percentage = formatter.parsePercentStringToDouble(input);
|
double percentage = formatter.parsePercentStringToDouble(input);
|
||||||
double maxPercentage = Restrictions.getMaxBuyerSecurityDepositAsPercent();
|
double maxPercentage = Restrictions.getMaxBuyerSecurityDepositAsPercent(paymentAccount);
|
||||||
if (percentage > maxPercentage)
|
if (percentage > maxPercentage)
|
||||||
return new ValidationResult(false,
|
return new ValidationResult(false,
|
||||||
Res.get("validation.inputTooLarge", formatter.formatToPercentWithSymbol(maxPercentage)));
|
Res.get("validation.inputTooLarge", formatter.formatToPercentWithSymbol(maxPercentage)));
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class CreateOfferDataModelTest {
|
||||||
|
|
||||||
when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
|
when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
|
||||||
when(preferences.isUsePercentageBasedPrice()).thenReturn(true);
|
when(preferences.isUsePercentageBasedPrice()).thenReturn(true);
|
||||||
when(preferences.getBuyerSecurityDepositAsPercent()).thenReturn(0.01);
|
when(preferences.getBuyerSecurityDepositAsPercent(null)).thenReturn(0.01);
|
||||||
|
|
||||||
model = new CreateOfferDataModel(null, btcWalletService,
|
model = new CreateOfferDataModel(null, btcWalletService,
|
||||||
null, preferences, user, null,
|
null, preferences, user, null,
|
||||||
|
|
Loading…
Add table
Reference in a new issue