Updated on 2026-08-14

This commit is contained in:
Tangem 2023-08-28 10:51:17 +03:00
parent cd02ce7bc0
commit e421ca8d32
11 changed files with 160 additions and 31 deletions

View file

@ -1,5 +1,7 @@
package com.tangem.tap.features.customtoken.impl.presentation.routers
import com.tangem.blockchain.common.Blockchain
/**
* Custom token feature router
*
@ -12,4 +14,10 @@ internal interface CustomTokenRouter {
/** Open wallet (main) screen */
fun openWalletScreen()
/** Open alert if solana network is unsupported
*
* @param blockchain blockchain to show alert
*/
fun openUnsupportedNetworkAlert(blockchain: Blockchain)
}

View file

@ -1,8 +1,12 @@
package com.tangem.tap.features.customtoken.impl.presentation.routers
import com.tangem.blockchain.common.Blockchain
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.store
import com.tangem.wallet.R
/** Default implementation of custom token feature router */
internal class DefaultCustomTokenRouter : CustomTokenRouter {
@ -14,4 +18,13 @@ internal class DefaultCustomTokenRouter : CustomTokenRouter {
override fun openWalletScreen() {
store.dispatch(NavigationAction.PopBackTo(screen = AppScreen.Wallet))
}
override fun openUnsupportedNetworkAlert(blockchain: Blockchain) {
val alert = AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_curve_message,
args = listOf(blockchain.fullName),
)
store.dispatchDialogShow(alert)
}
}

View file

@ -635,6 +635,15 @@ internal class AddCustomTokenViewModel @Inject constructor(
return derivationNetwork.derivationPath(derivationStyle)
}
private fun isUnsupportedBlockchain(blockchain: Blockchain): Boolean {
val scanResponse = reduxStateHolder.scanResponse
val canHandleToken = scanResponse?.card?.canHandleBlockchain(
blockchain = blockchain,
cardTypesResolver = scanResponse.cardTypesResolver,
) ?: false
return !canHandleToken
}
private inner class ActionsHandler(private val featureRouter: CustomTokenRouter) {
fun onBackButtonClick() {
@ -747,6 +756,11 @@ internal class AddCustomTokenViewModel @Inject constructor(
fun onAddCustomTokenClick() {
if (!isNetworkSelected()) return
val blockchain = uiState.form.networkSelectorField.selectedItem.blockchain
if (isUnsupportedBlockchain(blockchain)) {
featureRouter.openUnsupportedNetworkAlert(blockchain)
return
}
val currency = when (getCustomTokenType()) {
CustomTokenType.TOKEN -> {
@ -758,13 +772,13 @@ internal class AddCustomTokenViewModel @Inject constructor(
decimals = requireNotNull(uiState.form.decimalsInputField.value.toIntOrNull()),
id = foundToken?.id,
),
network = uiState.form.networkSelectorField.selectedItem.blockchain,
network = blockchain,
derivationPath = getDerivationPath(),
)
}
CustomTokenType.BLOCKCHAIN -> {
CustomCurrency.CustomBlockchain(
network = uiState.form.networkSelectorField.selectedItem.blockchain,
network = blockchain,
derivationPath = getDerivationPath(),
)
}

View file

@ -0,0 +1,11 @@
package com.tangem.tap.features.tokens.impl.presentation.models
/**
* State that shows is token support by given card
*/
sealed class SupportTokensState {
object SolanaNetworkUnsupported : SupportTokensState()
object UnsupportedCurve : SupportTokensState()
object SupportedToken : SupportTokensState()
}

View file

@ -51,17 +51,20 @@ internal class DefaultTokensListRouter(
}
override fun openUnsupportedNetworkAlert(blockchain: Blockchain) {
val alert = when (blockchain) {
Blockchain.Solana -> AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_message,
)
else -> AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_curve_message,
args = listOf(blockchain.fullName),
)
}
val alert = AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_curve_message,
args = listOf(blockchain.fullName),
)
store.dispatchDialogShow(alert)
}
override fun openSolanaTokensNotSupportAlert() {
store.dispatchDialogShow(
AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_message,
),
)
}
}

View file

@ -35,4 +35,9 @@ internal interface TokensListRouter {
* @param blockchain blockchain to show alert
*/
fun openUnsupportedNetworkAlert(blockchain: Blockchain)
/**
* Open alert with Solana tokens error
*/
fun openSolanaTokensNotSupportAlert()
}

View file

@ -17,6 +17,7 @@ import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
import com.tangem.domain.common.extensions.canHandleBlockchain
import com.tangem.domain.common.extensions.canHandleToken
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.supportedTokens
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.tap.common.extensions.fullNameWithoutTestnet
import com.tangem.tap.common.extensions.getGreyedOutIconRes
@ -24,6 +25,7 @@ import com.tangem.tap.common.extensions.getNetworkName
import com.tangem.tap.features.tokens.impl.domain.TokensListInteractor
import com.tangem.tap.features.tokens.impl.domain.models.Token
import com.tangem.tap.features.tokens.impl.domain.models.Token.Network
import com.tangem.tap.features.tokens.impl.presentation.models.SupportTokensState
import com.tangem.tap.features.tokens.impl.presentation.models.TokensListArgs
import com.tangem.tap.features.tokens.impl.presentation.router.TokensListRouter
import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState
@ -42,6 +44,7 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.plus
import timber.log.Timber
import javax.inject.Inject
import com.tangem.blockchain.common.Token as BlockchainToken
@ -355,24 +358,38 @@ internal class TokensListViewModel @Inject constructor(
toggledNetwork.changeToggleState()
}
} else {
if (isUnsupportedToken(token.blockchain)) {
router.openUnsupportedNetworkAlert(token.blockchain)
} else {
analyticsSender.sendWhenTokenAdded(token.token)
changedTokensList.add(token)
toggledNetwork.changeToggleState()
when (isUnsupportedToken(token.blockchain)) {
SupportTokensState.SolanaNetworkUnsupported -> router.openSolanaTokensNotSupportAlert()
SupportTokensState.SupportedToken -> {
analyticsSender.sendWhenTokenAdded(token.token)
changedTokensList.add(token)
toggledNetwork.changeToggleState()
}
SupportTokensState.UnsupportedCurve -> router.openUnsupportedNetworkAlert(token.blockchain)
null -> Timber.e("Something went wrong in isUnsupportedToken (no scanResponse found)")
}
}
}
}
private fun isUnsupportedToken(blockchain: Blockchain): Boolean {
private fun isUnsupportedToken(blockchain: Blockchain): SupportTokensState? {
val scanResponse = reduxStateHolder.scanResponse
val canHandleToken = scanResponse?.card?.canHandleToken(
val cardTypesResolver = scanResponse?.cardTypesResolver ?: return null
val supportedTokens = scanResponse.card.supportedTokens(cardTypesResolver)
// refactor this later by moving all this logic in card config
if (!supportedTokens.contains(Blockchain.Solana)) {
return SupportTokensState.SolanaNetworkUnsupported
}
val canHandleToken = scanResponse.card.canHandleToken(
supportedTokens = supportedTokens,
blockchain = blockchain,
cardTypesResolver = scanResponse.cardTypesResolver,
) ?: false
return !canHandleToken
cardTypesResolver = cardTypesResolver,
)
if (!canHandleToken) {
return SupportTokensState.UnsupportedCurve
}
return SupportTokensState.SupportedToken
}
private fun isUnsupportedBlockchain(blockchain: Blockchain): Boolean {