diff --git a/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java b/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java
index 3979eeac09..c570d749be 100644
--- a/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java
+++ b/core/src/main/java/bisq/core/payment/PaymentAccountFactory.java
@@ -82,6 +82,8 @@ public class PaymentAccountFactory {
return new AdvancedCashAccount();
case PaymentMethod.TRANSFERWISE_ID:
return new TransferwiseAccount();
+ case PaymentMethod.TRANSFERWISE_USD_ID:
+ return new TransferwiseUsdAccount();
case PaymentMethod.PAYSERA_ID:
return new PayseraAccount();
case PaymentMethod.PAXUM_ID:
@@ -114,6 +116,8 @@ public class PaymentAccountFactory {
return new MoneseAccount();
case PaymentMethod.SATISPAY_ID:
return new SatispayAccount();
+ case PaymentMethod.TIKKIE_ID:
+ return new TikkieAccount();
case PaymentMethod.VERSE_ID:
return new VerseAccount();
case PaymentMethod.STRIKE_ID:
diff --git a/core/src/main/java/bisq/core/payment/TikkieAccount.java b/core/src/main/java/bisq/core/payment/TikkieAccount.java
new file mode 100644
index 0000000000..813b2a7089
--- /dev/null
+++ b/core/src/main/java/bisq/core/payment/TikkieAccount.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.TikkieAccountPayload;
+
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+public final class TikkieAccount extends CountryBasedPaymentAccount {
+ public TikkieAccount() {
+ super(PaymentMethod.TIKKIE);
+ }
+
+ @Override
+ protected PaymentAccountPayload createPayload() {
+ return new TikkieAccountPayload(paymentMethod.getId(), id);
+ }
+
+ public void setIban(String iban) {
+ ((TikkieAccountPayload) paymentAccountPayload).setIban(iban);
+ }
+
+ public String getIban() {
+ return ((TikkieAccountPayload) paymentAccountPayload).getIban();
+ }
+
+ public String getMessageForBuyer() {
+ return "payment.tikkie.info.buyer";
+ }
+
+ public String getMessageForSeller() {
+ return "payment.tikkie.info.seller";
+ }
+
+ public String getMessageForAccountCreation() {
+ return "payment.tikkie.info.account";
+ }
+}
diff --git a/core/src/main/java/bisq/core/payment/TransferwiseUsdAccount.java b/core/src/main/java/bisq/core/payment/TransferwiseUsdAccount.java
new file mode 100644
index 0000000000..ab5e03ab41
--- /dev/null
+++ b/core/src/main/java/bisq/core/payment/TransferwiseUsdAccount.java
@@ -0,0 +1,72 @@
+/*
+ * 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.TransferwiseUsdAccountPayload;
+
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+public final class TransferwiseUsdAccount extends CountryBasedPaymentAccount {
+ public TransferwiseUsdAccount() {
+ super(PaymentMethod.TRANSFERWISE_USD);
+ }
+
+ @Override
+ protected PaymentAccountPayload createPayload() {
+ return new TransferwiseUsdAccountPayload(paymentMethod.getId(), id);
+ }
+
+ public void setEmail(String email) {
+ ((TransferwiseUsdAccountPayload) paymentAccountPayload).setEmail(email);
+ }
+
+ public String getEmail() {
+ return ((TransferwiseUsdAccountPayload) paymentAccountPayload).getEmail();
+ }
+
+ public void setHolderName(String accountId) {
+ ((TransferwiseUsdAccountPayload) paymentAccountPayload).setHolderName(accountId);
+ }
+
+ public String getHolderName() {
+ return ((TransferwiseUsdAccountPayload) paymentAccountPayload).getHolderName();
+ }
+
+ public void setBeneficiaryAddress(String address) {
+ ((TransferwiseUsdAccountPayload) paymentAccountPayload).setBeneficiaryAddress(address);
+ }
+
+ public String getBeneficiaryAddress() {
+ return ((TransferwiseUsdAccountPayload) paymentAccountPayload).getBeneficiaryAddress();
+ }
+
+ public String getMessageForBuyer() {
+ return "payment.transferwiseUsd.info.buyer";
+ }
+
+ public String getMessageForSeller() {
+ return "payment.transferwiseUsd.info.seller";
+ }
+
+ public String getMessageForAccountCreation() {
+ return "payment.transferwiseUsd.info.account";
+ }
+}
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 ee9f523bf4..59f76e04a8 100644
--- a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java
+++ b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java
@@ -96,6 +96,7 @@ 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 TikkieAccountPayload extends CountryBasedPaymentAccountPayload {
+ private String iban = "";
+
+ public TikkieAccountPayload(String paymentMethod, String id) {
+ super(paymentMethod, id);
+ }
+
+ private TikkieAccountPayload(String paymentMethod,
+ String id,
+ String countryCode,
+ String iban,
+ long maxTradePeriod,
+ Map excludeFromJsonDataMap) {
+ super(paymentMethod,
+ id,
+ countryCode,
+ maxTradePeriod,
+ excludeFromJsonDataMap);
+
+ this.iban = iban;
+ }
+
+ @Override
+ public Message toProtoMessage() {
+ protobuf.TikkieAccountPayload.Builder builder = protobuf.TikkieAccountPayload.newBuilder()
+ .setIban(iban);
+ final protobuf.CountryBasedPaymentAccountPayload.Builder countryBasedPaymentAccountPayload = getPaymentAccountPayloadBuilder()
+ .getCountryBasedPaymentAccountPayloadBuilder()
+ .setTikkieAccountPayload(builder);
+ return getPaymentAccountPayloadBuilder()
+ .setCountryBasedPaymentAccountPayload(countryBasedPaymentAccountPayload)
+ .build();
+ }
+
+ public static TikkieAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
+ protobuf.CountryBasedPaymentAccountPayload countryBasedPaymentAccountPayload = proto.getCountryBasedPaymentAccountPayload();
+ protobuf.TikkieAccountPayload accountPayloadPB = countryBasedPaymentAccountPayload.getTikkieAccountPayload();
+ return new TikkieAccountPayload(proto.getPaymentMethodId(),
+ proto.getId(),
+ countryBasedPaymentAccountPayload.getCountryCode(),
+ accountPayloadPB.getIban(),
+ proto.getMaxTradePeriod(),
+ new HashMap<>(proto.getExcludeFromJsonDataMap()));
+ }
+
+ @Override
+ public String getPaymentDetails() {
+ return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.iban") + " " + iban;
+ }
+
+ @Override
+ public String getPaymentDetailsForTradePopup() {
+ return getPaymentDetails();
+ }
+
+ @Override
+ public byte[] getAgeWitnessInputData() {
+ return super.getAgeWitnessInputData(iban.getBytes(StandardCharsets.UTF_8));
+ }
+}
diff --git a/core/src/main/java/bisq/core/payment/payload/TransferwiseUsdAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/TransferwiseUsdAccountPayload.java
new file mode 100644
index 0000000000..71cbb383f0
--- /dev/null
+++ b/core/src/main/java/bisq/core/payment/payload/TransferwiseUsdAccountPayload.java
@@ -0,0 +1,109 @@
+/*
+ * 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 TransferwiseUsdAccountPayload extends CountryBasedPaymentAccountPayload {
+ private String email = "";
+ private String holderName = "";
+ private String beneficiaryAddress = "";
+
+ public TransferwiseUsdAccountPayload(String paymentMethod, String id) {
+ super(paymentMethod, id);
+ }
+
+ private TransferwiseUsdAccountPayload(String paymentMethod,
+ String id,
+ String countryCode,
+ String email,
+ String holderName,
+ String beneficiaryAddress,
+ long maxTradePeriod,
+ Map excludeFromJsonDataMap) {
+ super(paymentMethod,
+ id,
+ countryCode,
+ maxTradePeriod,
+ excludeFromJsonDataMap);
+
+ this.email = email;
+ this.holderName = holderName;
+ this.beneficiaryAddress = beneficiaryAddress;
+ }
+
+ @Override
+ public Message toProtoMessage() {
+ protobuf.TransferwiseUsdAccountPayload.Builder builder = protobuf.TransferwiseUsdAccountPayload.newBuilder()
+ .setEmail(email)
+ .setHolderName(holderName)
+ .setBeneficiaryAddress(beneficiaryAddress);
+ final protobuf.CountryBasedPaymentAccountPayload.Builder countryBasedPaymentAccountPayload = getPaymentAccountPayloadBuilder()
+ .getCountryBasedPaymentAccountPayloadBuilder()
+ .setTransferwiseUsdAccountPayload(builder);
+ return getPaymentAccountPayloadBuilder()
+ .setCountryBasedPaymentAccountPayload(countryBasedPaymentAccountPayload)
+ .build();
+ }
+
+ public static TransferwiseUsdAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
+ protobuf.CountryBasedPaymentAccountPayload countryBasedPaymentAccountPayload = proto.getCountryBasedPaymentAccountPayload();
+ protobuf.TransferwiseUsdAccountPayload accountPayloadPB = countryBasedPaymentAccountPayload.getTransferwiseUsdAccountPayload();
+ return new TransferwiseUsdAccountPayload(proto.getPaymentMethodId(),
+ proto.getId(),
+ countryBasedPaymentAccountPayload.getCountryCode(),
+ accountPayloadPB.getEmail(),
+ accountPayloadPB.getHolderName(),
+ accountPayloadPB.getBeneficiaryAddress(),
+ proto.getMaxTradePeriod(),
+ new HashMap<>(proto.getExcludeFromJsonDataMap()));
+ }
+
+ @Override
+ public String getPaymentDetails() {
+ return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.account.userName") + " " + holderName;
+ }
+
+ @Override
+ public String getPaymentDetailsForTradePopup() {
+ return getPaymentDetails();
+ }
+
+ @Override
+ public byte[] getAgeWitnessInputData() {
+ return super.getAgeWitnessInputData(holderName.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 89d6cd4ed3..7566c43292 100644
--- a/core/src/main/java/bisq/core/proto/CoreProtoResolver.java
+++ b/core/src/main/java/bisq/core/proto/CoreProtoResolver.java
@@ -67,7 +67,9 @@ import bisq.core.payment.payload.SpecificBanksAccountPayload;
import bisq.core.payment.payload.StrikeAccountPayload;
import bisq.core.payment.payload.SwiftAccountPayload;
import bisq.core.payment.payload.SwishAccountPayload;
+import bisq.core.payment.payload.TikkieAccountPayload;
import bisq.core.payment.payload.TransferwiseAccountPayload;
+import bisq.core.payment.payload.TransferwiseUsdAccountPayload;
import bisq.core.payment.payload.USPostalMoneyOrderAccountPayload;
import bisq.core.payment.payload.UpholdAccountPayload;
import bisq.core.payment.payload.UpiAccountPayload;
@@ -144,8 +146,12 @@ public class CoreProtoResolver implements ProtoResolver {
return PixAccountPayload.fromProto(proto);
case SATISPAY_ACCOUNT_PAYLOAD:
return SatispayAccountPayload.fromProto(proto);
+ case TIKKIE_ACCOUNT_PAYLOAD:
+ return TikkieAccountPayload.fromProto(proto);
case STRIKE_ACCOUNT_PAYLOAD:
return StrikeAccountPayload.fromProto(proto);
+ case TRANSFERWISE_USD_ACCOUNT_PAYLOAD:
+ return TransferwiseUsdAccountPayload.fromProto(proto);
case IFSC_BASED_ACCOUNT_PAYLOAD:
final protobuf.IfscBasedAccountPayload.MessageCase messageCaseIfsc = proto.getCountryBasedPaymentAccountPayload().getIfscBasedAccountPayload().getMessageCase();
switch (messageCaseIfsc) {
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 bac91b3b28..f98e93db01 100644
--- a/core/src/main/java/bisq/core/trade/statistics/TradeStatistics3.java
+++ b/core/src/main/java/bisq/core/trade/statistics/TradeStatistics3.java
@@ -184,7 +184,9 @@ public final class TradeStatistics3 implements ProcessOncePersistableNetworkPayl
MONESE,
SATISPAY,
VERSE,
- STRIKE
+ STRIKE,
+ TIKKIE,
+ TRANSFERWISE_USD
}
@Getter
diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties
index c3eead303d..ff9b10e08a 100644
--- a/core/src/main/resources/i18n/displayStrings.properties
+++ b/core/src/main/resources/i18n/displayStrings.properties
@@ -3363,6 +3363,7 @@ payment.account.owner=Account owner full name
payment.account.fullName=Full name (first, middle, last)
payment.account.state=State/Province/Region
payment.account.city=City
+payment.account.address=Address
payment.bank.country=Country of bank
payment.account.name.email=Account owner full name / email
payment.account.name.emailAndHolderId=Account owner full name / email / {0}
@@ -3415,6 +3416,7 @@ payment.swift.phone.beneficiary=Beneficiary phone number
payment.swift.account=Account No. (or IBAN)
payment.swift.use.intermediary=Use Intermediary Bank
payment.swift.showPaymentInfo=Show Payment Information...
+payment.transferwiseUsd.address=Account owner address (must be US-based, consider using bank address)
payment.amazon.site=Buy giftcard at
payment.ask=Ask in Trader Chat
@@ -3459,6 +3461,8 @@ payment.bankIdOptional=Bank ID (BIC/SWIFT) (optional)
payment.branchNr=Branch no.
payment.branchNrOptional=Branch no. (optional)
payment.accountNrLabel=Account no. (IBAN)
+payment.iban=IBAN
+payment.tikkie.iban=IBAN used for Bisq trading on Tikkie
payment.accountType=Account type
payment.checking=Checking
payment.savings=Savings
@@ -3731,6 +3735,26 @@ Satispay account limits are individually set. If you want to trade increased amo
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.tikkie.info.account=To use Tikkie you need a bank account (IBAN) in The Netherlands and to be registered for the service.\n\n\
+When you send a Tikkie payment request to an individual person you can ask to receive a maximum of €750 per Tikkie \
+ request. The maximum amount you can request within 24 hours is €2,500 per Tikkie account.\n\n\
+Each bank however may establish its own limits, within these limits, for its clients.\n\n\
+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.tikkie.info.buyer=Please request a payment link from the BTC Seller in trader chat. Once the BTC Seller has \
+ sent you a payment link that matches the correct amount for the trade please proceed to payment.\n\n\
+When the BTC Seller requests a Tikkie payment the maximum they can ask to receive is €750 per Tikkie request. If the \
+ trade is over that amount the BTC Seller will have to sent multiple requests to total the trade amount. The maximum \
+ you can request in a day is €2,500.\n\n\
+Each bank however may establish its own limits, within these limits, for its clients.\n\n\
+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.tikkie.info.seller=Please send a payment link to the BTC Seller in trader chat. Once the BTC \
+ Buyer has sent you payment please check their IBAN detail match the details they have in Bisq.\n\n\
+When the BTC Seller requests a Tikkie payment the maximum they can ask to receive is €750 per Tikkie request. If the \
+ trade is over that amount the BTC Seller will have to sent multiple requests to total the trade amount. The maximum \
+ you can request in a day is €2,500.\n\n\
+Each bank however may establish its own limits, within these limits, for its clients.\n\n\
+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.verse.info.account=Verse is a multiple currency payment method that can send and receive payment in EUR, SEK, HUF, DKK, PLN.\n\n\
When setting up your Verse account in Bisq please make sure to include the username that matches your username in your \
Verse account. This will ensure that when you send funds they show from the correct account and when you receive \
@@ -3764,6 +3788,16 @@ payment.strike.info.seller=Please make sure your payment is received from the BT
The maximum trade size is $1,000 per payment.\n\n\
If you trade over the above limits your trade might be cancelled and there could be a penalty.
+payment.transferwiseUsd.info.account=Due US banking regulation, sending and receiving USD payments has more restrictions \
+ than most other currencies. For this reason USD was not added to Bisq TransferWise payment method.\n\n\
+The TransferWise-USD payment method allows Bisq users to trade in USD.\n\n\
+Anyone with a Wise, formally TransferWise account, can add TransferWise-USD as a payment method in Bisq. This will \
+ allow them to buy and sell BTC with USD.\n\n\
+When trading on Bisq BTC Buyers should not use any reference for reason for payment. If reason for payment is required \
+ they should only use the full name of the TransferWise-USD account owner.
+payment.transferwiseUsd.info.buyer=Please send payment only to the email address in the BTC Seller's Bisq TransferWise-USD account.
+payment.transferwiseUsd.info.seller=Please check that the payment received matches the BTC Buyer's name of the TransferWise-USD account in Bisq.
+
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\
@@ -3926,6 +3960,8 @@ ADVANCED_CASH=Advanced Cash
# suppress inspection "UnusedProperty"
TRANSFERWISE=TransferWise
# suppress inspection "UnusedProperty"
+TRANSFERWISE_USD=TransferWise-USD
+# suppress inspection "UnusedProperty"
PAYSERA=Paysera
# suppress inspection "UnusedProperty"
PAXUM=Paxum
@@ -3958,6 +3994,8 @@ MONESE=Monese
# suppress inspection "UnusedProperty"
SATISPAY=Satispay
# suppress inspection "UnusedProperty"
+TIKKIE=Tikkie
+# suppress inspection "UnusedProperty"
VERSE=Verse
# suppress inspection "UnusedProperty"
STRIKE=Strike
@@ -4014,6 +4052,8 @@ ADVANCED_CASH_SHORT=Advanced Cash
# suppress inspection "UnusedProperty"
TRANSFERWISE_SHORT=TransferWise
# suppress inspection "UnusedProperty"
+TRANSFERWISE_USD_SHORT=TransferWise-USD
+# suppress inspection "UnusedProperty"
PAYSERA_SHORT=Paysera
# suppress inspection "UnusedProperty"
PAXUM_SHORT=Paxum
@@ -4046,6 +4086,8 @@ MONESE_SHORT=Monese
# suppress inspection "UnusedProperty"
SATISPAY_SHORT=Satispay
# suppress inspection "UnusedProperty"
+TIKKIE_SHORT=Tikkie
+# suppress inspection "UnusedProperty"
VERSE_SHORT=Verse
# suppress inspection "UnusedProperty"
STRIKE_SHORT=Strike
diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/TikkieForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/TikkieForm.java
new file mode 100644
index 0000000000..5bed80dae7
--- /dev/null
+++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/TikkieForm.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.desktop.util.validation.IBANValidator;
+
+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.TikkieAccount;
+import bisq.core.payment.payload.PaymentAccountPayload;
+import bisq.core.payment.payload.TikkieAccountPayload;
+import bisq.core.util.coin.CoinFormatter;
+import bisq.core.util.validation.InputValidator;
+
+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 TikkieForm extends PaymentMethodForm {
+ private final TikkieAccount account;
+ private InputTextField ibanField;
+ private final IBANValidator ibanValidator = new IBANValidator("NL");
+
+ public static int addFormForBuyer(GridPane gridPane, int gridRow,
+ PaymentAccountPayload paymentAccountPayload) {
+ addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, 0, Res.get("payment.tikkie.iban"),
+ ((TikkieAccountPayload) paymentAccountPayload).getIban());
+ return gridRow;
+ }
+
+ public TikkieForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService,
+ InputValidator inputValidator, GridPane gridPane,
+ int gridRow, CoinFormatter formatter) {
+ super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
+ this.account = (TikkieAccount) paymentAccount;
+ }
+
+ @Override
+ public void addFormForAddAccount() {
+ // this payment method is only for Netherlands/EUR
+ account.setSingleTradeCurrency(new FiatCurrency("EUR"));
+ CountryUtil.findCountryByCode("NL").ifPresent(c -> account.setCountry(c));
+
+ gridRowFrom = gridRow + 1;
+
+ ibanField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.tikkie.iban"));
+ ibanField.setValidator(ibanValidator);
+ ibanField.textProperty().addListener((ov, oldValue, newValue) -> {
+ account.setIban(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(ibanField.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()));
+ addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.tikkie.iban"), account.getIban())
+ .second.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()
+ && ibanValidator.validate(account.getIban()).isValid);
+ }
+}
diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/TransferwiseUsdForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/TransferwiseUsdForm.java
new file mode 100644
index 0000000000..69a5e9183e
--- /dev/null
+++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/TransferwiseUsdForm.java
@@ -0,0 +1,138 @@
+/*
+ * 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.Layout;
+import bisq.desktop.util.validation.EmailValidator;
+import bisq.desktop.util.validation.LengthValidator;
+
+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.TransferwiseUsdAccount;
+import bisq.core.payment.payload.PaymentAccountPayload;
+import bisq.core.payment.payload.TransferwiseUsdAccountPayload;
+import bisq.core.util.coin.CoinFormatter;
+import bisq.core.util.validation.InputValidator;
+
+import javafx.scene.control.TextArea;
+import javafx.scene.layout.GridPane;
+
+import static bisq.common.util.Utilities.cleanString;
+import static bisq.desktop.util.FormBuilder.*;
+
+public class TransferwiseUsdForm extends PaymentMethodForm {
+ private final TransferwiseUsdAccount account;
+ private final LengthValidator addressValidator = new LengthValidator(0, 100);
+ private EmailValidator emailValidator = new EmailValidator();
+
+ public static int addFormForBuyer(GridPane gridPane, int gridRow,
+ PaymentAccountPayload paymentAccountPayload) {
+
+ addTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1, Res.get("payment.account.owner"),
+ ((TransferwiseUsdAccountPayload) paymentAccountPayload).getHolderName(),
+ Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE);
+
+ addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, 1, Res.get("payment.email"),
+ ((TransferwiseUsdAccountPayload) paymentAccountPayload).getEmail());
+
+ String address = ((TransferwiseUsdAccountPayload) paymentAccountPayload).getBeneficiaryAddress();
+ if (address.length() > 0) {
+ TextArea textAddress = addCompactTopLabelTextArea(gridPane, gridRow, 0, Res.get("payment.account.address"), "").second;
+ textAddress.setMinHeight(70);
+ textAddress.setEditable(false);
+ textAddress.setText(address);
+ }
+
+ return gridRow;
+ }
+
+ public TransferwiseUsdForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService,
+ InputValidator inputValidator, GridPane gridPane,
+ int gridRow, CoinFormatter formatter) {
+ super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
+ this.account = (TransferwiseUsdAccount) paymentAccount;
+ }
+
+ @Override
+ public void addFormForAddAccount() {
+ // this payment method is currently restricted to United States/USD
+ account.setSingleTradeCurrency(new FiatCurrency("USD"));
+ CountryUtil.findCountryByCode("US").ifPresent(c -> account.setCountry(c));
+
+ gridRowFrom = gridRow + 1;
+
+ InputTextField emailField = addInputTextField(gridPane, ++gridRow, Res.get("payment.email"));
+ emailField.setValidator(emailValidator);
+ emailField.textProperty().addListener((ov, oldValue, newValue) -> {
+ account.setEmail(newValue.trim());
+ updateFromInputs();
+ });
+
+ InputTextField holderNameField = addInputTextField(gridPane, ++gridRow, Res.get("payment.account.owner"));
+ holderNameField.setValidator(inputValidator);
+ holderNameField.textProperty().addListener((ov, oldValue, newValue) -> {
+ account.setHolderName(newValue.trim());
+ updateFromInputs();
+ });
+
+ TextArea addressTextArea = addTopLabelTextArea(gridPane, ++gridRow, Res.get("payment.transferwiseUsd.address"), Res.get("payment.transferwiseUsd.address")).second;
+ addressTextArea.setMinHeight(70);
+ addressTextArea.textProperty().addListener((ov, oldValue, newValue) -> {
+ account.setBeneficiaryAddress(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(account.getHolderName());
+ }
+
+ @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()));
+ addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.email"), account.getEmail());
+ addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.account.owner"), account.getHolderName());
+ addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.account.address"), cleanString(account.getBeneficiaryAddress()));
+ 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()
+ && emailValidator.validate(account.getEmail()).isValid
+ && inputValidator.validate(account.getHolderName()).isValid
+ && addressValidator.validate(account.getBeneficiaryAddress()).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 4742864e44..178c63084b 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
@@ -60,7 +60,9 @@ import bisq.desktop.components.paymentmethods.SpecificBankForm;
import bisq.desktop.components.paymentmethods.StrikeForm;
import bisq.desktop.components.paymentmethods.SwiftForm;
import bisq.desktop.components.paymentmethods.SwishForm;
+import bisq.desktop.components.paymentmethods.TikkieForm;
import bisq.desktop.components.paymentmethods.TransferwiseForm;
+import bisq.desktop.components.paymentmethods.TransferwiseUsdForm;
import bisq.desktop.components.paymentmethods.USPostalMoneyOrderForm;
import bisq.desktop.components.paymentmethods.UpholdForm;
import bisq.desktop.components.paymentmethods.UpiForm;
@@ -555,6 +557,8 @@ public class FiatAccountsView extends PaymentAccountsView 0 && !restrictToCountry.equals(input.substring(0, 2)))
+ return new ValidationResult(false, Res.get("validation.iban.invalidCountryCode"));
if (!(Character.isDigit(input.charAt(2)) && Character.isDigit(input.charAt(3))))
return new ValidationResult(false, Res.get("validation.iban.checkSumNotNumeric"));
diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto
index a728e495fb..255cc52c3a 100644
--- a/proto/src/main/proto/pb.proto
+++ b/proto/src/main/proto/pb.proto
@@ -1133,6 +1133,8 @@ message CountryBasedPaymentAccountPayload {
PixAccountPayload pix_account_payload = 14;
SatispayAccountPayload satispay_account_payload = 15;
StrikeAccountPayload strike_account_payload = 16;
+ TikkieAccountPayload tikkie_account_payload = 17;
+ TransferwiseUsdAccountPayload transferwise_usd_account_payload = 18;
}
}
@@ -1354,6 +1356,12 @@ message TransferwiseAccountPayload {
string email = 1;
}
+message TransferwiseUsdAccountPayload {
+ string email = 1;
+ string holder_name = 2;
+ string beneficiary_address = 3;
+}
+
message PayseraAccountPayload {
string email = 1;
}
@@ -1396,6 +1404,10 @@ message StrikeAccountPayload {
string holder_name = 1;
}
+message TikkieAccountPayload {
+ string iban = 1;
+}
+
message VerseAccountPayload {
string holder_name = 1;
}