diff --git a/core/src/main/java/haveno/core/offer/Offer.java b/core/src/main/java/haveno/core/offer/Offer.java index 63d9fd022e..675fbeb550 100644 --- a/core/src/main/java/haveno/core/offer/Offer.java +++ b/core/src/main/java/haveno/core/offer/Offer.java @@ -412,6 +412,8 @@ public class Offer implements NetworkPayload, PersistablePayload { return getExtraDataMap().get(OfferPayload.AUSTRALIA_PAYID_EXTRA_INFO); else if (getExtraDataMap() != null && getExtraDataMap().containsKey(OfferPayload.PAYPAL_EXTRA_INFO)) return getExtraDataMap().get(OfferPayload.PAYPAL_EXTRA_INFO); + else if (getExtraDataMap() != null && getExtraDataMap().containsKey(OfferPayload.CASHAPP_EXTRA_INFO)) + return getExtraDataMap().get(OfferPayload.CASHAPP_EXTRA_INFO); else return ""; } diff --git a/core/src/main/java/haveno/core/offer/OfferPayload.java b/core/src/main/java/haveno/core/offer/OfferPayload.java index 6f69dbebf8..a1e30d8de6 100644 --- a/core/src/main/java/haveno/core/offer/OfferPayload.java +++ b/core/src/main/java/haveno/core/offer/OfferPayload.java @@ -94,6 +94,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay // Keys for extra map // Only set for traditional offers public static final String ACCOUNT_AGE_WITNESS_HASH = "accountAgeWitnessHash"; + public static final String CASHAPP_EXTRA_INFO = "cashAppExtraInfo"; public static final String REFERRAL_ID = "referralId"; // Only used in payment method F2F public static final String F2F_CITY = "f2fCity"; diff --git a/core/src/main/java/haveno/core/offer/OfferUtil.java b/core/src/main/java/haveno/core/offer/OfferUtil.java index a097bf9609..72593ab5e7 100644 --- a/core/src/main/java/haveno/core/offer/OfferUtil.java +++ b/core/src/main/java/haveno/core/offer/OfferUtil.java @@ -37,6 +37,7 @@ import haveno.core.monetary.Volume; import static haveno.core.offer.OfferPayload.ACCOUNT_AGE_WITNESS_HASH; import static haveno.core.offer.OfferPayload.AUSTRALIA_PAYID_EXTRA_INFO; import static haveno.core.offer.OfferPayload.CAPABILITIES; +import static haveno.core.offer.OfferPayload.CASHAPP_EXTRA_INFO; import static haveno.core.offer.OfferPayload.F2F_CITY; import static haveno.core.offer.OfferPayload.F2F_EXTRA_INFO; import static haveno.core.offer.OfferPayload.PAY_BY_MAIL_EXTRA_INFO; @@ -46,6 +47,7 @@ import static haveno.core.offer.OfferPayload.XMR_AUTO_CONF; import static haveno.core.offer.OfferPayload.XMR_AUTO_CONF_ENABLED_VALUE; import haveno.core.payment.AustraliaPayidAccount; +import haveno.core.payment.CashAppAccount; import haveno.core.payment.F2FAccount; import haveno.core.payment.PayByMailAccount; import haveno.core.payment.PayPalAccount; @@ -206,6 +208,10 @@ public class OfferUtil { extraDataMap.put(PAYPAL_EXTRA_INFO, ((PayPalAccount) paymentAccount).getExtraInfo()); } + if (paymentAccount instanceof CashAppAccount) { + extraDataMap.put(CASHAPP_EXTRA_INFO, ((CashAppAccount) paymentAccount).getExtraInfo()); + } + if (paymentAccount instanceof AustraliaPayidAccount) { extraDataMap.put(AUSTRALIA_PAYID_EXTRA_INFO, ((AustraliaPayidAccount) paymentAccount).getExtraInfo()); } diff --git a/core/src/main/java/haveno/core/payment/CashAppAccount.java b/core/src/main/java/haveno/core/payment/CashAppAccount.java index eea4d26c79..250f1c5779 100644 --- a/core/src/main/java/haveno/core/payment/CashAppAccount.java +++ b/core/src/main/java/haveno/core/payment/CashAppAccount.java @@ -39,6 +39,7 @@ public final class CashAppAccount extends PaymentAccount { PaymentAccountFormField.FieldId.EMAIL_OR_MOBILE_NR_OR_CASHTAG, PaymentAccountFormField.FieldId.TRADE_CURRENCIES, PaymentAccountFormField.FieldId.ACCOUNT_NAME, + PaymentAccountFormField.FieldId.EXTRA_INFO, PaymentAccountFormField.FieldId.SALT); public CashAppAccount() { @@ -67,4 +68,12 @@ public final class CashAppAccount extends PaymentAccount { public String getEmailOrMobileNrOrCashtag() { return ((CashAppAccountPayload) paymentAccountPayload).getEmailOrMobileNrOrCashtag(); } + + public void setExtraInfo(String extraInfo) { + ((CashAppAccountPayload) paymentAccountPayload).setExtraInfo(extraInfo); + } + + public String getExtraInfo() { + return ((CashAppAccountPayload) paymentAccountPayload).getExtraInfo(); + } } diff --git a/core/src/main/java/haveno/core/payment/payload/CashAppAccountPayload.java b/core/src/main/java/haveno/core/payment/payload/CashAppAccountPayload.java index d9f7494013..bec0f340e5 100644 --- a/core/src/main/java/haveno/core/payment/payload/CashAppAccountPayload.java +++ b/core/src/main/java/haveno/core/payment/payload/CashAppAccountPayload.java @@ -36,6 +36,7 @@ import java.util.Map; @Slf4j public final class CashAppAccountPayload extends PaymentAccountPayload { private String emailOrMobileNrOrCashtag = ""; + private String extraInfo = ""; public CashAppAccountPayload(String paymentMethod, String id) { super(paymentMethod, id); @@ -48,6 +49,7 @@ public final class CashAppAccountPayload extends PaymentAccountPayload { private CashAppAccountPayload(String paymentMethod, String id, String emailOrMobileNrOrCashtag, + String extraInfo, long maxTradePeriod, Map excludeFromJsonDataMap) { super(paymentMethod, @@ -56,13 +58,15 @@ public final class CashAppAccountPayload extends PaymentAccountPayload { excludeFromJsonDataMap); this.emailOrMobileNrOrCashtag = emailOrMobileNrOrCashtag; + this.extraInfo = extraInfo; } @Override public Message toProtoMessage() { return getPaymentAccountPayloadBuilder() .setCashAppAccountPayload(protobuf.CashAppAccountPayload.newBuilder() - .setEmailOrMobileNrOrCashtag(emailOrMobileNrOrCashtag)) + .setExtraInfo(extraInfo) + .setEmailOrMobileNrOrCashtag(emailOrMobileNrOrCashtag)) .build(); } @@ -70,6 +74,7 @@ public final class CashAppAccountPayload extends PaymentAccountPayload { return new CashAppAccountPayload(proto.getPaymentMethodId(), proto.getId(), proto.getCashAppAccountPayload().getEmailOrMobileNrOrCashtag(), + proto.getCashAppAccountPayload().getExtraInfo(), proto.getMaxTradePeriod(), new HashMap<>(proto.getExcludeFromJsonDataMap())); } @@ -81,7 +86,10 @@ public final class CashAppAccountPayload extends PaymentAccountPayload { @Override public String getPaymentDetails() { - return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.email.mobile.cashtag") + " " + emailOrMobileNrOrCashtag; + return Res.get(paymentMethodId) + " - " + + Res.getWithCol("payment.email.mobile.cashtag") + + " " + emailOrMobileNrOrCashtag + "\n" + + Res.getWithCol("payment.shared.extraInfo") + " " + extraInfo+ "\n"; } @Override diff --git a/desktop/src/main/java/haveno/desktop/components/paymentmethods/CashAppForm.java b/desktop/src/main/java/haveno/desktop/components/paymentmethods/CashAppForm.java index ac54d7a2bf..529af4391d 100644 --- a/desktop/src/main/java/haveno/desktop/components/paymentmethods/CashAppForm.java +++ b/desktop/src/main/java/haveno/desktop/components/paymentmethods/CashAppForm.java @@ -17,6 +17,7 @@ package haveno.desktop.components.paymentmethods; +import com.jfoenix.controls.JFXTextArea; import haveno.core.account.witness.AccountAgeWitnessService; import haveno.core.locale.Res; import haveno.core.payment.CashAppAccount; @@ -29,6 +30,7 @@ import haveno.core.util.validation.InputValidator; import haveno.desktop.components.InputTextField; import haveno.desktop.util.FormBuilder; import haveno.desktop.util.Layout; +import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.layout.FlowPane; import javafx.scene.layout.GridPane; @@ -36,6 +38,8 @@ import javafx.scene.layout.GridPane; import static haveno.desktop.util.FormBuilder.addCompactTopLabelTextField; import static haveno.desktop.util.FormBuilder.addCompactTopLabelTextFieldWithCopyIcon; import static haveno.desktop.util.FormBuilder.addTopLabelFlowPane; +import static haveno.desktop.util.FormBuilder.addCompactTopLabelTextArea; +import static haveno.desktop.util.FormBuilder.addTopLabelTextArea; public class CashAppForm extends PaymentMethodForm { private final CashAppAccount cashAppAccount; @@ -43,6 +47,13 @@ public class CashAppForm extends PaymentMethodForm { public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountPayload paymentAccountPayload) { addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.email.mobile.cashtag"), ((CashAppAccountPayload) paymentAccountPayload).getEmailOrMobileNrOrCashtag()); + + CashAppAccountPayload payId = (CashAppAccountPayload) paymentAccountPayload; + TextArea textExtraInfo = addCompactTopLabelTextArea(gridPane, gridRow, 1, Res.get("payment.shared.extraInfo"), "").second; + textExtraInfo.setMinHeight(70); + textExtraInfo.setEditable(false); + textExtraInfo.setText(payId.getExtraInfo()); + return gridRow; } @@ -66,6 +77,16 @@ public class CashAppForm extends PaymentMethodForm { cashAppAccount.setEmailOrMobileNrOrCashtag(newValue.trim()); updateFromInputs(); }); + + TextArea extraTextArea = addTopLabelTextArea(gridPane, ++gridRow, + Res.get("payment.shared.optionalExtra"), Res.get("payment.shared.extraInfo.prompt")).second; + extraTextArea.setMinHeight(70); + ((JFXTextArea) extraTextArea).setLabelFloat(false); + extraTextArea.textProperty().addListener((ov, oldValue, newValue) -> { + cashAppAccount.setExtraInfo(newValue); + updateFromInputs(); + }); + addCurrenciesGrid(true); addLimitations(false); addAccountNameTextFieldWithAutoFillToggleButton(); @@ -96,6 +117,12 @@ public class CashAppForm extends PaymentMethodForm { addAccountNameTextFieldWithAutoFillToggleButton(); TextField field = addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.email.mobile.cashtag"), cashAppAccount.getEmailOrMobileNrOrCashtag()).second; + + TextArea textAreaExtra = addCompactTopLabelTextArea(gridPane, ++gridRow, Res.get("payment.shared.extraInfo"), "").second; + textAreaExtra.setText(cashAppAccount.getExtraInfo()); + textAreaExtra.setMinHeight(70); + textAreaExtra.setEditable(false); + field.setMouseTransparent(false); addLimitations(true); addCurrenciesGrid(false); 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 e64e1a6ae0..98233d2657 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 @@ -159,7 +159,7 @@ public class TakeOfferView extends ActivatableViewAndModel paymentAccountWarningDisplayed = new HashMap<>(); private boolean offerDetailsWindowDisplayed, zelleWarningDisplayed, fasterPaymentsWarningDisplayed, takeOfferFromUnsignedAccountWarningDisplayed, payByMailWarningDisplayed, cashAtAtmWarningDisplayed, - australiaPayidWarningDisplayed, paypalWarningDisplayed; + australiaPayidWarningDisplayed, paypalWarningDisplayed, cashAppWarningDisplayed; private SimpleBooleanProperty errorPopupDisplayed; private ChangeListener amountFocusedListener, getShowWalletFundedNotificationListener; @@ -270,6 +270,7 @@ public class TakeOfferView extends ActivatableViewAndModel { + 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"); diff --git a/desktop/src/main/java/haveno/desktop/main/overlays/windows/OfferDetailsWindow.java b/desktop/src/main/java/haveno/desktop/main/overlays/windows/OfferDetailsWindow.java index 30ed30e0df..e93dc647a3 100644 --- a/desktop/src/main/java/haveno/desktop/main/overlays/windows/OfferDetailsWindow.java +++ b/desktop/src/main/java/haveno/desktop/main/overlays/windows/OfferDetailsWindow.java @@ -177,7 +177,8 @@ public class OfferDetailsWindow extends Overlay { boolean showExtraInfo = offer.getPaymentMethod().equals(PaymentMethod.F2F) || offer.getPaymentMethod().equals(PaymentMethod.PAY_BY_MAIL) || offer.getPaymentMethod().equals(PaymentMethod.AUSTRALIA_PAYID)|| - offer.getPaymentMethod().equals(PaymentMethod.PAYPAL_ID); + offer.getPaymentMethod().equals(PaymentMethod.PAYPAL_ID)|| + offer.getPaymentMethod().equals(PaymentMethod.CASH_APP_ID); if (!takeOfferHandlerOptional.isPresent()) rows++; if (showAcceptedBanks) diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto index f50bebfb07..4a24f41397 100644 --- a/proto/src/main/proto/pb.proto +++ b/proto/src/main/proto/pb.proto @@ -1061,6 +1061,7 @@ message UpholdAccountPayload { message CashAppAccountPayload { string email_or_mobile_nr_or_cashtag = 1; + string extra_info = 2; } message MoneyBeamAccountPayload {