support goldback (XGB)

This commit is contained in:
woodser 2023-09-03 10:45:55 -04:00
parent 6a49fffb38
commit 9c2308f7a3
23 changed files with 135 additions and 121 deletions

View File

@ -209,7 +209,7 @@ public class AbstractPaymentAccountTest extends MethodTest {
protected final String getCommaDelimitedTraditionalCurrencyCodes(Collection<TraditionalCurrency> traditionalCurrencies) { protected final String getCommaDelimitedTraditionalCurrencyCodes(Collection<TraditionalCurrency> traditionalCurrencies) {
return traditionalCurrencies.stream() return traditionalCurrencies.stream()
.sorted(Comparator.comparing(TradeCurrency::getCode)) .sorted(Comparator.comparing(TradeCurrency::getCode))
.map(c -> c.getCurrency().getCurrencyCode()) .map(c -> c.getCode())
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
} }

View File

@ -56,6 +56,14 @@ public class CurrencyUtil {
private static String baseCurrencyCode = "XMR"; 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. // 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 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% // 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) { public static Collection<TraditionalCurrency> getAllSortedTraditionalCurrencies(Comparator comparator) {
return (List<TraditionalCurrency>) getAllSortedTraditionalCurrencies().stream() return (List<TraditionalCurrency>) getAllSortedTraditionalCurrencies().stream()
.sorted(comparator) // sorted by comparator param .sorted(comparator)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -109,7 +117,7 @@ public class CurrencyUtil {
List<TraditionalCurrency> currencies = CountryUtil.getAllCountries().stream() List<TraditionalCurrency> currencies = CountryUtil.getAllCountries().stream()
.map(country -> getCurrencyByCountryCode(country.code)) .map(country -> getCurrencyByCountryCode(country.code))
.collect(Collectors.toList()); .collect(Collectors.toList());
for (String isoCode : nonFiatIsoCodes) currencies.add(new TraditionalCurrency(Currency.getInstance(isoCode))); currencies.addAll(getTraditionalNonFiatCurrencies());
return currencies.stream().sorted(TradeCurrency::compareTo) return currencies.stream().sorted(TradeCurrency::compareTo)
.distinct() .distinct()
.collect(Collectors.toMap(TradeCurrency::getCode, Function.identity(), (x, y) -> x, LinkedHashMap::new)); .collect(Collectors.toMap(TradeCurrency::getCode, Function.identity(), (x, y) -> x, LinkedHashMap::new));
@ -131,12 +139,14 @@ public class CurrencyUtil {
public static List<TraditionalCurrency> getMainTraditionalCurrencies() { public static List<TraditionalCurrency> getMainTraditionalCurrencies() {
List<TraditionalCurrency> list = getMainFiatCurrencies(); List<TraditionalCurrency> list = getMainFiatCurrencies();
for (String isoCode : nonFiatIsoCodes) list.add(new TraditionalCurrency(isoCode)); list.addAll(getTraditionalNonFiatCurrencies());
postProcessTraditionalCurrenciesList(list); postProcessTraditionalCurrenciesList(list);
return 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) { private static void postProcessTraditionalCurrenciesList(List<TraditionalCurrency> list) {
list.sort(TradeCurrency::compareTo); list.sort(TradeCurrency::compareTo);
@ -209,7 +219,7 @@ public class CurrencyUtil {
public static boolean isFiatCurrency(String currencyCode) { public static boolean isFiatCurrency(String currencyCode) {
if (!isTraditionalCurrency(currencyCode)) return false; if (!isTraditionalCurrency(currencyCode)) return false;
if ("XAG".equalsIgnoreCase(currencyCode) || "XAU".equalsIgnoreCase(currencyCode)) return false; if (isTraditionalNonFiatCurrency(currencyCode)) return false;
return true; return true;
} }
@ -224,7 +234,7 @@ public class CurrencyUtil {
boolean isTraditionalCurrency = currencyCode != null boolean isTraditionalCurrency = currencyCode != null
&& !currencyCode.isEmpty() && !currencyCode.isEmpty()
&& !isCryptoCurrency(currencyCode) && !isCryptoCurrency(currencyCode)
&& Currency.getInstance(currencyCode) != null; && (isTraditionalNonFiatCurrency(currencyCode) || Currency.getInstance(currencyCode) != null);
if (currencyCode != null) { if (currencyCode != null) {
isTraditionalCurrencyMap.put(currencyCode, isTraditionalCurrency); 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) { public static Optional<TraditionalCurrency> getTraditionalCurrency(String currencyCode) {
return Optional.ofNullable(traditionalCurrencyMapSupplier.get().get(currencyCode)); return Optional.ofNullable(traditionalCurrencyMapSupplier.get().get(currencyCode));
} }

View File

@ -30,15 +30,22 @@ import java.util.Locale;
@ToString @ToString
@Getter @Getter
public final class TraditionalCurrency extends TradeCurrency { public final class TraditionalCurrency extends TradeCurrency {
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618 // http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
private final static String PREFIX = ""; private final static String PREFIX = "";
private final Currency currency;
public TraditionalCurrency(String currencyCode) { public TraditionalCurrency(String currencyCode) {
this(Currency.getInstance(currencyCode), getLocale()); 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") @SuppressWarnings("WeakerAccess")
public TraditionalCurrency(Currency currency) { public TraditionalCurrency(Currency currency) {
this(currency, getLocale()); this(currency, getLocale());
@ -47,7 +54,6 @@ public final class TraditionalCurrency extends TradeCurrency {
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public TraditionalCurrency(Currency currency, Locale locale) { public TraditionalCurrency(Currency currency, Locale locale) {
super(currency.getCurrencyCode(), currency.getDisplayName(locale)); super(currency.getCurrencyCode(), currency.getDisplayName(locale));
this.currency = currency;
} }
@ -57,15 +63,15 @@ public final class TraditionalCurrency extends TradeCurrency {
@Override @Override
public Message toProtoMessage() { public Message toProtoMessage() {
protobuf.Currency.Builder currencyBuilder = protobuf.Currency.newBuilder().setCurrencyCode(currency.getCurrencyCode());
protobuf.TraditionalCurrency.Builder traditionalCurrencyBuilder = protobuf.TraditionalCurrency.newBuilder().setCurrency(currencyBuilder);
return getTradeCurrencyBuilder() return getTradeCurrencyBuilder()
.setTraditionalCurrency(traditionalCurrencyBuilder) .setCode(code)
.setName(name)
.setTraditionalCurrency(protobuf.TraditionalCurrency.newBuilder())
.build(); .build();
} }
public static TraditionalCurrency fromProto(protobuf.TradeCurrency proto) { public static TraditionalCurrency fromProto(protobuf.TradeCurrency proto) {
return new TraditionalCurrency(proto.getCode()); return new TraditionalCurrency(proto.getCode(), proto.getName());
} }

View File

@ -632,7 +632,7 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
public void setTraditionalCurrencies(List<TraditionalCurrency> currencies) { public void setTraditionalCurrencies(List<TraditionalCurrency> currencies) {
traditionalCurrenciesAsObservable.setAll(currencies.stream() traditionalCurrenciesAsObservable.setAll(currencies.stream()
.map(traditionalCurrency -> new TraditionalCurrency(traditionalCurrency.getCurrency())) .map(traditionalCurrency -> new TraditionalCurrency(traditionalCurrency))
.distinct().collect(Collectors.toList())); .distinct().collect(Collectors.toList()));
requestPersistence(); requestPersistence();
} }

View File

@ -29,9 +29,8 @@ public class FormattingUtils {
public final static String RANGE_SEPARATOR = " - "; public final static String RANGE_SEPARATOR = " - ";
private static final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0); private static final MonetaryFormat priceFormat4Decimals = 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 priceFormat8Decimals = 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 cryptoFormat = new MonetaryFormat().shift(0).minDecimals(CryptoMoney.SMALLEST_UNIT_EXPONENT).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("#.#"); private static final DecimalFormat decimalFormat = new DecimalFormat("#.#");
@ -293,11 +292,7 @@ public class FormattingUtils {
return formattedNumber; return formattedNumber;
} }
public static MonetaryFormat getMonetaryFormat(String currencyCode) {
return CurrencyUtil.isTraditionalCurrency(currencyCode) ? traditionalFormat : cryptoFormat;
}
public static MonetaryFormat getPriceMonetaryFormat(String currencyCode) { public static MonetaryFormat getPriceMonetaryFormat(String currencyCode) {
return CurrencyUtil.isFiatCurrency(currencyCode) ? fiatPriceFormat : nonFiatPriceFormat; return CurrencyUtil.isPricePrecise(currencyCode) ? priceFormat8Decimals : priceFormat4Decimals;
} }
} }

View File

@ -29,8 +29,8 @@ import haveno.core.provider.price.MarketPrice;
import haveno.core.provider.price.PriceFeedService; import haveno.core.provider.price.PriceFeedService;
import haveno.core.trade.statistics.TradeStatisticsManager; import haveno.core.trade.statistics.TradeStatisticsManager;
import haveno.core.user.Preferences; import haveno.core.user.Preferences;
import haveno.core.util.validation.NonFiatPriceValidator; import haveno.core.util.validation.AmountValidator8Decimals;
import haveno.core.util.validation.FiatPriceValidator; import haveno.core.util.validation.AmountValidator4Decimals;
import haveno.core.util.validation.InputValidator; import haveno.core.util.validation.InputValidator;
import haveno.core.util.validation.MonetaryValidator; import haveno.core.util.validation.MonetaryValidator;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -53,21 +53,21 @@ public class PriceUtil {
this.priceFeedService = priceFeedService; this.priceFeedService = priceFeedService;
} }
public static MonetaryValidator getPriceValidator(boolean isFiatCurrency) { public static MonetaryValidator getPriceValidator(String currencyCode) {
return isFiatCurrency ? return CurrencyUtil.isPricePrecise(currencyCode) ?
new FiatPriceValidator() : new AmountValidator4Decimals() :
new NonFiatPriceValidator(); new AmountValidator8Decimals();
} }
public static InputValidator.ValidationResult isTriggerPriceValid(String triggerPriceAsString, public static InputValidator.ValidationResult isTriggerPriceValid(String triggerPriceAsString,
MarketPrice marketPrice, MarketPrice marketPrice,
boolean isSellOffer, boolean isSellOffer,
boolean isFiatCurrency) { String currencyCode) {
if (triggerPriceAsString == null || triggerPriceAsString.isEmpty()) { if (triggerPriceAsString == null || triggerPriceAsString.isEmpty()) {
return new InputValidator.ValidationResult(true); return new InputValidator.ValidationResult(true);
} }
InputValidator.ValidationResult result = getPriceValidator(isFiatCurrency).validate(triggerPriceAsString); InputValidator.ValidationResult result = getPriceValidator(currencyCode).validate(triggerPriceAsString);
if (!result.isValid) { if (!result.isValid) {
return result; return result;
} }
@ -76,7 +76,8 @@ public class PriceUtil {
long marketPriceAsLong = PriceUtil.getMarketPriceAsLong("" + marketPrice.getPrice(), marketPrice.getCurrencyCode()); long marketPriceAsLong = PriceUtil.getMarketPriceAsLong("" + marketPrice.getPrice(), marketPrice.getCurrencyCode());
String marketPriceAsString = FormattingUtils.formatMarketPrice(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) { if (triggerPriceAsLong >= marketPriceAsLong) {
return new InputValidator.ValidationResult(false, return new InputValidator.ValidationResult(false,
Res.get("createOffer.triggerPrice.invalid.tooHigh", marketPriceAsString)); Res.get("createOffer.triggerPrice.invalid.tooHigh", marketPriceAsString));

View File

@ -38,33 +38,33 @@ import java.util.Locale;
public class VolumeUtil { public class VolumeUtil {
private static final MonetaryFormat FIAT_VOLUME_FORMAT = new MonetaryFormat().shift(0).minDecimals(0).repeatOptionalDecimals(0, 0); private static final MonetaryFormat VOLUME_FORMAT_UNIT = 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_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 private static double EXPONENT = Math.pow(10, TraditionalMoney.SMALLEST_UNIT_EXPONENT); // 1000000000000 with precision 8
public static Volume getAdjustedVolume(Volume volumeByAmount, String paymentMethodId) { public static Volume getAdjustedVolume(Volume volumeByAmount, String paymentMethodId) {
if (PaymentMethod.isRoundedForAtmCash(paymentMethodId)) if (PaymentMethod.isRoundedForAtmCash(paymentMethodId))
return VolumeUtil.getRoundedAtmCashVolume(volumeByAmount); return VolumeUtil.getRoundedAtmCashVolume(volumeByAmount);
else if (CurrencyUtil.isFiatCurrency(volumeByAmount.getCurrencyCode())) else if (CurrencyUtil.isVolumeRoundedToNearestUnit(volumeByAmount.getCurrencyCode()))
return VolumeUtil.getRoundedFiatVolume(volumeByAmount); return VolumeUtil.getRoundedVolumeUnit(volumeByAmount);
else if (CurrencyUtil.isTraditionalCurrency(volumeByAmount.getCurrencyCode())) else if (CurrencyUtil.isTraditionalCurrency(volumeByAmount.getCurrencyCode()))
return VolumeUtil.getRoundedTraditionalVolume(volumeByAmount); return VolumeUtil.getRoundedVolumePrecise(volumeByAmount);
return volumeByAmount; return volumeByAmount;
} }
public static Volume getRoundedFiatVolume(Volume volumeByAmount) { public static Volume getRoundedVolumeUnit(Volume volumeByAmount) {
// We want to get rounded to 1 unit of the fiat currency, e.g. 1 EUR. // We want to get rounded to 1 unit of the currency, e.g. 1 EUR.
return getAdjustedFiatVolume(volumeByAmount, 1); return getAdjustedVolumeUnit(volumeByAmount, 1);
} }
private static Volume getRoundedAtmCashVolume(Volume volumeByAmount) { 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 // EUR has precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of 10 so we divide by EXPONENT then
// round and multiply with 10 // 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("#.####"); DecimalFormat decimalFormat = new DecimalFormat("#.####");
double roundedVolume = Double.parseDouble(decimalFormat.format(Double.parseDouble(volumeByAmount.toString()))); double roundedVolume = Double.parseDouble(decimalFormat.format(Double.parseDouble(volumeByAmount.toString())));
return Volume.parse(String.valueOf(roundedVolume), volumeByAmount.getCurrencyCode()); 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. * units of 1 EUR, 10 means rounded to 10 EUR.
* @return The adjusted Fiat volume * @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 // 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 // by EXPONENT * factor then round and multiply with factor
long roundedVolume = Math.round((double) volumeByAmount.getValue() / (EXPONENT * factor)) * factor; long roundedVolume = Math.round((double) volumeByAmount.getValue() / (EXPONENT * factor)) * factor;
@ -168,6 +168,6 @@ public class VolumeUtil {
} }
private static MonetaryFormat getMonetaryFormat(String currencyCode) { 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;
} }
} }

View File

@ -32,7 +32,7 @@ import java.math.BigInteger;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import static com.google.common.base.Preconditions.checkArgument; 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 { public class CoinUtil {
@ -82,10 +82,10 @@ public class CoinUtil {
public static BigInteger getRoundedAmount(BigInteger amount, Price price, long maxTradeLimit, String currencyCode, String paymentMethodId) { public static BigInteger getRoundedAmount(BigInteger amount, Price price, long maxTradeLimit, String currencyCode, String paymentMethodId) {
if (PaymentMethod.isRoundedForAtmCash(paymentMethodId)) { if (PaymentMethod.isRoundedForAtmCash(paymentMethodId)) {
return getRoundedAtmCashAmount(amount, price, maxTradeLimit); return getRoundedAtmCashAmount(amount, price, maxTradeLimit);
} else if (CurrencyUtil.isFiatCurrency(currencyCode)) { } else if (CurrencyUtil.isVolumeRoundedToNearestUnit(currencyCode)) {
return getRoundedFiatAmount(amount, price, maxTradeLimit); return getRoundedAmountUnit(amount, price, maxTradeLimit);
} else if (CurrencyUtil.isTraditionalCurrency(currencyCode)) { } else if (CurrencyUtil.isTraditionalCurrency(currencyCode)) {
return getRoundedTraditionalAmount(amount, price, maxTradeLimit); return getRoundedAmountPrecise(amount, price, maxTradeLimit);
} }
return amount; return amount;
} }
@ -98,16 +98,16 @@ public class CoinUtil {
* Calculate the possibly adjusted amount for {@code amount}, taking into account the * Calculate the possibly adjusted amount for {@code amount}, taking into account the
* {@code price} and {@code maxTradeLimit} and {@code factor}. * {@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 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 * @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); 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("#.####"); DecimalFormat decimalFormat = new DecimalFormat("#.####");
double roundedXmrAmount = Double.parseDouble(decimalFormat.format(HavenoUtils.atomicUnitsToXmr(amount))); double roundedXmrAmount = Double.parseDouble(decimalFormat.format(HavenoUtils.atomicUnitsToXmr(amount)));
return HavenoUtils.xmrToAtomicUnits(roundedXmrAmount); return HavenoUtils.xmrToAtomicUnits(roundedXmrAmount);
@ -154,8 +154,8 @@ public class CoinUtil {
// We get the adjusted volume from our amount // We get the adjusted volume from our amount
Volume volume = useSmallestUnitForAmount Volume volume = useSmallestUnitForAmount
? getAdjustedFiatVolume(price.getVolumeByAmount(smallestUnitForAmount), factor) ? getAdjustedVolumeUnit(price.getVolumeByAmount(smallestUnitForAmount), factor)
: getAdjustedFiatVolume(price.getVolumeByAmount(amount), factor); : getAdjustedVolumeUnit(price.getVolumeByAmount(amount), factor);
if (volume.getValue() <= 0) if (volume.getValue() <= 0)
return BigInteger.valueOf(0); return BigInteger.valueOf(0);

View File

@ -19,7 +19,7 @@ package haveno.core.util.validation;
import javax.inject.Inject; import javax.inject.Inject;
public class FiatPriceValidator extends MonetaryValidator { public class AmountValidator4Decimals extends MonetaryValidator {
@Override @Override
public double getMinValue() { public double getMinValue() {
return 0.0001; return 0.0001;
@ -33,6 +33,6 @@ public class FiatPriceValidator extends MonetaryValidator {
} }
@Inject @Inject
public FiatPriceValidator() { public AmountValidator4Decimals() {
} }
} }

View File

@ -19,7 +19,7 @@ package haveno.core.util.validation;
import javax.inject.Inject; import javax.inject.Inject;
public class NonFiatPriceValidator extends MonetaryValidator { public class AmountValidator8Decimals extends MonetaryValidator {
@Override @Override
public double getMinValue() { public double getMinValue() {
return 0.00000001; return 0.00000001;
@ -32,6 +32,6 @@ public class NonFiatPriceValidator extends MonetaryValidator {
} }
@Inject @Inject
public NonFiatPriceValidator() { public AmountValidator8Decimals() {
} }
} }

View File

@ -40,8 +40,6 @@ import haveno.core.user.User;
import haveno.core.util.FormattingUtils; import haveno.core.util.FormattingUtils;
import haveno.core.util.ParsingUtils; import haveno.core.util.ParsingUtils;
import haveno.core.util.PriceUtil; 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.core.util.validation.InputValidator;
import haveno.desktop.common.view.ActivatableView; import haveno.desktop.common.view.ActivatableView;
import haveno.desktop.common.view.FxmlView; import haveno.desktop.common.view.FxmlView;
@ -313,9 +311,8 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
TradeCurrency selectedItem = currencyComboBox.getSelectionModel().getSelectedItem(); TradeCurrency selectedItem = currencyComboBox.getSelectionModel().getSelectedItem();
if (selectedItem != null) { if (selectedItem != null) {
selectedPriceAlertTradeCurrency = selectedItem.getCode(); selectedPriceAlertTradeCurrency = selectedItem.getCode();
boolean isFiatCurrency = CurrencyUtil.isFiatCurrency(selectedPriceAlertTradeCurrency); priceAlertHighInputTextField.setValidator(PriceUtil.getPriceValidator(selectedPriceAlertTradeCurrency));
priceAlertHighInputTextField.setValidator(isFiatCurrency ? new FiatPriceValidator() : new NonFiatPriceValidator()); priceAlertLowInputTextField.setValidator(PriceUtil.getPriceValidator(selectedPriceAlertTradeCurrency));
priceAlertLowInputTextField.setValidator(isFiatCurrency ? new FiatPriceValidator() : new NonFiatPriceValidator());
} else { } else {
selectedPriceAlertTradeCurrency = null; selectedPriceAlertTradeCurrency = null;
} }

View File

@ -257,15 +257,15 @@ class OfferBookChartViewModel extends ActivatableViewModel {
} }
public int getMaxNumberOfPriceZeroDecimalsToColorize(Offer offer) { public int getMaxNumberOfPriceZeroDecimalsToColorize(Offer offer) {
return offer.isFiatOffer() return CurrencyUtil.isVolumeRoundedToNearestUnit(offer.getCurrencyCode())
? GUIUtil.FIAT_DECIMALS_WITH_ZEROS ? GUIUtil.NUM_DECIMALS_UNIT
: GUIUtil.CRYPTOS_DECIMALS_WITH_ZEROS; : GUIUtil.NUM_DECIMALS_PRECISE;
} }
public int getZeroDecimalsForPrice(Offer offer) { public int getZeroDecimalsForPrice(Offer offer) {
return offer.isFiatOffer() return CurrencyUtil.isPricePrecise(offer.getCurrencyCode())
? GUIUtil.FIAT_PRICE_DECIMALS_WITH_ZEROS ? GUIUtil.NUM_DECIMALS_PRECISE
: GUIUtil.CRYPTOS_DECIMALS_WITH_ZEROS; : GUIUtil.NUM_DECIMALS_PRICE_LESS_PRECISE;
} }
public String getPrice(Offer offer) { public String getPrice(Offer offer) {

View File

@ -32,7 +32,6 @@ import haveno.core.offer.OfferDirection;
import haveno.core.offer.OfferUtil; import haveno.core.offer.OfferUtil;
import haveno.core.offer.OpenOfferManager; import haveno.core.offer.OpenOfferManager;
import haveno.core.payment.PaymentAccount; import haveno.core.payment.PaymentAccount;
import haveno.core.payment.payload.PaymentMethod;
import haveno.core.provider.price.PriceFeedService; import haveno.core.provider.price.PriceFeedService;
import haveno.core.trade.HavenoUtils; import haveno.core.trade.HavenoUtils;
import haveno.core.trade.handlers.TransactionResultHandler; import haveno.core.trade.handlers.TransactionResultHandler;
@ -685,8 +684,4 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
public void setReserveExactAmount(boolean reserveExactAmount) { public void setReserveExactAmount(boolean reserveExactAmount) {
this.reserveExactAmount = reserveExactAmount; this.reserveExactAmount = reserveExactAmount;
} }
public boolean isUsingRoundedAtmCashAccount() {
return PaymentMethod.isRoundedForAtmCash(paymentAccount.getPaymentMethod().getId());
}
} }

View File

@ -47,8 +47,8 @@ import haveno.core.util.PriceUtil;
import haveno.core.util.VolumeUtil; import haveno.core.util.VolumeUtil;
import haveno.core.util.coin.CoinFormatter; import haveno.core.util.coin.CoinFormatter;
import haveno.core.util.coin.CoinUtil; import haveno.core.util.coin.CoinUtil;
import haveno.core.util.validation.NonFiatPriceValidator; import haveno.core.util.validation.AmountValidator8Decimals;
import haveno.core.util.validation.FiatPriceValidator; import haveno.core.util.validation.AmountValidator4Decimals;
import haveno.core.util.validation.InputValidator; import haveno.core.util.validation.InputValidator;
import haveno.core.util.validation.MonetaryValidator; import haveno.core.util.validation.MonetaryValidator;
import haveno.core.xmr.wallet.Restrictions; import haveno.core.xmr.wallet.Restrictions;
@ -95,8 +95,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
private final Preferences preferences; private final Preferences preferences;
protected final CoinFormatter btcFormatter; protected final CoinFormatter btcFormatter;
private final FiatVolumeValidator fiatVolumeValidator; private final FiatVolumeValidator fiatVolumeValidator;
private final FiatPriceValidator fiatPriceValidator; private final AmountValidator4Decimals amountValidator4Decimals;
private final NonFiatPriceValidator nonFiatPriceValidator; private final AmountValidator8Decimals amountValidator8Decimals;
protected final OfferUtil offerUtil; protected final OfferUtil offerUtil;
private String amountDescription; private String amountDescription;
@ -184,8 +184,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
@Inject @Inject
public MutableOfferViewModel(M dataModel, public MutableOfferViewModel(M dataModel,
FiatVolumeValidator fiatVolumeValidator, FiatVolumeValidator fiatVolumeValidator,
FiatPriceValidator fiatPriceValidator, AmountValidator4Decimals amountValidator4Decimals,
NonFiatPriceValidator nonFiatPriceValidator, AmountValidator8Decimals amountValidator8Decimals,
XmrValidator btcValidator, XmrValidator btcValidator,
SecurityDepositValidator securityDepositValidator, SecurityDepositValidator securityDepositValidator,
PriceFeedService priceFeedService, PriceFeedService priceFeedService,
@ -197,8 +197,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
super(dataModel); super(dataModel);
this.fiatVolumeValidator = fiatVolumeValidator; this.fiatVolumeValidator = fiatVolumeValidator;
this.fiatPriceValidator = fiatPriceValidator; this.amountValidator4Decimals = amountValidator4Decimals;
this.nonFiatPriceValidator = nonFiatPriceValidator; this.amountValidator8Decimals = amountValidator8Decimals;
this.xmrValidator = btcValidator; this.xmrValidator = btcValidator;
this.securityDepositValidator = securityDepositValidator; this.securityDepositValidator = securityDepositValidator;
this.priceFeedService = priceFeedService; this.priceFeedService = priceFeedService;
@ -763,7 +763,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
InputValidator.ValidationResult result = PriceUtil.isTriggerPriceValid(triggerPriceAsString, InputValidator.ValidationResult result = PriceUtil.isTriggerPriceValid(triggerPriceAsString,
marketPrice, marketPrice,
dataModel.isSellOffer(), dataModel.isSellOffer(),
dataModel.isTraditionalCurrency() dataModel.getCurrencyCode()
); );
triggerPriceValidationResult.set(result); triggerPriceValidationResult.set(result);
updateButtonDisableState(); updateButtonDisableState();
@ -1175,16 +1175,20 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
return getVolumeValidator().validate(input); return getVolumeValidator().validate(input);
} }
// TODO: replace with PriceUtils and VolumeUtils?
private MonetaryValidator getPriceValidator() { private MonetaryValidator getPriceValidator() {
return CurrencyUtil.isFiatCurrency(getTradeCurrency().getCode()) ? fiatPriceValidator : nonFiatPriceValidator; return CurrencyUtil.isPricePrecise(getTradeCurrency().getCode()) ? amountValidator8Decimals : amountValidator4Decimals;
} }
private MonetaryValidator getVolumeValidator() { private MonetaryValidator getVolumeValidator() {
final String code = getTradeCurrency().getCode(); final String code = getTradeCurrency().getCode();
if (CurrencyUtil.isFiatCurrency(code)) { if (CurrencyUtil.isFiatCurrency(code)) {
return fiatVolumeValidator; return fiatVolumeValidator;
} else if (CurrencyUtil.isVolumeRoundedToNearestUnit(code)) {
return amountValidator4Decimals;
} else { } else {
return nonFiatPriceValidator; return amountValidator8Decimals;
} }
} }

View File

@ -27,8 +27,8 @@ import haveno.core.provider.price.PriceFeedService;
import haveno.core.user.Preferences; import haveno.core.user.Preferences;
import haveno.core.util.FormattingUtils; import haveno.core.util.FormattingUtils;
import haveno.core.util.coin.CoinFormatter; import haveno.core.util.coin.CoinFormatter;
import haveno.core.util.validation.NonFiatPriceValidator; import haveno.core.util.validation.AmountValidator8Decimals;
import haveno.core.util.validation.FiatPriceValidator; import haveno.core.util.validation.AmountValidator4Decimals;
import haveno.desktop.Navigation; import haveno.desktop.Navigation;
import haveno.desktop.common.model.ViewModel; import haveno.desktop.common.model.ViewModel;
import haveno.desktop.main.offer.MutableOfferViewModel; import haveno.desktop.main.offer.MutableOfferViewModel;
@ -40,8 +40,8 @@ class CreateOfferViewModel extends MutableOfferViewModel<CreateOfferDataModel> i
@Inject @Inject
public CreateOfferViewModel(CreateOfferDataModel dataModel, public CreateOfferViewModel(CreateOfferDataModel dataModel,
FiatVolumeValidator fiatVolumeValidator, FiatVolumeValidator fiatVolumeValidator,
FiatPriceValidator fiatPriceValidator, AmountValidator4Decimals priceValidator4Decimals,
NonFiatPriceValidator nonFiatPriceValidator, AmountValidator8Decimals priceValidator8Decimals,
XmrValidator btcValidator, XmrValidator btcValidator,
SecurityDepositValidator securityDepositValidator, SecurityDepositValidator securityDepositValidator,
PriceFeedService priceFeedService, PriceFeedService priceFeedService,
@ -52,8 +52,8 @@ class CreateOfferViewModel extends MutableOfferViewModel<CreateOfferDataModel> i
OfferUtil offerUtil) { OfferUtil offerUtil) {
super(dataModel, super(dataModel,
fiatVolumeValidator, fiatVolumeValidator,
fiatPriceValidator, priceValidator4Decimals,
nonFiatPriceValidator, priceValidator8Decimals,
btcValidator, btcValidator,
securityDepositValidator, securityDepositValidator,
priceFeedService, priceFeedService,

View File

@ -427,7 +427,7 @@ abstract class OfferBookViewModel extends ActivatableViewModel {
} }
int getNumberOfDecimalsForVolume(OfferBookListItem item) { 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) { String getPaymentMethod(OfferBookListItem item) {

View File

@ -311,9 +311,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) { if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
// We only apply the rounding if the amount is variable (minAmount is lower as amount). // We only apply the rounding if the amount is variable (minAmount is lower as amount).
// Otherwise we could get an amount lower then the minAmount set by rounding // Otherwise we could get an amount lower then the minAmount set by rounding
BigInteger roundedAmount = dataModel.getOffer().isFiatOffer() ? BigInteger roundedAmount = CoinUtil.getRoundedAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
CoinUtil.getRoundedFiatAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit) :
CoinUtil.getRoundedTraditionalAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit);
dataModel.applyAmount(roundedAmount); dataModel.applyAmount(roundedAmount);
} }
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get())); amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
@ -582,9 +580,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
&& !isAmountEqualMinAmount(amount) && !isAmountEqualMaxAmount(amount)) { && !isAmountEqualMinAmount(amount) && !isAmountEqualMaxAmount(amount)) {
// We only apply the rounding if the amount is variable (minAmount is lower as amount). // We only apply the rounding if the amount is variable (minAmount is lower as amount).
// Otherwise we could get an amount lower then the minAmount set by rounding // Otherwise we could get an amount lower then the minAmount set by rounding
amount = dataModel.getOffer().isFiatOffer() ? amount = CoinUtil.getRoundedAmount(dataModel.getAmount().get(), price, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
CoinUtil.getRoundedFiatAmount(amount, price, maxTradeLimit) :
CoinUtil.getRoundedTraditionalAmount(amount, price, maxTradeLimit);
} }
} }
dataModel.applyAmount(amount); dataModel.applyAmount(amount);

View File

@ -29,8 +29,8 @@ import haveno.core.provider.price.PriceFeedService;
import haveno.core.user.Preferences; import haveno.core.user.Preferences;
import haveno.core.util.FormattingUtils; import haveno.core.util.FormattingUtils;
import haveno.core.util.coin.CoinFormatter; import haveno.core.util.coin.CoinFormatter;
import haveno.core.util.validation.NonFiatPriceValidator; import haveno.core.util.validation.AmountValidator8Decimals;
import haveno.core.util.validation.FiatPriceValidator; import haveno.core.util.validation.AmountValidator4Decimals;
import haveno.desktop.Navigation; import haveno.desktop.Navigation;
import haveno.desktop.main.offer.MutableOfferViewModel; import haveno.desktop.main.offer.MutableOfferViewModel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -43,8 +43,8 @@ class DuplicateOfferViewModel extends MutableOfferViewModel<DuplicateOfferDataMo
@Inject @Inject
public DuplicateOfferViewModel(DuplicateOfferDataModel dataModel, public DuplicateOfferViewModel(DuplicateOfferDataModel dataModel,
FiatVolumeValidator fiatVolumeValidator, FiatVolumeValidator fiatVolumeValidator,
FiatPriceValidator fiatPriceValidator, AmountValidator4Decimals priceValidator4Decimals,
NonFiatPriceValidator nonFiatPriceValidator, AmountValidator8Decimals priceValidator8Decimals,
XmrValidator btcValidator, XmrValidator btcValidator,
SecurityDepositValidator securityDepositValidator, SecurityDepositValidator securityDepositValidator,
PriceFeedService priceFeedService, PriceFeedService priceFeedService,
@ -55,8 +55,8 @@ class DuplicateOfferViewModel extends MutableOfferViewModel<DuplicateOfferDataMo
OfferUtil offerUtil) { OfferUtil offerUtil) {
super(dataModel, super(dataModel,
fiatVolumeValidator, fiatVolumeValidator,
fiatPriceValidator, priceValidator4Decimals,
nonFiatPriceValidator, priceValidator8Decimals,
btcValidator, btcValidator,
securityDepositValidator, securityDepositValidator,
priceFeedService, priceFeedService,

View File

@ -31,8 +31,8 @@ import haveno.core.user.Preferences;
import haveno.core.util.FormattingUtils; import haveno.core.util.FormattingUtils;
import haveno.core.util.PriceUtil; import haveno.core.util.PriceUtil;
import haveno.core.util.coin.CoinFormatter; import haveno.core.util.coin.CoinFormatter;
import haveno.core.util.validation.NonFiatPriceValidator; import haveno.core.util.validation.AmountValidator8Decimals;
import haveno.core.util.validation.FiatPriceValidator; import haveno.core.util.validation.AmountValidator4Decimals;
import haveno.desktop.Navigation; import haveno.desktop.Navigation;
import haveno.desktop.main.offer.MutableOfferViewModel; import haveno.desktop.main.offer.MutableOfferViewModel;
@ -43,8 +43,8 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
@Inject @Inject
public EditOfferViewModel(EditOfferDataModel dataModel, public EditOfferViewModel(EditOfferDataModel dataModel,
FiatVolumeValidator fiatVolumeValidator, FiatVolumeValidator fiatVolumeValidator,
FiatPriceValidator fiatPriceValidator, AmountValidator4Decimals priceValidator4Decimals,
NonFiatPriceValidator nonFiatPriceValidator, AmountValidator8Decimals priceValidator8Decimals,
XmrValidator btcValidator, XmrValidator btcValidator,
SecurityDepositValidator securityDepositValidator, SecurityDepositValidator securityDepositValidator,
PriceFeedService priceFeedService, PriceFeedService priceFeedService,
@ -55,8 +55,8 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
OfferUtil offerUtil) { OfferUtil offerUtil) {
super(dataModel, super(dataModel,
fiatVolumeValidator, fiatVolumeValidator,
fiatPriceValidator, priceValidator4Decimals,
nonFiatPriceValidator, priceValidator8Decimals,
btcValidator, btcValidator,
securityDepositValidator, securityDepositValidator,
priceFeedService, priceFeedService,

View File

@ -126,9 +126,9 @@ public class GUIUtil {
public final static String OPEN_WEB_PAGE_KEY = "warnOpenURLWhenTorEnabled"; public final static String OPEN_WEB_PAGE_KEY = "warnOpenURLWhenTorEnabled";
public final static int FIAT_DECIMALS_WITH_ZEROS = 0; public final static int NUM_DECIMALS_UNIT = 0;
public final static int FIAT_PRICE_DECIMALS_WITH_ZEROS = 3; public final static int NUM_DECIMALS_PRICE_LESS_PRECISE = 3;
public final static int CRYPTOS_DECIMALS_WITH_ZEROS = 7; public final static int NUM_DECIMALS_PRECISE = 7;
public final static int AMOUNT_DECIMALS_WITH_ZEROS = 3; public final static int AMOUNT_DECIMALS_WITH_ZEROS = 3;
public final static int AMOUNT_DECIMALS = 4; public final static int AMOUNT_DECIMALS = 4;

View File

@ -39,7 +39,7 @@ public class MarketsPrintTool {
final Collection<TraditionalCurrency> allSortedTraditionalCurrencies = CurrencyUtil.getAllSortedTraditionalCurrencies(); final Collection<TraditionalCurrency> allSortedTraditionalCurrencies = CurrencyUtil.getAllSortedTraditionalCurrencies();
final Stream<MarketCurrency> traditionalStream = allSortedTraditionalCurrencies.stream() 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())) .map(e -> new MarketCurrency("xmr_" + e.getCode().toLowerCase(), e.getName(), e.getCode()))
.distinct(); .distinct();

View File

@ -37,8 +37,8 @@ import haveno.core.user.Preferences;
import haveno.core.user.User; import haveno.core.user.User;
import haveno.core.util.coin.CoinFormatter; import haveno.core.util.coin.CoinFormatter;
import haveno.core.util.coin.ImmutableCoinFormatter; import haveno.core.util.coin.ImmutableCoinFormatter;
import haveno.core.util.validation.NonFiatPriceValidator; import haveno.core.util.validation.AmountValidator8Decimals;
import haveno.core.util.validation.FiatPriceValidator; import haveno.core.util.validation.AmountValidator4Decimals;
import haveno.core.util.validation.InputValidator; import haveno.core.util.validation.InputValidator;
import haveno.core.xmr.model.XmrAddressEntry; import haveno.core.xmr.model.XmrAddressEntry;
import haveno.core.xmr.wallet.XmrWalletService; import haveno.core.xmr.wallet.XmrWalletService;
@ -72,8 +72,8 @@ public class CreateOfferViewModelTest {
Res.setup(); Res.setup();
final XmrValidator btcValidator = new XmrValidator(); final XmrValidator btcValidator = new XmrValidator();
final NonFiatPriceValidator nonFiatPriceValidator = new NonFiatPriceValidator(); final AmountValidator8Decimals priceValidator8Decimals = new AmountValidator8Decimals();
final FiatPriceValidator fiatPriceValidator = new FiatPriceValidator(); final AmountValidator4Decimals priceValidator4Decimals = new AmountValidator4Decimals();
XmrAddressEntry addressEntry = mock(XmrAddressEntry.class); XmrAddressEntry addressEntry = mock(XmrAddressEntry.class);
XmrWalletService xmrWalletService = mock(XmrWalletService.class); XmrWalletService xmrWalletService = mock(XmrWalletService.class);
@ -121,8 +121,8 @@ public class CreateOfferViewModelTest {
model = new CreateOfferViewModel(dataModel, model = new CreateOfferViewModel(dataModel,
null, null,
fiatPriceValidator, priceValidator4Decimals,
nonFiatPriceValidator, priceValidator8Decimals,
btcValidator, btcValidator,
securityDepositValidator, securityDepositValidator,
priceFeedService, priceFeedService,

View File

@ -1786,7 +1786,6 @@ message CryptoCurrency {
} }
message TraditionalCurrency { message TraditionalCurrency {
Currency currency = 1;
} }
message Country { message Country {