From fcdaf5acfc5bb3b44c96fa10e5b7120eda17790c Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 8 Aug 2025 15:26:34 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../api/tangemTech/TangemTechApiV2.kt | 17 - .../models/v2/UserTokensResponseV2.kt | 26 -- .../com/tangem/datasource/di/NetworkModule.kt | 300 +++--------------- .../datasource/di/utils/RetrofitApiBuilder.kt | 185 +++++++++++ .../tangem/datasource/utils/HttpClientExt.kt | 76 ----- 5 files changed, 221 insertions(+), 383 deletions(-) delete mode 100644 core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechApiV2.kt delete mode 100644 core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/v2/UserTokensResponseV2.kt create mode 100644 core/datasource/src/main/java/com/tangem/datasource/di/utils/RetrofitApiBuilder.kt diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechApiV2.kt b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechApiV2.kt deleted file mode 100644 index 164cd09362..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechApiV2.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.datasource.api.tangemTech - -import com.tangem.datasource.api.common.response.ApiResponse -import com.tangem.datasource.api.tangemTech.models.v2.UserTokensResponseV2 -import retrofit2.http.* - -interface TangemTechApiV2 { - - @GET("user-tokens/{wallet_id}") - suspend fun getUserTokens(@Path("wallet_id") walletId: String): ApiResponse - - @PUT("user-tokens/{wallet_id}") - suspend fun saveUserTokens( - @Path("wallet_id") walletId: String, - @Body userTokens: UserTokensResponseV2, - ): ApiResponse -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/v2/UserTokensResponseV2.kt b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/v2/UserTokensResponseV2.kt deleted file mode 100644 index e03b095d4e..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/v2/UserTokensResponseV2.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.tangem.datasource.api.tangemTech.models.v2 - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass -import com.tangem.datasource.api.tangemTech.models.UserTokensResponse - -@JsonClass(generateAdapter = true) -data class UserTokensResponseV2( - @Json(name = "accounts") - val accounts: List, -) { - - @JsonClass(generateAdapter = true) - data class TokensAccount( - @Json(name = "id") - val id: Int, - @Json(name = "title") - val title: String, - @Json(name = "tokens") - val tokens: List? = null, - @Json(name = "tokensCount") - val tokensCount: Int? = null, - @Json(name = "archived") - val isArchived: Boolean, - ) -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt index 2363c048e7..6c8dc4b626 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt @@ -1,8 +1,5 @@ package com.tangem.datasource.di -import android.content.Context -import com.squareup.moshi.Moshi -import com.tangem.core.analytics.api.AnalyticsErrorHandler import com.tangem.datasource.BuildConfig import com.tangem.datasource.api.common.blockaid.BlockAidApi import com.tangem.datasource.api.common.config.ApiConfig @@ -12,44 +9,29 @@ 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.MockApiConfigsManager import com.tangem.datasource.api.common.config.managers.ProdApiConfigsManager -import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory import com.tangem.datasource.api.express.TangemExpressApi import com.tangem.datasource.api.markets.TangemTechMarketsApi import com.tangem.datasource.api.onramp.OnrampApi import com.tangem.datasource.api.pay.TangemPayApi import com.tangem.datasource.api.stakekit.StakeKitApi import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.api.tangemTech.TangemTechApiV2 -import com.tangem.datasource.local.logs.AppLogsStore +import com.tangem.datasource.di.utils.RetrofitApiBuilder +import com.tangem.datasource.di.utils.RetrofitApiBuilder.Timeouts import com.tangem.datasource.local.preferences.AppPreferencesStore -import com.tangem.datasource.utils.* -import com.tangem.datasource.utils.RequestHeader.AppVersionPlatformHeaders import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import com.tangem.utils.info.AppInfoProvider -import com.tangem.utils.version.AppVersionProvider import dagger.Module import dagger.Provides import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import okhttp3.OkHttpClient -import retrofit2.Retrofit -import retrofit2.converter.moshi.MoshiConverterFactory -import java.util.concurrent.TimeUnit import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) internal object NetworkModule { - private const val PROD_V2_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v2/" private const val TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS = 60L private const val STAKE_KIT_API_TIMEOUT_SECONDS = 60L - private val excludedApiForLogging: Set = setOf( - ApiConfig.ID.StakeKit, - ) - @Provides @Singleton fun provideApiConfigManager( @@ -66,286 +48,76 @@ internal object NetworkModule { @Provides @Singleton - fun provideExpressApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - apiConfigsManager: ApiConfigsManager, - appLogsStore: AppLogsStore, - ): TangemExpressApi { - return createApi( - id = ApiConfig.ID.Express, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, - clientBuilder = { - addInterceptor( - NetworkLogsSaveInterceptor(appLogsStore), - ) - }, + fun provideExpressApi(retrofitApiBuilder: RetrofitApiBuilder): TangemExpressApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.Express, + applyTimeoutAnnotations = false, ) } @Provides @Singleton - fun provideStakeKitApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - apiConfigsManager: ApiConfigsManager, - analyticsErrorHandler: AnalyticsErrorHandler, - appLogsStore: AppLogsStore, - ): StakeKitApi { - return createApi( - id = ApiConfig.ID.StakeKit, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, + fun provideStakeKitApi(retrofitApiBuilder: RetrofitApiBuilder): StakeKitApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.StakeKit, + applyTimeoutAnnotations = false, timeouts = Timeouts( callTimeoutSeconds = STAKE_KIT_API_TIMEOUT_SECONDS, connectTimeoutSeconds = STAKE_KIT_API_TIMEOUT_SECONDS, readTimeoutSeconds = STAKE_KIT_API_TIMEOUT_SECONDS, writeTimeoutSeconds = STAKE_KIT_API_TIMEOUT_SECONDS, ), - clientBuilder = { - addInterceptor( - NetworkLogsSaveInterceptor(appLogsStore), - ) - }, ) } @Provides @Singleton - fun provideOnrampApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - apiConfigsManager: ApiConfigsManager, - appLogsStore: AppLogsStore, - ): OnrampApi { - return createApi( - id = ApiConfig.ID.Express, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, - clientBuilder = { - addInterceptor( - NetworkLogsSaveInterceptor(appLogsStore), - ) - }, + fun provideOnrampApi(retrofitApiBuilder: RetrofitApiBuilder): OnrampApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.Express, + applyTimeoutAnnotations = false, ) } @Provides @Singleton - fun provideTangemTechApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - apiConfigsManager: ApiConfigsManager, - ): TangemTechApi { - return createApi( - id = ApiConfig.ID.TangemTech, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, - clientBuilder = { applyTimeoutAnnotations() }, - ) - } - - // TODO: It will be deleted in the future or refactored using ApiConfig - @Provides - @Singleton - fun provideTangemTechApiV2( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - appVersionProvider: AppVersionProvider, - appInfoProvider: AppInfoProvider, - ): TangemTechApiV2 { - return provideTangemTechApiInternal( - moshi = moshi, - context = context, - appVersionProvider = appVersionProvider, - baseUrl = PROD_V2_TANGEM_TECH_BASE_URL, - analyticsErrorHandler = analyticsErrorHandler, - appInfoProvider = appInfoProvider, + fun provideTangemTechApi(retrofitApiBuilder: RetrofitApiBuilder): TangemTechApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.TangemTech, + applyTimeoutAnnotations = true, ) } @Provides @Singleton - fun provideTangemTechMarketsApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - apiConfigsManager: ApiConfigsManager, - ): TangemTechMarketsApi { - return createApi( - id = ApiConfig.ID.TangemTech, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, - clientBuilder = { - this.callTimeout(TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, TimeUnit.SECONDS) - .connectTimeout(TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, TimeUnit.SECONDS) - .readTimeout(TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, TimeUnit.SECONDS) - .applyTimeoutAnnotations() - }, + fun provideTangemTechMarketsApi(retrofitApiBuilder: RetrofitApiBuilder): TangemTechMarketsApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.TangemTech, + applyTimeoutAnnotations = false, + timeouts = Timeouts( + callTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, + connectTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, + readTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS, + ), + logsSaving = false, ) } @Provides @Singleton - fun provideTangemVisaApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - apiConfigsManager: ApiConfigsManager, - appLogsStore: AppLogsStore, - ): TangemPayApi { - return createApi( - id = ApiConfig.ID.TangemPay, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, - clientBuilder = { - addInterceptor( - NetworkLogsSaveInterceptor(appLogsStore), - ).applyTimeoutAnnotations() - }, + fun provideTangemVisaApi(retrofitApiBuilder: RetrofitApiBuilder): TangemPayApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.TangemPay, + applyTimeoutAnnotations = false, ) } - @Suppress("LongParameterList") - @Deprecated("use createApi instead") - private inline fun provideTangemTechApiInternal( - moshi: Moshi, - context: Context, - appVersionProvider: AppVersionProvider, - appInfoProvider: AppInfoProvider, - baseUrl: String, - analyticsErrorHandler: AnalyticsErrorHandler, - timeouts: Timeouts = Timeouts(), - requestHeaders: List = listOf(AppVersionPlatformHeaders(appVersionProvider, appInfoProvider)), - ): T { - val client = OkHttpClient.Builder() - .applyTimeoutAnnotations() - .let { builder -> - var b = builder - if (timeouts.callTimeoutSeconds != null) { - b = b.callTimeout(timeouts.callTimeoutSeconds, TimeUnit.SECONDS) - } - if (timeouts.connectTimeoutSeconds != null) { - b = b.connectTimeout(timeouts.connectTimeoutSeconds, TimeUnit.SECONDS) - } - if (timeouts.readTimeoutSeconds != null) { - b = b.readTimeout(timeouts.readTimeoutSeconds, TimeUnit.SECONDS) - } - if (timeouts.writeTimeoutSeconds != null) { - b = b.writeTimeout(timeouts.writeTimeoutSeconds, TimeUnit.SECONDS) - } - b - } - .addHeaders( - *requestHeaders.toTypedArray(), - // TODO("refactor header init") get auth data after biometric auth to avoid race condition - // AuthenticationHeader(authProvider), - ) - .addLoggers(context) - .build() - - return Retrofit.Builder() - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .addCallAdapterFactory(ApiResponseCallAdapterFactory.create(analyticsErrorHandler)) - .baseUrl(baseUrl) - .client(client) - .build() - .create(T::class.java) - } - @Provides @Singleton - fun provideBlockAidApi( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - analyticsErrorHandler: AnalyticsErrorHandler, - apiConfigsManager: ApiConfigsManager, - appLogsStore: AppLogsStore, - ): BlockAidApi { - return createApi( - id = ApiConfig.ID.BlockAid, - moshi = moshi, - context = context, - apiConfigsManager = apiConfigsManager, - analyticsErrorHandler = analyticsErrorHandler, - clientBuilder = { - addInterceptor( - NetworkLogsSaveInterceptor(appLogsStore), - ).applyTimeoutAnnotations() - }, + fun provideBlockAidApi(retrofitApiBuilder: RetrofitApiBuilder): BlockAidApi { + return retrofitApiBuilder.build( + apiConfigId = ApiConfig.ID.BlockAid, + applyTimeoutAnnotations = false, ) } - - private inline fun createApi( - id: ApiConfig.ID, - moshi: Moshi, - context: Context, - apiConfigsManager: ApiConfigsManager, - analyticsErrorHandler: AnalyticsErrorHandler, - timeouts: Timeouts = Timeouts(), - clientBuilder: OkHttpClient.Builder.() -> OkHttpClient.Builder = { this }, - ): T { - val environmentConfig = apiConfigsManager.getEnvironmentConfig(id) - - return Retrofit.Builder() - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .addCallAdapterFactory(ApiResponseCallAdapterFactory.create(analyticsErrorHandler)) - .baseUrl(environmentConfig.baseUrl) - .client( - OkHttpClient.Builder() - .applyApiConfig(id, apiConfigsManager) - .applyTimeoutAnnotations() - .let { builder -> - var b = builder - if (timeouts.callTimeoutSeconds != null) { - b = b.callTimeout(timeouts.callTimeoutSeconds, TimeUnit.SECONDS) - } - if (timeouts.connectTimeoutSeconds != null) { - b = b.connectTimeout(timeouts.connectTimeoutSeconds, TimeUnit.SECONDS) - } - if (timeouts.readTimeoutSeconds != null) { - b = b.readTimeout(timeouts.readTimeoutSeconds, TimeUnit.SECONDS) - } - if (timeouts.writeTimeoutSeconds != null) { - b = b.writeTimeout(timeouts.writeTimeoutSeconds, TimeUnit.SECONDS) - } - b - } - .addLoggers(context = context, id = id) - .clientBuilder() - .build(), - ) - .build() - .create(T::class.java) - } - - private fun OkHttpClient.Builder.addLoggers(context: Context, id: ApiConfig.ID): OkHttpClient.Builder { - if (id in excludedApiForLogging) return this - - return addLoggers(context) - } - - private data class Timeouts( - val callTimeoutSeconds: Long? = null, - val connectTimeoutSeconds: Long? = null, - val readTimeoutSeconds: Long? = null, - val writeTimeoutSeconds: Long? = null, - ) } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/utils/RetrofitApiBuilder.kt b/core/datasource/src/main/java/com/tangem/datasource/di/utils/RetrofitApiBuilder.kt new file mode 100644 index 0000000000..87de60fbd0 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/di/utils/RetrofitApiBuilder.kt @@ -0,0 +1,185 @@ +package com.tangem.datasource.di.utils + +import android.content.Context +import com.chuckerteam.chucker.api.ChuckerInterceptor +import com.squareup.moshi.Moshi +import com.tangem.core.analytics.api.AnalyticsErrorHandler +import com.tangem.datasource.BuildConfig +import com.tangem.datasource.api.common.SwitchEnvironmentInterceptor +import com.tangem.datasource.api.common.config.ApiConfig +import com.tangem.datasource.api.common.config.ApiConfig.Companion.MOCKED_BUILD_TYPE +import com.tangem.datasource.api.common.config.ApiEnvironmentConfig +import com.tangem.datasource.api.common.config.managers.ApiConfigsManager +import com.tangem.datasource.api.common.createNetworkLoggingInterceptor +import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory +import com.tangem.datasource.api.utils.ConnectTimeout +import com.tangem.datasource.api.utils.ReadTimeout +import com.tangem.datasource.api.utils.WriteTimeout +import com.tangem.datasource.di.NetworkMoshi +import com.tangem.datasource.local.logs.AppLogsStore +import com.tangem.datasource.utils.NetworkLogsSaveInterceptor +import com.tangem.datasource.utils.addHeaders +import dagger.hilt.android.qualifiers.ApplicationContext +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import retrofit2.Invocation +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import java.util.concurrent.TimeUnit +import javax.inject.Inject +import javax.inject.Singleton + +/** + * A builder class for creating Retrofit API instances + * + * @property apiConfigsManager manages API configurations for different environments + * @property moshi moshi + * @property analyticsErrorHandler handles analytics-related errors + * @property context application context + * @property appLogsStore application logs store + * +[REDACTED_AUTHOR] + */ +@Singleton +internal class RetrofitApiBuilder @Inject constructor( + private val apiConfigsManager: ApiConfigsManager, + @NetworkMoshi private val moshi: Moshi, + private val analyticsErrorHandler: AnalyticsErrorHandler, + @ApplicationContext private val context: Context, + private val appLogsStore: AppLogsStore, +) { + + /** + * Builds a Retrofit API instance for the specified API configuration ID + * + * @param apiConfigId the ID of the API configuration to use + * @param applyTimeoutAnnotations whether to apply timeout annotations to the requests. See [ReadTimeout], etc. + * @param timeouts optional timeouts for the requests + * @param logsSaving whether to enable logs saving + * + * @return an instance [T] of the specified API interface + */ + inline fun build( + apiConfigId: ApiConfig.ID, + applyTimeoutAnnotations: Boolean, + timeouts: Timeouts? = null, + logsSaving: Boolean = true, + ): T { + val environmentConfig = apiConfigsManager.getEnvironmentConfig(apiConfigId) + + return Retrofit.Builder() + .addConverterFactory(MoshiConverterFactory.create(moshi)) + .addCallAdapterFactory(ApiResponseCallAdapterFactory.create(analyticsErrorHandler)) + .baseUrl(environmentConfig.baseUrl) + .client( + OkHttpClient.Builder() + .applyApiConfig(apiConfigId = apiConfigId, environmentConfig = environmentConfig) + .let { + if (applyTimeoutAnnotations) it.applyTimeoutAnnotations() else it + } + .applyTimeouts(timeouts = timeouts) + .let { + if (logsSaving) it.applyLogsSaving() else it + } + .addLoggers(apiConfigId = apiConfigId, context = context) + .build(), + ) + .build() + .create(T::class.java) + } + + data class Timeouts( + val callTimeoutSeconds: Long? = null, + val connectTimeoutSeconds: Long? = null, + val readTimeoutSeconds: Long? = null, + val writeTimeoutSeconds: Long? = null, + ) + + private fun OkHttpClient.Builder.applyApiConfig( + apiConfigId: ApiConfig.ID, + environmentConfig: ApiEnvironmentConfig, + ): OkHttpClient.Builder { + return if (BuildConfig.TESTER_MENU_ENABLED || BuildConfig.BUILD_TYPE == MOCKED_BUILD_TYPE) { + addInterceptor( + interceptor = SwitchEnvironmentInterceptor(id = apiConfigId, apiConfigsManager = apiConfigsManager), + ) + } else { + val headers = environmentConfig.headers + + this.addHeaders(headers) + } + } + + private fun OkHttpClient.Builder.applyTimeouts(timeouts: Timeouts?): OkHttpClient.Builder { + if (timeouts == null) return this + + var b = this + + if (timeouts.callTimeoutSeconds != null) { + b = b.callTimeout(timeouts.callTimeoutSeconds, TimeUnit.SECONDS) + } + if (timeouts.connectTimeoutSeconds != null) { + b = b.connectTimeout(timeouts.connectTimeoutSeconds, TimeUnit.SECONDS) + } + if (timeouts.readTimeoutSeconds != null) { + b = b.readTimeout(timeouts.readTimeoutSeconds, TimeUnit.SECONDS) + } + if (timeouts.writeTimeoutSeconds != null) { + b = b.writeTimeout(timeouts.writeTimeoutSeconds, TimeUnit.SECONDS) + } + + return b + } + + /** + * Apply timeout annotations [Interceptor]. + * Add this [Interceptor] to [OkHttpClient] if use timeout annotations for retrofit requests. + */ + private fun OkHttpClient.Builder.applyTimeoutAnnotations(): OkHttpClient.Builder { + return addInterceptor( + Interceptor { chain -> + val request = chain.request() + val tag = request.tag(Invocation::class.java) + val connectionTimeout = tag?.method()?.getAnnotation(ConnectTimeout::class.java) + val readTimeout = tag?.method()?.getAnnotation(ReadTimeout::class.java) + val writeTimeout = tag?.method()?.getAnnotation(WriteTimeout::class.java) + + chain + .run { + connectionTimeout?.let { withConnectTimeout(timeout = it.duration, unit = it.unit) } ?: this + } + .run { + readTimeout?.let { withReadTimeout(timeout = it.duration, unit = it.unit) } ?: this + } + .run { + writeTimeout?.let { withWriteTimeout(timeout = it.duration, unit = it.unit) } ?: this + } + .proceed(request) + }, + ) + } + + private fun OkHttpClient.Builder.applyLogsSaving(): OkHttpClient.Builder { + return addInterceptor( + interceptor = NetworkLogsSaveInterceptor(appLogsStore), + ) + } + + private fun OkHttpClient.Builder.addLoggers(apiConfigId: ApiConfig.ID, context: Context): OkHttpClient.Builder { + if (apiConfigId in excludedApiForLogging) return this + + return if (BuildConfig.LOG_ENABLED) { + addInterceptor(interceptor = ChuckerInterceptor(context)) + addInterceptor(interceptor = createNetworkLoggingInterceptor()) + } else { + this + } + } + + private companion object { + + val excludedApiForLogging: Set = setOf( + // ApiConfig.ID.StakeKit, + ) + } +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt index ed7d4c62b3..eb040fb1e4 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt @@ -1,21 +1,9 @@ package com.tangem.datasource.utils -import android.content.Context -import com.chuckerteam.chucker.api.ChuckerInterceptor -import com.tangem.datasource.BuildConfig -import com.tangem.datasource.api.common.SwitchEnvironmentInterceptor -import com.tangem.datasource.api.common.config.ApiConfig -import com.tangem.datasource.api.common.config.ApiConfig.Companion.MOCKED_BUILD_TYPE -import com.tangem.datasource.api.common.config.managers.ApiConfigsManager -import com.tangem.datasource.api.common.createNetworkLoggingInterceptor -import com.tangem.datasource.api.utils.ConnectTimeout -import com.tangem.datasource.api.utils.ReadTimeout -import com.tangem.datasource.api.utils.WriteTimeout import com.tangem.utils.ProviderSuspend import kotlinx.coroutines.runBlocking import okhttp3.Interceptor import okhttp3.OkHttpClient -import retrofit2.Invocation /** Extension for adding headers [requestHeaders] to every [OkHttpClient] request */ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeader): OkHttpClient.Builder { @@ -24,30 +12,6 @@ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeade ) } -/** - * Apply timeout annotations [Interceptor]. - * Add this [Interceptor] to [OkHttpClient] if use timeout annotations for retrofit requests. - */ -internal fun OkHttpClient.Builder.applyTimeoutAnnotations(): OkHttpClient.Builder { - return addInterceptor( - Interceptor { chain -> - val request = chain.request() - val tag = request.tag(Invocation::class.java) - val connectionTimeout = tag?.method()?.getAnnotation(ConnectTimeout::class.java) - val readTimeout = tag?.method()?.getAnnotation(ReadTimeout::class.java) - val writeTimeout = tag?.method()?.getAnnotation(WriteTimeout::class.java) - - chain.run { - connectionTimeout?.let { withConnectTimeout(timeout = it.duration, unit = it.unit) } ?: this - }.run { - readTimeout?.let { withReadTimeout(timeout = it.duration, unit = it.unit) } ?: this - }.run { - writeTimeout?.let { withWriteTimeout(timeout = it.duration, unit = it.unit) } ?: this - }.proceed(request) - }, - ) -} - /** Extension for adding headers [requestHeaders] to every [OkHttpClient] request */ internal fun OkHttpClient.Builder.addHeaders( requestHeaders: Map>, @@ -66,44 +30,4 @@ internal fun OkHttpClient.Builder.addHeaders( chain.proceed(request) }, ) -} - -/** - * Extension for logging each [OkHttpClient] request - * - * @param context context - */ -internal fun OkHttpClient.Builder.addLoggers(context: Context? = null): OkHttpClient.Builder { - return if (BuildConfig.LOG_ENABLED) { - context?.let { - addInterceptor(interceptor = ChuckerInterceptor(it)) - } - addInterceptor(interceptor = createNetworkLoggingInterceptor()) - } else { - this - } -} - -/** - * Apply api config - * - * @param id class of [ApiConfig] - * @param apiConfigsManager api configs manager - */ -internal fun OkHttpClient.Builder.applyApiConfig( - id: ApiConfig.ID, - apiConfigsManager: ApiConfigsManager, -): OkHttpClient.Builder { - return if (BuildConfig.TESTER_MENU_ENABLED || BuildConfig.BUILD_TYPE == MOCKED_BUILD_TYPE) { - addInterceptor( - interceptor = SwitchEnvironmentInterceptor( - id = id, - apiConfigsManager = apiConfigsManager, - ), - ) - } else { - val headers = apiConfigsManager.getEnvironmentConfig(id).headers - - this.addHeaders(headers) - } } \ No newline at end of file