mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 23:06:39 +01:00
Let users specify trade ccys and selected trade ccy in json form
Several payment methods support multiple trade currencies and a selected trade currency, but the api's payment account creation has not let CLI users specify them in the json form passed to the `createpaymentacct` command. This change adds `tradeCurrencies` and `selectedTradeCurrency` fields to the appropriate json forms.
This commit is contained in:
parent
a2bc999692
commit
f7e6898077
1 changed files with 108 additions and 33 deletions
|
@ -53,10 +53,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import static bisq.common.util.ReflectionUtils.*;
|
import static bisq.common.util.ReflectionUtils.*;
|
||||||
import static bisq.common.util.Utilities.decodeFromHex;
|
import static bisq.common.util.Utilities.decodeFromHex;
|
||||||
import static bisq.core.locale.CountryUtil.findCountryByCode;
|
import static bisq.core.locale.CountryUtil.findCountryByCode;
|
||||||
import static bisq.core.locale.CurrencyUtil.getAllTransferwiseCurrencies;
|
import static bisq.core.locale.CurrencyUtil.*;
|
||||||
import static bisq.core.locale.CurrencyUtil.getCurrencyByCountryCode;
|
import static bisq.core.payment.payload.PaymentMethod.*;
|
||||||
import static bisq.core.locale.CurrencyUtil.getTradeCurrencies;
|
|
||||||
import static bisq.core.locale.CurrencyUtil.getTradeCurrenciesInList;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
|
@ -110,13 +108,7 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
// We're not serializing a real payment account instance here.
|
// We're not serializing a real payment account instance here.
|
||||||
out.beginObject();
|
out.beginObject();
|
||||||
|
|
||||||
// All json forms start with immutable _COMMENTS_ and paymentMethodId fields.
|
writeComments(out, account);
|
||||||
out.name("_COMMENTS_");
|
|
||||||
out.beginArray();
|
|
||||||
for (String s : JSON_COMMENTS) {
|
|
||||||
out.value(s);
|
|
||||||
}
|
|
||||||
out.endArray();
|
|
||||||
|
|
||||||
out.name("paymentMethodId");
|
out.name("paymentMethodId");
|
||||||
out.value(account.getPaymentMethod().getId());
|
out.value(account.getPaymentMethod().getId());
|
||||||
|
@ -131,9 +123,32 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
out.endObject();
|
out.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeComments(JsonWriter out, PaymentAccount account) throws IOException {
|
||||||
|
// All json forms start with immutable _COMMENTS_ and paymentMethodId fields.
|
||||||
|
out.name("_COMMENTS_");
|
||||||
|
out.beginArray();
|
||||||
|
for (String s : JSON_COMMENTS) {
|
||||||
|
out.value(s);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (account.isSwiftAccount()) {
|
||||||
|
// Add extra comments for more complex swift account form.
|
||||||
|
List<String> wrappedSwiftComments = Res.getWrappedAsList("payment.swift.info", 110);
|
||||||
|
for (String line : wrappedSwiftComments) {
|
||||||
|
out.value(line);
|
||||||
|
}
|
||||||
|
out.value("See https://bisq.wiki/SWIFT");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
out.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeInnerMutableFields(JsonWriter out, PaymentAccount account) {
|
private void writeInnerMutableFields(JsonWriter out, PaymentAccount account) {
|
||||||
if (account.isTransferwiseAccount())
|
if (account.canSupportMultipleCurrencies()) {
|
||||||
writeTradeCurrenciesField(out, account);
|
writeTradeCurrenciesField(out, account);
|
||||||
|
writeSelectedTradeCurrencyField(out, account);
|
||||||
|
}
|
||||||
|
|
||||||
fieldSettersMap.forEach((field, value) -> {
|
fieldSettersMap.forEach((field, value) -> {
|
||||||
try {
|
try {
|
||||||
|
@ -170,7 +185,7 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
String fieldName = "tradeCurrencies";
|
String fieldName = "tradeCurrencies";
|
||||||
log.debug("Append form with non-settable field: {}", fieldName);
|
log.debug("Append form with non-settable field: {}", fieldName);
|
||||||
out.name(fieldName);
|
out.name(fieldName);
|
||||||
out.value("comma delimited currency code list, e.g., gbp,eur");
|
out.value("comma delimited currency code list, e.g., gbp,eur,jpy,usd");
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
String errMsg = format("cannot create a new %s json form",
|
String errMsg = format("cannot create a new %s json form",
|
||||||
account.getClass().getSimpleName());
|
account.getClass().getSimpleName());
|
||||||
|
@ -179,6 +194,22 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PaymentAccounts that support multiple 'tradeCurrencies' need to define a
|
||||||
|
// 'selectedTradeCurrency' field (not simply defaulting to first in list).
|
||||||
|
// Write this field to the form.
|
||||||
|
private void writeSelectedTradeCurrencyField(JsonWriter out, PaymentAccount account) {
|
||||||
|
try {
|
||||||
|
String fieldName = "selectedTradeCurrency";
|
||||||
|
log.debug("Append form with settable field: {}", fieldName);
|
||||||
|
out.name(fieldName);
|
||||||
|
out.value("primary trading currency code, e.g., eur");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
String errMsg = format("cannot create a new %s json form",
|
||||||
|
account.getClass().getSimpleName());
|
||||||
|
log.error(StringUtils.capitalize(errMsg) + ".", ex);
|
||||||
|
throw new IllegalStateException("programmer error: " + errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaymentAccount read(JsonReader in) throws IOException {
|
public PaymentAccount read(JsonReader in) throws IOException {
|
||||||
|
@ -187,12 +218,17 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
while (in.hasNext()) {
|
while (in.hasNext()) {
|
||||||
String currentFieldName = in.nextName();
|
String currentFieldName = in.nextName();
|
||||||
|
|
||||||
// The tradeCurrency field is common to all payment account types,
|
// The tradeCurrencies field is common to all payment account types,
|
||||||
// but has no setter.
|
// but has no setter.
|
||||||
if (didReadTradeCurrenciesField(in, account, currentFieldName))
|
if (didReadTradeCurrenciesField(in, account, currentFieldName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Some of the fields are common to all payment account types.
|
// The selectedTradeCurrency field is common to all payment account types,
|
||||||
|
// but is @Nullable, and may not need to be explicitly defined by user.
|
||||||
|
if (didReadSelectedTradeCurrencyField(in, account, currentFieldName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Some fields are common to all payment account types.
|
||||||
if (didReadCommonField(in, account, currentFieldName))
|
if (didReadCommonField(in, account, currentFieldName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -318,30 +354,22 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
PaymentAccount account,
|
PaymentAccount account,
|
||||||
String fieldName) {
|
String fieldName) {
|
||||||
// The PaymentAccount.tradeCurrencies field is a special case because it has
|
// The PaymentAccount.tradeCurrencies field is a special case because it has
|
||||||
// no setter, and we add currencies to the List here. Normally, it is an
|
// no setter, so we add currencies to the List here if the payment account
|
||||||
// excluded field, TransferwiseAccount excepted.
|
// supports multiple trade currencies.
|
||||||
if (fieldName.equals("tradeCurrencies")) {
|
if (fieldName.equals("tradeCurrencies")) {
|
||||||
String fieldValue = nextStringOrNull(in);
|
String fieldValue = nextStringOrNull(in);
|
||||||
List<String> currencyCodes = commaDelimitedCodesToList.apply(fieldValue);
|
List<String> currencyCodes = commaDelimitedCodesToList.apply(fieldValue);
|
||||||
|
Optional<List<TradeCurrency>> tradeCurrencies = getReconciledTradeCurrencies(currencyCodes, account);
|
||||||
Optional<List<TradeCurrency>> tradeCurrencies;
|
|
||||||
if (account.isTransferwiseAccount())
|
|
||||||
tradeCurrencies = getTradeCurrenciesInList(currencyCodes, getAllTransferwiseCurrencies());
|
|
||||||
else
|
|
||||||
tradeCurrencies = getTradeCurrencies(currencyCodes);
|
|
||||||
|
|
||||||
if (tradeCurrencies.isPresent()) {
|
if (tradeCurrencies.isPresent()) {
|
||||||
for (TradeCurrency tradeCurrency : tradeCurrencies.get()) {
|
for (TradeCurrency tradeCurrency : tradeCurrencies.get()) {
|
||||||
account.addCurrency(tradeCurrency);
|
account.addCurrency(tradeCurrency);
|
||||||
}
|
}
|
||||||
// For api users, define a selected currency.
|
|
||||||
account.setSelectedTradeCurrency(account.getTradeCurrency().orElse(null));
|
|
||||||
} else {
|
} else {
|
||||||
// Log a warning. We should not throw an exception here because the
|
// Log a warning. We should not throw an exception here because the
|
||||||
// gson library will not pass it up to the calling Bisq class as it
|
// gson library will not pass it up to the calling Bisq object exactly as
|
||||||
// would be defined here. Do a check in a calling class to make sure
|
// it would be defined here (causing confusion). Do a check in a calling
|
||||||
// the tradeCurrencies field is populated in the PaymentAccount
|
// class to make sure the tradeCurrencies field is populated in the
|
||||||
// object, if it is required for the payment account method.
|
// PaymentAccount object, if it is required for the payment account method.
|
||||||
log.warn("No trade currencies were found in the {} account form.",
|
log.warn("No trade currencies were found in the {} account form.",
|
||||||
account.getPaymentMethod().getDisplayString());
|
account.getPaymentMethod().getDisplayString());
|
||||||
}
|
}
|
||||||
|
@ -350,14 +378,61 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<List<TradeCurrency>> getReconciledTradeCurrencies(List<String> currencyCodes,
|
||||||
|
PaymentAccount account) {
|
||||||
|
if (account.hasPaymentMethodWithId(ADVANCED_CASH_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllAdvancedCashCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(AMAZON_GIFT_CARD_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllAmazonGiftCardCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(CAPITUAL_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllCapitualCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(MONEY_GRAM_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllMoneyGramCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(PAXUM_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllPaxumCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(PAYSERA_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllPayseraCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(REVOLUT_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllRevolutCurrencies());
|
||||||
|
/*else if (account.hasPaymentMethodWithId(SWIFT_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, new ArrayList<>(getAllSortedFiatCurrencies()));*/
|
||||||
|
else if (account.hasPaymentMethodWithId(TRANSFERWISE_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllTransferwiseCurrencies());
|
||||||
|
else if (account.hasPaymentMethodWithId(UPHOLD_ID))
|
||||||
|
return getTradeCurrenciesInList(currencyCodes, getAllUpholdCurrencies());
|
||||||
|
else
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean didReadSelectedTradeCurrencyField(JsonReader in,
|
||||||
|
PaymentAccount account,
|
||||||
|
String fieldName) {
|
||||||
|
if (fieldName.equals("selectedTradeCurrency")) {
|
||||||
|
String fieldValue = nextStringOrNull(in);
|
||||||
|
if (fieldValue != null && !fieldValue.isEmpty()) {
|
||||||
|
Optional<TradeCurrency> tradeCurrency = getTradeCurrency(fieldValue.toUpperCase());
|
||||||
|
if (tradeCurrency.isPresent()) {
|
||||||
|
account.setSelectedTradeCurrency(tradeCurrency.get());
|
||||||
|
} else {
|
||||||
|
// Log an error. We should not throw an exception here because the
|
||||||
|
// gson library will not pass it up to the calling Bisq object exactly as
|
||||||
|
// it would be defined here (causing confusion).
|
||||||
|
log.error("{} is not a valid trade currency code.", fieldValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean didReadCommonField(JsonReader in,
|
private boolean didReadCommonField(JsonReader in,
|
||||||
PaymentAccount account,
|
PaymentAccount account,
|
||||||
String fieldName) throws IOException {
|
String fieldName) throws IOException {
|
||||||
switch (fieldName) {
|
switch (fieldName) {
|
||||||
case "_COMMENTS_":
|
case "_COMMENTS_":
|
||||||
case "paymentMethodId":
|
case "paymentMethodId":
|
||||||
// Skip over the the comments and paymentMethodId, which is already
|
// Skip over comments and paymentMethodId field, which
|
||||||
// set on the PaymentAccount instance.
|
// are already set on the PaymentAccount instance.
|
||||||
in.skipValue();
|
in.skipValue();
|
||||||
return true;
|
return true;
|
||||||
case "accountName":
|
case "accountName":
|
||||||
|
@ -388,7 +463,7 @@ class PaymentAccountTypeAdapter extends TypeAdapter<PaymentAccount> {
|
||||||
((CountryBasedPaymentAccount) account).setCountry(country.get());
|
((CountryBasedPaymentAccount) account).setCountry(country.get());
|
||||||
FiatCurrency fiatCurrency = getCurrencyByCountryCode(checkNotNull(countryCode));
|
FiatCurrency fiatCurrency = getCurrencyByCountryCode(checkNotNull(countryCode));
|
||||||
account.setSingleTradeCurrency(fiatCurrency);
|
account.setSingleTradeCurrency(fiatCurrency);
|
||||||
} else if (account.isMoneyGramAccount()) {
|
} else if (account.hasPaymentMethodWithId(MONEY_GRAM_ID)) {
|
||||||
((MoneyGramAccount) account).setCountry(country.get());
|
((MoneyGramAccount) account).setCountry(country.get());
|
||||||
} else {
|
} else {
|
||||||
String errMsg = format("cannot set the country on a %s",
|
String errMsg = format("cannot set the country on a %s",
|
||||||
|
|
Loading…
Add table
Reference in a new issue