Updated on 2026-08-14
This commit is contained in:
commit
7c7f07080e
1413 changed files with 24740 additions and 8757 deletions
|
|
@ -39,8 +39,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.common.analytics.handlers.BlockchainExceptionHandler
|
||||
import com.tangem.tap.common.log.TangemAppLoggerInitializer
|
||||
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
|
||||
|
|
@ -118,8 +116,6 @@ interface ApplicationEntryPoint {
|
|||
|
||||
fun getTransactionSignerFactory(): TransactionSignerFactory
|
||||
|
||||
fun getOnrampFeatureToggles(): OnrampFeatureToggles
|
||||
|
||||
fun getOnboardingV2FeatureToggles(): OnboardingV2FeatureToggles
|
||||
|
||||
fun getOnboardingRepository(): OnboardingRepository
|
||||
|
|
@ -141,8 +137,6 @@ interface ApplicationEntryPoint {
|
|||
|
||||
fun getWorkerFactory(): HiltWorkerFactory
|
||||
|
||||
fun getOnlineCardVerifier(): OnlineCardVerifier
|
||||
|
||||
fun getColdUserWalletBuilderFactory(): ColdUserWalletBuilder.Factory
|
||||
|
||||
fun getApiConfigsManager(): ApiConfigsManager
|
||||
|
|
|
|||
|
|
@ -26,17 +26,13 @@ import androidx.lifecycle.flowWithLifecycle
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.RoutingFeatureToggle
|
||||
import com.tangem.common.routing.deeplink.DeeplinkConst.WEBLINK_KEY
|
||||
import com.tangem.common.routing.deeplink.PayloadToDeeplinkConverter
|
||||
import com.tangem.common.routing.entity.SerializableIntent
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.di.RootAppComponentContext
|
||||
import com.tangem.core.deeplink.DeepLinksRegistry
|
||||
import com.tangem.core.deeplink.WEBLINK_KEY
|
||||
import com.tangem.core.deeplink.converter.PayloadToDeeplinkConverter
|
||||
import com.tangem.core.navigation.email.EmailSender
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.UiDependencies
|
||||
import com.tangem.data.balancehiding.DefaultDeviceFlipDetector
|
||||
import com.tangem.data.card.sdk.CardSdkOwner
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
|
|
@ -52,6 +48,7 @@ import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
|||
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.features.tester.api.TesterMenuLauncher
|
||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||
import com.tangem.google.GoogleServicesHelper
|
||||
import com.tangem.operations.backup.BackupService
|
||||
|
|
@ -68,7 +65,6 @@ import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandle
|
|||
import com.tangem.tap.features.intentHandler.handlers.OnPushClickedIntentHandler
|
||||
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
|
||||
import com.tangem.tap.features.main.MainViewModel
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphAction
|
||||
import com.tangem.tap.routing.component.RoutingComponent
|
||||
import com.tangem.tap.routing.configurator.AppRouterConfig
|
||||
|
|
@ -102,9 +98,6 @@ val mainScope = CoroutineScope(mainCoroutineContext)
|
|||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
||||
|
||||
@Inject
|
||||
lateinit var appStateHolder: AppStateHolder
|
||||
|
||||
/** Router for opening tester menu */
|
||||
@Inject
|
||||
lateinit var cardSdkOwner: CardSdkOwner
|
||||
|
|
@ -121,9 +114,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
@Inject
|
||||
lateinit var walletConnectInteractor: WalletConnectInteractor
|
||||
|
||||
@Inject
|
||||
lateinit var deepLinksRegistry: DeepLinksRegistry
|
||||
|
||||
@Inject
|
||||
lateinit var settingsRepository: SettingsRepository
|
||||
|
||||
|
|
@ -142,9 +132,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
@Inject
|
||||
lateinit var userWalletsListManager: UserWalletsListManager
|
||||
|
||||
@Inject
|
||||
lateinit var emailSender: EmailSender
|
||||
|
||||
@Inject
|
||||
@RootAppComponentContext
|
||||
internal lateinit var rootComponentContext: AppComponentContext
|
||||
|
|
@ -173,15 +160,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
@Inject
|
||||
lateinit var dispatchers: CoroutineDispatcherProvider
|
||||
|
||||
@Inject
|
||||
internal lateinit var uiDependencies: UiDependencies
|
||||
|
||||
@Inject
|
||||
internal lateinit var defaultDeviceFlipDetector: DefaultDeviceFlipDetector
|
||||
|
||||
@Inject
|
||||
internal lateinit var routingFeatureToggle: RoutingFeatureToggle
|
||||
|
||||
@Inject
|
||||
internal lateinit var deeplinkFactory: DeepLinkFactory
|
||||
|
||||
|
|
@ -191,6 +172,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
@Inject
|
||||
internal lateinit var urlOpener: UrlOpener
|
||||
|
||||
@Inject
|
||||
internal lateinit var testerMenuLauncher: TesterMenuLauncher
|
||||
|
||||
internal val viewModel: MainViewModel by viewModels()
|
||||
|
||||
private lateinit var appThemeModeFlow: SharedFlow<AppThemeMode>
|
||||
|
|
@ -243,13 +227,12 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
sendStakingUnsubmittedHashes()
|
||||
checkGoogleServicesAvailability()
|
||||
|
||||
if (routingFeatureToggle.isDeepLinkNavigationEnabled.not() && intent != null && savedInstanceState == null) {
|
||||
// handle intent only on start, not on recreate
|
||||
handleDeepLink(intent = intent, isFromOnNewIntent = false)
|
||||
}
|
||||
|
||||
lifecycle.addObserver(WindowObscurationObserver)
|
||||
lifecycle.addObserver(defaultDeviceFlipDetector)
|
||||
|
||||
if (BuildConfig.TESTER_MENU_ENABLED) {
|
||||
lifecycle.addObserver(testerMenuLauncher.launchOnShakeObserver)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setRootContent() {
|
||||
|
|
@ -479,7 +462,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
}
|
||||
}
|
||||
|
||||
if (routingFeatureToggle.isDeepLinkNavigationEnabled && intent != null) {
|
||||
if (intent != null) {
|
||||
handleDeepLink(intent = intent, isFromOnNewIntent = false)
|
||||
}
|
||||
|
||||
|
|
@ -487,26 +470,22 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
}
|
||||
|
||||
private fun handleDeepLink(intent: Intent, isFromOnNewIntent: Boolean) {
|
||||
if (routingFeatureToggle.isDeepLinkNavigationEnabled) {
|
||||
val deepLinkExtras = PayloadToDeeplinkConverter.convertBundle(intent.extras)?.toUri()
|
||||
val webLink = intent.getStringExtra(WEBLINK_KEY)
|
||||
val deepLinkExtras = PayloadToDeeplinkConverter.convertBundle(intent.extras)?.toUri()
|
||||
val webLink = intent.getStringExtra(WEBLINK_KEY)
|
||||
|
||||
val receivedDeepLink = intent.data ?: deepLinkExtras
|
||||
val receivedDeepLink = intent.data ?: deepLinkExtras
|
||||
|
||||
when {
|
||||
receivedDeepLink != null -> {
|
||||
deeplinkFactory.handleDeeplink(
|
||||
deeplinkUri = receivedDeepLink,
|
||||
coroutineScope = lifecycleScope,
|
||||
isFromOnNewIntent = isFromOnNewIntent,
|
||||
)
|
||||
}
|
||||
webLink?.uriValidate() == true -> {
|
||||
urlOpener.openUrl(webLink)
|
||||
}
|
||||
when {
|
||||
receivedDeepLink != null -> {
|
||||
deeplinkFactory.handleDeeplink(
|
||||
deeplinkUri = receivedDeepLink,
|
||||
coroutineScope = lifecycleScope,
|
||||
isFromOnNewIntent = isFromOnNewIntent,
|
||||
)
|
||||
}
|
||||
webLink?.uriValidate() == true -> {
|
||||
urlOpener.openUrl(webLink)
|
||||
}
|
||||
} else {
|
||||
deepLinksRegistry.launch(intent)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.api.TangemApiServiceSettings
|
||||
import com.tangem.tap.common.analytics.AnalyticsFactory
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
|
|
@ -79,7 +77,6 @@ import com.tangem.wallet.BuildConfig
|
|||
import dagger.hilt.EntryPoints
|
||||
import kotlinx.coroutines.*
|
||||
import org.rekotlin.Store
|
||||
import kotlin.collections.set
|
||||
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
|
||||
|
||||
lateinit var store: Store<AppState>
|
||||
|
|
@ -186,9 +183,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
private val transactionSignerFactory: TransactionSignerFactory
|
||||
get() = entryPoint.getTransactionSignerFactory()
|
||||
|
||||
private val onrampFeatureToggles: OnrampFeatureToggles
|
||||
get() = entryPoint.getOnrampFeatureToggles()
|
||||
|
||||
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles
|
||||
get() = entryPoint.getOnboardingV2FeatureToggles()
|
||||
|
||||
|
|
@ -224,9 +218,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
.setWorkerFactory(workerFactory)
|
||||
.build()
|
||||
|
||||
private val onlineCardVerifier: OnlineCardVerifier
|
||||
get() = entryPoint.getOnlineCardVerifier()
|
||||
|
||||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory
|
||||
get() = entryPoint.getColdUserWalletBuilderFactory()
|
||||
|
||||
|
|
@ -363,7 +354,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
shareManager = shareManager,
|
||||
appRouter = appRouter,
|
||||
transactionSignerFactory = transactionSignerFactory,
|
||||
onrampFeatureToggles = onrampFeatureToggles,
|
||||
environmentConfigStorage = environmentConfigStorage,
|
||||
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
||||
onboardingRepository = onboardingRepository,
|
||||
|
|
@ -372,7 +362,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
clipboardManager = clipboardManager,
|
||||
settingsManager = settingsManager,
|
||||
uiMessageSender = uiMessageSender,
|
||||
onlineCardVerifier = onlineCardVerifier,
|
||||
coldUserWalletBuilderFactory = coldUserWalletBuilderFactory,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.common.analytics.converters
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.core.analytics.models.AnalyticsParam as CoreAnalyticsParam
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.common.analytics.paramsInterceptor
|
|||
|
||||
import com.tangem.core.analytics.api.ParamsInterceptor
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.scan.ProductType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.common.extensions
|
|||
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
import com.tangem.tap.common.analytics.paramsInterceptor.LinkedCardContextInterceptor
|
||||
|
||||
|
|
@ -21,6 +22,15 @@ fun Analytics.setContext(scanResponse: ScanResponse) {
|
|||
addParamsInterceptor(LinkedCardContextInterceptor(scanResponse))
|
||||
}
|
||||
|
||||
fun Analytics.setContext(userWallet: UserWallet) {
|
||||
setUserId(userWallet.walletId.stringValue)
|
||||
// TODO add product type for hot ([REDACTED_TASK_KEY])
|
||||
|
||||
if (userWallet is UserWallet.Cold) {
|
||||
addParamsInterceptor(LinkedCardContextInterceptor(userWallet.scanResponse))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erases the context
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import com.tangem.common.routing.AppRouter
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.redux.StateDialog
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
|
|
|
|||
|
|
@ -3,16 +3,11 @@ package com.tangem.tap.common.extensions
|
|||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.blockchainsdk.utils.amountToCreateAccount
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.tap.common.TestActions
|
||||
import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.getFirstToken
|
||||
import com.tangem.tap.domain.model.WalletAddressData
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -57,43 +52,4 @@ suspend fun WalletManager.safeUpdate(isDemoCard: Boolean): Result<Wallet> = try
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun WalletManager.getTopUpUrl(cryptoCurrency: CryptoCurrency): String? {
|
||||
val globalState = store.state.globalState
|
||||
val defaultAddress = wallet.address
|
||||
|
||||
return globalState.exchangeManager.getUrl(
|
||||
action = CurrencyExchangeManager.Action.Buy,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
fiatCurrencyName = globalState.appCurrency.code,
|
||||
walletAddress = defaultAddress,
|
||||
isDarkTheme = MutableAppThemeModeHolder.isDarkThemeActive,
|
||||
)
|
||||
}
|
||||
|
||||
internal fun WalletManager?.getAddressData(): WalletAddressData? {
|
||||
val wallet = this?.wallet ?: return null
|
||||
|
||||
val addressDataList = wallet.createAddressesData()
|
||||
return if (addressDataList.isEmpty()) null else addressDataList[0]
|
||||
}
|
||||
|
||||
private fun Wallet.createAddressesData(): List<WalletAddressData> {
|
||||
val listOfAddressData = mutableListOf<WalletAddressData>()
|
||||
// put a defaultAddress at the first place
|
||||
addresses.forEach {
|
||||
val addressData = WalletAddressData(
|
||||
it.value,
|
||||
it.type,
|
||||
getShareUri(it.value),
|
||||
getExploreUrl(it.value),
|
||||
)
|
||||
if (it.type == AddressType.Default) {
|
||||
listOfAddressData.add(0, addressData)
|
||||
} else {
|
||||
listOfAddressData.add(addressData)
|
||||
}
|
||||
}
|
||||
return listOfAddressData
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import android.util.Log
|
|||
import coil.ImageLoader
|
||||
import coil.decode.GifDecoder
|
||||
import coil.decode.ImageDecoderDecoder
|
||||
import coil.decode.SvgDecoder
|
||||
import coil.memory.MemoryCache
|
||||
import coil.request.CachePolicy
|
||||
import coil.util.Logger
|
||||
|
|
@ -36,6 +37,7 @@ fun createCoilImageLoader(context: Context, logEnabled: Boolean = false): ImageL
|
|||
} else {
|
||||
add(GifDecoder.Factory())
|
||||
}
|
||||
add(SvgDecoder.Factory())
|
||||
}
|
||||
.memoryCachePolicy(CachePolicy.ENABLED)
|
||||
.memoryCache {
|
||||
|
|
|
|||
|
|
@ -30,21 +30,5 @@ sealed class GlobalAction : Action {
|
|||
data class Success(val appCurrency: AppCurrency) : GlobalAction()
|
||||
}
|
||||
|
||||
data class UpdateWalletSignedHashes(
|
||||
val walletSignedHashes: Int?,
|
||||
val remainingSignatures: Int?,
|
||||
val walletPublicKey: ByteArray,
|
||||
) : GlobalAction()
|
||||
|
||||
data class IsSignWithRing(val isSignWithRing: Boolean) : GlobalAction()
|
||||
|
||||
object ExchangeManager : GlobalAction() {
|
||||
object Init : GlobalAction() {
|
||||
data class Success(
|
||||
val exchangeManager: com.tangem.tap.network.exchangeServices.CurrencyExchangeManager,
|
||||
) : GlobalAction()
|
||||
}
|
||||
|
||||
object Update : GlobalAction()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,23 +2,14 @@ package com.tangem.tap.common.redux.global
|
|||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfig
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.redux.StateDialog
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
import com.tangem.tap.common.extensions.dispatchWithMain
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.network.exchangeServices.CardExchangeRules
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeService
|
||||
import com.tangem.tap.network.exchangeServices.mercuryo.MercuryoEnvironment
|
||||
import com.tangem.tap.network.exchangeServices.mercuryo.MercuryoService
|
||||
import com.tangem.tap.network.exchangeServices.moonpay.MoonPayService
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -31,17 +22,17 @@ object GlobalMiddleware {
|
|||
val handler = globalMiddlewareHandler
|
||||
}
|
||||
|
||||
private val globalMiddlewareHandler: Middleware<AppState> = { dispatch, appState ->
|
||||
private val globalMiddlewareHandler: Middleware<AppState> = { _, _ ->
|
||||
{ nextDispatch ->
|
||||
{ action ->
|
||||
handleAction(action, appState)
|
||||
handleAction(action)
|
||||
nextDispatch(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod", "ComplexMethod")
|
||||
private fun handleAction(action: Action, appState: () -> AppState?) {
|
||||
private fun handleAction(action: Action) {
|
||||
when (action) {
|
||||
is GlobalAction.ScanFailsCounter.ChooseBehavior -> {
|
||||
when (action.result) {
|
||||
|
|
@ -51,42 +42,7 @@ private fun handleAction(action: Action, appState: () -> AppState?) {
|
|||
}
|
||||
}
|
||||
}
|
||||
is GlobalAction.RestoreAppCurrency -> {
|
||||
restoreAppCurrency()
|
||||
}
|
||||
is GlobalAction.ExchangeManager.Init -> {
|
||||
val config = store.inject(DaggerGraphState::environmentConfigStorage).getConfigSync()
|
||||
|
||||
scope.launch {
|
||||
val scanResponseProvider: () -> ScanResponse? = {
|
||||
val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager)
|
||||
userWalletsListManager.selectedUserWalletSync?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY]
|
||||
}
|
||||
val cardProvider: () -> CardDTO? = { scanResponseProvider.invoke()?.card }
|
||||
|
||||
val buyService = makeBuyExchangeService(config)
|
||||
val sellService = makeSellExchangeService(config)
|
||||
val exchangeManager = CurrencyExchangeManager(
|
||||
buyService = buyService,
|
||||
sellService = sellService,
|
||||
primaryRules = CardExchangeRules(cardProvider),
|
||||
)
|
||||
// TODO: for refactoring (after remove old design refactor CurrencyExchangeManager and use 1 instance)
|
||||
store.inject(DaggerGraphState::appStateHolder).buyService = buyService
|
||||
store.inject(DaggerGraphState::appStateHolder).sellService = sellService
|
||||
store.inject(DaggerGraphState::appStateHolder).exchangeService = exchangeManager
|
||||
store.dispatchOnMain(GlobalAction.ExchangeManager.Init.Success(exchangeManager))
|
||||
store.dispatchOnMain(GlobalAction.ExchangeManager.Update)
|
||||
}
|
||||
}
|
||||
is GlobalAction.ExchangeManager.Init.Success -> {}
|
||||
is GlobalAction.ExchangeManager.Update -> {
|
||||
val exchangeManager = appState()?.globalState?.exchangeManager.guard {
|
||||
store.dispatchDebugErrorNotification("exchangeManager is not initialized")
|
||||
return
|
||||
}
|
||||
scope.launch { exchangeManager.update() }
|
||||
}
|
||||
is GlobalAction.RestoreAppCurrency -> restoreAppCurrency()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,21 +75,4 @@ private fun restoreAppCurrency() {
|
|||
|
||||
store.dispatchWithMain(GlobalAction.RestoreAppCurrency.Success(currency))
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeSellExchangeService(environmentConfig: EnvironmentConfig): ExchangeService {
|
||||
return MoonPayService(
|
||||
apiKey = environmentConfig.moonPayApiKey,
|
||||
secretKey = environmentConfig.moonPayApiSecretKey,
|
||||
logEnabled = LogConfig.network.moonPayService,
|
||||
)
|
||||
}
|
||||
|
||||
private fun makeBuyExchangeService(environmentConfig: EnvironmentConfig): ExchangeService {
|
||||
return MercuryoService(
|
||||
environment = MercuryoEnvironment.prod(
|
||||
widgetId = environmentConfig.mercuryoWidgetId,
|
||||
secret = environmentConfig.mercuryoSecret,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.tap.common.redux.global
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.utils.extensions.replaceBy
|
||||
import org.rekotlin.Action
|
||||
|
||||
@Suppress("LongMethod", "ComplexMethod")
|
||||
|
|
@ -26,24 +25,6 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
|
|||
is GlobalAction.RestoreAppCurrency.Success -> {
|
||||
globalState.copy(appCurrency = action.appCurrency)
|
||||
}
|
||||
is GlobalAction.UpdateWalletSignedHashes -> {
|
||||
val card = globalState.scanResponse?.card ?: return globalState
|
||||
val wallet = card.wallets
|
||||
.firstOrNull { it.publicKey.contentEquals(action.walletPublicKey) }
|
||||
?: return globalState
|
||||
|
||||
val newCardInstance = card.copy(
|
||||
wallets = card.wallets.toMutableList().also { walletsMutable ->
|
||||
walletsMutable.replaceBy(
|
||||
item = wallet.copy(
|
||||
totalSignedHashes = action.walletSignedHashes,
|
||||
remainingSignatures = action.remainingSignatures,
|
||||
),
|
||||
) { it.index == wallet.index }
|
||||
},
|
||||
)
|
||||
globalState.copy(scanResponse = globalState.scanResponse.copy(card = newCardInstance))
|
||||
}
|
||||
is GlobalAction.IsSignWithRing -> globalState.copy(isLastSignWithRing = action.isSignWithRing)
|
||||
is GlobalAction.ShowDialog -> {
|
||||
globalState.copy(dialog = action.stateDialog)
|
||||
|
|
@ -51,9 +32,6 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
|
|||
is GlobalAction.HideDialog -> {
|
||||
globalState.copy(dialog = null)
|
||||
}
|
||||
is GlobalAction.ExchangeManager.Init.Success -> {
|
||||
globalState.copy(exchangeManager = action.exchangeManager)
|
||||
}
|
||||
else -> globalState
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,6 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
|||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.redux.StateDialog
|
||||
import com.tangem.tap.domain.TapWalletManager
|
||||
import com.tangem.tap.features.onboarding.OnboardingManager
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
import org.rekotlin.StateType
|
||||
|
||||
data class GlobalState(
|
||||
|
|
@ -16,7 +14,6 @@ data class GlobalState(
|
|||
val appCurrency: AppCurrency = AppCurrency.Default,
|
||||
val scanCardFailsCounter: Int = 0,
|
||||
val dialog: StateDialog? = null,
|
||||
val exchangeManager: CurrencyExchangeManager = CurrencyExchangeManager.dummy(),
|
||||
val isLastSignWithRing: Boolean = false,
|
||||
) : StateType
|
||||
|
||||
|
|
@ -24,6 +21,5 @@ typealias CryptoCurrencyName = String
|
|||
|
||||
data class OnboardingState(
|
||||
val onboardingStarted: Boolean = false,
|
||||
val onboardingManager: OnboardingManager? = null,
|
||||
val shouldResetOnCreate: Boolean = false,
|
||||
)
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.common.redux.legacy
|
||||
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.redux.LegacyAction
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.tap.common.extensions.dispatchWithMain
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
|
|
@ -37,8 +37,7 @@ internal object LegacyMiddleware {
|
|||
)
|
||||
store.dispatchWithMain(
|
||||
DetailsAction.PrepareScreen(
|
||||
// TODO [REDACTED_TASK_KEY]
|
||||
scanResponse = selectedUserWallet.requireColdWallet().scanResponse,
|
||||
scanResponse = (selectedUserWallet as? UserWallet.Cold)?.scanResponse,
|
||||
initializedAppSettingsState = initializedAppSettingsStateContent,
|
||||
),
|
||||
)
|
||||
|
|
@ -67,7 +66,7 @@ internal object LegacyMiddleware {
|
|||
?: AppThemeMode.DEFAULT,
|
||||
isHidingEnabled = store.inject(DaggerGraphState::balanceHidingRepository)
|
||||
.getBalanceHidingSettings().isHidingEnabledInSettings,
|
||||
needEnrollBiometrics = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() ?: false,
|
||||
needEnrollBiometrics = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() == true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,12 @@ package com.tangem.tap.common.url
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||
import androidx.browser.customtabs.CustomTabsClient
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK
|
||||
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT
|
||||
import androidx.core.net.toUri
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
|
||||
import com.tangem.tap.common.extensions.getColorCompat
|
||||
|
|
@ -25,30 +25,37 @@ internal class CustomTabsUrlOpener : UrlOpener {
|
|||
}
|
||||
}
|
||||
|
||||
override fun openUrlExternalBrowser(url: String) {
|
||||
foregroundActivityObserver.withForegroundActivity { context ->
|
||||
if (url.isEmpty()) return@withForegroundActivity
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
context.startActivity(browserIntent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun openUrl(url: String, context: Context) {
|
||||
if (url.isEmpty()) return
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setDefaultColorSchemeParams(
|
||||
CustomTabColorSchemeParams.Builder()
|
||||
.setNavigationBarColor(context.getColorCompat(R.color.toolbarColor))
|
||||
.build(),
|
||||
)
|
||||
.setColorScheme(
|
||||
if (MutableAppThemeModeHolder.isDarkThemeActive) COLOR_SCHEME_DARK else COLOR_SCHEME_LIGHT,
|
||||
)
|
||||
.build()
|
||||
|
||||
customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
runCatching {
|
||||
if (checkCustomTabsAvailability(context, browserIntent)) {
|
||||
context.startActivity(browserIntent)
|
||||
} else {
|
||||
customTabsIntent.launchUrl(context, Uri.parse(url))
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setDefaultColorSchemeParams(
|
||||
CustomTabColorSchemeParams.Builder()
|
||||
.setNavigationBarColor(context.getColorCompat(R.color.toolbarColor))
|
||||
.build(),
|
||||
)
|
||||
.setColorScheme(
|
||||
if (MutableAppThemeModeHolder.isDarkThemeActive) COLOR_SCHEME_DARK else COLOR_SCHEME_LIGHT,
|
||||
)
|
||||
.build()
|
||||
|
||||
customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
customTabsIntent.launchUrl(context, url.toUri())
|
||||
}
|
||||
}.onFailure {
|
||||
Timber.e(it.message)
|
||||
Timber.e(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,16 +16,13 @@ import com.tangem.crypto.bip39.Wordlist
|
|||
import com.tangem.data.card.sdk.CardSdkOwner
|
||||
import com.tangem.data.card.sdk.CardSdkProvider
|
||||
import com.tangem.datasource.api.common.config.ApiConfig
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironmentConfig
|
||||
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectMap
|
||||
import com.tangem.datasource.api.common.config.managers.MutableApiConfigsManager
|
||||
import com.tangem.datasource.utils.AddHeadersInterceptor
|
||||
import com.tangem.datasource.utils.RequestHeader
|
||||
import com.tangem.operations.attestation.api.TangemApiServiceSettings
|
||||
import com.tangem.sdk.DefaultSessionViewDelegate
|
||||
import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles
|
||||
import com.tangem.sdk.extensions.*
|
||||
import com.tangem.sdk.nfc.AndroidNfcAvailabilityProvider
|
||||
import com.tangem.sdk.nfc.NfcManager
|
||||
|
|
@ -34,13 +31,6 @@ import com.tangem.tap.foregroundActivityObserver
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.info.AppInfoProvider
|
||||
import com.tangem.utils.version.AppVersionProvider
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -55,11 +45,9 @@ import javax.inject.Singleton
|
|||
internal class DefaultCardSdkProvider @Inject constructor(
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val cardSdkFeatureToggles: CardSdkFeatureToggles,
|
||||
private val apiConfigsManager: ApiConfigsManager,
|
||||
appVersionProvider: AppVersionProvider,
|
||||
appInfoProvider: AppInfoProvider,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
) : CardSdkProvider, CardSdkOwner {
|
||||
|
||||
private val observer = Observer()
|
||||
|
|
@ -70,26 +58,15 @@ internal class DefaultCardSdkProvider @Inject constructor(
|
|||
get() = holder?.sdk ?: tryToRegisterWithForegroundActivity()
|
||||
|
||||
init {
|
||||
if (BuildConfig.TESTER_MENU_ENABLED) {
|
||||
appPreferencesStore.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
|
||||
.map {
|
||||
when (it[ApiConfig.ID.Attestation.name]) {
|
||||
ApiEnvironment.DEV,
|
||||
ApiEnvironment.STAGE,
|
||||
-> false
|
||||
ApiEnvironment.PROD,
|
||||
null,
|
||||
-> true
|
||||
}
|
||||
val mutableManager = apiConfigsManager as? MutableApiConfigsManager
|
||||
|
||||
mutableManager?.addListener(
|
||||
object : MutableApiConfigsManager.ApiConfigEnvChangeListener(id = ApiConfig.ID.TangemTech) {
|
||||
override fun onChange(environmentConfig: ApiEnvironmentConfig) {
|
||||
holder?.sdk?.config?.tangemApiBaseUrl = environmentConfig.baseUrl
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.onEach { isProd ->
|
||||
holder?.let {
|
||||
it.sdk.config.isTangemAttestationProdEnv = isProd
|
||||
}
|
||||
}
|
||||
.launchIn(CoroutineScope(SupervisorJob() + dispatchers.main))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
TangemApiServiceSettings.addInterceptors(
|
||||
AddHeadersInterceptor(
|
||||
|
|
@ -187,10 +164,8 @@ internal class DefaultCardSdkProvider @Inject constructor(
|
|||
keystoreManager = keystoreManager,
|
||||
wordlist = Wordlist.getWordlist(activity),
|
||||
config = config.apply {
|
||||
isNewOnlineAttestationEnabled = cardSdkFeatureToggles.isNewAttestationEnabled
|
||||
|
||||
val apiConfig = apiConfigsManager.getEnvironmentConfig(id = ApiConfig.ID.Attestation)
|
||||
isTangemAttestationProdEnv = apiConfig.environment == ApiEnvironment.PROD
|
||||
val apiConfig = apiConfigsManager.getEnvironmentConfig(id = ApiConfig.ID.TangemTech)
|
||||
tangemApiBaseUrl = apiConfig.baseUrl
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package com.tangem.tap.data
|
|||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
|||
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
|
||||
import com.tangem.tap.network.exchangeServices.DefaultRampManager
|
||||
|
|
@ -51,17 +50,13 @@ internal object ActivityModule {
|
|||
currenciesRepository: CurrenciesRepository,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
onrampFeatureToggles: OnrampFeatureToggles,
|
||||
): RampStateManager {
|
||||
return DefaultRampManager(
|
||||
exchangeService = appStateHolder.exchangeService,
|
||||
buyService = Provider { requireNotNull(appStateHolder.buyService) },
|
||||
sellService = Provider { requireNotNull(appStateHolder.sellService) },
|
||||
expressServiceLoader = expressServiceLoader,
|
||||
currenciesRepository = currenciesRepository,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
dispatchers = dispatchers,
|
||||
onrampFeatureToggles = onrampFeatureToggles,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ 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.demo.DemoConfig
|
||||
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.IsNeedToBackupUseCase
|
||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase
|
||||
import com.tangem.tap.domain.card.DefaultResetCardUseCase
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import com.tangem.domain.managetokens.repository.ManageTokensRepository
|
|||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -71,22 +69,18 @@ internal object ManageTokensDomainModule {
|
|||
walletManagersFacade: WalletManagersFacade,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
derivationsRepository: DerivationsRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): SaveManagedTokensUseCase {
|
||||
return SaveManagedTokensUseCase(
|
||||
customTokensRepository = customTokensRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
currenciesRepository = currenciesRepository,
|
||||
derivationsRepository = derivationsRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
|
|||
import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import dagger.Module
|
||||
|
|
@ -62,21 +60,17 @@ object MarketsDomainModule {
|
|||
derivationsRepository: DerivationsRepository,
|
||||
marketsTokenRepository: MarketsTokenRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): SaveMarketTokensUseCase {
|
||||
return SaveMarketTokensUseCase(
|
||||
derivationsRepository = derivationsRepository,
|
||||
marketsTokenRepository = marketsTokenRepository,
|
||||
currenciesRepository = currenciesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import com.tangem.domain.nft.*
|
|||
import com.tangem.domain.nft.repository.NFTRepository
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusFetcher
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -33,9 +35,13 @@ internal object NFTDomainModule {
|
|||
fun providesFetchNFTCollectionsUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
nftRepository: NFTRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchNFTCollectionsUseCase = FetchNFTCollectionsUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
nftRepository = nftRepository,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
|
||||
@Provides
|
||||
|
|
@ -43,9 +49,13 @@ internal object NFTDomainModule {
|
|||
fun providesRefreshAllNFTUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
nftRepository: NFTRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): RefreshAllNFTUseCase = RefreshAllNFTUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
nftRepository = nftRepository,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
|
||||
@Provides
|
||||
|
|
@ -118,8 +128,16 @@ internal object NFTDomainModule {
|
|||
walletsRepository: WalletsRepository,
|
||||
nftRepository: NFTRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): DisableWalletNFTUseCase {
|
||||
return DisableWalletNFTUseCase(walletsRepository, nftRepository, currenciesRepository)
|
||||
return DisableWalletNFTUseCase(
|
||||
walletsRepository = walletsRepository,
|
||||
nftRepository = nftRepository,
|
||||
currenciesRepository = currenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -94,12 +94,10 @@ internal object StakingDomainModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideFetchStakingYieldBalanceUseCase(
|
||||
stakingRepository: StakingRepository,
|
||||
stakingErrorResolver: StakingErrorResolver,
|
||||
singleYieldBalanceFetcher: SingleYieldBalanceFetcher,
|
||||
): FetchStakingYieldBalanceUseCase {
|
||||
return FetchStakingYieldBalanceUseCase(
|
||||
stakingRepository = stakingRepository,
|
||||
stakingErrorResolver = stakingErrorResolver,
|
||||
singleYieldBalanceFetcher = singleYieldBalanceFetcher,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,7 @@ package com.tangem.tap.di.domain
|
|||
import com.tangem.domain.swap.SwapErrorResolver
|
||||
import com.tangem.domain.swap.SwapRepositoryV2
|
||||
import com.tangem.domain.swap.SwapTransactionRepository
|
||||
import com.tangem.domain.swap.usecase.GetSwapPairsUseCase
|
||||
import com.tangem.domain.swap.usecase.GetSwapQuoteUseCase
|
||||
import com.tangem.domain.swap.usecase.GetSwapSupportedPairsUseCase
|
||||
import com.tangem.domain.swap.usecase.SelectInitialPairUseCase
|
||||
import com.tangem.domain.swap.usecase.*
|
||||
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -73,4 +70,30 @@ internal object SwapDomainModule {
|
|||
swapErrorResolver = swapErrorResolver,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetSwapDataUseCase(
|
||||
swapRepositoryV2: SwapRepositoryV2,
|
||||
swapErrorResolver: SwapErrorResolver,
|
||||
): GetSwapDataUseCase {
|
||||
return GetSwapDataUseCase(
|
||||
swapRepositoryV2 = swapRepositoryV2,
|
||||
swapErrorResolver = swapErrorResolver,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSwapTransactionSentUseCase(
|
||||
swapRepositoryV2: SwapRepositoryV2,
|
||||
swapTransactionRepository: SwapTransactionRepository,
|
||||
swapErrorResolver: SwapErrorResolver,
|
||||
): SwapTransactionSentUseCase {
|
||||
return SwapTransactionSentUseCase(
|
||||
swapRepositoryV2 = swapRepositoryV2,
|
||||
swapTransactionRepository = swapTransactionRepository,
|
||||
swapErrorResolver = swapErrorResolver,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import com.tangem.domain.tokens.operations.CachedCurrenciesStatusesOperations
|
|||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
|
||||
import com.tangem.domain.tokens.wallet.WalletBalanceFetcher
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.tap.domain.tokens.DefaultTokensFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -40,18 +41,18 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideAddCryptoCurrenciesUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
singleYieldBalanceFetcher: SingleYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): AddCryptoCurrenciesUseCase {
|
||||
return AddCryptoCurrenciesUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
singleYieldBalanceFetcher = singleYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -60,19 +61,15 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideFetchTokenListUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchTokenListUseCase {
|
||||
return FetchTokenListUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -107,8 +104,15 @@ internal object TokensDomainModule {
|
|||
fun provideRemoveCurrencyUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): RemoveCurrencyUseCase {
|
||||
return RemoveCurrencyUseCase(currenciesRepository, walletManagersFacade)
|
||||
return RemoveCurrencyUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -145,6 +149,8 @@ internal object TokensDomainModule {
|
|||
currencyChecksRepository: CurrencyChecksRepository,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
baseCurrencyStatusOperations: BaseCurrencyStatusOperations,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): GetCurrencyWarningsUseCase {
|
||||
return GetCurrencyWarningsUseCase(
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
|
|
@ -152,6 +158,8 @@ internal object TokensDomainModule {
|
|||
dispatchers = dispatchers,
|
||||
currencyChecksRepository = currencyChecksRepository,
|
||||
currencyStatusOperations = baseCurrencyStatusOperations,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -159,18 +167,18 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideFetchCurrencyStatusUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
singleNetworkStatusFetcher: SingleNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
singleYieldBalanceFetcher: SingleYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchCurrencyStatusUseCase {
|
||||
return FetchCurrencyStatusUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
singleNetworkStatusFetcher = singleNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
singleYieldBalanceFetcher = singleYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -179,26 +187,26 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideFetchCardTokenListUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchCardTokenListUseCase {
|
||||
return FetchCardTokenListUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCryptoCurrencyUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrencyUseCase {
|
||||
return GetCryptoCurrencyUseCase(currenciesRepository)
|
||||
fun provideGetCryptoCurrencyUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): GetCryptoCurrencyUseCase {
|
||||
return GetCryptoCurrencyUseCase(currenciesRepository, multiWalletCryptoCurrenciesSupplier, tokensFeatureToggles)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -219,9 +227,16 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideApplyTokenListSortingUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): ApplyTokenListSortingUseCase {
|
||||
return ApplyTokenListSortingUseCase(currenciesRepository, dispatchers)
|
||||
return ApplyTokenListSortingUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -280,9 +295,13 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideIsCryptoCurrencyCoinCouldHideUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): IsCryptoCurrencyCoinCouldHideUseCase {
|
||||
return IsCryptoCurrencyCoinCouldHideUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -300,9 +319,16 @@ internal object TokensDomainModule {
|
|||
@Singleton
|
||||
fun provideGetBalanceNotEnoughForFeeWarningUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): GetBalanceNotEnoughForFeeWarningUseCase {
|
||||
return GetBalanceNotEnoughForFeeWarningUseCase(currenciesRepository, dispatchers)
|
||||
return GetBalanceNotEnoughForFeeWarningUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -343,10 +369,14 @@ internal object TokensDomainModule {
|
|||
fun provideRefreshMultiCurrencyWalletQuotesUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): RefreshMultiCurrencyWalletQuotesUseCase {
|
||||
return RefreshMultiCurrencyWalletQuotesUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -374,6 +404,7 @@ internal object TokensDomainModule {
|
|||
singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
|
||||
singleYieldBalanceSupplier: SingleYieldBalanceSupplier,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
): BaseCurrenciesStatusesOperations {
|
||||
return CachedCurrenciesStatusesOperations(
|
||||
currenciesRepository = currenciesRepository,
|
||||
|
|
@ -388,6 +419,7 @@ internal object TokensDomainModule {
|
|||
singleYieldBalanceSupplier = singleYieldBalanceSupplier,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -406,6 +438,7 @@ internal object TokensDomainModule {
|
|||
singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
|
||||
singleYieldBalanceSupplier: SingleYieldBalanceSupplier,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
): BaseCurrencyStatusOperations {
|
||||
return CachedCurrenciesStatusesOperations(
|
||||
currenciesRepository = currenciesRepository,
|
||||
|
|
@ -419,6 +452,7 @@ internal object TokensDomainModule {
|
|||
singleQuoteStatusSupplier = singleQuoteStatusSupplier,
|
||||
singleYieldBalanceSupplier = singleYieldBalanceSupplier,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -428,4 +462,26 @@ internal object TokensDomainModule {
|
|||
fun provideGetCryptoCurrenciesUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrenciesUseCase {
|
||||
return GetCryptoCurrenciesUseCase(currenciesRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideWalletBalanceFetcher(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
multiWalletCryptoCurrenciesFetcher: MultiWalletCryptoCurrenciesFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher: MultiYieldBalanceFetcher,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): WalletBalanceFetcher {
|
||||
return WalletBalanceFetcher(
|
||||
currenciesRepository = currenciesRepository,
|
||||
multiWalletCryptoCurrenciesFetcher = multiWalletCryptoCurrenciesFetcher,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiYieldBalanceFetcher = multiYieldBalanceFetcher,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,17 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
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
|
||||
|
|
@ -41,6 +44,7 @@ internal object TransactionDomainModule {
|
|||
transactionRepository: TransactionRepository,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
singleNetworkStatusFetcher: SingleNetworkStatusFetcher,
|
||||
tangemHotWalletSignerFactory: TangemHotWalletSigner.Factory,
|
||||
): SendTransactionUseCase {
|
||||
return SendTransactionUseCase(
|
||||
demoConfig = DemoConfig(),
|
||||
|
|
@ -48,6 +52,7 @@ internal object TransactionDomainModule {
|
|||
transactionRepository = transactionRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
singleNetworkStatusFetcher = singleNetworkStatusFetcher,
|
||||
getHotWalletSigner = tangemHotWalletSignerFactory::create,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -58,12 +63,16 @@ internal object TransactionDomainModule {
|
|||
walletManagersFacade: WalletManagersFacade,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
|
||||
multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): AssociateAssetUseCase {
|
||||
return AssociateAssetUseCase(
|
||||
cardSdkConfigRepository = cardSdkConfigRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
currenciesRepository = currenciesRepository,
|
||||
singleNetworkStatusSupplier = singleNetworkStatusSupplier,
|
||||
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
import com.tangem.datasource.asset.loader.AssetLoader
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.datasource.local.walletmanager.WalletManagersStore
|
||||
import com.tangem.domain.walletmanager.DefaultWalletManagersFacade
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
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 WalletManagersFacadeModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideWalletManagersFacade(
|
||||
walletManagersStore: WalletManagersStore,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
assetLoader: AssetLoader,
|
||||
blockchainSDKFactory: BlockchainSDKFactory,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): WalletManagersFacade {
|
||||
return DefaultWalletManagersFacade(
|
||||
walletManagersStore = walletManagersStore,
|
||||
userWalletsStore = userWalletsStore,
|
||||
assetLoader = assetLoader,
|
||||
dispatchers = dispatchers,
|
||||
blockchainSDKFactory = blockchainSDKFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -15,10 +15,7 @@ import com.tangem.domain.wallets.repository.WalletsRepository
|
|||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSyncUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.features.nft.NFTFeatureToggles
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -191,28 +188,14 @@ internal object WalletsDomainModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCardImageUseCase(
|
||||
onlineCardVerifier: OnlineCardVerifier,
|
||||
cardArtworksProvider: CardArtworksProvider,
|
||||
cardSdkFeatureToggles: CardSdkFeatureToggles,
|
||||
): GetCardImageUseCase {
|
||||
return GetCardImageUseCase(
|
||||
verifier = onlineCardVerifier,
|
||||
cardArtworksProvider = cardArtworksProvider,
|
||||
cardSdkFeatureToggles = cardSdkFeatureToggles,
|
||||
)
|
||||
fun provideGetCardImageUseCase(cardArtworksProvider: CardArtworksProvider): GetCardImageUseCase {
|
||||
return GetCardImageUseCase(cardArtworksProvider = cardArtworksProvider)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesIsWalletNFTEnabledSyncUseCase(
|
||||
walletsRepository: WalletsRepository,
|
||||
nftFeatureToggles: NFTFeatureToggles,
|
||||
): IsWalletNFTEnabledSyncUseCase {
|
||||
return IsWalletNFTEnabledSyncUseCase(
|
||||
walletsRepository = walletsRepository,
|
||||
nftFeatureToggles = nftFeatureToggles,
|
||||
)
|
||||
fun providesIsWalletNFTEnabledSyncUseCase(walletsRepository: WalletsRepository): IsWalletNFTEnabledSyncUseCase {
|
||||
return IsWalletNFTEnabledSyncUseCase(walletsRepository = walletsRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
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
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface TangemHotSdkModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindTangemHotSdk(proxy: TangemHotSDKProxy): TangemHotSdk
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindHotWalletPasswordRequester(impl: DefaultHotWalletPasswordRequester): HotWalletPasswordRequester
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package com.tangem.tap.di.routing
|
||||
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.common.routing.RoutingFeatureToggle
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.tap.routing.ProxyAppRouter
|
||||
import com.tangem.tap.routing.configurator.AppRouterConfig
|
||||
import com.tangem.tap.routing.configurator.MutableAppRouterConfig
|
||||
|
|
@ -33,10 +31,4 @@ internal object AppRouterModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideAppRouterConfigurator(): AppRouterConfig = MutableAppRouterConfig()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRoutingFeatureToggle(featureTogglesManager: FeatureTogglesManager): RoutingFeatureToggle {
|
||||
return RoutingFeatureToggle(featureTogglesManager)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,7 @@ import com.tangem.blockchain.common.Token
|
|||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -35,14 +34,15 @@ class TapWalletManager(
|
|||
}
|
||||
|
||||
private suspend fun loadUserWalletData(userWallet: UserWallet) {
|
||||
Analytics.setContext(userWallet.requireColdWallet().scanResponse) // [REDACTED_TASK_KEY]
|
||||
val scanResponse = userWallet.scanResponse
|
||||
Analytics.setContext(userWallet)
|
||||
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
|
||||
|
||||
withMainContext {
|
||||
// Order is important
|
||||
store.dispatch(GlobalAction.SaveScanResponse(scanResponse))
|
||||
if (userWallet is UserWallet.Cold) {
|
||||
val scanResponse = userWallet.scanResponse
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
|
||||
withMainContext {
|
||||
// Order is important
|
||||
store.dispatch(GlobalAction.SaveScanResponse(scanResponse))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ import com.tangem.domain.card.repository.DerivationsRepository
|
|||
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.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter
|
||||
|
|
@ -50,7 +50,7 @@ internal class DefaultDerivationsRepository(
|
|||
networkFactory.create(
|
||||
blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
userWallet = userWallet,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -61,7 +61,11 @@ internal class DefaultDerivationsRepository(
|
|||
userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found")
|
||||
}
|
||||
|
||||
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
||||
if (userWallet is UserWallet.Hot) {
|
||||
return
|
||||
}
|
||||
|
||||
userWallet.requireColdWallet()
|
||||
|
||||
if (!userWallet.scanResponse.card.settings.isHDWalletAllowed) {
|
||||
Timber.d("Nothing to derive")
|
||||
|
|
@ -84,14 +88,18 @@ internal class DefaultDerivationsRepository(
|
|||
): Boolean {
|
||||
val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found")
|
||||
|
||||
if (userWallet is UserWallet.Hot) {
|
||||
return false
|
||||
}
|
||||
|
||||
val derivations =
|
||||
MissedDerivationsFinder(scanResponse = userWallet.requireColdWallet().scanResponse) // TODO [REDACTED_TASK_KEY]
|
||||
MissedDerivationsFinder(scanResponse = userWallet.requireColdWallet().scanResponse)
|
||||
.findByNetworks(
|
||||
networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) ->
|
||||
networkFactory.create(
|
||||
blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
userWallet = userWallet,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import com.tangem.common.core.UserCodeRequestPolicy
|
|||
import com.tangem.domain.card.ResetCardUseCase
|
||||
import com.tangem.domain.card.ResetCardUserCodeParams
|
||||
import com.tangem.domain.card.models.ResetCardError
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
|
||||
internal class DefaultResetCardUseCase(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.common.card.EllipticCurve
|
|||
import com.tangem.common.extensions.ByteArrayKey
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.card.configs.CardConfig
|
||||
import com.tangem.domain.card.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.scan.KeyWalletPublicKey
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
package com.tangem.tap.domain.extensions
|
||||
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.domain.common.getTwinCardNumber
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.wallets.models.Artwork
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.api.models.CardVerifyAndGetInfo
|
||||
|
||||
fun CardDTO.signedHashesCount(): Int {
|
||||
return wallets.sumOf { it.totalSignedHashes ?: 0 }
|
||||
}
|
||||
|
||||
suspend fun CardDTO.getOrLoadCardArtworkUrl(
|
||||
cardInfo: Result<CardVerifyAndGetInfo.Response.Item>? = null,
|
||||
onlineCardVerifier: OnlineCardVerifier,
|
||||
): String {
|
||||
fun ifAnyError(): String {
|
||||
return when {
|
||||
cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL
|
||||
cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL
|
||||
else -> {
|
||||
when (getTwinCardNumber()) {
|
||||
TwinCardNumber.First -> Artwork.TWIN_CARD_1_URL
|
||||
TwinCardNumber.Second -> Artwork.TWIN_CARD_2_URL
|
||||
else -> Artwork.DEFAULT_IMG_URL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return when (val cardInfoResult = cardInfo ?: onlineCardVerifier.getCardInfo(cardId, cardPublicKey)) {
|
||||
is Result.Success -> {
|
||||
val artworkId = cardInfoResult.data.artwork?.id
|
||||
if (artworkId.isNullOrEmpty()) {
|
||||
ifAnyError()
|
||||
} else {
|
||||
CardArtworksProvider.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
}
|
||||
}
|
||||
|
||||
is Result.Failure -> ifAnyError()
|
||||
}
|
||||
}
|
||||
113
app/src/main/java/com/tangem/tap/domain/hot/HotWalletAccessor.kt
Normal file
113
app/src/main/java/com/tangem/tap/domain/hot/HotWalletAccessor.kt
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
package com.tangem.tap.domain.hot
|
||||
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.features.hotwallet.HotWalletPasswordRequester
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.exception.WrongPasswordException
|
||||
import com.tangem.hot.sdk.model.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class HotWalletAccessor @Inject constructor(
|
||||
private val tangemHotSdk: TangemHotSdk,
|
||||
private val hotWalletPasswordRequester: HotWalletPasswordRequester,
|
||||
) {
|
||||
|
||||
suspend fun signHashes(hotWalletId: HotWalletId, dataToSign: List<DataToSign>): List<SignedData> {
|
||||
val auth = when (hotWalletId.authType) {
|
||||
HotWalletId.AuthType.NoPassword -> HotAuth.NoAuth
|
||||
HotWalletId.AuthType.Password -> requestPassword(false)
|
||||
HotWalletId.AuthType.Biometry -> HotAuth.Biometry
|
||||
}
|
||||
|
||||
return runCatchingSdkErrors(hotWalletId, auth) {
|
||||
tangemHotSdk.signHashes(
|
||||
unlockHotWallet = UnlockHotWallet(
|
||||
walletId = hotWalletId,
|
||||
auth = it,
|
||||
),
|
||||
dataToSign = dataToSign,
|
||||
).also {
|
||||
hotWalletPasswordRequester.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> runCatchingSdkErrors(
|
||||
hotWalletId: HotWalletId,
|
||||
auth: HotAuth,
|
||||
block: suspend (auth: HotAuth) -> T,
|
||||
): T {
|
||||
return runCatchingWrongPassInternal(
|
||||
originalAuth = auth,
|
||||
auth = auth,
|
||||
block = { blockAuth ->
|
||||
block(blockAuth).also {
|
||||
// TODO [REDACTED_TASK_KEY] if user has biometry enabled, we set it as the new auth method
|
||||
if (blockAuth is HotAuth.Password /*&& has biometry enabled */) {
|
||||
tangemHotSdk.changeAuth(
|
||||
unlockHotWallet = UnlockHotWallet(
|
||||
walletId = hotWalletId,
|
||||
auth = blockAuth,
|
||||
),
|
||||
auth = HotAuth.Biometry,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun <T> runCatchingWrongPassInternal(
|
||||
originalAuth: HotAuth,
|
||||
auth: HotAuth,
|
||||
block: suspend (auth: HotAuth) -> T,
|
||||
): T = runCatching {
|
||||
block(auth)
|
||||
}.getOrElse { exception ->
|
||||
if (auth is HotAuth.Biometry && exception.isBiometryError()) {
|
||||
// fallback to password if biometry fails
|
||||
val passAuth = requestPassword(true)
|
||||
|
||||
return@getOrElse runCatchingWrongPassInternal(
|
||||
originalAuth = originalAuth,
|
||||
auth = passAuth,
|
||||
block = block,
|
||||
)
|
||||
}
|
||||
|
||||
if (exception !is WrongPasswordException) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
// If the exception is a wrong password, we need to request the password again
|
||||
|
||||
hotWalletPasswordRequester.wrongPassword()
|
||||
val passResult = requestPassword(originalAuth is HotAuth.Biometry)
|
||||
|
||||
runCatchingWrongPassInternal(
|
||||
originalAuth = originalAuth,
|
||||
auth = passResult,
|
||||
block = block,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun requestPassword(hasBiometry: Boolean): HotAuth {
|
||||
return hotWalletPasswordRequester.requestPassword(hasBiometry).toAuth() ?: throw TangemSdkError.UserCancelled()
|
||||
}
|
||||
|
||||
private fun Throwable.isBiometryError(): Boolean {
|
||||
return this is TangemSdkError.AuthenticationFailed ||
|
||||
this is TangemSdkError.AuthenticationCanceled ||
|
||||
this is TangemSdkError.AuthenticationLockout ||
|
||||
this is TangemSdkError.AuthenticationUnavailable ||
|
||||
this is TangemSdkError.AuthenticationAlreadyInProgress ||
|
||||
this is TangemSdkError.AuthenticationNotInitialized ||
|
||||
this is TangemSdkError.AuthenticationPermanentLockout
|
||||
}
|
||||
|
||||
private fun HotWalletPasswordRequester.Result.toAuth() = when (this) {
|
||||
HotWalletPasswordRequester.Result.UseBiometry -> HotAuth.Biometry
|
||||
HotWalletPasswordRequester.Result.Dismiss -> null
|
||||
is HotWalletPasswordRequester.Result.EnteredPassword -> this.password
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
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
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
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<ByteArray> {
|
||||
return sign(listOf(hash), publicKey).map { it.first() }
|
||||
}
|
||||
|
||||
override suspend fun sign(
|
||||
hashes: List<ByteArray>,
|
||||
publicKey: Wallet.PublicKey,
|
||||
): CompletionResult<List<ByteArray>> {
|
||||
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<SignData>,
|
||||
publicKey: Wallet.PublicKey,
|
||||
): CompletionResult<Map<ByteArray, ByteArray>> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
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
|
||||
import timber.log.Timber
|
||||
|
||||
class TangemHotWalletSigner @AssistedInject constructor(
|
||||
@Assisted private val userWallet: UserWallet.Hot,
|
||||
private val hotWalletAccessor: HotWalletAccessor,
|
||||
) : TransactionSigner {
|
||||
|
||||
override suspend fun sign(hash: ByteArray, publicKey: Wallet.PublicKey): CompletionResult<ByteArray> {
|
||||
return sign(listOf(hash), publicKey).map { it.first() }
|
||||
}
|
||||
|
||||
override suspend fun sign(
|
||||
hashes: List<ByteArray>,
|
||||
publicKey: Wallet.PublicKey,
|
||||
): CompletionResult<List<ByteArray>> {
|
||||
val wallet = userWallet.wallets.orEmpty().firstOrNull { it.publicKey.contentEquals(publicKey.seedKey) }
|
||||
?: return CompletionResult.Failure(
|
||||
TangemSdkError.ExceptionError(IllegalStateException("wallet is locked")),
|
||||
)
|
||||
|
||||
val result = runCatching {
|
||||
hotWalletAccessor.signHashes(
|
||||
hotWalletId = userWallet.hotWalletId,
|
||||
dataToSign = listOf(
|
||||
DataToSign(
|
||||
curve = wallet.curve,
|
||||
hashes = hashes,
|
||||
derivationPath = publicKey.derivationPath,
|
||||
),
|
||||
),
|
||||
)
|
||||
}.getOrElse {
|
||||
Timber.e(it)
|
||||
return if (it is TangemSdkError) {
|
||||
CompletionResult.Failure(it)
|
||||
} else {
|
||||
CompletionResult.Failure(TangemSdkError.ExceptionError(it))
|
||||
}
|
||||
}
|
||||
|
||||
return CompletionResult.Success(result.map { it.signatures }.flatten())
|
||||
}
|
||||
|
||||
override suspend fun multiSign(
|
||||
dataToSign: List<SignData>,
|
||||
publicKey: Wallet.PublicKey,
|
||||
): CompletionResult<Map<ByteArray, ByteArray>> {
|
||||
val result = runCatching {
|
||||
hotWalletAccessor.signHashes(
|
||||
hotWalletId = userWallet.hotWalletId,
|
||||
dataToSign = dataToSign.map { signData ->
|
||||
val wallet =
|
||||
userWallet.wallets.orEmpty().firstOrNull { it.publicKey.contentEquals(signData.publicKey) }
|
||||
?: return CompletionResult.Failure(
|
||||
TangemSdkError.ExceptionError(IllegalStateException("wallet is locked")),
|
||||
)
|
||||
|
||||
DataToSign(
|
||||
curve = wallet.curve,
|
||||
hashes = listOf(signData.hash),
|
||||
derivationPath = signData.derivationPath,
|
||||
)
|
||||
},
|
||||
)
|
||||
}.getOrElse {
|
||||
Timber.e(it)
|
||||
return if (it is TangemSdkError) {
|
||||
CompletionResult.Failure(it)
|
||||
} else {
|
||||
CompletionResult.Failure(TangemSdkError.ExceptionError(it))
|
||||
}
|
||||
}
|
||||
|
||||
return CompletionResult.Success(
|
||||
result.mapIndexed { index, data ->
|
||||
dataToSign[index].publicKey to data.signatures.first()
|
||||
}.toMap(),
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(@Assisted userWallet: UserWallet.Hot): TangemHotWalletSigner
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.domain.model
|
||||
|
||||
import com.tangem.domain.common.BlockchainNetwork
|
||||
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.blockchain.common.Blockchain as SdkBlockchain
|
||||
|
|
@ -32,21 +31,6 @@ sealed interface Currency {
|
|||
}
|
||||
|
||||
companion object {
|
||||
fun fromBlockchainNetwork(blockchainNetwork: BlockchainNetwork, token: SdkToken? = null): Currency {
|
||||
return if (token != null) {
|
||||
Token(
|
||||
token = token,
|
||||
blockchain = blockchainNetwork.blockchain,
|
||||
derivationPath = blockchainNetwork.derivationPath,
|
||||
)
|
||||
} else {
|
||||
Blockchain(
|
||||
blockchain = blockchainNetwork.blockchain,
|
||||
derivationPath = blockchainNetwork.derivationPath,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun fromCustomCurrency(customCurrency: CustomCurrency): Currency {
|
||||
return when (customCurrency) {
|
||||
is CustomCurrency.CustomBlockchain -> Blockchain(
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.extensions.toWrappedList
|
||||
import com.tangem.core.ui.message.dialog.Dialogs
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.domain.common.util.twinsIsTwinned
|
||||
import com.tangem.domain.card.common.util.twinsIsTwinned
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import arrow.core.right
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.domain.card.ScanCardException
|
||||
import com.tangem.domain.common.util.twinsIsTwinned
|
||||
import com.tangem.domain.card.common.util.twinsIsTwinned
|
||||
import com.tangem.domain.core.chain.Chain
|
||||
import com.tangem.domain.core.chain.ResultChain
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ import com.tangem.crypto.bip39.DefaultMnemonic
|
|||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.model.VisaActivationInput
|
||||
import com.tangem.domain.visa.model.VisaDataForApprove
|
||||
import com.tangem.domain.visa.model.VisaSignedDataByCustomerWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||
import com.tangem.operations.ScanTask
|
||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ import com.tangem.crypto.hdWallet.DerivationPath
|
|||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.model.VisaActivationInput
|
||||
import com.tangem.domain.visa.model.VisaDataForApprove
|
||||
import com.tangem.domain.visa.model.VisaSignedDataByCustomerWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||
import com.tangem.operations.preflightread.PreflightReadFilter
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
|
|
|
|||
|
|
@ -177,6 +177,13 @@ object WalletMockContent : MockContent {
|
|||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
|
||||
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
|
||||
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
|
||||
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
|
||||
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ 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.domain.wallets.models.UserWalletId
|
||||
import com.tangem.operations.preflightread.PreflightReadFilter
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import com.tangem.common.extensions.toMapKey
|
|||
import com.tangem.common.map
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.domain.card.DerivationStyleProvider
|
||||
import com.tangem.domain.card.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.card.configs.CardConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.operations.backup.PrimaryCard
|
||||
import com.tangem.operations.backup.StartPrimaryCardLinkingCommand
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ 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.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.card.DerivationStyleProvider
|
||||
import com.tangem.domain.card.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
import com.tangem.common.core.CompletionCallback
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.operations.PreflightReadMode
|
||||
import com.tangem.operations.PreflightReadTask
|
||||
import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter
|
||||
|
|
|
|||
|
|
@ -14,16 +14,16 @@ 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.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.isExcluded
|
||||
import com.tangem.domain.common.TapWorkarounds.isNotSupportedInThatRelease
|
||||
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.common.TapWorkarounds.isVisa
|
||||
import com.tangem.domain.card.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.common.configs.CardConfig
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.common.visa.VisaUtilities
|
||||
import com.tangem.domain.card.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.card.common.visa.VisaUtilities
|
||||
import com.tangem.domain.card.configs.CardConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.CardDTO.Companion.RING_BATCH_IDS
|
||||
import com.tangem.domain.models.scan.CardDTO.Companion.RING_BATCH_PREFIX
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import com.tangem.datasource.local.visa.VisaAuthTokenStorage
|
|||
import com.tangem.datasource.local.visa.VisaOTPStorage
|
||||
import com.tangem.datasource.local.visa.VisaOtpData
|
||||
import com.tangem.datasource.local.visa.hasSavedOTP
|
||||
import com.tangem.domain.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.visa.error.VisaActivationError
|
||||
import com.tangem.domain.visa.model.*
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ 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.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.common.visa.VisaUtilities
|
||||
import com.tangem.domain.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.common.visa.VisaWalletPublicKeyUtility.findKeyWithoutDerivation
|
||||
import com.tangem.domain.card.common.util.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
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.visa.error.VisaActivationError
|
||||
import com.tangem.domain.visa.model.VisaDataForApprove
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ internal class DefaultTokensFeatureToggles(
|
|||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
) : TokensFeatureToggles {
|
||||
|
||||
override val isStakingLoadingRefactoringEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "STAKING_LOADING_REFACTORING_ENABLED")
|
||||
|
||||
override val isWalletBalanceFetcherEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "WALLET_BALANCE_FETCHER_ENABLED")
|
||||
}
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
package com.tangem.tap.domain.userWalletList.implementation
|
||||
|
||||
import com.tangem.common.*
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListError
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.isLocked
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository
|
||||
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
|
||||
|
|
@ -213,8 +212,7 @@ internal class BiometricUserWalletsListManager(
|
|||
changeSelectedUserWallet: Boolean,
|
||||
canOverridePublicInfo: Boolean,
|
||||
): CompletionResult<Unit> {
|
||||
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
||||
val encryptionKey = userWallet.scanResponse.card.encryptionKey
|
||||
val encryptionKey = userWallet.encryptionKey
|
||||
?.let { UserWalletEncryptionKey(userWallet.walletId, it) }
|
||||
?: return CompletionResult.Success(Unit) // No encryption key, no need to save
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.get
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ package com.tangem.tap.domain.userWalletList.implementation
|
|||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.catching
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListError
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.domain.userWalletList.model
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserWalletEncryptionKey(
|
||||
|
|
|
|||
|
|
@ -2,31 +2,44 @@ package com.tangem.tap.domain.userWalletList.model
|
|||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.domain.models.MobileWallet
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.model.VisaCardActivationStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserWalletSensitiveInformation(
|
||||
// Cold
|
||||
@Json(name = "wallets")
|
||||
val wallets: List<CardDTO.Wallet>,
|
||||
val wallets: List<CardDTO.Wallet>?,
|
||||
@Json(name = "visaCardActivationStatus")
|
||||
val visaCardActivationStatus: VisaCardActivationStatus? = null,
|
||||
// Hot
|
||||
@Json(name = "mobileWallets")
|
||||
val mobileWallets: List<MobileWallet>? = null,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserWalletPublicInformation(
|
||||
// Common
|
||||
@Json(name = "name")
|
||||
val name: String,
|
||||
@Json(name = "walletId")
|
||||
val walletId: UserWalletId,
|
||||
// Cold
|
||||
@Json(name = "cardsInWallet")
|
||||
val cardsInWallet: Set<String>,
|
||||
@Json(name = "scanResponse")
|
||||
val scanResponse: ScanResponse,
|
||||
val scanResponse: ScanResponse?,
|
||||
@Json(name = "isMultiCurrency")
|
||||
val isMultiCurrency: Boolean,
|
||||
@Json(name = "hasBackupError")
|
||||
val hasBackupError: Boolean = false,
|
||||
// Hot
|
||||
@Json(name = "hotWalletId")
|
||||
val hotWalletId: HotWalletId? = null,
|
||||
@Json(name = "backedUp")
|
||||
val backedUp: Boolean? = null,
|
||||
)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.domain.userWalletList.repository
|
||||
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
internal interface SelectedUserWalletRepository {
|
||||
suspend fun get(): UserWalletId?
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.domain.userWalletList.repository
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
|
||||
internal interface UserWalletsKeysRepository {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.domain.userWalletList.repository
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
|
||||
|
||||
internal interface UserWalletsPublicInformationRepository {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.domain.userWalletList.repository
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import com.tangem.common.services.secure.SecureStorage
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListError
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.domain.userWalletList.repository.implementation
|
||||
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.catching
|
||||
import com.tangem.common.flatMap
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
|
||||
import com.tangem.tap.domain.userWalletList.repository.UserWalletsPublicInformationRepository
|
||||
import com.tangem.tap.domain.userWalletList.utils.publicInformation
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.catching
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.crypto.operations.AESCipherOperations
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils
|
||||
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
|
||||
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
|
||||
|
||||
|
|
@ -10,8 +11,12 @@ internal val UserWallet.sensitiveInformation: UserWalletSensitiveInformation
|
|||
is UserWallet.Cold -> UserWalletSensitiveInformation(
|
||||
wallets = scanResponse.card.wallets,
|
||||
visaCardActivationStatus = scanResponse.visaCardActivationStatus,
|
||||
mobileWallets = null,
|
||||
)
|
||||
is UserWallet.Hot -> UserWalletSensitiveInformation(
|
||||
wallets = null,
|
||||
mobileWallets = this.wallets,
|
||||
)
|
||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
||||
}
|
||||
|
||||
internal val UserWallet.publicInformation: UserWalletPublicInformation
|
||||
|
|
@ -28,19 +33,39 @@ internal val UserWallet.publicInformation: UserWalletPublicInformation
|
|||
visaCardActivationStatus = null,
|
||||
),
|
||||
hasBackupError = hasBackupError,
|
||||
hotWalletId = null,
|
||||
backedUp = null,
|
||||
)
|
||||
is UserWallet.Hot -> UserWalletPublicInformation(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
cardsInWallet = emptySet(),
|
||||
scanResponse = null,
|
||||
hotWalletId = hotWalletId,
|
||||
backedUp = backedUp,
|
||||
)
|
||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
||||
}
|
||||
|
||||
internal fun UserWalletPublicInformation.toUserWallet(): UserWallet {
|
||||
return UserWallet.Cold(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
cardsInWallet = cardsInWallet,
|
||||
scanResponse = scanResponse,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
hasBackupError = hasBackupError,
|
||||
)
|
||||
return if (hotWalletId != null) {
|
||||
UserWallet.Hot(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
hotWalletId = hotWalletId,
|
||||
wallets = null,
|
||||
backedUp = backedUp!!,
|
||||
)
|
||||
} else {
|
||||
UserWallet.Cold(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
cardsInWallet = cardsInWallet,
|
||||
scanResponse = scanResponse!!,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
hasBackupError = hasBackupError,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun List<UserWalletPublicInformation>.toUserWallets(): List<UserWallet> {
|
||||
|
|
@ -53,13 +78,15 @@ internal fun UserWallet.updateWith(sensitiveInformation: UserWalletSensitiveInfo
|
|||
copy(
|
||||
scanResponse = scanResponse.copy(
|
||||
card = scanResponse.card.copy(
|
||||
wallets = sensitiveInformation.wallets,
|
||||
wallets = sensitiveInformation.wallets!!,
|
||||
),
|
||||
visaCardActivationStatus = sensitiveInformation.visaCardActivationStatus,
|
||||
),
|
||||
)
|
||||
}
|
||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
||||
is UserWallet.Hot -> copy(
|
||||
wallets = sensitiveInformation.mobileWallets,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,5 +117,5 @@ internal fun UserWallet.lock(): UserWallet = when (this) {
|
|||
),
|
||||
)
|
||||
}
|
||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
||||
is UserWallet.Hot -> copy(wallets = null)
|
||||
}
|
||||
|
|
@ -1,11 +1,16 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils
|
||||
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.common.extensions.calculateHmacSha256
|
||||
import com.tangem.domain.models.MobileWallet
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
||||
internal val CardDTO.encryptionKey: ByteArray?
|
||||
get() = findPublicKey(wallets)?.let { calculateEncryptionKey(it) }
|
||||
internal val UserWallet.encryptionKey: ByteArray?
|
||||
get() = when (this) {
|
||||
is UserWallet.Cold -> findPublicKey(this.scanResponse.card.wallets)
|
||||
is UserWallet.Hot -> findPublicKey(this.wallets.orEmpty())
|
||||
}?.let { calculateEncryptionKey(it) }
|
||||
|
||||
private fun calculateEncryptionKey(publicKey: ByteArray): ByteArray {
|
||||
val message = MESSAGE_FOR_ENCRYPTION_KEY.toByteArray()
|
||||
|
|
@ -15,8 +20,12 @@ private fun calculateEncryptionKey(publicKey: ByteArray): ByteArray {
|
|||
}
|
||||
|
||||
private fun findPublicKey(wallets: List<CardDTO.Wallet>): ByteArray? {
|
||||
return wallets.firstOrNull()
|
||||
?.publicKey
|
||||
return wallets.firstOrNull()?.publicKey
|
||||
}
|
||||
|
||||
@JvmName("findPublicKeyInMobileWallets")
|
||||
private fun findPublicKey(wallets: List<MobileWallet>): ByteArray? {
|
||||
return wallets.firstOrNull()?.publicKey
|
||||
}
|
||||
|
||||
private const val MESSAGE_FOR_ENCRYPTION_KEY = "UserWalletEncryptionKey"
|
||||
|
|
@ -9,7 +9,7 @@ import com.tangem.common.extensions.hexToBytes
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.core.error.ext.tangemError
|
||||
import com.tangem.datasource.local.visa.VisaAuthTokenStorage
|
||||
import com.tangem.domain.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.visa.error.VisaActivationError
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.domain.visa.error.VisaCardScanError
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.Basic.TransactionSent.MemoType
|
||||
import com.tangem.data.walletconnect.network.ethereum.LegacySdkHelper
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.operations.sign.SignHashCommand
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ import com.reown.android.relay.ConnectionType
|
|||
import com.reown.walletkit.client.Wallet
|
||||
import com.reown.walletkit.client.WalletKit
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.data.walletconnect.pair.unsupportedDApps
|
||||
import com.tangem.data.walletconnect.pair.UnsupportedDApps
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.walletconnect.WcPairService
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.walletconnect.model.legacy.Account
|
||||
import com.tangem.domain.walletconnect.usecase.initialize.WcInitializeUseCase
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
import com.tangem.tap.domain.walletconnect2.app.TangemWcBlockchainHelper
|
||||
|
|
@ -216,7 +216,7 @@ internal class DefaultLegacyWalletConnectRepository(
|
|||
Timber.i("sessionProposal: $sessionProposal")
|
||||
this@DefaultLegacyWalletConnectRepository.sessionProposal = sessionProposal
|
||||
|
||||
if (sessionProposal.name in unsupportedDApps) {
|
||||
if (sessionProposal.name in UnsupportedDApps.list) {
|
||||
Timber.i("Unsupported DApp")
|
||||
scope.launch {
|
||||
_events.emit(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.domain.walletconnect2.domain
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.walletconnect.model.legacy.Account
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.*
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction.OpenSession.SourceType
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
|
|||
|
|
@ -5,16 +5,15 @@ import com.tangem.blockchainsdk.utils.toBlockchain
|
|||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
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.isMultiCurrency
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.walletconnect.model.legacy.Account
|
||||
import com.tangem.domain.walletconnect.model.legacy.Session
|
||||
import com.tangem.domain.walletconnect.model.legacy.WalletConnectSessionsRepository
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
|
|
@ -422,8 +421,7 @@ class WalletConnectInteractor(
|
|||
}
|
||||
|
||||
private fun getCardId(userWallet: UserWallet): String? {
|
||||
userWallet.requireColdWallet() // [REDACTED_TASK_KEY]
|
||||
return if (userWallet.scanResponse.card.backupStatus?.isActive != true) {
|
||||
return if (userWallet is UserWallet.Cold && userWallet.scanResponse.card.backupStatus?.isActive != true) {
|
||||
userWallet.cardId
|
||||
} else { // if wallet has backup, any card from wallet can be used to sign
|
||||
null
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.features.demo
|
|||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
|
|
@ -43,9 +43,6 @@ object DemoHelper {
|
|||
}
|
||||
|
||||
private fun getScanResponse(appState: () -> AppState?): ScanResponse? {
|
||||
val state = appState() ?: return null
|
||||
|
||||
return state.globalState.onboardingState.onboardingManager?.scanResponse
|
||||
?: state.globalState.scanResponse
|
||||
return appState()?.globalState?.scanResponse
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.demo
|
||||
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import org.rekotlin.Action
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import org.rekotlin.Action
|
|||
sealed class DetailsAction : Action {
|
||||
|
||||
data class PrepareScreen(
|
||||
val scanResponse: ScanResponse,
|
||||
val scanResponse: ScanResponse?,
|
||||
val initializedAppSettingsState: AppSettingsState,
|
||||
) : DetailsAction()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.details.redux.walletconnect
|
||||
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WcPreparedRequest
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectError
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectEvents
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.features.details.ui.cardsettings.api
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface CardSettingsComponent : ComposableContentComponent {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.common.routing.AppRouter
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@ import com.tangem.core.analytics.Analytics
|
|||
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.CardTypesResolver
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.common.util.getBackupCardsCount
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.getBackupCardsCount
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
|
|
@ -27,7 +27,6 @@ import com.tangem.tap.common.analytics.events.Settings
|
|||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.common.redux.AppDialog
|
||||
import com.tangem.tap.domain.extensions.signedHashesCount
|
||||
import com.tangem.tap.features.details.ui.cardsettings.CardInfo
|
||||
import com.tangem.tap.features.details.ui.cardsettings.CardSettingsScreenState
|
||||
import com.tangem.tap.features.details.ui.cardsettings.api.CardSettingsComponent
|
||||
|
|
@ -171,6 +170,8 @@ internal class CardSettingsModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun CardDTO.signedHashesCount(): Int = wallets.sumOf { it.totalSignedHashes ?: 0 }
|
||||
|
||||
private fun handleClickingItem(item: CardInfo) {
|
||||
when (item) {
|
||||
is CardInfo.ChangeAccessCode -> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.details.ui.common.utils
|
||||
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
||||
internal fun isAccessCodeRecoveryAllowed(typeResolver: CardTypesResolver): Boolean = typeResolver.isWallet2()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.details.ui.common.utils
|
||||
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
||||
import com.tangem.wallet.R
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.details.ui.common.utils
|
||||
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.tap.features.details.redux.SecurityOption
|
||||
import java.util.EnumSet
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.features.details.ui.resetcard.api
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface ResetCardComponent : ComposableContentComponent {
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.domain.card.DeleteSavedAccessCodesUseCase
|
||||
import com.tangem.domain.card.ResetCardUseCase
|
||||
import com.tangem.domain.card.ResetCardUserCodeParams
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.asLockable
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.wallets.usecase.DeleteWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.features.details.ui.securitymode.api
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface SecurityModeComponent : ComposableContentComponent {
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.core.analytics.api.AnalyticsErrorHandler
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
|
|
|
|||
|
|
@ -5,6 +5,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.qrscanning.models.QrResultSource
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
|
||||
|
|
@ -31,12 +32,18 @@ internal class WalletConnectModel @Inject constructor(
|
|||
|
||||
init {
|
||||
modelScope.launch {
|
||||
listenToQrScanningUseCase(SourceType.WALLET_CONNECT)
|
||||
listenToQrScanningUseCase.listen(SourceType.WALLET_CONNECT)
|
||||
.getOrElse { emptyFlow() }
|
||||
.map {
|
||||
.map { result ->
|
||||
val source = when (result.resultSource) {
|
||||
QrResultSource.CLIPBOARD -> WalletConnectAction.OpenSession.SourceType.CLIPBOARD
|
||||
QrResultSource.CAMERA,
|
||||
QrResultSource.GALLERY,
|
||||
-> WalletConnectAction.OpenSession.SourceType.QR
|
||||
}
|
||||
WalletConnectAction.OpenSession(
|
||||
wcUri = it,
|
||||
source = WalletConnectAction.OpenSession.SourceType.QR,
|
||||
wcUri = result.qrCode,
|
||||
source = source,
|
||||
userWalletId = params.userWalletId,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.features.details.ui.walletconnect.api
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface WalletConnectComponent : ComposableContentComponent {
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.core.ui.components.SystemBarsIconsDisposable
|
||||
import com.tangem.core.ui.utils.ChangeRootBackgroundColorEffect
|
||||
import com.tangem.core.ui.utils.findActivity
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.home.api.HomeComponent
|
||||
import com.tangem.tap.features.home.compose.StoriesScreen
|
||||
|
|
@ -29,6 +30,7 @@ import org.rekotlin.StoreSubscriber
|
|||
internal class DefaultHomeComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: Unit,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : HomeComponent, AppComponentContext by appComponentContext, StoreSubscriber<HomeState> {
|
||||
|
||||
private val model: HomeModel = getOrCreateModel()
|
||||
|
|
@ -58,7 +60,7 @@ internal class DefaultHomeComponent @AssistedInject constructor(
|
|||
val activity = LocalContext.current.findActivity()
|
||||
BackHandler(onBack = activity::finish)
|
||||
SystemBarsIconsDisposable(darkIcons = false)
|
||||
if (homeState.value.isV2StoriesEnabled) {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
StoriesScreenV2(
|
||||
homeState = homeState,
|
||||
onCreateNewWalletButtonClick = model::onCreateNewWalletScreen,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.TestTags
|
||||
import com.tangem.core.ui.test.StoriesScreenTestTags
|
||||
import com.tangem.tap.features.home.compose.content.*
|
||||
import com.tangem.tap.features.home.compose.views.HomeButtons
|
||||
import com.tangem.tap.features.home.compose.views.SearchCurrenciesButton
|
||||
|
|
@ -61,7 +61,7 @@ internal fun StoriesScreen(
|
|||
StoriesScreenContent(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.testTag(TestTags.STORIES_SCREEN),
|
||||
.testTag(StoriesScreenTestTags.SCREEN_CONTAINER),
|
||||
config = StoriesScreenContentConfig(
|
||||
storiesSize = state.stories.lastIndex,
|
||||
currentStoryIndex = currentStoryIndex,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.TestTags
|
||||
import com.tangem.core.ui.test.StoriesScreenTestTags
|
||||
import com.tangem.tap.features.home.compose.content.*
|
||||
import com.tangem.tap.features.home.compose.views.HomeButtonsV2
|
||||
import com.tangem.tap.features.home.compose.views.StoriesProgressBar
|
||||
|
|
@ -57,7 +57,7 @@ internal fun StoriesScreenV2(
|
|||
StoriesScreenContentV2(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.testTag(TestTags.STORIES_SCREEN),
|
||||
.testTag(StoriesScreenTestTags.SCREEN_CONTAINER),
|
||||
config = StoriesScreenContentV2Config(
|
||||
storiesSize = state.stories.lastIndex,
|
||||
currentStoryIndex = currentStoryIndex,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
|||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.TestTags
|
||||
import com.tangem.core.ui.test.StoriesScreenTestTags
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
|
|
@ -34,7 +34,7 @@ internal fun HomeButtons(
|
|||
ScanCardButton(
|
||||
modifier = Modifier
|
||||
.weight(weight = 1f)
|
||||
.testTag(TestTags.STORIES_SCREEN_SCAN_BUTTON),
|
||||
.testTag(StoriesScreenTestTags.SCAN_BUTTON),
|
||||
showProgress = btnScanStateInProgress,
|
||||
onClick = onScanButtonClick,
|
||||
)
|
||||
|
|
@ -42,7 +42,7 @@ internal fun HomeButtons(
|
|||
OrderCardButton(
|
||||
modifier = Modifier
|
||||
.weight(weight = 1f)
|
||||
.testTag(TestTags.STORIES_SCREEN_ORDER_BUTTON),
|
||||
.testTag(StoriesScreenTestTags.ORDER_BUTTON),
|
||||
onClick = onShopButtonClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
|||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.TestTags
|
||||
import com.tangem.core.ui.test.StoriesScreenTestTags
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
|
|
@ -37,19 +37,19 @@ internal fun HomeButtonsV2(
|
|||
CreateNewWalletButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(TestTags.STORIES_SCREEN_CREATE_NEW_WALLET_BUTTON),
|
||||
.testTag(StoriesScreenTestTags.CREATE_NEW_WALLET_BUTTON),
|
||||
onClick = onCreateNewWalletButtonClick,
|
||||
)
|
||||
AddExistingWalletButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(TestTags.STORIES_SCREEN_ADD_EXISTING_WALLET_BUTTON),
|
||||
.testTag(StoriesScreenTestTags.ADD_EXISTING_WALLET_BUTTON),
|
||||
onClick = onAddExistingWalletButtonClick,
|
||||
)
|
||||
ScanCardButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(TestTags.STORIES_SCREEN_SCAN_BUTTON),
|
||||
.testTag(StoriesScreenTestTags.SCAN_BUTTON),
|
||||
showProgress = btnScanStateInProgress,
|
||||
onClick = onScanButtonClick,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||
|
|
@ -61,7 +61,6 @@ private fun handleHomeAction(action: Action) {
|
|||
Analytics.send(IntroductionProcess.ScreenOpened())
|
||||
|
||||
store.dispatch(GlobalAction.RestoreAppCurrency)
|
||||
store.dispatch(GlobalAction.ExchangeManager.Init)
|
||||
}
|
||||
is HomeAction.ReadCard -> {
|
||||
action.scope.launch {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import org.rekotlin.StateType
|
|||
// todo refactor [REDACTED_TASK_KEY]
|
||||
data class HomeState(
|
||||
val scanInProgress: Boolean = false,
|
||||
val isV2StoriesEnabled: Boolean = false,
|
||||
val stories: ImmutableList<Stories> = getRestrictedStories().toImmutableList(),
|
||||
) : StateType {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
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]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.tangem.tap.features.hot
|
||||
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.model.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Proxy for [TangemHotSdk] to allow lazy initialization and provide a way to access the SDK state from domain layer.
|
||||
* SDK is initialized in the [com.tangem.tap.routing.component.RoutingComponent] and can be accessed through this proxy.
|
||||
* Be aware that the SDK is initialized on activity creation, so it may not be available immediately.
|
||||
*/
|
||||
@Singleton
|
||||
class TangemHotSDKProxy @Inject constructor() : TangemHotSdk {
|
||||
|
||||
val sdkState = MutableStateFlow<TangemHotSdk?>(null)
|
||||
|
||||
override suspend fun importWallet(mnemonic: Mnemonic, passphrase: CharArray?, auth: HotAuth): HotWalletId =
|
||||
callSdk { importWallet(mnemonic, passphrase, auth) }
|
||||
|
||||
override suspend fun generateWallet(auth: HotAuth, mnemonicType: MnemonicType): HotWalletId =
|
||||
callSdk { generateWallet(auth, mnemonicType) }
|
||||
|
||||
override suspend fun exportMnemonic(unlockHotWallet: UnlockHotWallet): SeedPhrasePrivateInfo =
|
||||
callSdk { exportMnemonic(unlockHotWallet) }
|
||||
|
||||
override suspend fun exportBackup(unlockHotWallet: UnlockHotWallet): ByteArray =
|
||||
callSdk { exportBackup(unlockHotWallet) }
|
||||
|
||||
override suspend fun delete(id: HotWalletId) = callSdk { delete(id) }
|
||||
|
||||
override suspend fun changeAuth(unlockHotWallet: UnlockHotWallet, auth: HotAuth): HotWalletId =
|
||||
callSdk { changeAuth(unlockHotWallet, auth) }
|
||||
|
||||
override suspend fun derivePublicKey(
|
||||
unlockHotWallet: UnlockHotWallet,
|
||||
request: DeriveWalletRequest,
|
||||
): DerivedPublicKeyResponse = callSdk { derivePublicKey(unlockHotWallet, request) }
|
||||
|
||||
override suspend fun signHashes(unlockHotWallet: UnlockHotWallet, dataToSign: List<DataToSign>): List<SignedData> =
|
||||
callSdk { signHashes(unlockHotWallet, dataToSign) }
|
||||
|
||||
private suspend fun <T> callSdk(block: suspend TangemHotSdk.() -> T): T {
|
||||
return withTimeout(timeMillis = 1000) {
|
||||
sdkState.filterNotNull().first()
|
||||
}.block()
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,11 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
import com.tangem.common.keyboard.KeyboardValidator
|
||||
import com.tangem.common.routing.RoutingFeatureToggle
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.event.TechAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.deeplink.DeepLinksRegistry
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.coil.ImagePreloader
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
|
|
@ -18,11 +16,16 @@ import com.tangem.core.ui.message.BottomSheetMessage
|
|||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfig
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.domain.appcurrency.FetchAppCurrenciesUseCase
|
||||
import com.tangem.domain.balancehiding.BalanceHidingSettings
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
|
||||
import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.notifications.GetApplicationIdUseCase
|
||||
import com.tangem.domain.notifications.SendPushTokenUseCase
|
||||
import com.tangem.domain.notifications.models.ApplicationId
|
||||
|
|
@ -37,15 +40,16 @@ import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
|
|||
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
||||
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.wallets.usecase.AssociateWalletsWithApplicationIdUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetSavedWalletsCountUseCase
|
||||
import com.tangem.domain.wallets.usecase.UpdateRemoteWalletsInfoUseCase
|
||||
import com.tangem.feature.swap.analytics.StoriesEvents
|
||||
import com.tangem.features.onramp.deeplink.OnrampDeepLink
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeService
|
||||
import com.tangem.tap.network.exchangeServices.moonpay.MoonPayService
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.wallet.BuildConfig
|
||||
|
|
@ -58,7 +62,7 @@ import timber.log.Timber
|
|||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@HiltViewModel
|
||||
internal class MainViewModel @Inject constructor(
|
||||
private val updateBalanceHidingSettingsUseCase: UpdateBalanceHidingSettingsUseCase,
|
||||
|
|
@ -78,8 +82,6 @@ internal class MainViewModel @Inject constructor(
|
|||
private val imagePreloader: ImagePreloader,
|
||||
private val fetchHotCryptoUseCase: FetchHotCryptoUseCase,
|
||||
private val onboardingRepository: OnboardingRepository,
|
||||
private val deepLinksRegistry: DeepLinksRegistry,
|
||||
private val onrampDeepLinkFactory: OnrampDeepLink.Factory,
|
||||
private val notificationsToggles: NotificationsFeatureToggles,
|
||||
private val getApplicationIdUseCase: GetApplicationIdUseCase,
|
||||
private val subscribeOnWalletsUseCase: GetSavedWalletsCountUseCase,
|
||||
|
|
@ -88,7 +90,8 @@ internal class MainViewModel @Inject constructor(
|
|||
private val sendPushTokenUseCase: SendPushTokenUseCase,
|
||||
private val apiConfigsManager: ApiConfigsManager,
|
||||
private val multiQuoteUpdater: MultiQuoteUpdater,
|
||||
routingFeatureToggle: RoutingFeatureToggle,
|
||||
private val appStateHolder: AppStateHolder,
|
||||
private val environmentConfigStorage: EnvironmentConfigStorage,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
) : ViewModel() {
|
||||
|
||||
|
|
@ -120,6 +123,8 @@ internal class MainViewModel @Inject constructor(
|
|||
|
||||
multiQuoteUpdater.subscribe()
|
||||
|
||||
initializeOffRamp()
|
||||
|
||||
observeFlips()
|
||||
displayBalancesHidingStatusToast()
|
||||
displayHiddenBalancesModalNotification()
|
||||
|
|
@ -129,10 +134,6 @@ internal class MainViewModel @Inject constructor(
|
|||
sendKeyboardIdentifierEvent()
|
||||
|
||||
preloadImages()
|
||||
|
||||
if (!routingFeatureToggle.isDeepLinkNavigationEnabled) {
|
||||
initializeDeepLinks()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
|
@ -189,7 +190,7 @@ internal class MainViewModel @Inject constructor(
|
|||
userWalletsListManager.selectedUserWallet
|
||||
.distinctUntilChanged()
|
||||
.onEach { userWallet ->
|
||||
Analytics.setContext(userWallet.requireColdWallet().scanResponse) // TODO [REDACTED_TASK_KEY]
|
||||
Analytics.setContext(userWallet)
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(viewModelScope)
|
||||
|
|
@ -201,6 +202,28 @@ internal class MainViewModel @Inject constructor(
|
|||
.onRight { Timber.d("Staking token list was fetched successfully") }
|
||||
}
|
||||
|
||||
private fun initializeOffRamp() {
|
||||
viewModelScope.launch {
|
||||
val sellService = makeSellExchangeService(environmentConfig = environmentConfigStorage.getConfigSync())
|
||||
appStateHolder.sellService = sellService
|
||||
|
||||
sellService.update()
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeSellExchangeService(environmentConfig: EnvironmentConfig): ExchangeService {
|
||||
val cardProvider: () -> ScanResponse? = {
|
||||
userWalletsListManager.selectedUserWalletSync?.requireColdWallet()?.scanResponse // TODO [REDACTED_TASK_KEY]
|
||||
}
|
||||
|
||||
return MoonPayService(
|
||||
apiKey = environmentConfig.moonPayApiKey,
|
||||
secretKey = environmentConfig.moonPayApiSecretKey,
|
||||
logEnabled = LogConfig.network.moonPayService,
|
||||
cardProvider = { cardProvider.invoke()?.card },
|
||||
)
|
||||
}
|
||||
|
||||
private fun observeFlips() {
|
||||
listenToFlipsUseCase().launchIn(viewModelScope)
|
||||
}
|
||||
|
|
@ -384,7 +407,7 @@ internal class MainViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex.message)
|
||||
Timber.e(ex)
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
|
|
@ -393,10 +416,6 @@ internal class MainViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun initializeDeepLinks() {
|
||||
deepLinksRegistry.register(onrampDeepLinkFactory.create(viewModelScope))
|
||||
}
|
||||
|
||||
private suspend fun initPushNotifications() {
|
||||
if (notificationsToggles.isNotificationsEnabled) {
|
||||
getApplicationIdUseCase().onRight { applicationId ->
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue