Updated on 2026-08-14
This commit is contained in:
parent
4594602447
commit
b98bc113fc
54 changed files with 667 additions and 198 deletions
|
|
@ -90,6 +90,7 @@ dependencies {
|
||||||
implementation(projects.libs.crypto)
|
implementation(projects.libs.crypto)
|
||||||
implementation(projects.libs.auth)
|
implementation(projects.libs.auth)
|
||||||
implementation(projects.libs.blockchainSdk)
|
implementation(projects.libs.blockchainSdk)
|
||||||
|
implementation(projects.libs.tangemSdkApi)
|
||||||
|
|
||||||
implementation(projects.data.appCurrency)
|
implementation(projects.data.appCurrency)
|
||||||
implementation(projects.data.appTheme)
|
implementation(projects.data.appTheme)
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ import com.tangem.features.staking.api.navigation.StakingRouter
|
||||||
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
|
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
|
||||||
import com.tangem.features.wallet.navigation.WalletRouter
|
import com.tangem.features.wallet.navigation.WalletRouter
|
||||||
import com.tangem.operations.backup.BackupService
|
import com.tangem.operations.backup.BackupService
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.sdk.extensions.init
|
import com.tangem.sdk.extensions.init
|
||||||
import com.tangem.tap.common.ActivityResultCallbackHolder
|
import com.tangem.tap.common.ActivityResultCallbackHolder
|
||||||
import com.tangem.tap.common.DialogManager
|
import com.tangem.tap.common.DialogManager
|
||||||
|
|
@ -68,7 +69,6 @@ import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
|
||||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||||
import com.tangem.tap.common.extensions.showFragmentAllowingStateLoss
|
import com.tangem.tap.common.extensions.showFragmentAllowingStateLoss
|
||||||
import com.tangem.tap.common.redux.NotificationsHandler
|
import com.tangem.tap.common.redux.NotificationsHandler
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
|
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
|
||||||
import com.tangem.tap.features.intentHandler.IntentProcessor
|
import com.tangem.tap.features.intentHandler.IntentProcessor
|
||||||
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
|
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import com.tangem.domain.exchange.RampStateManager
|
||||||
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
||||||
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
||||||
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
|
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
|
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.network.exchangeServices.DefaultRampManager
|
import com.tangem.tap.network.exchangeServices.DefaultRampManager
|
||||||
import com.tangem.tap.proxy.AppStateHolder
|
import com.tangem.tap.proxy.AppStateHolder
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ package com.tangem.tap.di
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.tangem.domain.card.BuildConfig
|
import com.tangem.domain.card.BuildConfig
|
||||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.sdk.impl.DefaultTangemSdkManager
|
import com.tangem.tap.domain.sdk.impl.DefaultTangemSdkManager
|
||||||
import com.tangem.tap.domain.sdk.impl.MockTangemSdkManager
|
import com.tangem.tap.domain.sdk.impl.MockTangemSdkManager
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.di.data
|
||||||
|
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.card.repository.DerivationsRepository
|
import com.tangem.domain.card.repository.DerivationsRepository
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.card.DefaultDerivationsRepository
|
import com.tangem.tap.domain.card.DefaultDerivationsRepository
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ import com.tangem.domain.demo.IsDemoCardUseCase
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase
|
import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase
|
||||||
import com.tangem.tap.domain.card.DefaultResetCardUseCase
|
import com.tangem.tap.domain.card.DefaultResetCardUseCase
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import com.tangem.domain.settings.repositories.PromoSettingsRepository
|
||||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||||
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
||||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.settings.DefaultLegacySettingsRepository
|
import com.tangem.tap.domain.settings.DefaultLegacySettingsRepository
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import arrow.core.right
|
||||||
import com.tangem.common.doOnFailure
|
import com.tangem.common.doOnFailure
|
||||||
import com.tangem.common.doOnSuccess
|
import com.tangem.common.doOnSuccess
|
||||||
import com.tangem.domain.card.DeleteSavedAccessCodesUseCase
|
import com.tangem.domain.card.DeleteSavedAccessCodesUseCase
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
|
|
||||||
internal class DefaultDeleteSavedAccessCodesUseCase(
|
internal class DefaultDeleteSavedAccessCodesUseCase(
|
||||||
private val tangemSdkManager: TangemSdkManager,
|
private val tangemSdkManager: TangemSdkManager,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import com.tangem.domain.tokens.model.Network
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter
|
import com.tangem.tap.domain.tasks.UserWalletIdPreflightReadFilter
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import com.tangem.domain.card.ResetCardUseCase
|
||||||
import com.tangem.domain.card.ResetCardUserCodeParams
|
import com.tangem.domain.card.ResetCardUserCodeParams
|
||||||
import com.tangem.domain.card.models.ResetCardError
|
import com.tangem.domain.card.models.ResetCardError
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
|
|
||||||
internal class DefaultResetCardUseCase(
|
internal class DefaultResetCardUseCase(
|
||||||
private val tangemSdkManager: TangemSdkManager,
|
private val tangemSdkManager: TangemSdkManager,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.domain.scanCard.repository
|
||||||
import com.tangem.common.CompletionResult
|
import com.tangem.common.CompletionResult
|
||||||
import com.tangem.domain.card.repository.ScanCardRepository
|
import com.tangem.domain.card.repository.ScanCardRepository
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.scanCard.utils.ScanCardExceptionConverter
|
import com.tangem.tap.domain.scanCard.utils.ScanCardExceptionConverter
|
||||||
|
|
||||||
// TODO: Move to the :data:card module
|
// TODO: Move to the :data:card module
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ import com.tangem.operations.pins.SetUserCodeCommand
|
||||||
import com.tangem.operations.preflightread.PreflightReadFilter
|
import com.tangem.operations.preflightread.PreflightReadFilter
|
||||||
import com.tangem.operations.usersetttings.SetUserCodeRecoveryAllowedTask
|
import com.tangem.operations.usersetttings.SetUserCodeRecoveryAllowedTask
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.derivationsFinder
|
import com.tangem.tap.derivationsFinder
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.domain.tasks.product.*
|
import com.tangem.tap.domain.tasks.product.*
|
||||||
import com.tangem.tap.domain.twins.CreateFirstTwinWalletTask
|
import com.tangem.tap.domain.twins.CreateFirstTwinWalletTask
|
||||||
import com.tangem.tap.domain.twins.CreateSecondTwinWalletTask
|
import com.tangem.tap.domain.twins.CreateSecondTwinWalletTask
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||||
import com.tangem.operations.preflightread.PreflightReadFilter
|
import com.tangem.operations.preflightread.PreflightReadFilter
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.sdk.mocks.MockProvider
|
import com.tangem.tap.domain.sdk.mocks.MockProvider
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
|
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
class MockTangemSdkManager(
|
class MockTangemSdkManager(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import com.tangem.domain.models.scan.CardDTO
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
|
|
||||||
interface MockContent {
|
interface MockContent {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import com.tangem.common.CompletionResult
|
||||||
import com.tangem.common.core.TangemError
|
import com.tangem.common.core.TangemError
|
||||||
import com.tangem.common.core.TangemSdkError
|
import com.tangem.common.core.TangemSdkError
|
||||||
import com.tangem.domain.models.scan.ProductType
|
import com.tangem.domain.models.scan.ProductType
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import com.tangem.tap.domain.sdk.mocks.content.NoteMockContent
|
import com.tangem.tap.domain.sdk.mocks.content.NoteMockContent
|
||||||
import com.tangem.tap.domain.sdk.mocks.content.WalletMockContent
|
import com.tangem.tap.domain.sdk.mocks.content.WalletMockContent
|
||||||
import com.tangem.tap.domain.sdk.mocks.content.Wallet2MockContent
|
import com.tangem.tap.domain.sdk.mocks.content.Wallet2MockContent
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
|
|
||||||
object MockProvider {
|
object MockProvider {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.operations.attestation.Attestation
|
import com.tangem.operations.attestation.Attestation
|
||||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import com.tangem.tap.domain.sdk.mocks.MockContent
|
import com.tangem.tap.domain.sdk.mocks.MockContent
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
object NoteMockContent : MockContent {
|
object NoteMockContent : MockContent {
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import com.tangem.operations.backup.PrimaryCard
|
||||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import com.tangem.tap.domain.sdk.mocks.MockContent
|
import com.tangem.tap.domain.sdk.mocks.MockContent
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
object Wallet2MockContent : MockContent {
|
object Wallet2MockContent : MockContent {
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import com.tangem.operations.backup.PrimaryCard
|
||||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import com.tangem.tap.domain.sdk.mocks.MockContent
|
import com.tangem.tap.domain.sdk.mocks.MockContent
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
object WalletMockContent : MockContent {
|
object WalletMockContent : MockContent {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.tangem.tap.domain.settings
|
package com.tangem.tap.domain.settings
|
||||||
|
|
||||||
import com.tangem.domain.settings.repositories.LegacySettingsRepository
|
import com.tangem.domain.settings.repositories.LegacySettingsRepository
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
|
|
||||||
internal class DefaultLegacySettingsRepository(
|
internal class DefaultLegacySettingsRepository(
|
||||||
private val tangemSdkManager: TangemSdkManager,
|
private val tangemSdkManager: TangemSdkManager,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.tangem.tap.domain.tasks.product
|
||||||
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.common.CompletionResult
|
import com.tangem.common.CompletionResult
|
||||||
import com.tangem.common.card.Card
|
|
||||||
import com.tangem.common.card.EllipticCurve
|
import com.tangem.common.card.EllipticCurve
|
||||||
import com.tangem.common.card.FirmwareVersion
|
import com.tangem.common.card.FirmwareVersion
|
||||||
import com.tangem.common.core.CardSession
|
import com.tangem.common.core.CardSession
|
||||||
|
|
@ -19,33 +18,15 @@ import com.tangem.domain.common.DerivationStyleProvider
|
||||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||||
import com.tangem.domain.common.configs.CardConfig
|
import com.tangem.domain.common.configs.CardConfig
|
||||||
import com.tangem.domain.models.scan.CardDTO
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
import com.tangem.domain.models.scan.KeyWalletPublicKey
|
|
||||||
import com.tangem.operations.CommandResponse
|
|
||||||
import com.tangem.operations.backup.PrimaryCard
|
import com.tangem.operations.backup.PrimaryCard
|
||||||
import com.tangem.operations.backup.StartPrimaryCardLinkingCommand
|
import com.tangem.operations.backup.StartPrimaryCardLinkingCommand
|
||||||
import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
||||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
|
||||||
import com.tangem.operations.read.ReadWalletsListCommand
|
import com.tangem.operations.read.ReadWalletsListCommand
|
||||||
import com.tangem.operations.wallet.CreateWalletTask
|
import com.tangem.operations.wallet.CreateWalletTask
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import com.tangem.tap.features.demo.DemoHelper
|
import com.tangem.tap.features.demo.DemoHelper
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse as SdkCreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse as SdkCreateWalletResponse
|
||||||
|
|
||||||
data class CreateProductWalletTaskResponse(
|
|
||||||
val card: CardDTO,
|
|
||||||
val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
|
||||||
val primaryCard: PrimaryCard? = null,
|
|
||||||
) : CommandResponse {
|
|
||||||
constructor(
|
|
||||||
card: Card,
|
|
||||||
derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
|
||||||
primaryCard: PrimaryCard? = null,
|
|
||||||
) : this(
|
|
||||||
card = CardDTO(card),
|
|
||||||
derivedKeys = derivedKeys,
|
|
||||||
primaryCard = primaryCard,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class CreateWalletResponse(
|
private data class CreateWalletResponse(
|
||||||
val cardId: String,
|
val cardId: String,
|
||||||
val wallet: CardDTO.Wallet,
|
val wallet: CardDTO.Wallet,
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ import com.tangem.domain.models.scan.CardDTO
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||||
import com.tangem.tap.common.analytics.events.Settings
|
import com.tangem.tap.common.analytics.events.Settings
|
||||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||||
import com.tangem.tap.common.redux.AppDialog
|
import com.tangem.tap.common.redux.AppDialog
|
||||||
import com.tangem.tap.domain.extensions.signedHashesCount
|
import com.tangem.tap.domain.extensions.signedHashesCount
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
|
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
|
||||||
import com.tangem.tap.features.details.ui.common.utils.*
|
import com.tangem.tap.features.details.ui.common.utils.*
|
||||||
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
|
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import com.tangem.common.doOnSuccess
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||||
import com.tangem.tap.common.analytics.events.Settings
|
import com.tangem.tap.common.analytics.events.Settings
|
||||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
|
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
|
||||||
import com.tangem.tap.features.details.ui.common.utils.isAccessCodeRecoveryEnabled
|
import com.tangem.tap.features.details.ui.common.utils.isAccessCodeRecoveryEnabled
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import com.tangem.common.core.TangemSdkError
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||||
import com.tangem.tap.common.analytics.events.Settings
|
import com.tangem.tap.common.analytics.events.Settings
|
||||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.features.details.redux.SecurityOption
|
import com.tangem.tap.features.details.redux.SecurityOption
|
||||||
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
|
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
|
||||||
import com.tangem.tap.features.details.ui.common.utils.getAllowedSecurityOptions
|
import com.tangem.tap.features.details.ui.common.utils.getAllowedSecurityOptions
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.tangem.common.CompletionResult
|
import com.tangem.common.CompletionResult
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
|
||||||
import com.tangem.common.card.Card
|
import com.tangem.common.card.Card
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
|
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
|
||||||
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
|
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import org.rekotlin.Action
|
import org.rekotlin.Action
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,13 @@ import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSo
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.BackupValidator
|
import com.tangem.feature.wallet.presentation.wallet.domain.BackupValidator
|
||||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||||
import com.tangem.operations.backup.BackupService
|
import com.tangem.operations.backup.BackupService
|
||||||
|
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||||
import com.tangem.tap.*
|
import com.tangem.tap.*
|
||||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||||
import com.tangem.tap.common.analytics.events.Onboarding
|
import com.tangem.tap.common.analytics.events.Onboarding
|
||||||
import com.tangem.tap.common.extensions.*
|
import com.tangem.tap.common.extensions.*
|
||||||
import com.tangem.tap.common.redux.AppState
|
import com.tangem.tap.common.redux.AppState
|
||||||
import com.tangem.tap.common.redux.global.GlobalAction
|
import com.tangem.tap.common.redux.global.GlobalAction
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
import com.tangem.tap.features.demo.DemoHelper
|
import com.tangem.tap.features.demo.DemoHelper
|
||||||
import com.tangem.tap.features.home.redux.HomeAction
|
import com.tangem.tap.features.home.redux.HomeAction
|
||||||
import com.tangem.tap.features.onboarding.OnboardingDialog
|
import com.tangem.tap.features.onboarding.OnboardingDialog
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.domain.redux.ReduxStateHolder
|
import com.tangem.domain.redux.ReduxStateHolder
|
||||||
import com.tangem.domain.redux.StateDialog
|
import com.tangem.domain.redux.StateDialog
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||||
import com.tangem.tap.common.extensions.dispatchWithMain
|
import com.tangem.tap.common.extensions.dispatchWithMain
|
||||||
import com.tangem.tap.common.extensions.onUserWalletSelected
|
import com.tangem.tap.common.extensions.onUserWalletSelected
|
||||||
import com.tangem.tap.common.redux.AppState
|
import com.tangem.tap.common.redux.AppState
|
||||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
|
||||||
import com.tangem.tap.network.exchangeServices.ExchangeService
|
import com.tangem.tap.network.exchangeServices.ExchangeService
|
||||||
import org.rekotlin.Action
|
import org.rekotlin.Action
|
||||||
import org.rekotlin.Store
|
import org.rekotlin.Store
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ dependencies {
|
||||||
implementation(projects.domain.core)
|
implementation(projects.domain.core)
|
||||||
|
|
||||||
/** Tangem libraries */
|
/** Tangem libraries */
|
||||||
|
implementation(projects.libs.tangemSdkApi)
|
||||||
implementation(deps.tangem.card.core)
|
implementation(deps.tangem.card.core)
|
||||||
implementation(deps.tangem.card.android) {
|
implementation(deps.tangem.card.android) {
|
||||||
exclude(module = "joda-time")
|
exclude(module = "joda-time")
|
||||||
|
|
@ -40,12 +41,14 @@ dependencies {
|
||||||
implementation(deps.lifecycle.runtime.ktx)
|
implementation(deps.lifecycle.runtime.ktx)
|
||||||
|
|
||||||
/** Compose libraries */
|
/** Compose libraries */
|
||||||
|
implementation(deps.compose.material) // to use buttons
|
||||||
implementation(deps.compose.material3)
|
implementation(deps.compose.material3)
|
||||||
implementation(deps.compose.animation)
|
implementation(deps.compose.animation)
|
||||||
implementation(deps.compose.foundation)
|
implementation(deps.compose.foundation)
|
||||||
implementation(deps.compose.ui)
|
implementation(deps.compose.ui)
|
||||||
implementation(deps.compose.ui.tooling)
|
implementation(deps.compose.ui.tooling)
|
||||||
implementation(deps.compose.coil)
|
implementation(deps.compose.coil)
|
||||||
|
implementation(deps.decompose.ext.compose)
|
||||||
|
|
||||||
/** Other libraries */
|
/** Other libraries */
|
||||||
implementation(deps.kotlin.immutable.collections)
|
implementation(deps.kotlin.immutable.collections)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.tangem.features.onboarding.v2
|
||||||
|
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
|
interface TitleProvider {
|
||||||
|
val currentTitle: StateFlow<TextReference>
|
||||||
|
fun changeTitle(text: TextReference)
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package com.tangem.features.onboarding.v2.entry.impl
|
package com.tangem.features.onboarding.v2.entry.impl
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
|
||||||
import com.arkivanov.decompose.router.stack.ChildStack
|
import com.arkivanov.decompose.router.stack.ChildStack
|
||||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||||
import com.arkivanov.decompose.router.stack.childStack
|
import com.arkivanov.decompose.router.stack.childStack
|
||||||
|
|
@ -12,16 +14,19 @@ import com.tangem.core.decompose.context.child
|
||||||
import com.tangem.core.decompose.context.childByContext
|
import com.tangem.core.decompose.context.childByContext
|
||||||
import com.tangem.core.decompose.model.getOrCreateModel
|
import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.decompose.navigation.inner.InnerNavigationHolder
|
import com.tangem.core.decompose.navigation.inner.InnerNavigationHolder
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
|
||||||
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.model.OnboardingEntryModel
|
import com.tangem.features.onboarding.v2.entry.impl.model.OnboardingEntryModel
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingChildFactory
|
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingChildFactory
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingRoute
|
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingRoute
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.ui.OnboardingEntry
|
import com.tangem.features.onboarding.v2.entry.impl.ui.OnboardingEntry
|
||||||
import com.tangem.features.onboarding.v2.stepper.api.OnboardingStepperComponent
|
import com.tangem.features.onboarding.v2.stepper.api.OnboardingStepperComponent
|
||||||
|
import com.tangem.utils.coroutines.JobHolder
|
||||||
|
import com.tangem.utils.coroutines.saveIn
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
|
internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
|
||||||
@Assisted val context: AppComponentContext,
|
@Assisted val context: AppComponentContext,
|
||||||
|
|
@ -30,6 +35,7 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
|
||||||
onboardingChildFactory: OnboardingChildFactory,
|
onboardingChildFactory: OnboardingChildFactory,
|
||||||
) : OnboardingEntryComponent, AppComponentContext by context {
|
) : OnboardingEntryComponent, AppComponentContext by context {
|
||||||
|
|
||||||
|
private val innerNavigationLinkJobHolder = JobHolder()
|
||||||
private val model: OnboardingEntryModel = getOrCreateModel(params)
|
private val model: OnboardingEntryModel = getOrCreateModel(params)
|
||||||
|
|
||||||
private val stepperComponent = stepperFactory.create(
|
private val stepperComponent = stepperFactory.create(
|
||||||
|
|
@ -39,7 +45,7 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
|
||||||
initState = OnboardingStepperComponent.StepperState(
|
initState = OnboardingStepperComponent.StepperState(
|
||||||
currentStep = 0,
|
currentStep = 0,
|
||||||
steps = 0,
|
steps = 0,
|
||||||
title = stringReference(""),
|
title = model.titleProvider.currentTitle.value,
|
||||||
showProgress = false,
|
showProgress = false,
|
||||||
),
|
),
|
||||||
popBack = {
|
popBack = {
|
||||||
|
|
@ -68,6 +74,10 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
linkToInnerNavigation()
|
||||||
|
}
|
||||||
|
|
||||||
private fun popInternal(onComplete: (Boolean) -> Unit) {
|
private fun popInternal(onComplete: (Boolean) -> Unit) {
|
||||||
val activeChild = innerStack.value.active.instance
|
val activeChild = innerStack.value.active.instance
|
||||||
if (activeChild is InnerNavigationHolder) {
|
if (activeChild is InnerNavigationHolder) {
|
||||||
|
|
@ -77,16 +87,36 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun linkToInnerNavigation() {
|
||||||
|
innerStack.observe { stack ->
|
||||||
|
val activeChild = stack.active.instance
|
||||||
|
if (activeChild is InnerNavigationHolder) {
|
||||||
|
componentScope.launch {
|
||||||
|
activeChild.innerNavigation.state.collect { state ->
|
||||||
|
stepperComponent.state.update {
|
||||||
|
it.copy(
|
||||||
|
currentStep = state.stackSize,
|
||||||
|
steps = state.stackMaxSize ?: 0,
|
||||||
|
title = model.titleProvider.currentTitle.value,
|
||||||
|
showProgress = state.stackMaxSize != null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.saveIn(innerNavigationLinkJobHolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content(modifier: Modifier) {
|
override fun Content(modifier: Modifier) {
|
||||||
|
val innerStackState by innerStack.subscribeAsState()
|
||||||
|
|
||||||
OnboardingEntry(
|
OnboardingEntry(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
stepperContent = { modifierParam ->
|
stepperContent = { modifierParam ->
|
||||||
stepperComponent.Content(modifierParam)
|
stepperComponent.Content(modifierParam)
|
||||||
},
|
},
|
||||||
content = { modifierParam ->
|
childStack = innerStackState,
|
||||||
// TODO
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
package com.tangem.features.onboarding.v2.entry.impl.di
|
package com.tangem.features.onboarding.v2.entry.impl.di
|
||||||
|
|
||||||
|
import com.tangem.core.decompose.di.DecomposeComponent
|
||||||
|
import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.DefaultOnboardingEntryComponent
|
import com.tangem.features.onboarding.v2.entry.impl.DefaultOnboardingEntryComponent
|
||||||
|
import com.tangem.features.onboarding.v2.entry.impl.model.OnboardingEntryModel
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import dagger.multibindings.ClassKey
|
||||||
|
import dagger.multibindings.IntoMap
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
|
@ -18,3 +23,12 @@ internal interface ComponentModule {
|
||||||
factory: DefaultOnboardingEntryComponent.Factory,
|
factory: DefaultOnboardingEntryComponent.Factory,
|
||||||
): OnboardingEntryComponent.Factory
|
): OnboardingEntryComponent.Factory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(DecomposeComponent::class)
|
||||||
|
internal interface ModelModule {
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ClassKey(OnboardingEntryModel::class)
|
||||||
|
fun provideModel(model: OnboardingEntryModel): Model
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,12 @@ package com.tangem.features.onboarding.v2.entry.impl.model
|
||||||
|
|
||||||
import com.tangem.core.decompose.di.ComponentScoped
|
import com.tangem.core.decompose.di.ComponentScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.domain.models.scan.ProductType
|
||||||
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
|
import com.tangem.features.onboarding.v2.TitleProvider
|
||||||
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.model.state.OnboardingState
|
import com.tangem.features.onboarding.v2.entry.impl.model.state.OnboardingState
|
||||||
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingRoute
|
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingRoute
|
||||||
|
|
@ -11,13 +17,42 @@ import javax.inject.Inject
|
||||||
|
|
||||||
@ComponentScoped
|
@ComponentScoped
|
||||||
internal class OnboardingEntryModel @Inject constructor(
|
internal class OnboardingEntryModel @Inject constructor(
|
||||||
|
paramsContainer: ParamsContainer,
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val params: OnboardingEntryComponent.Params,
|
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
|
private val params = paramsContainer.require<OnboardingEntryComponent.Params>()
|
||||||
|
|
||||||
|
val titleProvider = object : TitleProvider {
|
||||||
|
override val currentTitle = MutableStateFlow(stringReference(""))
|
||||||
|
override fun changeTitle(text: TextReference) {
|
||||||
|
currentTitle.value = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val state = MutableStateFlow(
|
val state = MutableStateFlow(
|
||||||
OnboardingState(
|
OnboardingState(
|
||||||
currentRoute = OnboardingRoute.Wallet12(params.scanResponse),
|
currentRoute = routeByProductType(params.scanResponse),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun routeByProductType(scanResponse: ScanResponse): OnboardingRoute {
|
||||||
|
return when (scanResponse.productType) {
|
||||||
|
ProductType.Note -> TODO()
|
||||||
|
ProductType.Twins -> TODO()
|
||||||
|
ProductType.Wallet -> OnboardingRoute.Wallet12(
|
||||||
|
scanResponse = scanResponse,
|
||||||
|
withSeedPhraseFlow = false,
|
||||||
|
titleProvider = titleProvider,
|
||||||
|
)
|
||||||
|
ProductType.Wallet2 -> OnboardingRoute.Wallet12(
|
||||||
|
scanResponse = scanResponse,
|
||||||
|
withSeedPhraseFlow = true,
|
||||||
|
titleProvider = titleProvider,
|
||||||
|
)
|
||||||
|
ProductType.Start2Coin -> TODO()
|
||||||
|
ProductType.Ring -> TODO()
|
||||||
|
ProductType.Visa -> TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
package com.tangem.features.onboarding.v2.entry.impl.routing
|
package com.tangem.features.onboarding.v2.entry.impl.routing
|
||||||
|
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.features.onboarding.v2.wallet12.api.OnboardingWallet12Component
|
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class OnboardingChildFactory @Inject constructor(
|
internal class OnboardingChildFactory @Inject constructor(
|
||||||
private val wallet12ComponentFactory: OnboardingWallet12Component.Factory,
|
private val wallet12ComponentFactory: OnboardingMultiWalletComponent.Factory,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun createChild(route: OnboardingRoute, childContext: AppComponentContext) {
|
fun createChild(route: OnboardingRoute, childContext: AppComponentContext): Any {
|
||||||
when (route) {
|
return when (route) {
|
||||||
is OnboardingRoute.Wallet12 -> wallet12ComponentFactory.create(
|
is OnboardingRoute.Wallet12 -> wallet12ComponentFactory.create(
|
||||||
context = childContext,
|
context = childContext,
|
||||||
params = OnboardingWallet12Component.Params(
|
params = OnboardingMultiWalletComponent.Params(
|
||||||
scanResponse = route.scanResponse,
|
scanResponse = route.scanResponse,
|
||||||
|
withSeedPhraseFlow = route.withSeedPhraseFlow,
|
||||||
|
titleProvider = route.titleProvider,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,8 +2,15 @@ package com.tangem.features.onboarding.v2.entry.impl.routing
|
||||||
|
|
||||||
import com.tangem.core.decompose.navigation.Route
|
import com.tangem.core.decompose.navigation.Route
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
|
import com.tangem.features.onboarding.v2.TitleProvider
|
||||||
|
|
||||||
sealed class OnboardingRoute : Route {
|
sealed class OnboardingRoute : Route {
|
||||||
|
|
||||||
data class Wallet12(val scanResponse: ScanResponse) : OnboardingRoute()
|
data object None : OnboardingRoute()
|
||||||
|
|
||||||
|
data class Wallet12(
|
||||||
|
val titleProvider: TitleProvider,
|
||||||
|
val scanResponse: ScanResponse,
|
||||||
|
val withSeedPhraseFlow: Boolean,
|
||||||
|
) : OnboardingRoute()
|
||||||
}
|
}
|
||||||
|
|
@ -4,19 +4,19 @@ import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
|
||||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
|
||||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
import com.arkivanov.decompose.router.stack.ChildStack
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingRoute
|
||||||
import com.tangem.features.onboarding.v2.impl.R
|
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal inline fun OnboardingEntry(
|
internal inline fun OnboardingEntry(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
childStack: ChildStack<OnboardingRoute, Any>,
|
||||||
stepperContent: @Composable (Modifier) -> Unit,
|
stepperContent: @Composable (Modifier) -> Unit,
|
||||||
content: @Composable (Modifier) -> Unit,
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|
@ -25,28 +25,19 @@ internal inline fun OnboardingEntry(
|
||||||
.background(TangemTheme.colors.background.primary),
|
.background(TangemTheme.colors.background.primary),
|
||||||
) {
|
) {
|
||||||
stepperContent(Modifier.fillMaxWidth())
|
stepperContent(Modifier.fillMaxWidth())
|
||||||
content(Modifier.fillMaxSize())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
Children(
|
||||||
@Composable
|
stack = childStack,
|
||||||
private fun Preview() {
|
animation = stackAnimation(slide()),
|
||||||
TangemThemePreview {
|
) {
|
||||||
OnboardingEntry(
|
when (it.configuration) {
|
||||||
stepperContent = {
|
is OnboardingRoute.Wallet12 -> {
|
||||||
TangemTopAppBar(
|
(it.instance as OnboardingMultiWalletComponent).Content(
|
||||||
title = "Onboarding",
|
modifier = modifier,
|
||||||
startButton = TopAppBarButtonUM(
|
|
||||||
iconRes = R.drawable.ic_back_24,
|
|
||||||
enabled = true,
|
|
||||||
onIconClicked = {},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
content = { modifier ->
|
|
||||||
Box(modifier.background(Color.Cyan.copy(alpha = 0.3f)))
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
OnboardingRoute.None -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.api
|
||||||
|
|
||||||
|
import com.tangem.core.decompose.factory.ComponentFactory
|
||||||
|
import com.tangem.core.decompose.navigation.inner.InnerNavigationHolder
|
||||||
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
|
import com.tangem.features.onboarding.v2.TitleProvider
|
||||||
|
|
||||||
|
interface OnboardingMultiWalletComponent : ComposableContentComponent, InnerNavigationHolder {
|
||||||
|
|
||||||
|
data class Params(
|
||||||
|
val titleProvider: TitleProvider,
|
||||||
|
val scanResponse: ScanResponse,
|
||||||
|
val withSeedPhraseFlow: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
|
interface Factory : ComponentFactory<Params, OnboardingMultiWalletComponent>
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
|
import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
|
import com.tangem.core.decompose.navigation.inner.InnerNavigation
|
||||||
|
import com.tangem.core.decompose.navigation.inner.InnerNavigationState
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletModel
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.ui.OnboardingMultiWallet
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor(
|
||||||
|
@Assisted private val context: AppComponentContext,
|
||||||
|
@Assisted private val params: OnboardingMultiWalletComponent.Params,
|
||||||
|
) : OnboardingMultiWalletComponent, AppComponentContext by context {
|
||||||
|
|
||||||
|
private val model: OnboardingMultiWalletModel = getOrCreateModel(params)
|
||||||
|
|
||||||
|
override val innerNavigation: InnerNavigation = object : InnerNavigation {
|
||||||
|
override val state = MutableStateFlow(
|
||||||
|
Wallet12InnerNavigationState(1, 5), // TODO
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun pop(onComplete: (Boolean) -> Unit) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun Content(modifier: Modifier) {
|
||||||
|
val uiState by model.uiState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
OnboardingMultiWallet(
|
||||||
|
modifier = modifier,
|
||||||
|
state = uiState,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory : OnboardingMultiWalletComponent.Factory {
|
||||||
|
override fun create(
|
||||||
|
context: AppComponentContext,
|
||||||
|
params: OnboardingMultiWalletComponent.Params,
|
||||||
|
): DefaultOnboardingMultiWalletComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Wallet12InnerNavigationState(
|
||||||
|
override val stackSize: Int,
|
||||||
|
override val stackMaxSize: Int?,
|
||||||
|
) : InnerNavigationState
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.di
|
||||||
|
|
||||||
|
import com.tangem.core.decompose.di.DecomposeComponent
|
||||||
|
import com.tangem.core.decompose.model.Model
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.DefaultOnboardingMultiWalletComponent
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletModel
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import dagger.multibindings.ClassKey
|
||||||
|
import dagger.multibindings.IntoMap
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal interface ComponentModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
fun bindComponent(factory: DefaultOnboardingMultiWalletComponent.Factory): OnboardingMultiWalletComponent.Factory
|
||||||
|
}
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(DecomposeComponent::class)
|
||||||
|
internal interface ModelModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ClassKey(OnboardingMultiWalletModel::class)
|
||||||
|
fun provideModel(model: OnboardingMultiWalletModel): Model
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.model
|
||||||
|
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.features.onboarding.v2.impl.R
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.ui.state.OnboardingMultiWalletUM
|
||||||
|
|
||||||
|
internal fun resetCardDialog(onConfirm: () -> Unit, onDismiss: () -> Unit, onDismissButtonClick: () -> Unit) =
|
||||||
|
OnboardingMultiWalletUM.Dialog(
|
||||||
|
title = resourceReference(R.string.onboarding_activation_error_title),
|
||||||
|
description = resourceReference(R.string.onboarding_activation_error_message),
|
||||||
|
confirmButtonText = resourceReference(R.string.common_ok),
|
||||||
|
dismissButtonText = resourceReference(R.string.common_support),
|
||||||
|
onDismiss = onDismiss,
|
||||||
|
onConfirm = onConfirm,
|
||||||
|
onDismissButtonClick = onDismissButtonClick,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.model
|
||||||
|
|
||||||
|
import com.tangem.common.CompletionResult
|
||||||
|
import com.tangem.common.core.TangemSdkError
|
||||||
|
import com.tangem.core.decompose.di.ComponentScoped
|
||||||
|
import com.tangem.core.decompose.model.Model
|
||||||
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
|
import com.tangem.domain.feedback.GetCardInfoUseCase
|
||||||
|
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||||
|
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||||
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.ui.state.OnboardingMultiWalletUM
|
||||||
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ComponentScoped
|
||||||
|
internal class OnboardingMultiWalletModel @Inject constructor(
|
||||||
|
paramsContainer: ParamsContainer,
|
||||||
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
|
private val tangemSdkManager: TangemSdkManager,
|
||||||
|
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||||
|
private val getCardInfoUseCase: GetCardInfoUseCase,
|
||||||
|
) : Model() {
|
||||||
|
|
||||||
|
private val params = paramsContainer.require<OnboardingMultiWalletComponent.Params>()
|
||||||
|
private val currentScanResponse = MutableStateFlow(params.scanResponse)
|
||||||
|
|
||||||
|
val state = MutableStateFlow(
|
||||||
|
OnboardingMultiWalletState(
|
||||||
|
currentStep = getInitialStep(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
val uiState = MutableStateFlow(
|
||||||
|
OnboardingMultiWalletUM(
|
||||||
|
onCreateWalletClick = { createWallet(false) },
|
||||||
|
showSeedPhraseOption = params.withSeedPhraseFlow,
|
||||||
|
onOtherOptionsClick = { /* navigate */ },
|
||||||
|
onBack = { },
|
||||||
|
dialog = null,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
initScreenTitleSub()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getInitialStep(): OnboardingMultiWalletState.Step {
|
||||||
|
val card = currentScanResponse.value.card
|
||||||
|
|
||||||
|
return when {
|
||||||
|
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup ->
|
||||||
|
OnboardingMultiWalletState.Step.AddBackupDevice
|
||||||
|
card.wallets.isNotEmpty() && card.backupStatus?.isActive == true ->
|
||||||
|
OnboardingMultiWalletState.Step.FinishBackup
|
||||||
|
else ->
|
||||||
|
OnboardingMultiWalletState.Step.CreateWallet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initScreenTitleSub() {
|
||||||
|
val title = screenTitleByStep(getInitialStep())
|
||||||
|
params.titleProvider.changeTitle(title)
|
||||||
|
|
||||||
|
modelScope.launch {
|
||||||
|
state
|
||||||
|
.map { it.currentStep }
|
||||||
|
.collectLatest { step ->
|
||||||
|
val title = screenTitleByStep(step)
|
||||||
|
params.titleProvider.changeTitle(title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createWallet(shouldReset: Boolean) {
|
||||||
|
modelScope.launch {
|
||||||
|
val result = tangemSdkManager.createProductWallet(
|
||||||
|
scanResponse = currentScanResponse.value,
|
||||||
|
shouldReset = shouldReset,
|
||||||
|
)
|
||||||
|
|
||||||
|
when (result) {
|
||||||
|
is CompletionResult.Success -> {
|
||||||
|
currentScanResponse.update {
|
||||||
|
it.copy(
|
||||||
|
card = result.data.card,
|
||||||
|
derivedKeys = result.data.derivedKeys,
|
||||||
|
primaryCard = result.data.primaryCard,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// Analytics.send(Onboarding.CreateWallet.WalletCreatedSuccessfully())
|
||||||
|
}
|
||||||
|
|
||||||
|
is CompletionResult.Failure -> {
|
||||||
|
if (result.error is TangemSdkError.WalletAlreadyCreated) {
|
||||||
|
// show should reset dialog
|
||||||
|
handleActivationError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleActivationError() {
|
||||||
|
uiState.update {
|
||||||
|
it.copy(
|
||||||
|
dialog = resetCardDialog(
|
||||||
|
onConfirm = {
|
||||||
|
uiState.update { it.copy(dialog = null) }
|
||||||
|
resetCard()
|
||||||
|
},
|
||||||
|
onDismiss = {
|
||||||
|
uiState.update { it.copy(dialog = null) }
|
||||||
|
},
|
||||||
|
onDismissButtonClick = ::navigateToSupportScreen,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetCard() {
|
||||||
|
createWallet(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun navigateToSupportScreen() {
|
||||||
|
modelScope.launch {
|
||||||
|
val cardInfo = getCardInfoUseCase(currentScanResponse.value).getOrNull() ?: return@launch
|
||||||
|
sendFeedbackEmailUseCase(FeedbackEmailType.DirectUserRequest(cardInfo))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.model
|
||||||
|
|
||||||
|
data class OnboardingMultiWalletState(
|
||||||
|
val currentStep: Step,
|
||||||
|
) {
|
||||||
|
|
||||||
|
enum class Step {
|
||||||
|
GeneratePrivateKeys, CreateWallet, AddBackupDevice, FinishBackup, Done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.model
|
||||||
|
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.features.onboarding.v2.impl.R
|
||||||
|
|
||||||
|
fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = when (step) {
|
||||||
|
OnboardingMultiWalletState.Step.GeneratePrivateKeys -> TODO()
|
||||||
|
OnboardingMultiWalletState.Step.CreateWallet -> resourceReference(R.string.onboarding_create_wallet_header)
|
||||||
|
OnboardingMultiWalletState.Step.AddBackupDevice -> TODO()
|
||||||
|
OnboardingMultiWalletState.Step.FinishBackup -> TODO()
|
||||||
|
OnboardingMultiWalletState.Step.Done -> TODO()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.tangem.core.ui.components.BasicDialog
|
||||||
|
import com.tangem.core.ui.components.DialogButtonUM
|
||||||
|
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||||
|
import com.tangem.core.ui.components.SecondaryButton
|
||||||
|
import com.tangem.core.ui.extensions.resolveReference
|
||||||
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
|
import com.tangem.features.onboarding.v2.impl.R
|
||||||
|
import com.tangem.features.onboarding.v2.multiwallet.impl.ui.state.OnboardingMultiWalletUM
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun OnboardingMultiWallet(state: OnboardingMultiWalletUM, modifier: Modifier = Modifier) {
|
||||||
|
if (state.dialog != null) {
|
||||||
|
BasicDialog(
|
||||||
|
title = state.dialog.title.resolveReference(),
|
||||||
|
message = state.dialog.description.resolveReference(),
|
||||||
|
confirmButton = DialogButtonUM(
|
||||||
|
title = state.dialog.confirmButtonText.resolveReference(),
|
||||||
|
onClick = state.dialog.onConfirm,
|
||||||
|
),
|
||||||
|
dismissButton = DialogButtonUM(
|
||||||
|
title = state.dialog.dismissButtonText.resolveReference(),
|
||||||
|
onClick = state.dialog.onDismissButtonClick,
|
||||||
|
),
|
||||||
|
onDismissDialog = state.dialog.onDismiss,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.navigationBarsPadding()
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
) {
|
||||||
|
Box(Modifier.weight(1f))
|
||||||
|
|
||||||
|
PrimaryButtonIconEnd(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
iconResId = R.drawable.ic_tangem_24,
|
||||||
|
text = stringResource(R.string.onboarding_create_wallet_button_create_wallet),
|
||||||
|
onClick = state.onCreateWalletClick,
|
||||||
|
)
|
||||||
|
|
||||||
|
SecondaryButton(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
text = stringResource(R.string.onboarding_create_wallet_options_button_options),
|
||||||
|
onClick = state.onOtherOptionsClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun Preview() {
|
||||||
|
TangemThemePreview {
|
||||||
|
OnboardingMultiWallet(
|
||||||
|
state = OnboardingMultiWalletUM(
|
||||||
|
onCreateWalletClick = {},
|
||||||
|
showSeedPhraseOption = true,
|
||||||
|
onBack = {},
|
||||||
|
onOtherOptionsClick = {},
|
||||||
|
dialog = null,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.tangem.features.onboarding.v2.multiwallet.impl.ui.state
|
||||||
|
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
|
||||||
|
internal data class OnboardingMultiWalletUM(
|
||||||
|
val onCreateWalletClick: () -> Unit,
|
||||||
|
val showSeedPhraseOption: Boolean,
|
||||||
|
val onOtherOptionsClick: () -> Unit,
|
||||||
|
val onBack: () -> Unit,
|
||||||
|
val dialog: Dialog?,
|
||||||
|
) {
|
||||||
|
data class Dialog(
|
||||||
|
val title: TextReference,
|
||||||
|
val description: TextReference,
|
||||||
|
val dismissButtonText: TextReference,
|
||||||
|
val confirmButtonText: TextReference,
|
||||||
|
val onConfirm: () -> Unit,
|
||||||
|
val onDismissButtonClick: () -> Unit,
|
||||||
|
val onDismiss: () -> Unit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
internal interface OnboardingStepperComponent : ComposableContentComponent {
|
internal interface OnboardingStepperComponent : ComposableContentComponent {
|
||||||
|
|
||||||
|
|
@ -22,11 +22,7 @@ internal interface OnboardingStepperComponent : ComposableContentComponent {
|
||||||
val scanResponse: ScanResponse,
|
val scanResponse: ScanResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
val state: StateFlow<StepperState>
|
val state: MutableStateFlow<StepperState>
|
||||||
|
|
||||||
fun changeStep(step: Int)
|
|
||||||
fun nextStep()
|
|
||||||
fun changeTitle(title: TextReference)
|
|
||||||
|
|
||||||
interface Factory : ComponentFactory<Params, OnboardingStepperComponent>
|
interface Factory : ComponentFactory<Params, OnboardingStepperComponent>
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.arkivanov.essenty.instancekeeper.getOrCreateSimple
|
import com.arkivanov.essenty.instancekeeper.getOrCreateSimple
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.domain.feedback.GetCardInfoUseCase
|
import com.tangem.domain.feedback.GetCardInfoUseCase
|
||||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||||
|
|
@ -17,7 +16,6 @@ import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
internal class DefaultOnboardingStepperComponent @AssistedInject constructor(
|
internal class DefaultOnboardingStepperComponent @AssistedInject constructor(
|
||||||
|
|
@ -29,24 +27,6 @@ internal class DefaultOnboardingStepperComponent @AssistedInject constructor(
|
||||||
|
|
||||||
override val state = instanceKeeper.getOrCreateSimple { MutableStateFlow(params.initState) }
|
override val state = instanceKeeper.getOrCreateSimple { MutableStateFlow(params.initState) }
|
||||||
|
|
||||||
override fun changeStep(step: Int) {
|
|
||||||
state.update { it.copy(currentStep = step.coerceAtLeast(minimumValue = 0)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun nextStep() {
|
|
||||||
state.update { state ->
|
|
||||||
if (state.currentStep < state.steps - 1) {
|
|
||||||
state.copy(currentStep = state.currentStep + 1)
|
|
||||||
} else {
|
|
||||||
state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun changeTitle(title: TextReference) {
|
|
||||||
state.update { it.copy(title = title) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun openSupport() {
|
private fun openSupport() {
|
||||||
componentScope.launch {
|
componentScope.launch {
|
||||||
val cardInfo = getCardInfoUseCase(params.scanResponse).getOrNull() ?: return@launch
|
val cardInfo = getCardInfoUseCase(params.scanResponse).getOrNull() ?: return@launch
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package com.tangem.features.onboarding.v2.wallet12.api
|
|
||||||
|
|
||||||
import com.tangem.core.decompose.factory.ComponentFactory
|
|
||||||
import com.tangem.core.decompose.navigation.inner.InnerNavigationHolder
|
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
|
|
||||||
interface OnboardingWallet12Component : ComposableContentComponent, InnerNavigationHolder {
|
|
||||||
|
|
||||||
data class Params(val scanResponse: ScanResponse)
|
|
||||||
|
|
||||||
interface Factory : ComponentFactory<Params, OnboardingWallet12Component>
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package com.tangem.features.onboarding.v2.wallet12.impl
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
|
||||||
import com.tangem.core.decompose.navigation.inner.InnerNavigation
|
|
||||||
import com.tangem.core.decompose.navigation.inner.InnerNavigationState
|
|
||||||
import com.tangem.features.onboarding.v2.wallet12.api.OnboardingWallet12Component
|
|
||||||
import dagger.assisted.Assisted
|
|
||||||
import dagger.assisted.AssistedFactory
|
|
||||||
import dagger.assisted.AssistedInject
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
|
|
||||||
@Suppress("UnusedPrivateMember")
|
|
||||||
class DefaultOnboardingWallet12Component @AssistedInject constructor(
|
|
||||||
@Assisted private val context: AppComponentContext,
|
|
||||||
@Assisted private val params: OnboardingWallet12Component.Params,
|
|
||||||
) : OnboardingWallet12Component, AppComponentContext by context {
|
|
||||||
|
|
||||||
override val innerNavigation: InnerNavigation = object : InnerNavigation {
|
|
||||||
override val state = MutableStateFlow(
|
|
||||||
Wallet12InnerNavigationState(0, null), // TODO
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun pop(onComplete: (Boolean) -> Unit) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
override fun Content(modifier: Modifier) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AssistedFactory
|
|
||||||
interface Factory : OnboardingWallet12Component.Factory {
|
|
||||||
override fun create(
|
|
||||||
context: AppComponentContext,
|
|
||||||
params: OnboardingWallet12Component.Params,
|
|
||||||
): DefaultOnboardingWallet12Component
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Wallet12InnerNavigationState(
|
|
||||||
override val stackSize: Int,
|
|
||||||
override val stackMaxSize: Int?,
|
|
||||||
) : InnerNavigationState
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package com.tangem.features.onboarding.v2.wallet12.impl.di
|
|
||||||
|
|
||||||
import com.tangem.features.onboarding.v2.wallet12.api.OnboardingWallet12Component
|
|
||||||
import com.tangem.features.onboarding.v2.wallet12.impl.DefaultOnboardingWallet12Component
|
|
||||||
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 ComponentModule {
|
|
||||||
|
|
||||||
@Binds
|
|
||||||
@Singleton
|
|
||||||
fun bindOnboardingWallet12Component(
|
|
||||||
factory: DefaultOnboardingWallet12Component.Factory,
|
|
||||||
): OnboardingWallet12Component.Factory
|
|
||||||
}
|
|
||||||
1
libs/tangem-sdk-api/.gitignore
vendored
Normal file
1
libs/tangem-sdk-api/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
35
libs/tangem-sdk-api/build.gradle.kts
Normal file
35
libs/tangem-sdk-api/build.gradle.kts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
plugins {
|
||||||
|
alias(deps.plugins.android.library)
|
||||||
|
alias(deps.plugins.kotlin.android)
|
||||||
|
alias(deps.plugins.kotlin.kapt)
|
||||||
|
alias(deps.plugins.kotlin.serialization)
|
||||||
|
alias(deps.plugins.hilt.android)
|
||||||
|
id("configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.tangem.legacy"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(projects.common)
|
||||||
|
implementation(projects.domain.models)
|
||||||
|
implementation(projects.domain.card)
|
||||||
|
implementation(projects.domain.legacy)
|
||||||
|
implementation(projects.domain.wallets.models)
|
||||||
|
|
||||||
|
implementation(projects.core.res)
|
||||||
|
|
||||||
|
/** Tangem libraries */
|
||||||
|
implementation(deps.tangem.card.core)
|
||||||
|
implementation(deps.tangem.card.android) {
|
||||||
|
exclude(module = "joda-time")
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Other libraries */
|
||||||
|
implementation(deps.timber)
|
||||||
|
|
||||||
|
/** DI */
|
||||||
|
implementation(deps.hilt.android)
|
||||||
|
kapt(deps.hilt.kapt)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.tangem.sdk.api
|
||||||
|
|
||||||
|
import com.tangem.common.card.Card
|
||||||
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
|
import com.tangem.domain.models.scan.KeyWalletPublicKey
|
||||||
|
import com.tangem.operations.CommandResponse
|
||||||
|
import com.tangem.operations.backup.PrimaryCard
|
||||||
|
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||||
|
|
||||||
|
data class CreateProductWalletTaskResponse(
|
||||||
|
val card: CardDTO,
|
||||||
|
val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
||||||
|
val primaryCard: PrimaryCard? = null,
|
||||||
|
) : CommandResponse {
|
||||||
|
constructor(
|
||||||
|
card: Card,
|
||||||
|
derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
||||||
|
primaryCard: PrimaryCard? = null,
|
||||||
|
) : this(
|
||||||
|
card = CardDTO(card),
|
||||||
|
derivedKeys = derivedKeys,
|
||||||
|
primaryCard = primaryCard,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.tap.domain.sdk
|
package com.tangem.sdk.api
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
|
@ -19,7 +19,6 @@ import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||||
import com.tangem.operations.preflightread.PreflightReadFilter
|
import com.tangem.operations.preflightread.PreflightReadFilter
|
||||||
import com.tangem.operations.wallet.CreateWalletResponse
|
import com.tangem.operations.wallet.CreateWalletResponse
|
||||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
|
||||||
|
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
interface TangemSdkManager {
|
interface TangemSdkManager {
|
||||||
|
|
@ -96,8 +95,8 @@ interface TangemSdkManager {
|
||||||
): CompletionResult<CardDTO>
|
): CompletionResult<CardDTO>
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"TangemSdkManager shouldn't run custom tasks. " +
|
"com.tangem.sdk.api.TangemSdkManager shouldn't run custom tasks. " +
|
||||||
"All of them should be specified in TangemSdkManager certain methods.",
|
"All of them should be specified in com.tangem.sdk.api.TangemSdkManager certain methods.",
|
||||||
)
|
)
|
||||||
suspend fun <T> runTaskAsync(
|
suspend fun <T> runTaskAsync(
|
||||||
runnable: CardSessionRunnable<T>,
|
runnable: CardSessionRunnable<T>,
|
||||||
|
|
@ -111,7 +110,7 @@ interface TangemSdkManager {
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
fun changeDisplayedCardIdNumbersCount(scanResponse: ScanResponse?)
|
fun changeDisplayedCardIdNumbersCount(scanResponse: ScanResponse?)
|
||||||
|
|
||||||
@Deprecated("TangemSdkManager shouldn't returns a string from resources")
|
@Deprecated("com.tangem.sdk.api.TangemSdkManager shouldn't returns a string from resources")
|
||||||
fun getString(@StringRes stringResId: Int, vararg formatArgs: Any?): String
|
fun getString(@StringRes stringResId: Int, vararg formatArgs: Any?): String
|
||||||
|
|
||||||
fun setUserCodeRequestPolicy(policy: UserCodeRequestPolicy)
|
fun setUserCodeRequestPolicy(policy: UserCodeRequestPolicy)
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.tangem.sdk.api
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import com.tangem.common.core.TangemError
|
||||||
|
import com.tangem.legacy.R
|
||||||
|
|
||||||
|
interface TapErrors
|
||||||
|
|
||||||
|
interface ArgError {
|
||||||
|
val args: List<Any>?
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MultiMessageError : TapErrors {
|
||||||
|
val errorList: List<TapError>
|
||||||
|
val builder: (List<String>) -> String
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class TapError(
|
||||||
|
@StringRes val messageResource: Int,
|
||||||
|
override val args: List<Any>? = null,
|
||||||
|
) : Throwable(), TapErrors, ArgError {
|
||||||
|
|
||||||
|
object UnknownError : TapError(R.string.send_error_unknown)
|
||||||
|
open class CustomError(val customMessage: String) : TapError(R.string.common_custom_string, listOf(customMessage))
|
||||||
|
|
||||||
|
object NoInternetConnection : TapError(R.string.wallet_notification_no_internet)
|
||||||
|
|
||||||
|
sealed class WalletManager {
|
||||||
|
class NoAccountError(amountToCreateAccount: String) : CustomError(amountToCreateAccount)
|
||||||
|
class InternalError(message: String) : CustomError(message)
|
||||||
|
object BlockchainIsUnreachableTryLater : TapError(R.string.wallet_balance_blockchain_unreachable_try_later)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) {
|
||||||
|
override var customMessage: String = code.toString()
|
||||||
|
|
||||||
|
object CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
|
||||||
|
object CardNotSupportedByRelease : TapSdkError(R.string.error_wrong_card_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TapErrors.assembleErrors(): MutableList<Pair<Int, List<Any>?>> {
|
||||||
|
val idList = mutableListOf<Pair<Int, List<Any>?>>()
|
||||||
|
when (this) {
|
||||||
|
is MultiMessageError -> this.errorList.forEach { idList.addAll(it.assembleErrors()) }
|
||||||
|
is TapError -> idList.add(Pair(this.messageResource, this.args))
|
||||||
|
}
|
||||||
|
return idList
|
||||||
|
}
|
||||||
|
|
@ -147,6 +147,7 @@ include(":libs:auth")
|
||||||
include(":libs:blockchain-sdk")
|
include(":libs:blockchain-sdk")
|
||||||
include(":libs:crypto")
|
include(":libs:crypto")
|
||||||
include(":libs:visa")
|
include(":libs:visa")
|
||||||
|
include(":libs:tangem-sdk-api")
|
||||||
// endregion Libs modules
|
// endregion Libs modules
|
||||||
|
|
||||||
// region Feature modules
|
// region Feature modules
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue