diff --git a/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt b/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt deleted file mode 100644 index 788367340b..0000000000 --- a/app/src/main/java/com/tangem/tap/di/data/CardDataModule.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.tangem.tap.di.data - -import com.tangem.data.common.network.NetworkFactory -import com.tangem.datasource.local.userwallet.UserWalletsStore -import com.tangem.domain.card.repository.DerivationsRepository -import com.tangem.sdk.api.TangemSdkManager -import com.tangem.tap.domain.card.DefaultDerivationsRepository -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal object CardDataModule { - - @Singleton - @Provides - fun providesDerivationsRepository( - tangemSdkManager: TangemSdkManager, - userWalletsStore: UserWalletsStore, - networkFactory: NetworkFactory, - dispatchers: CoroutineDispatcherProvider, - ): DerivationsRepository { - return DefaultDerivationsRepository( - tangemSdkManager = tangemSdkManager, - userWalletsStore = userWalletsStore, - networkFactory = networkFactory, - dispatchers = dispatchers, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt index fc0942279a..0aa400353e 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt @@ -2,11 +2,14 @@ package com.tangem.tap.di.domain import com.tangem.domain.card.* import com.tangem.domain.card.repository.CardRepository -import com.tangem.domain.card.repository.DerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager +import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase +import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase +import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase import com.tangem.sdk.api.TangemSdkManager diff --git a/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt index 0db474821f..89bd3b4ca9 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/ManageTokensDomainModule.kt @@ -1,6 +1,6 @@ package com.tangem.tap.di.domain -import com.tangem.domain.card.repository.DerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository import com.tangem.domain.managetokens.* import com.tangem.domain.managetokens.repository.CustomTokensRepository import com.tangem.domain.managetokens.repository.ManageTokensRepository diff --git a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt index 71f6985831..1bb8a1ec1c 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt @@ -1,7 +1,7 @@ package com.tangem.tap.di.domain import com.tangem.blockchainsdk.utils.ExcludedBlockchains -import com.tangem.domain.card.repository.DerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository import com.tangem.domain.markets.* import com.tangem.domain.markets.repositories.MarketsTokenRepository import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher diff --git a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt index eb56a8d16c..3538d33584 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt @@ -1,5 +1,6 @@ package com.tangem.tap.di.domain +import com.tangem.data.wallets.hot.TangemHotWalletSigner import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.networks.single.SingleNetworkStatusFetcher @@ -11,7 +12,6 @@ import com.tangem.domain.transaction.FeeRepository import com.tangem.domain.transaction.TransactionRepository import com.tangem.domain.transaction.usecase.* import com.tangem.domain.walletmanager.WalletManagersFacade -import com.tangem.tap.domain.hot.TangemHotWalletSigner import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/app/src/main/java/com/tangem/tap/di/hot/TangemHotSdkModule.kt b/app/src/main/java/com/tangem/tap/di/hot/TangemHotSdkModule.kt index f68e642f94..c21b55928b 100644 --- a/app/src/main/java/com/tangem/tap/di/hot/TangemHotSdkModule.kt +++ b/app/src/main/java/com/tangem/tap/di/hot/TangemHotSdkModule.kt @@ -1,8 +1,6 @@ package com.tangem.tap.di.hot import com.tangem.hot.sdk.TangemHotSdk -import com.tangem.tap.domain.hot.HotWalletPasswordRequester -import com.tangem.tap.features.hot.DefaultHotWalletPasswordRequester import com.tangem.tap.features.hot.TangemHotSDKProxy import dagger.Binds import dagger.Module @@ -17,8 +15,4 @@ internal interface TangemHotSdkModule { @Binds @Singleton fun bindTangemHotSdk(proxy: TangemHotSDKProxy): TangemHotSdk - - @Binds - @Singleton - fun bindHotWalletPasswordRequester(impl: DefaultHotWalletPasswordRequester): HotWalletPasswordRequester } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/hot/HotWalletPasswordRequester.kt b/app/src/main/java/com/tangem/tap/domain/hot/HotWalletPasswordRequester.kt deleted file mode 100644 index 1f80fd785f..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/hot/HotWalletPasswordRequester.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.tap.domain.hot - -import com.tangem.hot.sdk.model.HotAuth -import com.tangem.hot.sdk.model.HotWalletId - -interface HotWalletPasswordRequester { - - suspend fun requestPassword(hotWalletId: HotWalletId): HotAuth.Password -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/hot/TangemHotSigner.kt b/app/src/main/java/com/tangem/tap/domain/hot/TangemHotSigner.kt deleted file mode 100644 index 0b71ca974c..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/hot/TangemHotSigner.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.tangem.tap.domain.hot - -import com.tangem.blockchain.common.TransactionSigner -import com.tangem.blockchain.common.Wallet -import com.tangem.common.CompletionResult -import com.tangem.common.core.TangemSdkError -import com.tangem.common.map -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.hot.sdk.model.DataToSign -import com.tangem.operations.sign.SignData -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject - -class TangemHotSigner @AssistedInject constructor( - @Assisted private val userWallet: UserWallet.Hot, - private val hotWalletAccessor: HotWalletAccessor, -) : TransactionSigner { - - override suspend fun sign(hash: ByteArray, publicKey: Wallet.PublicKey): CompletionResult { - return sign(listOf(hash), publicKey).map { it.first() } - } - - override suspend fun sign( - hashes: List, - publicKey: Wallet.PublicKey, - ): CompletionResult> { - val wallet = userWallet.wallets.orEmpty().firstOrNull { it.publicKey == publicKey.seedKey } - ?: return CompletionResult.Failure( - TangemSdkError.ExceptionError(IllegalStateException("wallet is locked")), - ) - - val result = hotWalletAccessor.signHashes( - hotWalletId = userWallet.hotWalletId, - dataToSign = listOf( - DataToSign( - curve = wallet.curve, - hashes = hashes, - derivationPath = publicKey.derivationPath, - ), - ), - ) - - return CompletionResult.Success(result.map { it.signatures }.flatten()) - } - - override suspend fun multiSign( - dataToSign: List, - publicKey: Wallet.PublicKey, - ): CompletionResult> { - val result = hotWalletAccessor.signHashes( - hotWalletId = userWallet.hotWalletId, - dataToSign = dataToSign.map { signData -> - val wallet = userWallet.wallets.orEmpty().firstOrNull { it.publicKey == signData.publicKey } - ?: return CompletionResult.Failure( - TangemSdkError.ExceptionError(IllegalStateException("wallet is locked")), - ) - - DataToSign( - curve = wallet.curve, - hashes = listOf(signData.hash), - derivationPath = signData.derivationPath, - ) - }, - ) - - return CompletionResult.Success( - result.mapIndexed { index, data -> - dataToSign[index].publicKey to data.signatures.first() - }.toMap(), - ) - } - - @AssistedFactory - interface Factory { - fun create(@Assisted userWallet: UserWallet.Hot): TangemHotSigner - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt index 83c7a9c1fb..aaf4f87888 100644 --- a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt @@ -20,7 +20,7 @@ import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.card.common.util.cardTypesResolver -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWalletId diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt index acd5a2e14a..fba95394c0 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt @@ -14,7 +14,7 @@ import com.tangem.common.map import com.tangem.crypto.bip39.Mnemonic import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.card.CardTypesResolver -import com.tangem.domain.card.DerivationStyleProvider +import com.tangem.domain.wallets.derivations.DerivationStyleProvider import com.tangem.domain.card.common.TapWorkarounds.isTestCard import com.tangem.domain.card.configs.CardConfig import com.tangem.domain.models.scan.CardDTO diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/DerivationsFinder.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/DerivationsFinder.kt index 6e6a912b0d..fa255fdacb 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/DerivationsFinder.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/DerivationsFinder.kt @@ -6,7 +6,7 @@ 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.UserTokensResponseStore -import com.tangem.domain.card.DerivationStyleProvider +import com.tangem.domain.wallets.derivations.DerivationStyleProvider import com.tangem.domain.card.common.TapWorkarounds.useOldStyleDerivation import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.wallet.UserWalletId diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt index 90275890f2..df05ce2f7e 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt @@ -14,14 +14,14 @@ import com.tangem.common.tlv.Tlv import com.tangem.common.tlv.TlvDecoder import com.tangem.crypto.CryptoUtils import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.card.DerivationStyleProvider +import com.tangem.domain.wallets.derivations.DerivationStyleProvider import com.tangem.domain.card.common.TapWorkarounds.isExcluded import com.tangem.domain.card.common.TapWorkarounds.isNotSupportedInThatRelease import com.tangem.domain.card.common.TapWorkarounds.isStart2Coin import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins import com.tangem.domain.card.common.TapWorkarounds.isVisa import com.tangem.domain.common.TwinsHelper -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.domain.card.common.visa.VisaUtilities import com.tangem.domain.card.configs.CardConfig import com.tangem.domain.models.scan.CardDTO diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCustomerWalletApproveTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCustomerWalletApproveTask.kt index 3ef65f5c16..a44a04e051 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCustomerWalletApproveTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCustomerWalletApproveTask.kt @@ -16,7 +16,7 @@ import com.tangem.common.extensions.toHexString import com.tangem.core.error.ext.tangemError import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.domain.card.common.visa.VisaUtilities import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility.findKeyWithoutDerivation diff --git a/app/src/main/java/com/tangem/tap/features/hot/DefaultHotWalletPasswordRequester.kt b/app/src/main/java/com/tangem/tap/features/hot/DefaultHotWalletPasswordRequester.kt deleted file mode 100644 index b9d1c6ae6c..0000000000 --- a/app/src/main/java/com/tangem/tap/features/hot/DefaultHotWalletPasswordRequester.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.tap.features.hot - -import com.tangem.hot.sdk.model.HotAuth -import com.tangem.hot.sdk.model.HotWalletId -import com.tangem.tap.domain.hot.HotWalletPasswordRequester -import javax.inject.Inject - -class DefaultHotWalletPasswordRequester @Inject constructor() : HotWalletPasswordRequester { - - override suspend fun requestPassword(hotWalletId: HotWalletId): HotAuth.Password { - return HotAuth.Password("TODO [REDACTED_TASK_KEY]".toCharArray()) // TODO [REDACTED_TASK_KEY] - } -} \ No newline at end of file diff --git a/common/test/src/main/java/com/tangem/common/test/domain/token/MockCryptoCurrencyFactory.kt b/common/test/src/main/java/com/tangem/common/test/domain/token/MockCryptoCurrencyFactory.kt index efba92dc00..ee2579d3ca 100644 --- a/common/test/src/main/java/com/tangem/common/test/domain/token/MockCryptoCurrencyFactory.kt +++ b/common/test/src/main/java/com/tangem/common/test/domain/token/MockCryptoCurrencyFactory.kt @@ -8,8 +8,8 @@ import com.tangem.blockchainsdk.utils.toNetworkId import com.tangem.common.test.domain.card.MockScanResponseFactory import com.tangem.common.test.domain.wallet.MockUserWalletFactory import com.tangem.data.common.currency.CryptoCurrencyFactory -import com.tangem.domain.card.DerivationStyleProvider -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.DerivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.domain.card.configs.GenericCardConfig import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network diff --git a/data/common/src/main/kotlin/com/tangem/data/common/network/NetworkFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/network/NetworkFactory.kt index bd48e9cea2..e518072440 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/network/NetworkFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/network/NetworkFactory.kt @@ -6,11 +6,11 @@ import com.tangem.blockchain.common.FeePaidCurrency import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.blockchainsdk.utils.toBlockchain import com.tangem.blockchainsdk.utils.toNetworkId -import com.tangem.domain.card.DerivationStyleProvider import com.tangem.domain.card.common.extensions.canHandleToken -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.derivations.DerivationStyleProvider import timber.log.Timber import javax.inject.Inject diff --git a/data/common/src/test/kotlin/com/tangem/data/common/network/NetworkFactoryTest.kt b/data/common/src/test/kotlin/com/tangem/data/common/network/NetworkFactoryTest.kt index 766643ffe0..4cbcb9a0a5 100644 --- a/data/common/src/test/kotlin/com/tangem/data/common/network/NetworkFactoryTest.kt +++ b/data/common/src/test/kotlin/com/tangem/data/common/network/NetworkFactoryTest.kt @@ -7,10 +7,10 @@ import com.tangem.common.test.domain.card.MockScanResponseFactory import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory import com.tangem.common.test.domain.wallet.MockUserWalletFactory import com.tangem.common.test.utils.ProvideTestModels -import com.tangem.domain.card.DerivationStyleProvider +import com.tangem.domain.wallets.derivations.DerivationStyleProvider import com.tangem.domain.card.configs.GenericCardConfig import com.tangem.domain.card.configs.MultiWalletCardConfig -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.domain.models.network.Network import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet diff --git a/data/manage-tokens/build.gradle.kts b/data/manage-tokens/build.gradle.kts index c0da8f1be9..9095c4f1ab 100644 --- a/data/manage-tokens/build.gradle.kts +++ b/data/manage-tokens/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { implementation(projects.domain.models) implementation(projects.domain.manageTokens) implementation(projects.domain.card) + implementation(projects.domain.wallets) implementation(projects.domain.tokens.models) implementation(projects.domain.wallets.models) implementation(projects.domain.legacy) diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt index d311b44167..34beb0198c 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt @@ -22,8 +22,8 @@ import com.tangem.domain.managetokens.model.ManagedCryptoCurrency import com.tangem.domain.managetokens.repository.CustomTokensRepository import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.models.wallet.requireColdWallet import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext @@ -247,26 +247,43 @@ internal class DefaultCustomTokensRepository( val userWallet = requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) { "User wallet [$userWalletId] not found while getting supported networks" } - val scanResponse = userWallet.requireColdWallet().scanResponse // TODO [REDACTED_TASK_KEY] - Blockchain.entries - .mapNotNull { blockchain -> - val canHandleBlockchain = scanResponse.card.canHandleBlockchain( - blockchain, - scanResponse.cardTypesResolver, - excludedBlockchains, - ) + when (userWallet) { + is UserWallet.Hot -> { + Blockchain.entries.mapNotNull { + // TODO: refactor [REDACTED_JIRA]\ + if (it.isTestnet() || it in excludedBlockchains) return@mapNotNull null - if (canHandleBlockchain) { networkFactory.create( - blockchain = blockchain, + blockchain = it, extraDerivationPath = null, userWallet = userWallet, ) - } else { - null } } + is UserWallet.Cold -> { + val scanResponse = userWallet.scanResponse + + Blockchain.entries + .mapNotNull { blockchain -> + val canHandleBlockchain = scanResponse.card.canHandleBlockchain( + blockchain, + scanResponse.cardTypesResolver, + excludedBlockchains, + ) + + if (canHandleBlockchain) { + networkFactory.create( + blockchain = blockchain, + extraDerivationPath = null, + userWallet = userWallet, + ) + } else { + null + } + } + } + } } override fun createDerivationPath(rawPath: String): Network.DerivationPath { diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt index 444a4b5bb6..d785c4e2b6 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt @@ -13,14 +13,14 @@ import com.tangem.data.common.network.NetworkFactory import com.tangem.datasource.api.tangemTech.models.CoinsResponse import com.tangem.datasource.api.tangemTech.models.UserTokensResponse import com.tangem.datasource.local.config.testnet.models.TestnetTokensConfig -import com.tangem.domain.card.DerivationStyleProvider import com.tangem.domain.card.common.extensions.canHandleToken -import com.tangem.domain.card.common.util.derivationStyleProvider import com.tangem.domain.managetokens.model.ManagedCryptoCurrency import com.tangem.domain.managetokens.model.ManagedCryptoCurrency.SourceNetwork import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.derivations.DerivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import timber.log.Timber internal class ManagedCryptoCurrencyFactory( diff --git a/data/visa/build.gradle.kts b/data/visa/build.gradle.kts index 05af092bd5..ff1d5fb9ef 100644 --- a/data/visa/build.gradle.kts +++ b/data/visa/build.gradle.kts @@ -22,6 +22,7 @@ dependencies { /** Project - Domain */ implementation(projects.domain.visa) implementation(projects.domain.card) + implementation(projects.domain.wallets) implementation(projects.domain.models) implementation(projects.domain.wallets.models) implementation(projects.domain.appCurrency.models) diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt index f4a46dab61..829d185c39 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/VisaCurrencyFactory.kt @@ -3,12 +3,11 @@ package com.tangem.data.visa.utils import com.tangem.blockchain.common.Blockchain import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.data.common.network.NetworkFactory -import com.tangem.domain.card.common.util.derivationStyleProvider import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.NetworkAddress import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.requireColdWallet import com.tangem.domain.visa.model.VisaCurrency +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.lib.visa.model.VisaContractInfo import org.joda.time.DateTime import org.joda.time.DateTimeZone @@ -34,7 +33,7 @@ internal class VisaCurrencyFactory @Inject constructor( val currencyNetwork = networkFactory.create( blockchain = Blockchain.Polygon, extraDerivationPath = null, - derivationStyleProvider = userWallet.requireColdWallet().scanResponse.derivationStyleProvider, + derivationStyleProvider = userWallet.derivationStyleProvider, canHandleTokens = true, ) ?: error("Unable to create network for Visa currency") diff --git a/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/WalletManagerFactory.kt b/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/WalletManagerFactory.kt index 01e9213ddc..eff1e685f6 100644 --- a/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/WalletManagerFactory.kt +++ b/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/WalletManagerFactory.kt @@ -7,10 +7,10 @@ import com.tangem.blockchainsdk.BlockchainSDKFactory import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.data.walletmanager.extensions.makePublicKey import com.tangem.data.walletmanager.extensions.makeWalletManagerForApp -import com.tangem.domain.card.DerivationStyleProvider -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.DerivationStyleProvider import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.derivations.derivationStyleProvider import timber.log.Timber internal class WalletManagerFactory( diff --git a/data/wallets/build.gradle.kts b/data/wallets/build.gradle.kts index fc8569a999..f7867f6b5d 100644 --- a/data/wallets/build.gradle.kts +++ b/data/wallets/build.gradle.kts @@ -11,9 +11,14 @@ android { } dependencies { + implementation(projects.data.common) /** Tangem libraries */ - implementation(tangemDeps.blockchain) // android-library + implementation(tangemDeps.blockchain) + implementation(tangemDeps.card.core) + implementation(tangemDeps.hot.core) + implementation(projects.libs.tangemSdkApi) + implementation(projects.libs.blockchainSdk) /** Core */ implementation(projects.core.datasource) @@ -21,6 +26,7 @@ dependencies { /** Domain */ implementation(projects.domain.wallets) + implementation(projects.domain.card) api(projects.domain.models) /** Domain models */ @@ -29,15 +35,17 @@ dependencies { /** DI */ implementation(deps.hilt.android) - implementation(project(":domain:legacy")) kapt(deps.hilt.kapt) /** Other deps */ implementation(deps.androidx.datastore) implementation(deps.arrow.core) + implementation(deps.kotlin.coroutines) + implementation(deps.timber) /** tests */ testImplementation(projects.domain.models) + testImplementation(projects.common.test) testImplementation(deps.test.junit) testImplementation(deps.test.coroutine) testImplementation(deps.test.truth) diff --git a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/cold/DefaultColdMapDerivationsRepository.kt similarity index 56% rename from app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt rename to data/wallets/src/main/java/com/tangem/data/wallets/cold/DefaultColdMapDerivationsRepository.kt index b09a27d4cd..e00bde14e5 100644 --- a/app/src/main/java/com/tangem/tap/domain/card/DefaultDerivationsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/cold/DefaultColdMapDerivationsRepository.kt @@ -1,51 +1,50 @@ -package com.tangem.tap.domain.card +package com.tangem.data.wallets.cold 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 -import com.tangem.common.doOnFailure -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.network.NetworkFactory -import com.tangem.datasource.local.userwallet.UserWalletsStore -import com.tangem.domain.card.BackendId -import com.tangem.domain.card.repository.DerivationsRepository +import com.tangem.data.wallets.derivations.Derivations +import com.tangem.data.wallets.derivations.MissedDerivationsFinder import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.models.wallet.requireColdWallet +import com.tangem.domain.wallets.derivations.ColdMapDerivationsRepository +import com.tangem.domain.wallets.usecase.BackendId import com.tangem.operations.derivation.ExtendedPublicKeysMap import com.tangem.sdk.api.TangemSdkManager -import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import timber.log.Timber +import javax.inject.Inject -internal typealias Derivations = Map> private typealias DerivedKeys = Map -internal class DefaultDerivationsRepository( +internal class DefaultColdMapDerivationsRepository @Inject constructor( private val tangemSdkManager: TangemSdkManager, - private val userWalletsStore: UserWalletsStore, private val networkFactory: NetworkFactory, private val dispatchers: CoroutineDispatcherProvider, -) : DerivationsRepository { +) : ColdMapDerivationsRepository { - override suspend fun derivePublicKeys(userWalletId: UserWalletId, currencies: List) { - derivePublicKeysByNetworks(userWalletId = userWalletId, networks = currencies.map(CryptoCurrency::network)) + override suspend fun derivePublicKeys( + userWallet: UserWallet.Cold, + currencies: List, + ): UserWallet.Cold = withContext(dispatchers.io) { + derivePublicKeysByNetworks(userWallet = userWallet, networks = currencies.map(CryptoCurrency::network)) } - override suspend fun derivePublicKeysByNetworkIds(userWalletId: UserWalletId, networkIds: List) { - val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found") - + override suspend fun derivePublicKeysByNetworkIds( + userWallet: UserWallet.Cold, + networkIds: List, + ): UserWallet.Cold = withContext(dispatchers.io) { derivePublicKeysByNetworks( - userWalletId = userWalletId, + userWallet = userWallet, networks = networkIds.mapNotNull { networkFactory.create( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, @@ -56,44 +55,55 @@ internal class DefaultDerivationsRepository( ) } - override suspend fun derivePublicKeysByNetworks(userWalletId: UserWalletId, networks: List) { - val userWallet = withContext(dispatchers.io) { - userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found") - } - - if (userWallet is UserWallet.Hot) { - return - } - - userWallet.requireColdWallet() - + override suspend fun derivePublicKeysByNetworks( + userWallet: UserWallet.Cold, + networks: List, + ): UserWallet.Cold = withContext(dispatchers.io) { if (!userWallet.scanResponse.card.settings.isHDWalletAllowed) { Timber.d("Nothing to derive") - return + return@withContext userWallet } - val derivations = MissedDerivationsFinder(scanResponse = userWallet.scanResponse) + val derivations = MissedDerivationsFinder(userWallet) .findByNetworks(networks) .ifEmpty { Timber.d("Nothing to derive") - return + return@withContext userWallet } - derivePublicKeys(userWalletId = userWalletId, derivations = derivations) + return@withContext derivePublicKeys(userWallet = userWallet, derivations = derivations).first + } + + override suspend fun derivePublicKeys( + userWallet: UserWallet.Cold, + derivations: Map>, + ): Pair> = withContext(dispatchers.io) { + // todo replace it in task [REDACTED_JIRA] + val preflightReadFilter = UserWalletIdPreflightReadFilter(userWallet.walletId) + val result = tangemSdkManager.derivePublicKeys( + cardId = null, + derivations = derivations, + preflightReadFilter = preflightReadFilter, + ) + + when (result) { + is CompletionResult.Success -> { + userWallet.updateDerivedKeys(result.data.entries).also { + validateDerivations(scanResponse = it.scanResponse, derivations = derivations) + } to result.data.entries + } + is CompletionResult.Failure -> { + throw result.error + } + } } override suspend fun hasMissedDerivations( - userWalletId: UserWalletId, + userWallet: UserWallet.Cold, networksWithDerivationPath: Map, - ): Boolean { - val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found") - - if (userWallet is UserWallet.Hot) { - return false - } - + ): Boolean = withContext(dispatchers.io) { val derivations = - MissedDerivationsFinder(scanResponse = userWallet.requireColdWallet().scanResponse) + MissedDerivationsFinder(userWallet) .findByNetworks( networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) -> networkFactory.create( @@ -104,28 +114,7 @@ internal class DefaultDerivationsRepository( }, ) - return derivations.isNotEmpty() - } - - override suspend fun derivePublicKeys(userWalletId: UserWalletId, derivations: Derivations): DerivedKeys { - // todo replace it in task [REDACTED_JIRA] - val preflightReadFilter = UserWalletIdPreflightReadFilter(userWalletId) - tangemSdkManager.derivePublicKeys( - cardId = null, - derivations = derivations, - preflightReadFilter = preflightReadFilter, - ).doOnSuccess { response -> - updatePublicKeys(userWalletId = userWalletId, keys = response.entries) - .doOnSuccess { - // TODO [REDACTED_TASK_KEY] - validateDerivations(scanResponse = it.requireColdWallet().scanResponse, derivations = derivations) - return response.entries - } - .doOnFailure { throw it } - } - .doOnFailure { throw it } - - error("This code should never be reached") + derivations.isNotEmpty() } /** @@ -144,16 +133,7 @@ internal class DefaultDerivationsRepository( } } - private suspend fun updatePublicKeys(userWalletId: UserWalletId, keys: DerivedKeys): CompletionResult { - return withContext(dispatchers.io) { - userWalletsStore.update( - userWalletId = userWalletId, - update = { userWallet -> userWallet.requireColdWallet().updateDerivedKeys(keys) }, // TODO [REDACTED_TASK_KEY] - ) - } - } - - private fun UserWallet.Cold.updateDerivedKeys(keys: DerivedKeys): UserWallet { + private fun UserWallet.Cold.updateDerivedKeys(keys: DerivedKeys): UserWallet.Cold { return copy( scanResponse = scanResponse.copy( derivedKeys = getUpdatedDerivedKeys(oldKeys = scanResponse.derivedKeys, newKeys = keys), diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/cold/UserWalletIdPreflightReadFilter.kt b/data/wallets/src/main/java/com/tangem/data/wallets/cold/UserWalletIdPreflightReadFilter.kt new file mode 100644 index 0000000000..dcb1dc574b --- /dev/null +++ b/data/wallets/src/main/java/com/tangem/data/wallets/cold/UserWalletIdPreflightReadFilter.kt @@ -0,0 +1,25 @@ +package com.tangem.data.wallets.cold + +import com.tangem.common.card.Card +import com.tangem.common.core.SessionEnvironment +import com.tangem.common.core.TangemSdkError +import com.tangem.domain.models.scan.CardDTO +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.builder.UserWalletIdBuilder +import com.tangem.operations.preflightread.PreflightReadFilter + +/** + * [PreflightReadFilter] for checking if card has expected user wallet id + * +[REDACTED_AUTHOR] + */ +class UserWalletIdPreflightReadFilter(private val expectedUserWalletId: UserWalletId) : PreflightReadFilter { + + override fun onCardRead(card: Card, environment: SessionEnvironment) = Unit + + override fun onFullCardRead(card: Card, environment: SessionEnvironment) { + val actualUserWalletId = UserWalletIdBuilder.card(card = CardDTO(card)).build() ?: return + + if (expectedUserWalletId != actualUserWalletId) throw TangemSdkError.WalletNotFound() + } +} \ No newline at end of file diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt new file mode 100644 index 0000000000..862b90b035 --- /dev/null +++ b/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt @@ -0,0 +1,95 @@ +package com.tangem.data.wallets.derivations + +import com.tangem.common.CompletionResult +import com.tangem.common.extensions.ByteArrayKey +import com.tangem.common.map +import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.datasource.local.userwallet.UserWalletsStore +import com.tangem.domain.wallets.derivations.ColdMapDerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository +import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository +import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.usecase.BackendId +import com.tangem.operations.derivation.ExtendedPublicKeysMap +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext +import javax.inject.Inject + +internal class DefaultDerivationsRepository @Inject constructor( + private val userWalletsStore: UserWalletsStore, + private val hotDerivationsRepository: HotMapDerivationsRepository, + private val coldDerivationsRepository: ColdMapDerivationsRepository, + private val dispatchers: CoroutineDispatcherProvider, +) : DerivationsRepository { + + override suspend fun derivePublicKeys(userWalletId: UserWalletId, currencies: List) { + derivePublicKeysByNetworks(userWalletId = userWalletId, networks = currencies.map(CryptoCurrency::network)) + } + + override suspend fun derivePublicKeysByNetworkIds(userWalletId: UserWalletId, networkIds: List) { + val userWallet = userWalletsStore.getSyncStrict(userWalletId) + when (userWallet) { + is UserWallet.Cold -> coldDerivationsRepository.derivePublicKeysByNetworkIds(userWallet, networkIds) + is UserWallet.Hot -> hotDerivationsRepository.derivePublicKeysByNetworkIds(userWallet, networkIds) + }.also { + userWallet.update(it) + } + } + + override suspend fun derivePublicKeysByNetworks(userWalletId: UserWalletId, networks: List) { + val userWallet = userWalletsStore.getSyncStrict(userWalletId) + when (userWallet) { + is UserWallet.Cold -> coldDerivationsRepository.derivePublicKeysByNetworks(userWallet, networks) + is UserWallet.Hot -> hotDerivationsRepository.derivePublicKeysByNetworks(userWallet, networks) + }.also { + userWallet.update(it) + } + } + + override suspend fun derivePublicKeys( + userWalletId: UserWalletId, + derivations: Map>, + ): Map { + val userWallet = userWalletsStore.getSyncStrict(userWalletId) + return when (userWallet) { + is UserWallet.Cold -> coldDerivationsRepository.derivePublicKeys(userWallet, derivations) + is UserWallet.Hot -> hotDerivationsRepository.derivePublicKeys(userWallet, derivations) + }.let { + userWallet.update(it.first) + it.second + } + } + + override suspend fun hasMissedDerivations( + userWalletId: UserWalletId, + networksWithDerivationPath: Map, + ): Boolean { + return when (val userWallet = userWalletsStore.getSyncStrict(userWalletId)) { + is UserWallet.Cold -> coldDerivationsRepository.hasMissedDerivations(userWallet, networksWithDerivationPath) + is UserWallet.Hot -> hotDerivationsRepository.hasMissedDerivations(userWallet, networksWithDerivationPath) + } + } + + private suspend fun UserWallet.update(newUserWallet: UserWallet) = withContext(dispatchers.io) { + check(this@update.walletId == newUserWallet.walletId) { + "Cannot update UserWallet with different walletId: ${newUserWallet.walletId}" + } + + if (this@update == newUserWallet) { + return@withContext // No update needed + } + + val updateResult = userWalletsStore.update( + userWalletId = newUserWallet.walletId, + update = { userWalletToUpdate -> newUserWallet }, + ) + + when (updateResult) { + is CompletionResult.Failure -> throw updateResult.error + is CompletionResult.Success -> updateResult.data + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/card/MissedDerivationsFinder.kt b/data/wallets/src/main/java/com/tangem/data/wallets/derivations/MissedDerivationsFinder.kt similarity index 64% rename from app/src/main/java/com/tangem/tap/domain/card/MissedDerivationsFinder.kt rename to data/wallets/src/main/java/com/tangem/data/wallets/derivations/MissedDerivationsFinder.kt index 7e740159e5..5ea8f38be1 100644 --- a/app/src/main/java/com/tangem/tap/domain/card/MissedDerivationsFinder.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/derivations/MissedDerivationsFinder.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.domain.card +package com.tangem.data.wallets.derivations import com.tangem.blockchain.blockchains.cardano.CardanoUtils import com.tangem.blockchain.common.Blockchain @@ -8,23 +8,26 @@ import com.tangem.common.extensions.ByteArrayKey import com.tangem.common.extensions.toMapKey import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.card.configs.CardConfig -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.card.configs.Wallet2CardConfig import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.scan.KeyWalletPublicKey -import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.operations.derivation.ExtendedPublicKeysMap +import kotlin.collections.forEach private typealias DerivationData = Pair> +internal typealias Derivations = Map> /** * Finder of missed derivations * - * @property scanResponse scanning response + * @property userWallet User wallet to find derivations for * [REDACTED_AUTHOR] */ -internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) { +internal class MissedDerivationsFinder(private val userWallet: UserWallet) { /** Find missed derivations for given currencies [currencies] */ fun find(currencies: List): Derivations { @@ -48,30 +51,39 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) { } private fun List.mapToNewDerivations(): List { - val config = CardConfig.createConfig(scanResponse.card) + val config = when (userWallet) { + is UserWallet.Cold -> CardConfig.createConfig(userWallet.scanResponse.card) + is UserWallet.Hot -> Wallet2CardConfig // TODO create config [REDACTED_TASK_KEY] + } return mapNotNull { network -> val blockchain = network.toBlockchain() val curve = config.primaryCurve(blockchain) ?: return@mapNotNull null - findNewDerivations(curve = curve, scanResponse = scanResponse, network = network) + val walletPublicKey = when (userWallet) { + is UserWallet.Cold -> { + val wallet = userWallet.scanResponse.card.wallets.firstOrNull { it.curve == curve } + wallet?.publicKey + } + is UserWallet.Hot -> { + val wallet = userWallet.wallets?.firstOrNull { it.curve == curve } + wallet?.publicKey + } + } + + walletPublicKey?.let { + findNewDerivations(curve = curve, publicKey = it, network = network) + } } } - private fun findNewDerivations( - curve: EllipticCurve, - scanResponse: ScanResponse, - network: Network, - ): DerivationData? { - val wallet = scanResponse.card.wallets.firstOrNull { it.curve == curve } ?: return null - val publicKey = wallet.publicKey.toMapKey() - + private fun findNewDerivations(curve: EllipticCurve, publicKey: ByteArray, network: Network): DerivationData? { val derivationCandidates = network .getDerivationCandidates(curve) .ifEmpty { return null } - .filterAlreadyDerivedKeys(publicKey) + .filterAlreadyDerivedKeys(publicKey.toMapKey()) .ifEmpty { return null } - return publicKey to derivationCandidates + return publicKey.toMapKey() to derivationCandidates } private fun Network.getDerivationCandidates(curve: EllipticCurve): List { @@ -88,7 +100,7 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) { private fun Blockchain.getDerivationPath(curve: EllipticCurve): DerivationPath? { return if (getSupportedCurves().contains(curve)) { - derivationPath(style = scanResponse.derivationStyleProvider.getDerivationStyle()) + derivationPath(style = userWallet.derivationStyleProvider.getDerivationStyle()) } else { null } @@ -118,7 +130,15 @@ internal class MissedDerivationsFinder(private val scanResponse: ScanResponse) { } private fun getAlreadyDerivedKeys(publicKey: KeyWalletPublicKey): List { - val extendedPublicKeysMap = scanResponse.derivedKeys[publicKey] ?: ExtendedPublicKeysMap(emptyMap()) + val extendedPublicKeysMap = when (userWallet) { + is UserWallet.Cold -> userWallet.scanResponse.derivedKeys[publicKey] ?: ExtendedPublicKeysMap(emptyMap()) + is UserWallet.Hot -> { + val wallets = userWallet.wallets ?: return emptyList() + wallets.firstOrNull { it.publicKey.contentEquals(publicKey.bytes) }?.derivedKeys + ?: ExtendedPublicKeysMap(emptyMap()) + } + } + return extendedPublicKeysMap.keys.toList() } } \ No newline at end of file diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt b/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt index a154dc4f99..5564622241 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt @@ -2,14 +2,21 @@ package com.tangem.data.wallets.di import com.tangem.data.wallets.DefaultWalletNamesMigrationRepository import com.tangem.data.wallets.DefaultWalletsRepository +import com.tangem.data.wallets.cold.DefaultColdMapDerivationsRepository +import com.tangem.data.wallets.derivations.DefaultDerivationsRepository +import com.tangem.data.wallets.hot.DefaultHotMapDerivationsRepository import com.tangem.datasource.api.common.AuthProvider import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.local.datastore.RuntimeStateStore import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.userwallet.UserWalletsStore +import com.tangem.domain.wallets.derivations.ColdMapDerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository +import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -44,4 +51,21 @@ internal object WalletsDataModule { fun provideMigrateNamesRepository(appPreferencesStore: AppPreferencesStore): WalletNamesMigrationRepository { return DefaultWalletNamesMigrationRepository(appPreferencesStore) } +} + +@Module +@InstallIn(SingletonComponent::class) +internal interface WalletsDataBindsModule { + + @Binds + @Singleton + fun bindDerivationsRepository(impl: DefaultDerivationsRepository): DerivationsRepository + + @Binds + @Singleton + fun bindHotMapDerivationsRepository(impl: DefaultHotMapDerivationsRepository): HotMapDerivationsRepository + + @Binds + @Singleton + fun bindColdMapDerivationsRepository(impl: DefaultColdMapDerivationsRepository): ColdMapDerivationsRepository } \ No newline at end of file diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt new file mode 100644 index 0000000000..3eb9431fc3 --- /dev/null +++ b/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt @@ -0,0 +1,139 @@ +package com.tangem.data.wallets.hot + +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchainsdk.utils.fromNetworkId +import com.tangem.common.extensions.ByteArrayKey +import com.tangem.common.extensions.toMapKey +import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.data.common.network.NetworkFactory +import com.tangem.data.wallets.derivations.MissedDerivationsFinder +import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository +import com.tangem.domain.wallets.usecase.BackendId +import com.tangem.hot.sdk.model.DeriveWalletRequest +import com.tangem.operations.derivation.ExtendedPublicKeysMap +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext +import timber.log.Timber +import javax.inject.Inject + +internal class DefaultHotMapDerivationsRepository @Inject constructor( + private val networkFactory: NetworkFactory, + private val hotWalletAccessor: HotWalletAccessor, + private val dispatchers: CoroutineDispatcherProvider, +) : HotMapDerivationsRepository { + + override suspend fun derivePublicKeys( + userWallet: UserWallet.Hot, + currencies: List, + ): UserWallet.Hot { + return derivePublicKeysByNetworks(userWallet = userWallet, networks = currencies.map(CryptoCurrency::network)) + } + + override suspend fun derivePublicKeysByNetworkIds( + userWallet: UserWallet.Hot, + networkIds: List, + ): UserWallet.Hot { + return derivePublicKeysByNetworks( + userWallet = userWallet, + networks = networkIds.mapNotNull { + networkFactory.create( + blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, + extraDerivationPath = null, + userWallet = userWallet, + ) + }, + ) + } + + override suspend fun derivePublicKeysByNetworks( + userWallet: UserWallet.Hot, + networks: List, + ): UserWallet.Hot = withContext(dispatchers.default) { + val derivations = MissedDerivationsFinder(userWallet) + .findByNetworks(networks) + .ifEmpty { + Timber.d("Nothing to derive") + return@withContext userWallet + } + + derivePublicKeys(userWallet, derivations).first + } + + override suspend fun derivePublicKeys( + userWallet: UserWallet.Hot, + derivations: Map>, + ): Pair> { + val wallets = userWallet.wallets ?: return userWallet to emptyMap() + + val request = DeriveWalletRequest( + derivations.map { entry -> + val wallet = wallets.first { it.publicKey.contentEquals(entry.key.bytes) } + DeriveWalletRequest.Request( + curve = wallet.curve, + paths = entry.value, + ) + }, + ) + val result = hotWalletAccessor.derivePublicKeys( + hotWalletId = userWallet.hotWalletId, + request = request, + ) + val newKeys = + result.responses.associate { ByteArrayKey(it.seedKey.publicKey) to ExtendedPublicKeysMap(it.publicKeys) } + + return userWallet.updateWithNewKeys(newKeys) to newKeys + } + + override suspend fun hasMissedDerivations( + userWallet: UserWallet.Hot, + networksWithDerivationPath: Map, + ): Boolean = withContext(dispatchers.default) { + val derivations = MissedDerivationsFinder(userWallet) + .findByNetworks( + networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) -> + networkFactory.create( + blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null, + extraDerivationPath = extraDerivationPath, + userWallet = userWallet, + ) + }, + ) + + derivations.isNotEmpty() + } + + private fun UserWallet.Hot.updateWithNewKeys(newKeys: Map): UserWallet.Hot { + val wallets = this.wallets ?: return this + val derivedKeys = wallets.associate { + it.publicKey.toMapKey() to ExtendedPublicKeysMap(it.derivedKeys) + } + val updatedKeys = getUpdatedDerivedKeys( + oldKeys = derivedKeys, + newKeys = newKeys, + ) + + return copy( + wallets = wallets.map { wallet -> + wallet.copy( + derivedKeys = updatedKeys[wallet.publicKey.toMapKey()] ?: ExtendedPublicKeysMap(emptyMap()), + ) + }, + ) + } + + private fun getUpdatedDerivedKeys( + oldKeys: Map, + newKeys: Map, + ): Map { + return (oldKeys.keys + newKeys.keys).toSet() + .associateWith { walletKey -> + val oldDerivations = ExtendedPublicKeysMap(oldKeys[walletKey] ?: emptyMap()) + val newDerivations = newKeys[walletKey] ?: ExtendedPublicKeysMap(emptyMap()) + + ExtendedPublicKeysMap(oldDerivations + newDerivations) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/hot/HotWalletAccessor.kt b/data/wallets/src/main/java/com/tangem/data/wallets/hot/HotWalletAccessor.kt similarity index 84% rename from app/src/main/java/com/tangem/tap/domain/hot/HotWalletAccessor.kt rename to data/wallets/src/main/java/com/tangem/data/wallets/hot/HotWalletAccessor.kt index a65a2ecd53..9ae11b61c8 100644 --- a/app/src/main/java/com/tangem/tap/domain/hot/HotWalletAccessor.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/hot/HotWalletAccessor.kt @@ -1,7 +1,7 @@ -package com.tangem.tap.domain.hot +package com.tangem.data.wallets.hot import com.tangem.common.core.TangemSdkError -import com.tangem.features.hotwallet.HotWalletPasswordRequester +import com.tangem.domain.wallets.hot.HotWalletPasswordRequester import com.tangem.hot.sdk.TangemHotSdk import com.tangem.hot.sdk.exception.WrongPasswordException import com.tangem.hot.sdk.model.* @@ -12,7 +12,17 @@ class HotWalletAccessor @Inject constructor( private val hotWalletPasswordRequester: HotWalletPasswordRequester, ) { - suspend fun signHashes(hotWalletId: HotWalletId, dataToSign: List): List { + suspend fun signHashes(hotWalletId: HotWalletId, dataToSign: List): List = + hotSdkRequest(hotWalletId) { unlock -> + tangemHotSdk.signHashes(unlockHotWallet = unlock, dataToSign = dataToSign) + } + + suspend fun derivePublicKeys(hotWalletId: HotWalletId, request: DeriveWalletRequest): DerivedPublicKeyResponse = + hotSdkRequest(hotWalletId) { unlock -> + tangemHotSdk.derivePublicKey(unlockHotWallet = unlock, request = request) + } + + private suspend fun hotSdkRequest(hotWalletId: HotWalletId, block: suspend (unlock: UnlockHotWallet) -> T): T { val auth = when (hotWalletId.authType) { HotWalletId.AuthType.NoPassword -> HotAuth.NoAuth HotWalletId.AuthType.Password -> requestPassword(false) @@ -20,13 +30,7 @@ class HotWalletAccessor @Inject constructor( } return runCatchingSdkErrors(hotWalletId, auth) { - tangemHotSdk.signHashes( - unlockHotWallet = UnlockHotWallet( - walletId = hotWalletId, - auth = it, - ), - dataToSign = dataToSign, - ).also { + block(UnlockHotWallet(hotWalletId, it)).also { hotWalletPasswordRequester.dismiss() } } diff --git a/app/src/main/java/com/tangem/tap/domain/hot/TangemHotWalletSigner.kt b/data/wallets/src/main/java/com/tangem/data/wallets/hot/TangemHotWalletSigner.kt similarity index 99% rename from app/src/main/java/com/tangem/tap/domain/hot/TangemHotWalletSigner.kt rename to data/wallets/src/main/java/com/tangem/data/wallets/hot/TangemHotWalletSigner.kt index ba64c2fda2..b5bfc9da12 100644 --- a/app/src/main/java/com/tangem/tap/domain/hot/TangemHotWalletSigner.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/hot/TangemHotWalletSigner.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.domain.hot +package com.tangem.data.wallets.hot import com.tangem.blockchain.common.TransactionSigner import com.tangem.blockchain.common.Wallet diff --git a/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt b/data/wallets/src/test/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepositoryTest.kt similarity index 80% rename from app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt rename to data/wallets/src/test/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepositoryTest.kt index f5484b4b50..eb812166f7 100644 --- a/app/src/test/kotlin/com/tangem/tap/domain/card/DefaultDerivationsRepositoryTest.kt +++ b/data/wallets/src/test/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepositoryTest.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.domain.card +package com.tangem.data.wallets.derivations import android.annotation.SuppressLint import com.google.common.truth.Truth @@ -7,6 +7,7 @@ import com.tangem.common.CompletionResult import com.tangem.common.test.domain.card.MockScanResponseFactory import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory import com.tangem.data.common.network.NetworkFactory +import com.tangem.data.wallets.cold.DefaultColdMapDerivationsRepository import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.card.ScanCardException import com.tangem.domain.card.configs.GenericCardConfig @@ -14,7 +15,7 @@ import com.tangem.domain.card.configs.MultiWalletCardConfig import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.operations.derivation.DerivationTaskResponse -import com.tangem.tap.domain.sdk.impl.DefaultTangemSdkManager +import com.tangem.sdk.api.TangemSdkManager import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider import io.mockk.coEvery import io.mockk.coVerify @@ -27,13 +28,17 @@ import org.junit.Test */ internal class DefaultDerivationsRepositoryTest { - private val tangemSdkManager = mockk() + private val tangemSdkManager = mockk() private val userWalletsStore = mockk() private val repository = DefaultDerivationsRepository( - tangemSdkManager = tangemSdkManager, userWalletsStore = userWalletsStore, dispatchers = TestingCoroutineDispatcherProvider(), - networkFactory = NetworkFactory(excludedBlockchains = ExcludedBlockchains()), + hotDerivationsRepository = mockk(), + coldDerivationsRepository = DefaultColdMapDerivationsRepository( + tangemSdkManager = tangemSdkManager, + networkFactory = NetworkFactory(excludedBlockchains = ExcludedBlockchains()), + dispatchers = TestingCoroutineDispatcherProvider(), + ), ) private val defaultUserWalletId = UserWalletId("011") @@ -48,7 +53,7 @@ internal class DefaultDerivationsRepositoryTest { @Test fun `error if userWalletId not found`() = runTest { - coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns null + coEvery { userWalletsStore.getSyncStrict(defaultUserWalletId) } throws IllegalStateException() runCatching { repository.derivePublicKeys(userWalletId = defaultUserWalletId, currencies = emptyList()) @@ -56,7 +61,7 @@ internal class DefaultDerivationsRepositoryTest { .onSuccess { error("Should throws exception") } .onFailure { Truth.assertThat(it).isInstanceOf(IllegalStateException::class.java) } - coVerify(exactly = 1) { userWalletsStore.getSyncOrNull(defaultUserWalletId) } + coVerify(exactly = 1) { userWalletsStore.getSyncStrict(defaultUserWalletId) } coVerify(inverse = true) { tangemSdkManager.derivePublicKeys(null, any(), any()) } coVerify(inverse = true) { userWalletsStore.update(defaultUserWalletId, any()) } } @@ -64,13 +69,17 @@ internal class DefaultDerivationsRepositoryTest { @SuppressLint("CheckResult") @Test fun `success if card is not supported derivations`() = runTest { - coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns defaultUserWallet + coEvery { userWalletsStore.getSyncStrict(defaultUserWalletId) } returns defaultUserWallet - runCatching { repository.derivePublicKeys(userWalletId = defaultUserWalletId, currencies = emptyList()) } + repository.derivePublicKeys(userWalletId = defaultUserWalletId, currencies = emptyList()) + + runCatching { } .onSuccess { Truth.assertThat(it) } - .onFailure { error("Should returns success") } + .onFailure { + error("Should returns success") + } - coVerify(exactly = 1) { userWalletsStore.getSyncOrNull(defaultUserWalletId) } + coVerify(exactly = 1) { userWalletsStore.getSyncStrict(defaultUserWalletId) } coVerify(inverse = true) { tangemSdkManager.derivePublicKeys(null, any(), any()) } coVerify(inverse = true) { userWalletsStore.update(defaultUserWalletId, any()) } } @@ -81,13 +90,13 @@ internal class DefaultDerivationsRepositoryTest { val userWallet = defaultUserWallet.copy( scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()), ) - coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet + coEvery { userWalletsStore.getSyncStrict(defaultUserWalletId) } returns userWallet runCatching { repository.derivePublicKeys(userWalletId = defaultUserWalletId, currencies = emptyList()) } .onSuccess { Truth.assertThat(it) } .onFailure { error("Should returns success") } - coVerify(exactly = 1) { userWalletsStore.getSyncOrNull(defaultUserWalletId) } + coVerify(exactly = 1) { userWalletsStore.getSyncStrict(defaultUserWalletId) } coVerify(inverse = true) { tangemSdkManager.derivePublicKeys(null, any(), any()) } coVerify(inverse = true) { userWalletsStore.update(defaultUserWalletId, any()) } } @@ -102,7 +111,7 @@ internal class DefaultDerivationsRepositoryTest { ), ) - coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet + coEvery { userWalletsStore.getSyncStrict(defaultUserWalletId) } returns userWallet runCatching { repository.derivePublicKeys( @@ -113,7 +122,7 @@ internal class DefaultDerivationsRepositoryTest { .onSuccess { Truth.assertThat(it) } .onFailure { error("Should returns success") } - coVerify(exactly = 1) { userWalletsStore.getSyncOrNull(defaultUserWalletId) } + coVerify(exactly = 1) { userWalletsStore.getSyncStrict(defaultUserWalletId) } coVerify(inverse = true) { tangemSdkManager.derivePublicKeys(null, any(), any()) } coVerify(inverse = true) { userWalletsStore.update(defaultUserWalletId, any()) } } @@ -123,7 +132,7 @@ internal class DefaultDerivationsRepositoryTest { val userWallet = defaultUserWallet.copy( scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()), ) - coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet + coEvery { userWalletsStore.getSyncStrict(defaultUserWalletId) } returns userWallet coEvery { tangemSdkManager.derivePublicKeys(null, any(), any()) } throws ScanCardException.UserCancelled runCatching { @@ -135,7 +144,7 @@ internal class DefaultDerivationsRepositoryTest { .onSuccess { error("Should throws exception") } .onFailure { Truth.assertThat(it).isInstanceOf(ScanCardException.UserCancelled::class.java) } - coVerify(exactly = 1) { userWalletsStore.getSyncOrNull(defaultUserWalletId) } + coVerify(exactly = 1) { userWalletsStore.getSyncStrict(defaultUserWalletId) } coVerify(exactly = 1) { tangemSdkManager.derivePublicKeys(null, any(), any()) } coVerify(inverse = true) { userWalletsStore.update(defaultUserWalletId, any()) } } @@ -146,7 +155,7 @@ internal class DefaultDerivationsRepositoryTest { val userWallet = defaultUserWallet.copy( scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()), ) - coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet + coEvery { userWalletsStore.getSyncStrict(defaultUserWalletId) } returns userWallet coEvery { tangemSdkManager.derivePublicKeys(null, any(), any()) } returns CompletionResult.Success( DerivationTaskResponse(DerivedKeysMocks.ethereumDerivedKeys), ) @@ -161,7 +170,7 @@ internal class DefaultDerivationsRepositoryTest { .onSuccess { Truth.assertThat(it) } .onFailure { error("Should returns success but $it") } - coVerify(exactly = 1) { userWalletsStore.getSyncOrNull(defaultUserWalletId) } + coVerify(exactly = 1) { userWalletsStore.getSyncStrict(defaultUserWalletId) } coVerify(exactly = 1) { tangemSdkManager.derivePublicKeys(null, any(), any()) } coVerify(exactly = 1) { userWalletsStore.update(defaultUserWalletId, any()) } } diff --git a/app/src/test/kotlin/com/tangem/tap/domain/card/DerivedKeysMocks.kt b/data/wallets/src/test/java/com/tangem/data/wallets/derivations/DerivedKeysMocks.kt similarity index 95% rename from app/src/test/kotlin/com/tangem/tap/domain/card/DerivedKeysMocks.kt rename to data/wallets/src/test/java/com/tangem/data/wallets/derivations/DerivedKeysMocks.kt index a8398c930c..ae0e28b70b 100644 --- a/app/src/test/kotlin/com/tangem/tap/domain/card/DerivedKeysMocks.kt +++ b/data/wallets/src/test/java/com/tangem/data/wallets/derivations/DerivedKeysMocks.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.domain.card +package com.tangem.data.wallets.derivations import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.derivation.DerivationConfigV2 diff --git a/app/src/test/kotlin/com/tangem/tap/domain/card/MissedDerivationsFinderTest.kt b/data/wallets/src/test/java/com/tangem/data/wallets/derivations/MissedDerivationsFinderTest.kt similarity index 90% rename from app/src/test/kotlin/com/tangem/tap/domain/card/MissedDerivationsFinderTest.kt rename to data/wallets/src/test/java/com/tangem/data/wallets/derivations/MissedDerivationsFinderTest.kt index f623b13c56..426a1bc144 100644 --- a/app/src/test/kotlin/com/tangem/tap/domain/card/MissedDerivationsFinderTest.kt +++ b/data/wallets/src/test/java/com/tangem/data/wallets/derivations/MissedDerivationsFinderTest.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.domain.card +package com.tangem.data.wallets.derivations import com.google.common.truth.Truth import com.tangem.blockchain.blockchains.cardano.CardanoUtils @@ -13,7 +13,7 @@ import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.card.configs.GenericCardConfig import com.tangem.domain.card.configs.MultiWalletCardConfig import com.tangem.domain.card.configs.Wallet2CardConfig -import com.tangem.domain.card.common.util.derivationStyleProvider +import com.tangem.domain.wallets.derivations.derivationStyleProvider import org.junit.Test /** @@ -24,7 +24,8 @@ internal class MissedDerivationsFinderTest { @Test fun `empty derivations for empty currencies`() { val scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap()) - val finder = MissedDerivationsFinder(scanResponse) + val userWallet = MockUserWalletFactory.create(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val actual = finder.find(emptyList()) @@ -36,7 +37,7 @@ internal class MissedDerivationsFinderTest { // Bls is not supported val scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap()) val userWallet = MockUserWalletFactory.create(scanResponse) - val finder = MissedDerivationsFinder(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val currencies = MockCryptoCurrencyFactory(userWallet).chia.let(::listOf) val actual = finder.find(currencies) @@ -58,7 +59,7 @@ internal class MissedDerivationsFinderTest { ) } val userWallet = MockUserWalletFactory.create(scanResponse) - val finder = MissedDerivationsFinder(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val currencies = MockCryptoCurrencyFactory(userWallet).chiaAndEthereum val actual = finder.find(currencies) @@ -73,7 +74,7 @@ internal class MissedDerivationsFinderTest { fun `derivations for custom token`() { val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()) val userWallet = MockUserWalletFactory.create(scanResponse) - val finder = MissedDerivationsFinder(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val currencies = MockCryptoCurrencyFactory(userWallet).ethereumTokenWithBinanceDerivation val actual = finder.find(currencies) @@ -91,7 +92,7 @@ internal class MissedDerivationsFinderTest { fun `derivations for cardano`() { val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()) val userWallet = MockUserWalletFactory.create(scanResponse) - val finder = MissedDerivationsFinder(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val currencies = MockCryptoCurrencyFactory(userWallet).cardano.let(::listOf) val actual = finder.find(currencies) @@ -117,7 +118,7 @@ internal class MissedDerivationsFinderTest { derivedKeys = DerivedKeysMocks.ethereumDerivedKeys, ) val userWallet = MockUserWalletFactory.create(scanResponse) - val finder = MissedDerivationsFinder(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val currencies = MockCryptoCurrencyFactory(userWallet).ethereum.let(::listOf) val actual = finder.find(currencies) @@ -132,7 +133,7 @@ internal class MissedDerivationsFinderTest { derivedKeys = DerivedKeysMocks.ethereumDerivedKeys, ) val userWallet = MockUserWalletFactory.create(scanResponse) - val finder = MissedDerivationsFinder(scanResponse) + val finder = MissedDerivationsFinder(userWallet) val currencies = MockCryptoCurrencyFactory(userWallet).ethereumAndStellar val actual = finder.find(currencies) diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/TangemCardTypesResolver.kt b/domain/card/src/main/kotlin/com/tangem/domain/card/TangemCardTypesResolver.kt index f98a8ed3a7..e8badaf526 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/TangemCardTypesResolver.kt +++ b/domain/card/src/main/kotlin/com/tangem/domain/card/TangemCardTypesResolver.kt @@ -1,6 +1,7 @@ package com.tangem.domain.card import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.Blockchain.Companion.fromId import com.tangem.blockchain.common.Token import com.tangem.common.card.EllipticCurve import com.tangem.common.card.FirmwareVersion @@ -76,7 +77,7 @@ internal class TangemCardTypesResolver( } else { return Blockchain.Unknown } - Blockchain.Companion.fromBlockchainName(blockchainName) + Blockchain.fromBlockchainName(blockchainName) } } } diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/common/util/ScanResponseExt.kt b/domain/card/src/main/kotlin/com/tangem/domain/card/common/util/ScanResponseExt.kt index 6fb8c34eb4..0a6e22e8e5 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/common/util/ScanResponseExt.kt +++ b/domain/card/src/main/kotlin/com/tangem/domain/card/common/util/ScanResponseExt.kt @@ -6,10 +6,7 @@ import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.toMapKey import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.card.CardTypesResolver -import com.tangem.domain.card.DerivationStyleProvider import com.tangem.domain.card.TangemCardTypesResolver -import com.tangem.domain.card.TangemDerivationStyleProvider -import com.tangem.domain.card.TangemHotDerivationStyleProvider import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins import com.tangem.domain.card.common.TapWorkarounds.isTestCard import com.tangem.domain.card.configs.CardConfig @@ -25,18 +22,6 @@ val ScanResponse.cardTypesResolver: CardTypesResolver walletData = walletData, ) -val UserWallet.derivationStyleProvider: DerivationStyleProvider - get() = when (this) { - is UserWallet.Cold -> this.scanResponse.derivationStyleProvider - is UserWallet.Hot -> TangemHotDerivationStyleProvider() - } - -val ScanResponse.derivationStyleProvider: DerivationStyleProvider - get() = card.derivationStyleProvider - -val CardDTO.derivationStyleProvider: DerivationStyleProvider - get() = TangemDerivationStyleProvider(this) - val UserWallet.Cold.cardTypesResolver: CardTypesResolver get() = scanResponse.cardTypesResolver diff --git a/domain/manage-tokens/build.gradle.kts b/domain/manage-tokens/build.gradle.kts index c60557ebe2..e5fffdace4 100644 --- a/domain/manage-tokens/build.gradle.kts +++ b/domain/manage-tokens/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { implementation(projects.domain.staking) implementation(projects.domain.tokens) implementation(projects.domain.card) + implementation(projects.domain.wallets) implementation(projects.domain.legacy) /* Core */ diff --git a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt index 065f27f412..6c1b21b89b 100644 --- a/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt +++ b/domain/manage-tokens/src/main/kotlin/com/tangem/domain/managetokens/SaveManagedTokensUseCase.kt @@ -2,7 +2,6 @@ package com.tangem.domain.managetokens import arrow.core.Either import arrow.core.flatten -import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.managetokens.model.ManagedCryptoCurrency import com.tangem.domain.managetokens.repository.CustomTokensRepository import com.tangem.domain.models.currency.CryptoCurrency @@ -14,6 +13,7 @@ import com.tangem.domain.staking.StakingIdFactory import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.derivations.DerivationsRepository @Suppress("LongParameterList") class SaveManagedTokensUseCase( diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt index 47e769d11f..3417a876fd 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt @@ -1,7 +1,7 @@ package com.tangem.domain.markets import arrow.core.Either -import com.tangem.domain.card.repository.DerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository import com.tangem.domain.markets.repositories.MarketsTokenRepository import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/HotUserWalletBuilder.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/HotUserWalletBuilder.kt index ba55e47d78..8b8bda5d78 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/HotUserWalletBuilder.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/builder/HotUserWalletBuilder.kt @@ -25,7 +25,7 @@ class HotUserWalletBuilder @AssistedInject constructor( ) { suspend fun build(): UserWallet.Hot = withContext(dispatcherProvider.default) { - val allNetworks = Blockchain.entries + val allNetworks = Blockchain.entries // TODO [REDACTED_TASK_KEY] add derivation config val curves = allNetworks.map { it.getSupportedCurves() }.flatten().toSet() val requests = curves.sortedBy { it.ordinal }.map { curve -> val derivationPaths = allNetworks.filter { curve in it.getSupportedCurves() } diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/ColdMapDerivationsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/ColdMapDerivationsRepository.kt new file mode 100644 index 0000000000..86da09c677 --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/ColdMapDerivationsRepository.kt @@ -0,0 +1,35 @@ +package com.tangem.domain.wallets.derivations + +import com.tangem.common.extensions.ByteArrayKey +import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.usecase.BackendId +import com.tangem.operations.derivation.ExtendedPublicKeysMap + +interface ColdMapDerivationsRepository { + + @Throws + suspend fun derivePublicKeys(userWallet: UserWallet.Cold, currencies: List): UserWallet.Cold + + suspend fun derivePublicKeysByNetworkIds( + userWallet: UserWallet.Cold, + networkIds: List, + ): UserWallet.Cold + + @Throws + suspend fun derivePublicKeysByNetworks(userWallet: UserWallet.Cold, networks: List): UserWallet.Cold + + @Throws + suspend fun derivePublicKeys( + userWallet: UserWallet.Cold, + derivations: Map>, + ): Pair> + + /** Check if user [userWallet] has missed derivations using map of [Network.ID] with extraDerivationPath */ + suspend fun hasMissedDerivations( + userWallet: UserWallet.Cold, + networksWithDerivationPath: Map, + ): Boolean +} \ No newline at end of file diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/DerivationStyleProvider.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationStyleProvider.kt similarity index 92% rename from domain/card/src/main/kotlin/com/tangem/domain/card/DerivationStyleProvider.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationStyleProvider.kt index 36267e8d35..51e7ee6763 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/DerivationStyleProvider.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationStyleProvider.kt @@ -1,4 +1,4 @@ -package com.tangem.domain.card +package com.tangem.domain.wallets.derivations import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.domain.card.common.TapWorkarounds.isWallet2 @@ -25,7 +25,6 @@ internal class TangemDerivationStyleProvider( } } -// TODO remove this class [REDACTED_TASK_KEY] internal class TangemHotDerivationStyleProvider : DerivationStyleProvider { override fun getDerivationStyle(): DerivationStyle? = DerivationStyle.V3 } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationStyleProviderExt.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationStyleProviderExt.kt new file mode 100644 index 0000000000..6525c2d528 --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationStyleProviderExt.kt @@ -0,0 +1,17 @@ +package com.tangem.domain.wallets.derivations + +import com.tangem.domain.models.scan.CardDTO +import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.models.wallet.UserWallet + +val UserWallet.derivationStyleProvider: DerivationStyleProvider + get() = when (this) { + is UserWallet.Cold -> scanResponse.derivationStyleProvider + is UserWallet.Hot -> TangemHotDerivationStyleProvider() + } + +val ScanResponse.derivationStyleProvider: DerivationStyleProvider + get() = card.derivationStyleProvider + +val CardDTO.derivationStyleProvider: DerivationStyleProvider + get() = TangemDerivationStyleProvider(this) \ No newline at end of file diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/repository/DerivationsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt similarity index 92% rename from domain/card/src/main/kotlin/com/tangem/domain/card/repository/DerivationsRepository.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt index 0f655df789..43b5190947 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/repository/DerivationsRepository.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt @@ -1,11 +1,11 @@ -package com.tangem.domain.card.repository +package com.tangem.domain.wallets.derivations import com.tangem.common.extensions.ByteArrayKey import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.card.BackendId import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.usecase.BackendId import com.tangem.operations.derivation.ExtendedPublicKeysMap interface DerivationsRepository { diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt new file mode 100644 index 0000000000..65364e9a80 --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt @@ -0,0 +1,35 @@ +package com.tangem.domain.wallets.derivations + +import com.tangem.common.extensions.ByteArrayKey +import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.usecase.BackendId +import com.tangem.operations.derivation.ExtendedPublicKeysMap + +interface HotMapDerivationsRepository { + + @Throws + suspend fun derivePublicKeys(userWallet: UserWallet.Hot, currencies: List): UserWallet.Hot + + suspend fun derivePublicKeysByNetworkIds( + userWallet: UserWallet.Hot, + networkIds: List, + ): UserWallet.Hot + + @Throws + suspend fun derivePublicKeysByNetworks(userWallet: UserWallet.Hot, networks: List): UserWallet.Hot + + @Throws + suspend fun derivePublicKeys( + userWallet: UserWallet.Hot, + derivations: Map>, + ): Pair> + + /** Check if user [userWallet] has missed derivations using map of [Network.ID] with extraDerivationPath */ + suspend fun hasMissedDerivations( + userWallet: UserWallet.Hot, + networksWithDerivationPath: Map, + ): Boolean +} \ No newline at end of file diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletPasswordRequester.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/hot/HotWalletPasswordRequester.kt similarity index 91% rename from features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletPasswordRequester.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/hot/HotWalletPasswordRequester.kt index eac354ece4..6f8391e887 100644 --- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletPasswordRequester.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/hot/HotWalletPasswordRequester.kt @@ -1,4 +1,4 @@ -package com.tangem.features.hotwallet +package com.tangem.domain.wallets.hot import com.tangem.hot.sdk.model.HotAuth diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/HotDerivationsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/HotDerivationsRepository.kt deleted file mode 100644 index 5616695e03..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/HotDerivationsRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.domain.wallets.repository - -import com.tangem.domain.models.network.Network - -interface HotDerivationsRepository { - - fun getAllSupportedNetworks(): Set -} \ No newline at end of file diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/DerivePublicKeysUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DerivePublicKeysUseCase.kt similarity index 74% rename from domain/card/src/main/kotlin/com/tangem/domain/card/DerivePublicKeysUseCase.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DerivePublicKeysUseCase.kt index 86ed75fe6d..164d43a5cf 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/DerivePublicKeysUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DerivePublicKeysUseCase.kt @@ -1,16 +1,17 @@ -package com.tangem.domain.card + +package com.tangem.domain.wallets.usecase import arrow.core.Either -import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.derivations.DerivationsRepository class DerivePublicKeysUseCase( private val derivationsRepository: DerivationsRepository, ) { suspend operator fun invoke(userWalletId: UserWalletId, currencies: List): Either { - return Either.catch { + return Either.Companion.catch { derivationsRepository.derivePublicKeys(userWalletId, currencies) } } diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/GetExtendedPublicKeyForCurrencyUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetExtendedPublicKeyForCurrencyUseCase.kt similarity index 98% rename from domain/card/src/main/kotlin/com/tangem/domain/card/GetExtendedPublicKeyForCurrencyUseCase.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetExtendedPublicKeyForCurrencyUseCase.kt index ebbd38f355..e548eef8b7 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/GetExtendedPublicKeyForCurrencyUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetExtendedPublicKeyForCurrencyUseCase.kt @@ -1,4 +1,4 @@ -package com.tangem.domain.card +package com.tangem.domain.wallets.usecase import arrow.core.Either import arrow.core.right @@ -10,10 +10,10 @@ import com.tangem.common.extensions.calculateSha256 import com.tangem.crypto.NetworkType import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey -import com.tangem.domain.card.repository.DerivationsRepository import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.derivations.DerivationsRepository import com.tangem.operations.derivation.ExtendedPublicKeysMap /** diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/HasMissedDerivationsUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/HasMissedDerivationsUseCase.kt similarity index 75% rename from domain/card/src/main/kotlin/com/tangem/domain/card/HasMissedDerivationsUseCase.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/HasMissedDerivationsUseCase.kt index 69aa1442c2..c9b008133b 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/HasMissedDerivationsUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/HasMissedDerivationsUseCase.kt @@ -1,22 +1,20 @@ -package com.tangem.domain.card +package com.tangem.domain.wallets.usecase -import com.tangem.domain.card.repository.DerivationsRepository -import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.derivations.DerivationsRepository + +typealias BackendId = String /** * Use case to check if user has missed derivations * [REDACTED_AUTHOR] */ - -typealias BackendId = String - class HasMissedDerivationsUseCase( private val derivationsRepository: DerivationsRepository, ) { - /** Check if user [userWalletId] has missed derivations using map of [Network.ID] with extraDerivationPath */ + /** Check if user [userWalletId] has missed derivations using map of [com.tangem.domain.models.network.Network.ID] with extraDerivationPath */ suspend operator fun invoke( userWalletId: UserWalletId, networksWithDerivationPath: Map, diff --git a/features/hot-wallet/api/build.gradle.kts b/features/hot-wallet/api/build.gradle.kts index 310329cc67..a51cd40254 100644 --- a/features/hot-wallet/api/build.gradle.kts +++ b/features/hot-wallet/api/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { /* Project - Domain */ implementation(projects.domain.models) + implementation(projects.domain.wallets) implementation(projects.domain.wallets.models) /* Project - Core */ diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotAccessCodeRequestComponent.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotAccessCodeRequestComponent.kt index 6e6c9c7c8b..49b893e3a6 100644 --- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotAccessCodeRequestComponent.kt +++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotAccessCodeRequestComponent.kt @@ -2,6 +2,7 @@ package com.tangem.features.hotwallet import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.domain.wallets.hot.HotWalletPasswordRequester interface HotAccessCodeRequestComponent : ComposableContentComponent, HotWalletPasswordRequester { diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/DefaultHotAccessCodeRequestComponent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/DefaultHotAccessCodeRequestComponent.kt index beaba4f29a..f23af23895 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/DefaultHotAccessCodeRequestComponent.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/DefaultHotAccessCodeRequestComponent.kt @@ -1,14 +1,13 @@ package com.tangem.features.hotwallet.accesscoderequest -import androidx.compose.foundation.focusable import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.components.FullScreen +import com.tangem.domain.wallets.hot.HotWalletPasswordRequester import com.tangem.features.hotwallet.HotAccessCodeRequestComponent -import com.tangem.features.hotwallet.HotWalletPasswordRequester import com.tangem.features.hotwallet.accesscoderequest.ui.HotAccessCodeRequestFullScreenContent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt index 28fb18f009..c34ec66391 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt @@ -2,7 +2,7 @@ package com.tangem.features.hotwallet.accesscoderequest import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model -import com.tangem.features.hotwallet.HotWalletPasswordRequester +import com.tangem.domain.wallets.hot.HotWalletPasswordRequester import com.tangem.features.hotwallet.accesscoderequest.entity.HotAccessCodeRequestUM import com.tangem.hot.sdk.model.HotAuth import com.tangem.utils.coroutines.CoroutineDispatcherProvider diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/di/ComponentModuleBinds.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/di/ComponentModuleBinds.kt index b1fb298d59..70bb695f83 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/di/ComponentModuleBinds.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/di/ComponentModuleBinds.kt @@ -1,8 +1,8 @@ package com.tangem.features.hotwallet.accesscoderequest.di import com.tangem.core.decompose.model.Model +import com.tangem.domain.wallets.hot.HotWalletPasswordRequester import com.tangem.features.hotwallet.HotAccessCodeRequestComponent -import com.tangem.features.hotwallet.HotWalletPasswordRequester import com.tangem.features.hotwallet.accesscoderequest.DefaultHotAccessCodeRequestComponent import com.tangem.features.hotwallet.accesscoderequest.HotAccessCodeRequestModel import com.tangem.features.hotwallet.accesscoderequest.proxy.HotWalletPasswordRequesterProxy diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/proxy/HotWalletPasswordRequesterProxy.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/proxy/HotWalletPasswordRequesterProxy.kt index 29a16c9c2f..5208d91418 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/proxy/HotWalletPasswordRequesterProxy.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/proxy/HotWalletPasswordRequesterProxy.kt @@ -1,6 +1,6 @@ package com.tangem.features.hotwallet.accesscoderequest.proxy -import com.tangem.features.hotwallet.HotWalletPasswordRequester +import com.tangem.domain.wallets.hot.HotWalletPasswordRequester import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first diff --git a/features/manage-tokens/impl/build.gradle.kts b/features/manage-tokens/impl/build.gradle.kts index 3fcac8e481..e28cec1763 100644 --- a/features/manage-tokens/impl/build.gradle.kts +++ b/features/manage-tokens/impl/build.gradle.kts @@ -30,6 +30,7 @@ dependencies { implementation(projects.domain.manageTokens) implementation(projects.domain.tokens) implementation(projects.domain.tokens.models) + implementation(projects.domain.wallets) implementation(projects.domain.wallets.models) implementation(projects.domain.swap.models) diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/CustomTokenFormModel.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/CustomTokenFormModel.kt index fdcf5a9d1d..08d5f86574 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/CustomTokenFormModel.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/CustomTokenFormModel.kt @@ -9,12 +9,12 @@ import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.message.DialogMessage -import com.tangem.domain.card.DerivePublicKeysUseCase -import com.tangem.domain.card.HasMissedDerivationsUseCase import com.tangem.domain.managetokens.model.exceptoin.CustomTokenFormValidationException import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase +import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase +import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase import com.tangem.features.managetokens.analytics.CustomTokenAnalyticsEvent import com.tangem.features.managetokens.component.CustomTokenFormComponent import com.tangem.features.managetokens.entity.customtoken.ClickableFieldUM diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/ManageTokensModel.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/ManageTokensModel.kt index ff768a5e76..489033da8d 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/ManageTokensModel.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/ManageTokensModel.kt @@ -17,9 +17,9 @@ import com.tangem.core.ui.event.triggeredEvent import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.message.SnackbarMessage -import com.tangem.domain.card.HasMissedDerivationsUseCase import com.tangem.domain.managetokens.SaveManagedTokensUseCase import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase import com.tangem.features.managetokens.analytics.CustomTokenAnalyticsEvent import com.tangem.features.managetokens.analytics.ManageTokensAnalyticEvent import com.tangem.features.managetokens.component.ManageTokensComponent diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/OnboardingManageTokensModel.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/OnboardingManageTokensModel.kt index d6b6ca0899..30f64dad46 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/OnboardingManageTokensModel.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/model/OnboardingManageTokensModel.kt @@ -13,10 +13,10 @@ import com.tangem.core.ui.event.triggeredEvent import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.message.SnackbarMessage -import com.tangem.domain.card.HasMissedDerivationsUseCase import com.tangem.domain.managetokens.SaveManagedTokensUseCase import com.tangem.domain.redux.OnboardingManageTokensAction import com.tangem.domain.redux.ReduxStateHolder +import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase import com.tangem.features.managetokens.analytics.ManageTokensAnalyticEvent import com.tangem.features.managetokens.component.ManageTokensSource import com.tangem.features.managetokens.component.OnboardingManageTokensComponent diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt index deb96eacdb..e17c925595 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt @@ -15,7 +15,7 @@ import com.tangem.core.ui.message.DialogMessage import com.tangem.core.ui.message.SnackbarMessage import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.domain.card.HasMissedDerivationsUseCase +import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase import com.tangem.domain.managetokens.CheckCurrencyUnsupportedUseCase import com.tangem.domain.managetokens.model.CurrencyUnsupportedState import com.tangem.domain.markets.SaveMarketTokensUseCase diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt index 3f47acea4b..63b2225169 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt @@ -4,7 +4,7 @@ import arrow.core.getOrElse import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer -import com.tangem.domain.card.DerivePublicKeysUseCase +import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase diff --git a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ReferralInteractorImpl.kt b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ReferralInteractorImpl.kt index 083ea5d82b..9520d1847e 100644 --- a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ReferralInteractorImpl.kt +++ b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ReferralInteractorImpl.kt @@ -2,7 +2,7 @@ package com.tangem.feature.referral.domain import arrow.core.getOrElse import com.tangem.common.core.TangemSdkError -import com.tangem.domain.card.DerivePublicKeysUseCase +import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.wallets.usecase.GetUserWalletUseCase diff --git a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/di/ReferralDomainModule.kt b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/di/ReferralDomainModule.kt index 4e5166e070..bb4729aac8 100644 --- a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/di/ReferralDomainModule.kt +++ b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/di/ReferralDomainModule.kt @@ -2,7 +2,7 @@ package com.tangem.feature.referral.domain.di import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.di.ModelComponent -import com.tangem.domain.card.DerivePublicKeysUseCase +import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.referral.domain.ReferralInteractor diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt index cb0d326470..33f4a326c7 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt @@ -33,7 +33,6 @@ import com.tangem.core.ui.message.SnackbarMessage import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase -import com.tangem.domain.card.GetExtendedPublicKeyForCurrencyUseCase import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.models.currency.CryptoCurrency @@ -69,6 +68,7 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase +import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase import com.tangem.feature.tokendetails.deeplink.TokenDetailsDeepLinkActionListener diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index ab80da33c7..b6c6a7f60b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -9,7 +9,7 @@ import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.navigation.url.UrlOpener import com.tangem.core.ui.extensions.resourceReference -import com.tangem.domain.card.DerivePublicKeysUseCase +import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase import com.tangem.domain.card.SetCardWasScannedUseCase import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase