diff --git a/core/src/main/java/bisq/core/locale/CurrencyUtil.java b/core/src/main/java/bisq/core/locale/CurrencyUtil.java index d659c4f5ff8..6c012b0bdfc 100644 --- a/core/src/main/java/bisq/core/locale/CurrencyUtil.java +++ b/core/src/main/java/bisq/core/locale/CurrencyUtil.java @@ -436,6 +436,15 @@ public static List getAllCelPayCurrencies() { )); } + // https://github.com/bisq-network/growth/issues/227 + public static List getAllMoneseCurrencies() { + return new ArrayList<>(Arrays.asList( + new FiatCurrency("EUR"), + new FiatCurrency("GBP"), + new FiatCurrency("RON") + )); + } + // https://www.revolut.com/help/getting-started/exchanging-currencies/what-fiat-currencies-are-supported-for-holding-and-exchange public static List getAllRevolutCurrencies() { ArrayList currencies = new ArrayList<>(Arrays.asList( diff --git a/core/src/main/java/bisq/core/payment/MoneseAccount.java b/core/src/main/java/bisq/core/payment/MoneseAccount.java new file mode 100644 index 00000000000..cc15b49e914 --- /dev/null +++ b/core/src/main/java/bisq/core/payment/MoneseAccount.java @@ -0,0 +1,56 @@ +/* + * 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.payment; + +import bisq.core.payment.payload.MoneseAccountPayload; +import bisq.core.payment.payload.PaymentAccountPayload; +import bisq.core.payment.payload.PaymentMethod; + +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +public final class MoneseAccount extends PaymentAccount { + public MoneseAccount() { + super(PaymentMethod.MONESE); + } + + @Override + protected PaymentAccountPayload createPayload() { + return new MoneseAccountPayload(paymentMethod.getId(), id); + } + + public void setMobileNr(String accountId) { + ((MoneseAccountPayload) paymentAccountPayload).setMobileNr(accountId); + } + + public String getMobileNr() { + return ((MoneseAccountPayload) paymentAccountPayload).getMobileNr(); + } + + public String getMessageForBuyer() { + return "payment.monese.info.buyer"; + } + + public String getMessageForSeller() { + return "payment.monese.info.seller"; + } + + public String getMessageForAccountCreation() { + return "payment.monese.info.account"; + } +} diff --git a/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java b/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java index e594b2acd39..b7fd572a984 100644 --- a/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java @@ -110,6 +110,10 @@ public static PaymentAccount getPaymentAccount(PaymentMethod paymentMethod) { return new CapitualAccount(); case PaymentMethod.CELPAY_ID: return new CelPayAccount(); + case PaymentMethod.MONESE_ID: + return new MoneseAccount(); + case PaymentMethod.SATISPAY_ID: + return new SatispayAccount(); case PaymentMethod.SWIFT_ID: return new SwiftAccount(); diff --git a/core/src/main/java/bisq/core/payment/SatispayAccount.java b/core/src/main/java/bisq/core/payment/SatispayAccount.java new file mode 100644 index 00000000000..440126dd112 --- /dev/null +++ b/core/src/main/java/bisq/core/payment/SatispayAccount.java @@ -0,0 +1,56 @@ +/* + * 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.payment; + +import bisq.core.payment.payload.PaymentAccountPayload; +import bisq.core.payment.payload.PaymentMethod; +import bisq.core.payment.payload.SatispayAccountPayload; + +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +public final class SatispayAccount extends CountryBasedPaymentAccount { + public SatispayAccount() { + super(PaymentMethod.SATISPAY); + } + + @Override + protected PaymentAccountPayload createPayload() { + return new SatispayAccountPayload(paymentMethod.getId(), id); + } + + public void setMobileNr(String accountId) { + ((SatispayAccountPayload) paymentAccountPayload).setMobileNr(accountId); + } + + public String getMobileNr() { + return ((SatispayAccountPayload) paymentAccountPayload).getMobileNr(); + } + + public String getMessageForBuyer() { + return "payment.satispay.info.buyer"; + } + + public String getMessageForSeller() { + return "payment.satispay.info.seller"; + } + + public String getMessageForAccountCreation() { + return "payment.satispay.info.account"; + } +} diff --git a/core/src/main/java/bisq/core/payment/payload/MoneseAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/MoneseAccountPayload.java new file mode 100644 index 00000000000..dce0cea4a8a --- /dev/null +++ b/core/src/main/java/bisq/core/payment/payload/MoneseAccountPayload.java @@ -0,0 +1,89 @@ +/* + * 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.payment.payload; + +import bisq.core.locale.Res; + +import com.google.protobuf.Message; + +import java.nio.charset.StandardCharsets; + +import java.util.HashMap; +import java.util.Map; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@ToString +@Setter +@Getter +@Slf4j +public final class MoneseAccountPayload extends PaymentAccountPayload { + private String mobileNr = ""; + + public MoneseAccountPayload(String paymentMethod, String id) { + super(paymentMethod, id); + } + + private MoneseAccountPayload(String paymentMethod, + String id, + String mobileNr, + long maxTradePeriod, + Map excludeFromJsonDataMap) { + super(paymentMethod, + id, + maxTradePeriod, + excludeFromJsonDataMap); + + this.mobileNr = mobileNr; + } + + @Override + public Message toProtoMessage() { + return getPaymentAccountPayloadBuilder() + .setMoneseAccountPayload(protobuf.MoneseAccountPayload.newBuilder().setMobileNr(mobileNr)) + .build(); + } + + public static MoneseAccountPayload fromProto(protobuf.PaymentAccountPayload proto) { + return new MoneseAccountPayload(proto.getPaymentMethodId(), + proto.getId(), + proto.getMoneseAccountPayload().getMobileNr(), + proto.getMaxTradePeriod(), + new HashMap<>(proto.getExcludeFromJsonDataMap())); + } + + @Override + public String getPaymentDetails() { + return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.mobile") + " " + mobileNr; + } + + @Override + public String getPaymentDetailsForTradePopup() { + return getPaymentDetails(); + } + + @Override + public byte[] getAgeWitnessInputData() { + return super.getAgeWitnessInputData(mobileNr.getBytes(StandardCharsets.UTF_8)); + } +} 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 0d2593350ec..0ec8747724c 100644 --- a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java +++ b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java @@ -111,6 +111,8 @@ public final class PaymentMethod implements PersistablePayload, Comparable. + */ + +package bisq.core.payment.payload; + +import bisq.core.locale.Res; + +import com.google.protobuf.Message; + +import java.nio.charset.StandardCharsets; + +import java.util.HashMap; +import java.util.Map; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@ToString +@Setter +@Getter +@Slf4j +public final class SatispayAccountPayload extends CountryBasedPaymentAccountPayload { + private String mobileNr = ""; + + public SatispayAccountPayload(String paymentMethod, String id) { + super(paymentMethod, id); + } + + private SatispayAccountPayload(String paymentMethod, + String id, + String countryCode, + String mobileNr, + long maxTradePeriod, + Map excludeFromJsonDataMap) { + super(paymentMethod, + id, + countryCode, + maxTradePeriod, + excludeFromJsonDataMap); + + this.mobileNr = mobileNr; + } + + @Override + public Message toProtoMessage() { + protobuf.SatispayAccountPayload.Builder builder = protobuf.SatispayAccountPayload.newBuilder() + .setMobileNr(mobileNr); + final protobuf.CountryBasedPaymentAccountPayload.Builder countryBasedPaymentAccountPayload = getPaymentAccountPayloadBuilder() + .getCountryBasedPaymentAccountPayloadBuilder() + .setSatispayAccountPayload(builder); + return getPaymentAccountPayloadBuilder() + .setCountryBasedPaymentAccountPayload(countryBasedPaymentAccountPayload) + .build(); + } + + public static SatispayAccountPayload fromProto(protobuf.PaymentAccountPayload proto) { + protobuf.CountryBasedPaymentAccountPayload countryBasedPaymentAccountPayload = proto.getCountryBasedPaymentAccountPayload(); + protobuf.SatispayAccountPayload paytmAccountPayloadPB = countryBasedPaymentAccountPayload.getSatispayAccountPayload(); + return new SatispayAccountPayload(proto.getPaymentMethodId(), + proto.getId(), + countryBasedPaymentAccountPayload.getCountryCode(), + paytmAccountPayloadPB.getMobileNr(), + proto.getMaxTradePeriod(), + new HashMap<>(proto.getExcludeFromJsonDataMap())); + } + + @Override + public String getPaymentDetails() { + return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.mobile") + " " + mobileNr; + } + + @Override + public String getPaymentDetailsForTradePopup() { + return getPaymentDetails(); + } + + @Override + public byte[] getAgeWitnessInputData() { + return super.getAgeWitnessInputData(mobileNr.getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/core/src/main/java/bisq/core/proto/CoreProtoResolver.java b/core/src/main/java/bisq/core/proto/CoreProtoResolver.java index 3fc71008c7a..98857ad4d91 100644 --- a/core/src/main/java/bisq/core/proto/CoreProtoResolver.java +++ b/core/src/main/java/bisq/core/proto/CoreProtoResolver.java @@ -41,6 +41,7 @@ import bisq.core.payment.payload.InstantCryptoCurrencyPayload; import bisq.core.payment.payload.InteracETransferAccountPayload; import bisq.core.payment.payload.JapanBankAccountPayload; +import bisq.core.payment.payload.MoneseAccountPayload; import bisq.core.payment.payload.MoneyBeamAccountPayload; import bisq.core.payment.payload.MoneyGramAccountPayload; import bisq.core.payment.payload.NationalBankAccountPayload; @@ -58,6 +59,7 @@ import bisq.core.payment.payload.RevolutAccountPayload; import bisq.core.payment.payload.RtgsAccountPayload; import bisq.core.payment.payload.SameBankAccountPayload; +import bisq.core.payment.payload.SatispayAccountPayload; import bisq.core.payment.payload.SepaAccountPayload; import bisq.core.payment.payload.SepaInstantAccountPayload; import bisq.core.payment.payload.SpecificBanksAccountPayload; @@ -137,6 +139,8 @@ public PaymentAccountPayload fromProto(protobuf.PaymentAccountPayload proto) { return BizumAccountPayload.fromProto(proto); case PIX_ACCOUNT_PAYLOAD: return PixAccountPayload.fromProto(proto); + case SATISPAY_ACCOUNT_PAYLOAD: + return SatispayAccountPayload.fromProto(proto); case IFSC_BASED_ACCOUNT_PAYLOAD: final protobuf.IfscBasedAccountPayload.MessageCase messageCaseIfsc = proto.getCountryBasedPaymentAccountPayload().getIfscBasedAccountPayload().getMessageCase(); switch (messageCaseIfsc) { @@ -204,6 +208,8 @@ public PaymentAccountPayload fromProto(protobuf.PaymentAccountPayload proto) { return CapitualAccountPayload.fromProto(proto); case CEL_PAY_ACCOUNT_PAYLOAD: return CelPayAccountPayload.fromProto(proto); + case MONESE_ACCOUNT_PAYLOAD: + return MoneseAccountPayload.fromProto(proto); case SWIFT_ACCOUNT_PAYLOAD: return SwiftAccountPayload.fromProto(proto); diff --git a/core/src/main/java/bisq/core/trade/statistics/TradeStatistics3.java b/core/src/main/java/bisq/core/trade/statistics/TradeStatistics3.java index d4edb0a90e5..aab3b0c2b97 100644 --- a/core/src/main/java/bisq/core/trade/statistics/TradeStatistics3.java +++ b/core/src/main/java/bisq/core/trade/statistics/TradeStatistics3.java @@ -165,7 +165,9 @@ private enum PaymentMethodMapper { CELPAY, NEQUI, BIZUM, - PIX + PIX, + MONESE, + SATISPAY } @Getter diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 0bd1f0ee77e..4b61e5d835a 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -3606,6 +3606,28 @@ Please use your Pix Key as the payment reference so that it is easy for the BTC payment.pix.info.seller=Please check that the payment received description matches the Pix Key provided in the BTC Buyer's Bisq account. payment.pix.key=Pix Key (CPF, CNPJ, Email, Phone number or UUID) +payment.monese.info.account=Monese is a bank app for users of GBP, EUR and RON*. Monese allows users to send money to \ + other Monese accounts instantly and for free in any supported currency.\n\n\ +*To open a RON account in Monese, you need to either live in Romania or have Romanian citizenship.\n\n\ +When setting up your Monese account in Bisq please make sure to include your name and phone number that matches your \ + Monese account. This will ensure that when you send funds they show from the correct account and when you receive \ + funds they will be credited to your account. +payment.monese.info.buyer=Please send payment only to the phone number provided by the BTC Seller in their Bisq account. Please leave the payment description blank. +payment.monese.info.seller=BTC Sellers should expect to receive payment from the phone number / name shown in the BTC Buyer's Bisq account. + +payment.satispay.info.account=To use Satispay you need a bank account (IBAN) in Italy and to be registered for the service.\n\n\ +Satispay account limits are individually set. If you want to trade increased amounts you will need to contact Satispay \ + support to increase your limits. Traders on Bisq should be aware of their limits. If you trade over the above limits \ + your trade might be cancelled and there could be a penalty. +payment.satispay.info.buyer=Please send payment only to the BTC Seller's mobile phone number as provided in Bisq.\n\n\ +Satispay account limits are individually set. If you want to trade increased amounts you will need to contact Satispay \ + support to increase your limits. Traders on Bisq should be aware of their limits. If you trade over the above limits \ + your trade might be cancelled and there could be a penalty. +payment.satispay.info.seller=Please make sure your payment is received from the BTC Buyer's mobile phone number / name as provided in Bisq.\n\n\ +Satispay account limits are individually set. If you want to trade increased amounts you will need to contact Satispay \ + support to increase your limits. Traders on Bisq should be aware of their limits. If you trade over the above limits \ + your trade might be cancelled and there could be a penalty. + payment.usPostalMoneyOrder.info=Trading using US Postal Money Orders (USPMO) on Bisq requires that you understand the following:\n\ \n\ - BTC buyers must write the BTC Seller’s name in both the Payer and the Payee’s fields & take a high-resolution photo of the USPMO and envelope with proof of tracking before sending.\n\ @@ -3796,6 +3818,10 @@ CAPITUAL=Capitual # suppress inspection "UnusedProperty" CELPAY=CelPay # suppress inspection "UnusedProperty" +MONESE=Monese +# suppress inspection "UnusedProperty" +SATISPAY=Satispay +# suppress inspection "UnusedProperty" SWIFT=SWIFT International Wire Transfer # Deprecated: Cannot be deleted as it would break old trade history entries @@ -3874,6 +3900,10 @@ CAPITUAL_SHORT=Capitual # suppress inspection "UnusedProperty" CELPAY_SHORT=CelPay # suppress inspection "UnusedProperty" +MONESE_SHORT=Monese +# suppress inspection "UnusedProperty" +SATISPAY_SHORT=Satispay +# suppress inspection "UnusedProperty" SWIFT_SHORT=SWIFT # Deprecated: Cannot be deleted as it would break old trade history entries diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneseForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneseForm.java new file mode 100644 index 00000000000..a2a2fc4ad9c --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/MoneseForm.java @@ -0,0 +1,116 @@ +/* + * 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.desktop.components.paymentmethods; + +import bisq.desktop.components.InputTextField; +import bisq.desktop.util.FormBuilder; +import bisq.desktop.util.Layout; + +import bisq.core.account.witness.AccountAgeWitnessService; +import bisq.core.locale.CurrencyUtil; +import bisq.core.locale.Res; +import bisq.core.payment.PaymentAccount; +import bisq.core.payment.MoneseAccount; +import bisq.core.payment.payload.PaymentAccountPayload; +import bisq.core.payment.payload.MoneseAccountPayload; +import bisq.core.util.coin.CoinFormatter; +import bisq.core.util.validation.InputValidator; + +import javafx.scene.control.TextField; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.GridPane; + +import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField; +import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextFieldWithCopyIcon; +import static bisq.desktop.util.FormBuilder.addTopLabelTextField; + +public class MoneseForm extends PaymentMethodForm { + private final MoneseAccount account; + private InputTextField mobileNrInputTextField; + + public static int addFormForBuyer(GridPane gridPane, int gridRow, + PaymentAccountPayload paymentAccountPayload) { + addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.mobile"), + ((MoneseAccountPayload) paymentAccountPayload).getMobileNr()); + return gridRow; + } + + public MoneseForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, + InputValidator inputValidator, GridPane gridPane, + int gridRow, CoinFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + this.account = (MoneseAccount) paymentAccount; + } + + @Override + public void addFormForAddAccount() { + gridRowFrom = gridRow + 1; + + mobileNrInputTextField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.mobile")); + mobileNrInputTextField.setValidator(inputValidator); + mobileNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + account.setMobileNr(newValue.trim()); + updateFromInputs(); + }); + + addCurrenciesGrid(true); + addLimitations(false); + addAccountNameTextFieldWithAutoFillToggleButton(); + } + + private void addCurrenciesGrid(boolean isEditable) { + FlowPane flowPane = FormBuilder.addTopLabelFlowPane(gridPane, ++gridRow, + Res.get("payment.supportedCurrencies"), 20, 20).second; + + if (isEditable) { + flowPane.setId("flow-pane-checkboxes-bg"); + } else { + flowPane.setId("flow-pane-checkboxes-non-editable-bg"); + } + + CurrencyUtil.getAllMoneseCurrencies().forEach(currency -> + fillUpFlowPaneWithCurrencies(isEditable, flowPane, currency, account)); + } + + @Override + protected void autoFillNameTextField() { + setAccountNameWithString(mobileNrInputTextField.getText()); + } + + @Override + public void addFormForDisplayAccount() { + gridRowFrom = gridRow; + addTopLabelTextField(gridPane, gridRow, Res.get("payment.account.name"), + account.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"), + Res.get(account.getPaymentMethod().getId())); + TextField field = addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.mobile"), + account.getMobileNr()).second; + field.setMouseTransparent(false); + addLimitations(true); + addCurrenciesGrid(false); + } + + @Override + public void updateAllInputsValid() { + allInputsValid.set(isAccountNameValid() + && account.getMobileNr() != null + && inputValidator.validate(account.getMobileNr()).isValid + && account.getTradeCurrencies().size() > 0); + } +} diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/SatispayForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SatispayForm.java new file mode 100644 index 00000000000..ee9e302452b --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/SatispayForm.java @@ -0,0 +1,106 @@ +/* + * 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.desktop.components.paymentmethods; + +import bisq.desktop.components.InputTextField; +import bisq.desktop.util.FormBuilder; +import bisq.desktop.util.Layout; + +import bisq.core.account.witness.AccountAgeWitnessService; +import bisq.core.locale.CountryUtil; +import bisq.core.locale.FiatCurrency; +import bisq.core.locale.Res; +import bisq.core.payment.PaymentAccount; +import bisq.core.payment.SatispayAccount; +import bisq.core.payment.payload.PaymentAccountPayload; +import bisq.core.payment.payload.SatispayAccountPayload; +import bisq.core.util.coin.CoinFormatter; +import bisq.core.util.validation.InputValidator; + +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; + +import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField; +import static bisq.desktop.util.FormBuilder.addTopLabelTextField; +import static bisq.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon; + +public class SatispayForm extends PaymentMethodForm { + private final SatispayAccount account; + private InputTextField mobileNrInputTextField; + + public static int addFormForBuyer(GridPane gridPane, int gridRow, + PaymentAccountPayload paymentAccountPayload) { + addTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1, Res.get("payment.mobile"), + ((SatispayAccountPayload) paymentAccountPayload).getMobileNr(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE); + return gridRow; + } + + public SatispayForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, + InputValidator inputValidator, GridPane gridPane, + int gridRow, CoinFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + this.account = (SatispayAccount) paymentAccount; + } + + @Override + public void addFormForAddAccount() { + // this payment method is only for Italy/EUR + account.setSingleTradeCurrency(new FiatCurrency("EUR")); + CountryUtil.findCountryByCode("IT").ifPresent(c -> account.setCountry(c)); + + gridRowFrom = gridRow + 1; + + mobileNrInputTextField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.mobile")); + mobileNrInputTextField.setValidator(inputValidator); + mobileNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + account.setMobileNr(newValue.trim()); + updateFromInputs(); + }); + + addTopLabelTextField(gridPane, ++gridRow, Res.get("shared.currency"), account.getSingleTradeCurrency().getNameAndCode()); + addTopLabelTextField(gridPane, ++gridRow, Res.get("shared.country"), account.getCountry().name); + addLimitations(false); + addAccountNameTextFieldWithAutoFillToggleButton(); + } + + @Override + protected void autoFillNameTextField() { + setAccountNameWithString(mobileNrInputTextField.getText()); + } + + @Override + public void addFormForDisplayAccount() { + gridRowFrom = gridRow; + addTopLabelTextField(gridPane, gridRow, Res.get("payment.account.name"), + account.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"), + Res.get(account.getPaymentMethod().getId())); + TextField field = addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.mobile"), + account.getMobileNr()).second; + field.setMouseTransparent(false); + addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.currency"), account.getSingleTradeCurrency().getNameAndCode()); + addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.country"), account.getCountry().name); + addLimitations(true); + } + + @Override + public void updateAllInputsValid() { + allInputsValid.set(isAccountNameValid() + && inputValidator.validate(account.getMobileNr()).isValid); + } +} diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java index 6cb8f84e2f7..7889da9d1b3 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java @@ -36,6 +36,7 @@ import bisq.desktop.components.paymentmethods.ImpsForm; import bisq.desktop.components.paymentmethods.InteracETransferForm; import bisq.desktop.components.paymentmethods.JapanBankTransferForm; +import bisq.desktop.components.paymentmethods.MoneseForm; import bisq.desktop.components.paymentmethods.MoneyBeamForm; import bisq.desktop.components.paymentmethods.MoneyGramForm; import bisq.desktop.components.paymentmethods.NationalBankForm; @@ -50,6 +51,7 @@ import bisq.desktop.components.paymentmethods.RevolutForm; import bisq.desktop.components.paymentmethods.RtgsForm; import bisq.desktop.components.paymentmethods.SameBankForm; +import bisq.desktop.components.paymentmethods.SatispayForm; import bisq.desktop.components.paymentmethods.SepaForm; import bisq.desktop.components.paymentmethods.SepaInstantForm; import bisq.desktop.components.paymentmethods.SpecificBankForm; @@ -577,6 +579,10 @@ private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod, Paym return new CapitualForm(paymentAccount, accountAgeWitnessService, capitualValidator, inputValidator, root, gridRow, formatter); case PaymentMethod.CELPAY_ID: return new CelPayForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + case PaymentMethod.MONESE_ID: + return new MoneseForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); + case PaymentMethod.SATISPAY_ID: + return new SatispayForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); case PaymentMethod.SWIFT_ID: return new SwiftForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter); default: diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java index 188fd9e8863..1c2c3151596 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java @@ -38,6 +38,7 @@ import bisq.desktop.components.paymentmethods.ImpsForm; import bisq.desktop.components.paymentmethods.InteracETransferForm; import bisq.desktop.components.paymentmethods.JapanBankTransferForm; +import bisq.desktop.components.paymentmethods.MoneseForm; import bisq.desktop.components.paymentmethods.MoneyBeamForm; import bisq.desktop.components.paymentmethods.MoneyGramForm; import bisq.desktop.components.paymentmethods.NationalBankForm; @@ -53,6 +54,7 @@ import bisq.desktop.components.paymentmethods.RevolutForm; import bisq.desktop.components.paymentmethods.RtgsForm; import bisq.desktop.components.paymentmethods.SameBankForm; +import bisq.desktop.components.paymentmethods.SatispayForm; import bisq.desktop.components.paymentmethods.SepaForm; import bisq.desktop.components.paymentmethods.SepaInstantForm; import bisq.desktop.components.paymentmethods.SpecificBankForm; @@ -373,6 +375,12 @@ protected void addContent() { case PaymentMethod.CELPAY_ID: gridRow = CelPayForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload); break; + case PaymentMethod.MONESE_ID: + gridRow = MoneseForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload); + break; + case PaymentMethod.SATISPAY_ID: + gridRow = SatispayForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload); + break; case PaymentMethod.SWIFT_ID: gridRow = SwiftForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload, trade); break; diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto index f2ddf37287e..0d345fafe1d 100644 --- a/proto/src/main/proto/pb.proto +++ b/proto/src/main/proto/pb.proto @@ -1001,6 +1001,7 @@ message PaymentAccountPayload { PaxumAccountPayload Paxum_account_payload = 35; SwiftAccountPayload swift_account_payload = 36; CelPayAccountPayload cel_pay_account_payload = 37; + MoneseAccountPayload monese_account_payload = 38; } map exclude_from_json_data = 15; } @@ -1038,6 +1039,7 @@ message CountryBasedPaymentAccountPayload { NequiAccountPayload nequi_account_payload = 12; BizumAccountPayload bizum_account_payload = 13; PixAccountPayload pix_account_payload = 14; + SatispayAccountPayload satispay_account_payload = 15; } } @@ -1284,6 +1286,16 @@ message PixAccountPayload { string pix_key = 1; } +message MoneseAccountPayload { + string mobile_nr = 1; + string holder_name = 2; +} + +message SatispayAccountPayload { + string mobile_nr = 1; + string holder_name = 2; +} + message SwiftAccountPayload { string beneficiary_name = 1; string beneficiary_account_nr = 2;