Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-21 13:53:31 +03:00
commit 1774402319
11 changed files with 38 additions and 29 deletions

BIN
app/libs/rekotlin-1.0.4.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -5,7 +5,7 @@
},
{
"name": "LOCAL_USER_LOGS_ENABLED",
"version": "5.13.0"
"version": "undefined"
},
{
"name": "GENERATE_XPUB_ENABLED",

View file

@ -60,6 +60,7 @@ internal class QuotesUnsupportedCurrenciesIdAdapter {
Blockchain.Aurora.toCoinId() to ethCoinId,
Blockchain.Base.toCoinId() to ethCoinId,
Blockchain.Blast.toCoinId() to ethCoinId,
Blockchain.Cyber.toCoinId() to ethCoinId,
)
}
}

View file

@ -69,6 +69,20 @@ class GetExtendedPublicKeyForCurrencyUseCase(
}
}
/**
* @return true if xpub generation is supported, false otherwise
*/
suspend fun isSupported(userWalletId: UserWalletId, network: Network): Boolean {
val userWallet = walletManagersFacade.getOrCreateWalletManager(userWalletId, network)
?: error("Wallet not found")
val blockchain = Blockchain.fromId(network.id.value)
val isSecp256k1Blockchain = Blockchain.secp256k1Blockchains(network.isTestnet).contains(blockchain)
val isHdKey = userWallet.wallet.publicKey.derivationType?.hdKey
return isSecp256k1Blockchain && isHdKey != null
}
private suspend fun deriveKeys(
userWalletId: UserWalletId,
seedKey: ByteArray,

View file

@ -66,5 +66,6 @@ dependencies {
/* Other */
implementation(deps.kotlin.immutable.collections)
implementation(deps.reKotlin)
implementation(deps.timber)
}

View file

@ -5,9 +5,8 @@ import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.domain.feedback.FeedbackManager
import com.tangem.domain.feedback.GetCardInfoUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.redux.LegacyAction
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.walletconnect.CheckIsWalletConnectAvailableUseCase
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.features.details.component.DetailsComponent
@ -31,15 +30,14 @@ import javax.inject.Inject
@ComponentScoped
@Suppress("LongParameterList")
internal class DetailsModel @Inject constructor(
private val socialsBuilder: SocialsBuilder,
socialsBuilder: SocialsBuilder,
private val itemsBuilder: ItemsBuilder,
private val appVersionProvider: AppVersionProvider,
private val checkIsWalletConnectAvailableUseCase: CheckIsWalletConnectAvailableUseCase,
private val router: Router,
private val paramsContainer: ParamsContainer,
paramsContainer: ParamsContainer,
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
private val getCardInfoUseCase: GetCardInfoUseCase,
private val feedbackManager: FeedbackManager,
private val appStateHolder: ReduxStateHolder,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
@ -84,18 +82,13 @@ internal class DetailsModel @Inject constructor(
val scanResponse = getSelectedWalletSyncUseCase().getOrNull()?.scanResponse
?: error("Selected wallet is null")
val cardInfo = getCardInfoUseCase(scanResponse = scanResponse).getOrNull()
?: error("CardInfo must be not null")
feedbackManager.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo))
appStateHolder.dispatch(LegacyAction.SendEmailSupport(scanResponse))
}
}
private suspend fun updateState(items: ImmutableList<DetailsItemUM>) {
private fun updateState(items: ImmutableList<DetailsItemUM>) {
state.update { prevState ->
prevState.copy(
items = items,
)
prevState.copy(items = items)
}
}

View file

@ -29,9 +29,9 @@ import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.feature.tokendetails.presentation.tokendetails.state.SwapTransactionsState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBalanceSegmentedButtonConfig
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsAppBarMenuConfig
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadedTxHistoryConverter
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadingTxHistoryConverter
@ -366,13 +366,13 @@ internal class TokenDetailsStateFactory(
fun getStateWithUpdatedMenu(
cardTypesResolver: CardTypesResolver,
hasDerivations: Boolean,
isBitcoin: Boolean,
isSupported: Boolean,
): TokenDetailsState {
return with(currentStateProvider()) {
copy(
topAppBarConfig = topAppBarConfig.copy(
tokenDetailsAppBarMenuConfig = topAppBarConfig.tokenDetailsAppBarMenuConfig
?.updateMenu(cardTypesResolver, hasDerivations, isBitcoin),
?.updateMenu(cardTypesResolver, hasDerivations, isSupported),
),
)
}
@ -387,10 +387,10 @@ internal class TokenDetailsStateFactory(
private fun TokenDetailsAppBarMenuConfig.updateMenu(
cardTypesResolver: CardTypesResolver,
hasDerivations: Boolean,
isBitcoin: Boolean,
isSupported: Boolean,
): TokenDetailsAppBarMenuConfig? {
if (cardTypesResolver.isSingleWalletWithToken()) return null
val showGenerateExtendedKey = featureToggles.isGenerateXPubEnabled() && isBitcoin
val showGenerateExtendedKey = featureToggles.isGenerateXPubEnabled() && isSupported
return copy(
items = buildList {
if (showGenerateExtendedKey && hasDerivations) {

View file

@ -72,7 +72,6 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.e
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
import com.tangem.features.tokendetails.featuretoggles.TokenDetailsFeatureToggles
import com.tangem.features.tokendetails.impl.R
import com.tangem.lib.crypto.BlockchainUtils.isBitcoin
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import dagger.hilt.android.lifecycle.HiltViewModel
@ -123,7 +122,7 @@ internal class TokenDetailsViewModel @Inject constructor(
private val analyticsEventsHandler: AnalyticsEventHandler,
private val vibratorHapticManager: VibratorHapticManager,
private val clipboardManager: ClipboardManager,
private val getUserWalletUseCase: GetUserWalletUseCase,
getUserWalletUseCase: GetUserWalletUseCase,
tokenDetailsFeatureToggles: TokenDetailsFeatureToggles,
deepLinksRegistry: DeepLinksRegistry,
savedStateHandle: SavedStateHandle,
@ -412,10 +411,13 @@ internal class TokenDetailsViewModel @Inject constructor(
viewModelScope.launch(dispatchers.main) {
val hasDerivations =
networkHasDerivationUseCase(userWallet.scanResponse, cryptoCurrency.network).getOrElse { false }
val isSupported = getExtendedPublicKeyForCurrencyUseCase.isSupported(userWalletId, cryptoCurrency.network)
internalUiState.value = stateFactory.getStateWithUpdatedMenu(
cardTypesResolver = userWallet.scanResponse.cardTypesResolver,
hasDerivations = hasDerivations,
isBitcoin = isBitcoin(cryptoCurrency.network.id.value),
isSupported = isSupported,
)
}
}

View file

@ -24,6 +24,9 @@ dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
flatDir {
dirs("app/libs")
}
google {
content {
includeGroupAndSubgroups("androidx")
@ -92,11 +95,6 @@ dependencyResolutionManagement {
includeGroupAndSubgroups("com.tangem.vico")
}
}
jcenter { // unable to replace with mavenCentral() due to rekotlin
content {
includeModule("org.rekotlin", "rekotlin")
}
}
maven("https://jitpack.io")
maven("https://clients-nexus.sprinklr.com/")
}