Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pop-up warning for trading with risky payment methods #5344

Merged
merged 1 commit into from Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3293,6 +3293,18 @@ payment.accountType=Account type
payment.checking=Checking
payment.savings=Savings
payment.personalId=Personal ID
payment.makeOfferToUnsignedAccount.warning=With the recent rise in BTC price, beware that selling 0.01 BTC or less incurs higher risk than before.\n\n\
It is highly recommended to either:\n\
- make offers >0.01 BTC, so you only deal with signed/trusted buyers\n\
- keep any offers to sell <0.01 BTC to around ~100 USD in value, as this value has (historically) discouraged scammers\n\n\
Bisq developers are working on better ways to secure the payment account model for such smaller trades. \
Join the discussion here: [HYPERLINK:https://github.com/bisq-network/bisq/discussions/5339].
payment.takeOfferFromUnsignedAccount.warning=With the recent rise in BTC price, beware that selling 0.01 BTC or less incurs higher risk than before.\n\n\
It is highly recommended to either:\n\
- take offers from signed buyers only\n\
- keep trades with unsigned/untrusted buyers to around ~100 USD in value, as this value has (historically) discouraged scammers\n\n\
Bisq developers are working on better ways to secure the payment account model for such smaller trades. \
Join the discussion here: [HYPERLINK:https://github.com/bisq-network/bisq/discussions/5339].
payment.clearXchange.info=Zelle is a money transfer service that works best *through* another bank.\n\n\
1. Check this page to see if (and how) your bank works with Zelle: [HYPERLINK:https://www.zellepay.com/get-started]\n\n\
2. Take special note of your transfer limits—sending limits vary by bank, and banks often specify separate daily, weekly, and monthly limits.\n\n\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import bisq.core.offer.OfferRestrictions;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
Expand Down Expand Up @@ -660,6 +661,7 @@ public void onPaymentAccountSelected(PaymentAccount paymentAccount) {

btcValidator.setMaxValue(dataModel.paymentAccount.getPaymentMethod().getMaxTradeLimitAsCoin(dataModel.getTradeCurrencyCode().get()));
btcValidator.setMaxTradeLimit(Coin.valueOf(dataModel.getMaxTradeLimit()));
maybeShowMakeOfferToUnsignedAccountWarning();

securityDepositValidator.setPaymentAccount(paymentAccount);
}
Expand Down Expand Up @@ -776,6 +778,8 @@ public void onFocusOutMinAmountTextField(boolean oldValue, boolean newValue) {
} else {
syncMinAmountWithAmount = true;
}

maybeShowMakeOfferToUnsignedAccountWarning();
}
}

Expand Down Expand Up @@ -1218,6 +1222,16 @@ private void validateAndSetBuyerSecurityDepositToModel() {
}
}

private void maybeShowMakeOfferToUnsignedAccountWarning() {
if (dataModel.getDirection() == OfferPayload.Direction.SELL &&
PaymentMethod.hasChargebackRisk(dataModel.getPaymentAccount().getPaymentMethod(), dataModel.getTradeCurrency().getCode())) {
Coin checkAmount = dataModel.getMinAmount().get() == null ? dataModel.getAmount().get() : dataModel.getMinAmount().get();
if (checkAmount != null && !checkAmount.isGreaterThan(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT)) {
GUIUtil.showMakeOfferToUnsignedAccountWarning();
}
}
}

private InputValidator.ValidationResult isBtcInputValid(String input) {
return btcValidator.validate(input);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
isOfferAvailableSubscription;

private int gridRow = 0;
private boolean offerDetailsWindowDisplayed, clearXchangeWarningDisplayed, fasterPaymentsWarningDisplayed;
private boolean offerDetailsWindowDisplayed, clearXchangeWarningDisplayed, fasterPaymentsWarningDisplayed, takeOfferFromUnsignedAccountWarningDisplayed;
private SimpleBooleanProperty errorPopupDisplayed;
private ChangeListener<Boolean> amountFocusedListener, getShowWalletFundedNotificationListener;

Expand Down Expand Up @@ -304,6 +304,7 @@ protected void activate() {

balanceTextField.setTargetAmount(model.dataModel.getTotalToPayAsCoin().get());

maybeShowTakeOfferFromUnsignedAccountWarning(model.dataModel.getOffer());
maybeShowClearXchangeWarning(lastPaymentAccount);
maybeShowFasterPaymentsWarning(lastPaymentAccount);

Expand Down Expand Up @@ -1243,6 +1244,14 @@ else if (model.dataModel.getUsableBsqBalance().isZero())
.show();
}

private void maybeShowTakeOfferFromUnsignedAccountWarning(Offer offer) {
// warn if you are selling BTC to unsigned account (#5343)
if (model.isSellingToAnUnsignedAccount(offer) && !takeOfferFromUnsignedAccountWarningDisplayed) {
takeOfferFromUnsignedAccountWarningDisplayed = true;
UserThread.runAfter(GUIUtil::showTakeOfferFromUnsignedAccountWarning, 500, TimeUnit.MILLISECONDS);
}
}

private void maybeShowClearXchangeWarning(PaymentAccount paymentAccount) {
if (paymentAccount.getPaymentMethod().getId().equals(PaymentMethod.CLEAR_X_CHANGE_ID) &&
!clearXchangeWarningDisplayed) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,17 @@ boolean isSeller() {
return dataModel.getDirection() == OfferPayload.Direction.BUY;
}

public boolean isSellingToAnUnsignedAccount(Offer offer) {
if (offer.getDirection() == OfferPayload.Direction.BUY &&
PaymentMethod.hasChargebackRisk(offer.getPaymentMethod(), offer.getCurrencyCode())) {
// considered risky when either UNSIGNED, PEER_INITIAL, or BANNED (see #5343)
return accountAgeWitnessService.getSignState(offer) == AccountAgeWitnessService.SignState.UNSIGNED ||
accountAgeWitnessService.getSignState(offer) == AccountAgeWitnessService.SignState.PEER_INITIAL ||
accountAgeWitnessService.getSignState(offer) == AccountAgeWitnessService.SignState.BANNED;
}
return false;
}

private InputValidator.ValidationResult isBtcInputValid(String input) {
return btcValidator.validate(input);
}
Expand Down
18 changes: 18 additions & 0 deletions desktop/src/main/java/bisq/desktop/util/GUIUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,24 @@ public static <T> T getParentOfType(Node node, Class<T> t) {
return t.cast(parent);
}

public static void showTakeOfferFromUnsignedAccountWarning() {
String key = "confirmTakeOfferFromUnsignedAccount";
new Popup().warning(Res.get("payment.takeOfferFromUnsignedAccount.warning"))
.width(900)
.closeButtonText(Res.get("shared.iConfirm"))
.dontShowAgainId(key)
.show();
}

public static void showMakeOfferToUnsignedAccountWarning() {
String key = "confirmMakeOfferToUnsignedAccount";
new Popup().warning(Res.get("payment.makeOfferToUnsignedAccount.warning"))
.width(900)
.closeButtonText(Res.get("shared.iConfirm"))
.dontShowAgainId(key)
.show();
}

public static void showClearXchangeWarning() {
String key = "confirmClearXchangeRequirements";
final String currencyName = Config.baseCurrencyNetwork().getCurrencyName();
Expand Down