Updated on 2026-08-14
This commit is contained in:
parent
8f2c28715a
commit
0741b83490
13 changed files with 107 additions and 98 deletions
|
|
@ -40,8 +40,8 @@ sealed class ApiConfig {
|
|||
is TangemTech -> ID.TangemTech
|
||||
is StakeKit -> ID.StakeKit
|
||||
is P2PEthPool -> ID.P2PEthPool
|
||||
is TangemPay -> ID.TangemPay
|
||||
is TangemPayAuth -> ID.TangemPayAuth
|
||||
is TangemPay.Bff -> ID.TangemPay
|
||||
is TangemPay.Auth -> ID.TangemPayAuth
|
||||
is BlockAid -> ID.BlockAid
|
||||
is YieldSupply -> ID.YieldSupply
|
||||
is MoonPay -> ID.MoonPay
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package com.tangem.datasource.api.common.config
|
||||
|
||||
import com.tangem.datasource.BuildConfig
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.utils.ProviderSuspend
|
||||
import com.tangem.utils.version.AppVersionProvider
|
||||
|
||||
internal class TangemPay(
|
||||
internal sealed class TangemPay(
|
||||
private val appVersionProvider: AppVersionProvider,
|
||||
private val environmentConfigStorage: EnvironmentConfigStorage,
|
||||
) : ApiConfig() {
|
||||
|
||||
override val defaultEnvironment: ApiEnvironment = getInitialEnvironment()
|
||||
|
|
@ -16,6 +18,8 @@ internal class TangemPay(
|
|||
createProdEnvironment(),
|
||||
)
|
||||
|
||||
protected abstract fun getBaseUrl(apiEnvironment: ApiEnvironment): String
|
||||
|
||||
private fun getInitialEnvironment(): ApiEnvironment {
|
||||
return when (BuildConfig.BUILD_TYPE) {
|
||||
MOCKED_BUILD_TYPE -> ApiEnvironment.MOCK
|
||||
|
|
@ -31,24 +35,75 @@ internal class TangemPay(
|
|||
|
||||
private fun createDevEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.DEV,
|
||||
baseUrl = "https://api.dev.us.paera.com/bff-v2/",
|
||||
headers = createHeaders(),
|
||||
baseUrl = getBaseUrl(ApiEnvironment.DEV),
|
||||
headers = createHeaders(ApiEnvironment.DEV),
|
||||
)
|
||||
|
||||
private fun createMockedEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.MOCK,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
headers = createHeaders(),
|
||||
baseUrl = getBaseUrl(ApiEnvironment.MOCK),
|
||||
headers = createHeaders(ApiEnvironment.MOCK),
|
||||
)
|
||||
|
||||
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.PROD,
|
||||
baseUrl = "https://api.us.paera.com/bff-v2/",
|
||||
headers = createHeaders(),
|
||||
baseUrl = getBaseUrl(ApiEnvironment.PROD),
|
||||
headers = createHeaders(ApiEnvironment.PROD),
|
||||
)
|
||||
|
||||
private fun createHeaders() = mapOf(
|
||||
private fun createHeaders(apiEnvironment: ApiEnvironment) = mapOf(
|
||||
"version" to ProviderSuspend { appVersionProvider.versionName },
|
||||
"platform" to ProviderSuspend { "Android" },
|
||||
"X-API-KEY" to ProviderSuspend { getBffStaticToken(apiEnvironment) },
|
||||
)
|
||||
|
||||
private fun getBffStaticToken(apiEnvironment: ApiEnvironment): String {
|
||||
return when (apiEnvironment) {
|
||||
ApiEnvironment.MOCK,
|
||||
ApiEnvironment.DEV,
|
||||
-> environmentConfigStorage.getConfigSync().bffStaticTokenDev
|
||||
ApiEnvironment.PROD -> environmentConfigStorage.getConfigSync().bffStaticToken
|
||||
ApiEnvironment.STAGE,
|
||||
ApiEnvironment.STAGE_2,
|
||||
ApiEnvironment.DEV_2,
|
||||
ApiEnvironment.DEV_3,
|
||||
-> null
|
||||
} ?: error("BffStaticToken is not provided for $apiEnvironment")
|
||||
}
|
||||
|
||||
class Bff(
|
||||
appVersionProvider: AppVersionProvider,
|
||||
environmentConfigStorage: EnvironmentConfigStorage,
|
||||
) : TangemPay(appVersionProvider, environmentConfigStorage) {
|
||||
override fun getBaseUrl(apiEnvironment: ApiEnvironment): String {
|
||||
return when (apiEnvironment) {
|
||||
ApiEnvironment.DEV -> "https://api.dev.us.paera.com/bff-v2/"
|
||||
ApiEnvironment.MOCK -> "[REDACTED_ENV_URL]"
|
||||
ApiEnvironment.PROD -> "https://api.us.paera.com/bff-v2/"
|
||||
ApiEnvironment.DEV_2,
|
||||
ApiEnvironment.DEV_3,
|
||||
ApiEnvironment.STAGE,
|
||||
ApiEnvironment.STAGE_2,
|
||||
-> error("Unknown environment: $apiEnvironment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Auth(
|
||||
appVersionProvider: AppVersionProvider,
|
||||
environmentConfigStorage: EnvironmentConfigStorage,
|
||||
) : TangemPay(appVersionProvider, environmentConfigStorage) {
|
||||
override fun getBaseUrl(apiEnvironment: ApiEnvironment): String {
|
||||
return when (apiEnvironment) {
|
||||
ApiEnvironment.DEV -> "https://api.dev.us.paera.com/"
|
||||
ApiEnvironment.MOCK -> "[REDACTED_ENV_URL]"
|
||||
ApiEnvironment.PROD -> "https://api.us.paera.com/"
|
||||
ApiEnvironment.DEV_2,
|
||||
ApiEnvironment.DEV_3,
|
||||
ApiEnvironment.STAGE,
|
||||
ApiEnvironment.STAGE_2,
|
||||
-> error("Unknown environment: $apiEnvironment")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package com.tangem.datasource.api.common.config
|
||||
|
||||
import com.tangem.datasource.BuildConfig
|
||||
import com.tangem.utils.ProviderSuspend
|
||||
import com.tangem.utils.version.AppVersionProvider
|
||||
|
||||
internal class TangemPayAuth(
|
||||
private val appVersionProvider: AppVersionProvider,
|
||||
) : ApiConfig() {
|
||||
override val defaultEnvironment: ApiEnvironment = getInitialEnvironment()
|
||||
|
||||
override val environmentConfigs = listOf(
|
||||
createDevEnvironment(),
|
||||
createMockedEnvironment(),
|
||||
createProdEnvironment(),
|
||||
)
|
||||
|
||||
private fun getInitialEnvironment(): ApiEnvironment {
|
||||
return when (BuildConfig.BUILD_TYPE) {
|
||||
MOCKED_BUILD_TYPE -> ApiEnvironment.MOCK
|
||||
DEBUG_BUILD_TYPE,
|
||||
INTERNAL_BUILD_TYPE,
|
||||
-> ApiEnvironment.DEV
|
||||
EXTERNAL_BUILD_TYPE,
|
||||
RELEASE_BUILD_TYPE,
|
||||
-> ApiEnvironment.PROD
|
||||
else -> error("Unknown build type [${BuildConfig.BUILD_TYPE}]")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDevEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.DEV,
|
||||
baseUrl = "https://api.dev.us.paera.com/",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createMockedEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.MOCK,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.PROD,
|
||||
baseUrl = "https://api.us.paera.com/",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createHeaders() = mapOf(
|
||||
"version" to ProviderSuspend { appVersionProvider.versionName },
|
||||
"platform" to ProviderSuspend { "Android" },
|
||||
)
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ interface TangemPayApi {
|
|||
|
||||
@GET("v1/customer/wallets/{customer_wallet_id}")
|
||||
suspend fun checkCustomerWalletId(
|
||||
@Header("X-API-KEY") authHeader: String,
|
||||
@Path("customer_wallet_id") customerWalletId: String,
|
||||
): ApiResponse<CheckCustomerWalletResponse>
|
||||
|
||||
|
|
|
|||
|
|
@ -86,13 +86,17 @@ internal object ApiConfigsModule {
|
|||
|
||||
@Provides
|
||||
@IntoSet
|
||||
fun provideTangemVisaConfig(appVersionProvider: AppVersionProvider): ApiConfig = TangemPay(appVersionProvider)
|
||||
fun provideTangemPayBffConfig(
|
||||
appVersionProvider: AppVersionProvider,
|
||||
environmentConfigStorage: EnvironmentConfigStorage,
|
||||
): ApiConfig = TangemPay.Bff(appVersionProvider, environmentConfigStorage)
|
||||
|
||||
@Provides
|
||||
@IntoSet
|
||||
fun provideTangemPayAuthConfig(appVersionProvider: AppVersionProvider): ApiConfig = TangemPayAuth(
|
||||
appVersionProvider,
|
||||
)
|
||||
fun provideTangemPayAuthConfig(
|
||||
appVersionProvider: AppVersionProvider,
|
||||
environmentConfigStorage: EnvironmentConfigStorage,
|
||||
): ApiConfig = TangemPay.Auth(appVersionProvider, environmentConfigStorage)
|
||||
|
||||
@Provides
|
||||
@IntoSet
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ data class EnvironmentConfig(
|
|||
val yieldModuleApiKey: String? = null,
|
||||
val yieldModuleApiKeyDev: String? = null,
|
||||
val bffStaticToken: String? = null,
|
||||
val bffStaticTokenDev: String? = null,
|
||||
val gaslessTxApiKeyDev: String? = null,
|
||||
val gaslessTxApiKey: String? = null,
|
||||
)
|
||||
|
|
@ -33,6 +33,7 @@ internal object EnvironmentConfigConverter : Converter<EnvironmentConfigModel, E
|
|||
yieldModuleApiKey = value.yieldModuleApiKey,
|
||||
yieldModuleApiKeyDev = value.yieldModuleApiKeyDev,
|
||||
bffStaticToken = value.bffStaticToken,
|
||||
bffStaticTokenDev = value.bffStaticTokenDev,
|
||||
gaslessTxApiKeyDev = value.gaslessTxApiKeyDev,
|
||||
gaslessTxApiKey = value.gaslessTxApiKey,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class EnvironmentConfigModel(
|
|||
@Json(name = "blinkApiKey") val blinkApiKey: String?,
|
||||
@Json(name = "tatumApiKey") val tatumApiKey: String?,
|
||||
@Json(name = "bffStaticToken") val bffStaticToken: String?,
|
||||
@Json(name = "bffStaticTokenDev") val bffStaticTokenDev: String?,
|
||||
@Json(name = "gaslessTxApiKeyDev") val gaslessTxApiKeyDev: String?,
|
||||
@Json(name = "gaslessTxApiKey") val gaslessTxApiKey: String?,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,14 @@ class ApiConfigTest {
|
|||
)
|
||||
}
|
||||
ApiConfig.ID.StakeKit -> StakeKit(stakeKitAuthProvider = mockk())
|
||||
ApiConfig.ID.TangemPay -> TangemPay(appVersionProvider = mockk())
|
||||
ApiConfig.ID.TangemPay -> TangemPay.Bff(
|
||||
appVersionProvider = mockk(),
|
||||
environmentConfigStorage = mockk()
|
||||
)
|
||||
ApiConfig.ID.TangemPayAuth -> TangemPay.Auth(
|
||||
appVersionProvider = mockk(),
|
||||
environmentConfigStorage = mockk()
|
||||
)
|
||||
ApiConfig.ID.BlockAid -> BlockAid(configStorage = mockk())
|
||||
ApiConfig.ID.MoonPay -> MoonPay()
|
||||
ApiConfig.ID.P2PEthPool -> P2PEthPool(p2pAuthProvider = mockk())
|
||||
|
|
@ -78,7 +85,6 @@ class ApiConfigTest {
|
|||
authProvider = appAuthProvider,
|
||||
appInfoProvider = mockk(),
|
||||
)
|
||||
ApiConfig.ID.TangemPayAuth -> TangemPayAuth(appVersionProvider = mockk())
|
||||
ApiConfig.ID.GaslessTxService -> GaslessTxService(
|
||||
authProvider = appAuthProvider,
|
||||
appVersionProvider = mockk(),
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ internal class MockEnvironmentConfigStorage : EnvironmentConfigStorage {
|
|||
blockAidApiKey = BLOCK_AID_API_KEY,
|
||||
tangemApiKey = TANGEM_API_KEY,
|
||||
tangemApiKeyDev = TANGEM_API_KEY_DEV,
|
||||
bffStaticToken = TANGEM_PAY_BFF_KEY,
|
||||
bffStaticTokenDev = TANGEM_PAY_BFF_KEY_DEV,
|
||||
tangemApiKeyStage = TANGEM_API_KEY_STAGE,
|
||||
yieldModuleApiKey = YIELD_MODULE_KEY,
|
||||
yieldModuleApiKeyDev = YIELD_MODULE_KEY_DEV,
|
||||
|
|
@ -33,6 +35,8 @@ internal class MockEnvironmentConfigStorage : EnvironmentConfigStorage {
|
|||
const val BLOCK_AID_API_KEY = "block_aid_api_key"
|
||||
const val TANGEM_API_KEY = "tangem_api_key"
|
||||
const val TANGEM_API_KEY_DEV = "tangem_api_key_dev"
|
||||
const val TANGEM_PAY_BFF_KEY = "tangem_pay_bff_key"
|
||||
const val TANGEM_PAY_BFF_KEY_DEV = "tangem_pay_bff_key_dev"
|
||||
const val TANGEM_GASLESS_API_KEY = "tangem_gasless_api_key"
|
||||
const val TANGEM_API_KEY_STAGE = "tangem_api_key_stage"
|
||||
const val YIELD_MODULE_KEY = "yield_module_api_key"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.datasource.api.common.config.ApiConfig.Companion.RELEASE_BUILD
|
|||
import com.tangem.datasource.api.common.config.managers.MockEnvironmentConfigStorage.Companion.BLOCK_AID_API_KEY
|
||||
import com.tangem.datasource.api.common.config.managers.MockEnvironmentConfigStorage.Companion.TANGEM_API_KEY
|
||||
import com.tangem.datasource.api.common.config.managers.MockEnvironmentConfigStorage.Companion.TANGEM_GASLESS_API_KEY
|
||||
import com.tangem.datasource.api.common.config.managers.MockEnvironmentConfigStorage.Companion.TANGEM_PAY_BFF_KEY_DEV
|
||||
import com.tangem.domain.staking.model.ethpool.P2PEthPoolStakingConfig
|
||||
import com.tangem.lib.auth.ExpressAuthProvider
|
||||
import com.tangem.lib.auth.P2PEthPoolAuthProvider
|
||||
|
|
@ -115,7 +116,14 @@ internal class ProdApiConfigsManagerTest {
|
|||
)
|
||||
}
|
||||
ApiConfig.ID.StakeKit -> StakeKit(stakeKitAuthProvider = stakeKitAuthProvider)
|
||||
ApiConfig.ID.TangemPay -> TangemPay(appVersionProvider = appVersionProvider)
|
||||
ApiConfig.ID.TangemPay -> TangemPay.Bff(
|
||||
appVersionProvider = appVersionProvider,
|
||||
environmentConfigStorage = environmentConfigStorage,
|
||||
)
|
||||
ApiConfig.ID.TangemPayAuth -> TangemPay.Auth(
|
||||
appVersionProvider = appVersionProvider,
|
||||
environmentConfigStorage = environmentConfigStorage,
|
||||
)
|
||||
ApiConfig.ID.BlockAid -> BlockAid(configStorage = environmentConfigStorage)
|
||||
ApiConfig.ID.MoonPay -> MoonPay()
|
||||
ApiConfig.ID.P2PEthPool -> P2PEthPool(p2pAuthProvider = p2pEthPoolAuthProvider)
|
||||
|
|
@ -124,7 +132,6 @@ internal class ProdApiConfigsManagerTest {
|
|||
authProvider = appAuthProvider,
|
||||
appInfoProvider = appInfoProvider,
|
||||
)
|
||||
ApiConfig.ID.TangemPayAuth -> TangemPayAuth(appVersionProvider = appVersionProvider)
|
||||
ApiConfig.ID.GaslessTxService -> GaslessTxService(
|
||||
authProvider = appAuthProvider,
|
||||
appVersionProvider = appVersionProvider,
|
||||
|
|
@ -141,11 +148,11 @@ internal class ProdApiConfigsManagerTest {
|
|||
ApiConfig.ID.TangemTech -> createTangemTechModel()
|
||||
ApiConfig.ID.StakeKit -> createStakeKitModel()
|
||||
ApiConfig.ID.TangemPay -> createTangemPayModel()
|
||||
ApiConfig.ID.TangemPayAuth -> createTangemPayAuthModel()
|
||||
ApiConfig.ID.BlockAid -> createBlockAidSdkModel()
|
||||
ApiConfig.ID.MoonPay -> createMoonPayModel()
|
||||
ApiConfig.ID.P2PEthPool -> createP2PModel()
|
||||
ApiConfig.ID.News -> createNewsModel()
|
||||
ApiConfig.ID.TangemPayAuth -> createTangemPayAuthModel()
|
||||
ApiConfig.ID.GaslessTxService -> createGaslessTxServiceModel()
|
||||
}
|
||||
}
|
||||
|
|
@ -269,6 +276,7 @@ internal class ProdApiConfigsManagerTest {
|
|||
headers = mapOf(
|
||||
"version" to ProviderSuspend { VERSION_NAME },
|
||||
"platform" to ProviderSuspend { "Android" },
|
||||
"X-API-KEY" to ProviderSuspend { TANGEM_PAY_BFF_KEY_DEV },
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -283,6 +291,7 @@ internal class ProdApiConfigsManagerTest {
|
|||
headers = mapOf(
|
||||
"version" to ProviderSuspend { VERSION_NAME },
|
||||
"platform" to ProviderSuspend { "Android" },
|
||||
"X-API-KEY" to ProviderSuspend { TANGEM_PAY_BFF_KEY_DEV },
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -185,11 +185,8 @@ internal class DefaultOnboardingRepository @Inject constructor(
|
|||
return Either.Right(hasTangemPay)
|
||||
}
|
||||
|
||||
return requestHelper.performWithStaticToken { staticToken ->
|
||||
tangemPayApi.checkCustomerWalletId(
|
||||
authHeader = staticToken,
|
||||
customerWalletId = userWalletId.stringValue,
|
||||
)
|
||||
return requestHelper.performWithStaticToken {
|
||||
tangemPayApi.checkCustomerWalletId(customerWalletId = userWalletId.stringValue)
|
||||
}.map { response ->
|
||||
val id = response.result?.id
|
||||
val isTangemPayEnabled = response.result?.isTangemPayEnabled == true
|
||||
|
|
@ -205,7 +202,7 @@ internal class DefaultOnboardingRepository @Inject constructor(
|
|||
}
|
||||
|
||||
override suspend fun checkCustomerEligibility(): Boolean {
|
||||
val response = requestHelper.performWithoutToken {
|
||||
val response = requestHelper.performWithStaticToken {
|
||||
tangemPayApi.checkCustomerEligibility()
|
||||
}.getOrNull()
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.tangem.datasource.api.common.response.ApiResponse
|
|||
import com.tangem.datasource.api.pay.TangemPayAuthApi
|
||||
import com.tangem.datasource.api.pay.models.request.RefreshCustomerWalletAccessTokenRequest
|
||||
import com.tangem.datasource.api.pay.models.response.TangemPayGetTokensResponse
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.datasource.local.visa.TangemPayStorage
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
|
|
@ -31,7 +30,6 @@ private const val TAG = "TangemPayRequestPerformer"
|
|||
@Singleton
|
||||
internal class TangemPayRequestPerformer @Inject constructor(
|
||||
private val errorConverter: TangemPayErrorConverter,
|
||||
private val environmentConfigStorage: EnvironmentConfigStorage,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val tangemPayAuthApi: TangemPayAuthApi,
|
||||
private val tangemPayStorage: TangemPayStorage,
|
||||
|
|
@ -40,23 +38,10 @@ internal class TangemPayRequestPerformer @Inject constructor(
|
|||
private val customerWalletAddresses = ConcurrentHashMap<UserWalletId, String>()
|
||||
private val tokensMutex = Mutex()
|
||||
|
||||
suspend fun <T : Any> performWithStaticToken(
|
||||
requestBlock: suspend (header: String) -> ApiResponse<T>,
|
||||
): Either<VisaApiError, T> = withContext(dispatchers.io) {
|
||||
catch(
|
||||
block = {
|
||||
val staticToken =
|
||||
environmentConfigStorage.getConfigSync().bffStaticToken ?: error("BFF static token is null")
|
||||
when (val apiResponse = requestBlock(staticToken)) {
|
||||
is ApiResponse.Error -> errorConverter.convert(apiResponse.cause).left()
|
||||
is ApiResponse.Success<T> -> apiResponse.data.right()
|
||||
}
|
||||
},
|
||||
catch = { errorConverter.convert(it).left() },
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun <T : Any> performWithoutToken(requestBlock: suspend () -> ApiResponse<T>): Either<VisaApiError, T> =
|
||||
/**
|
||||
* Static token added in headers [com.tangem.datasource.api.common.config.TangemPay]
|
||||
*/
|
||||
suspend fun <T : Any> performWithStaticToken(requestBlock: suspend () -> ApiResponse<T>): Either<VisaApiError, T> =
|
||||
withContext(dispatchers.io) {
|
||||
catch(
|
||||
block = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue