Skip to content

Commit

Permalink
chore(coinbase): upgrade to payment methods to v3 (#1273)
Browse files Browse the repository at this point in the history
* chore: remove unneeded Build.VERSION_CODES.N checks

* chore: migrate to v3 payment_methods

* chore: disable auth_limit check

* fix: payment_methods url

* fix: tests

* fix: coinbase tests
  • Loading branch information
Syn-McJ authored Mar 25, 2024
1 parent c3972e9 commit 158566d
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 183 deletions.
13 changes: 11 additions & 2 deletions common/src/main/java/org/dash/wallet/common/util/GenericUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import android.os.Build
import android.os.LocaleList
import java.math.RoundingMode
import java.text.NumberFormat
import java.util.*
import java.util.Currency
import java.util.Locale

/**
* @author Andreas Schildbach
Expand All @@ -32,6 +33,14 @@ object GenericUtils {
roundingMode = RoundingMode.HALF_UP
}

private val isRunningUnitTest: Boolean
get() = try {
Class.forName("org.junit.Test")
true
} catch (e: ClassNotFoundException) {
false
}

fun startsWithIgnoreCase(string: String, prefix: String): Boolean =
string.regionMatches(0, prefix, 0, prefix.length, ignoreCase = true)

Expand All @@ -45,7 +54,7 @@ object GenericUtils {
}

fun getDeviceLocale(): Locale {
val countryCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val countryCode = if (!isRunningUnitTest) {
LocaleList.getDefault()[0].country
} else {
Locale.getDefault().country
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,19 @@ package org.dash.wallet.integrations.coinbase.model
import com.google.gson.annotations.SerializedName

data class PaymentMethodsResponse(
val `data`: List<PaymentMethodsData>?
@SerializedName("payment_methods")
val paymentMethods: List<PaymentMethodsData>?
)

data class PaymentMethodsData(
val id: String,
val type: String,
val name: String,
val currency: String,
@SerializedName("created_at")
val createdAt: String? = null,
@SerializedName("updated_at")
val updatedAt: String? = null,
@SerializedName("allow_buy")
val isBuyingAllowed: Boolean? = null,
@SerializedName("allow_deposit")
Expand All @@ -31,46 +40,5 @@ data class PaymentMethodsData(
val isSellingAllowed: Boolean? = null,
@SerializedName("allow_withdraw")
val isWithdrawalAllowed: Boolean? = null,
@SerializedName("created_at")
val createdAt: String? = null,
val currency: String? = null,
@SerializedName("fiat_account")
val fiatAccount: FiatAccount? = null,
val id: String? = null,
@SerializedName("instant_buy")
val isInstantBuyAllowed: Boolean? = null,
@SerializedName("instant_sell")
val isInstantSellAllowed: Boolean? = null,
val limits: Limits? = null,
@SerializedName("minimum_purchase_amount")
val minimumPurchaseAmount: MinimumPurchaseAmount? = null,
val name: String? = null,
@SerializedName("primary_buy")
val isPrimaryBuying: Boolean? = null,
@SerializedName("primary_sell")
val isPrimarySelling: Boolean? = null,
val resource: String? = null,
@SerializedName("resource_path")
val resourcePath: String? = null,
val type: String? = null,
@SerializedName("updated_at")
val updatedAt: String? = null,
val verified: Boolean? = null
)

data class FiatAccount(
val id: String? = null,
val resource: String? = null,
@SerializedName("resource_path")
val resourcePath: String? = null
)

data class Limits(
val name: String? = null,
val type: String? = null
)

data class MinimumPurchaseAmount(
val amount: String? = null,
val currency: String? = null
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ interface CoinBaseRepositoryInt {
suspend fun completeCoinbaseAuthentication(authorizationCode: String): Boolean
suspend fun refreshWithdrawalLimit()
suspend fun getExchangeRateFromCoinbase(): ResponseResource<CoinbaseToDashExchangeRateUIModel>
suspend fun getWithdrawalLimitInDash(): Double
suspend fun isInputGreaterThanLimit(amountInDash: Coin): Boolean
}

class CoinBaseRepository @Inject constructor(
Expand Down Expand Up @@ -161,7 +161,7 @@ class CoinBaseRepository @Inject constructor(

override suspend fun getActivePaymentMethods(): List<PaymentMethodsData> {
val apiResult = servicesApi.getActivePaymentMethods()
return apiResult?.data ?: emptyList()
return apiResult?.paymentMethods ?: emptyList()
}

override suspend fun depositToFiatAccount(paymentMethodId: String, amountUSD: String) {
Expand Down Expand Up @@ -266,7 +266,14 @@ class CoinBaseRepository @Inject constructor(
servicesApi.createAddress(accountId = userAccountId)?.addresses?.address ?: ""
}

override suspend fun getWithdrawalLimitInDash(): Double {
override suspend fun isInputGreaterThanLimit(amountInDash: Coin): Boolean {
// TODO: disabled until Coinbase changes are clear
return false
// val withdrawalLimitInDash = getWithdrawalLimitInDash()
// return amountInDash.toPlainString().toDoubleOrZero.compareTo(withdrawalLimitInDash) > 0
}

private suspend fun getWithdrawalLimitInDash(): Double {
val withdrawalLimit = config.get(CoinbaseConfig.USER_WITHDRAWAL_LIMIT)
val withdrawalLimitCurrency = config.get(CoinbaseConfig.SEND_LIMIT_CURRENCY)
?: CoinbaseConstants.DEFAULT_CURRENCY_USD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface CoinBaseServicesApi {
@Query("currency") currency: String = Constants.DASH_CURRENCY
): CoinBaseExchangeRates?

@GET("v2/payment-methods")
@GET("api/v3/brokerage/payment_methods")
suspend fun getActivePaymentMethods(
@Header(CoinbaseConstants.CB_VERSION_KEY) apiVersion: String = CoinbaseConstants.CB_VERSION_VALUE
): PaymentMethodsResponse?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@ class CoinbaseBuyDashViewModel @Inject constructor(
)
} else if (retryWithDeposit) {
val bankAccount = coinBaseRepository.getActivePaymentMethods().firstOrNull {
paymentMethodTypeFromCoinbaseType(it.type ?: "") == PaymentMethodType.BankAccount
paymentMethodTypeFromCoinbaseType(it.type) == PaymentMethodType.BankAccount
} ?: return CoinbaseErrorType.NO_BANK_ACCOUNT

paymentMethod = PaymentMethod(
bankAccount.id ?: "",
bankAccount.name ?: "",
bankAccount.id,
bankAccount.name,
account = "",
accountType = bankAccount.type ?: "",
accountType = bankAccount.type,
paymentMethodType = PaymentMethodType.BankAccount,
isValid = true
)
Expand Down Expand Up @@ -177,13 +177,14 @@ class CoinbaseBuyDashViewModel @Inject constructor(

private fun paymentMethodTypeFromCoinbaseType(type: String?): PaymentMethodType {
return when (type) {
"fiat_account" -> PaymentMethodType.Fiat
"secure3d_card", "worldpay_card", "credit_card", "debit_card" -> PaymentMethodType.Card
"ach_bank_account", "sepa_bank_account",
"ideal_bank_account", "eft_bank_account", "interac" -> PaymentMethodType.BankAccount
"bank_wire" -> PaymentMethodType.WireTransfer
"paypal_account" -> PaymentMethodType.PayPal
"apple_pay" -> PaymentMethodType.ApplePay
"COINBASE_FIAT_ACCOUNT" -> PaymentMethodType.Fiat
"SECURE3D_CARD", "WORLDPAY_CARD", "CREDIT_CARD", "DEBIT_CARD" -> PaymentMethodType.Card
"ACH", "SEPA",
"IDEAL", "EFT", "INTERAC" -> PaymentMethodType.BankAccount
"BANK_WIRE" -> PaymentMethodType.WireTransfer
"PAYPAL", "PAYPAL_ACCOUNT" -> PaymentMethodType.PayPal
"APPLE_PAY" -> PaymentMethodType.ApplePay
"GOOGLE_PAY" -> PaymentMethodType.GooglePay
else -> PaymentMethodType.Unknown
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ class CoinbaseConvertCryptoViewModel @Inject constructor(
}

suspend fun isInputGreaterThanLimit(amountInDash: Coin): Boolean {
val withdrawalLimitInDash = coinBaseRepository.getWithdrawalLimitInDash()
return amountInDash.toPlainString().toDoubleOrZero.compareTo(withdrawalLimitInDash) > 0
return coinBaseRepository.isInputGreaterThanLimit(amountInDash)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ class CoinbaseServicesViewModel @Inject constructor(
}.onEach { state -> _uiState.value = state }
.launchIn(viewModelScope)

viewModelScope.launch { coinBaseRepository.refreshWithdrawalLimit() }
// TODO: disabled until Coinbase changes are clear
// viewModelScope.launch { coinBaseRepository.refreshWithdrawalLimit() }
}

fun refreshBalance() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@ class CoinbaseViewModel @Inject constructor(
}

suspend fun isInputGreaterThanLimit(amountInDash: Coin): Boolean {
return amountInDash.toPlainString().toDoubleOrZero.compareTo(
coinBaseRepository.getWithdrawalLimitInDash()
) > 0
return coinBaseRepository.isInputGreaterThanLimit(amountInDash)
}

fun logEvent(eventName: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ class TransferDashViewModel @Inject constructor(
}

private suspend fun isInputGreaterThanLimit(amountInDash: Coin): Boolean {
val withdrawalLimitInDash = coinBaseRepository.getWithdrawalLimitInDash()
return amountInDash.toPlainString().toDoubleOrZero.compareTo(withdrawalLimitInDash) > 0
return coinBaseRepository.isInputGreaterThanLimit(amountInDash)
}

suspend fun checkEnteredAmountValue(amountInDash: Coin): SwapValueErrorType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ object TestUtils {
return gson.fromJson(dataSetAsString, resourceGenerator.type)
}

val paymentMethodsData = getPaymentMethodsApiResponse().data
val paymentMethodsData = getPaymentMethodsApiResponse().paymentMethods

fun getPaymentMethodsApiResponse(): PaymentMethodsResponse {
val apiResponse = readFileWithoutNewLineFromResources("payment_methods.json")
Expand Down
126 changes: 34 additions & 92 deletions integrations/coinbase/src/test/resources/payment_methods.json
Original file line number Diff line number Diff line change
@@ -1,101 +1,43 @@
{
"data": [
"payment_methods" : [
{
"id": "453eeb6d-a446-53c7-be6a-c0bb829488f6",
"type": "fiat_account",
"name": "Cash (USD)",
"currency": "USD",
"primary_buy": false,
"primary_sell": true,
"instant_buy": true,
"instant_sell": true,
"created_at": "2018-04-06T15:01:02Z",
"updated_at": "2018-04-06T15:01:02Z",
"resource": "payment_method",
"resource_path": "/v2/payment-methods/453eeb6d-a446-53c7-be6a-c0bb829488f6",
"allow_buy": false,
"allow_sell": true,
"allow_deposit": false,
"allow_withdraw": false,
"fiat_account": {
"id": "7c0bfa90-14d3-52f5-801e-7624a1234567",
"resource": "account",
"resource_path": "/v2/accounts/7c0bfa90-14d3-52f5-801e-7624a7670366"
},
"verified": true,
"minimum_purchase_amount": {
"amount": "0.00",
"currency": "USD"
}
"updated_at" : "2022-06-30T14:04:13Z",
"allow_deposit" : false,
"id" : "bfb4c087-b26d-5058-b614-4c6f9e411aaf",
"allow_withdraw" : false,
"allow_buy" : false,
"verified" : true,
"created_at" : "2022-06-30T14:04:13Z",
"type" : "COINBASE_FIAT_ACCOUNT",
"currency" : "USD",
"name" : "Cash (USD)",
"allow_sell" : false
},
{
"id": "931aa7a2-6500-505b-bf0b-35f031466711",
"type": "ach_bank_account",
"name": "Bank of America - Busi... ********1234",
"currency": "USD",
"primary_buy": true,
"primary_sell": false,
"instant_buy": true,
"instant_sell": false,
"created_at": "2018-03-16T18:50:09Z",
"updated_at": "2018-03-16T18:50:13Z",
"resource": "payment_method",
"resource_path": "/v2/payment-methods/931aa7a2-6500-505b-bf0b-35f031466711",
"allow_buy": true,
"allow_sell": false,
"allow_deposit": true,
"allow_withdraw": true,
"verified": true,
"minimum_purchase_amount": {
"amount": "1.00",
"currency": "USD"
}
"updated_at" : "2022-12-09T06:15:10Z",
"allow_deposit" : false,
"id" : "018b3577-47ce-5d15-8b25-2931166088db",
"allow_withdraw" : false,
"allow_buy" : false,
"verified" : true,
"created_at" : "2022-12-08T09:36:36Z",
"type" : "APPLE_PAY",
"currency" : "USD",
"name" : "Apple Pay",
"allow_sell" : false
},
{
"id": "ec4b15d0-a430-5a03-9dbf-bddf3c12bc73",
"type": "worldpay_card",
"name": "0007********2021",
"currency": "USD",
"primary_buy": false,
"primary_sell": false,
"instant_buy": true,
"instant_sell": false,
"created_at": "2021-10-28T17:13:26Z",
"updated_at": "2021-10-28T17:15:58Z",
"resource": "payment_method",
"resource_path": "/v2/payment-methods/ec4b15d0-a430-5a03-9dbf-bddf3c12bc73",
"allow_buy": false,
"allow_sell": false,
"allow_deposit": false,
"allow_withdraw": false,
"verified": true,
"minimum_purchase_amount": {
"amount": "1.00",
"currency": "USD"
}
},
{
"id": "2e55fc67-db8d-5e14-81f6-25432dc27227",
"type": "paypal_account",
"name": "PayPal - t***[email protected]",
"currency": "USD",
"primary_buy": false,
"primary_sell": false,
"instant_buy": true,
"instant_sell": true,
"created_at": "2021-12-14T18:34:51Z",
"updated_at": "2021-12-14T18:34:51Z",
"resource": "payment_method",
"resource_path": "/v2/payment-methods/2e55fc67-db8d-5e14-81f6-25432dc27227",
"allow_buy": true,
"allow_sell": false,
"allow_deposit": true,
"allow_withdraw": true,
"verified": true,
"minimum_purchase_amount": {
"amount": "1.00",
"currency": "USD"
}
"updated_at" : null,
"allow_deposit" : false,
"id" : "662eec93-2862-438a-b7e1-6b52c01b81b6",
"allow_withdraw" : false,
"allow_buy" : false,
"verified" : true,
"created_at" : "2022-12-09T06:15:02Z",
"type" : "GOOGLE_PAY",
"currency" : "USD",
"name" : "Google Pay",
"allow_sell" : false
}
]
}
Loading

0 comments on commit 158566d

Please sign in to comment.