support goldback (XGB)
This commit is contained in:
parent
6a49fffb38
commit
9c2308f7a3
@ -209,7 +209,7 @@ public class AbstractPaymentAccountTest extends MethodTest {
|
||||
protected final String getCommaDelimitedTraditionalCurrencyCodes(Collection<TraditionalCurrency> traditionalCurrencies) {
|
||||
return traditionalCurrencies.stream()
|
||||
.sorted(Comparator.comparing(TradeCurrency::getCode))
|
||||
.map(c -> c.getCurrency().getCurrencyCode())
|
||||
.map(c -> c.getCode())
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,14 @@ public class CurrencyUtil {
|
||||
|
||||
private static String baseCurrencyCode = "XMR";
|
||||
|
||||
private static List<TraditionalCurrency> getTraditionalNonFiatCurrencies() {
|
||||
return Arrays.asList(
|
||||
new TraditionalCurrency("XAG", "Gold"),
|
||||
new TraditionalCurrency("XAU", "Silver"),
|
||||
new TraditionalCurrency("XGB", "Goldback")
|
||||
);
|
||||
}
|
||||
|
||||
// Calls to isTraditionalCurrency and isCryptoCurrency are very frequent so we use a cache of the results.
|
||||
// The main improvement was already achieved with using memoize for the source maps, but
|
||||
// the caching still reduces performance costs by about 20% for isCryptoCurrency (1752 ms vs 2121 ms) and about 50%
|
||||
@ -101,7 +109,7 @@ public class CurrencyUtil {
|
||||
|
||||
public static Collection<TraditionalCurrency> getAllSortedTraditionalCurrencies(Comparator comparator) {
|
||||
return (List<TraditionalCurrency>) getAllSortedTraditionalCurrencies().stream()
|
||||
.sorted(comparator) // sorted by comparator param
|
||||
.sorted(comparator)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -109,7 +117,7 @@ public class CurrencyUtil {
|
||||
List<TraditionalCurrency> currencies = CountryUtil.getAllCountries().stream()
|
||||
.map(country -> getCurrencyByCountryCode(country.code))
|
||||
.collect(Collectors.toList());
|
||||
for (String isoCode : nonFiatIsoCodes) currencies.add(new TraditionalCurrency(Currency.getInstance(isoCode)));
|
||||
currencies.addAll(getTraditionalNonFiatCurrencies());
|
||||
return currencies.stream().sorted(TradeCurrency::compareTo)
|
||||
.distinct()
|
||||
.collect(Collectors.toMap(TradeCurrency::getCode, Function.identity(), (x, y) -> x, LinkedHashMap::new));
|
||||
@ -131,12 +139,14 @@ public class CurrencyUtil {
|
||||
|
||||
public static List<TraditionalCurrency> getMainTraditionalCurrencies() {
|
||||
List<TraditionalCurrency> list = getMainFiatCurrencies();
|
||||
for (String isoCode : nonFiatIsoCodes) list.add(new TraditionalCurrency(isoCode));
|
||||
list.addAll(getTraditionalNonFiatCurrencies());
|
||||
postProcessTraditionalCurrenciesList(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<String> nonFiatIsoCodes = Arrays.asList("XAG", "XAU");
|
||||
private static boolean isTraditionalNonFiatCurrency(String currencyCode) {
|
||||
return getTraditionalNonFiatCurrencies().stream().anyMatch(c -> c.getCode().equals(currencyCode));
|
||||
}
|
||||
|
||||
private static void postProcessTraditionalCurrenciesList(List<TraditionalCurrency> list) {
|
||||
list.sort(TradeCurrency::compareTo);
|
||||
@ -209,7 +219,7 @@ public class CurrencyUtil {
|
||||
|
||||
public static boolean isFiatCurrency(String currencyCode) {
|
||||
if (!isTraditionalCurrency(currencyCode)) return false;
|
||||
if ("XAG".equalsIgnoreCase(currencyCode) || "XAU".equalsIgnoreCase(currencyCode)) return false;
|
||||
if (isTraditionalNonFiatCurrency(currencyCode)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -224,7 +234,7 @@ public class CurrencyUtil {
|
||||
boolean isTraditionalCurrency = currencyCode != null
|
||||
&& !currencyCode.isEmpty()
|
||||
&& !isCryptoCurrency(currencyCode)
|
||||
&& Currency.getInstance(currencyCode) != null;
|
||||
&& (isTraditionalNonFiatCurrency(currencyCode) || Currency.getInstance(currencyCode) != null);
|
||||
|
||||
if (currencyCode != null) {
|
||||
isTraditionalCurrencyMap.put(currencyCode, isTraditionalCurrency);
|
||||
@ -237,6 +247,17 @@ public class CurrencyUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVolumeRoundedToNearestUnit(String currencyCode) {
|
||||
return isFiatCurrency(currencyCode) ||
|
||||
"XGB".equals(currencyCode.toUpperCase());
|
||||
}
|
||||
|
||||
public static boolean isPricePrecise(String currencyCode) {
|
||||
return isCryptoCurrency(currencyCode) ||
|
||||
"XAU".equals(currencyCode.toUpperCase()) ||
|
||||
"XAG".equals(currencyCode.toUpperCase());
|
||||
}
|
||||
|
||||
public static Optional<TraditionalCurrency> getTraditionalCurrency(String currencyCode) {
|
||||
return Optional.ofNullable(traditionalCurrencyMapSupplier.get().get(currencyCode));
|
||||
}
|
||||
|
@ -30,15 +30,22 @@ import java.util.Locale;
|
||||
@ToString
|
||||
@Getter
|
||||
public final class TraditionalCurrency extends TradeCurrency {
|
||||
|
||||
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
|
||||
private final static String PREFIX = "★ ";
|
||||
|
||||
private final Currency currency;
|
||||
|
||||
public TraditionalCurrency(String currencyCode) {
|
||||
this(Currency.getInstance(currencyCode), getLocale());
|
||||
}
|
||||
|
||||
public TraditionalCurrency(String currencyCode, String name) {
|
||||
super(currencyCode, name);
|
||||
}
|
||||
|
||||
public TraditionalCurrency(TraditionalCurrency currency) {
|
||||
this(currency.getCode(), currency.getName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public TraditionalCurrency(Currency currency) {
|
||||
this(currency, getLocale());
|
||||
@ -47,7 +54,6 @@ public final class TraditionalCurrency extends TradeCurrency {
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public TraditionalCurrency(Currency currency, Locale locale) {
|
||||
super(currency.getCurrencyCode(), currency.getDisplayName(locale));
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
|
||||
@ -57,15 +63,15 @@ public final class TraditionalCurrency extends TradeCurrency {
|
||||
|
||||
@Override
|
||||
public Message toProtoMessage() {
|
||||
protobuf.Currency.Builder currencyBuilder = protobuf.Currency.newBuilder().setCurrencyCode(currency.getCurrencyCode());
|
||||
protobuf.TraditionalCurrency.Builder traditionalCurrencyBuilder = protobuf.TraditionalCurrency.newBuilder().setCurrency(currencyBuilder);
|
||||
return getTradeCurrencyBuilder()
|
||||
.setTraditionalCurrency(traditionalCurrencyBuilder)
|
||||
.setCode(code)
|
||||
.setName(name)
|
||||
.setTraditionalCurrency(protobuf.TraditionalCurrency.newBuilder())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static TraditionalCurrency fromProto(protobuf.TradeCurrency proto) {
|
||||
return new TraditionalCurrency(proto.getCode());
|
||||
return new TraditionalCurrency(proto.getCode(), proto.getName());
|
||||
}
|
||||
|
||||
|
||||
|
@ -632,7 +632,7 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
||||
|
||||
public void setTraditionalCurrencies(List<TraditionalCurrency> currencies) {
|
||||
traditionalCurrenciesAsObservable.setAll(currencies.stream()
|
||||
.map(traditionalCurrency -> new TraditionalCurrency(traditionalCurrency.getCurrency()))
|
||||
.map(traditionalCurrency -> new TraditionalCurrency(traditionalCurrency))
|
||||
.distinct().collect(Collectors.toList()));
|
||||
requestPersistence();
|
||||
}
|
||||
|
@ -29,9 +29,8 @@ public class FormattingUtils {
|
||||
|
||||
public final static String RANGE_SEPARATOR = " - ";
|
||||
|
||||
private static final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat nonFiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(8).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat traditionalFormat = new MonetaryFormat().shift(0).minDecimals(TraditionalMoney.SMALLEST_UNIT_EXPONENT).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat priceFormat4Decimals = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat priceFormat8Decimals = new MonetaryFormat().shift(0).minDecimals(8).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat cryptoFormat = new MonetaryFormat().shift(0).minDecimals(CryptoMoney.SMALLEST_UNIT_EXPONENT).repeatOptionalDecimals(0, 0);
|
||||
private static final DecimalFormat decimalFormat = new DecimalFormat("#.#");
|
||||
|
||||
@ -293,11 +292,7 @@ public class FormattingUtils {
|
||||
return formattedNumber;
|
||||
}
|
||||
|
||||
public static MonetaryFormat getMonetaryFormat(String currencyCode) {
|
||||
return CurrencyUtil.isTraditionalCurrency(currencyCode) ? traditionalFormat : cryptoFormat;
|
||||
}
|
||||
|
||||
public static MonetaryFormat getPriceMonetaryFormat(String currencyCode) {
|
||||
return CurrencyUtil.isFiatCurrency(currencyCode) ? fiatPriceFormat : nonFiatPriceFormat;
|
||||
return CurrencyUtil.isPricePrecise(currencyCode) ? priceFormat8Decimals : priceFormat4Decimals;
|
||||
}
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ import haveno.core.provider.price.MarketPrice;
|
||||
import haveno.core.provider.price.PriceFeedService;
|
||||
import haveno.core.trade.statistics.TradeStatisticsManager;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.AmountValidator8Decimals;
|
||||
import haveno.core.util.validation.AmountValidator4Decimals;
|
||||
import haveno.core.util.validation.InputValidator;
|
||||
import haveno.core.util.validation.MonetaryValidator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -53,21 +53,21 @@ public class PriceUtil {
|
||||
this.priceFeedService = priceFeedService;
|
||||
}
|
||||
|
||||
public static MonetaryValidator getPriceValidator(boolean isFiatCurrency) {
|
||||
return isFiatCurrency ?
|
||||
new FiatPriceValidator() :
|
||||
new NonFiatPriceValidator();
|
||||
public static MonetaryValidator getPriceValidator(String currencyCode) {
|
||||
return CurrencyUtil.isPricePrecise(currencyCode) ?
|
||||
new AmountValidator4Decimals() :
|
||||
new AmountValidator8Decimals();
|
||||
}
|
||||
|
||||
public static InputValidator.ValidationResult isTriggerPriceValid(String triggerPriceAsString,
|
||||
MarketPrice marketPrice,
|
||||
boolean isSellOffer,
|
||||
boolean isFiatCurrency) {
|
||||
String currencyCode) {
|
||||
if (triggerPriceAsString == null || triggerPriceAsString.isEmpty()) {
|
||||
return new InputValidator.ValidationResult(true);
|
||||
}
|
||||
|
||||
InputValidator.ValidationResult result = getPriceValidator(isFiatCurrency).validate(triggerPriceAsString);
|
||||
InputValidator.ValidationResult result = getPriceValidator(currencyCode).validate(triggerPriceAsString);
|
||||
if (!result.isValid) {
|
||||
return result;
|
||||
}
|
||||
@ -76,7 +76,8 @@ public class PriceUtil {
|
||||
long marketPriceAsLong = PriceUtil.getMarketPriceAsLong("" + marketPrice.getPrice(), marketPrice.getCurrencyCode());
|
||||
String marketPriceAsString = FormattingUtils.formatMarketPrice(marketPrice.getPrice(), marketPrice.getCurrencyCode());
|
||||
|
||||
if ((isSellOffer && isFiatCurrency) || (!isSellOffer && !isFiatCurrency)) {
|
||||
boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
|
||||
if ((isSellOffer && !isCryptoCurrency) || (!isSellOffer && isCryptoCurrency)) {
|
||||
if (triggerPriceAsLong >= marketPriceAsLong) {
|
||||
return new InputValidator.ValidationResult(false,
|
||||
Res.get("createOffer.triggerPrice.invalid.tooHigh", marketPriceAsString));
|
||||
|
@ -38,33 +38,33 @@ import java.util.Locale;
|
||||
|
||||
public class VolumeUtil {
|
||||
|
||||
private static final MonetaryFormat FIAT_VOLUME_FORMAT = new MonetaryFormat().shift(0).minDecimals(0).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat TRADITIONAL_VOLUME_FORMAT = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat VOLUME_FORMAT_UNIT = new MonetaryFormat().shift(0).minDecimals(0).repeatOptionalDecimals(0, 0);
|
||||
private static final MonetaryFormat VOLUME_FORMAT_PRECISE = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
|
||||
|
||||
private static double EXPONENT = Math.pow(10, TraditionalMoney.SMALLEST_UNIT_EXPONENT); // 1000000000000 with precision 8
|
||||
|
||||
public static Volume getAdjustedVolume(Volume volumeByAmount, String paymentMethodId) {
|
||||
if (PaymentMethod.isRoundedForAtmCash(paymentMethodId))
|
||||
return VolumeUtil.getRoundedAtmCashVolume(volumeByAmount);
|
||||
else if (CurrencyUtil.isFiatCurrency(volumeByAmount.getCurrencyCode()))
|
||||
return VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
||||
else if (CurrencyUtil.isVolumeRoundedToNearestUnit(volumeByAmount.getCurrencyCode()))
|
||||
return VolumeUtil.getRoundedVolumeUnit(volumeByAmount);
|
||||
else if (CurrencyUtil.isTraditionalCurrency(volumeByAmount.getCurrencyCode()))
|
||||
return VolumeUtil.getRoundedTraditionalVolume(volumeByAmount);
|
||||
return VolumeUtil.getRoundedVolumePrecise(volumeByAmount);
|
||||
return volumeByAmount;
|
||||
}
|
||||
|
||||
public static Volume getRoundedFiatVolume(Volume volumeByAmount) {
|
||||
// We want to get rounded to 1 unit of the fiat currency, e.g. 1 EUR.
|
||||
return getAdjustedFiatVolume(volumeByAmount, 1);
|
||||
public static Volume getRoundedVolumeUnit(Volume volumeByAmount) {
|
||||
// We want to get rounded to 1 unit of the currency, e.g. 1 EUR.
|
||||
return getAdjustedVolumeUnit(volumeByAmount, 1);
|
||||
}
|
||||
|
||||
private static Volume getRoundedAtmCashVolume(Volume volumeByAmount) {
|
||||
// EUR has precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of 10 so we divide by EXPONENT then
|
||||
// round and multiply with 10
|
||||
return getAdjustedFiatVolume(volumeByAmount, 10);
|
||||
return getAdjustedVolumeUnit(volumeByAmount, 10);
|
||||
}
|
||||
|
||||
public static Volume getRoundedTraditionalVolume(Volume volumeByAmount) {
|
||||
public static Volume getRoundedVolumePrecise(Volume volumeByAmount) {
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.####");
|
||||
double roundedVolume = Double.parseDouble(decimalFormat.format(Double.parseDouble(volumeByAmount.toString())));
|
||||
return Volume.parse(String.valueOf(roundedVolume), volumeByAmount.getCurrencyCode());
|
||||
@ -77,7 +77,7 @@ public class VolumeUtil {
|
||||
* units of 1 EUR, 10 means rounded to 10 EUR.
|
||||
* @return The adjusted Fiat volume
|
||||
*/
|
||||
public static Volume getAdjustedFiatVolume(Volume volumeByAmount, int factor) {
|
||||
public static Volume getAdjustedVolumeUnit(Volume volumeByAmount, int factor) {
|
||||
// Fiat currencies use precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of factor so we divide
|
||||
// by EXPONENT * factor then round and multiply with factor
|
||||
long roundedVolume = Math.round((double) volumeByAmount.getValue() / (EXPONENT * factor)) * factor;
|
||||
@ -168,6 +168,6 @@ public class VolumeUtil {
|
||||
}
|
||||
|
||||
private static MonetaryFormat getMonetaryFormat(String currencyCode) {
|
||||
return CurrencyUtil.isFiatCurrency(currencyCode) ? FIAT_VOLUME_FORMAT : TRADITIONAL_VOLUME_FORMAT;
|
||||
return CurrencyUtil.isVolumeRoundedToNearestUnit(currencyCode) ? VOLUME_FORMAT_UNIT : VOLUME_FORMAT_PRECISE;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ import java.math.BigInteger;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static haveno.core.util.VolumeUtil.getAdjustedFiatVolume;
|
||||
import static haveno.core.util.VolumeUtil.getAdjustedVolumeUnit;
|
||||
|
||||
public class CoinUtil {
|
||||
|
||||
@ -82,10 +82,10 @@ public class CoinUtil {
|
||||
public static BigInteger getRoundedAmount(BigInteger amount, Price price, long maxTradeLimit, String currencyCode, String paymentMethodId) {
|
||||
if (PaymentMethod.isRoundedForAtmCash(paymentMethodId)) {
|
||||
return getRoundedAtmCashAmount(amount, price, maxTradeLimit);
|
||||
} else if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
return getRoundedFiatAmount(amount, price, maxTradeLimit);
|
||||
} else if (CurrencyUtil.isVolumeRoundedToNearestUnit(currencyCode)) {
|
||||
return getRoundedAmountUnit(amount, price, maxTradeLimit);
|
||||
} else if (CurrencyUtil.isTraditionalCurrency(currencyCode)) {
|
||||
return getRoundedTraditionalAmount(amount, price, maxTradeLimit);
|
||||
return getRoundedAmountPrecise(amount, price, maxTradeLimit);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
@ -98,16 +98,16 @@ public class CoinUtil {
|
||||
* Calculate the possibly adjusted amount for {@code amount}, taking into account the
|
||||
* {@code price} and {@code maxTradeLimit} and {@code factor}.
|
||||
*
|
||||
* @param amount Bitcoin amount which is a candidate for getting rounded.
|
||||
* @param amount Monero amount which is a candidate for getting rounded.
|
||||
* @param price Price used in relation to that amount.
|
||||
* @param maxTradeLimit The max. trade limit of the users account, in satoshis.
|
||||
* @param maxTradeLimit The max. trade limit of the users account, in atomic units.
|
||||
* @return The adjusted amount
|
||||
*/
|
||||
public static BigInteger getRoundedFiatAmount(BigInteger amount, Price price, long maxTradeLimit) {
|
||||
public static BigInteger getRoundedAmountUnit(BigInteger amount, Price price, long maxTradeLimit) {
|
||||
return getAdjustedAmount(amount, price, maxTradeLimit, 1);
|
||||
}
|
||||
|
||||
public static BigInteger getRoundedTraditionalAmount(BigInteger amount, Price price, long maxTradeLimit) {
|
||||
public static BigInteger getRoundedAmountPrecise(BigInteger amount, Price price, long maxTradeLimit) {
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.####");
|
||||
double roundedXmrAmount = Double.parseDouble(decimalFormat.format(HavenoUtils.atomicUnitsToXmr(amount)));
|
||||
return HavenoUtils.xmrToAtomicUnits(roundedXmrAmount);
|
||||
@ -154,8 +154,8 @@ public class CoinUtil {
|
||||
|
||||
// We get the adjusted volume from our amount
|
||||
Volume volume = useSmallestUnitForAmount
|
||||
? getAdjustedFiatVolume(price.getVolumeByAmount(smallestUnitForAmount), factor)
|
||||
: getAdjustedFiatVolume(price.getVolumeByAmount(amount), factor);
|
||||
? getAdjustedVolumeUnit(price.getVolumeByAmount(smallestUnitForAmount), factor)
|
||||
: getAdjustedVolumeUnit(price.getVolumeByAmount(amount), factor);
|
||||
if (volume.getValue() <= 0)
|
||||
return BigInteger.valueOf(0);
|
||||
|
||||
|
@ -19,7 +19,7 @@ package haveno.core.util.validation;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class FiatPriceValidator extends MonetaryValidator {
|
||||
public class AmountValidator4Decimals extends MonetaryValidator {
|
||||
@Override
|
||||
public double getMinValue() {
|
||||
return 0.0001;
|
||||
@ -33,6 +33,6 @@ public class FiatPriceValidator extends MonetaryValidator {
|
||||
}
|
||||
|
||||
@Inject
|
||||
public FiatPriceValidator() {
|
||||
public AmountValidator4Decimals() {
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ package haveno.core.util.validation;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class NonFiatPriceValidator extends MonetaryValidator {
|
||||
public class AmountValidator8Decimals extends MonetaryValidator {
|
||||
@Override
|
||||
public double getMinValue() {
|
||||
return 0.00000001;
|
||||
@ -32,6 +32,6 @@ public class NonFiatPriceValidator extends MonetaryValidator {
|
||||
}
|
||||
|
||||
@Inject
|
||||
public NonFiatPriceValidator() {
|
||||
public AmountValidator8Decimals() {
|
||||
}
|
||||
}
|
@ -40,8 +40,6 @@ import haveno.core.user.User;
|
||||
import haveno.core.util.FormattingUtils;
|
||||
import haveno.core.util.ParsingUtils;
|
||||
import haveno.core.util.PriceUtil;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.InputValidator;
|
||||
import haveno.desktop.common.view.ActivatableView;
|
||||
import haveno.desktop.common.view.FxmlView;
|
||||
@ -313,9 +311,8 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
TradeCurrency selectedItem = currencyComboBox.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null) {
|
||||
selectedPriceAlertTradeCurrency = selectedItem.getCode();
|
||||
boolean isFiatCurrency = CurrencyUtil.isFiatCurrency(selectedPriceAlertTradeCurrency);
|
||||
priceAlertHighInputTextField.setValidator(isFiatCurrency ? new FiatPriceValidator() : new NonFiatPriceValidator());
|
||||
priceAlertLowInputTextField.setValidator(isFiatCurrency ? new FiatPriceValidator() : new NonFiatPriceValidator());
|
||||
priceAlertHighInputTextField.setValidator(PriceUtil.getPriceValidator(selectedPriceAlertTradeCurrency));
|
||||
priceAlertLowInputTextField.setValidator(PriceUtil.getPriceValidator(selectedPriceAlertTradeCurrency));
|
||||
} else {
|
||||
selectedPriceAlertTradeCurrency = null;
|
||||
}
|
||||
|
@ -257,15 +257,15 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
}
|
||||
|
||||
public int getMaxNumberOfPriceZeroDecimalsToColorize(Offer offer) {
|
||||
return offer.isFiatOffer()
|
||||
? GUIUtil.FIAT_DECIMALS_WITH_ZEROS
|
||||
: GUIUtil.CRYPTOS_DECIMALS_WITH_ZEROS;
|
||||
return CurrencyUtil.isVolumeRoundedToNearestUnit(offer.getCurrencyCode())
|
||||
? GUIUtil.NUM_DECIMALS_UNIT
|
||||
: GUIUtil.NUM_DECIMALS_PRECISE;
|
||||
}
|
||||
|
||||
public int getZeroDecimalsForPrice(Offer offer) {
|
||||
return offer.isFiatOffer()
|
||||
? GUIUtil.FIAT_PRICE_DECIMALS_WITH_ZEROS
|
||||
: GUIUtil.CRYPTOS_DECIMALS_WITH_ZEROS;
|
||||
return CurrencyUtil.isPricePrecise(offer.getCurrencyCode())
|
||||
? GUIUtil.NUM_DECIMALS_PRECISE
|
||||
: GUIUtil.NUM_DECIMALS_PRICE_LESS_PRECISE;
|
||||
}
|
||||
|
||||
public String getPrice(Offer offer) {
|
||||
|
@ -32,7 +32,6 @@ import haveno.core.offer.OfferDirection;
|
||||
import haveno.core.offer.OfferUtil;
|
||||
import haveno.core.offer.OpenOfferManager;
|
||||
import haveno.core.payment.PaymentAccount;
|
||||
import haveno.core.payment.payload.PaymentMethod;
|
||||
import haveno.core.provider.price.PriceFeedService;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.handlers.TransactionResultHandler;
|
||||
@ -685,8 +684,4 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
|
||||
public void setReserveExactAmount(boolean reserveExactAmount) {
|
||||
this.reserveExactAmount = reserveExactAmount;
|
||||
}
|
||||
|
||||
public boolean isUsingRoundedAtmCashAccount() {
|
||||
return PaymentMethod.isRoundedForAtmCash(paymentAccount.getPaymentMethod().getId());
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ import haveno.core.util.PriceUtil;
|
||||
import haveno.core.util.VolumeUtil;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import haveno.core.util.coin.CoinUtil;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.AmountValidator8Decimals;
|
||||
import haveno.core.util.validation.AmountValidator4Decimals;
|
||||
import haveno.core.util.validation.InputValidator;
|
||||
import haveno.core.util.validation.MonetaryValidator;
|
||||
import haveno.core.xmr.wallet.Restrictions;
|
||||
@ -95,8 +95,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
private final Preferences preferences;
|
||||
protected final CoinFormatter btcFormatter;
|
||||
private final FiatVolumeValidator fiatVolumeValidator;
|
||||
private final FiatPriceValidator fiatPriceValidator;
|
||||
private final NonFiatPriceValidator nonFiatPriceValidator;
|
||||
private final AmountValidator4Decimals amountValidator4Decimals;
|
||||
private final AmountValidator8Decimals amountValidator8Decimals;
|
||||
protected final OfferUtil offerUtil;
|
||||
|
||||
private String amountDescription;
|
||||
@ -184,8 +184,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
@Inject
|
||||
public MutableOfferViewModel(M dataModel,
|
||||
FiatVolumeValidator fiatVolumeValidator,
|
||||
FiatPriceValidator fiatPriceValidator,
|
||||
NonFiatPriceValidator nonFiatPriceValidator,
|
||||
AmountValidator4Decimals amountValidator4Decimals,
|
||||
AmountValidator8Decimals amountValidator8Decimals,
|
||||
XmrValidator btcValidator,
|
||||
SecurityDepositValidator securityDepositValidator,
|
||||
PriceFeedService priceFeedService,
|
||||
@ -197,8 +197,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
super(dataModel);
|
||||
|
||||
this.fiatVolumeValidator = fiatVolumeValidator;
|
||||
this.fiatPriceValidator = fiatPriceValidator;
|
||||
this.nonFiatPriceValidator = nonFiatPriceValidator;
|
||||
this.amountValidator4Decimals = amountValidator4Decimals;
|
||||
this.amountValidator8Decimals = amountValidator8Decimals;
|
||||
this.xmrValidator = btcValidator;
|
||||
this.securityDepositValidator = securityDepositValidator;
|
||||
this.priceFeedService = priceFeedService;
|
||||
@ -763,7 +763,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
InputValidator.ValidationResult result = PriceUtil.isTriggerPriceValid(triggerPriceAsString,
|
||||
marketPrice,
|
||||
dataModel.isSellOffer(),
|
||||
dataModel.isTraditionalCurrency()
|
||||
dataModel.getCurrencyCode()
|
||||
);
|
||||
triggerPriceValidationResult.set(result);
|
||||
updateButtonDisableState();
|
||||
@ -1175,16 +1175,20 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
return getVolumeValidator().validate(input);
|
||||
}
|
||||
|
||||
// TODO: replace with PriceUtils and VolumeUtils?
|
||||
|
||||
private MonetaryValidator getPriceValidator() {
|
||||
return CurrencyUtil.isFiatCurrency(getTradeCurrency().getCode()) ? fiatPriceValidator : nonFiatPriceValidator;
|
||||
return CurrencyUtil.isPricePrecise(getTradeCurrency().getCode()) ? amountValidator8Decimals : amountValidator4Decimals;
|
||||
}
|
||||
|
||||
private MonetaryValidator getVolumeValidator() {
|
||||
final String code = getTradeCurrency().getCode();
|
||||
if (CurrencyUtil.isFiatCurrency(code)) {
|
||||
return fiatVolumeValidator;
|
||||
} else if (CurrencyUtil.isVolumeRoundedToNearestUnit(code)) {
|
||||
return amountValidator4Decimals;
|
||||
} else {
|
||||
return nonFiatPriceValidator;
|
||||
return amountValidator8Decimals;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@ import haveno.core.provider.price.PriceFeedService;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.core.util.FormattingUtils;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.AmountValidator8Decimals;
|
||||
import haveno.core.util.validation.AmountValidator4Decimals;
|
||||
import haveno.desktop.Navigation;
|
||||
import haveno.desktop.common.model.ViewModel;
|
||||
import haveno.desktop.main.offer.MutableOfferViewModel;
|
||||
@ -40,8 +40,8 @@ class CreateOfferViewModel extends MutableOfferViewModel<CreateOfferDataModel> i
|
||||
@Inject
|
||||
public CreateOfferViewModel(CreateOfferDataModel dataModel,
|
||||
FiatVolumeValidator fiatVolumeValidator,
|
||||
FiatPriceValidator fiatPriceValidator,
|
||||
NonFiatPriceValidator nonFiatPriceValidator,
|
||||
AmountValidator4Decimals priceValidator4Decimals,
|
||||
AmountValidator8Decimals priceValidator8Decimals,
|
||||
XmrValidator btcValidator,
|
||||
SecurityDepositValidator securityDepositValidator,
|
||||
PriceFeedService priceFeedService,
|
||||
@ -52,8 +52,8 @@ class CreateOfferViewModel extends MutableOfferViewModel<CreateOfferDataModel> i
|
||||
OfferUtil offerUtil) {
|
||||
super(dataModel,
|
||||
fiatVolumeValidator,
|
||||
fiatPriceValidator,
|
||||
nonFiatPriceValidator,
|
||||
priceValidator4Decimals,
|
||||
priceValidator8Decimals,
|
||||
btcValidator,
|
||||
securityDepositValidator,
|
||||
priceFeedService,
|
||||
|
@ -427,7 +427,7 @@ abstract class OfferBookViewModel extends ActivatableViewModel {
|
||||
}
|
||||
|
||||
int getNumberOfDecimalsForVolume(OfferBookListItem item) {
|
||||
return item.getOffer().isFiatOffer() ? GUIUtil.FIAT_DECIMALS_WITH_ZEROS : GUIUtil.CRYPTOS_DECIMALS_WITH_ZEROS;
|
||||
return CurrencyUtil.isVolumeRoundedToNearestUnit(item.getOffer().getCurrencyCode()) ? GUIUtil.NUM_DECIMALS_UNIT : GUIUtil.NUM_DECIMALS_PRECISE;
|
||||
}
|
||||
|
||||
String getPaymentMethod(OfferBookListItem item) {
|
||||
|
@ -311,9 +311,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
|
||||
// We only apply the rounding if the amount is variable (minAmount is lower as amount).
|
||||
// Otherwise we could get an amount lower then the minAmount set by rounding
|
||||
BigInteger roundedAmount = dataModel.getOffer().isFiatOffer() ?
|
||||
CoinUtil.getRoundedFiatAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit) :
|
||||
CoinUtil.getRoundedTraditionalAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit);
|
||||
BigInteger roundedAmount = CoinUtil.getRoundedAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
|
||||
dataModel.applyAmount(roundedAmount);
|
||||
}
|
||||
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
|
||||
@ -582,9 +580,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
&& !isAmountEqualMinAmount(amount) && !isAmountEqualMaxAmount(amount)) {
|
||||
// We only apply the rounding if the amount is variable (minAmount is lower as amount).
|
||||
// Otherwise we could get an amount lower then the minAmount set by rounding
|
||||
amount = dataModel.getOffer().isFiatOffer() ?
|
||||
CoinUtil.getRoundedFiatAmount(amount, price, maxTradeLimit) :
|
||||
CoinUtil.getRoundedTraditionalAmount(amount, price, maxTradeLimit);
|
||||
amount = CoinUtil.getRoundedAmount(dataModel.getAmount().get(), price, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
|
||||
}
|
||||
}
|
||||
dataModel.applyAmount(amount);
|
||||
|
@ -29,8 +29,8 @@ import haveno.core.provider.price.PriceFeedService;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.core.util.FormattingUtils;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.AmountValidator8Decimals;
|
||||
import haveno.core.util.validation.AmountValidator4Decimals;
|
||||
import haveno.desktop.Navigation;
|
||||
import haveno.desktop.main.offer.MutableOfferViewModel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -43,8 +43,8 @@ class DuplicateOfferViewModel extends MutableOfferViewModel<DuplicateOfferDataMo
|
||||
@Inject
|
||||
public DuplicateOfferViewModel(DuplicateOfferDataModel dataModel,
|
||||
FiatVolumeValidator fiatVolumeValidator,
|
||||
FiatPriceValidator fiatPriceValidator,
|
||||
NonFiatPriceValidator nonFiatPriceValidator,
|
||||
AmountValidator4Decimals priceValidator4Decimals,
|
||||
AmountValidator8Decimals priceValidator8Decimals,
|
||||
XmrValidator btcValidator,
|
||||
SecurityDepositValidator securityDepositValidator,
|
||||
PriceFeedService priceFeedService,
|
||||
@ -55,8 +55,8 @@ class DuplicateOfferViewModel extends MutableOfferViewModel<DuplicateOfferDataMo
|
||||
OfferUtil offerUtil) {
|
||||
super(dataModel,
|
||||
fiatVolumeValidator,
|
||||
fiatPriceValidator,
|
||||
nonFiatPriceValidator,
|
||||
priceValidator4Decimals,
|
||||
priceValidator8Decimals,
|
||||
btcValidator,
|
||||
securityDepositValidator,
|
||||
priceFeedService,
|
||||
|
@ -31,8 +31,8 @@ import haveno.core.user.Preferences;
|
||||
import haveno.core.util.FormattingUtils;
|
||||
import haveno.core.util.PriceUtil;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.AmountValidator8Decimals;
|
||||
import haveno.core.util.validation.AmountValidator4Decimals;
|
||||
import haveno.desktop.Navigation;
|
||||
import haveno.desktop.main.offer.MutableOfferViewModel;
|
||||
|
||||
@ -43,8 +43,8 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
|
||||
@Inject
|
||||
public EditOfferViewModel(EditOfferDataModel dataModel,
|
||||
FiatVolumeValidator fiatVolumeValidator,
|
||||
FiatPriceValidator fiatPriceValidator,
|
||||
NonFiatPriceValidator nonFiatPriceValidator,
|
||||
AmountValidator4Decimals priceValidator4Decimals,
|
||||
AmountValidator8Decimals priceValidator8Decimals,
|
||||
XmrValidator btcValidator,
|
||||
SecurityDepositValidator securityDepositValidator,
|
||||
PriceFeedService priceFeedService,
|
||||
@ -55,8 +55,8 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
|
||||
OfferUtil offerUtil) {
|
||||
super(dataModel,
|
||||
fiatVolumeValidator,
|
||||
fiatPriceValidator,
|
||||
nonFiatPriceValidator,
|
||||
priceValidator4Decimals,
|
||||
priceValidator8Decimals,
|
||||
btcValidator,
|
||||
securityDepositValidator,
|
||||
priceFeedService,
|
||||
|
@ -126,9 +126,9 @@ public class GUIUtil {
|
||||
|
||||
public final static String OPEN_WEB_PAGE_KEY = "warnOpenURLWhenTorEnabled";
|
||||
|
||||
public final static int FIAT_DECIMALS_WITH_ZEROS = 0;
|
||||
public final static int FIAT_PRICE_DECIMALS_WITH_ZEROS = 3;
|
||||
public final static int CRYPTOS_DECIMALS_WITH_ZEROS = 7;
|
||||
public final static int NUM_DECIMALS_UNIT = 0;
|
||||
public final static int NUM_DECIMALS_PRICE_LESS_PRECISE = 3;
|
||||
public final static int NUM_DECIMALS_PRECISE = 7;
|
||||
public final static int AMOUNT_DECIMALS_WITH_ZEROS = 3;
|
||||
public final static int AMOUNT_DECIMALS = 4;
|
||||
|
||||
|
@ -39,7 +39,7 @@ public class MarketsPrintTool {
|
||||
|
||||
final Collection<TraditionalCurrency> allSortedTraditionalCurrencies = CurrencyUtil.getAllSortedTraditionalCurrencies();
|
||||
final Stream<MarketCurrency> traditionalStream = allSortedTraditionalCurrencies.stream()
|
||||
.filter(e -> !e.getCurrency().getCurrencyCode().equals("XMR")) // TODO (woodser): update to XMR
|
||||
.filter(e -> !e.getCode().equals("XMR"))
|
||||
.map(e -> new MarketCurrency("xmr_" + e.getCode().toLowerCase(), e.getName(), e.getCode()))
|
||||
.distinct();
|
||||
|
||||
|
@ -37,8 +37,8 @@ import haveno.core.user.Preferences;
|
||||
import haveno.core.user.User;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import haveno.core.util.coin.ImmutableCoinFormatter;
|
||||
import haveno.core.util.validation.NonFiatPriceValidator;
|
||||
import haveno.core.util.validation.FiatPriceValidator;
|
||||
import haveno.core.util.validation.AmountValidator8Decimals;
|
||||
import haveno.core.util.validation.AmountValidator4Decimals;
|
||||
import haveno.core.util.validation.InputValidator;
|
||||
import haveno.core.xmr.model.XmrAddressEntry;
|
||||
import haveno.core.xmr.wallet.XmrWalletService;
|
||||
@ -72,8 +72,8 @@ public class CreateOfferViewModelTest {
|
||||
Res.setup();
|
||||
|
||||
final XmrValidator btcValidator = new XmrValidator();
|
||||
final NonFiatPriceValidator nonFiatPriceValidator = new NonFiatPriceValidator();
|
||||
final FiatPriceValidator fiatPriceValidator = new FiatPriceValidator();
|
||||
final AmountValidator8Decimals priceValidator8Decimals = new AmountValidator8Decimals();
|
||||
final AmountValidator4Decimals priceValidator4Decimals = new AmountValidator4Decimals();
|
||||
|
||||
XmrAddressEntry addressEntry = mock(XmrAddressEntry.class);
|
||||
XmrWalletService xmrWalletService = mock(XmrWalletService.class);
|
||||
@ -121,8 +121,8 @@ public class CreateOfferViewModelTest {
|
||||
|
||||
model = new CreateOfferViewModel(dataModel,
|
||||
null,
|
||||
fiatPriceValidator,
|
||||
nonFiatPriceValidator,
|
||||
priceValidator4Decimals,
|
||||
priceValidator8Decimals,
|
||||
btcValidator,
|
||||
securityDepositValidator,
|
||||
priceFeedService,
|
||||
|
@ -1786,7 +1786,6 @@ message CryptoCurrency {
|
||||
}
|
||||
|
||||
message TraditionalCurrency {
|
||||
Currency currency = 1;
|
||||
}
|
||||
|
||||
message Country {
|
||||
|
Loading…
Reference in New Issue
Block a user