From 0c442c925192aa034b6e5656b871959fd73a4824 Mon Sep 17 00:00:00 2001 From: woodser Date: Thu, 23 Jan 2025 10:12:42 -0500 Subject: [PATCH 1/4] do not override trade currency on country-based form deserialization --- .../haveno/core/payment/PaymentAccountTypeAdapter.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java b/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java index 0160a1a736d..0226fe45302 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java @@ -24,7 +24,6 @@ import com.google.gson.stream.JsonWriter; import haveno.core.locale.Country; import haveno.core.locale.CountryUtil; -import haveno.core.locale.TraditionalCurrency; import haveno.core.locale.Res; import haveno.core.locale.TradeCurrency; import haveno.core.payment.payload.PaymentAccountPayload; @@ -42,7 +41,6 @@ import java.util.Optional; import java.util.function.Predicate; -import static com.google.common.base.Preconditions.checkNotNull; import static haveno.common.util.ReflectionUtils.getSetterMethodForFieldInClassHierarchy; import static haveno.common.util.ReflectionUtils.getVisibilityModifierAsString; import static haveno.common.util.ReflectionUtils.handleSetFieldValueError; @@ -50,7 +48,6 @@ import static haveno.common.util.ReflectionUtils.loadFieldListForClassHierarchy; import static haveno.common.util.Utilities.decodeFromHex; import static haveno.core.locale.CountryUtil.findCountryByCode; -import static haveno.core.locale.CurrencyUtil.getCurrencyByCountryCode; import static haveno.core.locale.CurrencyUtil.getTradeCurrenciesInList; import static haveno.core.locale.CurrencyUtil.getTradeCurrency; import static haveno.core.payment.payload.PaymentMethod.MONEY_GRAM_ID; @@ -435,8 +432,10 @@ private boolean didReadCountryField(JsonReader in, PaymentAccount account, Strin if (account.isCountryBasedPaymentAccount()) { ((CountryBasedPaymentAccount) account).setCountry(country.get()); - TraditionalCurrency fiatCurrency = getCurrencyByCountryCode(checkNotNull(countryCode)); - account.setSingleTradeCurrency(fiatCurrency); + + // TODO: applying single trade currency default can overwrite provided currencies, apply elsewhere? + // TraditionalCurrency fiatCurrency = getCurrencyByCountryCode(checkNotNull(countryCode)); + // account.setSingleTradeCurrency(fiatCurrency); } else if (account.hasPaymentMethodWithId(MONEY_GRAM_ID)) { ((MoneyGramAccount) account).setCountry(country.get()); } else { From 14a17c472f52e9eeac37b4ee4e1a171c917a082d Mon Sep 17 00:00:00 2001 From: woodser Date: Thu, 23 Jan 2025 10:27:22 -0500 Subject: [PATCH 2/4] show extra info popup on take f2f offer --- .../main/offer/takeoffer/TakeOfferView.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java index 1d662aebc72..e0385bb5b31 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java @@ -162,7 +162,7 @@ public class TakeOfferView extends ActivatableViewAndModel paymentAccountWarningDisplayed = new HashMap<>(); private boolean offerDetailsWindowDisplayed, zelleWarningDisplayed, fasterPaymentsWarningDisplayed, takeOfferFromUnsignedAccountWarningDisplayed, payByMailWarningDisplayed, cashAtAtmWarningDisplayed, - australiaPayidWarningDisplayed, paypalWarningDisplayed, cashAppWarningDisplayed; + australiaPayidWarningDisplayed, paypalWarningDisplayed, cashAppWarningDisplayed, F2FWarningDisplayed; private SimpleBooleanProperty errorPopupDisplayed; private ChangeListener amountFocusedListener, getShowWalletFundedNotificationListener; @@ -276,6 +276,7 @@ protected void activate() { maybeShowAustraliaPayidWarning(lastPaymentAccount, model.dataModel.getOffer()); maybeShowPayPalWarning(lastPaymentAccount, model.dataModel.getOffer()); maybeShowCashAppWarning(lastPaymentAccount, model.dataModel.getOffer()); + maybeShowF2FWarning(lastPaymentAccount, model.dataModel.getOffer()); if (!model.isRange()) { nextButton.setVisible(false); @@ -1235,6 +1236,23 @@ private void maybeShowCashAppWarning(PaymentAccount paymentAccount, Offer offer) } } + private void maybeShowF2FWarning(PaymentAccount paymentAccount, Offer offer) { + if (paymentAccount.getPaymentMethod().getId().equals(PaymentMethod.F2F_ID) && + !F2FWarningDisplayed && !offer.getExtraInfo().isEmpty()) { + F2FWarningDisplayed = true; + UserThread.runAfter(() -> { + new GenericMessageWindow() + .preamble(Res.get("payment.tradingRestrictions")) + .instruction(offer.getExtraInfo()) + .actionButtonText(Res.get("shared.iConfirm")) + .closeButtonText(Res.get("shared.close")) + .width(Layout.INITIAL_WINDOW_WIDTH) + .onClose(() -> close(false)) + .show(); + }, 500, TimeUnit.MILLISECONDS); + } + } + private Tuple2 getTradeInputBox(HBox amountValueBox, String promptText) { Label descriptionLabel = new AutoTooltipLabel(promptText); descriptionLabel.setId("input-description-label"); From a36c7132e9463f94b2822bb54941e1a78dfaf750 Mon Sep 17 00:00:00 2001 From: woodser Date: Fri, 24 Jan 2025 09:04:48 -0500 Subject: [PATCH 3/4] display N/A for buyer contact in seller step 2 form --- .../haveno/desktop/components/paymentmethods/F2FForm.java | 6 +++--- .../portfolio/pendingtrades/steps/buyer/BuyerStep2View.java | 2 +- .../pendingtrades/steps/seller/SellerStep2View.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/desktop/src/main/java/haveno/desktop/components/paymentmethods/F2FForm.java b/desktop/src/main/java/haveno/desktop/components/paymentmethods/F2FForm.java index ada24a71d49..aebd470d318 100644 --- a/desktop/src/main/java/haveno/desktop/components/paymentmethods/F2FForm.java +++ b/desktop/src/main/java/haveno/desktop/components/paymentmethods/F2FForm.java @@ -52,15 +52,15 @@ public class F2FForm extends PaymentMethodForm { private final F2FValidator f2fValidator; private Country selectedCountry; - public static int addFormForBuyer(GridPane gridPane, int gridRow, - PaymentAccountPayload paymentAccountPayload, Offer offer, double top) { + public static int addStep2Form(GridPane gridPane, int gridRow, + PaymentAccountPayload paymentAccountPayload, Offer offer, double top, boolean isBuyer) { F2FAccountPayload f2fAccountPayload = (F2FAccountPayload) paymentAccountPayload; addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, 0, Res.get("shared.country"), CountryUtil.getNameAndCode(f2fAccountPayload.getCountryCode()), top); addCompactTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1, Res.get("payment.f2f.city"), offer.getF2FCity(), top); addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.f2f.contact"), - f2fAccountPayload.getContact()); + isBuyer ? f2fAccountPayload.getContact() : Res.get("shared.na")); TextArea textArea = addTopLabelTextArea(gridPane, gridRow, 1, Res.get("payment.shared.extraInfo"), "").second; textArea.setMinHeight(70); textArea.setEditable(false); diff --git a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java index e36cba49d47..3872ef85abf 100644 --- a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java +++ b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java @@ -326,7 +326,7 @@ protected void addContent() { case PaymentMethod.F2F_ID: checkNotNull(model.dataModel.getTrade(), "model.dataModel.getTrade() must not be null"); checkNotNull(model.dataModel.getTrade().getOffer(), "model.dataModel.getTrade().getOffer() must not be null"); - gridRow = F2FForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload, model.dataModel.getTrade().getOffer(), 0); + gridRow = F2FForm.addStep2Form(gridPane, gridRow, paymentAccountPayload, model.dataModel.getTrade().getOffer(), 0, true); break; case PaymentMethod.BLOCK_CHAINS_ID: case PaymentMethod.BLOCK_CHAINS_INSTANT_ID: diff --git a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep2View.java b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep2View.java index 06ceba45a2a..e9905c3f823 100644 --- a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep2View.java +++ b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep2View.java @@ -46,8 +46,8 @@ protected void addContent() { if (model.dataModel.getSellersPaymentAccountPayload() instanceof F2FAccountPayload) { addTitledGroupBg(gridPane, ++gridRow, 4, Res.get("portfolio.pending.step2_seller.f2fInfo.headline"), Layout.COMPACT_GROUP_DISTANCE); - gridRow = F2FForm.addFormForBuyer(gridPane, --gridRow, model.dataModel.getSellersPaymentAccountPayload(), - model.dataModel.getTrade().getOffer(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE); + gridRow = F2FForm.addStep2Form(gridPane, --gridRow, model.dataModel.getSellersPaymentAccountPayload(), + model.dataModel.getTrade().getOffer(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, false); } } From cd7fb42424784c60294319735704608186d7df53 Mon Sep 17 00:00:00 2001 From: woodser Date: Fri, 24 Jan 2025 09:31:19 -0500 Subject: [PATCH 4/4] set arbitrator payment account payloads on dispute opened --- .../haveno/core/support/dispute/DisputeManager.java | 10 ++++++++-- .../haveno/core/support/dispute/DisputeValidation.java | 7 +++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/haveno/core/support/dispute/DisputeManager.java b/core/src/main/java/haveno/core/support/dispute/DisputeManager.java index d6b24697447..64de6b3f2d0 100644 --- a/core/src/main/java/haveno/core/support/dispute/DisputeManager.java +++ b/core/src/main/java/haveno/core/support/dispute/DisputeManager.java @@ -537,15 +537,21 @@ protected void handleDisputeOpenedMessage(DisputeOpenedMessage message) { throw e; } - // try to validate payment account + // try to validate payment accounts try { - DisputeValidation.validatePaymentAccountPayload(dispute); // TODO: add field to dispute details: valid, invalid, missing + DisputeValidation.validatePaymentAccountPayloads(dispute); // TODO: add field to dispute details: valid, invalid, missing } catch (Exception e) { log.error(ExceptionUtils.getStackTrace(e)); trade.prependErrorMessage(e.getMessage()); throw e; } + // set arbitrator's payment account payloads + if (trade.isArbitrator()) { + if (trade.getBuyer().getPaymentAccountPayload() == null) trade.getBuyer().setPaymentAccountPayload(dispute.getBuyerPaymentAccountPayload()); + if (trade.getSeller().getPaymentAccountPayload() == null) trade.getSeller().setPaymentAccountPayload(dispute.getSellerPaymentAccountPayload()); + } + // get sender TradePeer sender; if (reOpen) { // re-open can come from either peer diff --git a/core/src/main/java/haveno/core/support/dispute/DisputeValidation.java b/core/src/main/java/haveno/core/support/dispute/DisputeValidation.java index 4591a6fbc25..0905af4a1d4 100644 --- a/core/src/main/java/haveno/core/support/dispute/DisputeValidation.java +++ b/core/src/main/java/haveno/core/support/dispute/DisputeValidation.java @@ -41,9 +41,12 @@ @Slf4j public class DisputeValidation { - public static void validatePaymentAccountPayload(Dispute dispute) throws ValidationException { + public static void validatePaymentAccountPayloads(Dispute dispute) throws ValidationException { if (dispute.getSellerPaymentAccountPayload() == null) throw new ValidationException(dispute, "Seller's payment account payload is null in dispute opened for trade " + dispute.getTradeId()); - if (!Arrays.equals(dispute.getSellerPaymentAccountPayload().getHash(), dispute.getContract().getSellerPaymentAccountPayloadHash())) throw new ValidationException(dispute, "Hash of maker's payment account payload does not match contract"); + if (!Arrays.equals(dispute.getSellerPaymentAccountPayload().getHash(), dispute.getContract().getSellerPaymentAccountPayloadHash())) throw new ValidationException(dispute, "Hash of seller's payment account payload does not match contract"); + if (dispute.getBuyerPaymentAccountPayload() != null) { + if (!Arrays.equals(dispute.getBuyerPaymentAccountPayload().getHash(), dispute.getContract().getBuyerPaymentAccountPayloadHash())) throw new ValidationException(dispute, "Hash of buyer's payment account payload does not match contract"); + } } public static void validateDisputeData(Dispute dispute) throws ValidationException {