Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-10 15:21:55 +05:00
parent 4570bc334c
commit 602e20a1d2
53 changed files with 489 additions and 368 deletions

View file

@ -7,22 +7,25 @@ plugins {
}
android {
namespace = "com.tangem.data.tokensync"
namespace = "com.tangem.data.assetsdiscovery"
}
dependencies {
api(projects.domain.tokensync)
api(projects.domain.assetsdiscovery)
implementation(projects.domain.tokens)
implementation(projects.domain.tokens.models)
implementation(projects.domain.models)
implementation(projects.domain.walletManager)
implementation(projects.domain.wallets)
implementation(projects.data.common)
implementation(projects.data.walletManager)
implementation(projects.libs.blockchainSdk)
implementation(projects.libs.tangemSdkApi)
implementation(projects.core.datasource)
implementation(projects.core.utils)
implementation(tangemDeps.blockchain)
implementation(tangemDeps.card.core)
implementation(deps.androidx.datastore)

View file

@ -0,0 +1,86 @@
package com.tangem.data.assetsdiscovery
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.address.AddressType
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.blockchainsdk.utils.toBlockchain
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.data.walletmanager.extensions.makePublicKey
import com.tangem.domain.assetsdiscovery.AssetsDiscoveryFacade
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.getSyncStrict
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.wallets.config.curvesConfig
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.withContext
import javax.inject.Inject
internal class DefaultAssetsDiscoveryFacade @Inject constructor(
private val blockchainSDKFactory: BlockchainSDKFactory,
private val userWalletsListRepository: UserWalletsListRepository,
private val dispatchers: CoroutineDispatcherProvider,
) : AssetsDiscoveryFacade {
override suspend fun getAssetsDiscoveryService(
userWalletId: UserWalletId,
network: Network,
): AssetsDiscoveryFacade.AssetsDiscoveryServiceInfo? = withContext(dispatchers.io) {
val userWallet = userWalletsListRepository.getSyncStrict(userWalletId)
if (userWallet !is UserWallet.Hot) return@withContext null
val assetsDiscoveryServiceFactory = blockchainSDKFactory.getAssetsDiscoveryServiceFactorySync()
?: return@withContext null
val blockchain = network.toBlockchain()
val address = makeAddress(userWallet, blockchain, network.derivationPath.value)
?: return@withContext null
AssetsDiscoveryFacade.AssetsDiscoveryServiceInfo(
address = address,
service = assetsDiscoveryServiceFactory.create(blockchain),
)
}
private fun makeAddress(hotWallet: UserWallet.Hot, blockchain: Blockchain, derivationPath: String?): String? {
val curve = hotWallet.curvesConfig.primaryCurve(blockchain)
val selectedWallet = hotWallet.wallets.orEmpty().firstOrNull { it.curve == curve }
?: return null
val path = derivationPath?.let { DerivationPath(rawPath = it) }
val publicKey = if (path != null) {
makePublicKey(
seedKey = selectedWallet.publicKey,
blockchain = blockchain,
derivationPath = path,
derivedWalletKeys = selectedWallet.derivedKeys,
isWallet2 = true,
) ?: return null
} else {
null
}
return try {
val addresses = if (publicKey != null) {
blockchain.makeAddresses(
walletPublicKey = publicKey.blockchainKey,
pairPublicKey = null,
curve = selectedWallet.curve,
)
} else {
blockchain.makeAddresses(
walletPublicKey = selectedWallet.publicKey,
pairPublicKey = null,
curve = selectedWallet.curve,
)
}
addresses.find { it.type == AddressType.Default }?.value
} catch (e: Throwable) {
TangemLogger.w("Failed to derive address for $blockchain", e)
null
}
}
}

View file

@ -0,0 +1,61 @@
package com.tangem.data.assetsdiscovery.di
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.data.assetsdiscovery.DefaultAssetsDiscoveryFacade
import com.tangem.data.assetsdiscovery.repository.DefaultAssetsDiscoveryRepository
import com.tangem.data.assetsdiscovery.store.AssetsDiscoveryStoreFactory
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.data.common.network.NetworkFactory
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.assetsdiscovery.AssetsDiscoveryFacade
import com.tangem.domain.assetsdiscovery.repository.AssetsDiscoveryRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object AssetsDiscoveryDataModule {
@Provides
@Singleton
fun provideAssetsDiscoveryFacade(
blockchainSDKFactory: BlockchainSDKFactory,
userWalletsListRepository: UserWalletsListRepository,
dispatchers: CoroutineDispatcherProvider,
): AssetsDiscoveryFacade = DefaultAssetsDiscoveryFacade(
blockchainSDKFactory = blockchainSDKFactory,
userWalletsListRepository = userWalletsListRepository,
dispatchers = dispatchers,
)
@Provides
@Singleton
fun provideAssetsDiscoveryRepository(
assetsDiscoveryFacade: AssetsDiscoveryFacade,
tangemTechApi: TangemTechApi,
userWalletsListRepository: UserWalletsListRepository,
networkFactory: NetworkFactory,
appPreferencesStore: AppPreferencesStore,
assetsDiscoveryStoreFactory: AssetsDiscoveryStoreFactory,
responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory,
dispatchers: CoroutineDispatcherProvider,
excludedBlockchains: ExcludedBlockchains,
): AssetsDiscoveryRepository = DefaultAssetsDiscoveryRepository(
assetsDiscoveryFacade = assetsDiscoveryFacade,
tangemTechApi = tangemTechApi,
userWalletsListRepository = userWalletsListRepository,
networkFactory = networkFactory,
appPreferencesStore = appPreferencesStore,
assetsDiscoveryStoreFactory = assetsDiscoveryStoreFactory,
responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory,
dispatchers = dispatchers,
excludedBlockchains = excludedBlockchains,
)
}

View file

@ -1,12 +1,12 @@
package com.tangem.data.tokensync.repository
package com.tangem.data.assetsdiscovery.repository
import com.tangem.blockchain.assetsdiscovery.models.DiscoveredAsset
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.tokenbalance.models.TokenBalance
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.data.assetsdiscovery.store.AssetsDiscoveryStore
import com.tangem.data.assetsdiscovery.store.AssetsDiscoveryStoreFactory
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.data.common.network.NetworkFactory
import com.tangem.data.tokensync.store.TokenSyncStore
import com.tangem.data.tokensync.store.TokenSyncStoreFactory
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.CoinsResponse
@ -14,15 +14,15 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectMapSync
import com.tangem.domain.assetsdiscovery.AssetsDiscoveryFacade
import com.tangem.domain.assetsdiscovery.model.AssetsDiscoveryProgress
import com.tangem.domain.assetsdiscovery.repository.AssetsDiscoveryRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.getSyncStrict
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.tokensync.model.TokenSyncProgress
import com.tangem.domain.tokensync.repository.TokenSyncRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.async
@ -30,42 +30,39 @@ import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.withContext
import java.math.BigDecimal
import java.util.concurrent.ConcurrentHashMap
@Suppress("LongParameterList")
internal class DefaultTokenSyncRepository(
private val walletManagersFacade: WalletManagersFacade,
internal class DefaultAssetsDiscoveryRepository(
private val assetsDiscoveryFacade: AssetsDiscoveryFacade,
private val tangemTechApi: TangemTechApi,
private val userWalletsListRepository: UserWalletsListRepository,
private val networkFactory: NetworkFactory,
private val appPreferencesStore: AppPreferencesStore,
private val tokenSyncStoreFactory: TokenSyncStoreFactory,
private val assetsDiscoveryStoreFactory: AssetsDiscoveryStoreFactory,
private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory,
private val dispatchers: CoroutineDispatcherProvider,
private val excludedBlockchains: ExcludedBlockchains,
) : TokenSyncRepository {
) : AssetsDiscoveryRepository {
private val semaphore = Semaphore(MAX_CONCURRENT_REQUESTS)
private val progressStates = ConcurrentHashMap<String, MutableStateFlow<TokenSyncProgress>>()
private val progressStates = ConcurrentHashMap<String, MutableStateFlow<AssetsDiscoveryProgress>>()
override fun observeSyncProgress(userWalletId: UserWalletId): Flow<TokenSyncProgress> {
override fun observeDiscoveryProgress(userWalletId: UserWalletId): Flow<AssetsDiscoveryProgress> {
return getProgressFlow(userWalletId)
}
override fun acknowledgeCompletion(userWalletId: UserWalletId) {
val key = userWalletId.stringValue
val stateFlow = progressStates[key] ?: return
stateFlow.value = TokenSyncProgress.Idle
stateFlow.value = AssetsDiscoveryProgress.Idle
progressStates.remove(key, stateFlow)
}
override suspend fun getDiscoveredCurrencies(userWalletId: UserWalletId): List<CryptoCurrency> {
val tokenSyncStore = tokenSyncStoreFactory.provide(userWalletId)
val storedTokens = tokenSyncStore.get()
val assetsDiscoveryStore = assetsDiscoveryStoreFactory.provide(userWalletId)
val storedTokens = assetsDiscoveryStore.get()
if (storedTokens.isEmpty()) return emptyList()
val userWallet = userWalletsListRepository.getSyncStrict(userWalletId)
@ -77,34 +74,34 @@ internal class DefaultTokenSyncRepository(
}
override suspend fun clearDiscoveredTokens(userWalletId: UserWalletId) {
val tokenSyncStore = tokenSyncStoreFactory.provide(userWalletId)
tokenSyncStore.clear()
val assetsDiscoveryStore = assetsDiscoveryStoreFactory.provide(userWalletId)
assetsDiscoveryStore.clear()
}
override suspend fun clearPendingFlag(userWalletId: UserWalletId) {
setPendingFlag(userWalletId, value = false)
}
override suspend fun getPendingSyncWalletIds(): List<UserWalletId> {
override suspend fun getPendingDiscoveryWalletIds(): List<UserWalletId> {
val pendingMap = appPreferencesStore
.getObjectMapSync<Boolean>(PreferencesKeys.PENDING_DISCOVERY_SYNC_KEY)
.getObjectMapSync<Boolean>(PreferencesKeys.PENDING_ASSETS_DISCOVERY_KEY)
return pendingMap
.filter { it.value }
.map { UserWalletId(it.key) }
}
override suspend fun runSync(userWalletId: UserWalletId) {
override suspend fun runDiscovery(userWalletId: UserWalletId) {
val networks = getSupportedNetworks(userWalletId)
if (networks.isEmpty()) return
setPendingFlag(userWalletId, value = true)
val tokenSyncStore = tokenSyncStoreFactory.provide(userWalletId)
tokenSyncStore.clear()
val assetsDiscoveryStore = assetsDiscoveryStoreFactory.provide(userWalletId)
assetsDiscoveryStore.clear()
val batches = networks.chunked(MAX_CONCURRENT_REQUESTS)
var completedNetworks = 0
getProgressFlow(userWalletId).value = TokenSyncProgress.InProgress(
getProgressFlow(userWalletId).value = AssetsDiscoveryProgress.InProgress(
completedNetworks = 0,
totalNetworks = networks.size,
)
@ -114,25 +111,23 @@ internal class DefaultTokenSyncRepository(
completedNetworks = handleBatchResults(
userWalletId = userWalletId,
results = batchResults,
tokenSyncStore = tokenSyncStore,
assetsDiscoveryStore = assetsDiscoveryStore,
completedNetworks = completedNetworks,
totalNetworks = networks.size,
)
}
}
override suspend fun completeSync(userWalletId: UserWalletId) {
override suspend fun completeDiscovery(userWalletId: UserWalletId) {
setPendingFlag(userWalletId, value = false)
getProgressFlow(userWalletId).value = TokenSyncProgress.Completed
getProgressFlow(userWalletId).value = AssetsDiscoveryProgress.Completed
}
private suspend fun processBatch(userWalletId: UserWalletId, batch: List<Network>): List<NetworkResult> {
return coroutineScope {
batch.map { network ->
async(dispatchers.io) {
semaphore.withPermit {
processNetwork(userWalletId, network)
}
processNetwork(userWalletId, network)
}
}.awaitAll()
}
@ -141,7 +136,7 @@ internal class DefaultTokenSyncRepository(
private suspend fun handleBatchResults(
userWalletId: UserWalletId,
results: List<NetworkResult>,
tokenSyncStore: TokenSyncStore,
assetsDiscoveryStore: AssetsDiscoveryStore,
completedNetworks: Int,
totalNetworks: Int,
): Int {
@ -150,8 +145,8 @@ internal class DefaultTokenSyncRepository(
for (result in results) {
completed++
handleNetworkResult(result, tokenSyncStore)
progressFlow.value = TokenSyncProgress.InProgress(
handleNetworkResult(result, assetsDiscoveryStore)
progressFlow.value = AssetsDiscoveryProgress.InProgress(
completedNetworks = completed,
totalNetworks = totalNetworks,
)
@ -160,35 +155,35 @@ internal class DefaultTokenSyncRepository(
return completed
}
private suspend fun handleNetworkResult(result: NetworkResult, tokenSyncStore: TokenSyncStore) {
private suspend fun handleNetworkResult(result: NetworkResult, assetsDiscoveryStore: AssetsDiscoveryStore) {
when (result) {
is NetworkResult.Success -> {
if (result.responseTokens.isNotEmpty()) {
try {
tokenSyncStore.append(result.responseTokens)
assetsDiscoveryStore.append(result.responseTokens)
} catch (e: Exception) {
TangemLogger.e("Failed to store discovered tokens for network: ${result.networkId}", e)
}
}
}
is NetworkResult.Error -> {
TangemLogger.e("Token sync failed for network: ${result.networkId}", result.cause)
TangemLogger.e("Assets discovery failed for network: ${result.networkId}", result.cause)
}
}
}
private suspend fun processNetwork(userWalletId: UserWalletId, network: Network): NetworkResult {
return try {
val tokenBalances = fetchAndFilterTokenBalances(userWalletId, network)
val discoveredAssets = discoverAndFilterAssets(userWalletId, network)
if (tokenBalances.isEmpty()) {
if (discoveredAssets.isEmpty()) {
return NetworkResult.Success(
networkId = network.rawId,
responseTokens = emptyList(),
)
}
val enrichedTokens = enrichTokensWithCatalog(tokenBalances, network)
val enrichedTokens = enrichTokensWithCatalog(discoveredAssets, network)
val responseTokens = enrichedTokens
.filter { it.contractAddress != null }
@ -203,36 +198,35 @@ internal class DefaultTokenSyncRepository(
}
}
private suspend fun fetchAndFilterTokenBalances(userWalletId: UserWalletId, network: Network): List<TokenBalance> {
return withContext(dispatchers.io) {
walletManagersFacade.getTokenBalances(userWalletId, network)
private suspend fun discoverAndFilterAssets(userWalletId: UserWalletId, network: Network): List<DiscoveredAsset> =
withContext(dispatchers.io) {
val providerInfo = assetsDiscoveryFacade.getAssetsDiscoveryService(userWalletId, network)
?: return@withContext emptyList()
providerInfo.service.discoverAssets(providerInfo.address)
.filter { it.amount > BigDecimal.ZERO }
}
}
private suspend fun enrichTokensWithCatalog(
tokenBalances: List<TokenBalance>,
assets: List<DiscoveredAsset>,
network: Network,
): List<DiscoveredToken> = withContext(dispatchers.io) {
val tokensToEnrich = tokenBalances.filter { !it.isNativeToken }
): List<EnrichedDiscoveredAsset> = withContext(dispatchers.io) {
val tokensToEnrich = assets.filterIsInstance<DiscoveredAsset.Token>()
val catalogMap = fetchCatalogInfo(
networkId = network.rawId,
contractAddresses = tokensToEnrich.mapNotNull(TokenBalance::contractAddress),
contractAddresses = tokensToEnrich.map { it.contractAddress },
)
tokenBalances.mapNotNull { balance ->
if (balance.isNativeToken) return@mapNotNull null
val contractAddressLower = balance.contractAddress?.lowercase()
val coin = contractAddressLower?.let { catalogMap[it] } ?: return@mapNotNull null
tokensToEnrich.mapNotNull { balance ->
val contractAddressLower = balance.contractAddress.lowercase()
val coin = catalogMap[contractAddressLower] ?: return@mapNotNull null
val decimals = coin.networks
.find { it.contractAddress?.lowercase() == contractAddressLower }
?.decimalCount
?.toInt()
?: 0
DiscoveredToken(
EnrichedDiscoveredAsset(
contractAddress = balance.contractAddress,
symbol = coin.symbol,
name = coin.name,
@ -290,23 +284,23 @@ internal class DefaultTokenSyncRepository(
}
}
private fun getProgressFlow(userWalletId: UserWalletId): MutableStateFlow<TokenSyncProgress> {
private fun getProgressFlow(userWalletId: UserWalletId): MutableStateFlow<AssetsDiscoveryProgress> {
return progressStates.getOrPut(userWalletId.stringValue) {
MutableStateFlow(TokenSyncProgress.Idle)
MutableStateFlow(AssetsDiscoveryProgress.Idle)
}
}
private suspend fun setPendingFlag(userWalletId: UserWalletId, value: Boolean) {
appPreferencesStore.editData { prefs ->
prefs.setObjectMap(
key = PreferencesKeys.PENDING_DISCOVERY_SYNC_KEY,
value = prefs.getObjectMap<Boolean>(PreferencesKeys.PENDING_DISCOVERY_SYNC_KEY)
key = PreferencesKeys.PENDING_ASSETS_DISCOVERY_KEY,
value = prefs.getObjectMap<Boolean>(PreferencesKeys.PENDING_ASSETS_DISCOVERY_KEY)
.plus(userWalletId.stringValue to value),
)
}
}
private fun DiscoveredToken.toResponseToken(): UserTokensResponse.Token {
private fun EnrichedDiscoveredAsset.toResponseToken(): UserTokensResponse.Token {
return UserTokensResponse.Token(
id = currencyId,
networkId = networkId,
@ -317,7 +311,7 @@ internal class DefaultTokenSyncRepository(
)
}
private data class DiscoveredToken(
private data class EnrichedDiscoveredAsset(
val contractAddress: String?,
val symbol: String,
val name: String,

View file

@ -1,8 +1,8 @@
package com.tangem.data.tokensync.store
package com.tangem.data.assetsdiscovery.store
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
interface TokenSyncStore {
interface AssetsDiscoveryStore {
suspend fun get(): List<UserTokensResponse.Token>

View file

@ -1,4 +1,4 @@
package com.tangem.data.tokensync.store
package com.tangem.data.assetsdiscovery.store
import android.content.Context
import androidx.datastore.core.DataStore
@ -17,18 +17,18 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TokenSyncStoreFactory @Inject constructor(
class AssetsDiscoveryStoreFactory @Inject constructor(
@NetworkMoshi private val moshi: Moshi,
@ApplicationContext private val context: Context,
private val appScope: AppCoroutineScope,
) {
private val stores = ConcurrentHashMap<String, TokenSyncStore>()
private val stores = ConcurrentHashMap<String, AssetsDiscoveryStore>()
fun provide(userWalletId: UserWalletId): TokenSyncStore {
fun provide(userWalletId: UserWalletId): AssetsDiscoveryStore {
val userWalletStringId = userWalletId.formatted()
return stores.computeIfAbsent(userWalletStringId) {
DefaultTokenSyncStore(
DefaultAssetsDiscoveryStore(
persistenceStore = createPersistenceStore(
fileName = "token_sync_$userWalletStringId",
types = listTypes<UserTokensResponse.Token>(),

View file

@ -1,12 +1,12 @@
package com.tangem.data.tokensync.store
package com.tangem.data.assetsdiscovery.store
import androidx.datastore.core.DataStore
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import kotlinx.coroutines.flow.firstOrNull
internal class DefaultTokenSyncStore(
internal class DefaultAssetsDiscoveryStore(
private val persistenceStore: DataStore<List<UserTokensResponse.Token>>,
) : TokenSyncStore {
) : AssetsDiscoveryStore {
override suspend fun get(): List<UserTokensResponse.Token> {
return persistenceStore.data.firstOrNull().orEmpty()

View file

@ -1,49 +0,0 @@
package com.tangem.data.tokensync.di
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.data.common.network.NetworkFactory
import com.tangem.data.tokensync.repository.DefaultTokenSyncRepository
import com.tangem.data.tokensync.store.TokenSyncStoreFactory
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.tokensync.repository.TokenSyncRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object TokenSyncDataModule {
@Provides
@Singleton
fun provideTokenSyncRepository(
walletManagersFacade: WalletManagersFacade,
tangemTechApi: TangemTechApi,
userWalletsListRepository: UserWalletsListRepository,
networkFactory: NetworkFactory,
appPreferencesStore: AppPreferencesStore,
tokenSyncStoreFactory: TokenSyncStoreFactory,
responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory,
dispatchers: CoroutineDispatcherProvider,
excludedBlockchains: ExcludedBlockchains,
): TokenSyncRepository {
return DefaultTokenSyncRepository(
walletManagersFacade = walletManagersFacade,
tangemTechApi = tangemTechApi,
userWalletsListRepository = userWalletsListRepository,
networkFactory = networkFactory,
appPreferencesStore = appPreferencesStore,
tokenSyncStoreFactory = tokenSyncStoreFactory,
responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory,
dispatchers = dispatchers,
excludedBlockchains = excludedBlockchains,
)
}
}

View file

@ -19,7 +19,6 @@ import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.blockchain.nft.models.NFTAsset
import com.tangem.blockchain.nft.models.NFTCollection
import com.tangem.blockchain.tokenbalance.models.TokenBalance
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryRequest
import com.tangem.blockchain.yieldsupply.YieldSupplyContractCallDataProviderFactory
import com.tangem.blockchainsdk.BlockchainSDKFactory
@ -850,17 +849,6 @@ internal class DefaultWalletManagersFacade @Inject constructor(
return blockchain.getNFTExploreUrl(assetIdentifier)
}
override suspend fun getTokenBalances(userWalletId: UserWalletId, network: Network): List<TokenBalance> {
val blockchain = network.toBlockchain()
val walletManager = getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
derivationPath = network.derivationPath.value,
) ?: return emptyList()
val address = walletManager.wallet.address
return walletManager.getTokenBalances(address)
}
override suspend fun isAccountInitialized(userWalletId: UserWalletId, network: Network): Boolean {
val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = network)
val initializableAccountWalletManger = walletManager as? InitializableAccount ?: return true