Updated on 2026-08-14
This commit is contained in:
parent
1675b44cd3
commit
da0318964e
25 changed files with 186 additions and 212 deletions
|
|
@ -2,8 +2,8 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.datasource.api.tangemTech.models.CoinsResponse
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CurrencyFromJson(
|
||||
|
|
@ -26,7 +26,6 @@ data class CurrenciesFromJson(
|
|||
val coins: List<CurrencyFromJson>
|
||||
)
|
||||
|
||||
|
||||
fun List<ContractFromJson>.toContracts(): List<Contract> {
|
||||
return mapNotNull { Contract.fromJsonObject(it) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,17 @@ import com.squareup.moshi.JsonAdapter
|
|||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.getListOfCoins
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.CoinsResponse
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.tap.common.AssetReader
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class LoadAvailableCoinsService(
|
||||
private val networkService: TangemTechService,
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val assetReader: AssetReader,
|
||||
) {
|
||||
private val moshi: Moshi by lazy { MoshiConverter.defaultMoshi() }
|
||||
|
|
@ -55,16 +57,23 @@ class LoadAvailableCoinsService(
|
|||
private suspend fun loadCoins(
|
||||
supportedBlockchains: List<Blockchain>,
|
||||
offset: Int,
|
||||
searchInput: String? = null
|
||||
searchInput: String? = null,
|
||||
): Result<CoinsResponse> {
|
||||
val networkIds = supportedBlockchains.toSet().map { it.toNetworkId() }
|
||||
return networkService.getListOfCoins(
|
||||
networkIds = networkIds,
|
||||
active = true,
|
||||
offset = offset,
|
||||
limit = LOAD_PER_PAGE,
|
||||
searchText = searchInput,
|
||||
)
|
||||
return withContext(dispatchers.io) {
|
||||
runCatching {
|
||||
tangemTechApi.getCoins(
|
||||
networkIds = supportedBlockchains.toSet().map(Blockchain::toNetworkId).joinToString(","),
|
||||
active = true,
|
||||
searchText = searchInput,
|
||||
offset = offset,
|
||||
limit = LOAD_PER_PAGE,
|
||||
)
|
||||
}
|
||||
.onSuccess { return@withContext Result.Success(it) }
|
||||
.onFailure { return@withContext Result.Failure(it) }
|
||||
|
||||
throw IllegalStateException("Unreachable code because runCatching must return result")
|
||||
}
|
||||
}
|
||||
|
||||
fun getTestnetCoins(): List<Currency> {
|
||||
|
|
@ -88,7 +97,6 @@ class LoadAvailableCoinsService(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
data class LoadedCoins(
|
||||
val currencies: List<Currency>,
|
||||
val moreAvailable: Boolean,
|
||||
|
|
|
|||
|
|
@ -4,21 +4,21 @@ import com.squareup.moshi.JsonAdapter
|
|||
import com.squareup.moshi.Types
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.getTokens
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.tap.common.FileReader
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.domain.tokens.models.TokenDao
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@Deprecated("Use this only for migration")
|
||||
class OldUserTokensRepository(
|
||||
private val fileReader: FileReader,
|
||||
private val tangemNetworkService: TangemTechService,
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
private val moshi = MoshiConverter.defaultMoshi()
|
||||
private val blockchainsAdapter: JsonAdapter<List<Blockchain>> = moshi.adapter(
|
||||
|
|
@ -104,20 +104,27 @@ class OldUserTokensRepository(
|
|||
return blockchainNetworks
|
||||
}
|
||||
|
||||
private suspend fun getTokensIds(tokens: List<TokenDao>): Map<String, String> = coroutineScope {
|
||||
private suspend fun getTokensIds(tokens: List<TokenDao>): Map<String, String> = withContext(dispatchers.io) {
|
||||
tokens.map {
|
||||
async {
|
||||
tangemNetworkService.getTokens(
|
||||
tangemTechApi.getCoins(
|
||||
contractAddress = it.contractAddress,
|
||||
networkId = it.blockchainDao.toBlockchain().toNetworkId(),
|
||||
networkIds = it.blockchainDao.toBlockchain().toNetworkId(),
|
||||
active = true,
|
||||
)
|
||||
}
|
||||
}.map { it.await() }
|
||||
.map { (it as? Result.Success)?.data?.coins?.firstOrNull()?.id }
|
||||
}
|
||||
.map {
|
||||
runCatching { it.await() }
|
||||
.onSuccess { return@map it.coins.firstOrNull()?.id }
|
||||
.onFailure { return@map null }
|
||||
|
||||
throw IllegalStateException("Unreachable code because runCatching must return result")
|
||||
}
|
||||
.mapIndexedNotNull { index, id ->
|
||||
if (id == null) null else tokens[index].contractAddress to id
|
||||
}.toMap()
|
||||
}
|
||||
.toMap()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import com.tangem.tap.features.wallet.models.Currency
|
|||
import com.tangem.tap.features.wallet.models.toBlockchainNetworks
|
||||
import com.tangem.tap.features.wallet.models.toCurrencies
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -120,9 +119,12 @@ class UserTokensRepository(
|
|||
// TODO("After adding DI") get dependencies by DI
|
||||
fun init(context: Context, tangemTechService: TangemTechService): UserTokensRepository {
|
||||
val fileReader = AndroidFileReader(context)
|
||||
val dispatchers = AppCoroutineDispatcherProvider()
|
||||
|
||||
val oldUserTokensRepository = OldUserTokensRepository(
|
||||
fileReader = fileReader,
|
||||
tangemNetworkService = store.state.domainNetworks.tangemTechService,
|
||||
tangemTechApi = tangemTechService.api,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
val storageService = UserTokensStorageService(
|
||||
oldUserTokensRepository = oldUserTokensRepository,
|
||||
|
|
@ -132,7 +134,7 @@ class UserTokensRepository(
|
|||
return UserTokensRepository(
|
||||
storageService = storageService,
|
||||
tangemTechApi = tangemTechService.api,
|
||||
dispatchers = AppCoroutineDispatcherProvider(),
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
package com.tangem.tap.domain.tokens.converters
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.models.TokenBody
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
/** Converter from domain model [Currency] to data model [TokenBody] */
|
||||
object CurrencyConverter : Converter<Currency, TokenBody> {
|
||||
/** Converter from domain model [Currency] to data model [UserTokensResponse.Token] */
|
||||
object CurrencyConverter : Converter<Currency, UserTokensResponse.Token> {
|
||||
|
||||
override fun convert(value: Currency) = TokenBody(
|
||||
override fun convert(value: Currency) = UserTokensResponse.Token(
|
||||
id = value.coinId,
|
||||
networkId = value.blockchain.toNetworkId(),
|
||||
derivationPath = value.derivationPath,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import com.tangem.tap.store
|
|||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.tap.userWalletsListManager
|
||||
import com.tangem.tap.walletCurrenciesManager
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Middleware
|
||||
|
|
@ -83,8 +84,9 @@ class TokensMiddleware {
|
|||
.filter { !it.isTestnet() }
|
||||
|
||||
val loadCoinsService = LoadAvailableCoinsService(
|
||||
store.state.domainNetworks.tangemTechService,
|
||||
assetReader,
|
||||
tangemTechApi = store.state.domainNetworks.tangemTechService.api,
|
||||
dispatchers = AppCoroutineDispatcherProvider(),
|
||||
assetReader = assetReader,
|
||||
)
|
||||
|
||||
scope.launch {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.features.wallet.models
|
||||
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.datasource.api.tangemTech.models.TokenBody
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.common.extensions.toCoinId
|
||||
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
||||
|
|
@ -98,7 +98,7 @@ sealed interface Currency {
|
|||
)
|
||||
}
|
||||
|
||||
fun fromTokenResponse(tokenBody: TokenBody): Currency? {
|
||||
fun fromTokenResponse(tokenBody: UserTokensResponse.Token): Currency? {
|
||||
val blockchain = com.tangem.blockchain.common.Blockchain.fromNetworkId(tokenBody.networkId)
|
||||
?: return null
|
||||
return when {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.wallet.redux.middlewares
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.models.Currency
|
||||
import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
|
|
@ -38,7 +38,7 @@ class AppCurrencyMiddleware(
|
|||
store.dispatchDialogShow(
|
||||
WalletDialog.CurrencySelectionDialog(
|
||||
currenciesList = storedFiatCurrencies.mapToUiModel(),
|
||||
currentAppCurrency = appCurrencyProvider.invoke()
|
||||
currentAppCurrency = appCurrencyProvider.invoke(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ class AppCurrencyMiddleware(
|
|||
store.dispatchDialogShow(
|
||||
WalletDialog.CurrencySelectionDialog(
|
||||
currenciesList = currenciesList.mapToUiModel(),
|
||||
currentAppCurrency = appCurrencyProvider.invoke()
|
||||
currentAppCurrency = appCurrencyProvider.invoke(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ class AppCurrencyMiddleware(
|
|||
}
|
||||
}
|
||||
|
||||
private fun List<Currency>.mapToUiModel(): List<FiatCurrency> {
|
||||
private fun List<CurrenciesResponse.Currency>.mapToUiModel(): List<FiatCurrency> {
|
||||
return this.map {
|
||||
FiatCurrency(
|
||||
code = it.code,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.persistence
|
|||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.datasource.api.tangemTech.models.Currency
|
||||
import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
|
||||
/**
|
||||
|
|
@ -32,14 +32,14 @@ class FiatCurrenciesPrefStorage(
|
|||
preferences.edit { putString(APP_CURRENCY_KEY, json) }
|
||||
}
|
||||
|
||||
fun save(currencies: List<Currency>) {
|
||||
fun save(currencies: List<CurrenciesResponse.Currency>) {
|
||||
val json: String = converter.toJson(currencies)
|
||||
return preferences.edit().putString(FIAT_CURRENCIES_KEY, json).apply()
|
||||
}
|
||||
|
||||
fun restore(): List<Currency> {
|
||||
fun restore(): List<CurrenciesResponse.Currency> {
|
||||
val json = preferences.getString(FIAT_CURRENCIES_KEY, "")
|
||||
val type = converter.typedList(Currency::class.java)
|
||||
val type = converter.typedList(CurrenciesResponse.Currency::class.java)
|
||||
if (json.isNullOrBlank()) return emptyList()
|
||||
|
||||
return converter.fromJson(json, type) ?: emptyList()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue