Skip to content

Commit

Permalink
Merge pull request #5501 from BtcContributor/capitual
Browse files Browse the repository at this point in the history
Add Capitual payment method
  • Loading branch information
ripcurlx authored Jul 19, 2021
2 parents 1c5b5a8 + ca02610 commit 3512313
Show file tree
Hide file tree
Showing 14 changed files with 387 additions and 2 deletions.
9 changes: 9 additions & 0 deletions core/src/main/java/bisq/core/locale/CurrencyUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,15 @@ public static List<TradeCurrency> getAllAmazonGiftCardCurrencies() {
return currencies;
}

public static List<TradeCurrency> getAllCapitualCurrencies() {
return new ArrayList<>(Arrays.asList(
new FiatCurrency("BRL"),
new FiatCurrency("EUR"),
new FiatCurrency("GBP"),
new FiatCurrency("USD")
));
}

// https://www.revolut.com/help/getting-started/exchanging-currencies/what-fiat-currencies-are-supported-for-holding-and-exchange
public static List<TradeCurrency> getAllRevolutCurrencies() {
ArrayList<TradeCurrency> currencies = new ArrayList<>(Arrays.asList(
Expand Down
46 changes: 46 additions & 0 deletions core/src/main/java/bisq/core/payment/CapitualAccount.java
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

package bisq.core.payment;

import bisq.core.locale.CurrencyUtil;
import bisq.core.payment.payload.CapitualAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.PaymentMethod;

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
public final class CapitualAccount extends PaymentAccount {
public CapitualAccount() {
super(PaymentMethod.CAPITUAL);
tradeCurrencies.addAll(CurrencyUtil.getAllCapitualCurrencies());
}

@Override
protected PaymentAccountPayload createPayload() {
return new CapitualAccountPayload(paymentMethod.getId(), id);
}

public void setAccountNr(String accountNr) {
((CapitualAccountPayload) paymentAccountPayload).setAccountNr(accountNr);
}

public String getAccountNr() {
return ((CapitualAccountPayload) paymentAccountPayload).getAccountNr();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ public static PaymentAccount getPaymentAccount(PaymentMethod paymentMethod) {
return new AmazonGiftCardAccount();
case PaymentMethod.BLOCK_CHAINS_INSTANT_ID:
return new InstantCryptoCurrencyAccount();
case PaymentMethod.CAPITUAL_ID:
return new CapitualAccount();

// Cannot be deleted as it would break old trade history entries
case PaymentMethod.OK_PAY_ID:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

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 CapitualAccountPayload extends PaymentAccountPayload {
private String accountNr = "";

public CapitualAccountPayload(String paymentMethod, String id) {
super(paymentMethod, id);
}


///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////

private CapitualAccountPayload(String paymentMethod,
String id,
String accountNr,
long maxTradePeriod,
Map<String, String> excludeFromJsonDataMap) {
super(paymentMethod,
id,
maxTradePeriod,
excludeFromJsonDataMap);

this.accountNr = accountNr;
}

@Override
public Message toProtoMessage() {
return getPaymentAccountPayloadBuilder()
.setCapitualAccountPayload(protobuf.CapitualAccountPayload.newBuilder()
.setAccountNr(accountNr))
.build();
}

public static CapitualAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
return new CapitualAccountPayload(proto.getPaymentMethodId(),
proto.getId(),
proto.getCapitualAccountPayload().getAccountNr(),
proto.getMaxTradePeriod(),
new HashMap<>(proto.getExcludeFromJsonDataMap()));
}

///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public String getPaymentDetails() {
return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.capitual.cap") + " " + accountNr;
}

@Override
public String getPaymentDetailsForTradePopup() {
return getPaymentDetails();
}

@Override
public byte[] getAgeWitnessInputData() {
return super.getAgeWitnessInputData(accountNr.getBytes(StandardCharsets.UTF_8));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
public static final String AMAZON_GIFT_CARD_ID = "AMAZON_GIFT_CARD";
public static final String BLOCK_CHAINS_INSTANT_ID = "BLOCK_CHAINS_INSTANT";
public static final String CASH_BY_MAIL_ID = "CASH_BY_MAIL";
public static final String CAPITUAL_ID = "CAPITUAL";

// Cannot be deleted as it would break old trade history entries
@Deprecated
Expand Down Expand Up @@ -140,6 +141,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
public static PaymentMethod AMAZON_GIFT_CARD;
public static PaymentMethod BLOCK_CHAINS_INSTANT;
public static PaymentMethod CASH_BY_MAIL;
public static PaymentMethod CAPITUAL;

// Cannot be deleted as it would break old trade history entries
@Deprecated
Expand Down Expand Up @@ -191,6 +193,8 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK),
ADVANCED_CASH = new PaymentMethod(ADVANCED_CASH_ID, DAY, DEFAULT_TRADE_LIMIT_VERY_LOW_RISK),
TRANSFERWISE = new PaymentMethod(TRANSFERWISE_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
CAPITUAL = new PaymentMethod(CAPITUAL_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),


// Japan
JAPAN_BANK = new PaymentMethod(JAPAN_BANK_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK),
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/bisq/core/proto/CoreProtoResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import bisq.core.payment.payload.AliPayAccountPayload;
import bisq.core.payment.payload.AmazonGiftCardAccountPayload;
import bisq.core.payment.payload.AustraliaPayidPayload;
import bisq.core.payment.payload.CapitualAccountPayload;
import bisq.core.payment.payload.CashAppAccountPayload;
import bisq.core.payment.payload.CashByMailAccountPayload;
import bisq.core.payment.payload.CashDepositAccountPayload;
Expand Down Expand Up @@ -159,6 +160,8 @@ public PaymentAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
return AmazonGiftCardAccountPayload.fromProto(proto);
case INSTANT_CRYPTO_CURRENCY_ACCOUNT_PAYLOAD:
return InstantCryptoCurrencyPayload.fromProto(proto);
case CAPITUAL_ACCOUNT_PAYLOAD:
return CapitualAccountPayload.fromProto(proto);

// Cannot be deleted as it would break old trade history entries
case O_K_PAY_ACCOUNT_PAYLOAD:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ private enum PaymentMethodMapper {
BLOCK_CHAINS_INSTANT,
TRANSFERWISE,
AMAZON_GIFT_CARD,
CASH_BY_MAIL
CASH_BY_MAIL,
CAPITUAL
}

@Getter
Expand Down
7 changes: 6 additions & 1 deletion core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3268,6 +3268,7 @@ payment.select.altcoin=Select or search Altcoin
payment.secret=Secret question
payment.answer=Answer
payment.wallet=Wallet ID
payment.capitual.cap=CAP Code
payment.amazon.site=Buy giftcard at
payment.ask=Ask in Trader Chat
payment.uphold.accountId=Username or email or phone no.
Expand Down Expand Up @@ -3481,7 +3482,6 @@ payment.amazonGiftCard.info=To pay with Amazon eGift Card, you will need to send
to tell your trading peer the reference text you picked so they can verify your payment)\n\
- Amazon eGift Cards can only be redeemed on the Amazon website they were purchased on (e.g., a gift card purchased on amazon.it can only be redeemed on amazon.it)


# We use constants from the code so we do not use our normal naming convention
# dynamic values are not recognized by IntelliJ

Expand Down Expand Up @@ -3564,6 +3564,8 @@ TRANSFERWISE=TransferWise
AMAZON_GIFT_CARD=Amazon eGift Card
# suppress inspection "UnusedProperty"
BLOCK_CHAINS_INSTANT=Altcoins Instant
# suppress inspection "UnusedProperty"
CAPITUAL=Capitual

# Deprecated: Cannot be deleted as it would break old trade history entries
# suppress inspection "UnusedProperty"
Expand Down Expand Up @@ -3616,6 +3618,8 @@ TRANSFERWISE_SHORT=TransferWise
AMAZON_GIFT_CARD_SHORT=Amazon eGift Card
# suppress inspection "UnusedProperty"
BLOCK_CHAINS_INSTANT_SHORT=Altcoins Instant
# suppress inspection "UnusedProperty"
CAPITUAL_SHORT=Capitual

# Deprecated: Cannot be deleted as it would break old trade history entries
# suppress inspection "UnusedProperty"
Expand Down Expand Up @@ -3706,3 +3710,4 @@ validation.phone.tooManyDigits=There are too many digits in {0} to be a valid ph
validation.phone.invalidDialingCode=Country dialing code for number {0} is invalid for country {1}. \
The correct dialing code is {2}.
validation.invalidAddressList=Must be comma separated list of valid addresses
validation.capitual.invalidFormat=Must be a valid CAP code of format: CAP-XXXXXX (6 alphanumeric characters)
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

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.CapitualValidator;

import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.CapitualAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.CapitualAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.validation.InputValidator;

import bisq.common.util.Tuple2;

import org.apache.commons.lang3.StringUtils;

import javafx.scene.control.Label;
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.addTopLabelFlowPane;

public class CapitualForm extends PaymentMethodForm {
private final CapitualAccount capitualAccount;
private final CapitualValidator capitualValidator;
private InputTextField accountNrInputTextField;

public static int addFormForBuyer(GridPane gridPane, int gridRow,
PaymentAccountPayload paymentAccountPayload) {
addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.capitual.cap"),
((CapitualAccountPayload) paymentAccountPayload).getAccountNr());
return gridRow;
}

public CapitualForm(PaymentAccount paymentAccount,
AccountAgeWitnessService accountAgeWitnessService,
CapitualValidator capitualValidator,
InputValidator inputValidator,
GridPane gridPane,
int gridRow,
CoinFormatter formatter) {
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
this.capitualAccount = (CapitualAccount) paymentAccount;
this.capitualValidator = capitualValidator;
}

@Override
public void addFormForAddAccount() {
gridRowFrom = gridRow + 1;

accountNrInputTextField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.capitual.cap"));
accountNrInputTextField.setValidator(capitualValidator);
accountNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
capitualAccount.setAccountNr(newValue);
updateFromInputs();
});

addCurrenciesGrid(true);
addLimitations(false);
addAccountNameTextFieldWithAutoFillToggleButton();
}

private void addCurrenciesGrid(boolean isEditable) {
final Tuple2<Label, FlowPane> labelFlowPaneTuple2 = addTopLabelFlowPane(gridPane, ++gridRow, Res.get("payment.supportedCurrencies"), 0);

FlowPane flowPane = labelFlowPaneTuple2.second;

if (isEditable)
flowPane.setId("flow-pane-checkboxes-bg");
else
flowPane.setId("flow-pane-checkboxes-non-editable-bg");

CurrencyUtil.getAllCapitualCurrencies().forEach(e ->
fillUpFlowPaneWithCurrencies(isEditable, flowPane, e, capitualAccount));
}

@Override
protected void autoFillNameTextField() {
if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected()) {
String accountNr = accountNrInputTextField.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;
addCompactTopLabelTextField(gridPane, gridRow, Res.get("payment.account.name"),
capitualAccount.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"),
Res.get(capitualAccount.getPaymentMethod().getId()));
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.capitual.cap"),
capitualAccount.getAccountNr());
addLimitations(true);
addCurrenciesGrid(false);
}

@Override
public void updateAllInputsValid() {
allInputsValid.set(isAccountNameValid()
&& capitualValidator.validate(capitualAccount.getAccountNr()).isValid
&& !capitualAccount.getTradeCurrencies().isEmpty());
}

}
Loading

0 comments on commit 3512313

Please sign in to comment.