diff --git a/core/src/main/java/bisq/core/account/creation/AccountCreationAgeService.java b/core/src/main/java/bisq/core/account/creation/AccountCreationAgeService.java new file mode 100644 index 00000000000..3b3c6c22a6a --- /dev/null +++ b/core/src/main/java/bisq/core/account/creation/AccountCreationAgeService.java @@ -0,0 +1,324 @@ +/* + * 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.account.creation; + +import bisq.core.account.score.AccountScoreCategory; +import bisq.core.account.witness.AccountAgeWitnessService; +import bisq.core.locale.CurrencyUtil; +import bisq.core.offer.Offer; +import bisq.core.offer.OfferPayload; +import bisq.core.payment.PaymentAccount; +import bisq.core.payment.payload.PaymentMethod; +import bisq.core.trade.Contract; +import bisq.core.trade.Trade; + +import javax.inject.Inject; + +import com.google.common.annotations.VisibleForTesting; + +import org.apache.commons.lang3.time.DateUtils; + +import java.util.Date; +import java.util.Optional; + +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Nullable; + +/** + * Responsible for delayed payout based on account age. It does not consider if the account was yet used for + * trading and is therefor not considered a strong protection. + */ +@Slf4j +public class AccountCreationAgeService { + private final static int MAX_REQUIRED_AGE = 42; + private final static int MAX_DELAY = 28; + private final AccountAgeWitnessService accountAgeWitnessService; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public AccountCreationAgeService(AccountAgeWitnessService accountAgeWitnessService) { + this.accountAgeWitnessService = accountAgeWitnessService; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Returns the delay for the payout in days based on a linear function which starts with a delay of 28 days at age 0 and + * ends with 0 days delay at account age 42 (6 weeks). + * @param buyersAccountAge Account age of buyer in ms + * @param requiredAccountAge Required account age in ms + * @return The delay for the delayed payout in days. + */ + @VisibleForTesting + public static long getDelayInDays(long buyersAccountAge, long requiredAccountAge) { + double maxDelay = (double) MAX_DELAY; + double requiredAccountAgeAsDays = ((double) requiredAccountAge) / DateUtils.MILLIS_PER_DAY; + double buyersAccountAgeAsDays = ((double) buyersAccountAge) / DateUtils.MILLIS_PER_DAY; + double result = (requiredAccountAgeAsDays - buyersAccountAgeAsDays) / requiredAccountAgeAsDays * maxDelay; + return Math.round(Math.max(0, result)); + } + + /** + * @param trade The trade for which we want to know the delayed payout for the buyer. + * @return The delay in ms for the payout for the fiat buyer in a trade. + */ + public long getDelay(Trade trade) { + Offer offer = trade.getOffer(); + if (offer == null) { + return 0; + } + + if (CurrencyUtil.isCryptoCurrency(offer.getCurrencyCode())) { + return 0; + } + + Contract contract = trade.getContract(); + if (contract == null) { + return 0; + } + + long buyersAccountAge = accountAgeWitnessService.getAccountAge(contract.getBuyerPaymentAccountPayload(), contract.getBuyerPubKeyRing()); + long requiredAccountAge = getRequiredAccountAge(offer.getPaymentMethod()); + + return getDelayInDays(buyersAccountAge, requiredAccountAge) * DateUtils.MILLIS_PER_DAY; + } + + /** + * @param offer The offer for which we want to know the delayed payout. + * @return The delay in ms for the payout if offer maker is buyer. + */ + public long getDelayForOffer(Offer offer) { + if (CurrencyUtil.isCryptoCurrency(offer.getCurrencyCode())) { + return 0; + } + if (offer.getDirection() == OfferPayload.Direction.SELL) { + return 0; + } + + long buyersAccountAge = accountAgeWitnessService.getMakersAccountAge(offer); + long requiredAccountAge = getRequiredAccountAge(offer.getPaymentMethod()); + return getDelayInDays(buyersAccountAge, requiredAccountAge) * DateUtils.MILLIS_PER_DAY; + } + + /** + * Delay for maker if he is fiat buyer. + * @param myPaymentAccount My payment account used for my offer + * @param currencyCode Currency code of my offer + * @param direction Direction of my offer + * @return The delay in ms for the payout of maker. + */ + public long getDelayForMyOffer(PaymentAccount myPaymentAccount, @Nullable String currencyCode, @Nullable OfferPayload.Direction direction) { + if (direction != null && direction == OfferPayload.Direction.SELL) { + return 0; + } + + if (currencyCode != null && CurrencyUtil.isCryptoCurrency(currencyCode)) { + return 0; + } + + long myAccountAge = accountAgeWitnessService.getMyAccountAge(myPaymentAccount.getPaymentAccountPayload()); + long requiredAccountAge = getRequiredAccountAge(myPaymentAccount.getPaymentMethod()); + return getDelayInDays(myAccountAge, requiredAccountAge) * DateUtils.MILLIS_PER_DAY; + } + + /** + * @param trade The trade for which we want to know the delayed payout date. + * @return The date of a delayed payout + */ + public Date getDelayedTradePayoutDate(Trade trade) { + long delay = getDelay(trade); + long now = new Date().getTime(); + return new Date(delay + now); + } + + /** + * Depending on payment methods chargeback risk we determine the required account age when we do not apply a payout delay anymore. + * The max. period is 42 days/6 weeks. For lower risk payment methods we reduce that to 21 days. + * @param paymentMethod The paymentMethod which determines the max. period + * @return The required account age in ms as day units when we do not apply a payout delay anymore + */ + public long getRequiredAccountAge(PaymentMethod paymentMethod) { + switch (paymentMethod.getId()) { + case PaymentMethod.BLOCK_CHAINS_ID: + case PaymentMethod.BLOCK_CHAINS_INSTANT_ID: + + case PaymentMethod.US_POSTAL_MONEY_ORDER_ID: + case PaymentMethod.HAL_CASH_ID: + case PaymentMethod.F2F_ID: + case PaymentMethod.MONEY_GRAM_ID: + case PaymentMethod.WESTERN_UNION_ID: + + case PaymentMethod.SWISH_ID: + case PaymentMethod.PERFECT_MONEY_ID: + case PaymentMethod.ALI_PAY_ID: + case PaymentMethod.WECHAT_PAY_ID: + return 0; + + case PaymentMethod.ADVANCED_CASH_ID: + case PaymentMethod.PROMPT_PAY_ID: + case PaymentMethod.CASH_DEPOSIT_ID: + return MAX_REQUIRED_AGE / 2 * DateUtils.MILLIS_PER_DAY; + + default: + // All other bank transfer methods + return MAX_REQUIRED_AGE * DateUtils.MILLIS_PER_DAY; + } + } + + /** + * We take the buyer in a trade (maker or taker) into consideration for a delayed payout. + * @param trade The trade for which we request the delayed payout state. + * @return If that trade requires a delayed payout + */ + public boolean tradeRequirePayoutDelay(Trade trade) { + Offer offer = trade.getOffer(); + if (offer == null) { + return false; + } + + if (CurrencyUtil.isCryptoCurrency(offer.getCurrencyCode())) { + return false; + } + + Contract contract = trade.getContract(); + if (contract == null) { + return false; + } + + long buyersAccountAge = accountAgeWitnessService.getAccountAge(contract.getBuyerPaymentAccountPayload(), contract.getBuyerPubKeyRing()); + long requiredAccountAge = getRequiredAccountAge(offer.getPaymentMethod()); + return buyersAccountAge < requiredAccountAge; + } + + /** + * We take the maker as buyer into consideration for a delayed payout. + * @param offer The offer for which we request the delayed payout state. + * @return If that offer requires a delayed payout + */ + public boolean offerRequirePayoutDelay(Offer offer) { + return accountRequiresPayoutDelay(offer.getPaymentMethod(), + accountAgeWitnessService.getMakersAccountAge(offer), + offer.getCurrencyCode(), + offer.getDirection()); + } + + /** + * My account is taken into consideration for a delayed payout. + * @param myPaymentAccount My payment account used for my offer + * @param currencyCode Currency code of my offer + * @param direction Direction of my offer + * @return If my account requires a delayed payout + */ + public boolean myMakerAccountRequiresPayoutDelay(PaymentAccount myPaymentAccount, + String currencyCode, + OfferPayload.Direction direction) { + return accountRequiresPayoutDelay(myPaymentAccount.getPaymentMethod(), + accountAgeWitnessService.getMyAccountAge(myPaymentAccount.getPaymentAccountPayload()), + currencyCode, + direction); + } + + /** + * @param myPaymentAccount My payment account used for my offer + * @return The AccountScoreCategory representing the account age. + */ + public Optional getMyAccountScoreCategory(PaymentAccount myPaymentAccount) { + return Optional.of(getAccountScoreCategory(accountAgeWitnessService.getMyAccountAge(myPaymentAccount.getPaymentAccountPayload()))); + } + + /** + * @param offer The offer for which we request the AccountScoreCategory. + * @return The AccountScoreCategory representing the account age. + */ + public Optional getAccountScoreCategoryOfMaker(Offer offer) { + //TODO probably we want to show the AccountScoreCategory also for sellers + /* if (offer.getDirection() == OfferPayload.Direction.SELL) { + return Optional.empty(); + }*/ + + if (CurrencyUtil.isCryptoCurrency(offer.getCurrencyCode())) { + return Optional.empty(); + } + + long makersAccountAge = accountAgeWitnessService.getMakersAccountAge(offer); + return Optional.of(getAccountScoreCategory(makersAccountAge)); + } + + /** + * @param trade The trade for which we request the AccountScoreCategory. + * @return The AccountScoreCategory representing the account age. + */ + public Optional getAccountScoreCategoryOfBuyer(Trade trade) { + Offer offer = trade.getOffer(); + if (offer == null) { + return Optional.empty(); + } + + if (CurrencyUtil.isCryptoCurrency(offer.getCurrencyCode())) { + return Optional.empty(); + } + + Contract contract = trade.getContract(); + if (contract == null) { + return Optional.empty(); + } + + long buyersAccountAge = accountAgeWitnessService.getAccountAge(contract.getBuyerPaymentAccountPayload(), contract.getBuyerPubKeyRing()); + return Optional.of(getAccountScoreCategory(buyersAccountAge)); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private boolean accountRequiresPayoutDelay(PaymentMethod paymentMethod, + long accountAge, + String currencyCode, + OfferPayload.Direction direction) { + if (direction == OfferPayload.Direction.SELL) { + return false; + } + + if (CurrencyUtil.isCryptoCurrency(currencyCode)) { + return false; + } + + long requiredAccountAge = getRequiredAccountAge(paymentMethod); + return accountAge < requiredAccountAge; + } + + private AccountScoreCategory getAccountScoreCategory(long accountAge) { + long maxRequiredAge = MAX_REQUIRED_AGE * DateUtils.MILLIS_PER_DAY; + if (accountAge >= maxRequiredAge) { + return AccountScoreCategory.GOLD; + } else if (accountAge >= maxRequiredAge / 2) { + return AccountScoreCategory.SILVER; + } else { + return AccountScoreCategory.BRONZE; + } + } +} diff --git a/core/src/main/java/bisq/core/account/score/AccountScoreCategory.java b/core/src/main/java/bisq/core/account/score/AccountScoreCategory.java new file mode 100644 index 00000000000..45ddb162d09 --- /dev/null +++ b/core/src/main/java/bisq/core/account/score/AccountScoreCategory.java @@ -0,0 +1,25 @@ +/* + * 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.account.score; + +public enum AccountScoreCategory { + UNDEFINED, + BRONZE, + SILVER, + GOLD +} diff --git a/core/src/main/java/bisq/core/account/score/AccountScoreService.java b/core/src/main/java/bisq/core/account/score/AccountScoreService.java new file mode 100644 index 00000000000..438bc5aee11 --- /dev/null +++ b/core/src/main/java/bisq/core/account/score/AccountScoreService.java @@ -0,0 +1,96 @@ +/* + * 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.account.score; + +import bisq.core.account.creation.AccountCreationAgeService; +import bisq.core.offer.Offer; +import bisq.core.offer.OfferPayload; +import bisq.core.payment.PaymentAccount; +import bisq.core.payment.payload.PaymentMethod; +import bisq.core.trade.Trade; + +import javax.inject.Inject; + +import java.util.Date; +import java.util.Optional; + +/** + * Main class for account score domain. + * Provides access to any data related to account score. Internally it used different protection tools to constructing + * the resulting parameters. + */ +public class AccountScoreService { + private final AccountCreationAgeService accountCreationAgeService; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public AccountScoreService(AccountCreationAgeService accountCreationAgeService) { + this.accountCreationAgeService = accountCreationAgeService; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public long getRequiredAccountAge(PaymentMethod paymentMethod) { + return accountCreationAgeService.getRequiredAccountAge(paymentMethod); + } + + public boolean myMakerAccountRequiresPayoutDelay(PaymentAccount myPaymentAccount, String currencyCode, OfferPayload.Direction direction) { + return accountCreationAgeService.myMakerAccountRequiresPayoutDelay(myPaymentAccount, currencyCode, direction); + } + + public boolean offerRequirePayoutDelay(Offer offer) { + return accountCreationAgeService.offerRequirePayoutDelay(offer); + } + + public boolean tradeRequirePayoutDelay(Trade trade) { + return accountCreationAgeService.tradeRequirePayoutDelay(trade); + } + + public long getDelayForMyOffer(PaymentAccount myPaymentAccount, String currencyCode, OfferPayload.Direction direction) { + return accountCreationAgeService.getDelayForMyOffer(myPaymentAccount, currencyCode, direction); + } + + public long getDelayForOffer(Offer offer) { + return accountCreationAgeService.getDelayForOffer(offer); + } + + public Date getDelayedTradePayoutDate(Trade trade) { + return accountCreationAgeService.getDelayedTradePayoutDate(trade); + } + + public Optional getMyAccountScoreCategory(PaymentAccount myPaymentAccount) { + return accountCreationAgeService.getMyAccountScoreCategory(myPaymentAccount); + } + + public Optional getAccountScoreCategoryOfMaker(Offer offer) { + return accountCreationAgeService.getAccountScoreCategoryOfMaker(offer); + } + + public Optional getAccountScoreCategoryOfBuyer(Trade trade) { + return accountCreationAgeService.getAccountScoreCategoryOfBuyer(trade); + } + + +} diff --git a/core/src/main/java/bisq/core/payment/AccountAgeWitness.java b/core/src/main/java/bisq/core/account/witness/AccountAgeWitness.java similarity index 99% rename from core/src/main/java/bisq/core/payment/AccountAgeWitness.java rename to core/src/main/java/bisq/core/account/witness/AccountAgeWitness.java index 78660248a55..df42102a545 100644 --- a/core/src/main/java/bisq/core/payment/AccountAgeWitness.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeWitness.java @@ -15,7 +15,7 @@ * along with bisq. If not, see . */ -package bisq.core.payment; +package bisq.core.account.witness; import bisq.network.p2p.storage.P2PDataStorage; import bisq.network.p2p.storage.payload.CapabilityRequiringPayload; diff --git a/core/src/main/java/bisq/core/payment/AccountAgeWitnessService.java b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java similarity index 99% rename from core/src/main/java/bisq/core/payment/AccountAgeWitnessService.java rename to core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java index 405bd694c19..3dd79e681d6 100644 --- a/core/src/main/java/bisq/core/payment/AccountAgeWitnessService.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java @@ -15,10 +15,12 @@ * along with bisq. If not, see . */ -package bisq.core.payment; +package bisq.core.account.witness; import bisq.core.locale.CurrencyUtil; import bisq.core.offer.Offer; +import bisq.core.payment.AssetAccount; +import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.payload.PaymentMethod; import bisq.core.trade.Trade; @@ -283,13 +285,13 @@ public long getMyTradeLimit(PaymentAccount paymentAccount, String currencyCode) /////////////////////////////////////////////////////////////////////////////////////////// // Return -1 if witness data is not found (old versions) - public long getMakersAccountAge(Offer offer, Date peersCurrentDate) { + public long getMakersAccountAge(Offer offer) { final Optional accountAgeWitnessHash = offer.getAccountAgeWitnessHashAsHex(); final Optional witnessByHashAsHex = accountAgeWitnessHash.isPresent() ? getWitnessByHashAsHex(accountAgeWitnessHash.get()) : Optional.empty(); return witnessByHashAsHex - .map(accountAgeWitness -> getAccountAge(accountAgeWitness, peersCurrentDate)) + .map(accountAgeWitness -> getAccountAge(accountAgeWitness, new Date())) .orElse(-1L); } diff --git a/core/src/main/java/bisq/core/payment/AccountAgeWitnessStorageService.java b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessStorageService.java similarity index 98% rename from core/src/main/java/bisq/core/payment/AccountAgeWitnessStorageService.java rename to core/src/main/java/bisq/core/account/witness/AccountAgeWitnessStorageService.java index 437014d9797..84fd4d8d5cc 100644 --- a/core/src/main/java/bisq/core/payment/AccountAgeWitnessStorageService.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessStorageService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.payment; +package bisq.core.account.witness; import bisq.network.p2p.storage.P2PDataStorage; import bisq.network.p2p.storage.payload.PersistableNetworkPayload; diff --git a/core/src/main/java/bisq/core/payment/AccountAgeWitnessStore.java b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessStore.java similarity index 98% rename from core/src/main/java/bisq/core/payment/AccountAgeWitnessStore.java rename to core/src/main/java/bisq/core/account/witness/AccountAgeWitnessStore.java index 9493be42a4e..cd7637d5fbf 100644 --- a/core/src/main/java/bisq/core/payment/AccountAgeWitnessStore.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessStore.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.payment; +package bisq.core.account.witness; import bisq.network.p2p.storage.P2PDataStorage; import bisq.network.p2p.storage.payload.PersistableNetworkPayload; diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java index 07668b9b241..f722b6b795c 100644 --- a/core/src/main/java/bisq/core/app/BisqSetup.java +++ b/core/src/main/java/bisq/core/app/BisqSetup.java @@ -17,6 +17,7 @@ package bisq.core.app; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.Alert; import bisq.core.alert.AlertManager; import bisq.core.alert.PrivateNotificationManager; @@ -41,7 +42,6 @@ import bisq.core.notifications.alerts.market.MarketAlerts; import bisq.core.notifications.alerts.price.PriceAlert; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.TradeLimits; import bisq.core.provider.fee.FeeService; diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java index 07c74d7e760..c708552d1aa 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java @@ -17,10 +17,10 @@ package bisq.core.app.misc; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.app.SetupUtils; import bisq.core.app.TorSetup; import bisq.core.filter.FilterManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.statistics.TradeStatisticsManager; import bisq.network.crypto.EncryptionService; diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java index 4a2a89c2953..9de90a9d09f 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java @@ -17,6 +17,7 @@ package bisq.core.app.misc; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.app.TorSetup; import bisq.core.dao.DaoOptionKeys; import bisq.core.dao.DaoSetup; @@ -27,7 +28,6 @@ import bisq.core.dao.governance.proofofburn.MyProofOfBurnListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.filter.FilterManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.statistics.TradeStatisticsManager; import bisq.network.crypto.EncryptionService; diff --git a/core/src/main/java/bisq/core/offer/OfferUtil.java b/core/src/main/java/bisq/core/offer/OfferUtil.java index dbd892a410c..be0191d3252 100644 --- a/core/src/main/java/bisq/core/offer/OfferUtil.java +++ b/core/src/main/java/bisq/core/offer/OfferUtil.java @@ -17,6 +17,7 @@ package bisq.core.offer; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.Restrictions; import bisq.core.filter.FilterManager; @@ -24,7 +25,6 @@ import bisq.core.locale.Res; import bisq.core.monetary.Price; import bisq.core.monetary.Volume; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.F2FAccount; import bisq.core.payment.PaymentAccount; import bisq.core.provider.fee.FeeService; diff --git a/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java b/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java index 4b0a08d9092..7848bfa19c8 100644 --- a/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccountUtil.java @@ -17,6 +17,7 @@ package bisq.core.payment; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Country; import bisq.core.offer.Offer; import bisq.core.payment.payload.PaymentMethod; diff --git a/core/src/main/java/bisq/core/payment/PaymentAccounts.java b/core/src/main/java/bisq/core/payment/PaymentAccounts.java index e91c26c72ce..6018595bd13 100644 --- a/core/src/main/java/bisq/core/payment/PaymentAccounts.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccounts.java @@ -17,6 +17,8 @@ package bisq.core.payment; +import bisq.core.account.witness.AccountAgeWitness; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.offer.Offer; import java.util.Comparator; diff --git a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java index 23066d18c26..a0721096437 100644 --- a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java +++ b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java @@ -150,7 +150,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { // Sweden SWISH = new PaymentMethod(SWISH_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK), - // US + // US (ZELLE) CLEAR_X_CHANGE = new PaymentMethod(CLEAR_X_CHANGE_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK), POPMONEY = new PaymentMethod(POPMONEY_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK), @@ -174,7 +174,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { UPHOLD = new PaymentMethod(UPHOLD_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK), REVOLUT = new PaymentMethod(REVOLUT_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK), PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK), - ADVANCED_CASH = new PaymentMethod(ADVANCED_CASH_ID, DAY, DEFAULT_TRADE_LIMIT_VERY_LOW_RISK), + ADVANCED_CASH = new PaymentMethod(ADVANCED_CASH_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK), // China ALI_PAY = new PaymentMethod(ALI_PAY_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK), diff --git a/core/src/main/java/bisq/core/proto/CoreProtoResolver.java b/core/src/main/java/bisq/core/proto/CoreProtoResolver.java index ebc101175e1..6d632cf97f9 100644 --- a/core/src/main/java/bisq/core/proto/CoreProtoResolver.java +++ b/core/src/main/java/bisq/core/proto/CoreProtoResolver.java @@ -17,9 +17,9 @@ package bisq.core.proto; +import bisq.core.account.witness.AccountAgeWitness; import bisq.core.dao.governance.blindvote.storage.BlindVotePayload; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload; -import bisq.core.payment.AccountAgeWitness; import bisq.core.payment.payload.AdvancedCashAccountPayload; import bisq.core.payment.payload.AliPayAccountPayload; import bisq.core.payment.payload.CashAppAccountPayload; diff --git a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java index 0878077c5ce..36b5b5c72b8 100644 --- a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java +++ b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java @@ -17,6 +17,7 @@ package bisq.core.proto.persistable; +import bisq.core.account.witness.AccountAgeWitnessStore; import bisq.core.arbitration.DisputeList; import bisq.core.btc.model.AddressEntryList; import bisq.core.btc.wallet.BtcWalletService; @@ -32,7 +33,6 @@ import bisq.core.dao.state.model.governance.BallotList; import bisq.core.dao.state.model.governance.MeritList; import bisq.core.dao.state.unconfirmed.UnconfirmedBsqChangeOutputList; -import bisq.core.payment.AccountAgeWitnessStore; import bisq.core.payment.PaymentAccountList; import bisq.core.proto.CoreProtoResolver; import bisq.core.trade.TradableList; diff --git a/core/src/main/java/bisq/core/trade/Trade.java b/core/src/main/java/bisq/core/trade/Trade.java index dd14c4f092a..a21b09612ce 100644 --- a/core/src/main/java/bisq/core/trade/Trade.java +++ b/core/src/main/java/bisq/core/trade/Trade.java @@ -17,6 +17,7 @@ package bisq.core.trade; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.Arbitrator; import bisq.core.arbitration.ArbitratorManager; import bisq.core.arbitration.Mediator; @@ -30,7 +31,6 @@ import bisq.core.offer.Offer; import bisq.core.offer.OfferUtil; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.payload.PaymentMethod; import bisq.core.proto.CoreProtoResolver; import bisq.core.trade.protocol.ProcessModel; diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index 4e70e45ad6e..5f1fa1d6c91 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -17,6 +17,8 @@ package bisq.core.trade; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.ArbitratorManager; import bisq.core.btc.exceptions.AddressEntryException; import bisq.core.btc.model.AddressEntry; @@ -29,7 +31,6 @@ import bisq.core.offer.OpenOffer; import bisq.core.offer.OpenOfferManager; import bisq.core.offer.availability.OfferAvailabilityModel; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.provider.price.PriceFeedService; import bisq.core.trade.closed.ClosedTradableManager; import bisq.core.trade.failed.FailedTradesManager; @@ -117,6 +118,7 @@ public class TradeManager implements PersistedDataHost { private final ReferralIdService referralIdService; private final AccountAgeWitnessService accountAgeWitnessService; private final ArbitratorManager arbitratorManager; + private final AccountScoreService accountScoreService; private final Clock clock; private final Storage> tradableListStorage; @@ -151,6 +153,7 @@ public TradeManager(User user, PersistenceProtoResolver persistenceProtoResolver, AccountAgeWitnessService accountAgeWitnessService, ArbitratorManager arbitratorManager, + AccountScoreService accountScoreService, Clock clock, @Named(Storage.STORAGE_DIR) File storageDir) { this.user = user; @@ -168,6 +171,7 @@ public TradeManager(User user, this.referralIdService = referralIdService; this.accountAgeWitnessService = accountAgeWitnessService; this.arbitratorManager = arbitratorManager; + this.accountScoreService = accountScoreService; this.clock = clock; tradableListStorage = new Storage<>(storageDir, persistenceProtoResolver); @@ -642,12 +646,17 @@ private void updateTradePeriodState() { Date halfTradePeriodDate = trade.getHalfTradePeriodDate(); if (maxTradePeriodDate != null && halfTradePeriodDate != null) { Date now = new Date(); - if (now.after(maxTradePeriodDate)) + if (now.after(maxTradePeriodDate)) { trade.setTradePeriodState(Trade.TradePeriodState.TRADE_PERIOD_OVER); - else if (now.after(halfTradePeriodDate)) + } else if (now.after(halfTradePeriodDate)) { trade.setTradePeriodState(Trade.TradePeriodState.SECOND_HALF); + } } } }); } + + public boolean requirePayoutDelay(Trade trade) { + return accountScoreService.tradeRequirePayoutDelay(trade); + } } diff --git a/core/src/main/java/bisq/core/trade/TradeModule.java b/core/src/main/java/bisq/core/trade/TradeModule.java index 7d0ed2ce4cc..3b888a8421f 100644 --- a/core/src/main/java/bisq/core/trade/TradeModule.java +++ b/core/src/main/java/bisq/core/trade/TradeModule.java @@ -17,9 +17,11 @@ package bisq.core.trade; +import bisq.core.account.creation.AccountCreationAgeService; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; +import bisq.core.account.witness.AccountAgeWitnessStorageService; import bisq.core.app.AppOptionKeys; -import bisq.core.payment.AccountAgeWitnessService; -import bisq.core.payment.AccountAgeWitnessStorageService; import bisq.core.trade.closed.ClosedTradableManager; import bisq.core.trade.failed.FailedTradesManager; import bisq.core.trade.statistics.AssetTradeActivityCheck; @@ -48,6 +50,8 @@ protected void configure() { bind(TradeStatistics2StorageService.class).in(Singleton.class); bind(ClosedTradableManager.class).in(Singleton.class); bind(FailedTradesManager.class).in(Singleton.class); + bind(AccountCreationAgeService.class).in(Singleton.class); + bind(AccountScoreService.class).in(Singleton.class); bind(AccountAgeWitnessService.class).in(Singleton.class); bind(ReferralIdService.class).in(Singleton.class); bind(AccountAgeWitnessStorageService.class).in(Singleton.class); diff --git a/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java b/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java index e6164436eb4..174acc85c24 100644 --- a/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java +++ b/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java @@ -17,6 +17,7 @@ package bisq.core.trade.protocol; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.ArbitratorManager; import bisq.core.btc.model.RawTransactionInput; import bisq.core.btc.wallet.BsqWalletService; @@ -26,7 +27,6 @@ import bisq.core.network.MessageState; import bisq.core.offer.Offer; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.proto.CoreProtoResolver; diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/VerifyPeersAccountAgeWitness.java b/core/src/main/java/bisq/core/trade/protocol/tasks/VerifyPeersAccountAgeWitness.java index 1b1b4cc9b42..a0636c6b8b1 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/VerifyPeersAccountAgeWitness.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/VerifyPeersAccountAgeWitness.java @@ -17,8 +17,8 @@ package bisq.core.trade.protocol.tasks; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CurrencyUtil; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.trade.Trade; import bisq.core.trade.protocol.TradingPeer; diff --git a/core/src/main/java/bisq/core/util/BSFormatter.java b/core/src/main/java/bisq/core/util/BSFormatter.java index 54e54c016ff..443220e50c3 100644 --- a/core/src/main/java/bisq/core/util/BSFormatter.java +++ b/core/src/main/java/bisq/core/util/BSFormatter.java @@ -608,7 +608,9 @@ public String formatAccountAge(long durationMillis) { String day = Res.get("time.day").toLowerCase(); String days = Res.get("time.days"); String format = "d\' " + days + "\'"; - return StringUtils.replaceOnce(DurationFormatUtils.formatDuration(durationMillis, format), "1 " + days, "1 " + day); + String duration = DurationFormatUtils.formatDuration(durationMillis, format); + long daysAsLong = durationMillis / DateUtils.MILLIS_PER_DAY; + return daysAsLong == 1 ? StringUtils.replaceOnce(duration, "1 " + days, "1 " + day) : duration; } public String formatDurationAsWords(long durationMillis) { diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 9d5e9d78a86..3b35d95b082 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -356,7 +356,10 @@ offerbook.warning.tradeLimitNotMatching=Your payment account has been created {0 Your trade limit is: {1}\n\ The min. trade amount of the offer is: {2}.\n\n\ You cannot take that offer at the moment. Once your account is older than 2 months this restriction gets removed. - +offerbook.warning.buyerHasImmatureAccount=The peer''s account age is {0} and therefore less than the required \ +minimum account age for bitcoin buyers of {1}.\n\n\ +You can still take this offer, but the payout will be delayed for {2}. +offerbook.warning.buyerHasImmatureAccount.confirm=Ok, I understand and still want to take this offer. offerbook.info.sellAtMarketPrice=You will sell at market price (updated every minute). offerbook.info.buyAtMarketPrice=You will buy at market price (updated every minute). @@ -654,6 +657,15 @@ portfolio.pending.step3_seller.onPaymentReceived.name=Please also verify that th portfolio.pending.step3_seller.onPaymentReceived.note=Please note, that as soon you have confirmed the receipt, the locked trade amount will be released to the BTC buyer and the security deposit will be refunded. portfolio.pending.step3_seller.onPaymentReceived.confirm.headline=Confirm that you have received the payment portfolio.pending.step3_seller.onPaymentReceived.confirm.yes=Yes, I have received the payment +portfolio.pending.step3_seller.status.delayedPayoutInfo=Please open your Bisq application after {0} to release the bitcoin. +portfolio.pending.step3_seller.popup.delayedPayoutInfo=The buyer''s account was created {0} ago.\n\n\ +To reduce risks with bank chargebacks, the payout of the bitcoin is delayed until {1}.\n\n\ +Please be sure to open your Bisq application after that date to release the bitcoin to the buyer, and to get your security deposit refunded.\n\n\ +In case you get a chargeback request from your bank, open a dispute with Cmd + o or Ctrl + o. + + +portfolio.pending.step3_seller.button.release=Release Bitcoin +portfolio.pending.step3_seller.status.confirmRelease=The buyer''s account is now {0} days old. Please confirm to release the bitcoin. portfolio.pending.step5_buyer.groupTitle=Summary of completed trade portfolio.pending.step5_buyer.tradeFee=Trade fee @@ -690,6 +702,7 @@ portfolio.pending.remainingTimeDetail={0} (until {1}) portfolio.pending.tradePeriodInfo=After the first blockchain confirmation, the trade period starts. Based on the payment method used, a different maximum allowed trade period is applied. portfolio.pending.tradePeriodWarning=If the period is exceeded both traders can open a dispute. portfolio.pending.tradeNotCompleted=Trade not completed in time (until {0}) +portfolio.pending.tradeNotCompleted.immatureBuyerAccount=Trade not completed yet portfolio.pending.tradeProcess=Trade process portfolio.pending.openAgainDispute.msg=If you are not sure that the message to the arbitrator arrived (e.g. if you did not get a response after 1 day) feel free to open a dispute again. portfolio.pending.openAgainDispute.button=Open dispute again @@ -2305,8 +2318,10 @@ popup.shutDownInProgress.msg=Shutting down application can take a few seconds.\n popup.attention.forTradeWithId=Attention required for trade with ID {0} -popup.roundedFiatValues.headline=New privacy feature: Rounded fiat values -popup.roundedFiatValues.msg=To increase privacy of your trade the {0} amount was rounded.\n\nDepending on the client version you''ll pay or receive either values with decimals or rounded ones.\n\nBoth values do comply from now on with the trade protocol.\n\nAlso be aware that BTC values are changed automatically to match the rounded fiat amount as close as possible. +popup.immatureBuyerAccountAge.createOffer.msg=Your account was created {0} ago.\n\n\ +To protect against bank chargeback fraud, this payment method requires a minimum account age of {1} for the bitcoin buyer.\n\n\ +You can still create this offer, but the payout of the bitcoin will be delayed until your account age reaches {2}.\n\n\ +This is a necessary protection against bank chargeback fraud. popup.info.multiplePaymentAccounts.headline=Multiple payment accounts available popup.info.multiplePaymentAccounts.msg=You have multiple payment accounts available for this offer. Please make sure you've picked the right one. @@ -2573,6 +2588,7 @@ payment.revolut.phoneNr=Registered phone no. payment.promptPay.promptPayId=Citizen ID/Tax ID or phone no. payment.supportedCurrencies=Supported currencies payment.limitations=Limitations +payment.accountAgeTitle=Account age payment.salt=Salt for account age verification payment.error.noHexSalt=The salt need to be in HEX format.\n\ It is only recommended to edit the salt field if you want to transfer the salt from an old account to keep your account age. \ @@ -2592,8 +2608,8 @@ payment.accountNr=Account number payment.emailOrMobile=Email or mobile nr payment.useCustomAccountName=Use custom account name payment.maxPeriod=Max. allowed trade period -payment.maxPeriodAndLimit=Max. trade duration: {0} / Max. trade limit: {1} / Account age: {2} -payment.maxPeriodAndLimitCrypto=Max. trade duration: {0} / Max. trade limit: {1} +payment.accountAge=Account age: {0} / Buyer''s min. account age: {1} +payment.maxPeriodAndTradeLimits=Max. trade duration: {0} / Max. trade limit: {1} payment.currencyWithSymbol=Currency: {0} payment.nameOfAcceptedBank=Name of accepted bank payment.addAcceptedBank=Add accepted bank @@ -2657,7 +2673,11 @@ payment.limits.info=Please be aware that all bank transfers carry a certain amou ● During the 2nd month, your per-trade limit will be {1}\n\ ● After the 2nd month, your per-trade limit will be {2}\n\ \n\ - Please note that there are no limits on the total number of times you can trade. + Please note that there are no limits on the number of times you can trade.\n\n\ + For trades where you are the bitcoin buyer, payout of the purchased bitcoin will be \ + delayed until you reach the required account age of {3}. You are free to place more \ + trades in the interim, but you will not receive the bitcoin for these trades before \ + the account age reaches {3}. payment.cashDeposit.info=Please confirm your bank allows you to send cash deposits into other peoples' accounts. \ For example, Bank of America and Wells Fargo no longer allow such deposits. diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index 60863333000..25121fc003c 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Kontonummer payment.emailOrMobile=E-Mail oder Telefonnr. payment.useCustomAccountName=Spezifischen Kontonamen nutzen payment.maxPeriod=Max. erlaubte Handelsdauer -payment.maxPeriodAndLimit=Max. Handelsdauer: {0} / Max. Handelsgrenze: {1} / Konto-Alter: {2} -payment.maxPeriodAndLimitCrypto=Max. Handelsdauer: {0} / Max. Handelsgrenze: {1} +payment.maxPeriodAndTradeLimits=Max. Handelsdauer: {0} / Max. Handelsgrenze: {1} payment.currencyWithSymbol=Währung: {0} payment.nameOfAcceptedBank=Name der akzeptierten Bank payment.addAcceptedBank=Akzeptierte Bank hinzufügen diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index 0aed332abd8..a9daab48a0a 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Account number payment.emailOrMobile=Email or mobile nr payment.useCustomAccountName=Χρήση προεπιλεγμένου ονόματος λογαριασμού payment.maxPeriod=Max. allowed trade period -payment.maxPeriodAndLimit=Μέγιστη διάρκεια συναλλαγής: {0} / Μέγιστο όριο συναλλαγής: {1} / Ηλικία λογαριασμού: {2} -payment.maxPeriodAndLimitCrypto=Μέγιστη διάρκεια συναλλαγής: {0} / Μέγιστο όριο συναλλαγής: {1} +payment.maxPeriodAndTradeLimits=Μέγιστη διάρκεια συναλλαγής: {0} / Μέγιστο όριο συναλλαγής: {1} payment.currencyWithSymbol=Νόμισμα: {0} payment.nameOfAcceptedBank=Όνομα αποδεκτής τράπεζας payment.addAcceptedBank=Εισαγωγή αποδεκτής τράπεζας diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index f71c21e3a1b..82414224d17 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Número de cuenta payment.emailOrMobile=Email o número de móvil payment.useCustomAccountName=Utilizar nombre de cuenta personalizado payment.maxPeriod=Periodo máximo de intercambio -payment.maxPeriodAndLimit=Duración máxima de intercambio: {0} / Límite máximo de intercambio: {1} -payment.maxPeriodAndLimitCrypto=Duración máxima de intercambio: {0} / Límite máximo de intercambio: {1} +payment.maxPeriodAndTradeLimits=Duración máxima de intercambio: {0} / Límite máximo de intercambio: {1} payment.currencyWithSymbol=Moneda: {0} payment.nameOfAcceptedBank=Nombre de banco aceptado payment.addAcceptedBank=Añadir banco aceptado diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index dad3af0f66c..5e3fcad37f1 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -2243,8 +2243,7 @@ payment.accountNr=شماره حساب payment.emailOrMobile=ایمیل یا شماره موبایل payment.useCustomAccountName=استفاده از نام حساب سفارشی payment.maxPeriod=حداکثر دوره ی زمانی مجاز معامله -payment.maxPeriodAndLimit=حداکثر طول مدت معامله: {0} / حداکثر حد معامله: {1} / عمر حساب: {2} -payment.maxPeriodAndLimitCrypto=حداکثر طول مدت معامله: {0} / حداکثر معامله: {1} +payment.maxPeriodAndTradeLimits=حداکثر طول مدت معامله: {0} / حداکثر معامله: {1} payment.currencyWithSymbol=ارز: {0} payment.nameOfAcceptedBank=نام بانک پذیرفته شده payment.addAcceptedBank=افزودن بانک پذیرفته شده diff --git a/core/src/main/resources/i18n/displayStrings_fr.properties b/core/src/main/resources/i18n/displayStrings_fr.properties index 60fd6017eae..099ab1c57db 100644 --- a/core/src/main/resources/i18n/displayStrings_fr.properties +++ b/core/src/main/resources/i18n/displayStrings_fr.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Account number payment.emailOrMobile=Email or mobile nr payment.useCustomAccountName=Utiliser un nom de compte personnalisé payment.maxPeriod=Max. allowed trade period -payment.maxPeriodAndLimit=Max. trade duration: {0} / Max. trade limit: {1} / Account age: {2} -payment.maxPeriodAndLimitCrypto=Max. trade duration: {0} / Max. trade limit: {1} +payment.maxPeriodAndTradeLimits=Max. trade duration: {0} / Max. trade limit: {1} payment.currencyWithSymbol=Devise:{0} payment.nameOfAcceptedBank=Nom de la banque acceptée payment.addAcceptedBank=Ajouter une banque acceptée diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index b474a6efd56..84046a2fcc9 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Número da conta payment.emailOrMobile=Email ou nº de telemóvel payment.useCustomAccountName=Usar nome de conta personalizado: payment.maxPeriod=Período máx. de negócio -payment.maxPeriodAndLimit=Duração máx. de negócio: {0} / Máx. limite de negócio: {1} / Idade da conta: {2} -payment.maxPeriodAndLimitCrypto=Período máx. de negócio {0} / Limite máx. de negócio: {1} +payment.maxPeriodAndTradeLimits=Período máx. de negócio {0} / Limite máx. de negócio: {1} payment.currencyWithSymbol=Moeda: {0} payment.nameOfAcceptedBank=Nome do banco aceite payment.addAcceptedBank=Adicionar banco aceite diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 0e84c54857e..7c7ba900d30 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Номер счёта payment.emailOrMobile=Э-почта или мобильный номер payment.useCustomAccountName=Использовать своё название счёта payment.maxPeriod=Макс. допустимый срок сделки -payment.maxPeriodAndLimit=Макс. продолжительность сделки: {0} / Макс. торговый предел: {1} / Срок существования счёта: {2} -payment.maxPeriodAndLimitCrypto=Макс. продолжительность сделки: {0} / Макс. торговый предел: {1} +payment.maxPeriodAndTradeLimits=Макс. продолжительность сделки: {0} / Макс. торговый предел: {1} payment.currencyWithSymbol=Валюта: {0} payment.nameOfAcceptedBank=Название приемлемого банка payment.addAcceptedBank=Добавить приемлемый банк diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index 932ff9a7228..6f3c75c32ee 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -2243,8 +2243,7 @@ payment.accountNr=หมายเลขบัญชี payment.emailOrMobile=หมายเลขโทรศัพท์มือถือหรืออีเมล payment.useCustomAccountName=ใช้ชื่อบัญชีที่กำหนดเอง payment.maxPeriod=ระยะเวลาสูงสุดการค้าที่อนุญาต -payment.maxPeriodAndLimit=ระยะเวลาสูงสุดทางการค้า: {0} / ขีดจำกัดสูงสุดทางการค้า: {1} / อายุบัญชี: {2} -payment.maxPeriodAndLimitCrypto=ระยะเวลาสูงสุดทางการค้า: {0} / ขีดจำกัดสูงสุดทางการค้า: {1} +payment.maxPeriodAndTradeLimits=ระยะเวลาสูงสุดทางการค้า: {0} / ขีดจำกัดสูงสุดทางการค้า: {1} payment.currencyWithSymbol=สกุลเงิน: {0} payment.nameOfAcceptedBank=ชื่อธนาคารที่ได้รับการยอมรับ payment.addAcceptedBank=เพิ่มธนาคารที่ได้รับการยอมรับ diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index d3b33232565..46939dd9d6c 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Số tài khoản payment.emailOrMobile=Email hoặc số điện thoại payment.useCustomAccountName=Sử dụng tên tài khoản thông dụng payment.maxPeriod=Thời gian giao dịch cho phép tối đa -payment.maxPeriodAndLimit=Thời gian giao dịch tối đa: {0} / Giới hạn giao dịch tối đa: {1} / Tuổi tài khoản: {2} -payment.maxPeriodAndLimitCrypto=Thời gian giao dịch tối đa: {0} / Giới hạn giao dịch tối đa: {1} +payment.maxPeriodAndTradeLimits=Thời gian giao dịch tối đa: {0} / Giới hạn giao dịch tối đa: {1} payment.currencyWithSymbol=Tiền tệ: {0} payment.nameOfAcceptedBank=Tên NH được chấp nhận payment.addAcceptedBank=Thêm NH được chấp nhận diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index 0e5ee43cf7b..4be0d80e8bf 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -2243,8 +2243,7 @@ payment.accountNr=Account number payment.emailOrMobile=Email or mobile nr payment.useCustomAccountName=使用自定义名称 payment.maxPeriod=Max. allowed trade period -payment.maxPeriodAndLimit=最大交易期限:{0} /最大交易限额:{1} -payment.maxPeriodAndLimitCrypto=最大交易期限:{0} /最大交易限额:{1} +payment.maxPeriodAndTradeLimits=最大交易期限:{0} /最大交易限额:{1} payment.currencyWithSymbol=货币:{0} payment.nameOfAcceptedBank=接受的银行名称 payment.addAcceptedBank=添加接受的银行 diff --git a/core/src/test/java/bisq/core/account/creation/AccountCreationAgeServiceTest.java b/core/src/test/java/bisq/core/account/creation/AccountCreationAgeServiceTest.java new file mode 100644 index 00000000000..fb1deb66d48 --- /dev/null +++ b/core/src/test/java/bisq/core/account/creation/AccountCreationAgeServiceTest.java @@ -0,0 +1,70 @@ +/* + * 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.account.creation; + +import org.apache.commons.lang3.time.DateUtils; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class AccountCreationAgeServiceTest { + + @Test + public void testGetDelay() { + long buyersAccountAge, requiredAccountAge, expected; + + requiredAccountAge = 0; + buyersAccountAge = 0; + expected = 0; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + requiredAccountAge = 42 * DateUtils.MILLIS_PER_DAY; + buyersAccountAge = 0; + expected = 28; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 42 * DateUtils.MILLIS_PER_DAY; + expected = 0; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 28 * DateUtils.MILLIS_PER_DAY; + expected = 9; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 100 * DateUtils.MILLIS_PER_DAY; + expected = 0; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 1 * DateUtils.MILLIS_PER_DAY; + expected = 27; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 2 * DateUtils.MILLIS_PER_DAY; + expected = 27; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 40 * DateUtils.MILLIS_PER_DAY; + expected = 1; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + + buyersAccountAge = 41 * DateUtils.MILLIS_PER_DAY; + expected = 1; + assertEquals(expected, AccountCreationAgeService.getDelayInDays(buyersAccountAge, requiredAccountAge)); + } +} diff --git a/core/src/test/java/bisq/core/payment/AccountAgeWitnessServiceTest.java b/core/src/test/java/bisq/core/account/witness/AccountAgeWitnessServiceTest.java similarity index 99% rename from core/src/test/java/bisq/core/payment/AccountAgeWitnessServiceTest.java rename to core/src/test/java/bisq/core/account/witness/AccountAgeWitnessServiceTest.java index b9af8202372..c5f28113f55 100644 --- a/core/src/test/java/bisq/core/payment/AccountAgeWitnessServiceTest.java +++ b/core/src/test/java/bisq/core/account/witness/AccountAgeWitnessServiceTest.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.payment; +package bisq.core.account.witness; import bisq.common.crypto.CryptoException; import bisq.common.crypto.Sig; diff --git a/core/src/test/java/bisq/core/payment/PaymentAccountsTest.java b/core/src/test/java/bisq/core/payment/PaymentAccountsTest.java index 871215967a0..82f9c5f6348 100644 --- a/core/src/test/java/bisq/core/payment/PaymentAccountsTest.java +++ b/core/src/test/java/bisq/core/payment/PaymentAccountsTest.java @@ -17,6 +17,8 @@ package bisq.core.payment; +import bisq.core.account.witness.AccountAgeWitness; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.offer.Offer; import bisq.core.payment.payload.PaymentAccountPayload; diff --git a/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java b/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java index 8886ec24bbd..5d9262ecdfb 100644 --- a/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java +++ b/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java @@ -19,11 +19,11 @@ import bisq.desktop.main.overlays.editor.PeerInfoWithTagEditor; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.Trade; import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; @@ -46,7 +46,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.Date; import java.util.Map; import lombok.extern.slf4j.Slf4j; @@ -254,7 +253,7 @@ private long getPeersAccountAge(@Nullable Trade trade, @Nullable Offer offer) { } else { checkNotNull(offer, "Offer must not be null if trade is null."); - return accountAgeWitnessService.getMakersAccountAge(offer, new Date()); + return accountAgeWitnessService.getMakersAccountAge(offer); } } diff --git a/desktop/src/main/java/bisq/desktop/components/PeerInfoIconSmall.java b/desktop/src/main/java/bisq/desktop/components/PeerInfoIconSmall.java index 10992826141..c07bc5ff328 100644 --- a/desktop/src/main/java/bisq/desktop/components/PeerInfoIconSmall.java +++ b/desktop/src/main/java/bisq/desktop/components/PeerInfoIconSmall.java @@ -1,8 +1,8 @@ package bisq.desktop.components; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java index 44d03fbedeb..445bc77b4a6 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AdvancedCashForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.AdvancedCashValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.AdvancedCashAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.AdvancedCashAccountPayload; @@ -37,22 +38,14 @@ import org.apache.commons.lang3.StringUtils; import javafx.scene.control.Label; -import javafx.scene.control.TextField; import javafx.scene.layout.FlowPane; import javafx.scene.layout.GridPane; -import javafx.geometry.Insets; -import javafx.geometry.VPos; +import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField; +import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextFieldWithCopyIcon; +import static bisq.desktop.util.FormBuilder.addTopLabelFlowPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static bisq.desktop.util.FormBuilder.*; - -@Deprecated public class AdvancedCashForm extends PaymentMethodForm { - private static final Logger log = LoggerFactory.getLogger(AdvancedCashForm.class); - private final AdvancedCashAccount advancedCashAccount; private final AdvancedCashValidator advancedCashValidator; private InputTextField accountNrInputTextField; @@ -64,9 +57,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public AdvancedCashForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AdvancedCashValidator advancedCashValidator, - InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public AdvancedCashForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, AdvancedCashValidator advancedCashValidator, + InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.advancedCashAccount = (AdvancedCashAccount) paymentAccount; this.advancedCashValidator = advancedCashValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AliPayForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AliPayForm.java index 3b565c8165c..ca910d2f4ed 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AliPayForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AliPayForm.java @@ -19,8 +19,9 @@ import bisq.desktop.util.validation.AliPayValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.AliPayAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.AliPayAccountPayload; @@ -41,8 +42,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public AliPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AliPayValidator aliPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public AliPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, AliPayValidator aliPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.aliPayAccount = (AliPayAccount) paymentAccount; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java index 76bad08bbed..b13f7c3ef3b 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java @@ -23,12 +23,13 @@ import bisq.desktop.util.FormBuilder; import bisq.desktop.util.Layout; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.dao.governance.asset.AssetService; import bisq.core.filter.FilterManager; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.AssetAccount; import bisq.core.payment.InstantCryptoCurrencyAccount; import bisq.core.payment.PaymentAccount; @@ -89,6 +90,7 @@ public static int addFormForBuyer(GridPane gridPane, public AssetsForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, AltCoinAddressValidator altCoinAddressValidator, InputValidator inputValidator, GridPane gridPane, @@ -97,7 +99,7 @@ public AssetsForm(PaymentAccount paymentAccount, AssetService assetService, FilterManager filterManager, Preferences preferences) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.assetAccount = (AssetAccount) paymentAccount; this.altCoinAddressValidator = altCoinAddressValidator; this.assetService = assetService; diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/BankForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/BankForm.java index 0c1b303495a..a3f9ce9c09a 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/BankForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/BankForm.java @@ -21,6 +21,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.BankUtil; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; @@ -28,7 +30,6 @@ import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.CountryBasedPaymentAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.BankAccountPayload; @@ -166,9 +167,9 @@ static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountPayload private ComboBox accountTypeComboBox; private Country selectedCountry; - BankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + BankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.bankAccountPayload = (BankAccountPayload) paymentAccount.paymentAccountPayload; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/CashDepositForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/CashDepositForm.java index 04ce422bca9..728c8eaeca6 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/CashDepositForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/CashDepositForm.java @@ -22,6 +22,8 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.EmailValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.BankUtil; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; @@ -29,7 +31,6 @@ import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.CountryBasedPaymentAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.CashDepositAccountPayload; @@ -181,9 +182,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount private final EmailValidator emailValidator; private Country selectedCountry; - public CashDepositForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + public CashDepositForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.cashDepositAccountPayload = (CashDepositAccountPayload) paymentAccount.paymentAccountPayload; emailValidator = new EmailValidator(); diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/ChaseQuickPayForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/ChaseQuickPayForm.java index 291358e60bd..4160481b501 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/ChaseQuickPayForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/ChaseQuickPayForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.ChaseQuickPayValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.ChaseQuickPayAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.ChaseQuickPayAccountPayload; @@ -52,9 +53,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public ChaseQuickPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, ChaseQuickPayValidator chaseQuickPayValidator, + public ChaseQuickPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, ChaseQuickPayValidator chaseQuickPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.chaseQuickPayAccount = (ChaseQuickPayAccount) paymentAccount; this.chaseQuickPayValidator = chaseQuickPayValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/ClearXchangeForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/ClearXchangeForm.java index 9ecde3e17e2..a867c02cadd 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/ClearXchangeForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/ClearXchangeForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.ClearXchangeValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.ClearXchangeAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.ClearXchangeAccountPayload; @@ -52,8 +53,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public ClearXchangeForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, ClearXchangeValidator clearXchangeValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public ClearXchangeForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, ClearXchangeValidator clearXchangeValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.clearXchangeAccount = (ClearXchangeAccount) paymentAccount; this.clearXchangeValidator = clearXchangeValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/F2FForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/F2FForm.java index 5ead5ebc66d..585678e2d27 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/F2FForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/F2FForm.java @@ -23,6 +23,8 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.F2FValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; import bisq.core.locale.CurrencyUtil; @@ -30,7 +32,6 @@ import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.CountryBasedPaymentAccount; import bisq.core.payment.F2FAccount; import bisq.core.payment.PaymentAccount; @@ -73,9 +74,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, } public F2FForm(PaymentAccount paymentAccount, - AccountAgeWitnessService accountAgeWitnessService, F2FValidator f2fValidator, + AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, F2FValidator f2fValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.f2fAccount = (F2FAccount) paymentAccount; this.f2fValidator = f2fValidator; diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/FasterPaymentsForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/FasterPaymentsForm.java index cdeb6aaceb5..88faf425a8a 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/FasterPaymentsForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/FasterPaymentsForm.java @@ -23,9 +23,10 @@ import bisq.desktop.util.validation.AccountNrValidator; import bisq.desktop.util.validation.BranchIdValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.FasterPaymentsAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.FasterPaymentsAccountPayload; @@ -57,9 +58,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, private InputTextField accountNrInputTextField; private InputTextField sortCodeInputTextField; - public FasterPaymentsForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, GridPane gridPane, + public FasterPaymentsForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.fasterPaymentsAccount = (FasterPaymentsAccount) paymentAccount; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralAccountNumberForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralAccountNumberForm.java index b32d0704b31..1aab7251e13 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralAccountNumberForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralAccountNumberForm.java @@ -3,9 +3,10 @@ import bisq.desktop.components.InputTextField; import bisq.desktop.util.Layout; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentMethod; import bisq.core.util.BSFormatter; @@ -22,8 +23,8 @@ abstract public class GeneralAccountNumberForm extends PaymentMethodForm { private InputTextField accountNrInputTextField; - GeneralAccountNumberForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + GeneralAccountNumberForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); } @Override diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralBankForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralBankForm.java index 2e3935d85b7..381cda079b5 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralBankForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralBankForm.java @@ -6,9 +6,10 @@ import bisq.desktop.util.validation.BranchIdValidator; import bisq.desktop.util.validation.NationalAccountIdValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.BankUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.CountryBasedPaymentAccountPayload; import bisq.core.util.BSFormatter; @@ -38,8 +39,8 @@ public abstract class GeneralBankForm extends PaymentMethodForm { boolean accountNrInputTextFieldEdited; - public GeneralBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public GeneralBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); } static int getIndexOfColumn(int colIndex) { diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralSepaForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralSepaForm.java index d6c1d2013e2..1275150c9d0 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralSepaForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/GeneralSepaForm.java @@ -3,11 +3,12 @@ import bisq.desktop.components.InputTextField; import bisq.desktop.util.FormBuilder; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Country; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.CountryBasedPaymentAccount; import bisq.core.payment.PaymentAccount; import bisq.core.util.BSFormatter; @@ -45,8 +46,8 @@ public abstract class GeneralSepaForm extends PaymentMethodForm { private ComboBox currencyComboBox; InputTextField ibanInputTextField; - GeneralSepaForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + GeneralSepaForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); } @Override diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/HalCashForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/HalCashForm.java index 1fb08de78ce..d9e43f640ef 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/HalCashForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/HalCashForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.HalCashValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.HalCashAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.HalCashAccountPayload; @@ -50,9 +51,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public HalCashForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, HalCashValidator halCashValidator, + public HalCashForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, HalCashValidator halCashValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.halCashAccount = (HalCashAccount) paymentAccount; this.halCashValidator = halCashValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/InteracETransferForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/InteracETransferForm.java index ffe20fccb4d..27cd98319b6 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/InteracETransferForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/InteracETransferForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.InteracETransferValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.InteracETransferAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.InteracETransferAccountPayload; @@ -56,9 +57,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public InteracETransferForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InteracETransferValidator interacETransferValidator, + public InteracETransferForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InteracETransferValidator interacETransferValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.interacETransferAccount = (InteracETransferAccount) paymentAccount; this.interacETransferValidator = interacETransferValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyBeamForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyBeamForm.java index 39e741f2bc5..e1e0931f852 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyBeamForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyBeamForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.MoneyBeamValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.MoneyBeamAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.MoneyBeamAccountPayload; @@ -49,8 +50,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public MoneyBeamForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, MoneyBeamValidator moneyBeamValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public MoneyBeamForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, MoneyBeamValidator moneyBeamValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.account = (MoneyBeamAccount) paymentAccount; this.validator = moneyBeamValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java index a6b1b67352a..d950354b48d 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java @@ -22,12 +22,13 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.EmailValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.BankUtil; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.MoneyGramAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.MoneyGramAccountPayload; @@ -73,9 +74,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, private InputTextField stateInputTextField; private final EmailValidator emailValidator; - public MoneyGramForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + public MoneyGramForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.moneyGramAccountPayload = (MoneyGramAccountPayload) paymentAccount.paymentAccountPayload; emailValidator = new EmailValidator(); diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/NationalBankForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/NationalBankForm.java index ec2edc7e584..bcbc7bf2c45 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/NationalBankForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/NationalBankForm.java @@ -17,7 +17,8 @@ package bisq.desktop.components.paymentmethods; -import bisq.core.payment.AccountAgeWitnessService; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.util.BSFormatter; @@ -30,8 +31,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload); } - public NationalBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + public NationalBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); } } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java index 61d965a7084..0f1e3ea0d44 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java @@ -24,13 +24,14 @@ import bisq.desktop.util.FormBuilder; import bisq.desktop.util.Layout; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Country; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.AssetAccount; import bisq.core.payment.PaymentAccount; import bisq.core.util.BSFormatter; @@ -69,6 +70,7 @@ public abstract class PaymentMethodForm { protected final PaymentAccount paymentAccount; private final AccountAgeWitnessService accountAgeWitnessService; + private final AccountScoreService accountScoreService; protected final InputValidator inputValidator; protected final GridPane gridPane; protected int gridRow; @@ -80,10 +82,16 @@ public abstract class PaymentMethodForm { ToggleButton useCustomAccountNameToggleButton; protected ComboBox currencyComboBox; - public PaymentMethodForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, - InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + public PaymentMethodForm(PaymentAccount paymentAccount, + AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, + InputValidator inputValidator, + GridPane gridPane, + int gridRow, + BSFormatter formatter) { this.paymentAccount = paymentAccount; this.accountAgeWitnessService = accountAgeWitnessService; + this.accountScoreService = accountScoreService; this.inputValidator = inputValidator; this.gridPane = gridPane; this.gridRow = gridRow; @@ -159,6 +167,7 @@ protected void addLimitations(boolean isDisplayForm) { long hours = paymentAccount.getMaxTradePeriod() / 3600_000; final TradeCurrency tradeCurrency; + boolean isAltcoin = paymentAccount instanceof AssetAccount; if (paymentAccount.getSingleTradeCurrency() != null) tradeCurrency = paymentAccount.getSingleTradeCurrency(); else if (paymentAccount.getSelectedTradeCurrency() != null) @@ -166,29 +175,31 @@ else if (paymentAccount.getSelectedTradeCurrency() != null) else if (!paymentAccount.getTradeCurrencies().isEmpty()) tradeCurrency = paymentAccount.getTradeCurrencies().get(0); else - tradeCurrency = paymentAccount instanceof AssetAccount ? + tradeCurrency = isAltcoin ? CurrencyUtil.getAllSortedCryptoCurrencies().get(0) : CurrencyUtil.getDefaultTradeCurrency(); + boolean isAddAccountScreen = paymentAccount.getAccountName() == null; + String tradeLimit = formatter.formatCoinWithCode(Coin.valueOf(accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrency.getCode()))); + String limitationsText = Res.get("payment.maxPeriodAndTradeLimits", getTimeText(hours), tradeLimit); + String accountAgeText = ""; + if (!isAltcoin) { + String requiredAccountAge = formatter.formatAccountAge(accountScoreService.getRequiredAccountAge(paymentAccount.getPaymentMethod())); + long accountAge = !isAddAccountScreen ? accountAgeWitnessService.getMyAccountAge(paymentAccount.getPaymentAccountPayload()) : 0L; + accountAgeText = Res.get("payment.accountAge", formatter.formatAccountAge(accountAge), requiredAccountAge); + } - final boolean isAddAccountScreen = paymentAccount.getAccountName() == null; - final long accountAge = !isAddAccountScreen ? accountAgeWitnessService.getMyAccountAge(paymentAccount.getPaymentAccountPayload()) : 0L; - - final String limitationsText = paymentAccount instanceof AssetAccount ? - Res.get("payment.maxPeriodAndLimitCrypto", - getTimeText(hours), - formatter.formatCoinWithCode(Coin.valueOf(accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrency.getCode())))) - : - Res.get("payment.maxPeriodAndLimit", - getTimeText(hours), - formatter.formatCoinWithCode(Coin.valueOf(accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrency.getCode()))), - formatter.formatAccountAge(accountAge)); - - if (isDisplayForm) + if (isDisplayForm) { addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.limitations"), limitationsText); - else + if (!isAltcoin) { + addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.accountAgeTitle"), accountAgeText); + } + } else { addTopLabelTextField(gridPane, ++gridRow, Res.get("payment.limitations"), limitationsText); - + if (!isAltcoin) { + addTopLabelTextField(gridPane, ++gridRow, Res.get("payment.accountAgeTitle"), accountAgeText); + } + } if (isAddAccountScreen) { InputTextField inputTextField = addInputTextField(gridPane, ++gridRow, Res.get("payment.salt"), 0); inputTextField.setText(Utilities.bytesAsHexString(paymentAccount.getPaymentAccountPayload().getSalt())); diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PerfectMoneyForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PerfectMoneyForm.java index dfb799201ce..c0807bc31e6 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PerfectMoneyForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PerfectMoneyForm.java @@ -19,9 +19,10 @@ import bisq.desktop.util.validation.PerfectMoneyValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PerfectMoneyAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -44,9 +45,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public PerfectMoneyForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, PerfectMoneyValidator perfectMoneyValidator, InputValidator inputValidator, GridPane gridPane, int + public PerfectMoneyForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, PerfectMoneyValidator perfectMoneyValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.perfectMoneyAccount = (PerfectMoneyAccount) paymentAccount; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PopmoneyForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PopmoneyForm.java index a5c629e91ac..58317673899 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PopmoneyForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PopmoneyForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.PopmoneyValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PopmoneyAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -51,8 +52,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public PopmoneyForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, PopmoneyValidator popmoneyValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public PopmoneyForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, PopmoneyValidator popmoneyValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.account = (PopmoneyAccount) paymentAccount; this.validator = popmoneyValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PromptPayForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PromptPayForm.java index 7ddeb92d145..63f6d2db57f 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PromptPayForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PromptPayForm.java @@ -21,9 +21,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.PromptPayValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PromptPayAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -50,9 +51,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public PromptPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, PromptPayValidator promptPayValidator, - InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public PromptPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, PromptPayValidator promptPayValidator, + InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.promptPayAccount = (PromptPayAccount) paymentAccount; this.promptPayValidator = promptPayValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/RevolutForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/RevolutForm.java index e01833c5e43..6e4d49d1a2e 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/RevolutForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/RevolutForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.RevolutValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.RevolutAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -63,9 +64,10 @@ private static String getTitle(String accountId) { } public RevolutForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, RevolutValidator revolutValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.account = (RevolutAccount) paymentAccount; this.validator = revolutValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SameBankForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SameBankForm.java index a6ca52f80b5..6e66a6e8222 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SameBankForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SameBankForm.java @@ -17,7 +17,8 @@ package bisq.desktop.components.paymentmethods; -import bisq.core.payment.AccountAgeWitnessService; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.util.BSFormatter; @@ -31,8 +32,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload); } - public SameBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + public SameBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); } } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaForm.java index 3ebad03ad08..ed236c2e61e 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaForm.java @@ -23,12 +23,13 @@ import bisq.desktop.util.validation.BICValidator; import bisq.desktop.util.validation.IBANValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.SepaAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -73,10 +74,10 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, private final IBANValidator ibanValidator; private final BICValidator bicValidator; - public SepaForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, IBANValidator ibanValidator, + public SepaForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, IBANValidator ibanValidator, BICValidator bicValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.sepaAccount = (SepaAccount) paymentAccount; this.ibanValidator = ibanValidator; this.bicValidator = bicValidator; diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaInstantForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaInstantForm.java index 545a1618892..8f52062dc09 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaInstantForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SepaInstantForm.java @@ -23,12 +23,13 @@ import bisq.desktop.util.validation.BICValidator; import bisq.desktop.util.validation.IBANValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.SepaInstantAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -73,10 +74,10 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, private final IBANValidator ibanValidator; private final BICValidator bicValidator; - public SepaInstantForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, IBANValidator ibanValidator, + public SepaInstantForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, IBANValidator ibanValidator, BICValidator bicValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.sepaInstantAccount = (SepaInstantAccount) paymentAccount; this.ibanValidator = ibanValidator; this.bicValidator = bicValidator; diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SpecificBankForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SpecificBankForm.java index 1f0e6fd377a..ed1f233455a 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SpecificBankForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SpecificBankForm.java @@ -19,8 +19,9 @@ import bisq.desktop.components.InputTextField; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.payload.SpecificBanksAccountPayload; @@ -52,9 +53,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload); } - public SpecificBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + public SpecificBankForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.specificBanksAccountPayload = (SpecificBanksAccountPayload) paymentAccount.paymentAccountPayload; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SwishForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SwishForm.java index 4258f6214c1..51313113a57 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SwishForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SwishForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.SwishValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.SwishAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -58,9 +59,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public SwishForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, SwishValidator swishValidator, + public SwishForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, SwishValidator swishValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.swishAccount = (SwishAccount) paymentAccount; this.swishValidator = swishValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/USPostalMoneyOrderForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/USPostalMoneyOrderForm.java index 0aa70c70492..e47bda48d19 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/USPostalMoneyOrderForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/USPostalMoneyOrderForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.USPostalMoneyOrderValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.USPostalMoneyOrderAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -55,9 +56,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, } public USPostalMoneyOrderForm(PaymentAccount paymentAccount, - AccountAgeWitnessService accountAgeWitnessService, USPostalMoneyOrderValidator usPostalMoneyOrderValidator, + AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, USPostalMoneyOrderValidator usPostalMoneyOrderValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.usPostalMoneyOrderAccount = (USPostalMoneyOrderAccount) paymentAccount; this.usPostalMoneyOrderValidator = usPostalMoneyOrderValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/UpholdForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/UpholdForm.java index 2ee6dae511f..3a6e20353f1 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/UpholdForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/UpholdForm.java @@ -22,9 +22,10 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.UpholdValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.UpholdAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -52,10 +53,15 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, return gridRow; } - public UpholdForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, - UpholdValidator upholdValidator, InputValidator inputValidator, GridPane gridPane, - int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public UpholdForm(PaymentAccount paymentAccount, + AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, + UpholdValidator upholdValidator, + InputValidator inputValidator, + GridPane gridPane, + int gridRow, + BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.upholdAccount = (UpholdAccount) paymentAccount; this.upholdValidator = upholdValidator; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/WeChatPayForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/WeChatPayForm.java index 7292f2eeb26..7e4dfe59fb9 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/WeChatPayForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/WeChatPayForm.java @@ -19,8 +19,9 @@ import bisq.desktop.util.validation.WeChatPayValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.WeChatPayAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -41,8 +42,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccount return gridRow; } - public WeChatPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, WeChatPayValidator weChatPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + public WeChatPayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, WeChatPayValidator weChatPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.weChatPayAccount = (WeChatPayAccount) paymentAccount; } diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/WesternUnionForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/WesternUnionForm.java index 9470cd2b2c5..e97baea0012 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/WesternUnionForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/WesternUnionForm.java @@ -23,13 +23,14 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.EmailValidator; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.BankUtil; import bisq.core.locale.Country; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.CountryBasedPaymentAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; @@ -75,9 +76,9 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, private final EmailValidator emailValidator; private Country selectedCountry; - public WesternUnionForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator, + public WesternUnionForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, AccountScoreService accountScoreService, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { - super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + super(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, gridPane, gridRow, formatter); this.westernUnionAccountPayload = (WesternUnionAccountPayload) paymentAccount.paymentAccountPayload; emailValidator = new EmailValidator(); diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index 11b85f60cb5..66b98bb0b1a 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -34,6 +34,7 @@ import bisq.desktop.main.presentation.MarketPricePresentation; import bisq.desktop.util.GUIUtil; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; import bisq.core.app.AppOptionKeys; import bisq.core.app.BisqEnvironment; @@ -42,7 +43,6 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.AliPayAccount; import bisq.core.payment.CryptoCurrencyAccount; import bisq.core.presentation.BalancePresentation; @@ -223,13 +223,15 @@ public void onSetupComplete() { } break; case TRADE_PERIOD_OVER: - key = "displayTradePeriodOver" + trade.getId(); - if (DontShowAgainLookup.showAgain(key)) { - DontShowAgainLookup.dontShowAgain(key, true); - new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", - trade.getShortId(), - formatter.formatDateTime(maxTradePeriodDate))) - .show(); + if (!tradeManager.requirePayoutDelay(trade)) { + key = "displayTradePeriodOver" + trade.getId(); + if (DontShowAgainLookup.showAgain(key)) { + DontShowAgainLookup.dontShowAgain(key, true); + new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", + trade.getShortId(), + formatter.formatDateTime(maxTradePeriodDate))) + .show(); + } } break; } diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java index 11fbec3a87b..b37aa50d3ad 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java @@ -20,11 +20,11 @@ import bisq.desktop.common.model.ActivatableDataModel; import bisq.desktop.util.GUIUtil; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CryptoCurrency; import bisq.core.locale.FiatCurrency; import bisq.core.locale.TradeCurrency; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.AssetAccount; import bisq.core.payment.PaymentAccount; import bisq.core.trade.TradeManager; diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java index 0ca30300bcf..6aac0ab47e6 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java @@ -26,13 +26,14 @@ import bisq.desktop.util.FormBuilder; import bisq.desktop.util.Layout; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.dao.governance.asset.AssetService; import bisq.core.filter.FilterManager; import bisq.core.locale.CryptoCurrency; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountFactory; import bisq.core.payment.payload.PaymentMethod; @@ -73,6 +74,7 @@ public class AltCoinAccountsView extends PaymentAccountsView paymentMethodComboBox; private PaymentMethodForm paymentMethodForm; @@ -167,6 +169,7 @@ public FiatAccountsView(FiatAccountsViewModel model, PromptPayValidator promptPayValidator, AdvancedCashValidator advancedCashValidator, AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, BSFormatter formatter) { super(model); @@ -190,6 +193,7 @@ public FiatAccountsView(FiatAccountsViewModel model, this.promptPayValidator = promptPayValidator; this.advancedCashValidator = advancedCashValidator; this.accountAgeWitnessService = accountAgeWitnessService; + this.accountScoreService = accountScoreService; this.formatter = formatter; } @@ -233,10 +237,13 @@ private void onSaveNewAccount(PaymentAccount paymentAccount) { .onAction(() -> doSaveNewAccount(paymentAccount)) .show(); } else { - new Popup<>().information(Res.get("payment.limits.info", + String requiredAccountAge = formatter.formatAccountAge(accountScoreService.getRequiredAccountAge(paymentAccount.getPaymentMethod())); + String text = Res.get("payment.limits.info", formatter.formatCoinWithCode(maxTradeLimitFirstMonth), formatter.formatCoinWithCode(maxTradeLimitSecondMonth), - formatter.formatCoinWithCode(maxTradeLimitAsCoin))) + formatter.formatCoinWithCode(maxTradeLimitAsCoin), + requiredAccountAge); + new Popup<>().information(text) .width(700) .closeButtonText(Res.get("shared.cancel")) .actionButtonText(Res.get("shared.iUnderstand")) @@ -415,55 +422,55 @@ private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod) { private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod, PaymentAccount paymentAccount) { switch (paymentMethod.getId()) { case PaymentMethod.UPHOLD_ID: - return new UpholdForm(paymentAccount, accountAgeWitnessService, upholdValidator, inputValidator, root, gridRow, formatter); + return new UpholdForm(paymentAccount, accountAgeWitnessService, accountScoreService, upholdValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.MONEY_BEAM_ID: - return new MoneyBeamForm(paymentAccount, accountAgeWitnessService, moneyBeamValidator, inputValidator, root, gridRow, formatter); + return new MoneyBeamForm(paymentAccount, accountAgeWitnessService, accountScoreService, moneyBeamValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.POPMONEY_ID: - return new PopmoneyForm(paymentAccount, accountAgeWitnessService, popmoneyValidator, inputValidator, root, gridRow, formatter); + return new PopmoneyForm(paymentAccount, accountAgeWitnessService, accountScoreService, popmoneyValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.REVOLUT_ID: - return new RevolutForm(paymentAccount, accountAgeWitnessService, revolutValidator, inputValidator, root, gridRow, formatter); + return new RevolutForm(paymentAccount, accountAgeWitnessService, accountScoreService, revolutValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.PERFECT_MONEY_ID: - return new PerfectMoneyForm(paymentAccount, accountAgeWitnessService, perfectMoneyValidator, inputValidator, root, gridRow, formatter); + return new PerfectMoneyForm(paymentAccount, accountAgeWitnessService, accountScoreService, perfectMoneyValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.SEPA_ID: - return new SepaForm(paymentAccount, accountAgeWitnessService, ibanValidator, bicValidator, inputValidator, root, gridRow, formatter); + return new SepaForm(paymentAccount, accountAgeWitnessService, accountScoreService, ibanValidator, bicValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.SEPA_INSTANT_ID: - return new SepaInstantForm(paymentAccount, accountAgeWitnessService, ibanValidator, bicValidator, inputValidator, root, gridRow, formatter); + return new SepaInstantForm(paymentAccount, accountAgeWitnessService, accountScoreService, ibanValidator, bicValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.FASTER_PAYMENTS_ID: - return new FasterPaymentsForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new FasterPaymentsForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.NATIONAL_BANK_ID: - return new NationalBankForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new NationalBankForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.SAME_BANK_ID: - return new SameBankForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new SameBankForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.SPECIFIC_BANKS_ID: - return new SpecificBankForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new SpecificBankForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.ALI_PAY_ID: - return new AliPayForm(paymentAccount, accountAgeWitnessService, aliPayValidator, inputValidator, root, gridRow, formatter); + return new AliPayForm(paymentAccount, accountAgeWitnessService, accountScoreService, aliPayValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.WECHAT_PAY_ID: - return new WeChatPayForm(paymentAccount, accountAgeWitnessService, weChatPayValidator, inputValidator, root, gridRow, formatter); + return new WeChatPayForm(paymentAccount, accountAgeWitnessService, accountScoreService, weChatPayValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.SWISH_ID: - return new SwishForm(paymentAccount, accountAgeWitnessService, swishValidator, inputValidator, root, gridRow, formatter); + return new SwishForm(paymentAccount, accountAgeWitnessService, accountScoreService, swishValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.CLEAR_X_CHANGE_ID: - return new ClearXchangeForm(paymentAccount, accountAgeWitnessService, clearXchangeValidator, inputValidator, root, gridRow, formatter); + return new ClearXchangeForm(paymentAccount, accountAgeWitnessService, accountScoreService, clearXchangeValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.CHASE_QUICK_PAY_ID: - return new ChaseQuickPayForm(paymentAccount, accountAgeWitnessService, chaseQuickPayValidator, inputValidator, root, gridRow, formatter); + return new ChaseQuickPayForm(paymentAccount, accountAgeWitnessService, accountScoreService, chaseQuickPayValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.INTERAC_E_TRANSFER_ID: - return new InteracETransferForm(paymentAccount, accountAgeWitnessService, interacETransferValidator, inputValidator, root, gridRow, formatter); + return new InteracETransferForm(paymentAccount, accountAgeWitnessService, accountScoreService, interacETransferValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.US_POSTAL_MONEY_ORDER_ID: - return new USPostalMoneyOrderForm(paymentAccount, accountAgeWitnessService, usPostalMoneyOrderValidator, inputValidator, root, gridRow, formatter); + return new USPostalMoneyOrderForm(paymentAccount, accountAgeWitnessService, accountScoreService, usPostalMoneyOrderValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.MONEY_GRAM_ID: - return new MoneyGramForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new MoneyGramForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.WESTERN_UNION_ID: - return new WesternUnionForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new WesternUnionForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.CASH_DEPOSIT_ID: - return new CashDepositForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + return new CashDepositForm(paymentAccount, accountAgeWitnessService, accountScoreService, inputValidator, root, gridRow, formatter); case PaymentMethod.HAL_CASH_ID: - return new HalCashForm(paymentAccount, accountAgeWitnessService, halCashValidator, inputValidator, root, gridRow, formatter); + return new HalCashForm(paymentAccount, accountAgeWitnessService, accountScoreService, halCashValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.F2F_ID: - return new F2FForm(paymentAccount, accountAgeWitnessService, f2FValidator, inputValidator, root, gridRow, formatter); + return new F2FForm(paymentAccount, accountAgeWitnessService, accountScoreService, f2FValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.PROMPT_PAY_ID: - return new PromptPayForm(paymentAccount, accountAgeWitnessService, promptPayValidator, inputValidator, root, gridRow, formatter); + return new PromptPayForm(paymentAccount, accountAgeWitnessService, accountScoreService, promptPayValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.ADVANCED_CASH_ID: - return new AdvancedCashForm(paymentAccount, accountAgeWitnessService, advancedCashValidator, inputValidator, root, gridRow, formatter); + return new AdvancedCashForm(paymentAccount, accountAgeWitnessService, accountScoreService, advancedCashValidator, inputValidator, root, gridRow, formatter); default: log.error("Not supported PaymentMethod: " + paymentMethod); return null; diff --git a/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java b/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java index c7f8ecb340a..f21f53fa395 100644 --- a/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java +++ b/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java @@ -23,10 +23,10 @@ import bisq.desktop.main.overlays.windows.DisputeSummaryWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; import bisq.core.app.AppOptionKeys; import bisq.core.arbitration.DisputeManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.TradeManager; import bisq.core.util.BSFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java b/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java index 753c7956384..9f1b4d5a84b 100644 --- a/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java +++ b/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java @@ -35,6 +35,7 @@ import bisq.desktop.main.overlays.windows.TradeDetailsWindow; import bisq.desktop.util.GUIUtil; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; import bisq.core.app.AppOptionKeys; import bisq.core.arbitration.Attachment; @@ -43,7 +44,6 @@ import bisq.core.arbitration.messages.DisputeCommunicationMessage; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.Contract; import bisq.core.trade.Trade; import bisq.core.trade.TradeManager; diff --git a/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java b/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java index 397b3746414..74220d84f4a 100644 --- a/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java @@ -28,13 +28,13 @@ import bisq.desktop.util.CurrencyListItem; import bisq.desktop.util.GUIUtil; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.GlobalSettings; import bisq.core.locale.TradeCurrency; import bisq.core.monetary.Price; import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.provider.price.PriceFeedService; import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; 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 b153cda451f..96fba23de97 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java @@ -17,6 +17,8 @@ package bisq.desktop.main.offer; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.Arbitrator; import bisq.core.btc.TxFeeEstimationService; import bisq.core.btc.listeners.BalanceListener; @@ -35,7 +37,6 @@ import bisq.core.offer.OfferPayload; import bisq.core.offer.OfferUtil; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.HalCashAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountUtil; @@ -101,6 +102,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs final String shortOfferId; private final FilterManager filterManager; private final AccountAgeWitnessService accountAgeWitnessService; + private final AccountScoreService accountScoreService; private final FeeService feeService; private final TxFeeEstimationService txFeeEstimationService; private final ReferralIdService referralIdService; @@ -153,6 +155,7 @@ public MutableOfferDataModel(OpenOfferManager openOfferManager, PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, FeeService feeService, TxFeeEstimationService txFeeEstimationService, ReferralIdService referralIdService, @@ -168,6 +171,7 @@ public MutableOfferDataModel(OpenOfferManager openOfferManager, this.priceFeedService = priceFeedService; this.filterManager = filterManager; this.accountAgeWitnessService = accountAgeWitnessService; + this.accountScoreService = accountScoreService; this.feeService = feeService; this.txFeeEstimationService = txFeeEstimationService; this.referralIdService = referralIdService; @@ -828,4 +832,20 @@ public boolean isBsqForFeeAvailable() { public boolean isHalCashAccount() { return paymentAccount instanceof HalCashAccount; } + + long getMyAccountAge() { + return accountAgeWitnessService.getMyAccountAge(paymentAccount.getPaymentAccountPayload()); + } + + long getRequiredAccountAge() { + return accountScoreService.getRequiredAccountAge(paymentAccount.getPaymentMethod()); + } + + long getDelay() { + return accountScoreService.getDelayForMyOffer(paymentAccount, tradeCurrencyCode.get(), getDirection()); + } + + boolean myAccountRequiresPayoutDelay() { + return accountScoreService.myMakerAccountRequiresPayoutDelay(paymentAccount, tradeCurrencyCode.get(), getDirection()); + } } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferView.java index 75770ae7bdd..2c474098af9 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferView.java @@ -344,15 +344,6 @@ public void setCloseHandler(OfferView.CloseHandler closeHandler) { // UI actions /////////////////////////////////////////////////////////////////////////////////////////// - protected void showFiatRoundingInfoPopup() { - if (CurrencyUtil.isFiatCurrency(model.tradeCurrencyCode.get()) && !DevEnv.isDevMode()) { - new Popup<>().headLine(Res.get("popup.roundedFiatValues.headline")) - .information(Res.get("popup.roundedFiatValues.msg", model.tradeCurrencyCode.get())) - .dontShowAgainId("FiatValuesRoundedWarning") - .show(); - } - } - private void onPlaceOffer() { if (model.isReadyForTxBroadcast()) { if (model.getDataModel().isMakerFeeValid()) { @@ -477,6 +468,19 @@ private void onShowPayFundsScreen() { .toByteArray(); Image qrImage = new Image(new ByteArrayInputStream(imageBytes)); qrCodeImageView.setImage(qrImage); + + String key = "immatureBuyerAccountAgeCreateOffer"; + if (preferences.showAgain(key) && !DevEnv.isDevMode()) { + if (model.getDataModel().myAccountRequiresPayoutDelay()) { + String myAccountAge = btcFormatter.formatAccountAge(model.getDataModel().getMyAccountAge()); + String requiredAccountAge = btcFormatter.formatAccountAge(model.getDataModel().getRequiredAccountAge()); + String delay = btcFormatter.formatAccountAge(model.getDataModel().getDelay()); + new Popup().information(Res.get("popup.immatureBuyerAccountAge.createOffer.msg", + myAccountAge, requiredAccountAge, delay)) + .dontShowAgainId(key) + .show(); + } + } } private void updateOfferElementsStyle() { @@ -534,8 +538,6 @@ protected void onPaymentAccountsComboBoxSelected() { model.onPaymentAccountSelected(paymentAccount); model.onCurrencySelected(model.getDataModel().getTradeCurrency()); } - - showFiatRoundingInfoPopup(); } else { currencySelection.setVisible(false); currencySelection.setManaged(false); 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 21286166366..66a9be884ba 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 @@ -23,12 +23,13 @@ import bisq.desktop.main.offer.MutableOfferDataModel; +import bisq.core.account.score.AccountScoreService; +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.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.provider.fee.FeeService; import bisq.core.provider.price.PriceFeedService; import bisq.core.trade.statistics.ReferralIdService; @@ -60,6 +61,7 @@ public CreateOfferDataModel(OpenOfferManager openOfferManager, PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, FeeService feeService, TxFeeEstimationService txFeeEstimationService, ReferralIdService referralIdService, @@ -74,6 +76,7 @@ public CreateOfferDataModel(OpenOfferManager openOfferManager, priceFeedService, filterManager, accountAgeWitnessService, + accountScoreService, feeService, txFeeEstimationService, referralIdService, diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java index ab533aa6785..db74a35eca4 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java @@ -40,6 +40,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; import bisq.core.app.AppOptionKeys; import bisq.core.locale.CurrencyUtil; @@ -115,6 +117,8 @@ public class OfferBookView extends ActivatableViewAndModel currencyComboBox; @@ -141,6 +145,8 @@ public class OfferBookView extends ActivatableViewAndModel().confirmation(Res.get("popup.info.cashDepositInfo", offer.getBankId())) - .actionButtonText(Res.get("popup.info.cashDepositInfo.confirm")) - .onAction(() -> offerActionHandler.onTakeOffer(offer)) - .show(); - } else { - offerActionHandler.onTakeOffer(offer); - } - } else { + if (!model.isBootstrapped()) { new Popup<>().information(Res.get("popup.warning.notFullyConnected")).show(); + return; + } + + if (offer.getDirection() == OfferPayload.Direction.SELL && + offer.getPaymentMethod().getId().equals(PaymentMethod.CASH_DEPOSIT.getId())) { + new Popup<>().confirmation(Res.get("popup.info.cashDepositInfo", offer.getBankId())) + .actionButtonText(Res.get("popup.info.cashDepositInfo.confirm")) + .onAction(() -> offerActionHandler.onTakeOffer(offer)) + .show(); + return; + } + + if (accountScoreService.offerRequirePayoutDelay(offer)) { + String requiredAccountAge = formatter.formatAccountAge(accountScoreService.getRequiredAccountAge(offer.getPaymentMethod())); + String makersAccountAge = formatter.formatAccountAge(accountAgeWitnessService.getMakersAccountAge(offer)); + String delay = formatter.formatAccountAge(accountScoreService.getDelayForOffer(offer)); + new Popup<>().confirmation(Res.get("offerbook.warning.buyerHasImmatureAccount", + makersAccountAge, + requiredAccountAge, + delay)) + .actionButtonText(Res.get("offerbook.warning.buyerHasImmatureAccount.confirm")) + .onAction(() -> offerActionHandler.onTakeOffer(offer)) + .closeButtonText(Res.get("shared.cancel")) + .show(); + return; } + + offerActionHandler.onTakeOffer(offer); } private void onRemoveOpenOffer(Offer offer) { diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index e20ab3d03df..3a0810eedb0 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -24,6 +24,7 @@ import bisq.desktop.main.settings.preferences.PreferencesView; import bisq.desktop.util.GUIUtil; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.filter.FilterManager; import bisq.core.locale.BankUtil; import bisq.core.locale.CountryUtil; @@ -37,7 +38,6 @@ import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountUtil; import bisq.core.payment.payload.PaymentMethod; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java index 46f776a6727..7345322bba1 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java @@ -20,6 +20,7 @@ import bisq.desktop.main.offer.OfferDataModel; import bisq.desktop.main.overlays.popups.Popup; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.Arbitrator; import bisq.core.btc.TxFeeEstimationService; import bisq.core.btc.listeners.BalanceListener; @@ -35,7 +36,6 @@ import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; import bisq.core.offer.OfferUtil; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.HalCashAccount; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountUtil; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java index f7a4c75c496..f93f0396cff 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java @@ -306,13 +306,6 @@ protected void activate() { showNextStepAfterAmountIsSet(); } - if (CurrencyUtil.isFiatCurrency(model.getOffer().getCurrencyCode()) && !DevEnv.isDevMode()) { - new Popup<>().headLine(Res.get("popup.roundedFiatValues.headline")) - .information(Res.get("popup.roundedFiatValues.msg", model.getOffer().getCurrencyCode())) - .dontShowAgainId("FiatValuesRoundedWarning") - .show(); - } - boolean currencyForMakerFeeBtc = model.dataModel.isCurrencyForTakerFeeBtc(); tradeFeeInBtcToggle.setSelected(currencyForMakerFeeBtc); tradeFeeInBsqToggle.setSelected(!currencyForMakerFeeBtc); diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java index 123901a6cf5..8fdf15225db 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java @@ -22,13 +22,13 @@ import bisq.desktop.main.overlays.Overlay; import bisq.desktop.util.Layout; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.Dispute; import bisq.core.arbitration.DisputeManager; import bisq.core.locale.CountryUtil; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.payload.PaymentMethod; import bisq.core.trade.Contract; diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java index d76732e8dae..6c3d94152da 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java @@ -23,11 +23,11 @@ import bisq.desktop.main.overlays.Overlay; import bisq.desktop.util.Layout; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.DisputeManager; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.trade.Contract; import bisq.core.trade.Trade; diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java index d6865f836a2..a54848066d4 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java @@ -20,9 +20,9 @@ import bisq.desktop.common.model.ActivatableWithDataModel; import bisq.desktop.common.model.ViewModel; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.offer.OpenOffer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.Tradable; import bisq.core.trade.Trade; import bisq.core.util.BSFormatter; 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 c28fda0f218..4e14ce10310 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 @@ -20,6 +20,8 @@ import bisq.desktop.main.offer.MutableOfferDataModel; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.btc.TxFeeEstimationService; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; @@ -30,7 +32,6 @@ import bisq.core.offer.OfferPayload; import bisq.core.offer.OpenOffer; import bisq.core.offer.OpenOfferManager; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.proto.persistable.CorePersistenceProtoResolver; import bisq.core.provider.fee.FeeService; @@ -68,6 +69,7 @@ class EditOfferDataModel extends MutableOfferDataModel { PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, FeeService feeService, TxFeeEstimationService txFeeEstimationService, ReferralIdService referralIdService, @@ -83,6 +85,7 @@ class EditOfferDataModel extends MutableOfferDataModel { priceFeedService, filterManager, accountAgeWitnessService, + accountScoreService, feeService, txFeeEstimationService, referralIdService, diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferView.java index 8d253569c8c..d3667713a36 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferView.java @@ -130,10 +130,6 @@ protected void deactivate() { removeBindings(); } - @Override - protected void showFiatRoundingInfoPopup() { - // don't show it again as it was already shown when creating the offer in the first place - } /////////////////////////////////////////////////////////////////////////////////////////// // API diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java index d487aa0e5f0..0b21e9a1f9c 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java @@ -27,6 +27,8 @@ import bisq.desktop.main.overlays.windows.WalletPasswordWindow; import bisq.desktop.util.GUIUtil; +import bisq.core.account.score.AccountScoreService; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.Dispute; import bisq.core.arbitration.DisputeAlreadyOpenException; import bisq.core.arbitration.DisputeManager; @@ -37,10 +39,12 @@ import bisq.core.offer.OfferPayload; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.trade.BuyerTrade; +import bisq.core.trade.Contract; import bisq.core.trade.SellerTrade; import bisq.core.trade.Trade; import bisq.core.trade.TradeManager; import bisq.core.user.Preferences; +import bisq.core.util.BSFormatter; import bisq.network.p2p.P2PService; @@ -86,6 +90,9 @@ public class PendingTradesDataModel extends ActivatableDataModel { public final Navigation navigation; public final WalletPasswordWindow walletPasswordWindow; private final NotificationCenter notificationCenter; + private final AccountAgeWitnessService accountAgeWitnessService; + private final AccountScoreService accountScoreService; + private final BSFormatter formatter; final ObservableList list = FXCollections.observableArrayList(); private final ListChangeListener tradesListChangeListener; @@ -98,6 +105,7 @@ public class PendingTradesDataModel extends ActivatableDataModel { private ChangeListener tradeStateChangeListener; private Trade selectedTrade; + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, initialization /////////////////////////////////////////////////////////////////////////////////////////// @@ -112,7 +120,10 @@ public PendingTradesDataModel(TradeManager tradeManager, WalletsSetup walletsSetup, Navigation navigation, WalletPasswordWindow walletPasswordWindow, - NotificationCenter notificationCenter) { + NotificationCenter notificationCenter, + AccountAgeWitnessService accountAgeWitnessService, + AccountScoreService accountScoreService, + BSFormatter formatter) { this.tradeManager = tradeManager; this.btcWalletService = btcWalletService; this.keyRing = keyRing; @@ -123,6 +134,9 @@ public PendingTradesDataModel(TradeManager tradeManager, this.navigation = navigation; this.walletPasswordWindow = walletPasswordWindow; this.notificationCenter = notificationCenter; + this.accountAgeWitnessService = accountAgeWitnessService; + this.accountScoreService = accountScoreService; + this.formatter = formatter; tradesListChangeListener = change -> onListChanged(); notificationCenter.setSelectItemByTradeIdConsumer(this::selectItemByTradeId); @@ -162,10 +176,35 @@ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler er ((BuyerTrade) trade).onFiatPaymentStarted(resultHandler, errorMessageHandler); } - public void onFiatPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { + public void onFiatPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler, Runnable delayedPayoutHandler) { checkNotNull(getTrade(), "trade must not be null"); checkArgument(getTrade() instanceof SellerTrade, "Check failed: trade not instanceof SellerTrade"); - ((SellerTrade) getTrade()).onFiatPaymentReceived(resultHandler, errorMessageHandler); + + if (requirePayoutDelay()) { + delayedPayoutHandler.run(); + } else if (getTrade().getDisputeState() == Trade.DisputeState.NO_DISPUTE) { + ((SellerTrade) getTrade()).onFiatPaymentReceived(resultHandler, errorMessageHandler); + } + } + + public boolean requirePayoutDelay() { + return accountScoreService.tradeRequirePayoutDelay(selectedTrade); + } + + public String getFormattedDelayedPayoutDate() { + return formatter.formatDateTime(accountScoreService.getDelayedTradePayoutDate(selectedTrade)); + } + + public String getFormattedBuyersAccountAge() { + return formatter.formatAccountAge(getBuyersAccountAge()); + } + + private long getBuyersAccountAge() { + Contract contract = selectedTrade.getContract(); + if (contract == null) { + return 0; // Not expected case + } + return accountAgeWitnessService.getAccountAge(contract.getBuyerPaymentAccountPayload(), contract.getBuyerPubKeyRing()); } public void onWithdrawRequest(String toAddress, Coin amount, Coin fee, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) { @@ -209,7 +248,7 @@ public void onMoveToFailedTrades() { @Nullable public PendingTradesListItem getSelectedItem() { - return selectedItemProperty.get() != null ? selectedItemProperty.get() : null; + return selectedItemProperty.get(); } @Nullable @@ -222,7 +261,7 @@ Offer getOffer() { return getTrade() != null ? getTrade().getOffer() : null; } - boolean isBuyOffer() { + private boolean isBuyOffer() { return getOffer() != null && getOffer().getDirection() == OfferPayload.Direction.BUY; } @@ -244,7 +283,7 @@ Coin getTradeFeeInBTC() { if (trade != null) { Offer offer = trade.getOffer(); if (isMaker()) { - if (offer.isCurrencyForMakerFeeBtc()) + if (offer != null && offer.isCurrencyForMakerFeeBtc()) return offer.getMakerFee(); else return Coin.ZERO;// getTradeFeeAsBsq is used for BSQ @@ -265,6 +304,9 @@ Coin getTxFee() { if (trade != null) { if (isMaker()) { Offer offer = trade.getOffer(); + if (offer == null) + return Coin.ZERO; + if (offer.isCurrencyForMakerFeeBtc()) return offer.getTxFee(); else @@ -286,6 +328,9 @@ Coin getTradeFeeAsBsq() { if (trade != null) { if (isMaker()) { Offer offer = trade.getOffer(); + if (offer == null) + return Coin.ZERO; + if (offer.isCurrencyForMakerFeeBtc()) return Coin.ZERO; // getTradeFeeInBTC is used for BTC else @@ -405,7 +450,7 @@ private void tryOpenDispute(boolean isSupportTicket) { log.info("Trade.depositTx is null. We try to find the tx in our wallet."); List candidates = new ArrayList<>(); List transactions = btcWalletService.getRecentTransactions(100, true); - transactions.stream().forEach(transaction -> { + transactions.forEach(transaction -> { Coin valueSentFromMe = btcWalletService.getValueSentFromMeForTransaction(transaction); if (!valueSentFromMe.isZero()) { // spending tx @@ -456,10 +501,13 @@ private void doOpenDispute(boolean isSupportTicket, Transaction depositTx) { final PubKeyRing arbitratorPubKeyRing = trade.getArbitratorPubKeyRing(); checkNotNull(arbitratorPubKeyRing, "arbitratorPubKeyRing must no tbe null"); + Offer offer = trade.getOffer(); + boolean disputeOpenerIsBuyer = offer != null && offer.getDirection() == OfferPayload.Direction.BUY ? + isMaker : !isMaker; Dispute dispute = new Dispute(disputeManager.getDisputeStorage(), trade.getId(), keyRing.getPubKeyRing().hashCode(), // traderId - trade.getOffer().getDirection() == OfferPayload.Direction.BUY ? isMaker : !isMaker, + disputeOpenerIsBuyer, isMaker, keyRing.getPubKeyRing(), trade.getDate().getTime(), diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java index 7d7147c1144..a5eb12b1d0d 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -21,10 +21,10 @@ import bisq.desktop.common.model.ViewModel; import bisq.desktop.util.GUIUtil; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; import bisq.core.network.MessageState; import bisq.core.offer.Offer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.Contract; import bisq.core.trade.Trade; import bisq.core.trade.closed.ClosedTradableManager; diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/TradeStepView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/TradeStepView.java index b95d941f12c..8abc1a48cfa 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/TradeStepView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/TradeStepView.java @@ -290,10 +290,13 @@ private void updateTimeLeft() { timeLeftProgressBar.getStyleClass().add("error"); } } else { - timeLeftTextField.setText(Res.get("portfolio.pending.tradeNotCompleted", - model.getDateForOpenDispute())); - timeLeftTextField.getStyleClass().add("error-text"); - timeLeftProgressBar.getStyleClass().add("error"); + if (model.dataModel.requirePayoutDelay()) { + timeLeftTextField.setText(Res.get("portfolio.pending.tradeNotCompleted.immatureBuyerAccount")); + } else { + timeLeftTextField.setText(Res.get("portfolio.pending.tradeNotCompleted", model.getDateForOpenDispute())); + timeLeftTextField.getStyleClass().add("error-text"); + timeLeftProgressBar.getStyleClass().add("error"); + } } } } @@ -486,7 +489,9 @@ private void updateTradePeriodState(Trade.TradePeriodState tradePeriodState) { removeWarning(); break; case TRADE_PERIOD_OVER: - onOpenForDispute(); + if (!model.dataModel.requirePayoutDelay()) { + onOpenForDispute(); + } break; } } diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java index 846e6d33747..081efb68938 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java @@ -21,6 +21,7 @@ import bisq.desktop.components.TextFieldWithCopyIcon; import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.main.portfolio.pendingtrades.PendingTradesListItem; import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel; import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView; import bisq.desktop.util.Layout; @@ -43,8 +44,6 @@ import bisq.core.trade.Trade; import bisq.core.user.DontShowAgainLookup; -import bisq.common.Timer; -import bisq.common.UserThread; import bisq.common.app.DevEnv; import bisq.common.util.Tuple4; @@ -71,7 +70,8 @@ public class SellerStep3View extends TradeStepView { private Label statusLabel; private BusyAnimation busyAnimation; private Subscription tradeStatePropertySubscription; - private Timer timeoutTimer; + private boolean delayedPayoutInfoDisplayed; + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, Initialisation @@ -85,30 +85,29 @@ public SellerStep3View(PendingTradesViewModel model) { public void activate() { super.activate(); - if (timeoutTimer != null) - timeoutTimer.stop(); - tradeStatePropertySubscription = EasyBind.subscribe(trade.stateProperty(), state -> { - if (timeoutTimer != null) - timeoutTimer.stop(); - if (trade.isFiatSent() && !trade.isFiatReceived()) { showPopup(); } else if (trade.isFiatReceived()) { if (!trade.hasFailed()) { switch (state) { case SELLER_CONFIRMED_IN_UI_FIAT_PAYMENT_RECEIPT: - case SELLER_PUBLISHED_PAYOUT_TX: - case SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG: - busyAnimation.play(); - // confirmButton.setDisable(true); - statusLabel.setText(Res.get("shared.sendingConfirmation")); + if (model.dataModel.requirePayoutDelay()) { + handleDelayedPayout(); + } else { + statusLabel.setText(Res.get("portfolio.pending.step3_seller.status.confirmRelease", + model.dataModel.getFormattedBuyersAccountAge())); + confirmButton.setText(Res.get("portfolio.pending.step3_seller.button.release").toUpperCase()); - timeoutTimer = UserThread.runAfter(() -> { busyAnimation.stop(); - // confirmButton.setDisable(false); - statusLabel.setText(Res.get("shared.sendingConfirmationAgain")); - }, 10); + confirmButton.setDisable(false); + } + break; + case SELLER_PUBLISHED_PAYOUT_TX: + case SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG: + if (model.dataModel.requirePayoutDelay()) { + handleDelayedPayout(); + } break; case SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG: busyAnimation.stop(); @@ -119,7 +118,7 @@ public void activate() { statusLabel.setText(Res.get("shared.messageStoredInMailbox")); break; case SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG: - // We get a popup and the trade closed, so we dont need to show anything here + // We get a popup and the trade closed, so we don't need to show anything here busyAnimation.stop(); // confirmButton.setDisable(false); statusLabel.setText(""); @@ -150,9 +149,6 @@ public void deactivate() { } busyAnimation.stop(); - - if (timeoutTimer != null) - timeoutTimer.stop(); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -297,7 +293,11 @@ private void onPaymentReceived() { message += Res.get("portfolio.pending.step3_seller.onPaymentReceived.name", optionalHolderName.get()); } } - message += Res.get("portfolio.pending.step3_seller.onPaymentReceived.note"); + + if (!model.dataModel.requirePayoutDelay()) { + message += Res.get("portfolio.pending.step3_seller.onPaymentReceived.note"); + } + new Popup<>() .headLine(Res.get("portfolio.pending.step3_seller.onPaymentReceived.confirm.headline")) .confirmation(message) @@ -384,7 +384,29 @@ private void confirmPaymentReceived() { // confirmButton.setDisable(false); busyAnimation.stop(); new Popup<>().warning(Res.get("popup.warning.sendMsgFailed")).show(); - }); + }, this::handleDelayedPayout); + } + + private void handleDelayedPayout() { + if (!delayedPayoutInfoDisplayed) { + delayedPayoutInfoDisplayed = true; + confirmButton.setDisable(true); + confirmButton.setVisible(false); + confirmButton.setManaged(false); + busyAnimation.stop(); + PendingTradesListItem selectedItem = model.dataModel.getSelectedItem(); + String id = "delayedPayoutInfo_" + (selectedItem != null ? selectedItem.getTrade().getId() : ""); + if (preferences.showAgain(id)) { + new Popup().information(Res.get("portfolio.pending.step3_seller.popup.delayedPayoutInfo", + model.dataModel.getFormattedBuyersAccountAge(), + model.dataModel.getFormattedDelayedPayoutDate())) + .dontShowAgainId(id) + .width(900) + .show(); + } + statusLabel.setText(Res.get("portfolio.pending.step3_seller.status.delayedPayoutInfo", + model.dataModel.getFormattedDelayedPayoutDate())); + } } private Optional getOptionalHolderName() { 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 e0173a6b2f8..5fb65904bd5 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 @@ -22,6 +22,7 @@ import bisq.desktop.util.validation.FiatPriceValidator; 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; @@ -31,7 +32,6 @@ import bisq.core.locale.GlobalSettings; import bisq.core.locale.Res; import bisq.core.offer.OfferPayload; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.PaymentAccount; import bisq.core.provider.fee.FeeService; import bisq.core.provider.price.MarketPrice; 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 2cece3114c3..e6c9e798d17 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 @@ -2,6 +2,7 @@ import bisq.desktop.util.validation.SecurityDepositValidator; +import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.btc.model.AddressEntry; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; @@ -11,7 +12,6 @@ import bisq.core.locale.Res; import bisq.core.offer.OfferPayload; import bisq.core.offer.OpenOffer; -import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.CryptoCurrencyAccount; import bisq.core.payment.PaymentAccount; import bisq.core.provider.fee.FeeService;