From ad56c26f7fae84ffa83602326a9000abefcc1945 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 13 Feb 2018 19:42:29 -0500 Subject: [PATCH] Add payment method Cash App (#1049) --- common/src/main/proto/pb.proto | 5 + .../resources/i18n/displayStrings.properties | 6 +- .../io/bisq/core/payment/CashAppAccount.java | 46 ++++++++ .../core/payment/PaymentAccountFactory.java | 2 + .../payload/CashAppAccountPayload.java | 98 +++++++++++++++++ .../core/payment/payload/PaymentMethod.java | 3 + .../io/bisq/core/proto/CoreProtoResolver.java | 2 + .../paymentmethods/CashAppForm.java | 101 ++++++++++++++++++ .../fiataccounts/FiatAccountsView.java | 5 + .../steps/buyer/BuyerStep2View.java | 3 + .../gui/util/validation/CashAppValidator.java | 28 +++++ 11 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/io/bisq/core/payment/CashAppAccount.java create mode 100644 core/src/main/java/io/bisq/core/payment/payload/CashAppAccountPayload.java create mode 100644 gui/src/main/java/io/bisq/gui/components/paymentmethods/CashAppForm.java create mode 100644 gui/src/main/java/io/bisq/gui/util/validation/CashAppValidator.java diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index dfd374f7fb..730c2bd261 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -831,6 +831,7 @@ message PaymentAccountPayload { SwishAccountPayload swish_account_payload = 13; USPostalMoneyOrderAccountPayload u_s_postal_money_order_account_payload = 14; UpholdAccountPayload uphold_account_payload = 16; + CashAppAccountPayload cash_app_account_payload = 17; } map exclude_from_json_data = 15; } @@ -945,6 +946,10 @@ message UpholdAccountPayload { string account_id = 1; } +message CashAppAccountPayload { + string account_id = 1; +} + message PerfectMoneyAccountPayload { string account_nr = 1; } diff --git a/common/src/main/resources/i18n/displayStrings.properties b/common/src/main/resources/i18n/displayStrings.properties index 1bbff91bb2..a9d641003e 100644 --- a/common/src/main/resources/i18n/displayStrings.properties +++ b/common/src/main/resources/i18n/displayStrings.properties @@ -1618,7 +1618,8 @@ payment.select.altcoin=Select or search altcoin payment.secret=Secret question: payment.answer=Answer: payment.wallet=Wallet ID: -payment.uphold.accountId=Account ID (username or email or tel. no): +payment.uphold.accountId=Account ID (username or email or phone. no): +payment.cashApp.accountId=Account ID ($Cashtag or email or phone. no): payment.supported.okpay=Supported currencies: payment.supported.uphold=Supported currencies: payment.limitations=Limitations: @@ -1704,6 +1705,7 @@ WESTERN_UNION_SHORT=Western Union # Do not translate brand names OK_PAY=OKPay UPHOLD=Uphold +CASH_APP=Cash App PERFECT_MONEY=Perfect Money ALI_PAY=AliPay SEPA=SEPA @@ -1720,6 +1722,8 @@ OK_PAY_SHORT=OKPay # suppress inspection "UnusedProperty" UPHOLD_SHORT=Uphold # suppress inspection "UnusedProperty" +CASH_APP_SHORT=Cash App +# suppress inspection "UnusedProperty" PERFECT_MONEY_SHORT=Perfect Money # suppress inspection "UnusedProperty" ALI_PAY_SHORT=AliPay diff --git a/core/src/main/java/io/bisq/core/payment/CashAppAccount.java b/core/src/main/java/io/bisq/core/payment/CashAppAccount.java new file mode 100644 index 0000000000..fba4413669 --- /dev/null +++ b/core/src/main/java/io/bisq/core/payment/CashAppAccount.java @@ -0,0 +1,46 @@ +/* + * 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 io.bisq.core.payment; + +import io.bisq.common.locale.FiatCurrency; +import io.bisq.core.payment.payload.CashAppAccountPayload; +import io.bisq.core.payment.payload.PaymentAccountPayload; +import io.bisq.core.payment.payload.PaymentMethod; +import lombok.EqualsAndHashCode; + +//TODO missing support for selected trade currency +@EqualsAndHashCode(callSuper = true) +public final class CashAppAccount extends PaymentAccount { + public CashAppAccount() { + super(PaymentMethod.CASH_APP); + setSingleTradeCurrency(new FiatCurrency("USD")); + } + + @Override + protected PaymentAccountPayload createPayload() { + return new CashAppAccountPayload(paymentMethod.getId(), id); + } + + public void setAccountId(String accountId) { + ((CashAppAccountPayload) paymentAccountPayload).setAccountId(accountId); + } + + public String getAccountId() { + return ((CashAppAccountPayload) paymentAccountPayload).getAccountId(); + } +} diff --git a/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java b/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java index cff32e69a4..6aef459669 100644 --- a/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java +++ b/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java @@ -26,6 +26,8 @@ public class PaymentAccountFactory { return new OKPayAccount(); case PaymentMethod.UPHOLD_ID: return new UpholdAccount(); + case PaymentMethod.CASH_APP_ID: + return new CashAppAccount(); case PaymentMethod.PERFECT_MONEY_ID: return new PerfectMoneyAccount(); case PaymentMethod.SEPA_ID: diff --git a/core/src/main/java/io/bisq/core/payment/payload/CashAppAccountPayload.java b/core/src/main/java/io/bisq/core/payment/payload/CashAppAccountPayload.java new file mode 100644 index 0000000000..6ae9abecee --- /dev/null +++ b/core/src/main/java/io/bisq/core/payment/payload/CashAppAccountPayload.java @@ -0,0 +1,98 @@ +/* + * 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 io.bisq.core.payment.payload; + +import com.google.protobuf.Message; +import io.bisq.generated.protobuffer.PB; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +@EqualsAndHashCode(callSuper = true) +@ToString +@Setter +@Getter +@Slf4j +public final class CashAppAccountPayload extends PaymentAccountPayload { + private String accountId = ""; + + public CashAppAccountPayload(String paymentMethod, String id) { + super(paymentMethod, id); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + private CashAppAccountPayload(String paymentMethod, + String id, + String accountId, + long maxTradePeriod, + Map excludeFromJsonDataMap) { + super(paymentMethod, + id, + maxTradePeriod, + excludeFromJsonDataMap); + + this.accountId = accountId; + } + + @Override + public Message toProtoMessage() { + return getPaymentAccountPayloadBuilder() + .setCashAppAccountPayload(PB.CashAppAccountPayload.newBuilder() + .setAccountId(accountId)) + .build(); + } + + public static CashAppAccountPayload fromProto(PB.PaymentAccountPayload proto) { + return new CashAppAccountPayload(proto.getPaymentMethodId(), + proto.getId(), + proto.getCashAppAccountPayload().getAccountId(), + proto.getMaxTradePeriod(), + CollectionUtils.isEmpty(proto.getExcludeFromJsonDataMap()) ? null : new HashMap<>(proto.getExcludeFromJsonDataMap())); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public String getPaymentDetails() { + return "CashApp - Account: " + accountId; + } + + @Override + public String getPaymentDetailsForTradePopup() { + return getPaymentDetails(); + } + + @Override + public byte[] getAgeWitnessInputData() { + return super.getAgeWitnessInputData(accountId.getBytes(Charset.forName("UTF-8"))); + } +} diff --git a/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java b/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java index 09ea03dd47..c081f23c64 100644 --- a/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java +++ b/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java @@ -48,6 +48,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { public static final String OK_PAY_ID = "OK_PAY"; public static final String UPHOLD_ID = "UPHOLD"; + public static final String CASH_APP_ID = "CASH_APP"; public static final String PERFECT_MONEY_ID = "PERFECT_MONEY"; public static final String SEPA_ID = "SEPA"; public static final String SEPA_INSTANT_ID = "SEPA_INSTANT"; @@ -67,6 +68,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { public static PaymentMethod OK_PAY; public static PaymentMethod UPHOLD; + public static PaymentMethod CASH_APP; public static PaymentMethod PERFECT_MONEY; public static PaymentMethod SEPA; public static PaymentMethod SEPA_INSTANT; @@ -170,6 +172,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { // US CLEAR_X_CHANGE = new PaymentMethod(CLEAR_X_CHANGE_ID, 4 * DAY, maxTradeLimitMidRisk), + CASH_APP = new PaymentMethod(CASH_APP_ID, DAY, maxTradeLimitMidRisk), CHASE_QUICK_PAY = new PaymentMethod(CHASE_QUICK_PAY_ID, DAY, maxTradeLimitMidRisk), US_POSTAL_MONEY_ORDER = new PaymentMethod(US_POSTAL_MONEY_ORDER_ID, 8 * DAY, maxTradeLimitMidRisk), diff --git a/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java b/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java index 41449d6fe1..e73769555d 100644 --- a/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java +++ b/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java @@ -62,6 +62,8 @@ public class CoreProtoResolver implements ProtoResolver { return OKPayAccountPayload.fromProto(proto); case UPHOLD_ACCOUNT_PAYLOAD: return UpholdAccountPayload.fromProto(proto); + case CASH_APP_ACCOUNT_PAYLOAD: + return CashAppAccountPayload.fromProto(proto); case PERFECT_MONEY_ACCOUNT_PAYLOAD: return PerfectMoneyAccountPayload.fromProto(proto); case SWISH_ACCOUNT_PAYLOAD: diff --git a/gui/src/main/java/io/bisq/gui/components/paymentmethods/CashAppForm.java b/gui/src/main/java/io/bisq/gui/components/paymentmethods/CashAppForm.java new file mode 100644 index 0000000000..f4a8b4a8ce --- /dev/null +++ b/gui/src/main/java/io/bisq/gui/components/paymentmethods/CashAppForm.java @@ -0,0 +1,101 @@ +/* + * 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 io.bisq.gui.components.paymentmethods; + +import io.bisq.common.locale.Res; +import io.bisq.common.locale.TradeCurrency; +import io.bisq.core.payment.AccountAgeWitnessService; +import io.bisq.core.payment.CashAppAccount; +import io.bisq.core.payment.PaymentAccount; +import io.bisq.core.payment.payload.CashAppAccountPayload; +import io.bisq.core.payment.payload.PaymentAccountPayload; +import io.bisq.gui.components.InputTextField; +import io.bisq.gui.util.BSFormatter; +import io.bisq.gui.util.Layout; +import io.bisq.gui.util.validation.CashAppValidator; +import io.bisq.gui.util.validation.InputValidator; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import org.apache.commons.lang3.StringUtils; + +import static io.bisq.gui.util.FormBuilder.*; + +public class CashAppForm extends PaymentMethodForm { + private final CashAppAccount account; + private final CashAppValidator validator; + private InputTextField accountIdInputTextField; + + public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountPayload paymentAccountPayload) { + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.cashApp.accountId"), ((CashAppAccountPayload) paymentAccountPayload).getAccountId()); + return gridRow; + } + + public CashAppForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, CashAppValidator aliPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + this.account = (CashAppAccount) paymentAccount; + this.validator = aliPayValidator; + } + + @Override + public void addFormForAddAccount() { + gridRowFrom = gridRow + 1; + + accountIdInputTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("payment.cashApp.accountId")).second; + accountIdInputTextField.setValidator(validator); + accountIdInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + account.setAccountId(newValue); + updateFromInputs(); + }); + + final TradeCurrency singleTradeCurrency = account.getSingleTradeCurrency(); + final String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : ""; + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.currency"), nameAndCode); + addLimitations(); + addAccountNameTextFieldWithAutoFillCheckBox(); + } + + @Override + protected void autoFillNameTextField() { + if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) { + String accountNr = accountIdInputTextField.getText(); + accountNr = StringUtils.abbreviate(accountNr, 9); + String method = Res.get(paymentAccount.getPaymentMethod().getId()); + accountNameTextField.setText(method.concat(": ").concat(accountNr)); + } + } + + @Override + public void addFormForDisplayAccount() { + gridRowFrom = gridRow; + addLabelTextField(gridPane, gridRow, Res.get("payment.account.name"), account.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.paymentMethod"), Res.get(account.getPaymentMethod().getId())); + TextField field = addLabelTextField(gridPane, ++gridRow, Res.get("payment.cashApp.accountId"), account.getAccountId()).second; + field.setMouseTransparent(false); + final TradeCurrency singleTradeCurrency = account.getSingleTradeCurrency(); + final String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : ""; + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.currency"), nameAndCode); + addLimitations(); + } + + @Override + public void updateAllInputsValid() { + allInputsValid.set(isAccountNameValid() + && validator.validate(account.getAccountId()).isValid + && account.getTradeCurrencies().size() > 0); + } +} diff --git a/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java b/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java index 1c1724891a..62c1213559 100644 --- a/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java +++ b/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java @@ -63,6 +63,7 @@ public class FiatAccountsView extends ActivatableViewAndModel. + */ + +package io.bisq.gui.util.validation; + + +public final class CashAppValidator extends InputValidator { + + @Override + public ValidationResult validate(String input) { + // TODO + return super.validate(input); + } +}