diff --git a/api-schema/src/main/java/org/stellar/anchor/api/platform/GetTransactionResponse.java b/api-schema/src/main/java/org/stellar/anchor/api/platform/GetTransactionResponse.java index 2f5851198b..e8f9fc2377 100644 --- a/api-schema/src/main/java/org/stellar/anchor/api/platform/GetTransactionResponse.java +++ b/api-schema/src/main/java/org/stellar/anchor/api/platform/GetTransactionResponse.java @@ -12,4 +12,6 @@ */ @SuperBuilder @NoArgsConstructor -public class GetTransactionResponse extends PlatformTransactionData {} +public class GetTransactionResponse extends PlatformTransactionData { + String fundingMethod; +} diff --git a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/InfoResponse.java b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/InfoResponse.java index 055f4d3bcb..64e5b057ca 100644 --- a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/InfoResponse.java +++ b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/InfoResponse.java @@ -1,6 +1,7 @@ package org.stellar.anchor.api.sep.sep6; import com.google.gson.annotations.SerializedName; +import java.util.List; import java.util.Map; import lombok.Builder; import lombok.Data; @@ -77,13 +78,16 @@ public static class DepositAssetResponse { @SerializedName("max_amount") Long maxAmount; + @SerializedName("funding_methods") + List fundingMethods; + /** * The fields required to initiate a deposit. * *

The only field supported by the platform is type. Additional fields required * for KYC are supplied asynchronously through SEP-12 requests. */ - Map fields; + @Deprecated Map fields; } /** Withdrawal configuration. */ @@ -109,6 +113,10 @@ public static class WithdrawAssetResponse { @SerializedName("max_amount") Long maxAmount; + /** The maximum amount that can be withdrawn. */ + @SerializedName("funding_methods") + List fundingMethods; + /** * The types of withdrawal methods supported and their fields. * @@ -116,7 +124,7 @@ public static class WithdrawAssetResponse { * account and KYC information is supplied asynchronously through PATCH requests and SEP-12 * requests respectively. */ - Map types; + @Deprecated Map types; } /** Withdrawal type configuration. */ diff --git a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositExchangeRequest.java b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositExchangeRequest.java index 7f10e4b6c9..509cd37f2b 100644 --- a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositExchangeRequest.java +++ b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositExchangeRequest.java @@ -49,8 +49,12 @@ public class StartDepositExchangeRequest { /** The memo to use for the deposit. */ String memo; - /** Type of deposit. */ - @NonNull String type; + /** Deposit method used for the transaction. */ + @SerializedName("funding_method") + String fundingMethod; + + /** Type of deposit. Deprecated in favor of funding_method */ + @Deprecated String type; /** * Defaults to en if not specified or if the specified language is not supported. Currently, diff --git a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositRequest.java b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositRequest.java index dc0f67b70f..2af1e3292d 100644 --- a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositRequest.java +++ b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartDepositRequest.java @@ -32,8 +32,12 @@ public class StartDepositRequest { @SerializedName("email_address") String emailAddress; - /** Type of deposit. */ - String type; + /** Deposit method used for the transaction. */ + @SerializedName("funding_method") + String fundingMethod; + + /** Type of deposit. Deprecated in favor of funding_method */ + @Deprecated String type; /** Name of wallet to deposit to. Currently, ignored. */ @SerializedName("wallet_name") diff --git a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawExchangeRequest.java b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawExchangeRequest.java index 3888ead1b9..8817fc25fb 100644 --- a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawExchangeRequest.java +++ b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawExchangeRequest.java @@ -39,8 +39,12 @@ public class StartWithdrawExchangeRequest { /** The amount of the source asset the user would like to withdraw. */ @NonNull String amount; - /** The type of withdrawal to make. */ - @NonNull String type; + /** Withdraw method used for the transaction. */ + @SerializedName("funding_method") + String fundingMethod; + + /** The type of withdrawal to make. Deprecated in favor of funding_method */ + @Deprecated String type; /** The ISO 3166-1 alpha-3 code of the user's current address. */ @SerializedName("country_code") diff --git a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawRequest.java b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawRequest.java index fe30c031da..6a73126e20 100644 --- a/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawRequest.java +++ b/api-schema/src/main/java/org/stellar/anchor/api/sep/sep6/StartWithdrawRequest.java @@ -20,8 +20,12 @@ public class StartWithdrawRequest { @NonNull String assetCode; - /** Type of withdrawal. */ - String type; + /** Withdraw method used for the transaction. */ + @SerializedName("funding_method") + String fundingMethod; + + /** Type of withdrawal. Deprecated in favor of funding_method */ + @Deprecated String type; /** The account to withdraw from. */ String account; diff --git a/core/src/main/java/org/stellar/anchor/sep6/RequestValidator.java b/core/src/main/java/org/stellar/anchor/sep6/RequestValidator.java index 841d8565ca..ed072a4a06 100644 --- a/core/src/main/java/org/stellar/anchor/sep6/RequestValidator.java +++ b/core/src/main/java/org/stellar/anchor/sep6/RequestValidator.java @@ -10,6 +10,7 @@ import org.stellar.anchor.api.asset.StellarAssetInfo; import org.stellar.anchor.api.exception.*; import org.stellar.anchor.asset.AssetService; +import org.stellar.anchor.util.StringHelper; import org.stellar.sdk.KeyPair; /** SEP-6 request validations */ @@ -91,6 +92,12 @@ public void validateAmount( */ public void validateTypes(String requestType, String assetCode, List validTypes) throws SepValidationException { + if (StringHelper.isEmpty(requestType)) { + throw new SepValidationException( + String.format( + "this field cannot be null or empty for asset %s, supported types are %s", + assetCode, validTypes)); + } if (!validTypes.contains(requestType)) { throw new SepValidationException( String.format( diff --git a/core/src/main/java/org/stellar/anchor/sep6/Sep6Service.java b/core/src/main/java/org/stellar/anchor/sep6/Sep6Service.java index 352abe7e2b..88856f50bb 100644 --- a/core/src/main/java/org/stellar/anchor/sep6/Sep6Service.java +++ b/core/src/main/java/org/stellar/anchor/sep6/Sep6Service.java @@ -107,10 +107,11 @@ public StartDepositResponse deposit(Sep10Jwt token, StartDepositRequest request) } StellarAssetInfo asset = requestValidator.getDepositAsset(request.getAssetCode()); - if (request.getType() != null) { - requestValidator.validateTypes( - request.getType(), asset.getCode(), asset.getSep6().getDeposit().getMethods()); - } + String fundingMethod = + request.getFundingMethod() != null ? request.getFundingMethod() : request.getType(); + requestValidator.validateTypes( + fundingMethod, asset.getCode(), asset.getSep6().getDeposit().getMethods()); + if (request.getAmount() != null) { requestValidator.validateAmount( request.getAmount(), @@ -130,7 +131,7 @@ public StartDepositResponse deposit(Sep10Jwt token, StartDepositRequest request) .transactionId(id) .status(SepTransactionStatus.INCOMPLETE.toString()) .kind(Sep6Transaction.Kind.DEPOSIT.toString()) - .type(request.getType()) + .type(fundingMethod) .assetCode(request.getAssetCode()) .assetIssuer(asset.getIssuer()) .amountExpected(request.getAmount()) @@ -186,8 +187,10 @@ public StartDepositResponse depositExchange(Sep10Jwt token, StartDepositExchange } StellarAssetInfo buyAsset = requestValidator.getDepositAsset(request.getDestinationAsset()); + String fundingMethod = + request.getFundingMethod() != null ? request.getFundingMethod() : request.getType(); requestValidator.validateTypes( - request.getType(), buyAsset.getCode(), buyAsset.getSep6().getDeposit().getMethods()); + fundingMethod, buyAsset.getCode(), buyAsset.getSep6().getDeposit().getMethods()); requestValidator.validateAmount( request.getAmount(), buyAsset.getCode(), @@ -224,7 +227,7 @@ public StartDepositResponse depositExchange(Sep10Jwt token, StartDepositExchange .transactionId(id) .status(SepTransactionStatus.INCOMPLETE.toString()) .kind(Sep6Transaction.Kind.DEPOSIT_EXCHANGE.toString()) - .type(request.getType()) + .type(fundingMethod) .assetCode(buyAsset.getCode()) .assetIssuer(buyAsset.getIssuer()) .amountIn(amounts.getAmountIn()) @@ -281,10 +284,11 @@ public StartWithdrawResponse withdraw(Sep10Jwt token, StartWithdrawRequest reque } StellarAssetInfo asset = requestValidator.getWithdrawAsset(request.getAssetCode()); - if (request.getType() != null) { - requestValidator.validateTypes( - request.getType(), asset.getCode(), asset.getSep6().getWithdraw().getMethods()); - } + String fundingMethod = + request.getFundingMethod() != null ? request.getFundingMethod() : request.getType(); + requestValidator.validateTypes( + fundingMethod, asset.getCode(), asset.getSep6().getWithdraw().getMethods()); + if (request.getAmount() != null) { requestValidator.validateAmount( request.getAmount(), @@ -304,7 +308,7 @@ public StartWithdrawResponse withdraw(Sep10Jwt token, StartWithdrawRequest reque .transactionId(id) .status(SepTransactionStatus.INCOMPLETE.toString()) .kind(Sep6Transaction.Kind.WITHDRAWAL.toString()) - .type(request.getType()) + .type(fundingMethod) .assetCode(request.getAssetCode()) .assetIssuer(asset.getIssuer()) .amountIn(request.getAmount()) @@ -357,8 +361,10 @@ public StartWithdrawResponse withdrawExchange( } StellarAssetInfo sellAsset = requestValidator.getWithdrawAsset(request.getSourceAsset()); + String fundingMethod = + request.getFundingMethod() != null ? request.getFundingMethod() : request.getType(); requestValidator.validateTypes( - request.getType(), sellAsset.getCode(), sellAsset.getSep6().getWithdraw().getMethods()); + fundingMethod, sellAsset.getCode(), sellAsset.getSep6().getWithdraw().getMethods()); requestValidator.validateAmount( request.getAmount(), sellAsset.getCode(), @@ -395,7 +401,7 @@ public StartWithdrawResponse withdrawExchange( .transactionId(id) .status(SepTransactionStatus.INCOMPLETE.toString()) .kind(Sep6Transaction.Kind.WITHDRAWAL_EXCHANGE.toString()) - .type(request.getType()) + .type(fundingMethod) .assetCode(sellAsset.getCode()) .assetIssuer(sellAsset.getIssuer()) .amountIn(amounts.getAmountIn()) @@ -534,6 +540,7 @@ private InfoResponse buildInfoResponse() { AssetInfo.Field.builder() .description("type of deposit to make") .choices(methods) + .optional(true) .build(); DepositAssetResponse deposit = @@ -542,6 +549,7 @@ private InfoResponse buildInfoResponse() { .authenticationRequired(true) .minAmount(asset.getSep6().getDeposit().getMinAmount()) .maxAmount(asset.getSep6().getDeposit().getMaxAmount()) + .fundingMethods(methods) .fields(ImmutableMap.of("type", type)) .build(); @@ -555,13 +563,13 @@ private InfoResponse buildInfoResponse() { for (String method : methods) { types.put(method, WithdrawType.builder().fields(new HashMap<>()).build()); } - WithdrawAssetResponse withdraw = WithdrawAssetResponse.builder() .enabled(true) .authenticationRequired(true) .minAmount(asset.getSep6().getWithdraw().getMinAmount()) .maxAmount(asset.getSep6().getWithdraw().getMaxAmount()) + .fundingMethods(methods) .types(types) .build(); diff --git a/core/src/main/java/org/stellar/anchor/util/TransactionMapper.java b/core/src/main/java/org/stellar/anchor/util/TransactionMapper.java index 7dca728a3a..94e1cc88e0 100644 --- a/core/src/main/java/org/stellar/anchor/util/TransactionMapper.java +++ b/core/src/main/java/org/stellar/anchor/util/TransactionMapper.java @@ -95,7 +95,7 @@ public static GetTransactionResponse toGetTransactionResponse(Sep31Transaction t .sep(PlatformTransactionData.Sep.SEP_31) .kind(RECEIVE) .status(SepTransactionStatus.from(txn.getStatus())) - .type(txn.getFundingMethod()) + .fundingMethod(txn.getFundingMethod()) .amountExpected(new Amount(txn.getAmountExpected(), txn.getAmountInAsset())) .amountIn(new Amount(txn.getAmountIn(), txn.getAmountInAsset())) .amountOut(new Amount(txn.getAmountOut(), txn.getAmountOutAsset())) @@ -137,6 +137,7 @@ public static GetTransactionResponse toGetTransactionResponse( .sep(PlatformTransactionData.Sep.SEP_6) .kind(PlatformTransactionData.Kind.from(txn.getKind())) .status(SepTransactionStatus.from(txn.getStatus())) + .fundingMethod(txn.getType()) .type(txn.getType()) .amountExpected( (amountExpectedAsset != null) diff --git a/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTest.kt b/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTest.kt index 1650d15962..a2f4b6033c 100644 --- a/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTest.kt @@ -111,7 +111,7 @@ class Sep6ServiceTest { StartDepositRequest.builder() .assetCode(TEST_ASSET) .account(TEST_ACCOUNT) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() val response = sep6Service.deposit(token, request) @@ -224,7 +224,7 @@ class Sep6ServiceTest { StartDepositRequest.builder() .assetCode(unsupportedAsset) .account(TEST_ACCOUNT) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() every { requestValidator.getDepositAsset(unsupportedAsset) } throws @@ -247,7 +247,7 @@ class Sep6ServiceTest { StartDepositRequest.builder() .assetCode(TEST_ASSET) .account(TEST_ACCOUNT) - .type(unsupportedType) + .fundingMethod(unsupportedType) .amount("100") .build() every { requestValidator.validateTypes(unsupportedType, TEST_ASSET, any()) } throws @@ -273,7 +273,7 @@ class Sep6ServiceTest { StartDepositRequest.builder() .assetCode(TEST_ASSET) .account(TEST_ACCOUNT) - .type("bank_account") + .fundingMethod("bank_account") .amount(badAmount) .build() every { requestValidator.validateAmount(badAmount, TEST_ASSET, any(), any(), any()) } throws @@ -312,7 +312,7 @@ class Sep6ServiceTest { StartDepositRequest.builder() .assetCode(TEST_ASSET) .account(TEST_ACCOUNT) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() @@ -369,7 +369,7 @@ class Sep6ServiceTest { .quoteId(TEST_QUOTE_ID) .amount(amount) .account(TEST_ACCOUNT) - .type("SWIFT") + .fundingMethod("SWIFT") .build() val response = sep6Service.depositExchange(token, request) @@ -450,7 +450,7 @@ class Sep6ServiceTest { .sourceAsset(sourceAsset) .amount(amount) .account(TEST_ACCOUNT) - .type("SWIFT") + .fundingMethod("SWIFT") .build() val response = sep6Service.depositExchange(token, request) @@ -509,7 +509,7 @@ class Sep6ServiceTest { .sourceAsset("iso4217:USD") .amount("100") .account(TEST_ACCOUNT) - .type("SWIFT") + .fundingMethod("SWIFT") .build() every { requestValidator.getDepositAsset(unsupportedAsset) } throws SepValidationException("unsupported asset") @@ -534,7 +534,7 @@ class Sep6ServiceTest { .sourceAsset(unsupportedAsset) .amount("100") .account(TEST_ACCOUNT) - .type("SWIFT") + .fundingMethod("SWIFT") .build() assertThrows { sep6Service.depositExchange(token, request) } @@ -554,7 +554,7 @@ class Sep6ServiceTest { .sourceAsset("iso4217:USD") .amount("100") .account(TEST_ACCOUNT) - .type(unsupportedType) + .fundingMethod(unsupportedType) .build() every { requestValidator.validateTypes(unsupportedType, TEST_ASSET, any()) } throws SepValidationException("unsupported type") @@ -585,7 +585,7 @@ class Sep6ServiceTest { .sourceAsset(sourceAsset) .amount(badAmount) .account(TEST_ACCOUNT) - .type("SWIFT") + .fundingMethod("SWIFT") .build() every { requestValidator.validateAmount(badAmount, TEST_ASSET, any(), any(), any()) } throws SepValidationException("bad amount") @@ -626,7 +626,7 @@ class Sep6ServiceTest { .sourceAsset("iso4217:USD") .amount("100") .account(TEST_ACCOUNT) - .type("SWIFT") + .fundingMethod("SWIFT") .build() assertThrows { sep6Service.depositExchange(token, request) } @@ -664,7 +664,7 @@ class Sep6ServiceTest { val request = StartWithdrawRequest.builder() .assetCode(TEST_ASSET) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .refundMemo("some text") .refundMemoType("text") @@ -812,7 +812,7 @@ class Sep6ServiceTest { val request = StartWithdrawRequest.builder() .assetCode(unsupportedAsset) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() every { requestValidator.getWithdrawAsset(unsupportedAsset) } throws @@ -834,7 +834,7 @@ class Sep6ServiceTest { val request = StartWithdrawRequest.builder() .assetCode(TEST_ASSET) - .type(unsupportedType) + .fundingMethod(unsupportedType) .amount("100") .build() every { requestValidator.getWithdrawAsset(TEST_ASSET) } returns @@ -861,7 +861,7 @@ class Sep6ServiceTest { val request = StartWithdrawRequest.builder() .assetCode(TEST_ASSET) - .type("bank_account") + .fundingMethod("bank_account") .amount(badAmount) .build() every { requestValidator.validateAmount(badAmount, TEST_ASSET, any(), any(), any()) } throws @@ -899,7 +899,7 @@ class Sep6ServiceTest { val request = StartWithdrawRequest.builder() .assetCode(TEST_ASSET) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() @@ -951,7 +951,7 @@ class Sep6ServiceTest { .sourceAsset(sourceAsset) .destinationAsset(destinationAsset) .quoteId(TEST_QUOTE_ID) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .refundMemo("some text") .refundMemoType("text") @@ -1025,7 +1025,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(sourceAsset) .destinationAsset(destinationAsset) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .refundMemo("some text") .refundMemoType("text") @@ -1104,7 +1104,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(sourceAsset) .destinationAsset(destinationAsset) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .account("requested_account") .refundMemo("some text") @@ -1128,7 +1128,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(unsupportedAsset) .destinationAsset("iso4217:USD") - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() every { requestValidator.getWithdrawAsset(unsupportedAsset) } throws @@ -1152,7 +1152,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(TEST_ASSET) .destinationAsset(unsupportedAsset) - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() @@ -1169,7 +1169,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(TEST_ASSET) .destinationAsset("iso4217:USD") - .type(unsupportedType) + .fundingMethod(unsupportedType) .amount("100") .build() every { requestValidator.validateTypes(unsupportedType, TEST_ASSET, any()) } throws @@ -1196,7 +1196,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(TEST_ASSET) .destinationAsset("iso4217:USD") - .type("bank_account") + .fundingMethod("bank_account") .amount(badAmount) .build() every { requestValidator.getWithdrawAsset(TEST_ASSET) } returns @@ -1238,7 +1238,7 @@ class Sep6ServiceTest { StartWithdrawExchangeRequest.builder() .sourceAsset(TEST_ASSET) .destinationAsset("iso4217:USD") - .type("bank_account") + .fundingMethod("bank_account") .amount("100") .build() every { requestValidator.getWithdrawAsset(TEST_ASSET) } returns diff --git a/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTestData.kt b/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTestData.kt index 416bb1be79..5e9526506a 100644 --- a/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTestData.kt +++ b/core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTestData.kt @@ -11,6 +11,7 @@ class Sep6ServiceTestData { "authentication_required": true, "min_amount": 1, "max_amount": 10000, + "funding_methods": ["SEPA", "SWIFT"], "fields": { "type": { "description": "type of deposit to make", @@ -18,7 +19,7 @@ class Sep6ServiceTestData { "SEPA", "SWIFT" ], - "optional": false + "optional": true } } } @@ -29,6 +30,7 @@ class Sep6ServiceTestData { "authentication_required": true, "min_amount": 1, "max_amount": 10000, + "funding_methods": ["SEPA", "SWIFT"], "fields": { "type": { "description": "type of deposit to make", @@ -36,7 +38,7 @@ class Sep6ServiceTestData { "SEPA", "SWIFT" ], - "optional": false + "optional": true } } } @@ -47,6 +49,7 @@ class Sep6ServiceTestData { "authentication_required": true, "min_amount": 1, "max_amount": 10000, + "funding_methods": ["bank_account", "cash"], "types": { "cash": { "fields": {} @@ -63,6 +66,7 @@ class Sep6ServiceTestData { "authentication_required": true, "min_amount": 1, "max_amount": 10000, + "funding_methods": ["bank_account", "cash"], "types": { "cash": { "fields": {} diff --git a/core/src/test/kotlin/org/stellar/anchor/util/TransactionMapperTest.kt b/core/src/test/kotlin/org/stellar/anchor/util/TransactionMapperTest.kt index 6c987a0ae2..f87a045cc9 100644 --- a/core/src/test/kotlin/org/stellar/anchor/util/TransactionMapperTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/util/TransactionMapperTest.kt @@ -1,5 +1,6 @@ package org.stellar.anchor.util +import com.google.gson.JsonObject import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK @@ -47,6 +48,7 @@ class TransactionMapperTest { } @MockK(relaxed = true) private lateinit var assertService: AssetService + val gson = GsonUtils.getInstance() @BeforeEach fun setup() { @@ -344,47 +346,53 @@ class TransactionMapperTest { val actual = GsonUtils.getInstance() .toJson(TransactionMapper.toGetTransactionResponse(sepTxn, assertService)) - val expected = - GsonUtils.getInstance() - .toJson( - PlatformTransactionData.builder() - .id(sepTxn.id) - .sep(PlatformTransactionData.Sep.SEP_6) - .kind(PlatformTransactionData.Kind.DEPOSIT) - .status(SepTransactionStatus.COMPLETED) - .type("bank_account") - .amountExpected(Amount("100.0", "stellar:USDC:issuer")) - .amountIn(Amount("100.0", "USD")) - .amountOut(Amount("100.0", "USDC")) - .feeDetails(FeeDetails("10.0", "USD")) - .quoteId(sepTxn.quoteId) - .startedAt(sepTxn.startedAt) - .updatedAt(sepTxn.updatedAt) - .completedAt(sepTxn.completedAt) - .userActionRequiredBy(sepTxn.userActionRequiredBy) - .transferReceivedAt(sepTxn.transferReceivedAt) - .message(sepTxn.message) - .refunds(sepTxn.refunds) - .stellarTransactions(listOf(stellarTransaction)) - .sourceAccount(sepTxn.fromAccount) - .destinationAccount(sepTxn.toAccount) - .externalTransactionId(sepTxn.externalTransactionId) - .memo(sepTxn.memo) - .memoType(sepTxn.memoType) - .refundMemo(sepTxn.refundMemo) - .refundMemoType(sepTxn.refundMemoType) - .clientDomain(sepTxn.clientDomain) - .clientName(sepTxn.clientName) - .customers( - Customers.builder() - .sender(StellarId(null, sepTxn.sep10Account, sepTxn.sep10AccountMemo)) - .receiver(StellarId(null, sepTxn.sep10Account, sepTxn.sep10AccountMemo)) - .build() - ) - .creator(StellarId(null, sepTxn.sep10Account, sepTxn.sep10AccountMemo)) + + val platformTxn = + PlatformTransactionData.builder() + .id(sepTxn.id) + .sep(PlatformTransactionData.Sep.SEP_6) + .kind(PlatformTransactionData.Kind.DEPOSIT) + .status(SepTransactionStatus.COMPLETED) + .type("bank_account") + .amountExpected(Amount("100.0", "stellar:USDC:issuer")) + .amountIn(Amount("100.0", "USD")) + .amountOut(Amount("100.0", "USDC")) + .feeDetails(FeeDetails("10.0", "USD")) + .quoteId(sepTxn.quoteId) + .startedAt(sepTxn.startedAt) + .updatedAt(sepTxn.updatedAt) + .completedAt(sepTxn.completedAt) + .userActionRequiredBy(sepTxn.userActionRequiredBy) + .transferReceivedAt(sepTxn.transferReceivedAt) + .message(sepTxn.message) + .refunds(sepTxn.refunds) + .stellarTransactions(listOf(stellarTransaction)) + .sourceAccount(sepTxn.fromAccount) + .destinationAccount(sepTxn.toAccount) + .externalTransactionId(sepTxn.externalTransactionId) + .memo(sepTxn.memo) + .memoType(sepTxn.memoType) + .refundMemo(sepTxn.refundMemo) + .refundMemoType(sepTxn.refundMemoType) + .clientDomain(sepTxn.clientDomain) + .clientName(sepTxn.clientName) + .customers( + Customers.builder() + .sender(StellarId(null, sepTxn.sep10Account, sepTxn.sep10AccountMemo)) + .receiver(StellarId(null, sepTxn.sep10Account, sepTxn.sep10AccountMemo)) .build() ) + .creator(StellarId(null, sepTxn.sep10Account, sepTxn.sep10AccountMemo)) + .build() - JSONAssert.assertEquals(expected, actual, true) + val jsonString = gson.toJson(platformTxn) + val jsonObject = gson.fromJson(jsonString, JsonObject::class.java) + + // Add the "funding_method" field + jsonObject.addProperty("fundingMethod", sepTxn.type) + // Convert back to JSON string if needed + val expectedJsonString = gson.toJson(jsonObject) + + JSONAssert.assertEquals(expectedJsonString, actual, true) } } diff --git a/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/integrationtest/Sep6Tests.kt b/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/integrationtest/Sep6Tests.kt index 413f431433..3e1870233c 100644 --- a/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/integrationtest/Sep6Tests.kt +++ b/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/integrationtest/Sep6Tests.kt @@ -182,11 +182,12 @@ class Sep6Tests : AbstractIntegrationTests(TestConfig()) { "authentication_required": true, "min_amount": 0, "max_amount": 10, + "funding_methods": ["SEPA", "SWIFT"], "fields": { "type": { "description": "type of deposit to make", "choices": ["SEPA", "SWIFT"], - "optional": false + "optional": true } } } @@ -197,11 +198,12 @@ class Sep6Tests : AbstractIntegrationTests(TestConfig()) { "authentication_required": true, "min_amount": 0, "max_amount": 10, + "funding_methods": ["SEPA", "SWIFT"], "fields": { "type": { "description": "type of deposit to make", "choices": ["SEPA", "SWIFT"], - "optional": false + "optional": true } } } @@ -212,6 +214,7 @@ class Sep6Tests : AbstractIntegrationTests(TestConfig()) { "authentication_required": true, "min_amount": 0, "max_amount": 10, + "funding_methods": ["bank_account", "cash"], "types": { "cash": { "fields": {} }, "bank_account": { "fields": {} } } } }, @@ -221,6 +224,7 @@ class Sep6Tests : AbstractIntegrationTests(TestConfig()) { "authentication_required": true, "min_amount": 0, "max_amount": 10, + "funding_methods": ["bank_account", "cash"], "types": { "cash": { "fields": {} }, "bank_account": { "fields": {} } } } }, diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java index fca9167ed5..cbf3856238 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java @@ -47,6 +47,7 @@ public StartDepositResponse deposit( @RequestParam(value = "memo_type", required = false) String memoType, @RequestParam(value = "memo", required = false) String memo, @RequestParam(value = "email_address", required = false) String emailAddress, + @RequestParam(value = "funding_method", required = false) String fundingMethod, @RequestParam(value = "type", required = false) String type, @RequestParam(value = "wallet_name", required = false) String walletName, @RequestParam(value = "wallet_url", required = false) String walletUrl, @@ -65,6 +66,7 @@ public StartDepositResponse deposit( .memoType(memoType) .memo(memo) .emailAddress(emailAddress) + .fundingMethod(fundingMethod) .type(type) .walletName(walletName) .walletUrl(walletUrl) @@ -90,7 +92,8 @@ public StartDepositResponse depositExchange( @RequestParam(value = "account") String account, @RequestParam(value = "memo_type", required = false) String memoType, @RequestParam(value = "memo", required = false) String memo, - @RequestParam(value = "type") String type, + @RequestParam(value = "funding_method", required = false) String fundingMethod, + @RequestParam(value = "type", required = false) String type, @RequestParam(value = "lang", required = false) String lang, @RequestParam(value = "country_code", required = false) String countryCode, @RequestParam(value = "claimable_balances_supported", required = false) @@ -107,6 +110,7 @@ public StartDepositResponse depositExchange( .account(account) .memoType(memoType) .memo(memo) + .fundingMethod(fundingMethod) .type(type) .lang(lang) .countryCode(countryCode) @@ -123,6 +127,7 @@ public StartDepositResponse depositExchange( public StartWithdrawResponse withdraw( HttpServletRequest request, @RequestParam(value = "asset_code") String assetCode, + @RequestParam(value = "funding_method", required = false) String fundingMethod, @RequestParam(value = "type", required = false) String type, @RequestParam(value = "amount", required = false) String amount, @RequestParam(value = "country_code", required = false) String countryCode, @@ -134,6 +139,7 @@ public StartWithdrawResponse withdraw( StartWithdrawRequest startWithdrawRequest = StartWithdrawRequest.builder() .assetCode(assetCode) + .fundingMethod(fundingMethod) .type(type) .amount(amount) .countryCode(countryCode) @@ -154,7 +160,8 @@ public StartWithdrawResponse withdraw( @RequestParam(value = "destination_asset") String destinationAsset, @RequestParam(value = "quote_id", required = false) String quoteId, @RequestParam(value = "amount") String amount, - @RequestParam(value = "type") String type, + @RequestParam(value = "funding_method", required = false) String fundingMethod, + @RequestParam(value = "type", required = false) String type, @RequestParam(value = "country_code", required = false) String countryCode, @RequestParam(value = "refund_memo", required = false) String refundMemo, @RequestParam(value = "refund_memo_type", required = false) String refundMemoType) @@ -167,6 +174,7 @@ public StartWithdrawResponse withdraw( .destinationAsset(destinationAsset) .quoteId(quoteId) .amount(amount) + .fundingMethod(fundingMethod) .type(type) .countryCode(countryCode) .refundMemo(refundMemo)