Updated on 2026-08-14
This commit is contained in:
commit
76bf94f718
407 changed files with 9866 additions and 3473 deletions
|
|
@ -25,7 +25,6 @@ sealed class ApiConfig {
|
|||
TangemTech,
|
||||
StakeKit,
|
||||
TangemPay,
|
||||
Attestation,
|
||||
BlockAid,
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +34,6 @@ sealed class ApiConfig {
|
|||
is TangemTech -> ID.TangemTech
|
||||
is StakeKit -> ID.StakeKit
|
||||
is TangemPay -> ID.TangemPay
|
||||
is Attestation -> ID.Attestation
|
||||
is BlockAid -> ID.BlockAid
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ enum class ApiEnvironment {
|
|||
@Json(name = "STAGE")
|
||||
STAGE,
|
||||
|
||||
@Json(name = "MOCK")
|
||||
MOCK,
|
||||
|
||||
@Json(name = "PROD")
|
||||
PROD,
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package com.tangem.datasource.api.common.config
|
||||
|
||||
/**
|
||||
* Attestation [ApiConfig] that used in CardSDK
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class Attestation : ApiConfig() {
|
||||
|
||||
override val defaultEnvironment: ApiEnvironment = ApiEnvironment.PROD
|
||||
|
||||
override val environmentConfigs: List<ApiEnvironmentConfig> = listOf(
|
||||
createDevEnvironment(),
|
||||
createProdEnvironment(),
|
||||
)
|
||||
|
||||
private fun createDevEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.DEV,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
)
|
||||
|
||||
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.PROD,
|
||||
baseUrl = "https://api.tangem-tech.com/",
|
||||
)
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import com.tangem.utils.version.AppVersionProvider
|
|||
* @property environmentConfigStorage environment config storage
|
||||
* @property expressAuthProvider express auth provider
|
||||
* @property appVersionProvider app version provider
|
||||
* @property appInfoProvider app info provider
|
||||
*/
|
||||
internal class Express(
|
||||
private val environmentConfigStorage: EnvironmentConfigStorage,
|
||||
|
|
@ -27,9 +28,25 @@ internal class Express(
|
|||
override val environmentConfigs: List<ApiEnvironmentConfig> = listOf(
|
||||
createDevEnvironment(),
|
||||
createStageEnvironment(),
|
||||
createMockedEnvironment(),
|
||||
createProdEnvironment(),
|
||||
)
|
||||
|
||||
private fun getInitialEnvironment(): ApiEnvironment {
|
||||
return when (BuildConfig.BUILD_TYPE) {
|
||||
DEBUG_BUILD_TYPE,
|
||||
-> ApiEnvironment.DEV
|
||||
INTERNAL_BUILD_TYPE,
|
||||
-> ApiEnvironment.STAGE
|
||||
MOCKED_BUILD_TYPE,
|
||||
-> ApiEnvironment.MOCK
|
||||
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 = "[REDACTED_ENV_URL]",
|
||||
|
|
@ -42,6 +59,12 @@ internal class Express(
|
|||
headers = createHeaders(isProd = false),
|
||||
)
|
||||
|
||||
private fun createMockedEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.MOCK,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
headers = createHeaders(isProd = false),
|
||||
)
|
||||
|
||||
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.PROD,
|
||||
baseUrl = "https://express.tangem.com/v1/",
|
||||
|
|
@ -63,21 +86,4 @@ internal class Express(
|
|||
?.apiKey
|
||||
?: error("No express config provided")
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
fun getInitialEnvironment(): ApiEnvironment {
|
||||
return when (BuildConfig.BUILD_TYPE) {
|
||||
DEBUG_BUILD_TYPE,
|
||||
-> ApiEnvironment.DEV
|
||||
INTERNAL_BUILD_TYPE,
|
||||
MOCKED_BUILD_TYPE,
|
||||
-> ApiEnvironment.STAGE
|
||||
EXTERNAL_BUILD_TYPE,
|
||||
RELEASE_BUILD_TYPE,
|
||||
-> ApiEnvironment.PROD
|
||||
else -> error("Unknown build type [${BuildConfig.BUILD_TYPE}]")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.datasource.api.common.config
|
||||
|
||||
import com.tangem.datasource.BuildConfig
|
||||
import com.tangem.utils.ProviderSuspend
|
||||
import com.tangem.utils.version.AppVersionProvider
|
||||
|
||||
|
|
@ -7,11 +8,37 @@ internal class TangemPay(
|
|||
private val appVersionProvider: AppVersionProvider,
|
||||
) : ApiConfig() {
|
||||
|
||||
override val defaultEnvironment: ApiEnvironment = ApiEnvironment.DEV
|
||||
override val defaultEnvironment: ApiEnvironment = getInitialEnvironment()
|
||||
|
||||
override val environmentConfigs = listOf(
|
||||
createProdEnvironment(),
|
||||
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 = "[REDACTED_ENV_URL]",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createMockedEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.MOCK,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
|
|
@ -20,12 +47,6 @@ internal class TangemPay(
|
|||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createDevEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.DEV,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createHeaders() = mapOf(
|
||||
"version" to ProviderSuspend { appVersionProvider.versionName },
|
||||
"platform" to ProviderSuspend { "Android" },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.datasource.api.common.config
|
||||
|
||||
import com.tangem.datasource.BuildConfig
|
||||
import com.tangem.datasource.api.common.AuthProvider
|
||||
import com.tangem.datasource.utils.RequestHeader
|
||||
import com.tangem.utils.info.AppInfoProvider
|
||||
|
|
@ -12,18 +13,27 @@ internal class TangemTech(
|
|||
private val appInfoProvider: AppInfoProvider,
|
||||
) : ApiConfig() {
|
||||
|
||||
override val defaultEnvironment: ApiEnvironment = ApiEnvironment.PROD
|
||||
override val defaultEnvironment: ApiEnvironment = getInitialEnvironment()
|
||||
|
||||
override val environmentConfigs = listOf(
|
||||
createDevEnvironment(),
|
||||
createStageEnvironment(),
|
||||
createMockedEnvironment(),
|
||||
createProdEnvironment(),
|
||||
)
|
||||
|
||||
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.PROD,
|
||||
baseUrl = "https://api.tangem.org/v1/",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
private fun getInitialEnvironment(): ApiEnvironment {
|
||||
return when (BuildConfig.BUILD_TYPE) {
|
||||
MOCKED_BUILD_TYPE,
|
||||
-> ApiEnvironment.MOCK
|
||||
DEBUG_BUILD_TYPE,
|
||||
INTERNAL_BUILD_TYPE,
|
||||
EXTERNAL_BUILD_TYPE,
|
||||
RELEASE_BUILD_TYPE,
|
||||
-> ApiEnvironment.PROD
|
||||
else -> error("Unknown build type [${BuildConfig.BUILD_TYPE}]")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDevEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.DEV,
|
||||
|
|
@ -31,6 +41,24 @@ internal class TangemTech(
|
|||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createStageEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
|
||||
environment = ApiEnvironment.STAGE,
|
||||
baseUrl = "[REDACTED_ENV_URL]",
|
||||
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.tangem.org/",
|
||||
headers = createHeaders(),
|
||||
)
|
||||
|
||||
private fun createHeaders() = buildMap {
|
||||
putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider, appInfoProvider).values)
|
||||
putAll(from = RequestHeader.AuthenticationHeader(authProvider).values)
|
||||
|
|
|
|||
|
|
@ -20,44 +20,42 @@ import kotlinx.coroutines.flow.*
|
|||
* @property dispatchers coroutine dispatcher provider
|
||||
*/
|
||||
internal class DevApiConfigsManager(
|
||||
apiConfigs: ApiConfigs,
|
||||
private val apiConfigs: ApiConfigs,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : MutableApiConfigsManager {
|
||||
) : MutableApiConfigsManager() {
|
||||
|
||||
override val configs: Flow<Map<ApiConfig, ApiEnvironment>> get() = _apiConfigs
|
||||
override val configs: StateFlow<Map<ApiConfig, ApiEnvironment>>
|
||||
field = MutableStateFlow(value = getInitialConfigs())
|
||||
|
||||
private val _apiConfigs = MutableStateFlow(value = apiConfigs.associateWith { it.defaultEnvironment })
|
||||
|
||||
override val isInitialized: StateFlow<Boolean> get() = _isInitialized.asStateFlow()
|
||||
|
||||
private val _isInitialized = MutableStateFlow(value = false)
|
||||
override val isInitialized: StateFlow<Boolean>
|
||||
field = MutableStateFlow(value = false)
|
||||
|
||||
override fun initialize() {
|
||||
_isInitialized.value = false
|
||||
isInitialized.value = false
|
||||
|
||||
// We can't use appPreferencesStore.getObjectMap as base flow,
|
||||
// because we should keep possibility to work with configs synchronous.
|
||||
// See [getBaseUrl]
|
||||
appPreferencesStore.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
|
||||
.distinctUntilChanged()
|
||||
.onEach { savedEnvironments ->
|
||||
_apiConfigs.update { apiConfigs ->
|
||||
apiConfigs.mapValues {
|
||||
val (config, currentEnvironment) = it
|
||||
val apiConfigs = configs.value
|
||||
|
||||
savedEnvironments[config.id.name] ?: currentEnvironment
|
||||
}
|
||||
configs.value = apiConfigs.mapValues {
|
||||
val (config, currentEnvironment) = it
|
||||
|
||||
savedEnvironments[config.id.name] ?: currentEnvironment
|
||||
}
|
||||
|
||||
if (!_isInitialized.value) {
|
||||
_isInitialized.value = true
|
||||
if (!isInitialized.value) {
|
||||
isInitialized.value = true
|
||||
}
|
||||
|
||||
notifyListeners(apiConfigs = apiConfigs, savedEnvironments = savedEnvironments)
|
||||
}
|
||||
.launchIn(CoroutineScope(SupervisorJob() + dispatchers.default))
|
||||
}
|
||||
|
||||
override fun getEnvironmentConfig(id: ApiConfig.ID): ApiEnvironmentConfig {
|
||||
val apiConfigs = _apiConfigs.value
|
||||
val apiConfigs = configs.value
|
||||
|
||||
val config = apiConfigs.map { it }.firstOrNull { it.key.id == id }?.key
|
||||
?: error("Api config with id [$id] not found")
|
||||
|
|
@ -78,4 +76,56 @@ internal class DevApiConfigsManager(
|
|||
mutablePreferences.setObjectMap(PreferencesKeys.apiConfigsEnvironmentKey, updatedMap)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun changeEnvironment(environment: ApiEnvironment) {
|
||||
val supportedConfigs = apiConfigs
|
||||
.filter { config ->
|
||||
config.environmentConfigs.any { it.environment == environment }
|
||||
}
|
||||
.map { it.id.name }
|
||||
|
||||
appPreferencesStore.editData { mutablePreferences ->
|
||||
val updatedMap = mutablePreferences.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
|
||||
.mapValues { (configName, currentEnvironment) ->
|
||||
val isEnvSupported = supportedConfigs.contains(configName)
|
||||
|
||||
if (isEnvSupported) environment else currentEnvironment
|
||||
}
|
||||
|
||||
mutablePreferences.setObjectMap(key = PreferencesKeys.apiConfigsEnvironmentKey, value = updatedMap)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(
|
||||
apiConfigs: Map<ApiConfig, ApiEnvironment>,
|
||||
savedEnvironments: Map<String, ApiEnvironment>,
|
||||
) {
|
||||
if (registerListeners.isNotEmpty()) {
|
||||
val changedConfigs = apiConfigs.mapNotNull { (config, prevEnvironment) ->
|
||||
val newEnvironment = savedEnvironments[config.id.name] ?: config.defaultEnvironment
|
||||
|
||||
if (prevEnvironment == newEnvironment) return@mapNotNull null
|
||||
|
||||
val environmentConfig = config.environmentConfigs
|
||||
.firstOrNull { it.environment == newEnvironment }
|
||||
?: return@mapNotNull null
|
||||
|
||||
config.id to environmentConfig
|
||||
}
|
||||
|
||||
if (changedConfigs.isNotEmpty()) {
|
||||
registerListeners.forEach { listener ->
|
||||
val changedConfig = changedConfigs.firstOrNull { it.first == listener.id }?.second
|
||||
|
||||
if (changedConfig != null) {
|
||||
listener.onChange(changedConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInitialConfigs(): Map<ApiConfig, ApiEnvironment> {
|
||||
return apiConfigs.associateWith(ApiConfig::defaultEnvironment)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.tangem.datasource.api.common.config.managers
|
||||
|
||||
import com.tangem.datasource.api.common.config.ApiConfig
|
||||
import com.tangem.datasource.api.common.config.ApiConfigs
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironmentConfig
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* Implementation of [ApiConfigsManager] in MOCK environment
|
||||
*
|
||||
* @property apiConfigs api configs
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class MockApiConfigsManager(
|
||||
private val apiConfigs: ApiConfigs,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
) : MutableApiConfigsManager() {
|
||||
|
||||
override val configs: StateFlow<Map<ApiConfig, ApiEnvironment>>
|
||||
field = MutableStateFlow(value = getInitialConfigs())
|
||||
|
||||
override val isInitialized: StateFlow<Boolean> = MutableStateFlow(value = true)
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default)
|
||||
|
||||
override fun initialize() = Unit
|
||||
|
||||
override fun getEnvironmentConfig(id: ApiConfig.ID): ApiEnvironmentConfig {
|
||||
val apiConfigs = configs.value
|
||||
|
||||
val (config, currentEnvironment) = apiConfigs.entries.firstOrNull { it.key.id == id }
|
||||
?: error("Api config with id [$id] not found")
|
||||
|
||||
return config.environmentConfigs.firstOrNull { it.environment == currentEnvironment }
|
||||
?: error("Api config with id [$id] doesn't contain environment [$currentEnvironment]")
|
||||
}
|
||||
|
||||
override suspend fun changeEnvironment(id: String, environment: ApiEnvironment) {
|
||||
configs.update { apiConfigs ->
|
||||
val apiConfig = apiConfigs.keys.firstOrNull { it.id.name == id }
|
||||
?: error("Api config with id [$id] not found. Check that ApiConfig with id [$id] was provided into DI")
|
||||
|
||||
apiConfigs + (apiConfig to environment)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun changeEnvironment(environment: ApiEnvironment) {
|
||||
configs.update { apiConfigs ->
|
||||
apiConfigs.mapValues { (config, currentEnvironment) ->
|
||||
val isEnvSupported = config.environmentConfigs.any { it.environment == environment }
|
||||
|
||||
if (isEnvSupported) environment else currentEnvironment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun addListener(listener: ApiConfigEnvChangeListener) {
|
||||
super.addListener(listener)
|
||||
|
||||
configs
|
||||
.map { it.entries.firstOrNull { it.key.id == listener.id } }
|
||||
.filterNotNull()
|
||||
.onEach { (apiConfig, currentEnvironment) ->
|
||||
listener.onChange(
|
||||
environmentConfig = apiConfig.environmentConfigs.first { it.environment == currentEnvironment },
|
||||
)
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
private fun getInitialConfigs(): Map<ApiConfig, ApiEnvironment> {
|
||||
return apiConfigs.associateWith { it.defaultEnvironment }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.datasource.api.common.config.managers
|
|||
|
||||
import com.tangem.datasource.api.common.config.ApiConfig
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironmentConfig
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
|
|
@ -9,11 +10,41 @@ import kotlinx.coroutines.flow.Flow
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface MutableApiConfigsManager : ApiConfigsManager {
|
||||
abstract class MutableApiConfigsManager : ApiConfigsManager {
|
||||
|
||||
/** Api configs with current [ApiEnvironment] */
|
||||
val configs: Flow<Map<ApiConfig, ApiEnvironment>>
|
||||
abstract val configs: Flow<Map<ApiConfig, ApiEnvironment>>
|
||||
|
||||
/**
|
||||
* A set of listeners registered to observe changes in API environment configurations.
|
||||
* These listeners are notified whenever an environment change occurs.
|
||||
*/
|
||||
protected val registerListeners: Set<ApiConfigEnvChangeListener>
|
||||
field = mutableSetOf<ApiConfigEnvChangeListener>()
|
||||
|
||||
/** Change api environment [environment] by [id] */
|
||||
suspend fun changeEnvironment(id: String, environment: ApiEnvironment)
|
||||
abstract suspend fun changeEnvironment(id: String, environment: ApiEnvironment)
|
||||
|
||||
/** Change api environment [environment] for all configs */
|
||||
abstract suspend fun changeEnvironment(environment: ApiEnvironment)
|
||||
|
||||
/** Adds a [listener] to observe changes in API environment configurations */
|
||||
open fun addListener(listener: ApiConfigEnvChangeListener) {
|
||||
registerListeners += listener
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for observing changes in API environment configurations
|
||||
*
|
||||
* @property id the identifier of the API configuration this listener is associated with
|
||||
*/
|
||||
abstract class ApiConfigEnvChangeListener(val id: ApiConfig.ID) {
|
||||
|
||||
/**
|
||||
* Called when the environment configuration changes
|
||||
*
|
||||
* @param environmentConfig the updated [ApiEnvironmentConfig] for the associated API configuration
|
||||
*/
|
||||
abstract fun onChange(environmentConfig: ApiEnvironmentConfig)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import retrofit2.http.Query
|
|||
interface TangemTechMarketsApi {
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@GET("coins/list")
|
||||
@GET("v1/coins/list")
|
||||
suspend fun getCoinsList(
|
||||
@Query("currency") currency: String,
|
||||
@Query("interval") interval: String,
|
||||
|
|
@ -20,24 +20,24 @@ interface TangemTechMarketsApi {
|
|||
@Query("timestamp") timestamp: Long?,
|
||||
): ApiResponse<TokenMarketListResponse>
|
||||
|
||||
@GET("coins/{coin_id}")
|
||||
@GET("v1/coins/{coin_id}")
|
||||
suspend fun getCoinMarketData(
|
||||
@Path("coin_id") coinId: String,
|
||||
@Query("currency") currency: String,
|
||||
@Query("language") language: String,
|
||||
): ApiResponse<TokenMarketInfoResponse>
|
||||
|
||||
@GET("coins/{coin_id}/history")
|
||||
@GET("v1/coins/{coin_id}/history")
|
||||
suspend fun getCoinChart(
|
||||
@Path("coin_id") coinId: String,
|
||||
@Query("currency") currency: String,
|
||||
@Query("interval") interval: String,
|
||||
): ApiResponse<TokenMarketChartResponse>
|
||||
|
||||
@GET("coins/{coin_id}/exchanges")
|
||||
@GET("v1/coins/{coin_id}/exchanges")
|
||||
suspend fun getCoinExchanges(@Path("coin_id") coinId: String): ApiResponse<TokenMarketExchangesResponse>
|
||||
|
||||
@GET("coins/history_preview")
|
||||
@GET("v1/coins/history_preview")
|
||||
suspend fun getCoinsListCharts(
|
||||
@Query("coin_ids") coinIds: String,
|
||||
@Query("currency") currency: String,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import java.util.concurrent.TimeUnit
|
|||
@Suppress("TooManyFunctions")
|
||||
interface TangemTechApi {
|
||||
|
||||
@GET("coins")
|
||||
@GET("v1/coins")
|
||||
suspend fun getCoins(
|
||||
@Header("Cache-Control") cacheControl: String = "max-age=600",
|
||||
@Query("contractAddress") contractAddress: String? = null,
|
||||
|
|
@ -30,150 +30,150 @@ interface TangemTechApi {
|
|||
@Query("limit") limit: Int? = null,
|
||||
): ApiResponse<CoinsResponse>
|
||||
|
||||
@GET("rates")
|
||||
@GET("v1/rates")
|
||||
suspend fun getRates(@Query("currencyId") currencyId: String, @Query("coinIds") coinIds: String): RatesResponse
|
||||
|
||||
@GET("currencies")
|
||||
@GET("v1/currencies")
|
||||
suspend fun getCurrencyList(
|
||||
@Header("Cache-Control") cacheControl: String = "max-age=600",
|
||||
): ApiResponse<CurrenciesResponse>
|
||||
|
||||
@GET("geo")
|
||||
@GET("v1/geo")
|
||||
suspend fun getUserCountryCode(): GeoResponse
|
||||
|
||||
@GET("user-tokens/{user-id}")
|
||||
@GET("v1/user-tokens/{user-id}")
|
||||
suspend fun getUserTokens(@Path(value = "user-id") userId: String): ApiResponse<UserTokensResponse>
|
||||
|
||||
@PUT("user-tokens/{user-id}")
|
||||
@PUT("v1/user-tokens/{user-id}")
|
||||
suspend fun saveUserTokens(
|
||||
@Path(value = "user-id") userId: String,
|
||||
@Body userTokens: UserTokensResponse,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@POST("user-tokens")
|
||||
@POST("v1/user-tokens")
|
||||
suspend fun markUserWallerWasCreated(@Body body: MarkUserWalletWasCreatedBody): ApiResponse<Unit>
|
||||
|
||||
/** Returns referral status by [walletId] */
|
||||
@GET("referral/{walletId}")
|
||||
@GET("v1/referral/{walletId}")
|
||||
suspend fun getReferralStatus(@Path("walletId") walletId: String): ApiResponse<ReferralResponse>
|
||||
|
||||
/** Make user referral, requires [StartReferralBody] */
|
||||
@POST("referral")
|
||||
@POST("v1/referral")
|
||||
suspend fun startReferral(@Body startReferralBody: StartReferralBody): ApiResponse<ReferralResponse>
|
||||
|
||||
@GET("quotes")
|
||||
@GET("v1/quotes")
|
||||
suspend fun getQuotes(
|
||||
@Query("currencyId") currencyId: String,
|
||||
@Query("coinIds") coinIds: String,
|
||||
@Query("fields") fields: String,
|
||||
): ApiResponse<QuotesResponse>
|
||||
|
||||
@GET("promotion")
|
||||
@GET("v1/promotion")
|
||||
suspend fun getPromotionInfo(
|
||||
@Query("programName") name: String,
|
||||
@Header("Cache-Control") cacheControl: String = "max-age=600",
|
||||
): ApiResponse<PromotionInfoResponse>
|
||||
|
||||
@GET("settings/{wallet_id}")
|
||||
@GET("v1/settings/{wallet_id}")
|
||||
suspend fun getUserTokensSettings(@Path("wallet_id") walletId: String): ApiResponse<UserTokensSettingsResponse>
|
||||
|
||||
@PUT("settings/{wallet_id}")
|
||||
@PUT("v1/settings/{wallet_id}")
|
||||
suspend fun saveUserTokensSettings(
|
||||
@Path("wallet_id") walletId: String,
|
||||
@Body userTokensSettings: UserTokensSettingsResponse,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@POST("user-network-account")
|
||||
@POST("v1/user-network-account")
|
||||
suspend fun createUserNetworkAccount(
|
||||
@Body body: CreateUserNetworkAccountBody,
|
||||
): ApiResponse<CreateUserNetworkAccountResponse>
|
||||
|
||||
@POST("account")
|
||||
@POST("v1/account")
|
||||
suspend fun createUserTokensAccount(
|
||||
@Body body: CreateUserTokensAccountBody,
|
||||
): ApiResponse<UserTokensAccountResponse>
|
||||
|
||||
@PUT("account/{account_id}")
|
||||
@PUT("v1/account/{account_id}")
|
||||
suspend fun updateUserTokensAccount(
|
||||
@Path("account_id") accountId: Int,
|
||||
@Body body: UpdateUserTokensAccountBody,
|
||||
): ApiResponse<UserTokensAccountResponse>
|
||||
|
||||
@PUT("account/{account_id}/archive")
|
||||
@PUT("v1/account/{account_id}/archive")
|
||||
suspend fun archiveUserTokensAccount(@Path("account_id") accountId: Int): ApiResponse<UserTokensAccountResponse>
|
||||
|
||||
@PUT("account/{account_id}/unarchive")
|
||||
@PUT("v1/account/{account_id}/unarchive")
|
||||
suspend fun restoreUserTokensAccount(@Path("account_id") accountId: Int): ApiResponse<UserTokensAccountResponse>
|
||||
|
||||
@GET("features")
|
||||
@GET("v1/features")
|
||||
suspend fun getFeatures(): ApiResponse<FeaturesResponse>
|
||||
|
||||
@ReadTimeout(duration = 5, unit = TimeUnit.SECONDS)
|
||||
@GET("networks/providers")
|
||||
@GET("v1/networks/providers")
|
||||
suspend fun getBlockchainProviders(): Map<String, List<ProviderModel>>
|
||||
|
||||
@GET("seedphrase-notification/{wallet_id}")
|
||||
@GET("v1/seedphrase-notification/{wallet_id}")
|
||||
suspend fun getSeedPhraseNotificationStatus(
|
||||
@Path("wallet_id") walletId: String,
|
||||
): ApiResponse<SeedPhraseNotificationDTO>
|
||||
|
||||
@PUT("seedphrase-notification/{wallet_id}")
|
||||
@PUT("v1/seedphrase-notification/{wallet_id}")
|
||||
suspend fun updateSeedPhraseNotificationStatus(
|
||||
@Path("wallet_id") walletId: String,
|
||||
@Body body: SeedPhraseNotificationDTO,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@GET("seedphrase-notification/{wallet_id}/confirmed")
|
||||
@GET("v1/seedphrase-notification/{wallet_id}/confirmed")
|
||||
suspend fun getSeedPhraseSecondNotificationStatus(
|
||||
@Path("wallet_id") walletId: String,
|
||||
): ApiResponse<SeedPhraseNotificationDTO>
|
||||
|
||||
@PUT("seedphrase-notification/{wallet_id}/confirmed")
|
||||
@PUT("v1/seedphrase-notification/{wallet_id}/confirmed")
|
||||
suspend fun updateSeedPhraseSecondNotificationStatus(
|
||||
@Path("wallet_id") walletId: String,
|
||||
@Body body: SeedPhraseNotificationDTO,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@GET("hot_crypto")
|
||||
@GET("v1/hot_crypto")
|
||||
suspend fun getHotCrypto(@Query("currency") currencyId: String): ApiResponse<HotCryptoResponse>
|
||||
|
||||
@GET("stories/{story_id}")
|
||||
@GET("v1/stories/{story_id}")
|
||||
suspend fun getStoryById(@Path("story_id") storyId: String): ApiResponse<StoryContentResponse>
|
||||
|
||||
// region push notifications
|
||||
@GET("notification/push_notifications_eligible_networks")
|
||||
@GET("v1/notification/push_notifications_eligible_networks")
|
||||
suspend fun getEligibleNetworksForPushNotifications(): ApiResponse<List<CryptoNetworkResponse>>
|
||||
|
||||
@POST("user-wallets/applications/")
|
||||
@POST("v1/user-wallets/applications/")
|
||||
suspend fun createApplicationId(
|
||||
@Body
|
||||
body: NotificationApplicationCreateBody,
|
||||
): ApiResponse<NotificationApplicationIdResponse>
|
||||
|
||||
@PATCH("user-wallets/applications/{application_id}")
|
||||
@PATCH("v1/user-wallets/applications/{application_id}")
|
||||
suspend fun updatePushTokenForApplicationId(
|
||||
@Path("application_id") applicationId: String,
|
||||
@Body body: NotificationApplicationCreateBody,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@PATCH("user-wallets/wallets/{wallet_id}/notify")
|
||||
@PATCH("v1/user-wallets/wallets/{wallet_id}/notify")
|
||||
suspend fun setNotificationsEnabled(@Path("wallet_id") walletId: String, @Body body: WalletBody): ApiResponse<Unit>
|
||||
// endregion
|
||||
|
||||
// region wallets
|
||||
@PATCH("user-wallets/wallets/{wallet_id}")
|
||||
@PATCH("v1/user-wallets/wallets/{wallet_id}")
|
||||
suspend fun updateWallet(@Path("wallet_id") walletId: String, @Body body: WalletBody): ApiResponse<Unit>
|
||||
|
||||
@POST("user-wallets/wallets/create-and-connect-by-appuid/{application_id}")
|
||||
@POST("v1/user-wallets/wallets/create-and-connect-by-appuid/{application_id}")
|
||||
suspend fun associateApplicationIdWithWallets(
|
||||
@Path("application_id") applicationId: String,
|
||||
@Body body: List<WalletIdBody>,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@GET("user-wallets/wallets/{wallet_id}")
|
||||
@GET("v1/user-wallets/wallets/{wallet_id}")
|
||||
suspend fun getWalletById(@Path("wallet_id") walletId: String): ApiResponse<WalletResponse>
|
||||
|
||||
@GET("user-wallets/wallets/by-app/{app_id}")
|
||||
@GET("v1/user-wallets/wallets/by-app/{app_id}")
|
||||
suspend fun getWallets(@Path("app_id") appId: String): ApiResponse<List<WalletResponse>>
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -60,8 +60,4 @@ internal object ApiConfigsModule {
|
|||
fun provideBlockAidConfig(environmentConfigStorage: EnvironmentConfigStorage): ApiConfig {
|
||||
return BlockAid(environmentConfigStorage)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@IntoSet
|
||||
fun provideAttestationConfig(): ApiConfig = Attestation()
|
||||
}
|
||||
|
|
@ -6,18 +6,20 @@ 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
|
||||
import com.tangem.datasource.api.common.config.ApiConfig.Companion.MOCKED_BUILD_TYPE
|
||||
import com.tangem.datasource.api.common.config.ApiConfigs
|
||||
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.api.pay.TangemPayApi
|
||||
import com.tangem.datasource.local.logs.AppLogsStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.utils.*
|
||||
|
|
@ -45,7 +47,7 @@ internal object NetworkModule {
|
|||
private const val STAKE_KIT_API_TIMEOUT_SECONDS = 60L
|
||||
|
||||
private val excludedApiForLogging: Set<ApiConfig.ID> = setOf(
|
||||
// ApiConfig.ID.StakeKit,
|
||||
ApiConfig.ID.StakeKit,
|
||||
)
|
||||
|
||||
@Provides
|
||||
|
|
@ -55,10 +57,10 @@ internal object NetworkModule {
|
|||
appPreferencesStore: AppPreferencesStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): ApiConfigsManager {
|
||||
return if (BuildConfig.TESTER_MENU_ENABLED) {
|
||||
DevApiConfigsManager(apiConfigs, appPreferencesStore, dispatchers)
|
||||
} else {
|
||||
ProdApiConfigsManager(apiConfigs)
|
||||
return when {
|
||||
BuildConfig.BUILD_TYPE == MOCKED_BUILD_TYPE -> MockApiConfigsManager(apiConfigs, dispatchers)
|
||||
BuildConfig.TESTER_MENU_ENABLED -> DevApiConfigsManager(apiConfigs, appPreferencesStore, dispatchers)
|
||||
else -> ProdApiConfigsManager(apiConfigs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ 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
|
||||
|
|
@ -93,7 +94,7 @@ internal fun OkHttpClient.Builder.applyApiConfig(
|
|||
id: ApiConfig.ID,
|
||||
apiConfigsManager: ApiConfigsManager,
|
||||
): OkHttpClient.Builder {
|
||||
return if (BuildConfig.TESTER_MENU_ENABLED) {
|
||||
return if (BuildConfig.TESTER_MENU_ENABLED || BuildConfig.BUILD_TYPE == MOCKED_BUILD_TYPE) {
|
||||
addInterceptor(
|
||||
interceptor = SwitchEnvironmentInterceptor(
|
||||
id = id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue