diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt index 97d9eb72e5..d32bdd60ff 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt @@ -61,6 +61,10 @@ internal class DefaultWalletCurrenciesManager( userWallet: UserWallet, currenciesToAdd: List, ): CompletionResult = withContext(Dispatchers.Default) { + if (currenciesToAdd.isEmpty()) { + return@withContext CompletionResult.Success(Unit) + } + val card = userWallet.scanResponse.card val currenciesToAddWithMissingBlockchains = currenciesToAdd.addMissingBlockchainsIfNeeded(card) listeners.forEach { it.willCurrenciesAdd(userWallet, currenciesToAddWithMissingBlockchains) } @@ -86,6 +90,10 @@ internal class DefaultWalletCurrenciesManager( userWallet: UserWallet, currenciesToRemove: List, ): CompletionResult = withContext(Dispatchers.Default) { + if (currenciesToRemove.isEmpty()) { + return@withContext CompletionResult.Success(Unit) + } + listeners.forEach { it.willCurrenciesRemove(userWallet, currenciesToRemove) } val card = userWallet.scanResponse.card val remainingCurrencies = getSavedCurrencies(userWallet.walletId) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index fafa99c7b3..2c4ad663cb 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -42,8 +42,10 @@ import com.tangem.tap.store import com.tangem.tap.tangemSdkManager import com.tangem.tap.totalFiatBalanceCalculator import com.tangem.tap.userWalletsListManager +import com.tangem.utils.coroutines.ifActive import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.rekotlin.Action @@ -70,6 +72,12 @@ class WalletMiddleware { private val networkConnectionManager: NetworkConnectionManager get() = store.state.daggerGraphState.get(DaggerGraphState::networkConnectionManager) + private var updateWalletStoresJob: Job? = null + set(value) { + field?.cancel() + field = value + } + val walletMiddleware: Middleware = { _, state -> { next -> { action -> @@ -176,11 +184,14 @@ class WalletMiddleware { } is WalletAction.UserWalletChanged -> Unit is WalletAction.WalletStoresChanged -> { - store.state.globalState.topUpController?.walletStoresChanged(action.walletStores) - updateWalletStores(action.walletStores, walletState) - fetchTotalFiatBalance(action.walletStores) - findMissedDerivations(action.walletStores) - tryToShowAppRatingWarning(action.walletStores) + // Cancel update job when new wallet stores received + updateWalletStoresJob = scope.launch(Dispatchers.Default) { + ifActive { updateWalletStores(action.walletStores, walletState) } + ifActive { fetchTotalFiatBalance(action.walletStores) } + ifActive { findMissedDerivations(action.walletStores) } + ifActive { tryToShowAppRatingWarning(action.walletStores) } + ifActive { store.state.globalState.topUpController?.walletStoresChanged(action.walletStores) } + } } is WalletAction.TotalFiatBalanceChanged -> Unit is WalletAction.PopBackToInitialScreen -> { @@ -197,55 +208,47 @@ class WalletMiddleware { } private fun updateWalletStores(walletsStores: List, state: WalletState) { - scope.launch(Dispatchers.Default) { - val reduxWalletStores = walletsStores.mapToReduxModels() - if (!state.isMultiwalletAllowed) { - findSelectedCurrency( - walletsStores = reduxWalletStores, - currentSelectedCurrency = null, - isMultiWalletAllowed = false, - )?.let { - store.dispatchOnMain(WalletAction.MultiWallet.SetSingleWalletCurrency(it)) - } + val reduxWalletStores = walletsStores.mapToReduxModels() + if (!state.isMultiwalletAllowed) { + findSelectedCurrency( + walletsStores = reduxWalletStores, + currentSelectedCurrency = null, + isMultiWalletAllowed = false, + )?.let { + store.dispatchOnMain(WalletAction.MultiWallet.SetSingleWalletCurrency(it)) } - store.dispatchOnMain( - WalletAction.WalletStoresChanged.UpdateWalletStores( - reduxWalletStores = reduxWalletStores, - ), - ) } + store.dispatchOnMain( + WalletAction.WalletStoresChanged.UpdateWalletStores( + reduxWalletStores = reduxWalletStores, + ), + ) } - private fun fetchTotalFiatBalance(walletStores: List) { - scope.launch(Dispatchers.Default) { - val totalFiatBalance = totalFiatBalanceCalculator.calculateOrNull(walletStores)?.mapToReduxModel() + private suspend fun fetchTotalFiatBalance(walletStores: List) { + val totalFiatBalance = totalFiatBalanceCalculator.calculateOrNull(walletStores)?.mapToReduxModel() - if (totalFiatBalance != null) { - store.dispatchOnMain(WalletAction.TotalFiatBalanceChanged(totalFiatBalance)) - } + if (totalFiatBalance != null) { + store.dispatchOnMain(WalletAction.TotalFiatBalanceChanged(totalFiatBalance)) } } private fun findMissedDerivations(wallStores: List) { - scope.launch(Dispatchers.Default) { - val missedDerivations = wallStores - .filter { store -> - store.walletsData.any { it.status is WalletDataModel.MissedDerivation } - } - .map(WalletStoreModel::blockchainNetwork) + val missedDerivations = wallStores + .filter { store -> + store.walletsData.any { it.status is WalletDataModel.MissedDerivation } + } + .map(WalletStoreModel::blockchainNetwork) - store.dispatchOnMain(WalletAction.MultiWallet.AddMissingDerivations(missedDerivations)) - } + store.dispatchOnMain(WalletAction.MultiWallet.AddMissingDerivations(missedDerivations)) } private fun tryToShowAppRatingWarning(walletStores: List) { - scope.launch(Dispatchers.Default) { - warningsMiddleware.tryToShowAppRatingWarning( - hasNonZeroWallets = walletStores - .flatMap { it.walletsData } - .any { it.status.amount.isGreaterThan(BigDecimal.ZERO) }, - ) - } + warningsMiddleware.tryToShowAppRatingWarning( + hasNonZeroWallets = walletStores + .flatMap { it.walletsData } + .any { it.status.amount.isGreaterThan(BigDecimal.ZERO) }, + ) } private fun showSaveWalletIfNeeded() { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt index 93f1c5ff90..2be9db11ee 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt @@ -17,8 +17,10 @@ import com.tangem.tap.store import com.tangem.tap.walletStoresManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.Job import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map @@ -98,12 +100,16 @@ internal class WalletViewModel @Inject constructor( } } + @OptIn(FlowPreview::class) private fun bootstrapSelectedWalletStoresChanges(manager: UserWalletsListManager) { observeWalletStoresUpdatesJob = manager.selectedUserWallet .map { it.walletId } .flatMapLatest { selectedUserWalletId -> walletStoresManager.get(selectedUserWalletId) } + .debounce { walletStores -> + if (walletStores.isNotEmpty()) WALLET_STORES_DEBOUNCE_TIMEOUT else 0 + } .onEach { walletStores -> store.dispatch(WalletAction.WalletStoresChanged(walletStores)) } @@ -126,4 +132,8 @@ internal class WalletViewModel @Inject constructor( .select { it.globalState.userWalletsListManager } } } + + companion object { + private const val WALLET_STORES_DEBOUNCE_TIMEOUT = 100L + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt index a6b1dc5348..fba11b855a 100644 --- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt @@ -4,6 +4,7 @@ import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.WalletManager +import com.tangem.common.doOnFailure import com.tangem.common.extensions.guard import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.toCoinId @@ -20,6 +21,8 @@ import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.userWalletsListManager import com.tangem.tap.walletCurrenciesManager +import com.tangem.tap.walletStoresManager +import kotlinx.coroutines.flow.firstOrNull import timber.log.Timber import java.math.BigDecimal import com.tangem.tap.features.wallet.models.Currency as WalletCurrency @@ -117,6 +120,28 @@ class UserWalletManagerImpl( ) } + override suspend fun hideAllTokens() { + val userWallet = userWalletsListManager.selectedUserWalletSync.guard { + Timber.e("No user wallets selected") + return + } + + val currencies = walletStoresManager.get(userWallet.walletId) + .firstOrNull() + ?.flatMap { walletStore -> + walletStore.walletsData.map { it.currency } + } + .guard { + Timber.d("No currencies found") + return + } + + walletCurrenciesManager.removeCurrencies(userWallet, currenciesToRemove = currencies) + .doOnFailure { e -> + Timber.e(e, "Unable to delete all currencies") + } + } + override fun getWalletAddress(networkId: String, derivationPath: String?): String { val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" } val walletManager = getActualWalletManager(blockchain, derivationPath) diff --git a/core/utils/src/main/java/com/tangem/utils/coroutines/CoroutineExt.kt b/core/utils/src/main/java/com/tangem/utils/coroutines/CoroutineExt.kt index 4fbd7b0ccb..b9ed8ee566 100644 --- a/core/utils/src/main/java/com/tangem/utils/coroutines/CoroutineExt.kt +++ b/core/utils/src/main/java/com/tangem/utils/coroutines/CoroutineExt.kt @@ -3,7 +3,9 @@ package com.tangem.utils.coroutines import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -13,6 +15,12 @@ suspend fun runCatching(dispatcher: CoroutineDispatcher, block: suspend () - } } +suspend inline fun ifActive(crossinline block: suspend () -> Unit) = coroutineScope { + if (isActive) { + block() + } +} + class Debouncer { private var debounceJob: Job? = null diff --git a/features/tester/impl/build.gradle.kts b/features/tester/impl/build.gradle.kts index 774c318817..b94d17db0e 100644 --- a/features/tester/impl/build.gradle.kts +++ b/features/tester/impl/build.gradle.kts @@ -29,4 +29,7 @@ dependencies { /** Feature Apis */ implementation(project(":features:tester:api")) + + /** Other modules */ + implementation(project(":libs:crypto")) } \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/TesterActivity.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/TesterActivity.kt index f90be893ca..ea29eaa44e 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/TesterActivity.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/TesterActivity.kt @@ -10,6 +10,8 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.tester.presentation.actions.TesterActionsScreen +import com.tangem.feature.tester.presentation.actions.TesterActionsViewModel import com.tangem.feature.tester.presentation.featuretoggles.ui.FeatureTogglesScreen import com.tangem.feature.tester.presentation.featuretoggles.viewmodels.FeatureTogglesViewModel import com.tangem.feature.tester.presentation.menu.state.TesterMenuContentState @@ -59,6 +61,7 @@ internal class TesterActivity : ComponentActivity() { state = TesterMenuContentState( onBackClick = innerTesterRouter::back, onFeatureTogglesClick = { innerTesterRouter.open(TesterScreen.FEATURE_TOGGLES) }, + onTesterActionsClick = { innerTesterRouter.open(TesterScreen.TESTER_ACTIONS) }, ), ) } @@ -70,6 +73,14 @@ internal class TesterActivity : ComponentActivity() { FeatureTogglesScreen(state = viewModel.uiState) } + + composable(route = TesterScreen.TESTER_ACTIONS.name) { + val viewModel = hiltViewModel().apply { + setupNavigation(innerTesterRouter) + } + + TesterActionsScreen(state = viewModel.uiState) + } } } } \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsContentState.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsContentState.kt new file mode 100644 index 0000000000..ea8771920d --- /dev/null +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsContentState.kt @@ -0,0 +1,12 @@ +package com.tangem.feature.tester.presentation.actions + +internal data class TesterActionsContentState( + val onBackClick: () -> Unit, + val hideAllCurrencies: HideAllCurrenciesState, +) + +internal sealed interface HideAllCurrenciesState { + data class Clickable(val onClick: () -> Unit) : HideAllCurrenciesState + + object Progress : HideAllCurrenciesState +} \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsScreen.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsScreen.kt new file mode 100644 index 0000000000..31b45f81f9 --- /dev/null +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsScreen.kt @@ -0,0 +1,94 @@ +package com.tangem.feature.tester.presentation.actions + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.components.PrimaryButton +import com.tangem.core.ui.components.appbar.AppBarWithBackButton +import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.tester.impl.R + +@OptIn(ExperimentalFoundationApi::class) +@Composable +internal fun TesterActionsScreen( + state: TesterActionsContentState, + modifier: Modifier = Modifier, +) { + LazyColumn( + modifier = modifier + .fillMaxSize() + .background(TangemTheme.colors.background.secondary), + ) { + stickyHeader { + AppBarWithBackButton( + text = stringResource(R.string.tester_actions), + onBackClick = state.onBackClick, + ) + } + item { + val onClick = remember(state.hideAllCurrencies) { + { (state.hideAllCurrencies as? HideAllCurrenciesState.Clickable)?.onClick?.invoke() ?: Unit } + } + TesterActionItem( + progress = state.hideAllCurrencies is HideAllCurrenciesState.Progress, + onClick = onClick, + ) + } + } +} + +@Composable +private fun TesterActionItem( + progress: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Box(modifier = modifier.padding(all = TangemTheme.dimens.spacing16)) { + PrimaryButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.hide_all_currencies), + onClick = onClick, + showProgress = progress, + ) + } +} + +// region Preview +@Composable +private fun TesterActionsScreenSample( + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .background(TangemTheme.colors.background.primary), + ) { + TesterActionsScreen(state = TesterActionsContentState({}, HideAllCurrenciesState.Clickable({}))) + } +} + +@Preview(showBackground = true, widthDp = 360) +@Composable +private fun TesterActionsScreenPreview_Light() { + TangemTheme { + TesterActionsScreenSample() + } +} + +@Preview(showBackground = true, widthDp = 360) +@Composable +private fun TesterActionsScreenPreview_Dark() { + TangemTheme(isDark = true) { + TesterActionsScreenSample() + } +} +// endregion Preview \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsViewModel.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsViewModel.kt new file mode 100644 index 0000000000..f2024d34cd --- /dev/null +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/actions/TesterActionsViewModel.kt @@ -0,0 +1,42 @@ +package com.tangem.feature.tester.presentation.actions + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter +import com.tangem.lib.crypto.UserWalletManager +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +internal class TesterActionsViewModel @Inject constructor( + private val userWalletManager: UserWalletManager, +) : ViewModel() { + + var uiState: TesterActionsContentState by mutableStateOf(initialState) + private set + + private val initialState: TesterActionsContentState + get() = TesterActionsContentState( + onBackClick = { /* [REDACTED_TODO_COMMENT] */ }, + hideAllCurrencies = HideAllCurrenciesState.Clickable(this::hideAllCurrencies), + ) + + fun setupNavigation(router: InnerTesterRouter) { + uiState = uiState.copy(onBackClick = router::back) + } + + private fun hideAllCurrencies() = viewModelScope.launch { + uiState = uiState.copy( + hideAllCurrencies = HideAllCurrenciesState.Progress, + ) + userWalletManager.hideAllTokens() + + uiState = uiState.copy( + hideAllCurrencies = HideAllCurrenciesState.Clickable(this@TesterActionsViewModel::hideAllCurrencies), + ) + } +} \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/state/TesterMenuContentState.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/state/TesterMenuContentState.kt index b99bc61405..a570b21660 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/state/TesterMenuContentState.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/state/TesterMenuContentState.kt @@ -5,8 +5,10 @@ package com.tangem.feature.tester.presentation.menu.state * * @property onBackClick the lambda to be invoked when back button is pressed * @property onFeatureTogglesClick the lambda to be invoked when feature toggles button is pressed + * @property onTesterActionsClick the lambda to be invoked when tester actions button is pressed */ data class TesterMenuContentState( val onBackClick: () -> Unit, val onFeatureTogglesClick: () -> Unit, + val onTesterActionsClick: () -> Unit, ) \ No newline at end of file diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/ui/TesterMenuScreen.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/ui/TesterMenuScreen.kt index ac0c7d15d4..4e5d7f056f 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/ui/TesterMenuScreen.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/menu/ui/TesterMenuScreen.kt @@ -54,6 +54,11 @@ internal fun TesterMenuScreen(state: TesterMenuContentState) { modifier = Modifier.fillMaxWidth(), enabled = false, ) + PrimaryButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(id = R.string.tester_actions), + onClick = state.onTesterActionsClick, + ) } } } @@ -66,6 +71,7 @@ private fun PreviewTesterMenuScreen_InLightTheme() { state = TesterMenuContentState( onBackClick = {}, onFeatureTogglesClick = {}, + onTesterActionsClick = {}, ), ) } @@ -79,6 +85,7 @@ private fun PreviewTesterMenuScreen_InDarkTheme() { state = TesterMenuContentState( onBackClick = {}, onFeatureTogglesClick = {}, + onTesterActionsClick = {}, ), ) } diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/navigation/TesterScreen.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/navigation/TesterScreen.kt index 18934aa128..903f287179 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/navigation/TesterScreen.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/navigation/TesterScreen.kt @@ -6,5 +6,5 @@ package com.tangem.feature.tester.presentation.navigation [REDACTED_AUTHOR] */ internal enum class TesterScreen { - MENU, FEATURE_TOGGLES + MENU, FEATURE_TOGGLES, TESTER_ACTIONS } \ No newline at end of file diff --git a/features/tester/impl/src/main/res/values/strings.xml b/features/tester/impl/src/main/res/values/strings.xml index 55e295ff67..22d5e89633 100644 --- a/features/tester/impl/src/main/res/values/strings.xml +++ b/features/tester/impl/src/main/res/values/strings.xml @@ -3,4 +3,6 @@ Tester menu Feature toggles Stand toggles - \ No newline at end of file + Tester actions + Hide all currencies + diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 69b8244ff4..00e0cb0b22 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -68,7 +68,7 @@ kotlinSerialization = "1.4.1" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-184" +tangemBlockchainSdk = "develop-185" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-206" # tangemCardSdk = "0.0.1" # Keep it! - used for local builds diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt index 23659c303f..c82675b1db 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/UserWalletManager.kt @@ -40,6 +40,8 @@ interface UserWalletManager { @Throws(IllegalStateException::class) suspend fun addToken(currency: Currency, derivationPath: String?) + suspend fun hideAllTokens() + fun refreshWallet() /**