From 0d993b5141832225c2ae0bc4537193f5dd4612af Mon Sep 17 00:00:00 2001 From: Tangem Date: Sat, 12 Nov 2022 03:46:02 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/common/analytics/TangemSdkError.kt | 4 +- .../converters/BasicEventConverter.kt | 6 +- .../common/feedback/AdditionalFeedbackInfo.kt | 4 +- .../tap/common/redux/global/GlobalReducer.kt | 20 ++-- .../com/tangem/tap/domain/TangemSdkManager.kt | 26 +++-- .../com/tangem/tap/domain/TangemSigner.kt | 4 +- .../java/com/tangem/tap/domain/TapErrors.kt | 5 +- .../com/tangem/tap/domain/TapWalletManager.kt | 4 +- .../com/tangem/tap/domain/extensions/Card.kt | 65 ++++-------- .../domain/extensions/WalletManagerFactory.kt | 7 +- .../tasks/product/CreateProductWalletTask.kt | 100 +++++++++++++----- .../tasks/product/ProductCommandProcessor.kt | 4 +- .../domain/tasks/product/ScanProductTask.kt | 83 ++++++++++----- .../tangem/tap/domain/termsOfUse/CardTou.kt | 6 +- .../tap/domain/tokens/CurrenciesRepository.kt | 7 +- .../tap/domain/tokens/UserTokensRepository.kt | 33 +++--- .../domain/tokens/UserTokensStorageService.kt | 4 +- .../domain/tokens/models/BlockchainNetwork.kt | 12 ++- .../domain/twins/CreateFirstTwinWalletTask.kt | 1 - .../twins/CreateSecondTwinWalletTask.kt | 4 +- .../tap/domain/twins/TwinCardsManager.kt | 5 +- .../twins/WriteProtectedIssuerDataTask.kt | 3 +- .../tangem/tap/features/demo/Extentions.kt | 4 +- .../features/details/redux/DetailsAction.kt | 4 +- .../details/redux/DetailsMiddleware.kt | 34 +++--- .../features/details/redux/DetailsReducer.kt | 23 ++-- .../features/details/redux/DetailsState.kt | 10 +- .../walletconnect/WalletConnectMiddleware.kt | 4 +- .../disclaimer/redux/DisclaimerState.kt | 4 +- .../tap/features/home/redux/HomeAction.kt | 2 +- .../tap/features/home/redux/HomeMiddleware.kt | 12 +-- .../features/onboarding/OnboardingHelper.kt | 3 +- .../note/redux/OnboardingNoteMiddleware.kt | 3 +- .../redux/OnboardingOtherCardsMiddleware.kt | 35 ++++-- .../twins/redux/TwinCardsMiddleware.kt | 9 +- .../redux/OnboardingWalletMiddleware.kt | 28 +++-- .../saltPay/SaltPayActivationManager.kt | 6 +- .../send/redux/middlewares/SendMiddleware.kt | 4 +- .../tap/features/wallet/models/Currency.kt | 20 ++-- .../tap/features/wallet/redux/WalletAction.kt | 15 +-- .../redux/middlewares/WarningsMiddleware.kt | 10 +- .../wallet/ui/wallet/MultiWalletView.kt | 6 +- .../exchangeServices/CardExchangeRules.kt | 4 +- .../CurrencyExchangeManager.kt | 5 +- .../com/tangem/tap/proxy/AppStateHolder.kt | 4 +- .../tangem/tap/proxy/UserWalletManagerImpl.kt | 8 +- buildSrc/src/main/java/Versions.kt | 9 +- .../com/tangem/domain/common/ScanResponse.kt | 18 +--- .../tangem/domain/common/TapWorkarounds.kt | 61 ++++++----- .../com/tangem/domain/common/TwinsHelper.kt | 7 +- .../domain/common/extensions/CardSdk.kt | 11 +- .../tangem/domain/common/util/UserWalletId.kt | 4 +- .../redux/AddCustomTokenState.kt | 12 +-- 53 files changed, 430 insertions(+), 356 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkError.kt b/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkError.kt index 17e31d88c4..491ef8f683 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkError.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/TangemSdkError.kt @@ -74,7 +74,7 @@ object TangemSdk { is TangemSdkError.UnsupportedWalletConfig -> TangemSdkError.UnsupportedWalletConfig() is TangemSdkError.CryptoUtilsError -> TangemSdkError.CryptoUtilsError(error.customMessage) is TangemSdkError.NetworkError -> TangemSdkError.NetworkError(error.customMessage) - is TangemSdkError.ExceptionError -> TangemSdkError.ExceptionError(error.throwable) + is TangemSdkError.ExceptionError -> TangemSdkError.ExceptionError(error.cause) is TangemSdkError.TooMuchBackupCards -> TangemSdkError.TooMuchBackupCards() is TangemSdkError.BackupCardRequired -> TangemSdkError.BackupCardRequired() is TangemSdkError.CertificateSignatureRequired -> TangemSdkError.CertificateSignatureRequired() @@ -107,6 +107,8 @@ object TangemSdk { is TangemSdkError.BackupFailedFirmware -> TangemSdkError.BackupFailedFirmware() is TangemSdkError.UserForgotTheCode -> TangemSdkError.UserForgotTheCode() is TangemSdkError.BackupFailedIncompatibleBatch -> TangemSdkError.BackupFailedIncompatibleBatch() + is TangemSdkError.BiometricsUnavailable -> error + is TangemSdkError.BiometricsAuthenticationFailed -> error } } diff --git a/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt b/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt index 3950f458bc..301ae0cb07 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt @@ -3,10 +3,10 @@ package com.tangem.tap.common.analytics.converters import com.tangem.common.Converter import com.tangem.common.extensions.isZero import com.tangem.domain.common.ScanResponse +import com.tangem.domain.common.util.userWalletId import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.filters.BasicTopUpFilter -import com.tangem.tap.domain.extensions.getUserWalletId import com.tangem.tap.domain.extensions.isMultiwalletAllowed import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.WalletData @@ -29,7 +29,7 @@ class BasicSignInEventConverter( currency = cardCurrency, batch = scanResponse.card.batchId, ).apply { - filterData = scanResponse.card.getUserWalletId() + filterData = scanResponse.card.userWalletId.stringValue } } } @@ -43,7 +43,7 @@ class BasicTopUpEventConverter( val cardCurrency = ParamCardCurrencyConverter().convert(scanResponse) ?: return null val data = BasicTopUpFilter.Data( - walletId = scanResponse.card.getUserWalletId(), + walletId = scanResponse.card.userWalletId.stringValue, cardBalanceState = AnalyticsParam.CardBalanceState.from(value.walletsData), ) diff --git a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt index 632f9f965b..48527059ad 100644 --- a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt +++ b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt @@ -8,7 +8,7 @@ import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.Address -import com.tangem.common.card.CardWallet +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.domain.extensions.getUserWalletId @@ -92,7 +92,7 @@ class AdditionalFeedbackInfo { ) } - private fun formatSignedHashes(wallets: List): String { + private fun formatSignedHashes(wallets: List): String { return wallets.joinToString("\n") { "Signed hashes: ${it.curve.curve} - ${it.totalSignedHashes}" } } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index f8563c233a..f4aa80ad03 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -2,6 +2,7 @@ package com.tangem.tap.common.redux.global import com.tangem.domain.redux.domainStore import com.tangem.domain.redux.global.DomainGlobalAction +import com.tangem.tap.common.extensions.replaceBy import com.tangem.tap.common.redux.AppState import com.tangem.tap.features.onboarding.OnboardingManager import com.tangem.tap.preferencesStorage @@ -49,12 +50,19 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde is GlobalAction.SetWarningManager -> globalState.copy(warningManager = action.warningManager) is GlobalAction.UpdateWalletSignedHashes -> { val card = globalState.scanResponse?.card ?: return globalState - val wallet = card.wallet(action.walletPublicKey) ?: return globalState - val newCardInstance = card.updateWallet( - wallet.copy( - totalSignedHashes = action.walletSignedHashes, - remainingSignatures = action.remainingSignatures, - ), + 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)) } diff --git a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt index 4fe7252ac7..66b16d1cad 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -1,7 +1,5 @@ package com.tangem.tap.domain -import CreateProductWalletTask -import CreateProductWalletTaskResponse import android.content.Context import androidx.annotation.StringRes import com.tangem.Message @@ -10,7 +8,6 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.common.CardFilter import com.tangem.common.CompletionResult import com.tangem.common.SuccessResponse -import com.tangem.common.card.Card import com.tangem.common.card.FirmwareVersion import com.tangem.common.core.CardIdDisplayFormat import com.tangem.common.core.CardSessionRunnable @@ -18,6 +15,8 @@ import com.tangem.common.core.Config import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.ByteArrayKey import com.tangem.common.hdWallet.DerivationPath +import com.tangem.common.map +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.operations.CommandResponse import com.tangem.operations.ScanTask @@ -29,6 +28,8 @@ import com.tangem.operations.pins.SetUserCodeCommand import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask +import com.tangem.tap.domain.tasks.product.CreateProductWalletTask +import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse import com.tangem.tap.domain.tasks.product.ResetToFactorySettingsTask import com.tangem.tap.domain.tasks.product.ScanProductTask import com.tangem.tap.domain.tokens.UserTokensRepository @@ -73,12 +74,13 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co } } - suspend fun createWallet(cardId: String?): CompletionResult { + suspend fun createWallet(cardId: String?): CompletionResult { return runTaskAsyncReturnOnMain( CreateWalletAndRescanTask(), cardId, initialMessage = Message(context.getString(R.string.initial_message_create_wallet_body)), ) + .map { CardDTO(it) } } suspend fun derivePublicKeys( @@ -88,12 +90,13 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co return runTaskAsyncReturnOnMain(DeriveMultipleWalletPublicKeysTask(derivations), cardId) } - suspend fun resetToFactorySettings(card: Card): CompletionResult { + suspend fun resetToFactorySettings(cardId: String): CompletionResult { return runTaskAsyncReturnOnMain( - ResetToFactorySettingsTask(), - card.cardId, + runnable = ResetToFactorySettingsTask(), + cardId = cardId, initialMessage = Message(context.getString(R.string.card_settings_reset_card_to_factory)), ) + .map { CardDTO(it) } } suspend fun setPasscode(cardId: String?): CompletionResult { @@ -128,11 +131,12 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co ) } - suspend fun scanCard(): CompletionResult { + suspend fun scanCard(): CompletionResult { return runTaskAsyncReturnOnMain( - ScanTask(), + runnable = ScanTask(), initialMessage = Message(context.getString(R.string.initial_message_tap_header)), ) + .map { CardDTO(it) } } suspend fun runTaskAsync( @@ -150,7 +154,9 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co } private suspend fun runTaskAsyncReturnOnMain( - runnable: CardSessionRunnable, cardId: String? = null, initialMessage: Message? = null, + runnable: CardSessionRunnable, + cardId: String? = null, + initialMessage: Message? = null, ): CompletionResult { val result = runTaskAsync(runnable, cardId, initialMessage) return withContext(Dispatchers.Main) { result } diff --git a/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt b/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt index af5cdb6a5c..1979b1df8a 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt @@ -5,13 +5,13 @@ import com.tangem.TangemSdk import com.tangem.blockchain.common.TransactionSigner import com.tangem.blockchain.common.Wallet import com.tangem.common.CompletionResult -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.tap.domain.tasks.SignHashesTask import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine class TangemSigner( - private val card: Card, + private val card: CardDTO, private val tangemSdk: TangemSdk, private val initialMessage: Message, private val accessCode: String? = null, diff --git a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt index 5a0cf85668..0bc9a2c283 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt @@ -64,8 +64,7 @@ sealed class TapError( ) : TapError(-1), MultiMessageError } -sealed class TapSdkError(override val messageResId: Int?) : Throwable(), TangemError { - final override val code: Int = 50100 +sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) { override var customMessage: String = code.toString() object CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card) @@ -88,4 +87,4 @@ fun TangemTechError.toTapError(): TapError { } } -class NoDataError(message: String) : TapError.CustomError(customMessage = message) +class NoDataError(message: String) : TapError.CustomError(customMessage = message) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index b15f2a7431..bb07af060e 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -6,8 +6,8 @@ import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.WalletManagerFactory -import com.tangem.common.card.Card import com.tangem.common.services.Result +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.common.TapWorkarounds.isTestCard @@ -96,7 +96,7 @@ class TapWalletManager { store.dispatch( WalletAction.MultiWallet.ShowWalletBackupWarning( show = data.card.settings.isBackupAllowed - && data.card.backupStatus == Card.BackupStatus.NoBackup, + && data.card.backupStatus == CardDTO.BackupStatus.NoBackup, ), ) loadData(data) diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt b/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt index ab2ba5610b..fd46ad2fde 100644 --- a/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt +++ b/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt @@ -1,58 +1,45 @@ package com.tangem.tap.domain.extensions -import com.tangem.common.card.Card -import com.tangem.common.card.CardWallet import com.tangem.common.card.EllipticCurve import com.tangem.common.card.FirmwareVersion -import com.tangem.common.extensions.calculateSha256 import com.tangem.common.extensions.toHexString import com.tangem.common.services.Result +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.isSaltPay import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.common.TapWorkarounds.isTangemNote import com.tangem.domain.common.TwinCardNumber -import com.tangem.domain.common.extensions.calculateHmacSha256 import com.tangem.domain.common.getTwinCardNumber import com.tangem.domain.common.isTangemTwin import com.tangem.operations.attestation.CardVerifyAndGetInfo import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.features.wallet.redux.Artwork -val Card.remainingSignatures: Int? - get() = this.getSingleWallet()?.remainingSignatures +val CardDTO.remainingSignatures: Int? + get() = this.wallets.firstOrNull()?.remainingSignatures -val Card.isWalletDataSupported: Boolean +val CardDTO.isWalletDataSupported: Boolean get() = this.firmwareVersion.major >= 4 -val Card.isMultiwalletAllowed: Boolean +val CardDTO.isMultiwalletAllowed: Boolean get() { - return !isTangemTwin() && !isStart2Coin && !isTangemNote && !isSaltPay - && (firmwareVersion >= FirmwareVersion.MultiWalletAvailable || - getSingleWallet()?.curve == EllipticCurve.Secp256k1) + return !isTangemTwin() && !isStart2Coin && !isTangemNote && !isSaltPay && + (firmwareVersion >= FirmwareVersion.MultiWalletAvailable || + wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1) } -val Card.isHdWalletAllowedByApp: Boolean +val CardDTO.isHdWalletAllowedByApp: Boolean get() = settings.isHDWalletAllowed && !isSaltPay -fun Card.getSingleWallet(): CardWallet? { - return wallets.firstOrNull() +fun CardDTO.hasSignedHashes(): Boolean { + return wallets.any { (it.totalSignedHashes ?: 0) > 0 } } -fun Card.hasWallets(): Boolean = wallets.isNotEmpty() - -fun Card.hasNoWallets(): Boolean = wallets.isEmpty() - -fun Card.hasSingleWallet(): Boolean = wallets.size == 1 - -fun Card.hasSignedHashes(): Boolean { - return wallets.any { it.totalSignedHashes ?: 0 > 0 } +fun CardDTO.signedHashesCount(): Int { + return wallets.sumOf { it.totalSignedHashes ?: 0 } } -fun Card.signedHashesCount(): Int { - return wallets.map { it.totalSignedHashes ?: 0 }.sum() -} - -suspend fun Card.getOrLoadCardArtworkUrl(cardInfo: Result? = null): String { +suspend fun CardDTO.getOrLoadCardArtworkUrl(cardInfo: Result? = null): String { fun ifAnyError(): String { return when { cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL @@ -67,42 +54,28 @@ suspend fun Card.getOrLoadCardArtworkUrl(cardInfo: Result { val artworkId = cardInfoResult.data.artwork?.id - if (artworkId == null || artworkId.isEmpty()) { + if (artworkId.isNullOrEmpty()) { ifAnyError() } else { OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId) } } + is Result.Failure -> ifAnyError() } } -fun Card.getArtworkUrl(artworkId: String?): String? { +fun CardDTO.getArtworkUrl(artworkId: String?): String? { return when { artworkId != null -> { OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId) } + cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL else -> null } -} - -fun Card.getUserWalletId(): String { - val walletPublicKey = this.wallets.firstOrNull()?.publicKey ?: return "" - return UserWalletId(walletPublicKey).stringValue -} - -class UserWalletId(val walletPublicKey: ByteArray) { - val stringValue: String = calculateUserId(walletPublicKey) - - private fun calculateUserId(walletPublicKey: ByteArray): String { - val message = "UserWalletID".toByteArray() - val keyHash = walletPublicKey.calculateSha256() - return message.calculateHmacSha256(keyHash).toHexString() - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt b/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt index ec95e13dc6..874e562a2a 100644 --- a/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt +++ b/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt @@ -7,13 +7,12 @@ import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.WalletManagerFactory -import com.tangem.common.card.Card -import com.tangem.common.card.CardWallet import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.guard import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toMapKey import com.tangem.common.hdWallet.DerivationPath +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.SaltPayWorkaround import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isTestCard @@ -82,7 +81,7 @@ fun WalletManagerFactory.makeWalletManagerForApp( ) } -private fun getDerivationParams(derivationPath: String?, card: Card): DerivationParams? { +private fun getDerivationParams(derivationPath: String?, card: CardDTO): DerivationParams? { return derivationPath?.let { DerivationParams.Custom( DerivationPath(it), @@ -132,7 +131,7 @@ fun WalletManagerFactory.makePrimaryWalletManager( ) } -private fun selectWallet(wallets: List): CardWallet? { +private fun selectWallet(wallets: List): CardDTO.Wallet? { return when (wallets.size) { 0 -> null 1 -> wallets[0] diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt index 982ed86857..91006e8dab 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt @@ -1,3 +1,5 @@ +package com.tangem.tap.domain.tasks.product + import com.tangem.blockchain.common.Blockchain import com.tangem.common.CompletionResult import com.tangem.common.card.Card @@ -9,6 +11,8 @@ import com.tangem.common.extensions.ByteArrayKey import com.tangem.common.extensions.guard import com.tangem.common.extensions.toMapKey import com.tangem.common.hdWallet.DerivationPath +import com.tangem.common.map +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.KeyWalletPublicKey import com.tangem.domain.common.ProductType import com.tangem.domain.common.TapWorkarounds.derivationStyle @@ -19,19 +23,37 @@ import com.tangem.operations.backup.PrimaryCard import com.tangem.operations.backup.StartPrimaryCardLinkingTask import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask import com.tangem.operations.derivation.ExtendedPublicKeysMap -import com.tangem.operations.wallet.CreateWalletResponse import com.tangem.operations.wallet.CreateWalletTask -import com.tangem.tap.domain.tasks.product.CreateWalletsTask -import com.tangem.tap.domain.tasks.product.ProductCommandProcessor -import com.tangem.tap.domain.tasks.product.getCurvesForNonCreatedWallets import com.tangem.tap.features.demo.DemoHelper - +import com.tangem.operations.wallet.CreateWalletResponse as SdkCreateWalletResponse data class CreateProductWalletTaskResponse( - val card: Card, + val card: CardDTO, val derivedKeys: Map = mapOf(), - val primaryCard: PrimaryCard? = null -) : CommandResponse + val primaryCard: PrimaryCard? = null, +) : CommandResponse { + constructor( + card: Card, + derivedKeys: Map = mapOf(), + primaryCard: PrimaryCard? = null, + ) : this( + card = CardDTO(card), + derivedKeys = derivedKeys, + primaryCard = primaryCard, + ) +} + +private data class CreateWalletResponse( + val cardId: String, + val wallet: CardDTO.Wallet, +) { + constructor( + sdkResponse: SdkCreateWalletResponse, + ) : this( + cardId = sdkResponse.cardId, + wallet = CardDTO.Wallet(sdkResponse.wallet), + ) +} class CreateProductWalletTask( private val type: ProductType, @@ -39,29 +61,32 @@ class CreateProductWalletTask( override fun run( session: CardSession, - callback: (result: CompletionResult) -> Unit + callback: (result: CompletionResult) -> Unit, ) { val card = session.environment.card.guard { callback(CompletionResult.Failure(TangemSdkError.CardError())) return } + val cardDto = CardDTO(card) val commandProcessor = when (type) { ProductType.Note -> CreateWalletTangemNote() ProductType.Twins -> throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet") else -> CreateWalletTangemWallet() } - commandProcessor.proceed(card, session) { + commandProcessor.proceed(cardDto, session) { when (it) { is CompletionResult.Success -> { val result = when (commandProcessor) { is CreateWalletTangemWallet -> { it.data as CreateProductWalletTaskResponse } + else -> CreateProductWalletTaskResponse(card = session.environment.card!!) } callback(CompletionResult.Success(result)) } + is CompletionResult.Failure -> callback(CompletionResult.Failure(it.error)) } } @@ -70,7 +95,7 @@ class CreateProductWalletTask( private class CreateWalletTangemNote : ProductCommandProcessor { override fun proceed( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { @@ -94,52 +119,65 @@ private class CreateWalletTangemNote : ProductCommandProcessor + callback(result.map { CreateWalletResponse(it) }) + } } } } private class CreateWalletTangemWallet : ProductCommandProcessor { - private lateinit var card: Card private var primaryCard: PrimaryCard? = null override fun proceed( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { - this.card = card val curves = card.getCurvesForNonCreatedWallets() if (curves.isEmpty()) { - val createWalletResponses = card.wallets.map { CreateWalletResponse(card.cardId, it) } - proceedWithCreatedWallets(createWalletResponses, session, callback) + val createWalletResponses = card.wallets.map { wallet -> + CreateWalletResponse(card.cardId, wallet) + } + proceedWithCreatedWallets(card, createWalletResponses, session, callback) return } CreateWalletsTask(curves).run(session) { result -> when (result) { is CompletionResult.Success -> { - proceedWithCreatedWallets(result.data.createWalletResponses, session, callback) + proceedWithCreatedWallets( + card = card, + createWalletResponses = result.data.createWalletResponses.map { CreateWalletResponse(it) }, + session = session, + callback = callback, + ) + } + + is CompletionResult.Failure -> { + callback(CompletionResult.Failure(result.error)) } - is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) } } } private fun proceedWithCreatedWallets( + card: CardDTO, createWalletResponses: List, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { when { card.settings.isBackupAllowed -> { - linkPrimaryCard(createWalletResponses, session, callback) + linkPrimaryCard(card, createWalletResponses, session, callback) } + card.settings.isHDWalletAllowed -> { - deriveKeys(createWalletResponses, session, callback) + deriveKeys(card, createWalletResponses, session, callback) } + else -> { callback( CompletionResult.Success( @@ -151,6 +189,7 @@ private class CreateWalletTangemWallet : ProductCommandProcessor, session: CardSession, callback: (result: CompletionResult) -> Unit, @@ -161,8 +200,9 @@ private class CreateWalletTangemWallet : ProductCommandProcessor { - deriveKeys(createWalletResponse, session, callback) + deriveKeys(card, createWalletResponse, session, callback) } + else -> { callback( CompletionResult.Success( @@ -174,6 +214,7 @@ private class CreateWalletTangemWallet : ProductCommandProcessor { callback(CompletionResult.Failure(result.error)) } @@ -182,13 +223,14 @@ private class CreateWalletTangemWallet : ProductCommandProcessor, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { val map = mutableMapOf>() createWalletResponse.forEach { response -> - val blockchainsForCurve = getBlockchains(response.cardId).filter { + val blockchainsForCurve = getBlockchains(response.cardId, card).filter { it.getSupportedCurves().contains(response.wallet.curve) } val derivationPaths = blockchainsForCurve.mapNotNull { it.derivationPath(card.derivationStyle) } @@ -210,17 +252,21 @@ private class CreateWalletTangemWallet : ProductCommandProcessor callback(CompletionResult.Failure(result.error)) } } } - private fun getBlockchains(cardId: String): List { + private fun getBlockchains( + cardId: String, + card: CardDTO, + ): List { return when { DemoHelper.isDemoCardId(cardId) -> DemoHelper.config.demoBlockchains card.isTestCard -> listOf(Blockchain.BitcoinTestnet, Blockchain.EthereumTestnet) diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ProductCommandProcessor.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ProductCommandProcessor.kt index c0810ff887..8b9d8d9d2f 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ProductCommandProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ProductCommandProcessor.kt @@ -1,15 +1,15 @@ package com.tangem.tap.domain.tasks.product import com.tangem.common.CompletionResult -import com.tangem.common.card.Card import com.tangem.common.core.CardSession +import com.tangem.domain.common.CardDTO /** [REDACTED_AUTHOR] */ interface ProductCommandProcessor { fun proceed( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt index 459191b260..575f5fc05f 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt @@ -13,6 +13,7 @@ import com.tangem.common.extensions.guard import com.tangem.common.extensions.toHexString import com.tangem.common.extensions.toMapKey import com.tangem.common.hdWallet.DerivationPath +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ProductType import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isExcluded @@ -31,7 +32,6 @@ import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand import com.tangem.tap.domain.TapSdkError import com.tangem.tap.domain.extensions.getPrimaryCurve -import com.tangem.tap.domain.extensions.getSingleWallet import com.tangem.tap.domain.extensions.isMultiwalletAllowed import com.tangem.tap.domain.tokens.UserTokensRepository import com.tangem.tap.domain.tokens.models.BlockchainNetwork @@ -53,19 +53,20 @@ class ScanProductTask( callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) return } + val cardDto = CardDTO(card) - val error = getErrorIfExcludedCard(card) + val error = getErrorIfExcludedCard(cardDto) if (error != null) { callback(CompletionResult.Failure(error)) return } val commandProcessor = when { - card.isTangemNote -> ScanNoteProcessor() - card.isTangemTwins -> ScanTwinProcessor() + cardDto.isTangemNote -> ScanNoteProcessor() + cardDto.isTangemTwins -> ScanTwinProcessor() else -> ScanWalletProcessor(userTokensRepository, additionalBlockchainsToDerive) } - commandProcessor.proceed(card, session) { processorResult -> + commandProcessor.proceed(cardDto, session) { processorResult -> when (processorResult) { is CompletionResult.Success -> ScanTask().run(session) { scanTaskResult -> when (scanTaskResult) { @@ -73,7 +74,7 @@ class ScanProductTask( // it need because processorResult.data.card doesn't contains attestation result // and CardWallet.derivedKeys val processorScanResponseWithNewCard = processorResult.data.copy( - card = scanTaskResult.data, + card = CardDTO(scanTaskResult.data), ) callback(CompletionResult.Success(processorScanResponseWithNewCard)) } @@ -85,7 +86,7 @@ class ScanProductTask( } } - private fun getErrorIfExcludedCard(card: Card): TangemError? { + private fun getErrorIfExcludedCard(card: CardDTO): TangemError? { if (card.isExcluded) return TapSdkError.CardForDifferentApp if (card.isNotSupportedInThatRelease) return TapSdkError.CardNotSupportedByRelease return null @@ -94,7 +95,7 @@ class ScanProductTask( private class ScanNoteProcessor : ProductCommandProcessor { override fun proceed( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { @@ -117,7 +118,7 @@ private class ScanWalletProcessor( var primaryCard: PrimaryCard? = null override fun proceed( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { @@ -125,7 +126,7 @@ private class ScanWalletProcessor( } private fun createMissingWalletsIfNeeded( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { @@ -159,13 +160,13 @@ private class ScanWalletProcessor( } private fun startLinkingForBackupIfNeeded( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { val activationInProgress = preferencesStorage.usedCardsPrefStorage.isActivationInProgress(card.cardId) - if ((card.backupStatus == Card.BackupStatus.NoBackup && card.wallets.isNotEmpty()) + if ((card.backupStatus == CardDTO.BackupStatus.NoBackup && card.wallets.isNotEmpty()) && (activationInProgress || card.isSaltPay) ) { StartPrimaryCardLinkingTask().run(session) { linkingResult -> @@ -185,7 +186,7 @@ private class ScanWalletProcessor( } private fun deriveKeysIfNeeded( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { @@ -227,25 +228,46 @@ private class ScanWalletProcessor( } } - private suspend fun getBlockchainsToDerive(card: Card): List { + private suspend fun getBlockchainsToDerive(card: CardDTO): List { val userTokensRepository = userTokensRepository ?: return emptyList() - val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card).toMutableList().ifEmpty { - mutableListOf( - BlockchainNetwork(Blockchain.Bitcoin, card), - BlockchainNetwork(Blockchain.Ethereum, card), - ) - } + val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card) + .toMutableList() + .ifEmpty { + mutableListOf( + BlockchainNetwork( + blockchain = Blockchain.Bitcoin, + card = card, + ), + BlockchainNetwork( + blockchain = Blockchain.Ethereum, + card = card, + ), + ) + } if (card.settings.isHDWalletAllowed) { blockchainsToDerive.addAll( listOf( - BlockchainNetwork(Blockchain.Ethereum, card), - BlockchainNetwork(Blockchain.EthereumTestnet, card), + BlockchainNetwork( + blockchain = Blockchain.Ethereum, + card = card, + ), + BlockchainNetwork( + blockchain = Blockchain.EthereumTestnet, + card = card, + ), ), ) } if (additionalBlockchainsToDerive != null) { - blockchainsToDerive.addAll(additionalBlockchainsToDerive.map { BlockchainNetwork(it, card) }) + blockchainsToDerive.addAll( + additionalBlockchainsToDerive.map { + BlockchainNetwork( + blockchain = it, + card = card, + ) + }, + ) } if (!card.useOldStyleDerivation) { blockchainsToDerive.removeAll( @@ -255,13 +277,18 @@ private class ScanWalletProcessor( Blockchain.RSK, Blockchain.Fantom, Blockchain.FantomTestnet, Blockchain.Avalanche, Blockchain.AvalancheTestnet, - ).map { BlockchainNetwork(it, card) }, + ).map { + BlockchainNetwork( + blockchain = it, + card = card, + ) + }, ) } return blockchainsToDerive.distinct() } - private suspend fun collectDerivations(card: Card): Map> { + private suspend fun collectDerivations(card: CardDTO): Map> { val blockchains = getBlockchainsToDerive(card) val derivations = mutableMapOf>() @@ -287,14 +314,14 @@ private class ScanWalletProcessor( private class ScanTwinProcessor : ProductCommandProcessor { override fun proceed( - card: Card, + card: CardDTO, session: CardSession, callback: (result: CompletionResult) -> Unit, ) { ReadIssuerDataCommand().run(session) { readDataResult -> when (readDataResult) { is CompletionResult.Success -> { - val publicKey = card.getSingleWallet()?.publicKey + val publicKey = card.wallets.firstOrNull()?.publicKey if (publicKey == null) { val response = ScanResponse( card = card, @@ -332,7 +359,7 @@ private class ScanTwinProcessor : ProductCommandProcessor { } } -fun Card.getCurvesForNonCreatedWallets(): List { +fun CardDTO.getCurvesForNonCreatedWallets(): List { val curvesPresent = wallets.map { it.curve }.toSet() val curvesForNonCreatedWallets = supportedCurves.subtract(curvesPresent + EllipticCurve.Secp256r1) return curvesForNonCreatedWallets.toList() diff --git a/app/src/main/java/com/tangem/tap/domain/termsOfUse/CardTou.kt b/app/src/main/java/com/tangem/tap/domain/termsOfUse/CardTou.kt index f05065bc8d..6644362bf5 100644 --- a/app/src/main/java/com/tangem/tap/domain/termsOfUse/CardTou.kt +++ b/app/src/main/java/com/tangem/tap/domain/termsOfUse/CardTou.kt @@ -3,8 +3,8 @@ package com.tangem.tap.domain.termsOfUse import android.content.res.Resources import android.net.Uri import androidx.core.os.ConfigurationCompat -import com.tangem.common.card.Card -import java.util.Locale +import com.tangem.domain.common.CardDTO +import java.util.* /** [REDACTED_AUTHOR] @@ -13,7 +13,7 @@ class CardTou { private val locale: Locale = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)!! - fun getUrl(card: Card): Uri? { + fun getUrl(card: CardDTO): Uri? { val issuerName = card.issuer.name if (issuerName.lowercase(Locale.getDefault()) != "start2coin") return null diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt index d3d5836701..28bcdc9c35 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt @@ -2,10 +2,11 @@ package com.tangem.tap.domain.tokens import com.tangem.blockchain.common.Blockchain import com.tangem.common.card.FirmwareVersion +import com.tangem.domain.common.CardDTO object CurrenciesRepository { fun getBlockchains( - cardFirmware: FirmwareVersion, + cardFirmware: CardDTO.FirmwareVersion, isTestNet: Boolean = false, ): List { val blockchains = if (cardFirmware < FirmwareVersion.MultiWalletAvailable) { @@ -26,6 +27,4 @@ object CurrenciesRepository { ) } } -} - - +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt index 40b8389049..4d6646ed32 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt @@ -2,13 +2,13 @@ package com.tangem.tap.domain.tokens import android.content.Context import com.tangem.blockchain.common.DerivationStyle -import com.tangem.common.card.Card import com.tangem.common.services.Result +import com.tangem.domain.common.CardDTO +import com.tangem.domain.common.util.userWalletId import com.tangem.network.api.tangemTech.TangemTechService import com.tangem.network.api.tangemTech.UserTokensResponse import com.tangem.tap.common.AndroidFileReader import com.tangem.tap.domain.NoDataError -import com.tangem.tap.domain.extensions.getUserWalletId import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.wallet.models.Currency @@ -23,8 +23,8 @@ class UserTokensRepository( private val storageService: UserTokensStorageService, private val networkService: UserTokensNetworkService, ) { - suspend fun getUserTokens(card: Card): List { - val userId = card.getUserWalletId() + suspend fun getUserTokens(card: CardDTO): List { + val userId = card.userWalletId.stringValue if (DemoHelper.isDemoCardId(card.cardId)) { return loadTokensOffline(card, userId).ifEmpty { loadDemoCurrencies() } } @@ -36,25 +36,28 @@ class UserTokensRepository( return when (val networkResult = networkService.getUserTokens(userId)) { is Result.Success -> { val tokens = networkResult.data.tokens.mapNotNull { Currency.fromTokenResponse(it) } - storageService.saveUserTokens(card.getUserWalletId(), tokens.toUserTokensResponse()) + storageService.saveUserTokens(userId, tokens.toUserTokensResponse()) tokens.distinct() } + is Result.Failure -> { handleGetUserTokensFailure(card = card, userId = userId, error = networkResult.error) } } } - suspend fun saveUserTokens(card: Card, tokens: List) { + suspend fun saveUserTokens(card: CardDTO, tokens: List) { + val userId = card.userWalletId.stringValue val userTokens = tokens.toUserTokensResponse() - networkService.saveUserTokens(card.getUserWalletId(), userTokens) - storageService.saveUserTokens(card.getUserWalletId(), userTokens) + networkService.saveUserTokens(userId, userTokens) + storageService.saveUserTokens(userId, userTokens) } - suspend fun removeUserTokens(card: Card) { + suspend fun removeUserTokens(card: CardDTO) { + val userId = card.userWalletId.stringValue val userTokens = emptyList().toUserTokensResponse() - networkService.saveUserTokens(card.getUserWalletId(), userTokens) - storageService.saveUserTokens(card.getUserWalletId(), userTokens) + networkService.saveUserTokens(userId, userTokens) + storageService.saveUserTokens(userId, userTokens) } private fun List.toUserTokensResponse(): UserTokensResponse { @@ -66,8 +69,8 @@ class UserTokensRepository( ) } - suspend fun loadBlockchainsToDerive(card: Card): List { - val userId = card.getUserWalletId() + suspend fun loadBlockchainsToDerive(card: CardDTO): List { + val userId = card.userWalletId.stringValue val blockchainNetworks = loadTokensOffline(card, userId).toBlockchainNetworks() if (DemoHelper.isDemoCardId(card.cardId)) { @@ -89,7 +92,7 @@ class UserTokensRepository( } private suspend fun handleGetUserTokensFailure( - card: Card, + card: CardDTO, userId: String, error: Throwable, ): List { @@ -107,7 +110,7 @@ class UserTokensRepository( } } - private suspend fun loadTokensOffline(card: Card, userId: String): List { + private suspend fun loadTokensOffline(card: CardDTO, userId: String): List { return storageService.getUserTokens(userId) ?: storageService.getUserTokens(card) } diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensStorageService.kt b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensStorageService.kt index c71e5afa53..5f36f9bd49 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensStorageService.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensStorageService.kt @@ -2,7 +2,7 @@ package com.tangem.tap.domain.tokens import com.squareup.moshi.JsonAdapter import com.tangem.Log -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.network.api.tangemTech.UserTokensResponse import com.tangem.network.common.MoshiConverter import com.tangem.tap.common.FileReader @@ -28,7 +28,7 @@ class UserTokensStorageService( } @Deprecated("") - suspend fun getUserTokens(card: Card): List { + suspend fun getUserTokens(card: CardDTO): List { val blockchainNetworks = oldUserTokensRepository.loadSavedCurrencies(card.cardId, card.settings.isHDWalletAllowed) return blockchainNetworks.flatMap { it.toCurrencies() } diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt b/app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt index 36e376a08b..3b9558c303 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt @@ -4,8 +4,8 @@ import com.squareup.moshi.JsonClass import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.WalletManager -import com.tangem.common.card.Card import com.tangem.common.extensions.calculateHashCode +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.derivationStyle @JsonClass(generateAdapter = true) @@ -15,16 +15,18 @@ data class BlockchainNetwork( val tokens: List ) { - constructor(blockchain: Blockchain, card: Card) : this( + constructor( + blockchain: Blockchain, + card: CardDTO, + ) : this( blockchain = blockchain, derivationPath = if (card.settings.isHDWalletAllowed) blockchain.derivationPath(card.derivationStyle)?.rawPath else null, - tokens = emptyList() + tokens = emptyList(), ) - fun updateTokens(tokens: List): BlockchainNetwork { return copy( - tokens = (this.tokens + tokens).distinct() + tokens = (this.tokens + tokens).distinct(), ) } diff --git a/app/src/main/java/com/tangem/tap/domain/twins/CreateFirstTwinWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/twins/CreateFirstTwinWalletTask.kt index 95e8753b3d..3860732b7d 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/CreateFirstTwinWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/CreateFirstTwinWalletTask.kt @@ -9,7 +9,6 @@ import com.tangem.domain.common.TwinsHelper import com.tangem.operations.wallet.CreateWalletResponse import com.tangem.operations.wallet.CreateWalletTask import com.tangem.operations.wallet.PurgeWalletCommand -import com.tangem.tap.domain.extensions.getSingleWallet class CreateFirstTwinWalletTask : CardSessionRunnable { override fun run( diff --git a/app/src/main/java/com/tangem/tap/domain/twins/CreateSecondTwinWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/twins/CreateSecondTwinWalletTask.kt index 8780d00055..cca9da3551 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/CreateSecondTwinWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/CreateSecondTwinWalletTask.kt @@ -23,7 +23,7 @@ class CreateSecondTwinWalletTask( override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { val card = session.environment.card - val publicKey = card?.getSingleWallet()?.publicKey + val publicKey = card?.wallets?.firstOrNull()?.publicKey if (publicKey != null) { if (TwinsHelper.getTwinCardNumber(card.cardId) == TwinCardNumber.First) { callback(CompletionResult.Failure(WrongTwinCard(TwinCardNumber.Second))) @@ -63,4 +63,4 @@ class CreateSecondTwinWalletTask( } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt index ad9df6d287..c29d226df4 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt @@ -6,9 +6,9 @@ import com.tangem.Message import com.tangem.blockchain.extensions.Result import com.tangem.common.CompletionResult import com.tangem.common.KeyPair -import com.tangem.common.card.Card import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.network.common.MoshiConverter import com.tangem.operations.wallet.CreateWalletResponse @@ -16,7 +16,7 @@ import com.tangem.tap.common.AssetReader import com.tangem.tap.tangemSdkManager class TwinCardsManager( - card: Card, + card: CardDTO, assetReader: AssetReader, ) { @@ -91,7 +91,6 @@ class TwinCardsManager( } private class Issuer( - val id: String, val privateKey: String, val publicKey: String, ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt b/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt index e4ae0109bd..31d35c4a06 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt @@ -13,7 +13,6 @@ import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand import com.tangem.operations.issuerAndUserData.ReadIssuerDataResponse import com.tangem.operations.issuerAndUserData.WriteIssuerDataCommand import com.tangem.operations.sign.SignHashCommand -import com.tangem.tap.domain.extensions.getSingleWallet class WriteProtectedIssuerDataTask( private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair, @@ -25,7 +24,7 @@ class WriteProtectedIssuerDataTask( ) { SignHashCommand( twinPublicKey.calculateSha256(), - session.environment.card!!.getSingleWallet()!!.publicKey + session.environment.card!!.wallets.first().publicKey, ) .run(session) { signResult -> when (signResult) { diff --git a/app/src/main/java/com/tangem/tap/features/demo/Extentions.kt b/app/src/main/java/com/tangem/tap/features/demo/Extentions.kt index 66d09bdbf0..1e97beb6e0 100644 --- a/app/src/main/java/com/tangem/tap/features/demo/Extentions.kt +++ b/app/src/main/java/com/tangem/tap/features/demo/Extentions.kt @@ -1,10 +1,10 @@ package com.tangem.tap.features.demo -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse /** [REDACTED_AUTHOR] */ fun ScanResponse.isDemoCard(): Boolean = DemoHelper.isDemoCardId(card.cardId) -fun Card.isDemoCard(): Boolean = DemoHelper.isDemoCardId(cardId) \ No newline at end of file +fun CardDTO.isDemoCard(): Boolean = DemoHelper.isDemoCardId(cardId) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index b421b69730..787e92f332 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -1,7 +1,7 @@ package com.tangem.tap.features.details.redux import com.tangem.blockchain.common.Wallet -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.domain.termsOfUse.CardTou @@ -30,7 +30,7 @@ sealed class DetailsAction : Action { object ScanCard : DetailsAction() - data class PrepareCardSettingsData(val card: Card) : DetailsAction() + data class PrepareCardSettingsData(val card: CardDTO) : DetailsAction() object ResetCardSettingsData : DetailsAction() sealed class ManageSecurity : DetailsAction() { diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index 88191c0ee4..4c2d72d2fe 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -3,6 +3,7 @@ package com.tangem.tap.features.details.redux import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError import com.tangem.domain.common.TapWorkarounds.isTangemTwins +import com.tangem.domain.common.util.userWalletId import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings @@ -13,7 +14,6 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction -import com.tangem.tap.domain.extensions.getUserWalletId import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction @@ -67,11 +67,12 @@ class DetailsMiddleware { scope.launch { when (val result = tangemSdkManager.scanCard()) { is CompletionResult.Success -> { - val card = result.data - if (card.getUserWalletId() == - store.state.globalState.scanResponse?.card?.getUserWalletId() - ) { - store.dispatchOnMain(DetailsAction.PrepareCardSettingsData(card)) + val scannedCard = result.data + val currentCardId = store.state.globalState.scanResponse?.card + ?.userWalletId + ?.stringValue + if (scannedCard.userWalletId.stringValue == currentCardId) { + store.dispatchOnMain(DetailsAction.PrepareCardSettingsData(scannedCard)) } else { store.dispatchDialogShow( AppDialog.SimpleOkDialogRes( @@ -81,8 +82,7 @@ class DetailsMiddleware { ) } } - is CompletionResult.Failure -> { - } + is CompletionResult.Failure -> Unit } } } @@ -104,22 +104,20 @@ class DetailsMiddleware { is DetailsAction.ResetToFactory.Proceed -> { val card = store.state.detailsState.cardSettingsState?.card ?: return scope.launch { - val result = tangemSdkManager.resetToFactorySettings(card) - when (result) { + when (val result = tangemSdkManager.resetToFactorySettings(card.cardId)) { is CompletionResult.Success -> { Analytics.send(Settings.CardSettings.FactoryResetFinished()) store.dispatchOnMain(NavigationAction.PopBackTo(AppScreen.Home)) } + is CompletionResult.Failure -> { (result.error as? TangemSdkError)?.let { error -> - Analytics.send(Settings.CardSettings.FactoryResetFinished(error)) - } + Analytics.send(Settings.CardSettings.FactoryResetFinished(error)) } } } } } - else -> { /* no-op */ - } + else -> Unit } } } @@ -156,8 +154,7 @@ class DetailsMiddleware { } store.dispatch(DetailsAction.ManageSecurity.SaveChanges.Failure) } - else -> { /* no-op */ - } + else -> Unit } } } @@ -171,8 +168,7 @@ class DetailsMiddleware { } } } - else -> { /* no-op */ - } + else -> Unit } } } @@ -186,4 +182,4 @@ class DetailsMiddleware { } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index ef4a0aa975..225505dfde 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -1,6 +1,6 @@ package com.tangem.tap.features.details.redux -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.isSaltPay import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.common.TapWorkarounds.isTangemNote @@ -51,12 +51,12 @@ private fun handlePrepareScreen( scanResponse = action.scanResponse, wallets = action.wallets, cardTermsOfUseUrl = action.cardTou.getUrl(action.scanResponse.card), - createBackupAllowed = action.scanResponse.card.backupStatus == Card.BackupStatus.NoBackup, + createBackupAllowed = action.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup, appCurrency = store.state.globalState.appCurrency, ) } -private fun handlePrepareCardSettingsScreen(card: Card, state: DetailsState): DetailsState { +private fun handlePrepareCardSettingsScreen(card: CardDTO, state: DetailsState): DetailsState { val cardSettingsState = CardSettingsState( cardInfo = card.toCardInfo(), manageSecurityState = prepareSecurityOptions(card), @@ -66,14 +66,16 @@ private fun handlePrepareCardSettingsScreen(card: Card, state: DetailsState): De return state.copy(cardSettingsState = cardSettingsState) } -private fun prepareSecurityOptions(card: Card): ManageSecurityState { +private fun prepareSecurityOptions(card: CardDTO): ManageSecurityState { val securityOption = when { card.isAccessCodeSet -> { SecurityOption.AccessCode } + card.isPasscodeSet == true -> { SecurityOption.PassCode } + else -> { SecurityOption.LongTap } @@ -94,7 +96,7 @@ private fun prepareSecurityOptions(card: Card): ManageSecurityState { ) } -private fun isResetToFactoryAllowedByCard(card: Card): Boolean { +private fun isResetToFactoryAllowedByCard(card: CardDTO): Boolean { val notAllowedByAnyWallet = card.wallets.any { it.settings.isPermanent } val notAllowedByCard = notAllowedByAnyWallet || (card.isWalletDataSupported && (!card.isTangemNote && !card.settings.isBackupAllowed)) || @@ -114,7 +116,8 @@ private fun handleEraseWallet( } private fun handleSecurityAction( - action: DetailsAction.ManageSecurity, state: DetailsState, + action: DetailsAction.ManageSecurity, + state: DetailsState, ): DetailsState { return when (action) { is DetailsAction.ManageSecurity.SelectOption -> { @@ -144,7 +147,8 @@ private fun handleSecurityAction( } private fun handlePrivacyAction( - action: DetailsAction.AppSettings, state: DetailsState, + action: DetailsAction.AppSettings, + state: DetailsState, ): DetailsState { return when (action) { is DetailsAction.AppSettings.SwitchPrivacySetting -> { @@ -157,7 +161,8 @@ private fun handlePrivacyAction( } private fun prepareAllowedSecurityOptions( - card: Card?, currentSecurityOption: SecurityOption?, + card: CardDTO?, + currentSecurityOption: SecurityOption?, ): EnumSet { val allowedSecurityOptions = EnumSet.of(SecurityOption.LongTap) @@ -173,7 +178,7 @@ private fun prepareAllowedSecurityOptions( return allowedSecurityOptions } -private fun Card.toCardInfo(): CardInfo { +private fun CardDTO.toCardInfo(): CardInfo { val cardId = this.cardId.chunked(4).joinToString(separator = " ") val issuer = this.issuer.name val signedHashes = this.signedHashesCount() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index 8e02856097..07c0847213 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -2,7 +2,7 @@ package com.tangem.tap.features.details.redux import android.net.Uri import com.tangem.blockchain.common.Wallet -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.entities.Button import com.tangem.tap.common.entities.FiatCurrency @@ -20,13 +20,13 @@ data class DetailsState( val privacyPolicyUrl: String? = null, val createBackupAllowed: Boolean = false, val appCurrency: FiatCurrency = FiatCurrency.Default, - val saveWallets: Boolean = true, - val saveAccessCodes: Boolean = true, + val saveWallets: Boolean = false, + val saveAccessCodes: Boolean = false, ) : StateType { // if you do not delegate - the application crashes on startup, // because twinCardsState has not been created yet - val twinCardsState: TwinCardsState by ReadOnlyProperty { thisRef, property -> + val twinCardsState: TwinCardsState by ReadOnlyProperty { _, _ -> store.state.twinCardsState } @@ -42,7 +42,7 @@ data class CardInfo( data class CardSettingsState( val cardInfo: CardInfo, - val card: Card, + val card: CardDTO, val manageSecurityState: ManageSecurityState?, val resetCardAllowed: Boolean, val resetConfirmed: Boolean = false, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt index ed2c68c8d6..7818f367b3 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt @@ -3,8 +3,8 @@ package com.tangem.tap.features.details.redux.walletconnect import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.WalletManager -import com.tangem.common.card.Card import com.tangem.common.extensions.guard +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.withMainContext @@ -240,7 +240,7 @@ class WalletConnectMiddleware { handleScanResponse(scanResponse = scanResponse, session = session, blockchain = blockchain) } - private fun getAvailableBlockchains(card: Card, walletState: WalletState): List { + private fun getAvailableBlockchains(card: CardDTO, walletState: WalletState): List { return walletState.currencies.filter { it.isBlockchain() && !it.isCustomCurrency(card.derivationStyle) && it.blockchain.isEvm() }.map { it.blockchain } diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt index 530a4afb78..ee0700f5b5 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt @@ -1,8 +1,8 @@ package com.tangem.tap.features.disclaimer.redux import android.net.Uri -import com.tangem.common.card.Card import com.tangem.common.extensions.VoidCallback +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isSaltPay import org.rekotlin.StateType @@ -22,7 +22,7 @@ sealed class DisclaimerType( companion object { fun get(scanResponse: ScanResponse): DisclaimerType = get(scanResponse.card) - fun get(card: Card): DisclaimerType = when { + fun get(card: CardDTO): DisclaimerType = when { card.isSaltPay -> SaltPay else -> Tangem } diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt index 0a276dff4f..6b71aee0f7 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt @@ -14,4 +14,4 @@ sealed class HomeAction : Action { data class GoToShop(val userCountryCode: String?) : HomeAction() data class ChangeScanCardButtonState(val state: IndeterminateProgressButton) : HomeAction() -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index c3c0145ec8..1d94184e98 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -1,8 +1,8 @@ package com.tangem.tap.features.home.redux -import com.tangem.common.card.Card import com.tangem.common.core.TangemError import com.tangem.common.services.Result +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.extensions.withIOContext import com.tangem.domain.common.extensions.withMainContext @@ -45,7 +45,6 @@ import com.tangem.wallet.R import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.rekotlin.Action -import org.rekotlin.DispatchFunction import org.rekotlin.Middleware class HomeMiddleware { @@ -56,22 +55,23 @@ class HomeMiddleware { } } -private val homeMiddleware: Middleware = { dispatch, state -> +private val homeMiddleware: Middleware = { _, _ -> { next -> { action -> - handleHomeAction(state, action, dispatch) + handleHomeAction(action) next(action) } } } -private fun handleHomeAction(appState: () -> AppState?, action: Action, dispatch: DispatchFunction) { +private fun handleHomeAction(action: Action) { when (action) { is HomeAction.Init -> { store.dispatch(GlobalAction.RestoreAppCurrency) store.dispatch(GlobalAction.ExchangeManager.Init) store.dispatch(GlobalAction.FetchUserCountry) } + is HomeAction.ShouldScanCardOnResume -> { if (action.shouldScanCard) { store.dispatch(HomeAction.ShouldScanCardOnResume(false)) @@ -123,7 +123,7 @@ private fun checkForUnfinishedBackupForSaltPay( return } - fun isTheSamePrimaryCard(card: Card): Boolean { + fun isTheSamePrimaryCard(card: CardDTO): Boolean { return backupService.primaryCardId?.let { it == card.cardId } ?: false } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt index 2917a052fe..f8996b9ea9 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt @@ -3,7 +3,6 @@ package com.tangem.tap.features.onboarding import com.tangem.domain.common.ProductType import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.redux.navigation.AppScreen -import com.tangem.tap.domain.extensions.hasWallets import com.tangem.tap.preferencesStorage /** @@ -23,7 +22,7 @@ class OnboardingHelper { cardInfoStorage.isActivationInProgress(cardId) } } - response.card.hasWallets() -> cardInfoStorage.isActivationInProgress(cardId) + response.card.wallets.isNotEmpty() -> cardInfoStorage.isActivationInProgress(cardId) else -> true } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt index 5ecccaa431..6f17c03078 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt @@ -22,7 +22,6 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.extensions.hasWallets import com.tangem.tap.domain.extensions.makePrimaryWalletManager import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE @@ -79,7 +78,7 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch } is OnboardingNoteAction.DetermineStepOfScreen -> { val step = when { - !card.hasWallets() -> OnboardingNoteStep.CreateWallet + card.wallets.isEmpty() -> OnboardingNoteStep.CreateWallet noteState.walletBalance.balanceIsToppedUp() -> OnboardingNoteStep.Done else -> OnboardingNoteStep.TopUpWallet } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt index 45c4a48fc8..acd4013518 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt @@ -12,7 +12,6 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction -import com.tangem.tap.domain.extensions.hasWallets import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.scope @@ -21,7 +20,6 @@ import com.tangem.tap.tangemSdkManager import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.rekotlin.Action -import org.rekotlin.DispatchFunction import org.rekotlin.Middleware class OnboardingOtherCardsMiddleware { @@ -30,16 +28,16 @@ class OnboardingOtherCardsMiddleware { } } -private val onboardingOtherCardsMiddleware: Middleware = { dispatch, state -> +private val onboardingOtherCardsMiddleware: Middleware = { dispatch, _ -> { next -> { action -> - handleOtherCardsAction(action, dispatch) + handleOtherCardsAction(action) next(action) } } } -private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) { +private fun handleOtherCardsAction(action: Action) { if (action !is OnboardingOtherCardsAction) return val globalState = store.state.globalState val onboardingManager = globalState.onboardingState.onboardingManager ?: return @@ -60,7 +58,7 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) { } is OnboardingOtherCardsAction.DetermineStepOfScreen -> { val step = when { - !card.hasWallets() -> OnboardingOtherCardsStep.CreateWallet + card.wallets.isEmpty() -> OnboardingOtherCardsStep.CreateWallet else -> OnboardingOtherCardsStep.Done } store.dispatch((OnboardingOtherCardsAction.SetStepOfScreen(step))) @@ -87,21 +85,32 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) { val updatedResponse = onboardingManager.scanResponse.copy( card = result.data.card, ) + val updatedCard = updatedResponse.card onboardingManager.scanResponse = updatedResponse - onboardingManager.activationStarted(updatedResponse.card.cardId) + onboardingManager.activationStarted(updatedCard.cardId) val primaryBlockchain = updatedResponse.getBlockchain() val blockchainNetworks = if (primaryBlockchain != Blockchain.Unknown) { val primaryToken = updatedResponse.getPrimaryToken() val blockchainNetwork = - BlockchainNetwork(primaryBlockchain, updatedResponse.card).updateTokens( - listOfNotNull(primaryToken), + BlockchainNetwork( + blockchain = primaryBlockchain, + card = updatedCard, ) + .updateTokens( + listOfNotNull(primaryToken), + ) listOf(blockchainNetwork) } else { listOf( - BlockchainNetwork(Blockchain.Bitcoin, updatedResponse.card), - BlockchainNetwork(Blockchain.Ethereum, updatedResponse.card), + BlockchainNetwork( + blockchain = Blockchain.Bitcoin, + card = updatedCard, + ), + BlockchainNetwork( + blockchain = Blockchain.Ethereum, + card = updatedCard, + ), ) } @@ -126,5 +135,9 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) { withMainContext { store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) } } } + is OnboardingOtherCardsAction.Confetti.Hide, + is OnboardingOtherCardsAction.SetArtworkUrl, + is OnboardingOtherCardsAction.Confetti.Show, + -> Unit } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index aa6de330d6..7233956925 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -150,6 +150,13 @@ private fun handle(action: Action, dispatch: DispatchFunction) { finishCardActivation() postUi(500) { store.dispatch(TwinCardsAction.Confetti.Show) } } + + TwinCardsStep.None, + TwinCardsStep.Warning, + TwinCardsStep.CreateFirstWallet, + TwinCardsStep.CreateSecondWallet, + TwinCardsStep.CreateThirdWallet, + -> Unit } } is TwinCardsAction.Wallet.LaunchFirstStep -> { @@ -299,4 +306,4 @@ private fun handle(action: Action, dispatch: DispatchFunction) { } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index dfe53282ed..31b85f86e6 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -2,8 +2,8 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import com.tangem.blockchain.common.Blockchain import com.tangem.common.CompletionResult -import com.tangem.common.card.Card import com.tangem.common.extensions.ifNotNull +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isSaltPay import com.tangem.domain.common.extensions.withMainContext @@ -18,7 +18,6 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction -import com.tangem.tap.domain.extensions.hasWallets import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.home.redux.HomeAction @@ -76,19 +75,23 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch: // it's possible when found unfinished backup for standard Wallet cards store.dispatch(OnboardingWalletAction.ResumeBackup) } - card.hasWallets() && card.backupStatus == Card.BackupStatus.NoBackup -> { + + card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup -> { store.dispatch(OnboardingWalletAction.ResumeBackup) } - card.hasWallets() && card.backupStatus?.isActive == true -> { + + card.wallets.isNotEmpty() && card.backupStatus?.isActive == true -> { when { // check for unfinished backup for saltPay cards. See more scanResponse.isSaltPay() && backupService.hasIncompletedBackup -> { store.dispatch(OnboardingWalletAction.ResumeBackup) } + scanResponse.isSaltPay() -> { store.dispatch(OnboardingWalletAction.GetToSaltPayStep) store.dispatch(BackupAction.FinishBackup) } + else -> store.dispatch(BackupAction.FinishBackup) } } @@ -125,8 +128,14 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch: ) onboardingManager.scanResponse = updatedResponse val blockchainNetworks = listOf( - BlockchainNetwork(Blockchain.Bitcoin, result.data.card), - BlockchainNetwork(Blockchain.Ethereum, result.data.card), + BlockchainNetwork( + blockchain = Blockchain.Bitcoin, + card = result.data.card, + ), + BlockchainNetwork( + blockchain = Blockchain.Ethereum, + card = result.data.card, + ), ) store.dispatch( WalletAction.MultiWallet.SaveCurrencies( @@ -193,7 +202,7 @@ private fun updateScanResponseAfterBackup( val card = if (backupState.backupCardsNumber > 0) { val cardsCount = backupState.backupCardsNumber scanResponse.card.copy( - backupStatus = Card.BackupStatus.Active(cardCount = cardsCount), + backupStatus = CardDTO.BackupStatus.Active(cardCount = cardsCount), isAccessCodeSet = true, ) } else { @@ -366,9 +375,10 @@ private fun startCardActivation(scanResponse: ScanResponse) { * Standard Wallet cards finish activation at BackupAction.FinishBackup * SaltPay cards finish activation at OnboardingWalletAction.FinishOnboarding */ -internal fun finishCardActivation(backupState: BackupState, card: Card?) { +internal fun finishCardActivation(backupState: BackupState, card: CardDTO?) { (listOf(backupState.primaryCardId, card?.cardId) + backupState.backupCardIds) - .distinct().filterNotNull() + .distinct() + .filterNotNull() .forEach { cardId -> preferencesStorage.usedCardsPrefStorage.activationFinished(cardId) } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/SaltPayActivationManager.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/SaltPayActivationManager.kt index 4ef4b407d2..04933d0a46 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/SaltPayActivationManager.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/SaltPayActivationManager.kt @@ -11,6 +11,7 @@ import com.tangem.common.extensions.guard import com.tangem.common.extensions.isZero import com.tangem.common.services.Result import com.tangem.domain.common.extensions.successOr +import com.tangem.domain.common.util.UserWalletId import com.tangem.network.api.paymentology.AttestationResponse import com.tangem.network.api.paymentology.PaymentologyApiService import com.tangem.network.api.paymentology.RegisterKYCRequest @@ -20,7 +21,6 @@ import com.tangem.network.api.paymentology.RegistrationResponse import com.tangem.network.api.paymentology.tryExtractError import com.tangem.operations.attestation.AttestWalletKeyResponse import com.tangem.tap.common.extensions.safeUpdate -import com.tangem.tap.domain.extensions.UserWalletId import com.tangem.tap.domain.getFirstToken import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayActivationError import java.math.BigDecimal @@ -123,7 +123,7 @@ class SaltPayActivationManager( } suspend fun claim(amountToClaim: BigDecimal, signer: TransactionSigner): Result { - val result = gnosisRegistrator.transferFrom(amountToClaim, signer).successOr { + gnosisRegistrator.transferFrom(amountToClaim, signer).successOr { return Result.Failure(SaltPayActivationError.ClaimTransactionFailed) } return Result.Success(Unit) @@ -192,4 +192,4 @@ class KYCUrlProvider( .appendQueryParameter(kycProvider.externalIdParameterKey, kycRefId) .build().toString() } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index da468c2636..13811d5ed0 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -11,9 +11,9 @@ import com.tangem.blockchain.common.TransactionError import com.tangem.blockchain.common.TransactionSender import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.extensions.SimpleResult -import com.tangem.common.card.Card import com.tangem.common.core.TangemSdkError import com.tangem.common.services.Result +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.common.extensions.withMainContext import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE @@ -150,7 +150,7 @@ private fun sendTransaction( feeAmount: Amount, destinationAddress: String, transactionExtras: TransactionExtrasState, - card: Card, + card: CardDTO, externalTransactionData: ExternalTransactionData?, dispatch: (Action) -> Unit, ) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt index 06e3cbae64..4c5dd07560 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt @@ -1,8 +1,6 @@ package com.tangem.tap.features.wallet.models -import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.DerivationStyle -import com.tangem.blockchain.common.Token import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.toCoinId import com.tangem.domain.common.extensions.toNetworkId @@ -11,6 +9,8 @@ import com.tangem.network.api.tangemTech.TokenResponse import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.tokens.redux.TokenWithBlockchain +import com.tangem.blockchain.common.Blockchain as SdkBlockchain +import com.tangem.blockchain.common.Token as SdkToken sealed interface Currency { val coinId: String? @@ -18,7 +18,7 @@ sealed interface Currency { is Blockchain -> blockchain.toCoinId() is Token -> token.id } - val blockchain: com.tangem.blockchain.common.Blockchain + val blockchain: SdkBlockchain val currencySymbol: CryptoCurrencyName val derivationPath: String? val currencyName: String @@ -33,15 +33,15 @@ sealed interface Currency { } data class Token( - val token: com.tangem.blockchain.common.Token, - override val blockchain: com.tangem.blockchain.common.Blockchain, + val token: SdkToken, + override val blockchain: SdkBlockchain, override val derivationPath: String?, ) : Currency { override val currencySymbol = token.symbol } data class Blockchain( - override val blockchain: com.tangem.blockchain.common.Blockchain, + override val blockchain: SdkBlockchain, override val derivationPath: String?, ) : Currency { override val currencySymbol: CryptoCurrencyName = blockchain.currency @@ -72,7 +72,7 @@ sealed interface Currency { companion object { fun fromBlockchainNetwork( blockchainNetwork: BlockchainNetwork, - token: com.tangem.blockchain.common.Token? = null, + token: SdkToken? = null, ): Currency { return if (token != null) { Token( @@ -115,7 +115,7 @@ sealed interface Currency { ?: return null return when { tokenResponse.contractAddress != null -> Token( - com.tangem.blockchain.common.Token( + token = SdkToken( name = tokenResponse.name, symbol = tokenResponse.symbol, contractAddress = tokenResponse.contractAddress!!, @@ -148,8 +148,8 @@ fun List.toBlockchainNetworks(): List { return this.filter { it.isBlockchain() }.map { BlockchainNetwork(it.blockchain, it.derivationPath, getTokens(it)) } } -private fun List.getTokens(currency: Currency): List { +fun List.getTokens(currency: Currency): List { return this .filter { it.isToken() && it.blockchain == currency.blockchain && it.derivationPath == currency.derivationPath } .mapNotNull { if (it is Currency.Token) it.token else null } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 02e6073066..fc947d90fd 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -7,9 +7,8 @@ import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.AddressType -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.tap.common.entities.FiatCurrency -import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.configurable.warningMessage.WarningMessage @@ -70,7 +69,7 @@ sealed class WalletAction : Action { data class AddToken(val token: Token, val blockchain: BlockchainNetwork, val save: Boolean) : MultiWallet() data class SaveCurrencies( - val blockchainNetworks: List, val card: Card? = null, + val blockchainNetworks: List, val card: CardDTO? = null, ) : MultiWallet() data class TokenLoaded( @@ -123,9 +122,9 @@ sealed class WalletAction : Action { object Failure : WalletAction() } - class LoadCardInfo(val card: Card) : WalletAction() + class LoadCardInfo(val card: CardDTO) : WalletAction() - data class LoadArtwork(val card: Card, val artworkId: String?) : WalletAction() { + data class LoadArtwork(val card: CardDTO, val artworkId: String?) : WalletAction() { data class Success(val artwork: Artwork) : WalletAction() object Failure : WalletAction() } @@ -134,10 +133,6 @@ sealed class WalletAction : Action { data class Send(val amount: Amount? = null) : WalletAction() - object EmptyField : WalletAction(), ErrorAction { - override val error = TapError.PayIdEmptyField - } - data class CopyAddress(val address: String, val context: Context) : WalletAction() { object Success : WalletAction(), NotificationAction { override val messageResource = R.string.wallet_notification_address_copied @@ -186,7 +181,7 @@ sealed class WalletAction : Action { data class SetWalletRent( val wallet: Wallet, val minRent: String, - val rentExempt: String + val rentExempt: String, ) : WalletAction() data class RemoveWalletRent(val wallet: Wallet) : WalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt index 112c3a0afb..109d44ad31 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt @@ -4,8 +4,8 @@ import com.tangem.blockchain.common.BlockchainSdkError import com.tangem.blockchain.common.SignatureCountValidator import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.extensions.SimpleResult -import com.tangem.common.card.Card import com.tangem.common.card.FirmwareVersion +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.tap.common.extensions.dispatchOnMain @@ -13,10 +13,8 @@ import com.tangem.tap.common.extensions.isGreaterThan import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager -import com.tangem.tap.domain.extensions.getSingleWallet import com.tangem.tap.domain.extensions.hasSignedHashes import com.tangem.tap.domain.extensions.isMultiwalletAllowed -import com.tangem.tap.domain.extensions.remainingSignatures import com.tangem.tap.features.demo.isDemoCard import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity @@ -108,8 +106,8 @@ class WarningsMiddleware { } } - private fun showWarningLowRemainingSignaturesIfNeeded(card: Card) { - val remainingSignatures = card.remainingSignatures + private fun showWarningLowRemainingSignaturesIfNeeded(card: CardDTO) { + val remainingSignatures = card.wallets.firstOrNull()?.remainingSignatures if (remainingSignatures != null && remainingSignatures <= WarningMessagesManager.REMAINING_SIGNATURES_WARNING ) { @@ -159,7 +157,7 @@ class WarningsMiddleware { val validator = store.state.walletState.walletManagers.firstOrNull() as? SignatureCountValidator scope.launch { - val signedHashes = card.getSingleWallet()?.totalSignedHashes ?: 0 + val signedHashes = card.wallets.firstOrNull()?.totalSignedHashes ?: 0 val result = validator?.validateSignatureCount(signedHashes) withContext(Dispatchers.Main) { when (result) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt index d4172e31ef..956fe058dc 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt @@ -3,7 +3,7 @@ package com.tangem.tap.features.wallet.ui.wallet import android.widget.Button import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.tap.common.analytics.Analytics @@ -54,8 +54,8 @@ class MultiWalletView : WalletView() { private fun setupWalletCardNumber(binding: FragmentWalletBinding) = with(binding) { val card = store.state.globalState.scanResponse?.card - if (card?.backupStatus is Card.BackupStatus.Active) { - val cardCount = (card.backupStatus as Card.BackupStatus.Active).cardCount + 1 + if (card?.backupStatus is CardDTO.BackupStatus.Active) { + val cardCount = (card.backupStatus as CardDTO.BackupStatus.Active).cardCount + 1 tvTwinCardNumber.show() tvTwinCardNumber.text = tvTwinCardNumber.getQuantityString(R.plurals.card_label_card_count, cardCount) } else { diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt index a7f7b9aec2..939121bda7 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt @@ -1,6 +1,6 @@ package com.tangem.tap.network.exchangeServices -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.tap.features.demo.isDemoCard import com.tangem.tap.features.wallet.models.Currency @@ -9,7 +9,7 @@ import com.tangem.tap.features.wallet.models.Currency [REDACTED_AUTHOR] */ class CardExchangeRules( - val cardProvider: () -> Card?, + val cardProvider: () -> CardDTO?, ) : ExchangeRules { override fun featureIsSwitchedOn(): Boolean { diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt index 04c92fc542..3f61d82801 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt @@ -7,7 +7,7 @@ import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.extensions.Result -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.tap.common.extensions.safeUpdate import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.common.redux.global.GlobalAction @@ -86,8 +86,9 @@ class CurrencyExchangeManager( } } +@Suppress("unused") suspend fun CurrencyExchangeManager.buyErc20TestnetTokens( - card: Card, + card: CardDTO, walletManager: EthereumWalletManager, token: Token, ) { diff --git a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt index c161b935fb..11cfdee61f 100644 --- a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt +++ b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt @@ -1,6 +1,6 @@ package com.tangem.tap.proxy -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TangemSdkManager @@ -20,7 +20,7 @@ class AppStateHolder { var mainStore: Store? = null var tangemSdkManager: TangemSdkManager? = null - fun getActualCard(): Card? { + fun getActualCard(): CardDTO? { return scanResponse?.card } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt index 2832cd6faf..8856cdc80d 100644 --- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt @@ -4,15 +4,15 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.DerivationParams import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.WalletManagerFactory -import com.tangem.common.card.Card +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.domain.common.util.userWalletId import com.tangem.lib.crypto.UserWalletManager import com.tangem.lib.crypto.models.Currency import com.tangem.lib.crypto.models.NativeToken import com.tangem.lib.crypto.models.NonNativeToken -import com.tangem.tap.domain.extensions.getUserWalletId import com.tangem.tap.domain.extensions.makeWalletManagerForApp import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.redux.WalletAction @@ -54,7 +54,7 @@ class UserWalletManagerImpl( } override fun getWalletId(): String { - return appStateHolder.getActualCard()?.getUserWalletId() ?: "" + return appStateHolder.getActualCard()?.userWalletId?.stringValue ?: "" } override suspend fun isTokenAdded(currency: Currency): Boolean { @@ -100,7 +100,7 @@ class UserWalletManagerImpl( } } - private fun addNativeTokenToWalletAction(token: NativeToken, card: Card): Action { + private fun addNativeTokenToWalletAction(token: NativeToken, card: CardDTO): Action { val blockchain = Blockchain.fromNetworkId(token.networkId) val scanResponse = appStateHolder.scanResponse if (blockchain != null && scanResponse != null) { diff --git a/buildSrc/src/main/java/Versions.kt b/buildSrc/src/main/java/Versions.kt index 1a730aa925..f9ac9274ec 100644 --- a/buildSrc/src/main/java/Versions.kt +++ b/buildSrc/src/main/java/Versions.kt @@ -58,11 +58,10 @@ object Versions { // endregion Other libraries // region Tangem - const val tangemBlockchainSdk = "develop-140" - - // const val tangemBlockchainSdk = "0.0.1" - const val tangemCardSgk = "develop-169" - // const val tangemCardSgk = "0.0.1" + const val tangemBlockchainSdk = "0.0.1" + // const val tangemBlockchainSdk = "develop-140" + const val tangemCardSgk = "0.0.1" + // const val tangemCardSgk = "develop-165" // endregion Tangem // region Testing diff --git a/domain/src/main/java/com/tangem/domain/common/ScanResponse.kt b/domain/src/main/java/com/tangem/domain/common/ScanResponse.kt index 56c6979d5e..ad0538d7a5 100644 --- a/domain/src/main/java/com/tangem/domain/common/ScanResponse.kt +++ b/domain/src/main/java/com/tangem/domain/common/ScanResponse.kt @@ -2,7 +2,6 @@ package com.tangem.domain.common import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token -import com.tangem.common.card.Card import com.tangem.common.card.EllipticCurve import com.tangem.common.card.WalletData import com.tangem.common.extensions.ByteArrayKey @@ -12,7 +11,6 @@ import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain import com.tangem.domain.common.TapWorkarounds.isSaltPay import com.tangem.domain.common.TapWorkarounds.isSaltPayVisa import com.tangem.domain.common.TapWorkarounds.isSaltPayWallet -import com.tangem.domain.common.TapWorkarounds.isTangemNote import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.operations.CommandResponse @@ -23,7 +21,7 @@ import com.tangem.operations.derivation.ExtendedPublicKeysMap [REDACTED_AUTHOR] */ data class ScanResponse( - val card: Card, + val card: CardDTO, val productType: ProductType, val walletData: WalletData?, val secondTwinPublicKey: String? = null, @@ -67,20 +65,22 @@ data class ScanResponse( return hasDerivation(blockchain, DerivationPath(rawDerivationPath)) } - fun hasDerivation(blockchain: Blockchain, derivationPath: DerivationPath): Boolean { + private fun hasDerivation(blockchain: Blockchain, derivationPath: DerivationPath): Boolean { val isTestnet = card.isTestCard || blockchain.isTestnet() return when { Blockchain.secp256k1Blockchains(isTestnet).contains(blockchain) -> { hasDerivation(EllipticCurve.Secp256k1, derivationPath) } + Blockchain.ed25519OnlyBlockchains(isTestnet).contains(blockchain) -> { hasDerivation(EllipticCurve.Ed25519, derivationPath) } + else -> false } } - fun hasDerivation(curve: EllipticCurve, derivationPath: DerivationPath): Boolean { + private fun hasDerivation(curve: EllipticCurve, derivationPath: DerivationPath): Boolean { val foundWallet = card.wallets.firstOrNull { it.curve == curve } ?: return false val extendedPublicKeysMap = derivedKeys[foundWallet.publicKey.toMapKey()] ?: return false @@ -93,12 +93,4 @@ enum class ProductType { Note, Twins, Wallet, SaltPay } -val Card.productType: ProductType - get() = when { - isTangemTwins -> ProductType.Twins - isTangemNote -> ProductType.Note - isSaltPay -> ProductType.SaltPay - else -> ProductType.Wallet - } - typealias KeyWalletPublicKey = ByteArrayKey \ No newline at end of file diff --git a/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt b/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt index 69ec26308b..21fa7e169f 100644 --- a/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt +++ b/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt @@ -17,18 +17,32 @@ object TapWorkarounds { return cardIssuer?.lowercase(Locale.US) == START_2_COIN_ISSUER } - val Card.isStart2Coin: Boolean + val CardDTO.isTangemTwins: Boolean + get() = TwinsHelper.getTwinCardNumber(cardId) != null + + //TODO: replace by reading files from a card + val CardDTO.isTangemNote: Boolean + get() = tangemNoteBatches.contains(batchId) + + val CardDTO.isStart2Coin: Boolean get() = isStart2CoinIssuer(issuer.name) - val Card.isTestCard: Boolean + val CardDTO.isSaltPay: Boolean + get() = isSaltPayVisa || isSaltPayWallet + + val CardDTO.isSaltPayVisa: Boolean + get() = SaltPayWorkaround.isVisaBatchId(batchId) + + val CardDTO.isSaltPayWallet: Boolean + get() = SaltPayWorkaround.isWalletCardId(cardId) + + val CardDTO.isTestCard: Boolean get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH) - val Card.useOldStyleDerivation: Boolean + val CardDTO.useOldStyleDerivation: Boolean get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95" - - val Card.derivationStyle: DerivationStyle? + val CardDTO.derivationStyle: DerivationStyle? get() = if (!settings.isHDWalletAllowed) { - Int.MAX_VALUE null } else if (useOldStyleDerivation) { DerivationStyle.LEGACY @@ -36,15 +50,18 @@ object TapWorkarounds { DerivationStyle.NEW } - val Card.isNotSupportedInThatRelease: Boolean + val CardDTO.isExcluded: Boolean + get() { + val excludedBatch = excludedBatches.contains(batchId) + val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT)) + return excludedBatch || excludedIssuerName + } + + val CardDTO.isNotSupportedInThatRelease: Boolean get() = false - val Card.isTangemTwins: Boolean - get() = TwinsHelper.getTwinCardNumber(cardId) != null - - //TODO: replace by reading files from a card - val Card.isTangemNote: Boolean - get() = tangemNoteBatches.contains(batchId) + fun CardDTO.getTangemNoteBlockchain(): Blockchain? = + tangemNoteBatches[batchId] ?: if (isSaltPay) Blockchain.Gnosis else null private val tangemNoteBatches = mapOf( "AB01" to Blockchain.Bitcoin, @@ -63,24 +80,6 @@ object TapWorkarounds { fun Card.getTangemNoteBlockchain(): Blockchain? = tangemNoteBatches[batchId] ?: null - - val Card.isSaltPay: Boolean - get() = isSaltPayVisa || isSaltPayWallet - - val Card.isSaltPayVisa: Boolean - get() = SaltPayWorkaround.isVisaBatchId(batchId) - - val Card.isSaltPayWallet: Boolean - get() = SaltPayWorkaround.isWalletCardId(cardId) - - - val Card.isExcluded: Boolean - get() { - val excludedBatch = excludedBatches.contains(batchId) - val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT)) - return excludedBatch || excludedIssuerName - } - private val excludedBatches = listOf( "0027", "0030", diff --git a/domain/src/main/java/com/tangem/domain/common/TwinsHelper.kt b/domain/src/main/java/com/tangem/domain/common/TwinsHelper.kt index 23485d8340..a1ded44422 100644 --- a/domain/src/main/java/com/tangem/domain/common/TwinsHelper.kt +++ b/domain/src/main/java/com/tangem/domain/common/TwinsHelper.kt @@ -1,6 +1,5 @@ package com.tangem.domain.common -import com.tangem.common.card.Card import com.tangem.crypto.CryptoUtils class TwinsHelper { @@ -57,14 +56,14 @@ enum class TwinCardNumber(val number: Int) { } @Deprecated("Use ScanResponse.isTangemTwin") -fun Card.isTangemTwin(): Boolean { +fun CardDTO.isTangemTwin(): Boolean { return TwinsHelper.getTwinCardNumber(cardId) != null } -fun Card.getTwinCardNumber(): TwinCardNumber? { +fun CardDTO.getTwinCardNumber(): TwinCardNumber? { return TwinsHelper.getTwinCardNumber(this.cardId) } -fun Card.getTwinCardIdForUser(): String { +fun CardDTO.getTwinCardIdForUser(): String { return TwinsHelper.getTwinCardIdForUser(this.cardId) } \ No newline at end of file diff --git a/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt b/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt index acc0fc7bf0..bd7a3d7643 100644 --- a/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt +++ b/domain/src/main/java/com/tangem/domain/common/extensions/CardSdk.kt @@ -1,9 +1,9 @@ package com.tangem.domain.common.extensions import com.tangem.blockchain.common.Blockchain -import com.tangem.common.card.Card import com.tangem.common.card.EllipticCurve import com.tangem.common.card.FirmwareVersion +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.isTestCard /** @@ -12,11 +12,12 @@ import com.tangem.domain.common.TapWorkarounds.isTestCard val FirmwareVersion.Companion.SolanaTokensAvailable get() = FirmwareVersion(4, 52) -fun Card.supportedBlockchains(): List { +fun CardDTO.supportedBlockchains(): List { val supportedBlockchains = when { firmwareVersion < FirmwareVersion.MultiWalletAvailable -> { Blockchain.fromCurve(EllipticCurve.Secp256k1) } + else -> { (Blockchain.fromCurve(EllipticCurve.Secp256k1) + Blockchain.fromCurve(EllipticCurve.Ed25519)).distinct() } @@ -26,7 +27,7 @@ fun Card.supportedBlockchains(): List { .filter { it.isSupportedInApp() } } -fun Card.supportedTokens(): List { +fun CardDTO.supportedTokens(): List { val tokensSupportedByBlockchain = supportedBlockchains().filter { it.canHandleTokens() }.toMutableList() val tokensSupportedByCard = when { firmwareVersion >= FirmwareVersion.SolanaTokensAvailable -> tokensSupportedByBlockchain @@ -41,10 +42,10 @@ fun Card.supportedTokens(): List { return filtered } -fun Card.canHandleBlockchain(blockchain: Blockchain): Boolean { +fun CardDTO.canHandleBlockchain(blockchain: Blockchain): Boolean { return this.supportedBlockchains().contains(blockchain) } -fun Card.canHandleToken(blockchain: Blockchain): Boolean { +fun CardDTO.canHandleToken(blockchain: Blockchain): Boolean { return this.supportedTokens().contains(blockchain) } \ No newline at end of file diff --git a/domain/src/main/java/com/tangem/domain/common/util/UserWalletId.kt b/domain/src/main/java/com/tangem/domain/common/util/UserWalletId.kt index 4c8bedcd22..1d51a46d2c 100644 --- a/domain/src/main/java/com/tangem/domain/common/util/UserWalletId.kt +++ b/domain/src/main/java/com/tangem/domain/common/util/UserWalletId.kt @@ -10,8 +10,8 @@ class UserWalletId( ) { val value = stringValue.hexToBytes() - constructor(walletPublicKey: ByteArray) : this( - stringValue = calculateUserWalletId(walletPublicKey).toHexString(), + constructor(walletPublicKey: ByteArray?) : this( + stringValue = walletPublicKey?.let { calculateUserWalletId(it).toHexString() } ?: "", ) override fun equals(other: Any?): Boolean { diff --git a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt index 28b821f2ab..6dde5b01c6 100644 --- a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt +++ b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt @@ -2,10 +2,10 @@ package com.tangem.domain.features.addCustomToken.redux import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.DerivationStyle -import com.tangem.common.card.Card import com.tangem.common.json.MoshiJsonConverter import com.tangem.domain.AddCustomTokenError import com.tangem.domain.DomainWrapped +import com.tangem.domain.common.CardDTO import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.domain.common.extensions.isSupportedInApp import com.tangem.domain.common.extensions.supportedBlockchains @@ -133,7 +133,7 @@ data class AddCustomTokenState( null } - fun reset(card: Card): AddCustomTokenState { + fun reset(card: CardDTO): AddCustomTokenState { return this.copy( appSavedCurrencies = null, onTokenAddCallback = null, @@ -159,7 +159,7 @@ data class AddCustomTokenState( .getConvertedData() } - fun getNetworks(card: Card, type: CustomTokenType): List { + fun getNetworks(card: CardDTO, type: CustomTokenType): List { return getNetworksList(card, type) } @@ -189,7 +189,7 @@ data class AddCustomTokenState( }.derivationPath(derivationStyleToUse) } - internal fun createFormFields(card: Card, type: CustomTokenType): List> { + internal fun createFormFields(card: CardDTO, type: CustomTokenType): List> { return listOf( TokenField(ContractAddress), TokenBlockchainField(Network, getNetworksList(card, type)), @@ -204,7 +204,7 @@ data class AddCustomTokenState( * Serves to determine the networks (blockchains & tokens) that can be selected by Form.Networks. * Blockchain.Unknown - is the default selection */ - private fun getNetworksList(card: Card, type: CustomTokenType): List { + private fun getNetworksList(card: CardDTO, type: CustomTokenType): List { val evmBlockchains = Blockchain.values() .filter { it.isEvm() } .filter { card.isTestCard == it.isTestnet() } @@ -239,7 +239,7 @@ data class AddCustomTokenState( ) } - private fun getSupportedDerivations(card: Card): List { + private fun getSupportedDerivations(card: CardDTO): List { val evmBlockchains = Blockchain.values() .filter { card.isTestCard == it.isTestnet() && it.isEvm() } .filter { it.isSupportedInApp() }