Updated on 2026-08-14
This commit is contained in:
commit
2ca7759e7e
16 changed files with 273 additions and 44 deletions
|
|
@ -61,6 +61,10 @@ internal class DefaultWalletCurrenciesManager(
|
|||
userWallet: UserWallet,
|
||||
currenciesToAdd: List<Currency>,
|
||||
): CompletionResult<Unit> = 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<Currency>,
|
||||
): CompletionResult<Unit> = 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)
|
||||
|
|
|
|||
|
|
@ -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<AppState> = { _, 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<WalletStoreModel>, 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<WalletStoreModel>) {
|
||||
scope.launch(Dispatchers.Default) {
|
||||
val totalFiatBalance = totalFiatBalanceCalculator.calculateOrNull(walletStores)?.mapToReduxModel()
|
||||
private suspend fun fetchTotalFiatBalance(walletStores: List<WalletStoreModel>) {
|
||||
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<WalletStoreModel>) {
|
||||
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<WalletStoreModel>) {
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 <R> runCatching(dispatcher: CoroutineDispatcher, block: suspend () -
|
|||
}
|
||||
}
|
||||
|
||||
suspend inline fun ifActive(crossinline block: suspend () -> Unit) = coroutineScope {
|
||||
if (isActive) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
class Debouncer {
|
||||
|
||||
private var debounceJob: Job? = null
|
||||
|
|
|
|||
|
|
@ -29,4 +29,7 @@ dependencies {
|
|||
|
||||
/** Feature Apis */
|
||||
implementation(project(":features:tester:api"))
|
||||
|
||||
/** Other modules */
|
||||
implementation(project(":libs:crypto"))
|
||||
}
|
||||
|
|
@ -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<TesterActionsViewModel>().apply {
|
||||
setupNavigation(innerTesterRouter)
|
||||
}
|
||||
|
||||
TesterActionsScreen(state = viewModel.uiState)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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 = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -3,4 +3,6 @@
|
|||
<string name="tester_menu" translatable="false">Tester menu</string>
|
||||
<string name="feature_toggles" translatable="false">Feature toggles</string>
|
||||
<string name="stand_toggles" translatable="false">Stand toggles</string>
|
||||
</resources>
|
||||
<string name="tester_actions" translatable="false">Tester actions</string>
|
||||
<string name="hide_all_currencies" translatable="false">Hide all currencies</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ interface UserWalletManager {
|
|||
@Throws(IllegalStateException::class)
|
||||
suspend fun addToken(currency: Currency, derivationPath: String?)
|
||||
|
||||
suspend fun hideAllTokens()
|
||||
|
||||
fun refreshWallet()
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue