Updated on 2026-08-14
This commit is contained in:
commit
d617c9c30d
491 changed files with 15019 additions and 5050 deletions
|
|
@ -10,7 +10,7 @@ import com.tangem.core.navigation.url.UrlOpener
|
|||
import com.tangem.datasource.asset.loader.AssetLoader
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
|
||||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
|
|
@ -76,7 +76,7 @@ interface ApplicationEntryPoint {
|
|||
|
||||
fun getBalanceHidingRepository(): BalanceHidingRepository
|
||||
|
||||
fun getUserTokensStore(): UserTokensStore
|
||||
fun getAppPreferencesStore(): AppPreferencesStore
|
||||
|
||||
fun getGetAppThemeModeUseCase(): GetAppThemeModeUseCase
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import com.tangem.datasource.config.ConfigManager
|
|||
import com.tangem.datasource.config.FeaturesLocalLoader
|
||||
import com.tangem.datasource.config.models.Config
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
|
||||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
|
|
@ -126,8 +126,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
private val balanceHidingRepository: BalanceHidingRepository
|
||||
get() = entryPoint.getBalanceHidingRepository()
|
||||
|
||||
private val userTokensStore: UserTokensStore
|
||||
get() = entryPoint.getUserTokensStore()
|
||||
private val appPreferencesStore: AppPreferencesStore
|
||||
get() = entryPoint.getAppPreferencesStore()
|
||||
|
||||
val getAppThemeModeUseCase: GetAppThemeModeUseCase
|
||||
get() = entryPoint.getGetAppThemeModeUseCase()
|
||||
|
|
@ -228,7 +228,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
}
|
||||
|
||||
derivationsFinder = DerivationsFinder(
|
||||
newTokensStore = userTokensStore,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
dispatchers = AppCoroutineDispatcherProvider(),
|
||||
)
|
||||
appStateHolder.mainStore = store
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.tap.common.analytics.handlers.firebase
|
||||
|
||||
import com.google.firebase.analytics.ktx.analytics
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import com.tangem.core.analytics.AppInstanceIdProvider
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
internal class FirebaseAppInstanceIdProvider : AppInstanceIdProvider {
|
||||
|
||||
override suspend fun getAppInstanceId(): String? = suspendCancellableCoroutine { continuation ->
|
||||
Firebase.analytics.appInstanceId
|
||||
.addOnSuccessListener { continuation.resume(it) }
|
||||
.addOnFailureListener {
|
||||
Timber.w("Fail to get appInstanceId")
|
||||
continuation.resume(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAppInstanceIdSync(): String? {
|
||||
return Firebase.analytics.appInstanceId.result
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package com.tangem.tap.di.analytics
|
||||
|
||||
import com.tangem.core.analytics.AppInstanceIdProvider
|
||||
import com.tangem.core.analytics.utils.AnalyticsContextProxy
|
||||
import com.tangem.domain.analytics.ChangeCardAnalyticsContextUseCase
|
||||
import com.tangem.tap.common.analytics.DefaultAnalyticsContextProxy
|
||||
import com.tangem.tap.common.analytics.DefaultChangeCardAnalyticsContextUseCase
|
||||
import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAppInstanceIdProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -23,4 +25,8 @@ internal object AnalyticsModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideAnalyticsContextProxy(): AnalyticsContextProxy = DefaultAnalyticsContextProxy()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAppInstanceIdProvider(): AppInstanceIdProvider = FirebaseAppInstanceIdProvider()
|
||||
}
|
||||
|
|
@ -92,4 +92,12 @@ internal object CardDomainModule {
|
|||
fun provideNetworkHasDerivationUseCase(): NetworkHasDerivationUseCase {
|
||||
return NetworkHasDerivationUseCase()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIsRequiredDerivePublicKeysUseCase(
|
||||
derivationsRepository: DerivationsRepository,
|
||||
): HasMissedDerivationsUseCase {
|
||||
return HasMissedDerivationsUseCase(derivationsRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.managetokens.GetManagedTokensUseCase
|
||||
import com.tangem.domain.card.repository.DerivationsRepository
|
||||
import com.tangem.domain.managetokens.*
|
||||
import com.tangem.domain.managetokens.repository.CustomTokensRepository
|
||||
import com.tangem.domain.managetokens.repository.ManageTokensRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -17,4 +19,66 @@ internal object ManageTokensDomainModule {
|
|||
fun provideGetManageTokensUseCase(manageTokensRepository: ManageTokensRepository): GetManagedTokensUseCase {
|
||||
return GetManagedTokensUseCase(manageTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideValidateTokenFormatUseCase(customTokensRepository: CustomTokensRepository): ValidateTokenFormUseCase {
|
||||
return ValidateTokenFormUseCase(customTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideCreateCurrencyUseCase(customTokensRepository: CustomTokensRepository): CreateCurrencyUseCase {
|
||||
return CreateCurrencyUseCase(customTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFindTokenUseCase(customTokensRepository: CustomTokensRepository): FindTokenUseCase {
|
||||
return FindTokenUseCase(customTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideCheckIsCurrencyNotAddedUseCase(
|
||||
customTokensRepository: CustomTokensRepository,
|
||||
): CheckIsCurrencyNotAddedUseCase {
|
||||
return CheckIsCurrencyNotAddedUseCase(customTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRemoveCustomManagedCryptoCurrencyUseCase(
|
||||
customTokensRepository: CustomTokensRepository,
|
||||
): RemoveCustomManagedCryptoCurrencyUseCase {
|
||||
return RemoveCustomManagedCryptoCurrencyUseCase(customTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSaveManagedTokensUseCase(
|
||||
manageTokensRepository: ManageTokensRepository,
|
||||
derivationsRepository: DerivationsRepository,
|
||||
): SaveManagedTokensUseCase {
|
||||
return SaveManagedTokensUseCase(
|
||||
manageTokensRepository = manageTokensRepository,
|
||||
derivationsRepository = derivationsRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetSupportedNetworksUseCase(
|
||||
customTokensRepository: CustomTokensRepository,
|
||||
): GetSupportedNetworksUseCase {
|
||||
return GetSupportedNetworksUseCase(customTokensRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideValidateDerivationPathUseCase(
|
||||
customTokensRepository: CustomTokensRepository,
|
||||
): ValidateDerivationPathUseCase {
|
||||
return ValidateDerivationPathUseCase(customTokensRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.markets.GetMarketsTokenListFlowUseCase
|
||||
import com.tangem.domain.markets.GetTokenMarketInfoUseCase
|
||||
import com.tangem.domain.markets.GetTokenPriceChartUseCase
|
||||
import com.tangem.domain.markets.GetTokenQuotesUseCase
|
||||
import com.tangem.domain.markets.*
|
||||
import com.tangem.domain.markets.repositories.MarketsTokenRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -37,7 +35,13 @@ object MarketsDomainModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetTokenQuotesUseCase(marketsTokenRepository: MarketsTokenRepository): GetTokenQuotesUseCase {
|
||||
return GetTokenQuotesUseCase(marketsTokenRepository = marketsTokenRepository)
|
||||
fun provideTokenFullQuotesUseCase(marketsTokenRepository: MarketsTokenRepository): GetTokenFullQuotesUseCase {
|
||||
return GetTokenFullQuotesUseCase(marketsTokenRepository = marketsTokenRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetTokenQuotesUseCase(quotesRepository: QuotesRepository): GetCurrencyQuotesUseCase {
|
||||
return GetCurrencyQuotesUseCase(quotesRepository = quotesRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -145,18 +145,6 @@ internal object StakingDomainModule {
|
|||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIsStakeMoreAvailableUseCase(
|
||||
stakingRepository: StakingRepository,
|
||||
stakingErrorResolver: StakingErrorResolver,
|
||||
): IsStakeMoreAvailableUseCase {
|
||||
return IsStakeMoreAvailableUseCase(
|
||||
stakingRepository = stakingRepository,
|
||||
stakingErrorResolver = stakingErrorResolver,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIsApproveNeededUseCase(
|
||||
|
|
|
|||
|
|
@ -104,6 +104,22 @@ internal object TokensDomainModule {
|
|||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetAllWalletsCryptoCurrencyStatusesUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
): GetAllWalletsCryptoCurrencyStatusesUseCase {
|
||||
return GetAllWalletsCryptoCurrencyStatusesUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCurrencyWarningsUseCase(
|
||||
|
|
@ -158,8 +174,9 @@ internal object TokensDomainModule {
|
|||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
): FetchCurrencyStatusUseCase {
|
||||
return FetchCurrencyStatusUseCase(currenciesRepository, networksRepository, quotesRepository)
|
||||
return FetchCurrencyStatusUseCase(currenciesRepository, networksRepository, quotesRepository, stakingRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -419,4 +436,10 @@ internal object TokensDomainModule {
|
|||
fun provideCheckHasLinkedTokensUseCase(currenciesRepository: CurrenciesRepository): CheckHasLinkedTokensUseCase {
|
||||
return CheckHasLinkedTokensUseCase(currenciesRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCurrencyCheckUseCase(currencyChecksRepository: CurrencyChecksRepository): GetCurrencyCheckUseCase {
|
||||
return GetCurrencyCheckUseCase(currencyChecksRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,21 @@ internal object TransactionDomainModule {
|
|||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSendMultipleTransactionUseCase(
|
||||
cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
transactionRepository: TransactionRepository,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
): SendMultipleTransactionUseCase {
|
||||
return SendMultipleTransactionUseCase(
|
||||
demoConfig = DemoConfig(),
|
||||
cardSdkConfigRepository = cardSdkConfigRepository,
|
||||
transactionRepository = transactionRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAssociateAssetUseCase(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.tap.domain.card
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
|
@ -8,10 +10,13 @@ import com.tangem.common.doOnSuccess
|
|||
import com.tangem.common.extensions.ByteArrayKey
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.data.common.currency.getNetwork
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.card.repository.DerivationsRepository
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
|
|
@ -30,6 +35,10 @@ internal class DefaultDerivationsRepository(
|
|||
) : DerivationsRepository {
|
||||
|
||||
override suspend fun derivePublicKeys(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) {
|
||||
derivePublicKeysByNetworks(userWalletId = userWalletId, networks = currencies.map(CryptoCurrency::network))
|
||||
}
|
||||
|
||||
override suspend fun derivePublicKeysByNetworks(userWalletId: UserWalletId, networks: List<Network>) {
|
||||
val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found")
|
||||
|
||||
if (!userWallet.scanResponse.card.settings.isHDWalletAllowed) {
|
||||
|
|
@ -38,7 +47,7 @@ internal class DefaultDerivationsRepository(
|
|||
}
|
||||
|
||||
val derivations = MissedDerivationsFinder(scanResponse = userWallet.scanResponse)
|
||||
.find(currencies)
|
||||
.findByNetworks(networks)
|
||||
.ifEmpty {
|
||||
Timber.d("Nothing to derive")
|
||||
return
|
||||
|
|
@ -47,6 +56,26 @@ internal class DefaultDerivationsRepository(
|
|||
derivePublicKeys(userWalletId = userWalletId, derivations = derivations)
|
||||
}
|
||||
|
||||
override suspend fun hasMissedDerivations(
|
||||
userWalletId: UserWalletId,
|
||||
networksWithDerivationPath: Map<Network.ID, String?>,
|
||||
): Boolean {
|
||||
val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found")
|
||||
|
||||
val derivations = MissedDerivationsFinder(scanResponse = userWallet.scanResponse)
|
||||
.findByNetworks(
|
||||
networksWithDerivationPath.mapNotNull { (networkId, extraDerivationPath) ->
|
||||
getNetwork(
|
||||
blockchain = Blockchain.fromNetworkId(networkId.value) ?: return@mapNotNull null,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
return derivations.isNotEmpty()
|
||||
}
|
||||
|
||||
override suspend fun derivePublicKeys(userWalletId: UserWalletId, derivations: Derivations): DerivedKeys {
|
||||
tangemSdkManager.derivePublicKeys(cardId = null, derivations = derivations)
|
||||
.doOnSuccess { response ->
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.common.util.derivationStyleProvider
|
|||
import com.tangem.domain.models.scan.KeyWalletPublicKey
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
|
||||
private typealias DerivationData = Pair<ByteArrayKey, List<DerivationPath>>
|
||||
|
|
@ -26,8 +27,12 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) {
|
|||
|
||||
/** Find missed derivations for given currencies [currencies] */
|
||||
fun find(currencies: List<CryptoCurrency>): Derivations {
|
||||
return currencies.map { it.network }.let(::findByNetworks)
|
||||
}
|
||||
|
||||
fun findByNetworks(networks: List<Network>): Derivations {
|
||||
return buildMap<ByteArrayKey, MutableList<DerivationPath>> {
|
||||
currencies
|
||||
networks
|
||||
.mapToNewDerivations()
|
||||
.forEach { data ->
|
||||
val current = this[data.first]
|
||||
|
|
@ -41,25 +46,25 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun List<CryptoCurrency>.mapToNewDerivations(): List<DerivationData> {
|
||||
private fun List<Network>.mapToNewDerivations(): List<DerivationData> {
|
||||
val config = CardConfig.createConfig(scanResponse.card)
|
||||
return mapNotNull { currency ->
|
||||
val blockchain = Blockchain.fromId(id = currency.network.id.value)
|
||||
return mapNotNull { network ->
|
||||
val blockchain = Blockchain.fromId(id = network.id.value)
|
||||
val curve = config.primaryCurve(blockchain) ?: return@mapNotNull null
|
||||
|
||||
findNewDerivations(curve = curve, scanResponse = scanResponse, currency = currency)
|
||||
findNewDerivations(curve = curve, scanResponse = scanResponse, network = network)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findNewDerivations(
|
||||
curve: EllipticCurve,
|
||||
scanResponse: ScanResponse,
|
||||
currency: CryptoCurrency,
|
||||
network: Network,
|
||||
): DerivationData? {
|
||||
val wallet = scanResponse.card.wallets.firstOrNull { it.curve == curve } ?: return null
|
||||
val publicKey = wallet.publicKey.toMapKey()
|
||||
|
||||
val derivationCandidates = currency
|
||||
val derivationCandidates = network
|
||||
.getDerivationCandidates(curve)
|
||||
.ifEmpty { return null }
|
||||
.filterAlreadyDerivedKeys(publicKey)
|
||||
|
|
@ -68,13 +73,13 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) {
|
|||
return publicKey to derivationCandidates
|
||||
}
|
||||
|
||||
private fun CryptoCurrency.getDerivationCandidates(curve: EllipticCurve): List<DerivationPath> {
|
||||
val blockchain = Blockchain.fromId(id = network.id.value)
|
||||
private fun Network.getDerivationCandidates(curve: EllipticCurve): List<DerivationPath> {
|
||||
val blockchain = Blockchain.fromId(id = this.id.value)
|
||||
|
||||
return buildList {
|
||||
add(blockchain.getDerivationPath(curve = curve))
|
||||
add(blockchain.getCustomDerivationPath(curve = curve, currency = this@getDerivationCandidates))
|
||||
add(blockchain.getCardanoDerivationPathIfNeeded(currency = this@getDerivationCandidates))
|
||||
add(blockchain.getCustomDerivationPath(curve = curve, network = this@getDerivationCandidates))
|
||||
add(blockchain.getCardanoDerivationPathIfNeeded(network = this@getDerivationCandidates))
|
||||
}
|
||||
.filterNotNull()
|
||||
.distinct()
|
||||
|
|
@ -88,17 +93,17 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun Blockchain.getCustomDerivationPath(curve: EllipticCurve, currency: CryptoCurrency): DerivationPath? {
|
||||
private fun Blockchain.getCustomDerivationPath(curve: EllipticCurve, network: Network): DerivationPath? {
|
||||
return if (getSupportedCurves().contains(curve)) {
|
||||
currency.network.derivationPath.value?.let(::DerivationPath)
|
||||
network.derivationPath.value?.let(::DerivationPath)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun Blockchain.getCardanoDerivationPathIfNeeded(currency: CryptoCurrency): DerivationPath? {
|
||||
return if (currency is CryptoCurrency.Coin && this == Blockchain.Cardano) {
|
||||
currency.network.derivationPath.value?.let {
|
||||
private fun Blockchain.getCardanoDerivationPathIfNeeded(network: Network): DerivationPath? {
|
||||
return if (this == Blockchain.Cardano) {
|
||||
network.derivationPath.value?.let {
|
||||
CardanoUtils.extendedDerivationPath(derivationPath = DerivationPath(it))
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -111,6 +111,10 @@ object WalletMockContent : MockContent {
|
|||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
),
|
||||
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
),
|
||||
),
|
||||
extendedPublicKey = ExtendedPublicKey(
|
||||
publicKey = byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
|
||||
|
|
@ -189,6 +193,13 @@ object WalletMockContent : MockContent {
|
|||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.derivation.DerivationStyle
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
|
@ -22,7 +25,7 @@ internal data class BlockchainToDerive(
|
|||
|
||||
// FIXME: May be move to DI, currently unnecessary
|
||||
internal class DerivationsFinder(
|
||||
private val newTokensStore: UserTokensStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
|
|
@ -64,7 +67,9 @@ internal class DerivationsFinder(
|
|||
}
|
||||
|
||||
private suspend fun getBlockchains(userWalletId: UserWalletId): MutableSet<BlockchainToDerive> {
|
||||
val responseTokens = newTokensStore.getSyncOrNull(userWalletId)
|
||||
val responseTokens = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
)
|
||||
?.tokens
|
||||
?: return hashSetOf()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButton
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsDialogsFactory
|
||||
|
|
@ -20,12 +20,12 @@ internal fun SettingsAlertDialog(dialog: Dialog.Alert) {
|
|||
title = dialog.title.resolveReference(),
|
||||
message = dialog.description.resolveReference(),
|
||||
isDismissable = false,
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = dialog.confirmText.resolveReference(),
|
||||
warning = true,
|
||||
onClick = dialog.onConfirm,
|
||||
),
|
||||
dismissButton = DialogButton(
|
||||
dismissButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
onClick = dialog.onDismiss,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import com.tangem.core.ui.components.DialogButton
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.SelectorDialog
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -21,7 +21,7 @@ internal fun SettingsSelectorDialog(dialog: Dialog.Selector) {
|
|||
title = dialog.title.resolveReference(),
|
||||
selectedItemIndex = dialog.selectedItemIndex,
|
||||
items = dialog.items.map { it.resolveReference() }.toImmutableList(),
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(R.string.common_cancel),
|
||||
onClick = dialog.onDismiss,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.common.util.getBackupCardsCount
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
|
|
@ -173,13 +174,7 @@ internal class CardSettingsViewModel @Inject constructor(
|
|||
userWalletId = userWalletId,
|
||||
cardId = card.cardId,
|
||||
isActiveBackupStatus = card.backupStatus?.isActive == true,
|
||||
backupCardsCount = when (val status = card.backupStatus) {
|
||||
is CardDTO.BackupStatus.Active -> status.cardCount
|
||||
is CardDTO.BackupStatus.CardLinked,
|
||||
CardDTO.BackupStatus.NoBackup,
|
||||
null,
|
||||
-> 0
|
||||
},
|
||||
backupCardsCount = scanResponse.getBackupCardsCount() ?: 0,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,11 +190,11 @@ private fun CommonResetDialog(dialog: ResetCardScreenState.Dialog) {
|
|||
BasicDialog(
|
||||
title = stringResource(dialog.titleResId),
|
||||
message = stringResource(dialog.messageResId),
|
||||
dismissButton = DialogButton(
|
||||
dismissButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
onClick = dialog.onDismiss,
|
||||
),
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.card_settings_action_sheet_reset),
|
||||
warning = true,
|
||||
onClick = dialog.onConfirmClick,
|
||||
|
|
@ -208,7 +208,7 @@ private fun CompletedResetDialog(dialog: ResetCardDialog) {
|
|||
BasicDialog(
|
||||
title = stringResource(id = dialog.titleResId),
|
||||
message = stringResource(id = dialog.messageResId),
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
onClick = dialog.onConfirmClick,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ internal class HomeFragment : ComposeFragment(), StoreSubscriber<HomeState> {
|
|||
viewModel.onSearchClick()
|
||||
} else {
|
||||
Analytics.send(IntroductionProcess.ButtonTokensList())
|
||||
store.dispatchNavigationAction { push(AppRoute.ManageTokens(readOnlyContent = true)) }
|
||||
store.dispatchNavigationAction { push(AppRoute.ManageTokens()) }
|
||||
store.dispatch(TokensAction.SetArgs.ReadAccess)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ internal class HomeViewModel @Inject constructor(
|
|||
analyticsEventHandler.send(IntroductionProcess.ButtonTokensList())
|
||||
|
||||
store.dispatch(TokensAction.SetArgs.ReadAccess)
|
||||
store.dispatchNavigationAction { push(AppRoute.ManageTokens(readOnlyContent = true)) }
|
||||
store.dispatchNavigationAction { push(AppRoute.ManageTokens()) }
|
||||
}
|
||||
|
||||
private fun scanCard() {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButton
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
|
||||
@Composable
|
||||
|
|
@ -19,11 +19,11 @@ fun EnrollBiometricsDialogContent(dialog: EnrollBiometricsDialog) {
|
|||
BasicDialog(
|
||||
title = stringResource(R.string.save_user_wallet_agreement_enroll_biometrics_title),
|
||||
message = stringResource(R.string.save_user_wallet_agreement_enroll_biometrics_description),
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(R.string.common_enable),
|
||||
onClick = dialog.onEnroll,
|
||||
),
|
||||
dismissButton = DialogButton(
|
||||
dismissButton = DialogButtonUM(
|
||||
onClick = dialog.onCancel,
|
||||
),
|
||||
onDismissDialog = dialog.onCancel,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
|
|
@ -48,12 +47,6 @@ object TradeCryptoMiddleware {
|
|||
is TradeCryptoAction.FinishSelling -> openReceiptUrl(action.transactionId)
|
||||
is TradeCryptoAction.Buy -> proceedBuyAction(state, action)
|
||||
is TradeCryptoAction.Sell -> proceedSellAction(action)
|
||||
is TradeCryptoAction.Swap -> openSwap(currency = action.cryptoCurrency)
|
||||
is TradeCryptoAction.Stake -> openStaking(
|
||||
userWalletId = action.userWalletId,
|
||||
cryptoCurrencyId = action.cryptoCurrencyId,
|
||||
yield = action.yield,
|
||||
)
|
||||
is TradeCryptoAction.SendToken -> handleNewSendToken(action = action)
|
||||
is TradeCryptoAction.SendCoin -> handleNewSendCoin(action = action)
|
||||
}
|
||||
|
|
@ -141,22 +134,6 @@ object TradeCryptoMiddleware {
|
|||
)?.let { store.dispatchOpenUrl(it) }
|
||||
}
|
||||
|
||||
private fun openSwap(currency: CryptoCurrency) {
|
||||
store.dispatchNavigationAction { push(AppRoute.Swap(currency = currency)) }
|
||||
}
|
||||
|
||||
private fun openStaking(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID, yield: Yield) {
|
||||
store.dispatchNavigationAction {
|
||||
push(
|
||||
AppRoute.Staking(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrencyId,
|
||||
yield = yield,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNewSendToken(action: TradeCryptoAction.SendToken) {
|
||||
handleNewSend(
|
||||
userWalletId = action.userWallet.walletId,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButton
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.welcome.ui.model.WarningModel
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -27,7 +27,7 @@ internal fun WarningDialog(warning: WarningModel?) {
|
|||
},
|
||||
),
|
||||
onDismissDialog = warning.onDismiss,
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
onClick = warning.onDismiss,
|
||||
),
|
||||
|
|
@ -38,7 +38,7 @@ internal fun WarningDialog(warning: WarningModel?) {
|
|||
title = stringResource(id = R.string.common_attention),
|
||||
message = stringResource(id = R.string.key_invalidated_warning_description),
|
||||
onDismissDialog = warning.onDismiss,
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
onClick = warning.onDismiss,
|
||||
),
|
||||
|
|
@ -50,7 +50,7 @@ internal fun WarningDialog(warning: WarningModel?) {
|
|||
message = stringResource(id = R.string.biometric_unavailable_warning),
|
||||
onDismissDialog = warning.onDismiss,
|
||||
isDismissable = false,
|
||||
confirmButton = DialogButton(
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
onClick = warning.onDismiss,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.features.details.component.DetailsComponent
|
|||
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
||||
import com.tangem.features.managetokens.ManageTokensToggles
|
||||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
||||
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
|
||||
import com.tangem.features.send.api.navigation.SendRouter
|
||||
|
|
@ -50,6 +51,7 @@ internal class ChildFactory @Inject constructor(
|
|||
private val walletSettingsComponentFactory: WalletSettingsComponent.Factory,
|
||||
private val disclaimerComponentFactory: DisclaimerComponent.Factory,
|
||||
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
|
||||
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
||||
private val sendRouter: SendRouter,
|
||||
private val tokenDetailsRouter: TokenDetailsRouter,
|
||||
private val walletRouter: WalletRouter,
|
||||
|
|
@ -126,13 +128,7 @@ internal class ChildFactory @Inject constructor(
|
|||
if (manageTokensToggles.isFeatureEnabled) {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = ManageTokensComponent.Params(
|
||||
mode = if (route.readOnlyContent) {
|
||||
ManageTokensComponent.Mode.READ_ONLY
|
||||
} else {
|
||||
ManageTokensComponent.Mode.MANAGE
|
||||
},
|
||||
),
|
||||
params = ManageTokensComponent.Params(route.userWalletId),
|
||||
componentFactory = manageTokensComponentFactory,
|
||||
)
|
||||
} else {
|
||||
|
|
@ -191,6 +187,16 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = walletSettingsComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.MarketsTokenDetails -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = MarketsTokenDetailsComponent.Params(
|
||||
token = route.token,
|
||||
appCurrency = route.appCurrency,
|
||||
),
|
||||
componentFactory = marketsTokenDetailsComponentFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue