Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-08 19:22:21 +03:00
parent a25cbc8d24
commit c63e6daf3c
3 changed files with 85 additions and 16 deletions

View file

@ -7,6 +7,7 @@ import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter import com.tangem.common.routing.AppRouter
import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.Basic import com.tangem.core.analytics.models.Basic
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
import com.tangem.domain.appcurrency.FetchAppCurrenciesUseCase import com.tangem.domain.appcurrency.FetchAppCurrenciesUseCase
import com.tangem.domain.balancehiding.BalanceHidingSettings import com.tangem.domain.balancehiding.BalanceHidingSettings
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
@ -43,8 +44,9 @@ internal class MainViewModel @Inject constructor(
private val walletManagersFacade: WalletManagersFacade, private val walletManagersFacade: WalletManagersFacade,
private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles, private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles,
private val dispatchers: CoroutineDispatcherProvider, private val dispatchers: CoroutineDispatcherProvider,
private val stakingFeatureToggles: StakingFeatureToggles, stakingFeatureToggles: StakingFeatureToggles,
private val fetchStakingTokensUseCase: FetchStakingTokensUseCase, private val fetchStakingTokensUseCase: FetchStakingTokensUseCase,
private val apiConfigsManager: ApiConfigsManager,
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
) : ViewModel(), MainIntents { ) : ViewModel(), MainIntents {
@ -82,6 +84,8 @@ internal class MainViewModel @Inject constructor(
/** Loading the resources needed to run the application */ /** Loading the resources needed to run the application */
private fun loadApplicationResources() { private fun loadApplicationResources() {
viewModelScope.launch(dispatchers.main) { viewModelScope.launch(dispatchers.main) {
apiConfigsManager.initialize()
blockchainSDKFactory.init() blockchainSDKFactory.init()
prepareSelectedWalletFeedback() prepareSelectedWalletFeedback()

View file

@ -3,6 +3,10 @@ package com.tangem.datasource.di
import android.content.Context import android.content.Context
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.tangem.datasource.BuildConfig import com.tangem.datasource.BuildConfig
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
import com.tangem.datasource.api.common.config.managers.DevApiConfigsManager
import com.tangem.datasource.api.common.config.managers.ProdApiConfigsManager
import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory
import com.tangem.datasource.api.express.TangemExpressApi import com.tangem.datasource.api.express.TangemExpressApi
import com.tangem.datasource.api.markets.TangemTechMarketsApi import com.tangem.datasource.api.markets.TangemTechMarketsApi
@ -10,12 +14,15 @@ import com.tangem.datasource.api.stakekit.StakeKitApi
import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.TangemTechApiV2 import com.tangem.datasource.api.tangemTech.TangemTechApiV2
import com.tangem.datasource.api.tangemTech.TangemTechServiceApi import com.tangem.datasource.api.tangemTech.TangemTechServiceApi
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.utils.RequestHeader import com.tangem.datasource.utils.RequestHeader
import com.tangem.datasource.utils.RequestHeader.* import com.tangem.datasource.utils.RequestHeader.*
import com.tangem.datasource.utils.addEnvironmentSwitcher
import com.tangem.datasource.utils.addHeaders import com.tangem.datasource.utils.addHeaders
import com.tangem.datasource.utils.addLoggers import com.tangem.datasource.utils.addLoggers
import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.ExpressAuthProvider
import com.tangem.lib.auth.StakeKitAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.version.AppVersionProvider import com.tangem.utils.version.AppVersionProvider
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
@ -32,6 +39,19 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
class NetworkModule { class NetworkModule {
@Provides
@Singleton
fun provideApiConfigManager(
appPreferencesStore: AppPreferencesStore,
dispatchers: CoroutineDispatcherProvider,
): ApiConfigsManager {
return if (BuildConfig.TESTER_MENU_ENABLED) {
DevApiConfigsManager(appPreferencesStore, dispatchers)
} else {
ProdApiConfigsManager()
}
}
@Provides @Provides
@Singleton @Singleton
fun provideExpressApi( fun provideExpressApi(
@ -39,18 +59,15 @@ class NetworkModule {
@ApplicationContext context: Context, @ApplicationContext context: Context,
expressAuthProvider: ExpressAuthProvider, expressAuthProvider: ExpressAuthProvider,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
): TangemExpressApi { ): TangemExpressApi {
val url = if (BuildConfig.ENVIRONMENT == "dev") {
STAGE_EXPRESS_BASE_URL
} else {
PROD_EXPRESS_BASE_URL
}
return Retrofit.Builder() return Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi)) .addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(ApiResponseCallAdapterFactory.create()) .addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
.baseUrl(url) .baseUrl(apiConfigsManager.getBaseUrl(id = ApiConfig.ID.Express))
.client( .client(
OkHttpClient.Builder() OkHttpClient.Builder()
.addEnvironmentSwitcher(ApiConfig.ID.Express, apiConfigsManager)
.addHeaders(Express(expressAuthProvider)) .addHeaders(Express(expressAuthProvider))
.addHeaders(AppVersionPlatformHeaders(appVersionProvider)) .addHeaders(AppVersionPlatformHeaders(appVersionProvider))
.addLoggers(context) .addLoggers(context)
@ -87,8 +104,15 @@ class NetworkModule {
@NetworkMoshi moshi: Moshi, @NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context, @ApplicationContext context: Context,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
): TangemTechApi { ): TangemTechApi {
return provideTangemTechApiInternal(moshi, context, appVersionProvider, PROD_V1_TANGEM_TECH_BASE_URL) return provideTangemTechApiInternal(
moshi = moshi,
context = context,
appVersionProvider = appVersionProvider,
apiConfigsManager = apiConfigsManager,
baseUrl = apiConfigsManager.getBaseUrl(id = ApiConfig.ID.TangemTech),
)
} }
@Provides @Provides
@ -97,8 +121,15 @@ class NetworkModule {
@NetworkMoshi moshi: Moshi, @NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context, @ApplicationContext context: Context,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
): TangemTechApiV2 { ): TangemTechApiV2 {
return provideTangemTechApiInternal(moshi, context, appVersionProvider, PROD_V2_TANGEM_TECH_BASE_URL) return provideTangemTechApiInternal(
moshi = moshi,
context = context,
appVersionProvider = appVersionProvider,
apiConfigsManager = apiConfigsManager,
baseUrl = PROD_V2_TANGEM_TECH_BASE_URL,
)
} }
@Provides @Provides
@ -108,8 +139,15 @@ class NetworkModule {
@NetworkMoshi moshi: Moshi, @NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context, @ApplicationContext context: Context,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
): TangemTechApi { ): TangemTechApi {
return provideTangemTechApiInternal(moshi, context, appVersionProvider, DEV_V1_TANGEM_TECH_BASE_URL) return provideTangemTechApiInternal(
moshi = moshi,
context = context,
appVersionProvider = appVersionProvider,
apiConfigsManager = apiConfigsManager,
baseUrl = DEV_V1_TANGEM_TECH_BASE_URL,
)
} }
@Provides @Provides
@ -118,12 +156,14 @@ class NetworkModule {
@NetworkMoshi moshi: Moshi, @NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context, @ApplicationContext context: Context,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
): TangemTechServiceApi { ): TangemTechServiceApi {
return provideTangemTechApiInternal( return provideTangemTechApiInternal(
moshi = moshi, moshi = moshi,
context = context, context = context,
appVersionProvider = appVersionProvider, appVersionProvider = appVersionProvider,
baseUrl = PROD_V1_TANGEM_TECH_BASE_URL, apiConfigsManager = apiConfigsManager,
baseUrl = apiConfigsManager.getBaseUrl(id = ApiConfig.ID.TangemTech),
timeouts = Timeouts( timeouts = Timeouts(
callTimeoutSeconds = TANGEM_TECH_SERVICE_TIMEOUT_SECONDS, callTimeoutSeconds = TANGEM_TECH_SERVICE_TIMEOUT_SECONDS,
), ),
@ -138,11 +178,13 @@ class NetworkModule {
@NetworkMoshi moshi: Moshi, @NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context, @ApplicationContext context: Context,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
): TangemTechMarketsApi { ): TangemTechMarketsApi {
return provideTangemTechApiInternal( return provideTangemTechApiInternal(
moshi = moshi, moshi = moshi,
context = context, context = context,
appVersionProvider = appVersionProvider, appVersionProvider = appVersionProvider,
apiConfigsManager = apiConfigsManager,
baseUrl = DEV_V1_TANGEM_TECH_BASE_URL, baseUrl = DEV_V1_TANGEM_TECH_BASE_URL,
timeouts = Timeouts( timeouts = Timeouts(
callTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, callTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS,
@ -157,11 +199,13 @@ class NetworkModule {
moshi: Moshi, moshi: Moshi,
context: Context, context: Context,
appVersionProvider: AppVersionProvider, appVersionProvider: AppVersionProvider,
apiConfigsManager: ApiConfigsManager,
baseUrl: String, baseUrl: String,
timeouts: Timeouts = Timeouts(), timeouts: Timeouts = Timeouts(),
requestHeaders: List<RequestHeader> = listOf(CacheControlHeader, AppVersionPlatformHeaders(appVersionProvider)), requestHeaders: List<RequestHeader> = listOf(CacheControlHeader, AppVersionPlatformHeaders(appVersionProvider)),
): T { ): T {
val client = OkHttpClient.Builder() val client = OkHttpClient.Builder()
.addEnvironmentSwitcher(id = ApiConfig.ID.TangemTech, apiConfigsManager = apiConfigsManager)
.let { builder -> .let { builder ->
var b = builder var b = builder
if (timeouts.callTimeoutSeconds != null) { if (timeouts.callTimeoutSeconds != null) {
@ -204,13 +248,9 @@ class NetworkModule {
private companion object { private companion object {
const val STAKEKIT_BASE_URL = "https://api.stakek.it/v1/" const val STAKEKIT_BASE_URL = "https://api.stakek.it/v1/"
const val PROD_EXPRESS_BASE_URL = "https://express.tangem.com/v1/"
const val STAGE_EXPRESS_BASE_URL = "[REDACTED_ENV_URL]"
const val DEV_EXPRESS_BASE_URL = "[REDACTED_ENV_URL]"
const val DEV_V1_TANGEM_TECH_BASE_URL = "https://devapi.tangem-tech.com/v1/" const val DEV_V1_TANGEM_TECH_BASE_URL = "https://devapi.tangem-tech.com/v1/"
const val PROD_V1_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v1/"
const val PROD_V2_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v2/" const val PROD_V2_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v2/"
const val TANGEM_TECH_SERVICE_TIMEOUT_SECONDS = 5L const val TANGEM_TECH_SERVICE_TIMEOUT_SECONDS = 5L

View file

@ -3,6 +3,9 @@ package com.tangem.datasource.utils
import android.content.Context import android.content.Context
import com.chuckerteam.chucker.api.ChuckerInterceptor import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.tangem.datasource.BuildConfig import com.tangem.datasource.BuildConfig
import com.tangem.datasource.api.common.SwitchBaseUrlInterceptor
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -25,7 +28,7 @@ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeade
/** /**
* Extension for logging each [OkHttpClient] request * Extension for logging each [OkHttpClient] request
* *
* @param level logging level. By default, only the request body. * @param context context
*/ */
internal fun OkHttpClient.Builder.addLoggers(context: Context? = null): OkHttpClient.Builder { internal fun OkHttpClient.Builder.addLoggers(context: Context? = null): OkHttpClient.Builder {
return if (BuildConfig.LOG_ENABLED) { return if (BuildConfig.LOG_ENABLED) {
@ -36,4 +39,26 @@ internal fun OkHttpClient.Builder.addLoggers(context: Context? = null): OkHttpCl
} else { } else {
this this
} }
}
/**
* Add environment switcher
*
* @param id class of [ApiConfig]
* @param apiConfigsManager api configs manager
*/
internal fun OkHttpClient.Builder.addEnvironmentSwitcher(
id: ApiConfig.ID,
apiConfigsManager: ApiConfigsManager,
): OkHttpClient.Builder {
return if (BuildConfig.TESTER_MENU_ENABLED) {
addInterceptor(
interceptor = SwitchBaseUrlInterceptor(
id = id,
apiConfigsManager = apiConfigsManager,
),
)
} else {
this
}
} }