diff --git a/core/src/main/java/bisq/core/offer/CreateOfferService.java b/core/src/main/java/bisq/core/offer/CreateOfferService.java
new file mode 100644
index 00000000000..35475e4d77e
--- /dev/null
+++ b/core/src/main/java/bisq/core/offer/CreateOfferService.java
@@ -0,0 +1,350 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.offer;
+
+import bisq.core.account.witness.AccountAgeWitnessService;
+import bisq.core.btc.TxFeeEstimationService;
+import bisq.core.btc.wallet.BsqWalletService;
+import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.wallet.Restrictions;
+import bisq.core.filter.FilterManager;
+import bisq.core.locale.CurrencyUtil;
+import bisq.core.locale.Res;
+import bisq.core.monetary.Price;
+import bisq.core.payment.HalCashAccount;
+import bisq.core.payment.PaymentAccount;
+import bisq.core.payment.PaymentAccountUtil;
+import bisq.core.provider.price.MarketPrice;
+import bisq.core.provider.price.PriceFeedService;
+import bisq.core.trade.statistics.ReferralIdService;
+import bisq.core.user.Preferences;
+import bisq.core.user.User;
+import bisq.core.util.CoinUtil;
+
+import bisq.network.p2p.NodeAddress;
+import bisq.network.p2p.P2PService;
+
+import bisq.common.app.Version;
+import bisq.common.crypto.PubKeyRing;
+import bisq.common.util.Tuple2;
+import bisq.common.util.Utilities;
+
+import org.bitcoinj.core.Coin;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Singleton
+public class CreateOfferService {
+ private final TxFeeEstimationService txFeeEstimationService;
+ private final MakerFeeProvider makerFeeProvider;
+ private final BsqWalletService bsqWalletService;
+ private final Preferences preferences;
+ private final PriceFeedService priceFeedService;
+ private final AccountAgeWitnessService accountAgeWitnessService;
+ private final ReferralIdService referralIdService;
+ private final FilterManager filterManager;
+ private final P2PService p2PService;
+ private final PubKeyRing pubKeyRing;
+ private final User user;
+ private final BtcWalletService btcWalletService;
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor, Initialization
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Inject
+ public CreateOfferService(TxFeeEstimationService txFeeEstimationService,
+ MakerFeeProvider makerFeeProvider,
+ BsqWalletService bsqWalletService,
+ Preferences preferences,
+ PriceFeedService priceFeedService,
+ AccountAgeWitnessService accountAgeWitnessService,
+ ReferralIdService referralIdService,
+ FilterManager filterManager,
+ P2PService p2PService,
+ PubKeyRing pubKeyRing,
+ User user,
+ BtcWalletService btcWalletService) {
+ this.txFeeEstimationService = txFeeEstimationService;
+ this.makerFeeProvider = makerFeeProvider;
+ this.bsqWalletService = bsqWalletService;
+ this.preferences = preferences;
+ this.priceFeedService = priceFeedService;
+ this.accountAgeWitnessService = accountAgeWitnessService;
+ this.referralIdService = referralIdService;
+ this.filterManager = filterManager;
+ this.p2PService = p2PService;
+ this.pubKeyRing = pubKeyRing;
+ this.user = user;
+ this.btcWalletService = btcWalletService;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // API
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public String getRandomOfferId() {
+ return Utilities.getRandomPrefix(5, 8) + "-" +
+ UUID.randomUUID().toString() + "-" +
+ Version.VERSION.replace(".", "");
+ }
+
+ public Offer createAndGetOffer(String offerId,
+ OfferPayload.Direction direction,
+ String currencyCode,
+ Coin amount,
+ Coin minAmount,
+ Price price,
+ boolean useMarketBasedPrice,
+ double marketPriceMargin,
+ double buyerSecurityDepositAsDouble,
+ PaymentAccount paymentAccount) {
+
+ log.info("offerId={}, \n" +
+ "currencyCode={}, \n" +
+ "direction={}, \n" +
+ "price={}, \n" +
+ "useMarketBasedPrice={}, \n" +
+ "marketPriceMargin={}, \n" +
+ "amount={}, \n" +
+ "minAmount={}, \n" +
+ "buyerSecurityDeposit={}, \n" +
+ "paymentAccount={}, \n",
+ offerId, currencyCode, direction, price.getValue(), useMarketBasedPrice, marketPriceMargin,
+ amount.value, minAmount.value, buyerSecurityDepositAsDouble, paymentAccount);
+
+ // prints our param list for dev testing api
+ log.info("{} " +
+ "{} " +
+ "{} " +
+ "{} " +
+ "{} " +
+ "{} " +
+ "{} " +
+ "{} " +
+ "{} " +
+ "{}",
+ offerId, currencyCode, direction.name(), price.getValue(), useMarketBasedPrice, marketPriceMargin,
+ amount.value, minAmount.value, buyerSecurityDepositAsDouble, paymentAccount.getId());
+
+ long creationTime = new Date().getTime();
+ NodeAddress makerAddress = p2PService.getAddress();
+ boolean useMarketBasedPriceValue = useMarketBasedPrice &&
+ isMarketPriceAvailable(currencyCode) &&
+ !isHalCashAccount(paymentAccount);
+
+ long priceAsLong = price != null && !useMarketBasedPriceValue ? price.getValue() : 0L;
+ double marketPriceMarginParam = useMarketBasedPriceValue ? marketPriceMargin : 0;
+ long amountAsLong = amount != null ? amount.getValue() : 0L;
+ long minAmountAsLong = minAmount != null ? minAmount.getValue() : 0L;
+ boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
+ String baseCurrencyCode = isCryptoCurrency ? currencyCode : Res.getBaseCurrencyCode();
+ String counterCurrencyCode = isCryptoCurrency ? Res.getBaseCurrencyCode() : currencyCode;
+ List acceptedArbitratorAddresses = user.getAcceptedArbitratorAddresses();
+ ArrayList arbitratorNodeAddresses = acceptedArbitratorAddresses != null ?
+ Lists.newArrayList(acceptedArbitratorAddresses) :
+ new ArrayList<>();
+ List acceptedMediatorAddresses = user.getAcceptedMediatorAddresses();
+ ArrayList mediatorNodeAddresses = acceptedMediatorAddresses != null ?
+ Lists.newArrayList(acceptedMediatorAddresses) :
+ new ArrayList<>();
+ String countryCode = PaymentAccountUtil.getCountryCode(paymentAccount);
+ List acceptedCountryCodes = PaymentAccountUtil.getAcceptedCountryCodes(paymentAccount);
+ String bankId = PaymentAccountUtil.getBankId(paymentAccount);
+ List acceptedBanks = PaymentAccountUtil.getAcceptedBanks(paymentAccount);
+ double sellerSecurityDeposit = getSellerSecurityDepositAsDouble();
+ Coin txFeeFromFeeService = getEstimatedFeeAndTxSize(amount, direction, buyerSecurityDepositAsDouble, sellerSecurityDeposit).first;
+ Coin makerFeeAsCoin = getMakerFee(amount);
+ boolean isCurrencyForMakerFeeBtc = OfferUtil.isCurrencyForMakerFeeBtc(preferences, bsqWalletService, amount);
+ Coin buyerSecurityDepositAsCoin = getBuyerSecurityDeposit(amount, buyerSecurityDepositAsDouble);
+ Coin sellerSecurityDepositAsCoin = getSellerSecurityDeposit(amount, sellerSecurityDeposit);
+ long maxTradeLimit = getMaxTradeLimit(paymentAccount, currencyCode, direction);
+ long maxTradePeriod = paymentAccount.getMaxTradePeriod();
+
+ // reserved for future use cases
+ // Use null values if not set
+ boolean isPrivateOffer = false;
+ boolean useAutoClose = false;
+ boolean useReOpenAfterAutoClose = false;
+ long lowerClosePrice = 0;
+ long upperClosePrice = 0;
+ String hashOfChallenge = null;
+ Map extraDataMap = OfferUtil.getExtraDataMap(accountAgeWitnessService,
+ referralIdService,
+ paymentAccount,
+ currencyCode,
+ preferences);
+
+ OfferUtil.validateOfferData(filterManager,
+ p2PService,
+ buyerSecurityDepositAsDouble,
+ paymentAccount,
+ currencyCode,
+ makerFeeAsCoin);
+
+ OfferPayload offerPayload = new OfferPayload(offerId,
+ creationTime,
+ makerAddress,
+ pubKeyRing,
+ OfferPayload.Direction.valueOf(direction.name()),
+ priceAsLong,
+ marketPriceMarginParam,
+ useMarketBasedPriceValue,
+ amountAsLong,
+ minAmountAsLong,
+ baseCurrencyCode,
+ counterCurrencyCode,
+ arbitratorNodeAddresses,
+ mediatorNodeAddresses,
+ paymentAccount.getPaymentMethod().getId(),
+ paymentAccount.getId(),
+ null,
+ countryCode,
+ acceptedCountryCodes,
+ bankId,
+ acceptedBanks,
+ Version.VERSION,
+ btcWalletService.getLastBlockSeenHeight(),
+ txFeeFromFeeService.value,
+ makerFeeAsCoin.value,
+ isCurrencyForMakerFeeBtc,
+ buyerSecurityDepositAsCoin.value,
+ sellerSecurityDepositAsCoin.value,
+ maxTradeLimit,
+ maxTradePeriod,
+ useAutoClose,
+ useReOpenAfterAutoClose,
+ upperClosePrice,
+ lowerClosePrice,
+ isPrivateOffer,
+ hashOfChallenge,
+ extraDataMap,
+ Version.TRADE_PROTOCOL_VERSION);
+ Offer offer = new Offer(offerPayload);
+ offer.setPriceFeedService(priceFeedService);
+ return offer;
+ }
+
+ public Tuple2 getEstimatedFeeAndTxSize(Coin amount,
+ OfferPayload.Direction direction,
+ double buyerSecurityDeposit,
+ double sellerSecurityDeposit) {
+ Coin reservedFundsForOffer = getReservedFundsForOffer(direction, amount, buyerSecurityDeposit, sellerSecurityDeposit);
+ return txFeeEstimationService.getEstimatedFeeAndTxSizeForMaker(reservedFundsForOffer, getMakerFee(amount));
+ }
+
+ public Coin getReservedFundsForOffer(OfferPayload.Direction direction,
+ Coin amount,
+ double buyerSecurityDeposit,
+ double sellerSecurityDeposit) {
+
+ Coin reservedFundsForOffer = getSecurityDeposit(direction,
+ amount,
+ buyerSecurityDeposit,
+ sellerSecurityDeposit);
+ if (!isBuyOffer(direction))
+ reservedFundsForOffer = reservedFundsForOffer.add(amount);
+
+ return reservedFundsForOffer;
+ }
+
+ public Coin getSecurityDeposit(OfferPayload.Direction direction,
+ Coin amount,
+ double buyerSecurityDeposit,
+ double sellerSecurityDeposit) {
+ return isBuyOffer(direction) ?
+ getBuyerSecurityDeposit(amount, buyerSecurityDeposit) :
+ getSellerSecurityDeposit(amount, sellerSecurityDeposit);
+ }
+
+ public double getSellerSecurityDepositAsDouble() {
+ return Restrictions.getSellerSecurityDepositAsPercent();
+ }
+
+ public Coin getMakerFee(Coin amount) {
+ return makerFeeProvider.getMakerFee(bsqWalletService, preferences, amount);
+ }
+
+ public long getMaxTradeLimit(PaymentAccount paymentAccount,
+ String currencyCode,
+ OfferPayload.Direction direction) {
+ if (paymentAccount != null) {
+ return accountAgeWitnessService.getMyTradeLimit(paymentAccount, currencyCode, direction);
+ } else {
+ return 0;
+ }
+ }
+
+ public boolean isBuyOffer(OfferPayload.Direction direction) {
+ return OfferUtil.isBuyOffer(direction);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Private
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ private boolean isMarketPriceAvailable(String currencyCode) {
+ MarketPrice marketPrice = priceFeedService.getMarketPrice(currencyCode);
+ return marketPrice != null && marketPrice.isExternallyProvidedPrice();
+ }
+
+ private boolean isHalCashAccount(PaymentAccount paymentAccount) {
+ return paymentAccount instanceof HalCashAccount;
+ }
+
+ private Coin getBuyerSecurityDeposit(Coin amount, double buyerSecurityDeposit) {
+ Coin percentOfAmountAsCoin = CoinUtil.getPercentOfAmountAsCoin(buyerSecurityDeposit, amount);
+ return getBoundedBuyerSecurityDeposit(percentOfAmountAsCoin);
+ }
+
+ private Coin getSellerSecurityDeposit(Coin amount, double sellerSecurityDeposit) {
+ Coin amountAsCoin = amount;
+ if (amountAsCoin == null)
+ amountAsCoin = Coin.ZERO;
+
+ Coin percentOfAmountAsCoin = CoinUtil.getPercentOfAmountAsCoin(sellerSecurityDeposit, amountAsCoin);
+ return getBoundedSellerSecurityDeposit(percentOfAmountAsCoin);
+ }
+
+ private Coin getBoundedBuyerSecurityDeposit(Coin value) {
+ // We need to ensure that for small amount values we don't get a too low BTC amount. We limit it with using the
+ // MinBuyerSecurityDepositAsCoin from Restrictions.
+ return Coin.valueOf(Math.max(Restrictions.getMinBuyerSecurityDepositAsCoin().value, value.value));
+ }
+
+ private Coin getBoundedSellerSecurityDeposit(Coin value) {
+ // We need to ensure that for small amount values we don't get a too low BTC amount. We limit it with using the
+ // MinSellerSecurityDepositAsCoin from Restrictions.
+ return Coin.valueOf(Math.max(Restrictions.getMinSellerSecurityDepositAsCoin().value, value.value));
+ }
+}
diff --git a/core/src/main/java/bisq/core/offer/MakerFeeProvider.java b/core/src/main/java/bisq/core/offer/MakerFeeProvider.java
new file mode 100644
index 00000000000..dc2d0fbd7f2
--- /dev/null
+++ b/core/src/main/java/bisq/core/offer/MakerFeeProvider.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.offer;
+
+import bisq.core.btc.wallet.BsqWalletService;
+import bisq.core.user.Preferences;
+
+import org.bitcoinj.core.Coin;
+
+public class MakerFeeProvider {
+ public Coin getMakerFee(BsqWalletService bsqWalletService, Preferences preferences, Coin amount) {
+ return OfferUtil.getMakerFee(bsqWalletService, preferences, amount);
+ }
+}
diff --git a/core/src/main/java/bisq/core/offer/OpenOfferManager.java b/core/src/main/java/bisq/core/offer/OpenOfferManager.java
index 1212a7313e2..bc0c3c8fb0e 100644
--- a/core/src/main/java/bisq/core/offer/OpenOfferManager.java
+++ b/core/src/main/java/bisq/core/offer/OpenOfferManager.java
@@ -94,6 +94,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
private static final long REPUBLISH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(40);
private static final long REFRESH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(6);
+ private final CreateOfferService createOfferService;
private final KeyRing keyRing;
private final User user;
private final P2PService p2PService;
@@ -121,7 +122,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
- public OpenOfferManager(KeyRing keyRing,
+ public OpenOfferManager(CreateOfferService createOfferService,
+ KeyRing keyRing,
User user,
P2PService p2PService,
BtcWalletService btcWalletService,
@@ -137,6 +139,7 @@ public OpenOfferManager(KeyRing keyRing,
RefundAgentManager refundAgentManager,
DaoFacade daoFacade,
Storage> storage) {
+ this.createOfferService = createOfferService;
this.keyRing = keyRing;
this.user = user;
this.p2PService = p2PService;
@@ -335,10 +338,17 @@ public void onAwakeFromStandby() {
///////////////////////////////////////////////////////////////////////////////////////////
public void placeOffer(Offer offer,
- Coin reservedFundsForOffer,
+ double buyerSecurityDeposit,
boolean useSavingsWallet,
TransactionResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler) {
+ checkNotNull(offer.getMakerFee(), "makerFee must not be null");
+
+ Coin reservedFundsForOffer = createOfferService.getReservedFundsForOffer(offer.getDirection(),
+ offer.getAmount(),
+ buyerSecurityDeposit,
+ createOfferService.getSellerSecurityDepositAsDouble());
+
PlaceOfferModel model = new PlaceOfferModel(offer,
reservedFundsForOffer,
useSavingsWallet,
diff --git a/core/src/main/java/bisq/core/trade/statistics/TradeStatistics2.java b/core/src/main/java/bisq/core/trade/statistics/TradeStatistics2.java
index feb0b6ed14d..601284f4e74 100644
--- a/core/src/main/java/bisq/core/trade/statistics/TradeStatistics2.java
+++ b/core/src/main/java/bisq/core/trade/statistics/TradeStatistics2.java
@@ -171,8 +171,7 @@ public byte[] createHash() {
return Hash.getSha256Ripemd160hash(Utilities.objectToJson(this).getBytes(Charsets.UTF_8));
}
- @Override
- public protobuf.PersistableNetworkPayload toProtoMessage() {
+ private protobuf.TradeStatistics2.Builder getBuilder() {
final protobuf.TradeStatistics2.Builder builder = protobuf.TradeStatistics2.newBuilder()
.setDirection(OfferPayload.Direction.toProtoMessage(direction))
.setBaseCurrency(baseCurrency)
@@ -190,12 +189,16 @@ public protobuf.PersistableNetworkPayload toProtoMessage() {
.setDepositTxId(depositTxId)
.setHash(ByteString.copyFrom(hash));
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData);
- return protobuf.PersistableNetworkPayload.newBuilder().setTradeStatistics2(builder).build();
+ return builder;
}
-
public protobuf.TradeStatistics2 toProtoTradeStatistics2() {
- return toProtoMessage().getTradeStatistics2();
+ return getBuilder().build();
+ }
+
+ @Override
+ public protobuf.PersistableNetworkPayload toProtoMessage() {
+ return protobuf.PersistableNetworkPayload.newBuilder().setTradeStatistics2(getBuilder()).build();
}
public static TradeStatistics2 fromProto(protobuf.TradeStatistics2 proto) {
diff --git a/core/src/main/resources/btc_regtest.seednodes b/core/src/main/resources/btc_regtest.seednodes
index caa87710d68..148e6ecb9e0 100644
--- a/core/src/main/resources/btc_regtest.seednodes
+++ b/core/src/main/resources/btc_regtest.seednodes
@@ -1,4 +1,4 @@
-# By default developers use either port 2002 or 3002 or both as local seed nodes. If they want to use regtest
+# By default developers use either port 2002 or 3002 or both as local seed nodes. If they want to use regtest
# with Tor they have to add a program argument to pass the custom onion address of the local Tor seed node.
# E.g. --seedNodes=YOUR_ONION.onion:2002
@@ -6,7 +6,7 @@
# 1. Run a seed node with prog args: --bitcoinNetwork=regtest --nodePort=2002 --appName=bisq_seed_node_localhost_YOUR_ONION
# 2. Find your local onion address in bisq_seed_node_localhost_YOUR_ONION/regtest/tor/hiddenservice/hostname
# 3. Shut down the seed node
-# 4. Rename YOUR_ONION at the directory with your local onion address as well as the appName program argument to reflect
+# 4. Rename YOUR_ONION at the directory with your local onion address as well as the appName program argument to reflect
# the real onion address.
# 5. Start the seed node again
# 6. Start the Bisq app which wants to connect to that seed node with program argument `--seedNodes=YOUR_ONION.onion:2002`
diff --git a/core/src/test/java/bisq/core/offer/OpenOfferManagerTest.java b/core/src/test/java/bisq/core/offer/OpenOfferManagerTest.java
index c80ea13e0e1..db2f334ded6 100644
--- a/core/src/test/java/bisq/core/offer/OpenOfferManagerTest.java
+++ b/core/src/test/java/bisq/core/offer/OpenOfferManagerTest.java
@@ -37,7 +37,7 @@ public void testStartEditOfferForActiveOffer() {
when(p2PService.getPeerManager()).thenReturn(mock(PeerManager.class));
- final OpenOfferManager manager = new OpenOfferManager(null, null, p2PService,
+ final OpenOfferManager manager = new OpenOfferManager(null, null, null, p2PService,
null, null, null, offerBookService,
null, null, null,
null, null, null, null, null,
@@ -73,7 +73,7 @@ public void testStartEditOfferForDeactivatedOffer() {
when(p2PService.getPeerManager()).thenReturn(mock(PeerManager.class));
- final OpenOfferManager manager = new OpenOfferManager(null, null, p2PService,
+ final OpenOfferManager manager = new OpenOfferManager(null, null, null, p2PService,
null, null, null, offerBookService,
null, null, null,
null, null, null, null, null,
@@ -101,7 +101,7 @@ public void testStartEditOfferForOfferThatIsCurrentlyEdited() {
when(p2PService.getPeerManager()).thenReturn(mock(PeerManager.class));
- final OpenOfferManager manager = new OpenOfferManager(null, null, p2PService,
+ final OpenOfferManager manager = new OpenOfferManager(null, null, null, p2PService,
null, null, null, offerBookService,
null, null, null,
null, null, null, null, null,
diff --git a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java
index 97ff63c8f1c..f28fc1f38fd 100644
--- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java
@@ -29,23 +29,20 @@
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.btc.wallet.Restrictions;
-import bisq.core.filter.FilterManager;
import bisq.core.locale.CurrencyUtil;
-import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.monetary.Price;
import bisq.core.monetary.Volume;
+import bisq.core.offer.CreateOfferService;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
-import bisq.core.payment.PaymentAccountUtil;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.handlers.TransactionResultHandler;
-import bisq.core.trade.statistics.ReferralIdService;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.BSFormatter;
@@ -53,8 +50,6 @@
import bisq.network.p2p.P2PService;
-import bisq.common.app.Version;
-import bisq.common.crypto.KeyRing;
import bisq.common.util.MathUtils;
import bisq.common.util.Tuple2;
import bisq.common.util.Utilities;
@@ -64,8 +59,6 @@
import com.google.inject.Inject;
-import com.google.common.collect.Lists;
-
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
@@ -83,33 +76,26 @@
import javafx.collections.ObservableList;
import javafx.collections.SetChangeListener;
-import java.util.Date;
import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
import java.util.Optional;
-import java.util.UUID;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public abstract class MutableOfferDataModel extends OfferDataModel implements BsqBalanceListener {
+ private final CreateOfferService createOfferService;
protected final OpenOfferManager openOfferManager;
private final BsqWalletService bsqWalletService;
private final Preferences preferences;
protected final User user;
- private final KeyRing keyRing;
private final P2PService p2PService;
protected final PriceFeedService priceFeedService;
final String shortOfferId;
- private final FilterManager filterManager;
private final AccountAgeWitnessService accountAgeWitnessService;
private final FeeService feeService;
- private final TxFeeEstimationService txFeeEstimationService;
- private final ReferralIdService referralIdService;
private final BSFormatter btcFormatter;
- private MakerFeeProvider makerFeeProvider;
+ private final MakerFeeProvider makerFeeProvider;
private final Navigation navigation;
private final String offerId;
private final BalanceListener btcBalanceListener;
@@ -119,10 +105,6 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
protected TradeCurrency tradeCurrency;
protected final StringProperty tradeCurrencyCode = new SimpleStringProperty();
protected final BooleanProperty useMarketBasedPrice = new SimpleBooleanProperty();
- //final BooleanProperty isMainNet = new SimpleBooleanProperty();
- //final BooleanProperty isFeeFromFundingTxSufficient = new SimpleBooleanProperty();
-
- // final ObjectProperty feeFromFundingTxProperty = new SimpleObjectProperty(Coin.NEGATIVE_SATOSHI);
protected final ObjectProperty amount = new SimpleObjectProperty<>();
protected final ObjectProperty minAmount = new SimpleObjectProperty<>();
protected final ObjectProperty price = new SimpleObjectProperty<>();
@@ -131,12 +113,11 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
// Percentage value of buyer security deposit. E.g. 0.01 means 1% of trade amount
protected final DoubleProperty buyerSecurityDeposit = new SimpleDoubleProperty();
- protected final DoubleProperty sellerSecurityDeposit = new SimpleDoubleProperty();
protected final ObservableList paymentAccounts = FXCollections.observableArrayList();
protected PaymentAccount paymentAccount;
- protected boolean isTabSelected;
+ boolean isTabSelected;
protected double marketPriceMargin = 0;
private Coin txFeeFromFeeService = Coin.ZERO;
private boolean marketPriceAvailable;
@@ -149,76 +130,45 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
- public MutableOfferDataModel(OpenOfferManager openOfferManager,
+ public MutableOfferDataModel(CreateOfferService createOfferService,
+ OpenOfferManager openOfferManager,
BtcWalletService btcWalletService,
BsqWalletService bsqWalletService,
Preferences preferences,
User user,
- KeyRing keyRing,
P2PService p2PService,
PriceFeedService priceFeedService,
- FilterManager filterManager,
AccountAgeWitnessService accountAgeWitnessService,
FeeService feeService,
- TxFeeEstimationService txFeeEstimationService,
- ReferralIdService referralIdService,
BSFormatter btcFormatter,
MakerFeeProvider makerFeeProvider,
Navigation navigation) {
super(btcWalletService);
+ this.createOfferService = createOfferService;
this.openOfferManager = openOfferManager;
this.bsqWalletService = bsqWalletService;
this.preferences = preferences;
this.user = user;
- this.keyRing = keyRing;
this.p2PService = p2PService;
this.priceFeedService = priceFeedService;
- this.filterManager = filterManager;
this.accountAgeWitnessService = accountAgeWitnessService;
this.feeService = feeService;
- this.txFeeEstimationService = txFeeEstimationService;
- this.referralIdService = referralIdService;
this.btcFormatter = btcFormatter;
this.makerFeeProvider = makerFeeProvider;
this.navigation = navigation;
- offerId = Utilities.getRandomPrefix(5, 8) + "-" +
- UUID.randomUUID().toString() + "-" +
- Version.VERSION.replace(".", "");
+ offerId = createOfferService.getRandomOfferId();
shortOfferId = Utilities.getShortId(offerId);
addressEntry = btcWalletService.getOrCreateAddressEntry(offerId, AddressEntry.Context.OFFER_FUNDING);
useMarketBasedPrice.set(preferences.isUsePercentageBasedPrice());
buyerSecurityDeposit.set(preferences.getBuyerSecurityDepositAsPercent(null));
- sellerSecurityDeposit.set(Restrictions.getSellerSecurityDepositAsPercent());
btcBalanceListener = new BalanceListener(getAddressEntry().getAddress()) {
@Override
public void onBalanceChanged(Coin balance, Transaction tx) {
updateBalance();
-
- /* if (isMainNet.get()) {
- SettableFuture future = blockchainService.requestFee(tx.getHashAsString());
- Futures.addCallback(future, new FutureCallback() {
- public void onSuccess(Coin fee) {
- UserThread.execute(() -> feeFromFundingTxProperty.set(fee));
- }
-
- public void onFailure(@NotNull Throwable throwable) {
- UserThread.execute(() -> new Popup<>()
- .warning("We did not get a response for the request of the mining fee used " +
- "in the funding transaction.\n\n" +
- "Are you sure you used a sufficiently high fee of at least " +
- formatter.formatCoinWithCode(FeePolicy.getMinRequiredFeeForFundingTx()) + "?")
- .actionButtonText("Yes, I used a sufficiently high fee.")
- .onAction(() -> feeFromFundingTxProperty.set(FeePolicy.getMinRequiredFeeForFundingTx()))
- .closeButtonText("No. Let's cancel that payment.")
- .onClose(() -> feeFromFundingTxProperty.set(Coin.ZERO))
- .show());
- }
- });
- }*/
}
};
@@ -322,115 +272,32 @@ void onTabSelected(boolean isSelected) {
// UI actions
///////////////////////////////////////////////////////////////////////////////////////////
- @SuppressWarnings("ConstantConditions")
Offer createAndGetOffer() {
- boolean useMarketBasedPriceValue = isUseMarketBasedPriceValue();
- long priceAsLong = price.get() != null && !useMarketBasedPriceValue ? price.get().getValue() : 0L;
- String currencyCode = tradeCurrencyCode.get();
- boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
- String baseCurrencyCode = isCryptoCurrency ? currencyCode : Res.getBaseCurrencyCode();
- String counterCurrencyCode = isCryptoCurrency ? Res.getBaseCurrencyCode() : currencyCode;
-
- double marketPriceMarginParam = useMarketBasedPriceValue ? marketPriceMargin : 0;
- long amountAsLong = this.amount.get() != null ? this.amount.get().getValue() : 0L;
- long minAmountAsLong = this.minAmount.get() != null ? this.minAmount.get().getValue() : 0L;
-
- List acceptedCountryCodes = PaymentAccountUtil.getAcceptedCountryCodes(paymentAccount);
- List acceptedBanks = PaymentAccountUtil.getAcceptedBanks(paymentAccount);
- String bankId = PaymentAccountUtil.getBankId(paymentAccount);
- String countryCode = PaymentAccountUtil.getCountryCode(paymentAccount);
-
- long maxTradeLimit = getMaxTradeLimit();
- long maxTradePeriod = paymentAccount.getMaxTradePeriod();
-
- // reserved for future use cases
- // Use null values if not set
- boolean isPrivateOffer = false;
- boolean useAutoClose = false;
- boolean useReOpenAfterAutoClose = false;
- long lowerClosePrice = 0;
- long upperClosePrice = 0;
- String hashOfChallenge = null;
-
- Coin makerFeeAsCoin = getMakerFee();
-
- Map extraDataMap = OfferUtil.getExtraDataMap(accountAgeWitnessService,
- referralIdService,
- paymentAccount,
- currencyCode,
- preferences);
-
- OfferUtil.validateOfferData(filterManager,
- p2PService,
+ return createOfferService.createAndGetOffer(offerId,
+ direction,
+ tradeCurrencyCode.get(),
+ amount.get(),
+ minAmount.get(),
+ price.get(),
+ useMarketBasedPrice.get(),
+ marketPriceMargin,
buyerSecurityDeposit.get(),
- paymentAccount,
- currencyCode,
- makerFeeAsCoin);
-
- OfferPayload offerPayload = new OfferPayload(offerId,
- new Date().getTime(),
- p2PService.getAddress(),
- keyRing.getPubKeyRing(),
- OfferPayload.Direction.valueOf(direction.name()),
- priceAsLong,
- marketPriceMarginParam,
- useMarketBasedPriceValue,
- amountAsLong,
- minAmountAsLong,
- baseCurrencyCode,
- counterCurrencyCode,
- Lists.newArrayList(user.getAcceptedArbitratorAddresses()),
- Lists.newArrayList(user.getAcceptedMediatorAddresses()),
- paymentAccount.getPaymentMethod().getId(),
- paymentAccount.getId(),
- null,
- countryCode,
- acceptedCountryCodes,
- bankId,
- acceptedBanks,
- Version.VERSION,
- btcWalletService.getLastBlockSeenHeight(),
- txFeeFromFeeService.value,
- makerFeeAsCoin.value,
- isCurrencyForMakerFeeBtc(),
- getBuyerSecurityDepositAsCoin().value,
- getSellerSecurityDepositAsCoin().value,
- maxTradeLimit,
- maxTradePeriod,
- useAutoClose,
- useReOpenAfterAutoClose,
- upperClosePrice,
- lowerClosePrice,
- isPrivateOffer,
- hashOfChallenge,
- extraDataMap,
- Version.TRADE_PROTOCOL_VERSION);
- Offer offer = new Offer(offerPayload);
- offer.setPriceFeedService(priceFeedService);
- return offer;
+ paymentAccount);
}
// This works only if we have already funds in the wallet
- public void estimateTxSize() {
- Coin reservedFundsForOffer = getSecurityDeposit();
- if (!isBuyOffer())
- reservedFundsForOffer = reservedFundsForOffer.add(amount.get());
-
- Tuple2 estimatedFeeAndTxSize = txFeeEstimationService.getEstimatedFeeAndTxSizeForMaker(reservedFundsForOffer,
- getMakerFee());
+ public void updateEstimatedFeeAndTxSize() {
+ Tuple2 estimatedFeeAndTxSize = createOfferService.getEstimatedFeeAndTxSize(amount.get(),
+ direction,
+ buyerSecurityDeposit.get(),
+ createOfferService.getSellerSecurityDepositAsDouble());
txFeeFromFeeService = estimatedFeeAndTxSize.first;
feeTxSize = estimatedFeeAndTxSize.second;
}
void onPlaceOffer(Offer offer, TransactionResultHandler resultHandler) {
- checkNotNull(getMakerFee(), "makerFee must not be null");
-
- Coin reservedFundsForOffer = getSecurityDeposit();
- if (!isBuyOffer())
- reservedFundsForOffer = reservedFundsForOffer.add(amount.get());
-
openOfferManager.placeOffer(offer,
- reservedFundsForOffer,
+ buyerSecurityDeposit.get(),
useSavingsWallet,
resultHandler,
log::error);
@@ -539,7 +406,6 @@ void setPreferredCurrencyForMakerFeeBtc(boolean preferredCurrencyForMakerFeeBtc)
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
- @SuppressWarnings("BooleanMethodIsAlwaysInverted")
boolean isMinAmountLessOrEqualAmount() {
//noinspection SimplifiableIfStatement
if (minAmount.get() != null && amount.get() != null)
@@ -700,7 +566,7 @@ public Coin getTxFee() {
return txFeeFromFeeService.subtract(getMakerFee());
}
- public void swapTradeToSavings() {
+ void swapTradeToSavings() {
btcWalletService.resetAddressEntriesForOpenOffer(offerId);
}
@@ -775,12 +641,12 @@ protected Coin getBuyerSecurityDepositAsCoin() {
return getBoundedBuyerSecurityDepositAsCoin(percentOfAmountAsCoin);
}
- Coin getSellerSecurityDepositAsCoin() {
+ private Coin getSellerSecurityDepositAsCoin() {
Coin amountAsCoin = this.amount.get();
if (amountAsCoin == null)
amountAsCoin = Coin.ZERO;
- Coin percentOfAmountAsCoin = CoinUtil.getPercentOfAmountAsCoin(sellerSecurityDeposit.get(), amountAsCoin);
+ Coin percentOfAmountAsCoin = CoinUtil.getPercentOfAmountAsCoin(createOfferService.getSellerSecurityDepositAsDouble(), amountAsCoin);
return getBoundedSellerSecurityDepositAsCoin(percentOfAmountAsCoin);
}
@@ -800,7 +666,7 @@ ReadOnlyObjectProperty totalToPayAsCoinProperty() {
return totalToPayAsCoin;
}
- public Coin getBsqBalance() {
+ Coin getBsqBalance() {
return bsqWalletService.getAvailableConfirmedBalance();
}
@@ -828,11 +694,11 @@ public boolean isCurrencyForMakerFeeBtc() {
return OfferUtil.isCurrencyForMakerFeeBtc(preferences, bsqWalletService, amount.get());
}
- public boolean isPreferredFeeCurrencyBtc() {
+ boolean isPreferredFeeCurrencyBtc() {
return preferences.isPayFeeInBtc();
}
- public boolean isBsqForFeeAvailable() {
+ boolean isBsqForFeeAvailable() {
return OfferUtil.isBsqForMakerFeeAvailable(bsqWalletService, amount.get());
}
@@ -840,7 +706,7 @@ public boolean isHalCashAccount() {
return paymentAccount instanceof HalCashAccount;
}
- public boolean canPlaceOffer() {
+ boolean canPlaceOffer() {
return GUIUtil.isBootstrappedOrShowPopup(p2PService) &&
GUIUtil.canCreateOrTakeOfferOrShowPopup(user, navigation);
}
diff --git a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java
index f3a4373ccc4..22aa8aa6347 100644
--- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java
@@ -682,7 +682,7 @@ public void onCurrencySelected(TradeCurrency tradeCurrency) {
}
void onShowPayFundsScreen(Runnable actionHandler) {
- dataModel.estimateTxSize();
+ dataModel.updateEstimatedFeeAndTxSize();
dataModel.requestTxFee(actionHandler);
showPayFundsScreenDisplayed.set(true);
updateSpinnerInfo();
diff --git a/desktop/src/main/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModel.java
index 06c2cfb42ea..361ee6694cb 100644
--- a/desktop/src/main/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModel.java
@@ -26,22 +26,18 @@
import bisq.desktop.main.offer.MutableOfferDataModel;
import bisq.core.account.witness.AccountAgeWitnessService;
-import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
-import bisq.core.filter.FilterManager;
+import bisq.core.offer.CreateOfferService;
import bisq.core.offer.OpenOfferManager;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
-import bisq.core.trade.statistics.ReferralIdService;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.BSFormatter;
import bisq.network.p2p.P2PService;
-import bisq.common.crypto.KeyRing;
-
import com.google.inject.Inject;
/**
@@ -52,35 +48,29 @@
class CreateOfferDataModel extends MutableOfferDataModel {
@Inject
- public CreateOfferDataModel(OpenOfferManager openOfferManager,
+ public CreateOfferDataModel(CreateOfferService createOfferService,
+ OpenOfferManager openOfferManager,
BtcWalletService btcWalletService,
BsqWalletService bsqWalletService,
Preferences preferences,
User user,
- KeyRing keyRing,
P2PService p2PService,
PriceFeedService priceFeedService,
- FilterManager filterManager,
AccountAgeWitnessService accountAgeWitnessService,
FeeService feeService,
- TxFeeEstimationService txFeeEstimationService,
- ReferralIdService referralIdService,
BSFormatter btcFormatter,
MakerFeeProvider makerFeeProvider,
Navigation navigation) {
- super(openOfferManager,
+ super(createOfferService,
+ openOfferManager,
btcWalletService,
bsqWalletService,
preferences,
user,
- keyRing,
p2PService,
priceFeedService,
- filterManager,
accountAgeWitnessService,
feeService,
- txFeeEstimationService,
- referralIdService,
btcFormatter,
makerFeeProvider,
navigation);
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java
index f5de8a4763b..388dd13a9e6 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java
@@ -23,13 +23,12 @@
import bisq.desktop.main.offer.MutableOfferDataModel;
import bisq.core.account.witness.AccountAgeWitnessService;
-import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.btc.wallet.Restrictions;
-import bisq.core.filter.FilterManager;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.TradeCurrency;
+import bisq.core.offer.CreateOfferService;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
@@ -38,7 +37,6 @@
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
-import bisq.core.trade.statistics.ReferralIdService;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.BSFormatter;
@@ -46,7 +44,6 @@
import bisq.network.p2p.P2PService;
-import bisq.common.crypto.KeyRing;
import bisq.common.handlers.ErrorMessageHandler;
import bisq.common.handlers.ResultHandler;
@@ -61,36 +58,30 @@ class EditOfferDataModel extends MutableOfferDataModel {
private OpenOffer.State initialState;
@Inject
- EditOfferDataModel(OpenOfferManager openOfferManager,
+ EditOfferDataModel(CreateOfferService createOfferService,
+ OpenOfferManager openOfferManager,
BtcWalletService btcWalletService,
BsqWalletService bsqWalletService,
Preferences preferences,
User user,
- KeyRing keyRing,
P2PService p2PService,
PriceFeedService priceFeedService,
- FilterManager filterManager,
AccountAgeWitnessService accountAgeWitnessService,
FeeService feeService,
- TxFeeEstimationService txFeeEstimationService,
- ReferralIdService referralIdService,
BSFormatter btcFormatter,
CorePersistenceProtoResolver corePersistenceProtoResolver,
MakerFeeProvider makerFeeProvider,
Navigation navigation) {
- super(openOfferManager,
+ super(createOfferService,
+ openOfferManager,
btcWalletService,
bsqWalletService,
preferences,
user,
- keyRing,
p2PService,
priceFeedService,
- filterManager,
accountAgeWitnessService,
feeService,
- txFeeEstimationService,
- referralIdService,
btcFormatter,
makerFeeProvider,
navigation);
diff --git a/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModelTest.java b/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModelTest.java
index e588735a914..4d58655dcc9 100644
--- a/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModelTest.java
+++ b/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferDataModelTest.java
@@ -2,13 +2,13 @@
import bisq.desktop.main.offer.MakerFeeProvider;
-import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
+import bisq.core.offer.CreateOfferService;
import bisq.core.offer.OfferPayload;
import bisq.core.payment.ClearXchangeAccount;
import bisq.core.payment.PaymentAccount;
@@ -21,6 +21,7 @@
import org.bitcoinj.core.Coin;
import java.util.HashSet;
+import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
@@ -48,20 +49,20 @@ public void setUp() {
BtcWalletService btcWalletService = mock(BtcWalletService.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
FeeService feeService = mock(FeeService.class);
- TxFeeEstimationService feeEstimationService = mock(TxFeeEstimationService.class);
+ CreateOfferService createOfferService = mock(CreateOfferService.class);
preferences = mock(Preferences.class);
user = mock(User.class);
when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
when(preferences.isUsePercentageBasedPrice()).thenReturn(true);
when(preferences.getBuyerSecurityDepositAsPercent(null)).thenReturn(0.01);
+ when(createOfferService.getRandomOfferId()).thenReturn(UUID.randomUUID().toString());
makerFeeProvider = mock(MakerFeeProvider.class);
- model = new CreateOfferDataModel(null, btcWalletService,
+ model = new CreateOfferDataModel(createOfferService, null, btcWalletService,
null, preferences, user, null,
- null, priceFeedService, null,
- null, feeService, feeEstimationService,
- null, null, makerFeeProvider, null);
+ priceFeedService, null,
+ feeService, null, makerFeeProvider, null);
}
@Test
diff --git a/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferViewModelTest.java b/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferViewModelTest.java
index 515126304ca..149f39a892b 100644
--- a/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferViewModelTest.java
+++ b/desktop/src/test/java/bisq/desktop/main/offer/createoffer/CreateOfferViewModelTest.java
@@ -24,7 +24,6 @@
import bisq.desktop.util.validation.SecurityDepositValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
-import bisq.core.btc.TxFeeEstimationService;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
@@ -32,6 +31,7 @@
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
+import bisq.core.offer.CreateOfferService;
import bisq.core.offer.OfferPayload;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.fee.FeeService;
@@ -51,6 +51,8 @@
import java.time.Instant;
+import java.util.UUID;
+
import org.junit.Before;
import org.junit.Test;
@@ -89,7 +91,7 @@ public void setUp() {
BsqWalletService bsqWalletService = mock(BsqWalletService.class);
SecurityDepositValidator securityDepositValidator = mock(SecurityDepositValidator.class);
AccountAgeWitnessService accountAgeWitnessService = mock(AccountAgeWitnessService.class);
- TxFeeEstimationService txFeeEstimationService = mock(TxFeeEstimationService.class);
+ CreateOfferService createOfferService = mock(CreateOfferService.class);
when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
when(btcWalletService.getBalanceForAddress(any())).thenReturn(Coin.valueOf(1000L));
@@ -103,11 +105,12 @@ public void setUp() {
when(preferences.getUserCountry()).thenReturn(new Country("ES", "Spain", null));
when(bsqFormatter.formatCoin(any())).thenReturn("0");
when(bsqWalletService.getAvailableConfirmedBalance()).thenReturn(Coin.ZERO);
+ when(createOfferService.getRandomOfferId()).thenReturn(UUID.randomUUID().toString());
- CreateOfferDataModel dataModel = new CreateOfferDataModel(null, btcWalletService,
- bsqWalletService, empty, user, null, null, priceFeedService, null,
- accountAgeWitnessService, feeService, txFeeEstimationService,
- null, bsFormatter, mock(MakerFeeProvider.class), null);
+ CreateOfferDataModel dataModel = new CreateOfferDataModel(createOfferService, null, btcWalletService,
+ bsqWalletService, empty, user, null, priceFeedService,
+ accountAgeWitnessService, feeService,
+ bsFormatter, mock(MakerFeeProvider.class), null);
dataModel.initWithData(OfferPayload.Direction.BUY, new CryptoCurrency("BTC", "bitcoin"));
dataModel.activate();
diff --git a/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java b/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java
index d95ba36bc70..2ee6a5bfde4 100644
--- a/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java
+++ b/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java
@@ -11,6 +11,7 @@
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
+import bisq.core.offer.CreateOfferService;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
import bisq.core.payment.CryptoCurrencyAccount;
@@ -32,6 +33,8 @@
import java.time.Instant;
+import java.util.UUID;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -75,6 +78,7 @@ public void setUp() {
BsqWalletService bsqWalletService = mock(BsqWalletService.class);
SecurityDepositValidator securityDepositValidator = mock(SecurityDepositValidator.class);
AccountAgeWitnessService accountAgeWitnessService = mock(AccountAgeWitnessService.class);
+ CreateOfferService createOfferService = mock(CreateOfferService.class);
when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
when(btcWalletService.getBalanceForAddress(any())).thenReturn(Coin.valueOf(1000L));
@@ -88,12 +92,13 @@ public void setUp() {
when(preferences.getUserCountry()).thenReturn(new Country("US", "United States", null));
when(bsqFormatter.formatCoin(any())).thenReturn("0");
when(bsqWalletService.getAvailableConfirmedBalance()).thenReturn(Coin.ZERO);
+ when(createOfferService.getRandomOfferId()).thenReturn(UUID.randomUUID().toString());
- model = new EditOfferDataModel(null,
+ model = new EditOfferDataModel(createOfferService, null,
btcWalletService, bsqWalletService, empty, user,
- null, null, priceFeedService, null,
+ null, priceFeedService,
accountAgeWitnessService, feeService, null, null,
- null, null, mock(MakerFeeProvider.class), null);
+ mock(MakerFeeProvider.class), null);
}
@Test