Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-15 23:23:27 +04:00
parent b14f487b21
commit 2fc98b948f
11 changed files with 15 additions and 495 deletions

View file

@ -19,10 +19,6 @@
"name": "WC_SOLANA_TX_SIGN_ENABLED",
"version": "undefined"
},
{
"name": "TOKEN_LIST_LCE_ENABLED",
"version": "5.12.0"
},
{
"name": "CARDANO_TOKENS_SUPPORT_ENABLED",
"version": "5.12.0"

View file

@ -1,8 +1,6 @@
package com.tangem.domain.tokens
import arrow.core.left
import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.core.utils.EitherFlow
import com.tangem.domain.core.utils.lceError
import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.core.utils.toLce
@ -12,7 +10,6 @@ import com.tangem.domain.tokens.error.mapper.mapToTokenListError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.operations.CurrenciesStatusesLceOperations
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
import com.tangem.domain.tokens.operations.TokenListOperations
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
@ -31,29 +28,7 @@ class GetTokenListUseCase(
) {
@OptIn(ExperimentalCoroutinesApi::class)
fun launch(userWalletId: UserWalletId): EitherFlow<TokenListError, TokenList> {
val operations = CurrenciesStatusesOperations(
userWalletId = userWalletId,
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
stakingRepository = stakingRepository,
)
return operations.getCurrenciesStatusesFlow().transformLatest { maybeTokens ->
maybeTokens.fold(
ifLeft = { error ->
emit(error.mapToTokenListError().left())
},
ifRight = { tokens ->
emitAll(createTokenList(userWalletId, tokens))
},
)
}
}
@OptIn(ExperimentalCoroutinesApi::class)
fun launchLce(userWalletId: UserWalletId): LceFlow<TokenListError, TokenList> {
fun launch(userWalletId: UserWalletId): LceFlow<TokenListError, TokenList> {
val operations = CurrenciesStatusesLceOperations(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
@ -78,21 +53,6 @@ class GetTokenListUseCase(
}
}
private fun createTokenList(
userWalletId: UserWalletId,
tokens: List<CryptoCurrencyStatus>,
): EitherFlow<TokenListError, TokenList> {
val operations = TokenListOperations(
userWalletId = userWalletId,
tokens = tokens,
currenciesRepository = currenciesRepository,
)
return operations.getTokenListFlow().map { maybeTokenList ->
maybeTokenList.mapLeft(TokenListOperations.Error::mapToTokenListError)
}
}
private fun createTokenListLce(
userWalletId: UserWalletId,
currencies: List<CryptoCurrencyStatus>,

View file

@ -24,52 +24,6 @@ internal class CurrenciesStatusesOperations(
private val userWalletId: UserWalletId,
) {
@OptIn(ExperimentalCoroutinesApi::class)
fun getCurrenciesStatusesFlow(): EitherFlow<Error, List<CryptoCurrencyStatus>> {
return getMultiCurrencyWalletCurrencies().transformLatest { maybeCurrencies ->
val nonEmptyCurrencies = maybeCurrencies.fold(
ifLeft = { error ->
emit(error.left())
return@transformLatest
},
ifRight = List<CryptoCurrency>::toNonEmptyListOrNull,
)
if (nonEmptyCurrencies == null) {
val emptyCurrenciesStatuses = emptyList<CryptoCurrencyStatus>()
emit(emptyCurrenciesStatuses.right())
return@transformLatest
}
val maybeLoadingCurrenciesStatuses = createCurrenciesStatuses(
currencies = nonEmptyCurrencies,
maybeNetworkStatuses = null,
maybeQuotes = null,
maybeYieldBalances = null,
)
emit(maybeLoadingCurrenciesStatuses)
val (networks, currenciesIds) = getIds(nonEmptyCurrencies)
val currenciesFlow = combine(
getQuotes(currenciesIds),
getNetworksStatuses(networks),
getYieldBalances(),
) { maybeQuotes, maybeNetworksStatuses, maybeYieldBalances ->
createCurrenciesStatuses(
currencies = nonEmptyCurrencies,
maybeQuotes = maybeQuotes,
maybeNetworkStatuses = maybeNetworksStatuses,
maybeYieldBalances = maybeYieldBalances,
)
}
emitAll(currenciesFlow)
}
}
suspend fun getCurrenciesStatusesSync(): Either<Error, List<CryptoCurrencyStatus>> {
return either {
catch(
@ -360,13 +314,6 @@ internal class CurrenciesStatusesOperations(
return currencyStatusOperations.createTokenStatus()
}
private fun getMultiCurrencyWalletCurrencies(): Flow<Either<Error, List<CryptoCurrency>>> {
return currenciesRepository.getMultiCurrencyWalletCurrenciesUpdates(userWalletId)
.map<List<CryptoCurrency>, Either<Error, List<CryptoCurrency>>> { it.right() }
.catch { emit(Error.DataError(it).left()) }
.onEmpty { emit(Error.EmptyCurrencies.left()) }
}
private suspend fun Raise<Error>.getMultiCurrencyWalletCurrency(currencyId: CryptoCurrency.ID): CryptoCurrency {
return Either.catch {
currenciesRepository.getMultiCurrencyWalletCurrency(

View file

@ -1,322 +0,0 @@
package com.tangem.domain.tokens
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.domain.core.error.DataError
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.tokens.mock.MockNetworks
import com.tangem.domain.tokens.mock.MockQuotes
import com.tangem.domain.tokens.mock.MockTokenLists
import com.tangem.domain.tokens.mock.MockTokens
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.NetworkStatus
import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.repository.MockCurrenciesRepository
import com.tangem.domain.tokens.repository.MockNetworksRepository
import com.tangem.domain.tokens.repository.MockQuotesRepository
import com.tangem.domain.tokens.repository.MockStakingRepository
import com.tangem.domain.wallets.models.UserWalletId
import junit.framework.TestCase.assertEquals
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.test.runTest
import org.junit.Ignore
import org.junit.Test
internal class GetTokenListUseCaseTest {
private val userWalletId = UserWalletId(value = null)
@Ignore
@Test
fun `when list ungrouped and unsorted then correct token list should be returned`() = runTest {
// Given
val expectedResult = listOf(
MockTokenLists.loadingUngroupedTokenList.right(),
MockTokenLists.failedUngroupedTokenList.right(),
)
val useCase = getUseCase(
isGrouped = flowOf(false.right()),
isSortedByBalance = flowOf(false.right()),
)
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when tokens getting failed then error should be received`() = runTest {
// Given
val expectedResult = TokenListError.DataError(DataError.NetworkError.NoInternetConnection).left()
val useCase = getUseCase(tokens = flowOf(DataError.NetworkError.NoInternetConnection.left()))
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when quotes getting failed then token list without quotes should be received`() = runTest {
// Given
val expectedResult = listOf(
MockTokenLists.loadingUngroupedTokenList.right(),
MockTokenLists.noQuotesUngroupedTokenList.right(),
)
val useCase = getUseCase(
quotes = flowOf(DataError.NetworkError.NoInternetConnection.left()),
statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()),
)
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when grouping type getting failed then error should be received`() = runTest {
// Given
val expectedResult = TokenListError.DataError(DataError.NetworkError.NoInternetConnection).left()
val useCase = getUseCase(isGrouped = flowOf(DataError.NetworkError.NoInternetConnection.left()))
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when sorting type getting failed then error should be received`() = runTest {
// Given
val expectedResult = TokenListError.DataError(DataError.NetworkError.NoInternetConnection).left()
val useCase = getUseCase(isSortedByBalance = flowOf(DataError.NetworkError.NoInternetConnection.left()))
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
@Ignore
@Test
fun `when tokens getting failed on second emit then error should be received`() = runTest {
// Given
val error = DataError.NetworkError.NoInternetConnection.left()
val expectedResult = listOf(
MockTokenLists.loadingUngroupedTokenList.right(),
MockTokenLists.failedUngroupedTokenList.right(),
TokenListError.DataError(DataError.NetworkError.NoInternetConnection).left(),
)
val useCase = getUseCase(
tokens = flowOf(
MockTokens.tokens.right(),
error,
).map { delay(timeMillis = 1_000); it },
)
// When
val result = useCase.launch(userWalletId)
.take(count = 3)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Ignore
@Test
fun `when list grouped then correct token list should be received`() = runTest {
val expectedResult = listOf(
MockTokenLists.loadingGroupedTokenList.right(),
MockTokenLists.failedGroupedTokenList.right(),
)
val useCase = getUseCase(isGrouped = flowOf(true.right()))
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when list is sorted and ungrouped then correct token list should be received`() = runTest {
val expectedResult = listOf(
MockTokenLists.loadingUngroupedTokenList.copy(sortedBy = TokenList.SortType.BALANCE).right(),
MockTokenLists.sortedUngroupedTokenList.right(),
)
val useCase = getUseCase(
statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()),
isGrouped = flowOf(false.right()),
isSortedByBalance = flowOf(true.right()),
)
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when list is sorted and grouped then correct token list should be received`() = runTest {
val expectedResult = listOf(
MockTokenLists.loadingGroupedTokenList.copy(sortedBy = TokenList.SortType.BALANCE).right(),
MockTokenLists.sortedGroupedTokenList.right(),
)
val useCase = getUseCase(
statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()),
isGrouped = flowOf(true.right()),
isSortedByBalance = flowOf(true.right()),
)
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when tokens is empty then not initialized token list should be received`() = runTest {
val expectedResult = MockTokenLists.emptyTokenList.right()
val useCase = getUseCase(tokens = flowOf(emptyList<CryptoCurrency>().right()))
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when tokens flow is empty then error should be received`() = runTest {
val expectedResult = TokenListError.EmptyTokens.left()
val useCase = getUseCase(tokens = flowOf())
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when networks statuses flow is empty then error should be received`() = runTest {
val expectedResult = listOf(
MockTokenLists.loadingUngroupedTokenList.right(),
TokenListError.EmptyTokens.left(),
)
val useCase = getUseCase(statuses = flowOf())
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when networks statuses is empty then loading token list should be received`() = runTest {
val expectedResult = MockTokenLists.loadingUngroupedTokenList.right()
val useCase = getUseCase(statuses = flowOf(emptySet<NetworkStatus>().right()))
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when quotes flow is empty then list without quotes should be received`() = runTest {
val expectedResult = listOf(
MockTokenLists.loadingUngroupedTokenList.right(),
MockTokenLists.noQuotesUngroupedTokenList.right(),
)
val useCase = getUseCase(
statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()),
quotes = flowOf(emptySet<Quote>().right()),
)
// When
val result = useCase.launch(userWalletId)
.take(count = 2)
.toList()
// Then
assertEquals(expectedResult, result)
}
@Test
fun `when quotes is empty and statuses verified then loading token list should be received`() = runTest {
val expectedResult = MockTokenLists.loadingUngroupedTokenList.right()
val useCase = getUseCase(
statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()),
quotes = flowOf(emptySet<Quote>().right()),
)
// When
val result = useCase.launch(userWalletId).first()
// Then
assertEquals(expectedResult, result)
}
private fun getUseCase(
tokens: Flow<Either<DataError, List<CryptoCurrency>>> = flowOf(MockTokens.tokens.right()),
quotes: Flow<Either<DataError, Set<Quote>>> = flowOf(MockQuotes.quotes.right()),
statuses: Flow<Either<DataError, Set<NetworkStatus>>> = flowOf(MockNetworks.errorNetworksStatuses.right()),
isGrouped: Flow<Either<DataError, Boolean>> = flowOf(MockTokenLists.isGrouped.right()),
isSortedByBalance: Flow<Either<DataError, Boolean>> = flowOf(MockTokenLists.isSortedByBalance.right()),
) = GetTokenListUseCase(
currenciesRepository = MockCurrenciesRepository(
sortTokensResult = Unit.right(),
removeCurrencyResult = Unit.right(),
token = MockTokens.token1.right(),
tokens = tokens,
isGrouped = isGrouped,
isSortedByBalance = isSortedByBalance,
),
quotesRepository = MockQuotesRepository(quotes),
networksRepository = MockNetworksRepository(statuses),
stakingRepository = MockStakingRepository(),
)
}

View file

@ -1,20 +0,0 @@
package com.tangem.feature.wallet.di
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
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 FeatureTogglesModule {
@Provides
@Singleton
fun provideWalletFeatureToggles(featureTogglesManager: FeatureTogglesManager): WalletFeatureToggles {
return WalletFeatureToggles(featureTogglesManager)
}
}

View file

@ -1,11 +0,0 @@
package com.tangem.feature.wallet.featuretoggle
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
internal class WalletFeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) {
val isTokenListLceFlowEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled("TOKEN_LIST_LCE_ENABLED")
}

View file

@ -13,9 +13,7 @@ import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.ToggleTokenListGroupingUseCase
import com.tangem.domain.tokens.ToggleTokenListSortingUseCase
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.organizetokens.analytics.PortfolioOrganizeTokensAnalyticsEvent
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensListState
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensState
@ -42,7 +40,6 @@ internal class OrganizeTokensViewModel @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val analyticsEventsHandler: AnalyticsEventHandler,
private val walletFeatureToggles: WalletFeatureToggles,
private val dispatchers: CoroutineDispatcherProvider,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver, OrganizeTokensIntents {
@ -173,34 +170,21 @@ internal class OrganizeTokensViewModel @Inject constructor(
}
private suspend fun getTokenList(): TokenList? {
return if (walletFeatureToggles.isTokenListLceFlowEnabled) {
val tokenList = getTokenListUseCase.launchLce(userWalletId)
.transform { maybeTokenList ->
val tokenList = maybeTokenList.getOrElse(
ifLoading = { return@transform },
ifError = { error ->
stateHolder.updateStateWithError(error)
val tokenList = getTokenListUseCase.launch(userWalletId)
.transform { maybeTokenList ->
val tokenList = maybeTokenList.getOrElse(
ifLoading = { return@transform },
ifError = { error ->
stateHolder.updateStateWithError(error)
return@transform
},
)
return@transform
},
)
emit(tokenList)
}
tokenList.firstOrNull()
} else {
val maybeTokenList = getTokenListUseCase.launch(userWalletId)
.first { maybeTokenList ->
maybeTokenList.getOrNull()?.totalFiatBalance !is TotalFiatBalance.Loading
}
maybeTokenList.getOrElse { error ->
stateHolder.updateStateWithError(error)
null
emit(tokenList)
}
}
return tokenList.firstOrNull()
}
private fun bootstrapDragAndDropUpdates() {

View file

@ -46,7 +46,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
val promoFlow = flow { emit(promoRepository.getOkxPromoBanner()) }
return combine(
flow = getTokenListUseCase.launchLce(userWallet.walletId),
flow = getTokenListUseCase.launch(userWallet.walletId),
flow2 = isReadyToShowRateAppUseCase(),
flow3 = isNeedToBackupUseCase(userWallet.walletId),
flow4 = shouldShowSwapPromoWalletUseCase(),

View file

@ -5,7 +5,6 @@ import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
@ -28,7 +27,6 @@ internal class MultiWalletContentLoader(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
private val walletFeatureToggles: WalletFeatureToggles,
private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase,
) : WalletContentLoader(id = userWallet.walletId) {
@ -42,7 +40,6 @@ internal class MultiWalletContentLoader(
walletWithFundsChecker = walletWithFundsChecker,
getTokenListUseCase = getTokenListUseCase,
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
walletFeatureToggles = walletFeatureToggles,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase,
),

View file

@ -5,7 +5,6 @@ import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
@ -26,7 +25,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
private val walletFeatureToggles: WalletFeatureToggles,
private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase,
) {
@ -42,7 +40,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
getMultiWalletWarningsFactory = getMultiWalletWarningsFactory,
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
walletFeatureToggles = walletFeatureToggles,
runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase,
)
}

View file

@ -3,7 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.core.utils.toLce
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
@ -12,19 +11,16 @@ import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
import kotlinx.coroutines.flow.map
@Suppress("LongParameterList")
internal class MultiWalletTokenListSubscriber(
private val userWallet: UserWallet,
private val getTokenListUseCase: GetTokenListUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val walletFeatureToggles: WalletFeatureToggles,
stateHolder: WalletStateController,
clickIntents: WalletClickIntents,
tokenListAnalyticsSender: TokenListAnalyticsSender,
@ -42,11 +38,7 @@ internal class MultiWalletTokenListSubscriber(
) {
override fun tokenListFlow(): LceFlow<TokenListError, TokenList> {
return if (walletFeatureToggles.isTokenListLceFlowEnabled) {
getTokenListUseCase.launchLce(userWallet.walletId)
} else {
getTokenListUseCase.launch(userWallet.walletId).map { it.toLce() }
}
return getTokenListUseCase.launch(userWallet.walletId)
}
override suspend fun onTokenListReceived(maybeTokenList: Lce<TokenListError, TokenList>) {