diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java index c19975ce4d..979db8e9b7 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java @@ -157,15 +157,15 @@ public class TakeBuyBTCOfferWithNationalBankAcctTest extends AbstractTradeTest { assertNotNull(bobsPaymentAccount); var alicesTrade = aliceClient.getTrade(tradeId); - assertNotEquals("", alicesTrade.getContract().getMakerPaymentAccountPayload().getPaymentDetails()); - assertNotEquals("", alicesTrade.getContract().getTakerPaymentAccountPayload().getPaymentDetails()); + assertNotEquals(null, alicesTrade.getContract().getMakerPaymentAccountPayload()); + assertNotEquals(null, alicesTrade.getContract().getTakerPaymentAccountPayload()); var alicesContractJson = alicesTrade.getContractAsJson(); verifyJsonContractIncludesBankAccountDetails(alicesContractJson, alicesPaymentAccount); verifyJsonContractIncludesBankAccountDetails(alicesContractJson, bobsPaymentAccount); var bobsTrade = bobClient.getTrade(tradeId); - assertNotEquals("", bobsTrade.getContract().getMakerPaymentAccountPayload().getPaymentDetails()); - assertNotEquals("", bobsTrade.getContract().getTakerPaymentAccountPayload().getPaymentDetails()); + assertNotEquals(null, bobsTrade.getContract().getMakerPaymentAccountPayload()); + assertNotEquals(null, bobsTrade.getContract().getTakerPaymentAccountPayload()); var bobsContractJson = bobsTrade.getContractAsJson(); verifyJsonContractIncludesBankAccountDetails(bobsContractJson, alicesPaymentAccount); verifyJsonContractIncludesBankAccountDetails(bobsContractJson, bobsPaymentAccount); diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java index be5b986096..91230dc94e 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java @@ -246,8 +246,8 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder { ContractInfo contract = t.getContract(); boolean isBuyerMakerAndSellerTaker = contract.getIsBuyerMakerAndSellerTaker(); return isBuyerMakerAndSellerTaker // (is BTC buyer / maker) - ? contract.getTakerPaymentAccountPayload().getAddress() - : contract.getMakerPaymentAccountPayload().getAddress(); + ? contract.getTakerPaymentAccountPayload().getCryptoCurrencyAccountPayload().getAddress() + : contract.getMakerPaymentAccountPayload().getCryptoCurrencyAccountPayload().getAddress(); } else { return ""; } diff --git a/common/src/main/java/bisq/common/util/ReflectionUtils.java b/common/src/main/java/bisq/common/util/ReflectionUtils.java index 7af96505c7..0ae45c1114 100644 --- a/common/src/main/java/bisq/common/util/ReflectionUtils.java +++ b/common/src/main/java/bisq/common/util/ReflectionUtils.java @@ -96,7 +96,7 @@ public class ReflectionUtils { } public static boolean isSetterOnClass(Method setter, Class clazz) { - return clazz.equals(setter.getDeclaringClass()); + return setter.getDeclaringClass().isAssignableFrom(clazz); } public static String getVisibilityModifierAsString(Field field) { diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java index cad7f9d5a5..8291c11b09 100644 --- a/core/src/main/java/bisq/core/api/CoreApi.java +++ b/core/src/main/java/bisq/core/api/CoreApi.java @@ -502,14 +502,18 @@ public class CoreApi { return paymentAccountsService.getPaymentAccounts(); } - public List getFiatPaymentMethods() { - return paymentAccountsService.getFiatPaymentMethods(); + public List getPaymentMethods() { + return paymentAccountsService.getPaymentMethods(); } public PaymentAccountForm getPaymentAccountForm(String paymentMethodId) { return paymentAccountsService.getPaymentAccountForm(paymentMethodId); } + public PaymentAccountForm getPaymentAccountForm(PaymentAccount paymentAccount) { + return paymentAccountsService.getPaymentAccountForm(paymentAccount); + } + public PaymentAccount createCryptoCurrencyPaymentAccount(String accountName, String currencyCode, String address, diff --git a/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java index 6438b12b14..e1ad09b59a 100644 --- a/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java +++ b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java @@ -19,7 +19,6 @@ package bisq.core.api; import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.api.model.PaymentAccountForm; -import bisq.core.api.model.PaymentAccountForm; import bisq.core.api.model.PaymentAccountFormField; import bisq.core.locale.CryptoCurrency; import bisq.core.locale.CurrencyUtil; @@ -64,8 +63,6 @@ class CorePaymentAccountsService { this.user = user; } - // Fiat Currency Accounts - PaymentAccount createPaymentAccount(PaymentAccountForm form) { PaymentAccount paymentAccount = form.toPaymentAccount(); setSelectedTradeCurrency(paymentAccount); // TODO: selected trade currency is function of offer, not payment account payload @@ -81,12 +78,15 @@ class CorePaymentAccountsService { private static void setSelectedTradeCurrency(PaymentAccount paymentAccount) { TradeCurrency singleTradeCurrency = paymentAccount.getSingleTradeCurrency(); List tradeCurrencies = paymentAccount.getTradeCurrencies(); - if (singleTradeCurrency != null) return; - else if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) { - if (tradeCurrencies.contains(CurrencyUtil.getDefaultTradeCurrency())) + if (singleTradeCurrency != null) { + paymentAccount.setSelectedTradeCurrency(singleTradeCurrency); + return; + } else if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) { + if (tradeCurrencies.contains(CurrencyUtil.getDefaultTradeCurrency())) { paymentAccount.setSelectedTradeCurrency(CurrencyUtil.getDefaultTradeCurrency()); - else + } else { paymentAccount.setSelectedTradeCurrency(tradeCurrencies.get(0)); + } } } @@ -94,9 +94,8 @@ class CorePaymentAccountsService { return user.getPaymentAccounts(); } - List getFiatPaymentMethods() { + List getPaymentMethods() { return PaymentMethod.getPaymentMethods().stream() - .filter(paymentMethod -> !paymentMethod.isBlockchain()) .sorted(Comparator.comparing(PaymentMethod::getId)) .collect(Collectors.toList()); } @@ -105,6 +104,10 @@ class CorePaymentAccountsService { return PaymentAccountForm.getForm(paymentMethodId); } + PaymentAccountForm getPaymentAccountForm(PaymentAccount paymentAccount) { + return paymentAccount.toForm(); + } + String getPaymentAccountFormAsString(String paymentMethodId) { File jsonForm = getPaymentAccountFormFile(paymentMethodId); jsonForm.deleteOnExit(); // If just asking for a string, delete the form file. diff --git a/core/src/main/java/bisq/core/api/model/ContractInfo.java b/core/src/main/java/bisq/core/api/model/ContractInfo.java index e93fd64c1b..3175251518 100644 --- a/core/src/main/java/bisq/core/api/model/ContractInfo.java +++ b/core/src/main/java/bisq/core/api/model/ContractInfo.java @@ -18,13 +18,13 @@ package bisq.core.api.model; import bisq.common.Payload; +import bisq.core.payment.payload.PaymentAccountPayload; +import bisq.core.proto.CoreProtoResolver; import java.util.function.Supplier; import lombok.Getter; -import static bisq.core.api.model.PaymentAccountPayloadInfo.emptyPaymentAccountPayload; - /** * A lightweight Trade Contract constructed from a trade's json contract. * Many fields in the core Contract are ignored, but can be added as needed. @@ -38,8 +38,8 @@ public class ContractInfo implements Payload { private final boolean isBuyerMakerAndSellerTaker; private final String makerAccountId; private final String takerAccountId; - private final PaymentAccountPayloadInfo makerPaymentAccountPayload; - private final PaymentAccountPayloadInfo takerPaymentAccountPayload; + private final PaymentAccountPayload makerPaymentAccountPayload; + private final PaymentAccountPayload takerPaymentAccountPayload; private final String makerPayoutAddressString; private final String takerPayoutAddressString; private final long lockTime; @@ -50,8 +50,8 @@ public class ContractInfo implements Payload { boolean isBuyerMakerAndSellerTaker, String makerAccountId, String takerAccountId, - PaymentAccountPayloadInfo makerPaymentAccountPayload, - PaymentAccountPayloadInfo takerPaymentAccountPayload, + PaymentAccountPayload makerPaymentAccountPayload, + PaymentAccountPayload takerPaymentAccountPayload, String makerPayoutAddressString, String takerPayoutAddressString, long lockTime) { @@ -77,8 +77,8 @@ public class ContractInfo implements Payload { false, "", "", - emptyPaymentAccountPayload.get(), - emptyPaymentAccountPayload.get(), + null, + null, "", "", 0); @@ -88,14 +88,15 @@ public class ContractInfo implements Payload { /////////////////////////////////////////////////////////////////////////////////////////// public static ContractInfo fromProto(bisq.proto.grpc.ContractInfo proto) { + CoreProtoResolver coreProtoResolver = new CoreProtoResolver(); return new ContractInfo(proto.getBuyerNodeAddress(), proto.getSellerNodeAddress(), proto.getArbitratorNodeAddress(), proto.getIsBuyerMakerAndSellerTaker(), proto.getMakerAccountId(), proto.getTakerAccountId(), - proto.getMakerPaymentAccountPayload() == null ? null : PaymentAccountPayloadInfo.fromProto(proto.getMakerPaymentAccountPayload()), - proto.getTakerPaymentAccountPayload() == null ? null : PaymentAccountPayloadInfo.fromProto(proto.getTakerPaymentAccountPayload()), + proto.getMakerPaymentAccountPayload() == null ? null : PaymentAccountPayload.fromProto(proto.getMakerPaymentAccountPayload(), coreProtoResolver), + proto.getTakerPaymentAccountPayload() == null ? null : PaymentAccountPayload.fromProto(proto.getTakerPaymentAccountPayload(), coreProtoResolver), proto.getMakerPayoutAddressString(), proto.getTakerPayoutAddressString(), proto.getLockTime()); @@ -113,8 +114,8 @@ public class ContractInfo implements Payload { .setMakerPayoutAddressString(makerPayoutAddressString) .setTakerPayoutAddressString(takerPayoutAddressString) .setLockTime(lockTime); - if (makerPaymentAccountPayload != null) builder.setMakerPaymentAccountPayload(makerPaymentAccountPayload.toProtoMessage()); - if (takerPaymentAccountPayload != null) builder.setTakerPaymentAccountPayload(takerPaymentAccountPayload.toProtoMessage()); + if (makerPaymentAccountPayload != null) builder.setMakerPaymentAccountPayload((protobuf.PaymentAccountPayload) makerPaymentAccountPayload.toProtoMessage()); + if (takerPaymentAccountPayload != null) builder.setTakerPaymentAccountPayload((protobuf.PaymentAccountPayload) takerPaymentAccountPayload.toProtoMessage()); return builder.build(); } } diff --git a/core/src/main/java/bisq/core/api/model/PaymentAccountForm.java b/core/src/main/java/bisq/core/api/model/PaymentAccountForm.java index b8d881feb0..b94e16ab37 100644 --- a/core/src/main/java/bisq/core/api/model/PaymentAccountForm.java +++ b/core/src/main/java/bisq/core/api/model/PaymentAccountForm.java @@ -17,7 +17,6 @@ package bisq.core.api.model; -import static bisq.core.payment.payload.PaymentMethod.getPaymentMethod; import static com.google.common.base.Preconditions.checkNotNull; import static java.lang.String.format; import static java.lang.System.getProperty; @@ -28,15 +27,14 @@ import bisq.common.proto.persistable.PersistablePayload; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountFactory; import bisq.core.payment.payload.PaymentMethod; +import bisq.core.trade.HavenoUtils; + import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.CaseFormat; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import java.lang.reflect.Type; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; @@ -60,11 +58,8 @@ import org.apache.commons.lang3.StringUtils; @Slf4j public final class PaymentAccountForm implements PersistablePayload { - private static final GsonBuilder gsonBuilder = new GsonBuilder() - .setPrettyPrinting() - .serializeNulls(); - public enum FormId { + BLOCK_CHAINS, REVOLUT, SEPA, SEPA_INSTANT, @@ -113,6 +108,10 @@ public final class PaymentAccountForm implements PersistablePayload { return new PaymentAccountForm(FormId.fromProto(proto.getId()), fields); } + public void addField(PaymentAccountFormField field) { + fields.add(field); + } + public String getValue(PaymentAccountFormField.FieldId fieldId) { for (PaymentAccountFormField field : fields) { if (field.getId() == fieldId) { @@ -122,14 +121,6 @@ public final class PaymentAccountForm implements PersistablePayload { throw new IllegalArgumentException("Form does not contain field " + fieldId); } - /** - * Get a structured form for the given payment method. - */ - public static PaymentAccountForm getForm(String paymentMethodId) { - PaymentAccount paymentAccount = PaymentAccountFactory.getPaymentAccount(PaymentMethod.getPaymentMethod(paymentMethodId)); - return paymentAccount.toForm(); - } - /** * Convert this form to a PaymentAccount json string. */ @@ -137,7 +128,7 @@ public final class PaymentAccountForm implements PersistablePayload { Map formMap = new HashMap(); formMap.put("paymentMethodId", getId().toString()); for (PaymentAccountFormField field : getFields()) { - formMap.put(toCamelCase(field.getId().toString()), field.getValue()); + formMap.put(HavenoUtils.toCamelCase(field.getId().toString()), field.getValue()); } return new Gson().toJson(formMap); } @@ -146,19 +137,15 @@ public final class PaymentAccountForm implements PersistablePayload { * Convert this form to a PaymentAccount. */ public PaymentAccount toPaymentAccount() { - return toPaymentAccount(toPaymentAccountJsonString()); + return PaymentAccount.fromJson(toPaymentAccountJsonString()); } /** - * De-serialize a PaymentAccount json string into a new PaymentAccount instance. - * - * @param paymentAccountJsonString The json data representing a new payment account form. - * @return A populated PaymentAccount subclass instance. + * Get a structured form for the given payment method. */ - public static PaymentAccount toPaymentAccount(String paymentAccountJsonString) { - Class clazz = getPaymentAccountClassFromJson(paymentAccountJsonString); - Gson gson = gsonBuilder.registerTypeAdapter(clazz, new PaymentAccountTypeAdapter(clazz)).create(); - return gson.fromJson(paymentAccountJsonString, clazz); + public static PaymentAccountForm getForm(String paymentMethodId) { + PaymentAccount paymentAccount = PaymentAccountFactory.getPaymentAccount(PaymentMethod.getPaymentMethod(paymentMethodId)); + return paymentAccount.toForm(); } // ----------------------------- OLD FORM API ----------------------------- @@ -170,7 +157,7 @@ public final class PaymentAccountForm implements PersistablePayload { * @return A uniquely named tmp file used to define new payment account details. */ public static File getPaymentAccountForm(String paymentMethodId) { - PaymentMethod paymentMethod = getPaymentMethod(paymentMethodId); + PaymentMethod paymentMethod = PaymentMethod.getPaymentMethod(paymentMethodId); File file = getTmpJsonFile(paymentMethodId); try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(checkNotNull(file), false), UTF_8)) { PaymentAccount paymentAccount = PaymentAccountFactory.getPaymentAccount(paymentMethod); @@ -193,8 +180,7 @@ public final class PaymentAccountForm implements PersistablePayload { @SuppressWarnings("unused") @VisibleForTesting public static PaymentAccount toPaymentAccount(File jsonForm) { - String jsonString = toJsonString(jsonForm); - return toPaymentAccount(jsonString); + return PaymentAccount.fromJson(toJsonString(jsonForm)); } public static String toJsonString(File jsonFile) { @@ -243,22 +229,4 @@ public final class PaymentAccountForm implements PersistablePayload { } return file; } - - // -------------------------------- HELPERS ------------------------------- - - private static String toCamelCase(String underscore) { - return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, underscore); - } - - private static Class getPaymentAccountClassFromJson(String json) { - Map jsonMap = gsonBuilder.create().fromJson(json, (Type) Object.class); - String paymentMethodId = checkNotNull((String) jsonMap.get("paymentMethodId"), - format("cannot not find a paymentMethodId in json string: %s", json)); - return getPaymentAccountClass(paymentMethodId); - } - - private static Class getPaymentAccountClass(String paymentMethodId) { - PaymentMethod paymentMethod = getPaymentMethod(paymentMethodId); - return PaymentAccountFactory.getPaymentAccount(paymentMethod).getClass(); - } } diff --git a/core/src/main/java/bisq/core/api/model/PaymentAccountFormField.java b/core/src/main/java/bisq/core/api/model/PaymentAccountFormField.java index f81419125a..a48c4e791e 100644 --- a/core/src/main/java/bisq/core/api/model/PaymentAccountFormField.java +++ b/core/src/main/java/bisq/core/api/model/PaymentAccountFormField.java @@ -40,6 +40,7 @@ import javax.annotation.concurrent.Immutable; public final class PaymentAccountFormField implements PersistablePayload { public enum FieldId { + ADDRESS, ACCEPTED_COUNTRY_CODES, ACCOUNT_ID, ACCOUNT_NAME, @@ -96,8 +97,7 @@ public final class PaymentAccountFormField implements PersistablePayload { SPECIAL_INSTRUCTIONS, STATE, TRADE_CURRENCIES, - USER_NAME, - VIRTUAL_PAYMENT_ADDRESS; + USER_NAME; public static PaymentAccountFormField.FieldId fromProto(protobuf.PaymentAccountFormField.FieldId fieldId) { return ProtoUtil.enumFromProto(PaymentAccountFormField.FieldId.class, fieldId.name()); diff --git a/core/src/main/java/bisq/core/api/model/PaymentAccountPayloadInfo.java b/core/src/main/java/bisq/core/api/model/PaymentAccountPayloadInfo.java deleted file mode 100644 index e0f4ac5c39..0000000000 --- a/core/src/main/java/bisq/core/api/model/PaymentAccountPayloadInfo.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Haveno. - * - * Haveno 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. - * - * Haveno 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 Haveno. If not, see . - */ - -package bisq.core.api.model; - -import bisq.core.payment.payload.CryptoCurrencyAccountPayload; -import bisq.core.payment.payload.InstantCryptoCurrencyPayload; -import bisq.core.payment.payload.PaymentAccountPayload; - -import bisq.common.Payload; - -import java.util.Optional; -import java.util.function.Supplier; - -import lombok.Getter; - -import javax.annotation.Nullable; - -@Getter -public class PaymentAccountPayloadInfo implements Payload { - - private final String id; - private final String paymentMethodId; - @Nullable - private final String address; - - public PaymentAccountPayloadInfo(String id, - String paymentMethodId, - @Nullable String address) { - this.id = id; - this.paymentMethodId = paymentMethodId; - this.address = address; - } - - public static PaymentAccountPayloadInfo toPaymentAccountPayloadInfo(PaymentAccountPayload paymentAccountPayload) { - if (paymentAccountPayload == null) return null; - Optional address = Optional.empty(); - if (paymentAccountPayload instanceof CryptoCurrencyAccountPayload) - address = Optional.of(((CryptoCurrencyAccountPayload) paymentAccountPayload).getAddress()); - else if (paymentAccountPayload instanceof InstantCryptoCurrencyPayload) - address = Optional.of(((InstantCryptoCurrencyPayload) paymentAccountPayload).getAddress()); - - return new PaymentAccountPayloadInfo(paymentAccountPayload.getId(), - paymentAccountPayload.getPaymentMethodId(), - address.orElse("")); - } - - // For transmitting TradeInfo messages when no contract & payloads are available. - public static Supplier emptyPaymentAccountPayload = () -> - new PaymentAccountPayloadInfo("", "", ""); - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - public static PaymentAccountPayloadInfo fromProto(bisq.proto.grpc.PaymentAccountPayloadInfo proto) { - return new PaymentAccountPayloadInfo(proto.getId(), proto.getPaymentMethodId(), proto.getAddress()); - } - - @Override - public bisq.proto.grpc.PaymentAccountPayloadInfo toProtoMessage() { - return bisq.proto.grpc.PaymentAccountPayloadInfo.newBuilder() - .setId(id) - .setPaymentMethodId(paymentMethodId) - .setAddress(address != null ? address : "") - .build(); - } -} diff --git a/core/src/main/java/bisq/core/api/model/TradeInfo.java b/core/src/main/java/bisq/core/api/model/TradeInfo.java index 753bcad8ea..0bc9d5f392 100644 --- a/core/src/main/java/bisq/core/api/model/TradeInfo.java +++ b/core/src/main/java/bisq/core/api/model/TradeInfo.java @@ -28,7 +28,6 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import static bisq.core.api.model.OfferInfo.toOfferInfo; -import static bisq.core.api.model.PaymentAccountPayloadInfo.toPaymentAccountPayloadInfo; import static bisq.core.util.PriceUtil.reformatMarketPrice; import static bisq.core.util.VolumeUtil.formatVolume; import static java.util.Objects.requireNonNull; @@ -141,8 +140,8 @@ public class TradeInfo implements Payload { contract.isBuyerMakerAndSellerTaker(), contract.getMakerAccountId(), contract.getTakerAccountId(), - toPaymentAccountPayloadInfo(trade.getMaker().getPaymentAccountPayload()), - toPaymentAccountPayloadInfo(trade.getTaker().getPaymentAccountPayload()), + trade.getMaker().getPaymentAccountPayload(), + trade.getTaker().getPaymentAccountPayload(), contract.getMakerPayoutAddressString(), contract.getTakerPayoutAddressString(), contract.getLockTime()); diff --git a/core/src/main/java/bisq/core/offer/OpenOfferManager.java b/core/src/main/java/bisq/core/offer/OpenOfferManager.java index 831f8ede59..8a2dbbfa48 100644 --- a/core/src/main/java/bisq/core/offer/OpenOfferManager.java +++ b/core/src/main/java/bisq/core/offer/OpenOfferManager.java @@ -611,11 +611,11 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe } public Optional getOpenOfferById(String offerId) { - return openOffers.stream().filter(e -> e.getId().equals(offerId)).findFirst(); + return openOffers.getObservableList().stream().filter(e -> e.getId().equals(offerId)).findFirst(); } public Optional getSignedOfferById(String offerId) { - return signedOffers.stream().filter(e -> e.getOfferId().equals(offerId)).findFirst(); + return signedOffers.getObservableList().stream().filter(e -> e.getOfferId().equals(offerId)).findFirst(); } /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/core/src/main/java/bisq/core/payment/AssetAccount.java b/core/src/main/java/bisq/core/payment/AssetAccount.java index a31138fdda..732bb19598 100644 --- a/core/src/main/java/bisq/core/payment/AssetAccount.java +++ b/core/src/main/java/bisq/core/payment/AssetAccount.java @@ -17,7 +17,7 @@ package bisq.core.payment; -import bisq.core.payment.payload.AssetsAccountPayload; +import bisq.core.payment.payload.AssetAccountPayload; import bisq.core.payment.payload.PaymentMethod; public abstract class AssetAccount extends PaymentAccount { @@ -26,10 +26,10 @@ public abstract class AssetAccount extends PaymentAccount { } public void setAddress(String address) { - ((AssetsAccountPayload) paymentAccountPayload).setAddress(address); + ((AssetAccountPayload) paymentAccountPayload).setAddress(address); } public String getAddress() { - return ((AssetsAccountPayload) paymentAccountPayload).getAddress(); + return ((AssetAccountPayload) paymentAccountPayload).getAddress(); } } diff --git a/core/src/main/java/bisq/core/payment/CountryBasedPaymentAccount.java b/core/src/main/java/bisq/core/payment/CountryBasedPaymentAccount.java index bdcbf7c19e..e0065f73d6 100644 --- a/core/src/main/java/bisq/core/payment/CountryBasedPaymentAccount.java +++ b/core/src/main/java/bisq/core/payment/CountryBasedPaymentAccount.java @@ -23,7 +23,6 @@ import bisq.core.payment.payload.CountryBasedPaymentAccountPayload; import bisq.core.payment.payload.PaymentMethod; import java.util.List; import lombok.EqualsAndHashCode; -import lombok.NonNull; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -35,17 +34,14 @@ public abstract class CountryBasedPaymentAccount extends PaymentAccount { @Nullable protected List acceptedCountries; - /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// - protected CountryBasedPaymentAccount(PaymentMethod paymentMethod) { super(paymentMethod); } - /////////////////////////////////////////////////////////////////////////////////////////// // Getter, Setter /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/core/src/main/java/bisq/core/payment/CryptoCurrencyAccount.java b/core/src/main/java/bisq/core/payment/CryptoCurrencyAccount.java index 14cc659291..fefd70be53 100644 --- a/core/src/main/java/bisq/core/payment/CryptoCurrencyAccount.java +++ b/core/src/main/java/bisq/core/payment/CryptoCurrencyAccount.java @@ -33,6 +33,13 @@ import lombok.NonNull; @EqualsAndHashCode(callSuper = true) public final class CryptoCurrencyAccount extends AssetAccount { + private static final List INPUT_FIELD_IDS = List.of( + PaymentAccountFormField.FieldId.ACCOUNT_NAME, + PaymentAccountFormField.FieldId.TRADE_CURRENCIES, + PaymentAccountFormField.FieldId.ADDRESS, + PaymentAccountFormField.FieldId.SALT + ); + public static final List SUPPORTED_CURRENCIES = new ArrayList<>(CurrencyUtil.getAllSortedCryptoCurrencies()); public CryptoCurrencyAccount() { @@ -51,6 +58,13 @@ public final class CryptoCurrencyAccount extends AssetAccount { @Override public @NonNull List getInputFieldIds() { - throw new RuntimeException("Not implemented"); + return INPUT_FIELD_IDS; + } + + @Override + protected PaymentAccountFormField getEmptyFormField(PaymentAccountFormField.FieldId fieldId) { + var field = super.getEmptyFormField(fieldId); + if (field.getId() == PaymentAccountFormField.FieldId.TRADE_CURRENCIES) field.setComponent(PaymentAccountFormField.Component.SELECT_ONE); + return field; } } diff --git a/core/src/main/java/bisq/core/payment/PaymentAccount.java b/core/src/main/java/bisq/core/payment/PaymentAccount.java index e905aea06a..c286f70a5f 100644 --- a/core/src/main/java/bisq/core/payment/PaymentAccount.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccount.java @@ -19,11 +19,12 @@ package bisq.core.payment; import bisq.core.api.model.PaymentAccountForm; import bisq.core.api.model.PaymentAccountFormField; +import bisq.core.api.model.PaymentAccountFormField.Component; +import bisq.core.api.model.PaymentAccountFormField.FieldId; import bisq.core.locale.BankUtil; import bisq.core.locale.Country; import bisq.core.locale.CountryUtil; import bisq.core.locale.CurrencyUtil; -import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.payload.PaymentMethod; @@ -35,6 +36,7 @@ import bisq.core.payment.validation.EmailValidator; import bisq.core.payment.validation.IBANValidator; import bisq.core.payment.validation.LengthValidator; import bisq.core.proto.CoreProtoResolver; +import bisq.core.trade.HavenoUtils; import bisq.core.util.validation.InputValidator; import bisq.core.util.validation.InputValidator.ValidationResult; import bisq.common.proto.ProtoUtil; @@ -43,7 +45,9 @@ import bisq.common.util.Utilities; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.function.Function; @@ -59,12 +63,17 @@ import lombok.extern.slf4j.Slf4j; import javax.annotation.Nullable; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + import static bisq.core.payment.payload.PaymentMethod.TRANSFERWISE_ID; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Arrays.stream; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; +import java.lang.reflect.Type; + @EqualsAndHashCode @ToString @Getter @@ -89,6 +98,10 @@ public abstract class PaymentAccount implements PersistablePayload { @Nullable protected TradeCurrency selectedTradeCurrency; + private static final GsonBuilder gsonBuilder = new GsonBuilder() + .setPrettyPrinting() + .serializeNulls(); + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -104,6 +117,12 @@ public abstract class PaymentAccount implements PersistablePayload { paymentAccountPayload = createPayload(); } + public void init(PaymentAccountPayload payload) { + id = payload.getId(); + creationDate = new Date().getTime(); + paymentAccountPayload = payload; + } + /////////////////////////////////////////////////////////////////////////////////////////// // PROTO BUFFER @@ -123,6 +142,19 @@ public abstract class PaymentAccount implements PersistablePayload { return builder.build(); } + public protobuf.PaymentAccount toProtoMessage(protobuf.PaymentAccountPayload paymentAccountPayload) { + checkNotNull(accountName, "accountName must not be null"); + protobuf.PaymentAccount.Builder builder = protobuf.PaymentAccount.newBuilder() + .setPaymentMethod(paymentMethod.toProtoMessage()) + .setId(id) + .setCreationDate(creationDate) + .setPaymentAccountPayload(paymentAccountPayload) + .setAccountName(accountName) + .addAllTradeCurrencies(ProtoUtil.collectionToProto(tradeCurrencies, protobuf.TradeCurrency.class)); + Optional.ofNullable(selectedTradeCurrency).ifPresent(selectedTradeCurrency -> builder.setSelectedTradeCurrency((protobuf.TradeCurrency) selectedTradeCurrency.toProtoMessage())); + return builder.build(); + } + public static PaymentAccount fromProto(protobuf.PaymentAccount proto, CoreProtoResolver coreProtoResolver) { String paymentMethodId = proto.getPaymentMethod().getId(); List tradeCurrencies = proto.getTradeCurrenciesList().stream() @@ -286,15 +318,56 @@ public abstract class PaymentAccount implements PersistablePayload { @NonNull public abstract List getSupportedCurrencies(); + // ---------------------------- SERIALIZATION ----------------------------- + + public String toJson() { + Map jsonMap = new HashMap(); + if (paymentAccountPayload != null) jsonMap.putAll(gsonBuilder.create().fromJson(paymentAccountPayload.toJson(), (Type) Object.class)); + jsonMap.put("accountName", getAccountName()); + jsonMap.put("accountId", getId()); + if (paymentAccountPayload != null) jsonMap.put("salt", getSaltAsHex()); + return gsonBuilder.create().toJson(jsonMap); + } + + /** + * Deserialize a PaymentAccount json string into a new PaymentAccount instance. + * + * @param paymentAccountJsonString The json data representing a new payment account form. + * @return A populated PaymentAccount subclass instance. + */ + public static PaymentAccount fromJson(String paymentAccountJsonString) { + Class clazz = getPaymentAccountClassFromJson(paymentAccountJsonString); + Gson gson = gsonBuilder.registerTypeAdapter(clazz, new PaymentAccountTypeAdapter(clazz)).create(); + return gson.fromJson(paymentAccountJsonString, clazz); + } + + private static Class getPaymentAccountClassFromJson(String json) { + Map jsonMap = gsonBuilder.create().fromJson(json, (Type) Object.class); + String paymentMethodId = checkNotNull((String) jsonMap.get("paymentMethodId"), + String.format("cannot not find a paymentMethodId in json string: %s", json)); + return getPaymentAccountClass(paymentMethodId); + } + + private static Class getPaymentAccountClass(String paymentMethodId) { + PaymentMethod paymentMethod = PaymentMethod.getPaymentMethod(paymentMethodId); + return PaymentAccountFactory.getPaymentAccount(paymentMethod).getClass(); + } + // ------------------------- PAYMENT ACCOUNT FORM ------------------------- @NonNull public abstract List getInputFieldIds(); public PaymentAccountForm toForm() { + + // convert to json map + Map jsonMap = gsonBuilder.create().fromJson(toJson(), (Type) Object.class); + + // build form PaymentAccountForm form = new PaymentAccountForm(PaymentAccountForm.FormId.valueOf(paymentMethod.getId())); for (PaymentAccountFormField.FieldId fieldId : getInputFieldIds()) { PaymentAccountFormField field = getEmptyFormField(fieldId); + field.setValue((String) jsonMap.get(HavenoUtils.toCamelCase(field.getId().toString()))); form.getFields().add(field); } return form; @@ -463,8 +536,9 @@ public abstract class PaymentAccount implements PersistablePayload { case USER_NAME: processValidationResult(new LengthValidator(3, 100).validate(value)); break; - case VIRTUAL_PAYMENT_ADDRESS: - throw new IllegalArgumentException("Not implemented"); + case ADDRESS: + processValidationResult(new LengthValidator(10, 150).validate(value)); // TODO: validate crypto address + break; default: throw new RuntimeException("Unhandled form field: " + fieldId); } @@ -673,8 +747,12 @@ public abstract class PaymentAccount implements PersistablePayload { field.setMinLength(3); field.setMaxLength(100); break; - case VIRTUAL_PAYMENT_ADDRESS: - throw new IllegalArgumentException("Not implemented"); + case ADDRESS: + field.setComponent(PaymentAccountFormField.Component.TEXT); + field.setLabel("Address"); + field.setMinLength(10); + field.setMaxLength(150); + break; default: throw new RuntimeException("Unhandled form field: " + field); } diff --git a/core/src/main/java/bisq/core/api/model/PaymentAccountTypeAdapter.java b/core/src/main/java/bisq/core/payment/PaymentAccountTypeAdapter.java similarity index 98% rename from core/src/main/java/bisq/core/api/model/PaymentAccountTypeAdapter.java rename to core/src/main/java/bisq/core/payment/PaymentAccountTypeAdapter.java index dcd83fd33e..ef2619ff13 100644 --- a/core/src/main/java/bisq/core/api/model/PaymentAccountTypeAdapter.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccountTypeAdapter.java @@ -15,7 +15,7 @@ * along with Haveno. If not, see . */ -package bisq.core.api.model; +package bisq.core.payment; import bisq.core.locale.Country; @@ -23,9 +23,6 @@ import bisq.core.locale.CountryUtil; import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; -import bisq.core.payment.CountryBasedPaymentAccount; -import bisq.core.payment.MoneyGramAccount; -import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentAccountPayload; import com.google.gson.TypeAdapter; @@ -156,13 +153,10 @@ class PaymentAccountTypeAdapter extends TypeAdapter { field.getType().getSimpleName(), field.getName(), value); - String fieldName = field.getName(); out.name(fieldName); - if (fieldName.equals("country")) - out.value("your two letter country code"); - else - out.value("your " + fieldName.toLowerCase()); + if (fieldName.equals("country")) out.value("your two letter country code"); + else out.value("your " + fieldName.toLowerCase()); } } catch (Exception ex) { String errMsg = format("cannot create a new %s json form", diff --git a/core/src/main/java/bisq/core/payment/RevolutAccount.java b/core/src/main/java/bisq/core/payment/RevolutAccount.java index 495349c468..d6e4587a25 100644 --- a/core/src/main/java/bisq/core/payment/RevolutAccount.java +++ b/core/src/main/java/bisq/core/payment/RevolutAccount.java @@ -24,7 +24,6 @@ import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.payload.PaymentMethod; import bisq.core.payment.payload.RevolutAccountPayload; import java.util.List; -import java.util.stream.Collectors; import lombok.EqualsAndHashCode; import lombok.NonNull; diff --git a/core/src/main/java/bisq/core/payment/TransferwiseAccount.java b/core/src/main/java/bisq/core/payment/TransferwiseAccount.java index 4ede998ee6..e32e6d7c09 100644 --- a/core/src/main/java/bisq/core/payment/TransferwiseAccount.java +++ b/core/src/main/java/bisq/core/payment/TransferwiseAccount.java @@ -25,7 +25,6 @@ import bisq.core.payment.payload.PaymentMethod; import bisq.core.payment.payload.TransferwiseAccountPayload; import java.util.List; -import java.util.Map; import lombok.EqualsAndHashCode; import lombok.NonNull; diff --git a/core/src/main/java/bisq/core/payment/payload/AssetsAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/AssetAccountPayload.java similarity index 92% rename from core/src/main/java/bisq/core/payment/payload/AssetsAccountPayload.java rename to core/src/main/java/bisq/core/payment/payload/AssetAccountPayload.java index 035bcd6136..f204d9bffd 100644 --- a/core/src/main/java/bisq/core/payment/payload/AssetsAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/AssetAccountPayload.java @@ -34,10 +34,10 @@ import lombok.extern.slf4j.Slf4j; @Setter @Getter @Slf4j -public abstract class AssetsAccountPayload extends PaymentAccountPayload { +public abstract class AssetAccountPayload extends PaymentAccountPayload { protected String address = ""; - protected AssetsAccountPayload(String paymentMethod, String id) { + protected AssetAccountPayload(String paymentMethod, String id) { super(paymentMethod, id); } @@ -46,7 +46,7 @@ public abstract class AssetsAccountPayload extends PaymentAccountPayload { // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// - protected AssetsAccountPayload(String paymentMethod, + protected AssetAccountPayload(String paymentMethod, String id, String address, long maxTradePeriod, diff --git a/core/src/main/java/bisq/core/payment/payload/CryptoCurrencyAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/CryptoCurrencyAccountPayload.java index cbdd7c5b23..2eba4c5d8c 100644 --- a/core/src/main/java/bisq/core/payment/payload/CryptoCurrencyAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/CryptoCurrencyAccountPayload.java @@ -33,7 +33,7 @@ import lombok.extern.slf4j.Slf4j; @Setter @Getter @Slf4j -public final class CryptoCurrencyAccountPayload extends AssetsAccountPayload { +public final class CryptoCurrencyAccountPayload extends AssetAccountPayload { public CryptoCurrencyAccountPayload(String paymentMethod, String id) { super(paymentMethod, id); diff --git a/core/src/main/java/bisq/core/payment/payload/InstantCryptoCurrencyPayload.java b/core/src/main/java/bisq/core/payment/payload/InstantCryptoCurrencyPayload.java index 90722725bb..9d96a62e44 100644 --- a/core/src/main/java/bisq/core/payment/payload/InstantCryptoCurrencyPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/InstantCryptoCurrencyPayload.java @@ -33,7 +33,7 @@ import lombok.extern.slf4j.Slf4j; @Setter @Getter @Slf4j -public final class InstantCryptoCurrencyPayload extends AssetsAccountPayload { +public final class InstantCryptoCurrencyPayload extends AssetAccountPayload { public InstantCryptoCurrencyPayload(String paymentMethod, String id) { super(paymentMethod, id); diff --git a/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java index 19bd133b2f..e3f4cc698f 100644 --- a/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java @@ -23,9 +23,12 @@ import bisq.common.crypto.Hash; import bisq.common.proto.network.NetworkPayload; import bisq.common.util.JsonExclude; import bisq.common.util.Utilities; +import bisq.core.proto.CoreProtoResolver; import org.apache.commons.lang3.ArrayUtils; +import com.google.gson.GsonBuilder; + import java.nio.charset.StandardCharsets; import java.util.HashMap; @@ -66,6 +69,10 @@ public abstract class PaymentAccountPayload implements NetworkPayload, UsedForTr @JsonExclude protected final Map excludeFromJsonDataMap; + private static final GsonBuilder gsonBuilder = new GsonBuilder() + .setPrettyPrinting() + .serializeNulls(); + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -109,11 +116,18 @@ public abstract class PaymentAccountPayload implements NetworkPayload, UsedForTr return builder; } + public static PaymentAccountPayload fromProto(protobuf.PaymentAccountPayload proto, CoreProtoResolver coreProtoResolver) { + return coreProtoResolver.fromProto(proto); + } /////////////////////////////////////////////////////////////////////////////////////////// // API /////////////////////////////////////////////////////////////////////////////////////////// + public String toJson() { + return gsonBuilder.create().toJson(this); + } + public abstract String getPaymentDetails(); public abstract String getPaymentDetailsForTradePopup(); 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 bbe8ede640..ac2880c5f4 100644 --- a/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java +++ b/core/src/main/java/bisq/core/payment/payload/PaymentMethod.java @@ -331,6 +331,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable getPaymentMethods() { List paymentMethodIds = List.of( + BLOCK_CHAINS_ID, REVOLUT_ID, SEPA_ID, SEPA_INSTANT_ID, diff --git a/core/src/main/java/bisq/core/trade/HavenoUtils.java b/core/src/main/java/bisq/core/trade/HavenoUtils.java index c5c8849767..bae9425644 100644 --- a/core/src/main/java/bisq/core/trade/HavenoUtils.java +++ b/core/src/main/java/bisq/core/trade/HavenoUtils.java @@ -36,6 +36,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import com.google.common.base.CaseFormat; import com.google.common.base.Charsets; /** @@ -225,6 +226,7 @@ public class HavenoUtils { } } + // TODO: replace with GenUtils.executeTasks() public static void executeTasks(Collection tasks) { executeTasks(tasks, tasks.size()); } @@ -241,4 +243,8 @@ public class HavenoUtils { throw new RuntimeException(e); } } + + public static String toCamelCase(String underscore) { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, underscore); + } } diff --git a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java index cfe4af656e..5dad52e3d3 100644 --- a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java @@ -750,7 +750,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D handleTaskRunnerSuccess(null, null, "SendDepositsConfirmedMessages"); }, (errorMessage) -> { - handleTaskRunnerFault(null, null, errorMessage); + handleTaskRunnerFault(null, null, "SendDepositsConfirmedMessages", errorMessage); }))) .executeTasks(true); awaitTradeLatch(); diff --git a/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofModel.java b/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofModel.java index 002d4d2481..b9270430f4 100644 --- a/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofModel.java +++ b/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofModel.java @@ -18,7 +18,7 @@ package bisq.core.trade.txproof.xmr; import bisq.core.monetary.Volume; -import bisq.core.payment.payload.AssetsAccountPayload; +import bisq.core.payment.payload.AssetAccountPayload; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.trade.Trade; import bisq.core.trade.txproof.AssetTxProofModel; @@ -26,8 +26,6 @@ import bisq.core.user.AutoConfirmSettings; import bisq.common.app.DevEnv; -import org.bitcoinj.core.Coin; - import com.google.common.annotations.VisibleForTesting; import java.util.Date; @@ -67,7 +65,7 @@ public class XmrTxProofModel implements AssetTxProofModel { PaymentAccountPayload sellersPaymentAccountPayload = checkNotNull(trade.getSeller().getPaymentAccountPayload()); recipientAddress = DevEnv.isDevMode() ? XmrTxProofModel.DEV_ADDRESS : // For dev testing we need to add the matching address to the dev tx key and dev view key - ((AssetsAccountPayload) sellersPaymentAccountPayload).getAddress(); + ((AssetAccountPayload) sellersPaymentAccountPayload).getAddress(); txHash = trade.getCounterCurrencyTxId(); txKey = trade.getCounterCurrencyExtraData(); tradeDate = trade.getDate(); diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java index dc99dde2a4..ad9abdc37a 100644 --- a/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java +++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java @@ -21,8 +21,10 @@ import bisq.core.api.CoreApi; import bisq.core.api.model.PaymentAccountForm; import bisq.core.api.model.PaymentAccountFormField; import bisq.core.payment.PaymentAccount; +import bisq.core.payment.PaymentAccountFactory; +import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.payload.PaymentMethod; - +import bisq.core.proto.CoreProtoResolver; import bisq.proto.grpc.CreateCryptoCurrencyPaymentAccountReply; import bisq.proto.grpc.CreateCryptoCurrencyPaymentAccountRequest; import bisq.proto.grpc.CreatePaymentAccountReply; @@ -104,7 +106,7 @@ class GrpcPaymentAccountsService extends PaymentAccountsImplBase { public void getPaymentMethods(GetPaymentMethodsRequest req, StreamObserver responseObserver) { try { - var paymentMethods = coreApi.getFiatPaymentMethods().stream() + var paymentMethods = coreApi.getPaymentMethods().stream() .map(PaymentMethod::toProtoMessage) .collect(Collectors.toList()); var reply = GetPaymentMethodsReply.newBuilder() @@ -120,7 +122,16 @@ class GrpcPaymentAccountsService extends PaymentAccountsImplBase { public void getPaymentAccountForm(GetPaymentAccountFormRequest req, StreamObserver responseObserver) { try { - var form = coreApi.getPaymentAccountForm(req.getPaymentMethodId()); + PaymentAccountForm form = null; + if (req.getPaymentMethodId().isEmpty()) { + PaymentAccount account = PaymentAccountFactory.getPaymentAccount(PaymentMethod.getPaymentMethod(req.getPaymentAccountPayload().getPaymentMethodId())); + account.setAccountName("tmp"); + account.init(PaymentAccountPayload.fromProto(req.getPaymentAccountPayload(), new CoreProtoResolver())); + account.setAccountName(null); + form = coreApi.getPaymentAccountForm(account); + } else { + form = coreApi.getPaymentAccountForm(req.getPaymentMethodId()); + } var reply = GetPaymentAccountFormReply.newBuilder() .setPaymentAccountForm(form.toProtoMessage()) .build(); diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java index cf8cfdf20d..096fb154af 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/AssetsForm.java @@ -31,7 +31,7 @@ import bisq.core.locale.TradeCurrency; import bisq.core.payment.AssetAccount; import bisq.core.payment.InstantCryptoCurrencyAccount; import bisq.core.payment.PaymentAccount; -import bisq.core.payment.payload.AssetsAccountPayload; +import bisq.core.payment.payload.AssetAccountPayload; import bisq.core.payment.payload.PaymentAccountPayload; import bisq.core.payment.validation.AltCoinAddressValidator; import bisq.core.util.coin.CoinFormatter; @@ -71,7 +71,7 @@ public class AssetsForm extends PaymentMethodForm { PaymentAccountPayload paymentAccountPayload, String labelTitle) { addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow, labelTitle, - ((AssetsAccountPayload) paymentAccountPayload).getAddress()); + ((AssetAccountPayload) paymentAccountPayload).getAddress()); return gridRow; } 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 233282515d..6fb2098a8d 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 @@ -87,7 +87,7 @@ import bisq.core.network.MessageState; import bisq.core.offer.Offer; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountUtil; -import bisq.core.payment.payload.AssetsAccountPayload; +import bisq.core.payment.payload.AssetAccountPayload; import bisq.core.payment.payload.CashByMailAccountPayload; import bisq.core.payment.payload.CashDepositAccountPayload; import bisq.core.payment.payload.F2FAccountPayload; @@ -548,7 +548,7 @@ public class BuyerStep2View extends TradeStepView { } else { showConfirmPaymentStartedPopup(); } - } else if (sellersPaymentAccountPayload instanceof AssetsAccountPayload && isXmrTrade()) { + } else if (sellersPaymentAccountPayload instanceof AssetAccountPayload && isXmrTrade()) { SetXmrTxKeyWindow setXmrTxKeyWindow = new SetXmrTxKeyWindow(); setXmrTxKeyWindow .actionButtonText(Res.get("portfolio.pending.step2_buyer.confirmStart.headline")) @@ -623,7 +623,7 @@ public class BuyerStep2View extends TradeStepView { String fees = Res.get("portfolio.pending.step2_buyer.fees"); String id = trade.getShortId(); String amount = VolumeUtil.formatVolumeWithCode(trade.getVolume()); - if (paymentAccountPayload instanceof AssetsAccountPayload) { + if (paymentAccountPayload instanceof AssetAccountPayload) { message += Res.get("portfolio.pending.step2_buyer.altcoin", getCurrencyName(trade), amount); diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java index 52486d61b0..0ded6580e6 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java @@ -24,7 +24,6 @@ import bisq.desktop.components.indicator.TxConfidenceIndicator; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel; import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView; -import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; @@ -32,7 +31,7 @@ import bisq.core.locale.Res; import bisq.core.payment.PaymentAccount; import bisq.core.payment.PaymentAccountUtil; import bisq.core.payment.payload.AmazonGiftCardAccountPayload; -import bisq.core.payment.payload.AssetsAccountPayload; +import bisq.core.payment.payload.AssetAccountPayload; import bisq.core.payment.payload.BankAccountPayload; import bisq.core.payment.payload.CashByMailAccountPayload; import bisq.core.payment.payload.CashDepositAccountPayload; @@ -226,13 +225,13 @@ public class SellerStep3View extends TradeStepView { .map(PaymentAccount::getAccountName) .orElse(""); - if (myPaymentAccountPayload instanceof AssetsAccountPayload) { + if (myPaymentAccountPayload instanceof AssetAccountPayload) { if (myPaymentDetails.isEmpty()) { // Not expected - myPaymentDetails = ((AssetsAccountPayload) myPaymentAccountPayload).getAddress(); + myPaymentDetails = ((AssetAccountPayload) myPaymentAccountPayload).getAddress(); } peersPaymentDetails = peersPaymentAccountPayload != null ? - ((AssetsAccountPayload) peersPaymentAccountPayload).getAddress() : "NA"; + ((AssetAccountPayload) peersPaymentAccountPayload).getAddress() : "NA"; myTitle = Res.get("portfolio.pending.step3_seller.yourAddress", currencyName); peersTitle = Res.get("portfolio.pending.step3_seller.buyersAddress", currencyName); } else { @@ -374,7 +373,7 @@ public class SellerStep3View extends TradeStepView { if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) { PaymentAccountPayload paymentAccountPayload = model.dataModel.getSellersPaymentAccountPayload(); String message = Res.get("portfolio.pending.step3_seller.onPaymentReceived.part1", getCurrencyName(trade)); - if (!(paymentAccountPayload instanceof AssetsAccountPayload)) { + if (!(paymentAccountPayload instanceof AssetAccountPayload)) { Optional optionalHolderName = getOptionalHolderName(); if (optionalHolderName.isPresent()) { message += Res.get("portfolio.pending.step3_seller.onPaymentReceived.name", optionalHolderName.get()); @@ -406,8 +405,8 @@ public class SellerStep3View extends TradeStepView { String tradeVolumeWithCode = VolumeUtil.formatVolumeWithCode(trade.getVolume()); String currencyName = getCurrencyName(trade); String part1 = Res.get("portfolio.pending.step3_seller.part", currencyName); - if (paymentAccountPayload instanceof AssetsAccountPayload) { - String address = ((AssetsAccountPayload) paymentAccountPayload).getAddress(); + if (paymentAccountPayload instanceof AssetAccountPayload) { + String address = ((AssetAccountPayload) paymentAccountPayload).getAddress(); String explorerOrWalletString = isXmrTrade() ? Res.get("portfolio.pending.step3_seller.altcoin.wallet", currencyName) : Res.get("portfolio.pending.step3_seller.altcoin.explorer", currencyName); diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 8a7a524df4..932f5ce2a1 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -595,6 +595,7 @@ message GetPaymentMethodsReply { message GetPaymentAccountFormRequest { string payment_method_id = 1; + PaymentAccountPayload payment_account_payload = 2; } message GetPaymentAccountFormReply { @@ -864,8 +865,8 @@ message ContractInfo { bool is_buyer_maker_and_seller_taker = 5; string maker_account_id = 6; string taker_account_id = 7; - PaymentAccountPayloadInfo maker_payment_account_payload = 8; - PaymentAccountPayloadInfo taker_payment_account_payload = 9; + PaymentAccountPayload maker_payment_account_payload = 8; + PaymentAccountPayload taker_payment_account_payload = 9; string maker_payout_address_string = 10; string taker_payout_address_string = 11; uint64 lock_time = 12; @@ -873,13 +874,6 @@ message ContractInfo { string arbitrator_node_address = 100; } -message PaymentAccountPayloadInfo { - string id = 1; - string payment_method_id = 2; - string address = 3; - string payment_details = 4; -} - /////////////////////////////////////////////////////////////////////////////////////////// // Transactions /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto index e6d21960a0..423ae8321c 100644 --- a/proto/src/main/proto/pb.proto +++ b/proto/src/main/proto/pb.proto @@ -1997,18 +1997,19 @@ message MockPayload { message PaymentAccountForm { enum FormId { - REVOLUT = 0; - SEPA = 1; - SEPA_INSTANT = 2; - TRANSFERWISE = 3; - CLEAR_X_CHANGE = 4; - SWIFT = 5; - F2F = 6; - STRIKE = 7; - MONEY_GRAM = 8; - FASTER_PAYMENTS = 9; - UPHOLD = 10; - PAXUM = 11; + BLOCK_CHAINS = 0; + REVOLUT = 1; + SEPA = 2; + SEPA_INSTANT = 3; + TRANSFERWISE = 4; + CLEAR_X_CHANGE = 5; + SWIFT = 6; + F2F = 7; + STRIKE = 8; + MONEY_GRAM = 9; + FASTER_PAYMENTS = 10; + UPHOLD = 11; + PAXUM = 12; } FormId id = 1; repeated PaymentAccountFormField fields = 2; @@ -2016,64 +2017,64 @@ message PaymentAccountForm { message PaymentAccountFormField { enum FieldId { - ACCEPTED_COUNTRY_CODES = 0; - ACCOUNT_ID = 1; - ACCOUNT_NAME = 2; - ACCOUNT_NR = 3; - ACCOUNT_OWNER = 4; - ACCOUNT_TYPE = 5; - ANSWER = 6; - BANK_ACCOUNT_NAME = 7; - BANK_ACCOUNT_NUMBER = 8; - BANK_ACCOUNT_TYPE = 9; - BANK_ADDRESS = 10; - BANK_BRANCH = 11; - BANK_BRANCH_CODE = 12; - BANK_BRANCH_NAME = 13; - BANK_CODE = 14; - BANK_COUNTRY_CODE = 15; - BANK_ID = 16; - BANK_NAME = 17; - BANK_SWIFT_CODE = 18; - BENEFICIARY_ACCOUNT_NR = 19; - BENEFICIARY_ADDRESS = 20; - BENEFICIARY_CITY = 21; - BENEFICIARY_NAME = 22; - BENEFICIARY_PHONE = 23; - BIC = 24; - BRANCH_ID = 25; - CITY = 26; - CONTACT = 27; - COUNTRY = 28; - EMAIL = 29; - EMAIL_OR_MOBILE_NR = 30; - EXTRA_INFO = 31; - HOLDER_ADDRESS = 32; - HOLDER_EMAIL = 33; - HOLDER_NAME = 34; - HOLDER_TAX_ID = 35; - IBAN = 36; - IFSC = 37; - INTERMEDIARY_ADDRESS = 38; - INTERMEDIARY_BRANCH = 39; - INTERMEDIARY_COUNTRY_CODE = 40; - INTERMEDIARY_NAME = 41; - INTERMEDIARY_SWIFT_CODE = 42; - MOBILE_NR = 43; - NATIONAL_ACCOUNT_ID = 44; - PAYID = 45; - PIX_KEY = 46; - POSTAL_ADDRESS = 47; - PROMPT_PAY_ID = 48; - QUESTION = 49; - REQUIREMENTS = 50; - SALT = 51; - SORT_CODE = 52; - SPECIAL_INSTRUCTIONS = 53; - STATE = 54; - TRADE_CURRENCIES = 55; - USER_NAME = 56; - VIRTUAL_PAYMENT_ADDRESS = 57; + ADDRESS = 0; + ACCEPTED_COUNTRY_CODES = 1; + ACCOUNT_ID = 2; + ACCOUNT_NAME = 3; + ACCOUNT_NR = 4; + ACCOUNT_OWNER = 5; + ACCOUNT_TYPE = 6; + ANSWER = 7; + BANK_ACCOUNT_NAME = 8; + BANK_ACCOUNT_NUMBER = 9; + BANK_ACCOUNT_TYPE = 10; + BANK_ADDRESS = 11; + BANK_BRANCH = 12; + BANK_BRANCH_CODE = 13; + BANK_BRANCH_NAME = 14; + BANK_CODE = 15; + BANK_COUNTRY_CODE = 16; + BANK_ID = 17; + BANK_NAME = 18; + BANK_SWIFT_CODE = 19; + BENEFICIARY_ACCOUNT_NR = 20; + BENEFICIARY_ADDRESS = 21; + BENEFICIARY_CITY = 22; + BENEFICIARY_NAME = 23; + BENEFICIARY_PHONE = 24; + BIC = 25; + BRANCH_ID = 26; + CITY = 27; + CONTACT = 28; + COUNTRY = 29; + EMAIL = 30; + EMAIL_OR_MOBILE_NR = 31; + EXTRA_INFO = 32; + HOLDER_ADDRESS = 33; + HOLDER_EMAIL = 34; + HOLDER_NAME = 35; + HOLDER_TAX_ID = 36; + IBAN = 37; + IFSC = 38; + INTERMEDIARY_ADDRESS = 39; + INTERMEDIARY_BRANCH = 40; + INTERMEDIARY_COUNTRY_CODE = 41; + INTERMEDIARY_NAME = 42; + INTERMEDIARY_SWIFT_CODE = 43; + MOBILE_NR = 44; + NATIONAL_ACCOUNT_ID = 45; + PAYID = 46; + PIX_KEY = 47; + POSTAL_ADDRESS = 48; + PROMPT_PAY_ID = 49; + QUESTION = 50; + REQUIREMENTS = 51; + SALT = 52; + SORT_CODE = 53; + SPECIAL_INSTRUCTIONS = 54; + STATE = 55; + TRADE_CURRENCIES = 56; + USER_NAME = 57; } enum Component { TEXT = 0;