diff --git a/app/src/main/java/com/tangem/tap/network/auth/ExpressAuthProviderImpl.kt b/app/src/main/java/com/tangem/tap/network/auth/ExpressAuthProviderImpl.kt index 53ed14fdbd..2a7f65eee3 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/ExpressAuthProviderImpl.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/ExpressAuthProviderImpl.kt @@ -8,7 +8,7 @@ import java.util.UUID class ExpressAuthProviderImpl( private val userWalletsStore: UserWalletsStore, - private val configManager: ConfigManager + private val configManager: ConfigManager, ) : ExpressAuthProvider, ExpressSessionIdGenerator { private var uuid = UUID.randomUUID() diff --git a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt index 7efa406601..3ae06e158e 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt @@ -31,7 +31,7 @@ class AuthModule { ): ExpressAuthProvider { return ExpressAuthProviderImpl( userWalletsStore = userWalletsStore, - configManager = configManager + configManager = configManager, ) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/express/ExpressApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/express/TangemExpressApi.kt similarity index 92% rename from core/datasource/src/main/java/com/tangem/datasource/api/express/ExpressApi.kt rename to core/datasource/src/main/java/com/tangem/datasource/api/express/TangemExpressApi.kt index 790694e688..627e70bdd0 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/express/ExpressApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/express/TangemExpressApi.kt @@ -6,7 +6,6 @@ import com.tangem.datasource.api.express.models.request.PairsRequestBody import com.tangem.datasource.api.express.models.response.* import retrofit2.http.Body import retrofit2.http.GET -import retrofit2.http.Header import retrofit2.http.POST import retrofit2.http.Query import java.math.BigDecimal @@ -15,12 +14,10 @@ import java.math.BigDecimal * Interface of Tangem Express API (new swap mechanism) */ @Suppress("LongParameterList") -interface ExpressApi { - +interface TangemExpressApi { + @POST("assets") - suspend fun getAssets( - @Body body: AssetsRequestBody, - ): ApiResponse> + suspend fun getAssets(@Body body: AssetsRequestBody): ApiResponse> @POST("pairs") suspend fun getPairs(@Body body: PairsRequestBody): ApiResponse> diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/express/models/TangemExpressValues.kt b/core/datasource/src/main/java/com/tangem/datasource/api/express/models/TangemExpressValues.kt new file mode 100644 index 0000000000..984184791c --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/api/express/models/TangemExpressValues.kt @@ -0,0 +1,5 @@ +package com.tangem.datasource.api.express.models + +object TangemExpressValues { + const val EMPTY_CONTRACT_ADDRESS_VALUE = "0" +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/express/models/request/AssetsRequestBody.kt b/core/datasource/src/main/java/com/tangem/datasource/api/express/models/request/AssetsRequestBody.kt index f1d31bd24e..ffe4a0a5b0 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/express/models/request/AssetsRequestBody.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/express/models/request/AssetsRequestBody.kt @@ -3,5 +3,6 @@ package com.tangem.datasource.api.express.models.request import com.squareup.moshi.Json data class AssetsRequestBody( - @Json(name = "filter") val filter: List?, + @Json(name = "tokensList") val tokensList: List?, + @Json(name = "onlyActive") val onlyActive: Boolean, ) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt index 20bd72d674..3fced2471f 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt @@ -106,7 +106,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager { swapReferrerAccount = configValues.swapReferrerAccount, walletConnectProjectId = configValues.walletConnectProjectId, tangemComAuthorization = configValues.tangemComAuthorization, - tangemExpressApiKey = configValues.tangemExpressApiKey + tangemExpressApiKey = configValues.tangemExpressApiKey, ) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt index a4d08b27a3..00596c5621 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt @@ -19,5 +19,5 @@ data class Config( val swapReferrerAccount: SwapReferrerAccount? = null, val walletConnectProjectId: String = "", val tangemComAuthorization: String? = null, - val tangemExpressApiKey: String = "" + val tangemExpressApiKey: String = "", ) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/MarketCoinsStoreModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/AssetsStoreModule.kt similarity index 51% rename from core/datasource/src/main/java/com/tangem/datasource/di/MarketCoinsStoreModule.kt rename to core/datasource/src/main/java/com/tangem/datasource/di/AssetsStoreModule.kt index bd2098a670..43b8e93f5c 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/MarketCoinsStoreModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/AssetsStoreModule.kt @@ -1,8 +1,8 @@ package com.tangem.datasource.di import com.tangem.datasource.local.datastore.RuntimeDataStore -import com.tangem.datasource.local.token.DefaultUserMarketCoinsStore -import com.tangem.datasource.local.token.UserMarketCoinsStore +import com.tangem.datasource.local.token.DefaultAssetsStore +import com.tangem.datasource.local.token.AssetsStore import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -11,11 +11,11 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -internal object MarketCoinsStoreModule { +internal object AssetsStoreModule { @Provides @Singleton - fun provideUserMarketCoinsStore(): UserMarketCoinsStore { - return DefaultUserMarketCoinsStore(dataStore = RuntimeDataStore()) + fun provideAssetsStore(): AssetsStore { + return DefaultAssetsStore(dataStore = RuntimeDataStore()) } } \ 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 93f0528a18..7d1f732da5 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 @@ -3,10 +3,9 @@ package com.tangem.datasource.di import android.content.Context import com.squareup.moshi.Moshi import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory -import com.tangem.datasource.api.express.ExpressApi +import com.tangem.datasource.api.express.TangemExpressApi import com.tangem.datasource.api.promotion.PromotionApi import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.utils.RequestHeader import com.tangem.datasource.utils.RequestHeader.* import com.tangem.datasource.utils.addHeaders import com.tangem.datasource.utils.addLoggers @@ -33,8 +32,7 @@ class NetworkModule { @NetworkMoshi moshi: Moshi, @ApplicationContext context: Context, expressAuthProvider: ExpressAuthProvider, - ): ExpressApi { - + ): TangemExpressApi { return Retrofit.Builder() .addConverterFactory(MoshiConverterFactory.create(moshi)) .addCallAdapterFactory(ApiResponseCallAdapterFactory.create()) @@ -46,7 +44,7 @@ class NetworkModule { .build(), ) .build() - .create(ExpressApi::class.java) + .create(TangemExpressApi::class.java) } @Provides diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/AssetsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/AssetsStore.kt new file mode 100644 index 0000000000..11d6101843 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/AssetsStore.kt @@ -0,0 +1,11 @@ +package com.tangem.datasource.local.token + +import com.tangem.datasource.api.express.models.response.Asset +import com.tangem.domain.wallets.models.UserWalletId + +interface AssetsStore { + + suspend fun getSyncOrNull(userWalletId: UserWalletId): List? + + suspend fun store(userWalletId: UserWalletId, item: List) +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultUserMarketCoinsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultAssetsStore.kt similarity index 64% rename from core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultUserMarketCoinsStore.kt rename to core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultAssetsStore.kt index c08a627df9..9177ec70b7 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultUserMarketCoinsStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultAssetsStore.kt @@ -1,18 +1,18 @@ package com.tangem.datasource.local.token -import com.tangem.datasource.api.tangemTech.models.CoinsResponse +import com.tangem.datasource.api.express.models.response.Asset import com.tangem.datasource.local.datastore.core.StringKeyDataStore import com.tangem.domain.wallets.models.UserWalletId -internal class DefaultUserMarketCoinsStore( - private val dataStore: StringKeyDataStore, -) : UserMarketCoinsStore { +internal class DefaultAssetsStore( + private val dataStore: StringKeyDataStore>, +) : AssetsStore { - override suspend fun getSyncOrNull(userWalletId: UserWalletId): CoinsResponse? { + override suspend fun getSyncOrNull(userWalletId: UserWalletId): List? { return dataStore.getSyncOrNull(userWalletId.stringValue) } - override suspend fun store(userWalletId: UserWalletId, item: CoinsResponse) { + override suspend fun store(userWalletId: UserWalletId, item: List) { dataStore.store(userWalletId.stringValue, item) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/UserMarketCoinsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/UserMarketCoinsStore.kt deleted file mode 100644 index 10895699ac..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/token/UserMarketCoinsStore.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.tangem.datasource.local.token - -import com.tangem.datasource.api.tangemTech.models.CoinsResponse -import com.tangem.domain.wallets.models.UserWalletId - -interface UserMarketCoinsStore { - - suspend fun getSyncOrNull(userWalletId: UserWalletId): CoinsResponse? - - suspend fun store(userWalletId: UserWalletId, item: CoinsResponse) -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt index b41f2c18f2..6a5fde6a53 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt @@ -20,9 +20,9 @@ sealed class RequestHeader(vararg pairs: Pair String>) { "card_public_key" to { authProvider.getCardPublicKey() }, ) - class Express(expressAuthProvider: ExpressAuthProvider): RequestHeader( + class Express(expressAuthProvider: ExpressAuthProvider) : RequestHeader( "api-key" to { expressAuthProvider.getApiKey() }, "user-id" to { expressAuthProvider.getUserId() }, - "session-id" to { expressAuthProvider.getSessionId() } + "session-id" to { expressAuthProvider.getSessionId() }, ) } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt index f8e33206dd..b683931af9 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt @@ -5,11 +5,12 @@ import com.tangem.data.tokens.repository.DefaultCurrenciesRepository import com.tangem.data.tokens.repository.DefaultMarketCryptoCurrencyRepository import com.tangem.data.tokens.repository.DefaultNetworksRepository import com.tangem.data.tokens.repository.DefaultQuotesRepository +import com.tangem.datasource.api.express.TangemExpressApi import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore import com.tangem.datasource.local.network.NetworksStatusesStore import com.tangem.datasource.local.quote.QuotesStore -import com.tangem.datasource.local.token.UserMarketCoinsStore +import com.tangem.datasource.local.token.AssetsStore import com.tangem.datasource.local.token.UserTokensStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.tokens.repository.CurrenciesRepository @@ -32,17 +33,19 @@ internal object TokensDataModule { @Singleton fun provideCurrenciesRepository( tangemTechApi: TangemTechApi, + tangemExpressApi: TangemExpressApi, userTokensStore: UserTokensStore, userWalletsStore: UserWalletsStore, - userMarketCoinsStore: UserMarketCoinsStore, + assetsStore: AssetsStore, cacheRegistry: CacheRegistry, dispatchers: CoroutineDispatcherProvider, ): CurrenciesRepository { return DefaultCurrenciesRepository( tangemTechApi = tangemTechApi, + tangemExpressApi = tangemExpressApi, userTokensStore = userTokensStore, userWalletsStore = userWalletsStore, - userMarketCoinsStore = userMarketCoinsStore, + assetsStore = assetsStore, cacheRegistry = cacheRegistry, dispatchers = dispatchers, ) @@ -88,9 +91,7 @@ internal object TokensDataModule { @Provides @Singleton - fun provideDefaultMarketCoinsRepository( - userMarketCoinsStore: UserMarketCoinsStore, - ): MarketCryptoCurrencyRepository { - return DefaultMarketCryptoCurrencyRepository(userMarketCoinsStore) + fun provideDefaultMarketCoinsRepository(assetsStore: AssetsStore): MarketCryptoCurrencyRepository { + return DefaultMarketCryptoCurrencyRepository(assetsStore) } } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 3f623010d5..7caa36ac26 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -5,9 +5,14 @@ import com.tangem.data.common.api.safeApiCall import com.tangem.data.common.cache.CacheRegistry import com.tangem.data.tokens.utils.* import com.tangem.datasource.api.common.response.ApiResponseError +import com.tangem.datasource.api.common.response.getOrThrow +import com.tangem.datasource.api.express.TangemExpressApi +import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE +import com.tangem.datasource.api.express.models.request.AssetsRequestBody +import com.tangem.datasource.api.express.models.request.LeastTokenInfo import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.models.UserTokensResponse -import com.tangem.datasource.local.token.UserMarketCoinsStore +import com.tangem.datasource.local.token.AssetsStore import com.tangem.datasource.local.token.UserTokensStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.common.extensions.toCoinId @@ -27,12 +32,13 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber -@Suppress("LargeClass") +@Suppress("LargeClass", "LongParameterList") internal class DefaultCurrenciesRepository( private val tangemTechApi: TangemTechApi, + private val tangemExpressApi: TangemExpressApi, private val userTokensStore: UserTokensStore, private val userWalletsStore: UserWalletsStore, - private val userMarketCoinsStore: UserMarketCoinsStore, + private val assetsStore: AssetsStore, private val cacheRegistry: CacheRegistry, private val dispatchers: CoroutineDispatcherProvider, ) : CurrenciesRepository { @@ -341,14 +347,25 @@ internal class DefaultCurrenciesRepository( userTokens: UserTokensResponse, ) { try { - val networkIds = userTokens.tokens + val tokensList = userTokens.tokens .distinctBy { it.networkId } - .joinToString(separator = ",") { it.networkId } - val response = tangemTechApi.getCoins(networkIds = networkIds, exchangeable = true) + .map { + LeastTokenInfo( + contractAddress = it.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE, + network = it.networkId, + ) + } - userMarketCoinsStore.store(userWalletId, response) + val response = tangemExpressApi.getAssets( + AssetsRequestBody( + tokensList = tokensList, + onlyActive = true, + ), + ) + + assetsStore.store(userWalletId, response.getOrThrow()) } catch (e: Throwable) { - Timber.e(e, "Unable to fetch user market coins for: ${userWalletId.stringValue}") + Timber.e(e, "Unable to fetch assets for: ${userWalletId.stringValue}") } } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt index 441f3f97d2..b2bc8bf0a2 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt @@ -1,22 +1,28 @@ package com.tangem.data.tokens.repository import com.tangem.blockchain.common.Blockchain -import com.tangem.datasource.local.token.UserMarketCoinsStore +import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE +import com.tangem.datasource.local.token.AssetsStore import com.tangem.domain.common.extensions.toNetworkId import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.repository.MarketCryptoCurrencyRepository import com.tangem.domain.wallets.models.UserWalletId class DefaultMarketCryptoCurrencyRepository( - private val userMarketCoinsStore: UserMarketCoinsStore, + private val assetsStore: AssetsStore, ) : MarketCryptoCurrencyRepository { - override suspend fun isExchangeable(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Boolean { + override suspend fun isExchangeable(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean { + val cryptoCurrencyId = cryptoCurrency.id val blockchain = Blockchain.fromId(cryptoCurrencyId.rawNetworkId) val apiNetworkId = blockchain.toNetworkId() - return userMarketCoinsStore.getSyncOrNull(userWalletId)?.coins - ?.firstOrNull { it.id == cryptoCurrencyId.rawCurrencyId } - ?.networks - ?.firstOrNull { it.networkId == apiNetworkId }?.exchangeable ?: false + val contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE + + return assetsStore.getSyncOrNull(userWalletId)?.find { + it.network == apiNetworkId && + it.token == cryptoCurrencyId.rawCurrencyId && + it.contractAddress == contractAddress && + it.isActive + }?.exchangeAvailable ?: false } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index 718b412716..a6c9f21f01 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -84,7 +84,7 @@ class GetCryptoCurrencyActionsUseCase( activeList.add(TokenActionsState.ActionState.Receive(true)) // swap - if (marketCryptoCurrencyRepository.isExchangeable(userWalletId, cryptoCurrency.id)) { + if (marketCryptoCurrencyRepository.isExchangeable(userWalletId, cryptoCurrency)) { activeList.add(TokenActionsState.ActionState.Swap(true)) } else { disabledList.add(TokenActionsState.ActionState.Swap(false)) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/MarketCryptoCurrencyRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/MarketCryptoCurrencyRepository.kt index 0186226918..0e0d223a53 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/MarketCryptoCurrencyRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/MarketCryptoCurrencyRepository.kt @@ -8,5 +8,5 @@ import com.tangem.domain.wallets.models.UserWalletId */ interface MarketCryptoCurrencyRepository { - suspend fun isExchangeable(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Boolean + suspend fun isExchangeable(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean } \ No newline at end of file