From 1e6ee16b223f4f2381b698e874a7cd5b95b095b2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 29 Jul 2021 16:18:02 +0300 Subject: [PATCH 1/5] Updated on 2026-08-14 --- .../com/tangem/tap/domain/TapWorkarounds.kt | 21 +++++++++++++++++++ .../tangem/tap/domain/tasks/ScanNoteTask.kt | 14 +++++++++++++ .../main/res/values/strings_untranslated.xml | 2 ++ 3 files changed, 37 insertions(+) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index 5807bd024e..79186f4c94 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -3,6 +3,7 @@ package com.tangem.tap.domain import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.EllipticCurve import com.tangem.commands.common.card.masks.Product +import com.tangem.tap.domain.TapWorkarounds.isNote import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.extensions.getSingleWallet import java.util.* @@ -27,6 +28,14 @@ object TapWorkarounds { } + fun Card.isNote(): Boolean { + return notesBatches.contains(cardData?.batchId) + } + + fun Card.isMultiCurrencyWallet(): Boolean { + return multiCurrencyWalletsBatches.contains(cardData?.batchId) + } + private const val START_2_COIN_ISSUER = "start2coin" private val excludedBatches = listOf( @@ -39,12 +48,24 @@ object TapWorkarounds { private val excludedIssuers = listOf( "TTM BANK" ) + + private val notesBatches = listOf( + "AB01", + "AB02", + "AB03", + "AB04", + "AB05", + "AB06", + ) + + private val multiCurrencyWalletsBatches = listOf("AC01") } val Card.isMultiwalletAllowed: Boolean get() { return cardData?.productMask?.contains(Product.TwinCard) != true && !isStart2Coin + && !isNote() && (firmwareVersion.major >= 4 || getSingleWallet()?.curve == EllipticCurve.Secp256k1) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt index 0415316f32..a138f8838f 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt @@ -15,6 +15,7 @@ import com.tangem.common.CompletionResult import com.tangem.common.extensions.toHexString import com.tangem.tap.domain.TapSdkError import com.tangem.tap.domain.TapWorkarounds.isExcluded +import com.tangem.tap.domain.TapWorkarounds.isMultiCurrencyWallet import com.tangem.tap.domain.extensions.getSingleWallet import com.tangem.tap.domain.extensions.getStatus import com.tangem.tap.domain.twins.TwinCardsManager @@ -23,6 +24,7 @@ import com.tangem.tap.store import com.tangem.tasks.PreflightReadCapable import com.tangem.tasks.PreflightReadSettings import com.tangem.tasks.ScanTask +import com.tangem.wallet.R data class ScanNoteResponse( val card: Card, @@ -147,6 +149,8 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnableThis card can’t be used to establish WalletConnect session The operation couldn\'t be completed The operation couldn\'t be completed. \n\nYou have already established a WalletConnect session with this parameters. + + Oops, the current version of the application is not ready to work with this card, please check for updates. From cf0a180b3a70a3042aab9b7a4ce174db6662d90f Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 29 Jul 2021 20:01:13 +0300 Subject: [PATCH 2/5] Updated on 2026-08-14 --- .../java/com/tangem/tap/domain/TapWorkarounds.kt | 14 ++++++++++++++ .../java/com/tangem/tap/domain/extensions/Card.kt | 2 ++ .../com/tangem/tap/domain/tasks/ScanNoteTask.kt | 4 +--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index 79186f4c94..3766c21c06 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -1,5 +1,6 @@ package com.tangem.tap.domain +import com.tangem.blockchain.common.Blockchain import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.EllipticCurve import com.tangem.commands.common.card.masks.Product @@ -36,6 +37,19 @@ object TapWorkarounds { return multiCurrencyWalletsBatches.contains(cardData?.batchId) } + val Card.noteCurrency: Blockchain? + get() { + return when (cardData?.batchId) { + "AB01" -> Blockchain.Bitcoin + "AB02" -> Blockchain.Ethereum + "AB03" -> Blockchain.Cardano + "AB04" -> Blockchain.Dogecoin + "AB05" -> Blockchain.Binance + "AB06" -> Blockchain.XRP + else -> null + } + } + private const val START_2_COIN_ISSUER = "start2coin" private val excludedBatches = listOf( 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 9e805a29de..dfe0e1e2a7 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 @@ -8,6 +8,7 @@ import com.tangem.commands.common.card.CardStatus import com.tangem.commands.wallet.CardWallet import com.tangem.commands.wallet.WalletStatus import com.tangem.common.TangemSdkConstants +import com.tangem.tap.domain.TapWorkarounds.noteCurrency fun Card.getToken(): Token? { val symbol = cardData?.tokenSymbol ?: return null @@ -18,6 +19,7 @@ fun Card.getToken(): Token? { } fun Card.getBlockchain(): Blockchain? { + if (noteCurrency != null) return noteCurrency val blockchainName: String = cardData?.blockchainName ?: return null return Blockchain.fromId(blockchainName) } diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt index a138f8838f..db67d87dff 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt @@ -165,9 +165,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable Date: Fri, 30 Jul 2021 15:27:08 +0300 Subject: [PATCH 3/5] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index 3766c21c06..b64b862627 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -42,7 +42,7 @@ object TapWorkarounds { return when (cardData?.batchId) { "AB01" -> Blockchain.Bitcoin "AB02" -> Blockchain.Ethereum - "AB03" -> Blockchain.Cardano + "AB03" -> Blockchain.CardanoShelley "AB04" -> Blockchain.Dogecoin "AB05" -> Blockchain.Binance "AB06" -> Blockchain.XRP From 05113dc124daa9de09c0e3f77443e771f78a20d9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 3 Aug 2021 09:56:11 +0300 Subject: [PATCH 4/5] Updated on 2026-08-14 --- app/build.gradle | 2 + app/src/main/assets/features_dev.json | 2 +- .../main/java/com/tangem/tap/MainActivity.kt | 11 +- .../tap/common/analytics/AnalyticsHandler.kt | 7 +- .../analytics/FirebaseAnalyticsHandler.kt | 20 ++- .../tap/common/analytics/TangemSdkError.kt | 26 ++-- .../tap/common/redux/global/GlobalAction.kt | 3 + .../common/redux/global/GlobalMidlleware.kt | 4 +- .../tap/common/redux/global/GlobalReducer.kt | 27 +--- .../tap/common/redux/global/GlobalState.kt | 3 +- .../com/tangem/tap/domain/PayIdManager.kt | 2 +- .../com/tangem/tap/domain/TangemSdkManager.kt | 119 ++++++++-------- .../com/tangem/tap/domain/TangemSigner.kt | 40 ++++-- .../java/com/tangem/tap/domain/TapErrors.kt | 2 +- .../com/tangem/tap/domain/TapWalletManager.kt | 34 ++--- .../com/tangem/tap/domain/TapWorkarounds.kt | 67 ++++++--- .../configurable/config/ConfigManager.kt | 2 +- .../warningMessage/WarningMessagesManager.kt | 2 +- .../com/tangem/tap/domain/extensions/Card.kt | 40 +----- .../domain/extensions/TangemSdkConstants.kt | 8 -- .../domain/extensions/WalletManagerFactory.kt | 10 +- .../domain/tasks/CreateWalletAndRescanTask.kt | 33 +++-- .../tap/domain/tasks/CreateWalletsTask.kt | 44 +++--- .../tangem/tap/domain/tasks/ScanNoteTask.kt | 133 ++++++++++-------- .../tangem/tap/domain/tasks/SignHashTask.kt | 36 +++++ .../tangem/tap/domain/tasks/SignHashesTask.kt | 35 +++++ .../tangem/tap/domain/termsOfUse/CardTou.kt | 6 +- .../tap/domain/tokens/CurrenciesRepository.kt | 4 +- .../tangem/tap/domain/topup/TopUpManager.kt | 6 +- .../domain/twins/CreateFirstTwinWalletTask.kt | 28 ++-- .../twins/CreateSecondTwinWalletTask.kt | 26 ++-- .../tap/domain/twins/FinalizeTwinTask.kt | 13 +- .../tap/domain/twins/TwinCardsManager.kt | 8 +- .../tangem/tap/domain/twins/TwinsHelper.kt | 18 +-- .../twins/WriteProtectedIssuerDataTask.kt | 74 ++++++---- .../walletconnect/WalletConnectSdkHelper.kt | 18 +-- .../features/details/redux/DetailsAction.kt | 5 +- .../details/redux/DetailsMiddleware.kt | 25 +++- .../features/details/redux/DetailsReducer.kt | 58 ++++---- .../features/details/redux/DetailsState.kt | 2 +- .../walletconnect/WalletConnectMiddleware.kt | 2 +- .../features/details/ui/DetailsFragment.kt | 2 +- .../tap/features/feedback/FeedbackManager.kt | 10 +- .../middlewares/AddressPayIdMiddleware.kt | 2 +- .../send/redux/middlewares/SendMiddleware.kt | 12 +- .../tap/features/wallet/redux/WalletAction.kt | 4 +- .../redux/middlewares/WalletMiddleware.kt | 31 +++- .../redux/middlewares/WarningsMiddleware.kt | 16 +-- .../wallet/redux/reducers/WalletReducer.kt | 36 +++-- .../coinmarketcap/CoinMarketCapService.kt | 4 +- .../tap/network/moonpay/MoonpayService.kt | 4 +- .../tangem/tap/network/payid/PayIdService.kt | 4 +- .../tap/network/payid/PayIdVerifyService.kt | 4 +- .../main/res/values/strings_untranslated.xml | 2 + dependencies.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 56 files changed, 624 insertions(+), 516 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/domain/extensions/TangemSdkConstants.kt create mode 100644 app/src/main/java/com/tangem/tap/domain/tasks/SignHashTask.kt create mode 100644 app/src/main/java/com/tangem/tap/domain/tasks/SignHashesTask.kt diff --git a/app/build.gradle b/app/build.gradle index 5bad46aa84..14a1f59a8a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -83,6 +83,8 @@ dependencies { // WebView implementation "androidx.browser:browser:1.3.0" + implementation 'com.jakewharton.timber:timber:4.7.1' + //lifecycle implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1" implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1" diff --git a/app/src/main/assets/features_dev.json b/app/src/main/assets/features_dev.json index 71561c4c69..82e46b21bf 100644 --- a/app/src/main/assets/features_dev.json +++ b/app/src/main/assets/features_dev.json @@ -2,5 +2,5 @@ "isWalletPayIdEnabled": true, "isSendingToPayIdEnabled": true, "isTopUpEnabled": true, - "isCreatingTwinCardsAllowed": false + "isCreatingTwinCardsAllowed": true } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 544e1d7cda..89ede4d80d 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -7,10 +7,7 @@ import android.util.Log import android.view.View import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar -import com.tangem.CardFilter -import com.tangem.Config import com.tangem.TangemSdk -import com.tangem.commands.common.card.CardType import com.tangem.tangem_sdk_new.extensions.init import com.tangem.tap.common.DialogManager import com.tangem.tap.common.IntentHandler @@ -30,7 +27,6 @@ import kotlinx.coroutines.Job import java.io.PrintWriter import java.io.StringWriter import java.lang.ref.WeakReference -import java.util.* import kotlin.coroutines.CoroutineContext lateinit var tangemSdk: TangemSdk @@ -68,10 +64,9 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; store.dispatch(NavigationAction.ActivityCreated(WeakReference(this))) - tangemSdk = TangemSdk.init( - this, Config(cardFilter = CardFilter(EnumSet.allOf(CardType::class.java))) - ) - tangemSdkManager = TangemSdkManager(this) + tangemSdk = TangemSdk.init(this, TangemSdkManager.config) + tangemSdkManager = TangemSdkManager(tangemSdk, this) + store.dispatch(WalletConnectAction.RestoreSessions) } diff --git a/app/src/main/java/com/tangem/tap/common/analytics/AnalyticsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/AnalyticsHandler.kt index 30bb8d545d..1022f85c5a 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/AnalyticsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/AnalyticsHandler.kt @@ -1,12 +1,11 @@ package com.tangem.tap.common.analytics -import com.tangem.TangemSdkError -import com.tangem.blockchain.common.Blockchain -import com.tangem.commands.common.card.Card +import com.tangem.common.card.Card +import com.tangem.common.core.TangemSdkError interface AnalyticsHandler { - fun triggerEvent(event: AnalyticsEvent, card: Card? = null, blockchain: Blockchain? = null) + fun triggerEvent(event: AnalyticsEvent, card: Card? = null, blockchain: String? = null) fun logCardSdkError( error: TangemSdkError, actionToLog: FirebaseAnalyticsHandler.ActionToLog, diff --git a/app/src/main/java/com/tangem/tap/common/analytics/FirebaseAnalyticsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/FirebaseAnalyticsHandler.kt index f9aea4c495..33383e1089 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/FirebaseAnalyticsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/FirebaseAnalyticsHandler.kt @@ -5,13 +5,12 @@ import androidx.core.os.bundleOf import com.google.firebase.analytics.ktx.analytics import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.ktx.Firebase -import com.tangem.TangemSdkError -import com.tangem.blockchain.common.Blockchain -import com.tangem.commands.common.card.Card +import com.tangem.common.card.Card +import com.tangem.common.core.TangemSdkError import com.tangem.tap.common.extensions.filterNotNull object FirebaseAnalyticsHandler : AnalyticsHandler { - override fun triggerEvent(event: AnalyticsEvent, card: Card?, blockchain: Blockchain?) { + override fun triggerEvent(event: AnalyticsEvent, card: Card?, blockchain: String?) { Firebase.analytics.logEvent(event.event, setData(card, blockchain)) } @@ -47,18 +46,17 @@ object FirebaseAnalyticsHandler : AnalyticsHandler { private fun getParamsFromCard(card: Card): Map { return mapOf( - AnalyticsParam.FIRMWARE to card.firmwareVersion.version, - AnalyticsParam.BATCH_ID to card.cardData?.batchId + AnalyticsParam.FIRMWARE to card.firmwareVersion.stringValue, + AnalyticsParam.BATCH_ID to card.batchId ).filterNotNull() } - private fun setData(card: Card?, blockchain: Blockchain?): Bundle { + private fun setData(card: Card?, blockchain: String?): Bundle { if (card == null) return bundleOf() return bundleOf( - AnalyticsParam.BLOCKCHAIN.param to (blockchain?.currency - ?: card.cardData?.blockchainName), - AnalyticsParam.BATCH_ID.param to card.cardData?.batchId, - AnalyticsParam.FIRMWARE.param to card.firmwareVersion.version + AnalyticsParam.BLOCKCHAIN.param to (blockchain), + AnalyticsParam.BATCH_ID.param to card.batchId, + AnalyticsParam.FIRMWARE.param to card.firmwareVersion.stringValue ) } 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 1c574708e1..0d6b58db28 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 @@ -1,6 +1,6 @@ package com.tangem.tap.common.analytics -import com.tangem.TangemSdkError +import com.tangem.common.core.TangemSdkError object TangemSdk { @@ -31,17 +31,15 @@ object TangemSdk { is TangemSdkError.WalletNotFound -> TangemSdkError.WalletNotFound() is TangemSdkError.AlreadyPersonalized -> TangemSdkError.AlreadyPersonalized() is TangemSdkError.CannotBeDepersonalized -> TangemSdkError.CannotBeDepersonalized() - is TangemSdkError.Pin1Required -> TangemSdkError.Pin1Required() + is TangemSdkError.AccessCodeRequired -> TangemSdkError.AccessCodeRequired() is TangemSdkError.CardReadWrongWallet -> TangemSdkError.CardReadWrongWallet() is TangemSdkError.CardWithMaxZeroWallets -> TangemSdkError.CardWithMaxZeroWallets() is TangemSdkError.AlreadyCreated -> TangemSdkError.AlreadyCreated() - is TangemSdkError.WalletIndexExceedsMaxValue -> TangemSdkError.WalletIndexExceedsMaxValue() is TangemSdkError.MaxNumberOfWalletsCreated -> TangemSdkError.MaxNumberOfWalletsCreated() - is TangemSdkError.WalletIndexNotCorrect -> TangemSdkError.WalletIndexNotCorrect() is TangemSdkError.PurgeWalletProhibited -> TangemSdkError.PurgeWalletProhibited() - is TangemSdkError.Pin1CannotBeChanged -> TangemSdkError.Pin1CannotBeChanged() - is TangemSdkError.Pin2CannotBeChanged -> TangemSdkError.Pin2CannotBeChanged() - is TangemSdkError.Pin1CannotBeDefault -> TangemSdkError.Pin1CannotBeDefault() + is TangemSdkError.AccessCodeCannotBeChanged -> TangemSdkError.AccessCodeCannotBeChanged() + is TangemSdkError.PasscodeCannotBeChanged -> TangemSdkError.PasscodeCannotBeChanged() + is TangemSdkError.AccessCodeCannotBeDefault -> TangemSdkError.AccessCodeCannotBeDefault() is TangemSdkError.NoRemainingSignatures -> TangemSdkError.NoRemainingSignatures() is TangemSdkError.EmptyHashes -> TangemSdkError.EmptyHashes() is TangemSdkError.HashSizeMustBeEqual -> TangemSdkError.HashSizeMustBeEqual() @@ -52,7 +50,7 @@ object TangemSdk { is TangemSdkError.NotPersonalized -> TangemSdkError.NotPersonalized() is TangemSdkError.NotActivated -> TangemSdkError.NotActivated() is TangemSdkError.WalletIsPurged -> TangemSdkError.WalletIsPurged() - is TangemSdkError.Pin2OrCvcRequired -> TangemSdkError.Pin2OrCvcRequired() + is TangemSdkError.PasscodeRequired -> TangemSdkError.PasscodeRequired() is TangemSdkError.VerificationFailed -> TangemSdkError.VerificationFailed() is TangemSdkError.DataSizeTooLarge -> TangemSdkError.DataSizeTooLarge() is TangemSdkError.MissingCounter -> TangemSdkError.MissingCounter() @@ -60,8 +58,8 @@ object TangemSdk { is TangemSdkError.DataCannotBeWritten -> TangemSdkError.DataCannotBeWritten() is TangemSdkError.MissingIssuerPubicKey -> TangemSdkError.MissingIssuerPubicKey() is TangemSdkError.CardVerificationFailed -> TangemSdkError.CardVerificationFailed() - is TangemSdkError.WrongPin1 -> TangemSdkError.WrongPin1() - is TangemSdkError.WrongPin2 -> TangemSdkError.WrongPin2() + is TangemSdkError.WrongAccessCode -> TangemSdkError.WrongAccessCode() + is TangemSdkError.WrongPasscode -> TangemSdkError.WrongPasscode() is TangemSdkError.UnknownError -> TangemSdkError.UnknownError() is TangemSdkError.UserCancelled -> TangemSdkError.UserCancelled() is TangemSdkError.Busy -> TangemSdkError.Busy() @@ -69,8 +67,14 @@ object TangemSdk { is TangemSdkError.WrongCardNumber -> TangemSdkError.WrongCardNumber() is TangemSdkError.WrongCardType -> TangemSdkError.WrongCardType() is TangemSdkError.CardError -> TangemSdkError.CardError() - is TangemSdkError.FirmwareNotSupported -> TangemSdkError.FirmwareNotSupported() + is TangemSdkError.NotSupportedFirmwareVersion -> TangemSdkError.NotSupportedFirmwareVersion() is TangemSdkError.WalletError -> TangemSdkError.WalletError() + is TangemSdkError.WalletCannotBeCreated -> TangemSdkError.WalletCannotBeCreated() + is TangemSdkError.UnsupportedCurve -> TangemSdkError.UnsupportedCurve() + is TangemSdkError.UnsupportedWalletConfig -> TangemSdkError.UnsupportedWalletConfig() + is TangemSdkError.CryptoUtilsError -> TangemSdkError.CryptoUtilsError() + is TangemSdkError.NetworkError -> TangemSdkError.NetworkError(error.customMessage) + is TangemSdkError.ExceptionError -> TangemSdkError.ExceptionError(error.throwable) } } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index bb32bfa7b4..c1c9137aec 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -21,6 +21,9 @@ sealed class GlobalAction : Action { } data class SaveScanNoteResponse(val scanNoteResponse: ScanNoteResponse) : GlobalAction() + + data class SetIfCardVerifiedOnline(val verified: Boolean) : GlobalAction() + data class ChangeAppCurrency(val appCurrency: FiatCurrencyName) : GlobalAction() object RestoreAppCurrency : GlobalAction() { data class Success(val appCurrency: FiatCurrencyName) : GlobalAction() diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt index e499b320c2..d90e263263 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt @@ -1,8 +1,8 @@ package com.tangem.tap.common.redux.global -import com.tangem.TangemSdkError -import com.tangem.commands.common.network.Result import com.tangem.common.CompletionResult +import com.tangem.common.core.TangemSdkError +import com.tangem.common.services.Result import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager 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 7dbbe6f40e..e1f1fa2217 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 @@ -1,8 +1,6 @@ package com.tangem.tap.common.redux.global -import com.tangem.commands.wallet.WalletIndex import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.details.redux.SecurityOption import org.rekotlin.Action fun globalReducer(action: Action, state: AppState): GlobalState { @@ -30,29 +28,11 @@ fun globalReducer(action: Action, state: AppState): GlobalState { globalState.copy(configManager = action.configManager) } is GlobalAction.SetWarningManager -> globalState.copy(warningManager = action.warningManager) - is GlobalAction.UpdateSecurityOptions -> { - val card = when (action.securityOption) { - SecurityOption.LongTap -> globalState.scanNoteResponse?.card?.copy( - isPin1Default = true, isPin2Default = true - ) - SecurityOption.PassCode -> globalState.scanNoteResponse?.card?.copy( - isPin1Default = true, isPin2Default = false - ) - SecurityOption.AccessCode -> globalState.scanNoteResponse?.card?.copy( - isPin1Default = false, isPin2Default = true - ) - } - if (card != null) { - globalState.copy(scanNoteResponse = globalState.scanNoteResponse?.copy(card = card)) - } else { - globalState - } - } is GlobalAction.UpdateWalletSignedHashes -> { val wallet = globalState.scanNoteResponse?.card - ?.wallet(WalletIndex.PublicKey(action.walletPublicKey)) + ?.wallet(action.walletPublicKey) ?.copy( - signedHashes = action.walletSignedHashes, + totalSignedHashes = action.walletSignedHashes, remainingSignatures = action.remainingSignatures ) val card = globalState.scanNoteResponse?.card @@ -76,6 +56,9 @@ fun globalReducer(action: Action, state: AppState): GlobalState { is GlobalAction.GetMoonPayUserStatus.Success -> { globalState.copy(moonPayUserStatus = action.moonPayUserStatus) } + is GlobalAction.SetIfCardVerifiedOnline -> + globalState.copy(cardVerifiedOnline = action.verified) + else -> globalState } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 77b02d5e8c..f370fca90c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -1,6 +1,5 @@ package com.tangem.tap.common.redux.global -import com.tangem.commands.common.network.TangemService import com.tangem.tap.common.entities.TapCurrency.Companion.DEFAULT_FIAT_CURRENCY import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapWalletManager @@ -14,10 +13,10 @@ import org.rekotlin.StateType data class GlobalState( val scanNoteResponse: ScanNoteResponse? = null, + val cardVerifiedOnline: Boolean = false, val tapWalletManager: TapWalletManager = TapWalletManager(), val payIdManager: PayIdManager = PayIdManager(), val coinMarketCapService: CoinMarketCapService = CoinMarketCapService(), - val tangemService: TangemService = TangemService(), val configManager: ConfigManager? = null, val warningManager: WarningMessagesManager? = null, val feedbackManager: FeedbackManager? = null, diff --git a/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt b/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt index a6e329ca04..cfd5c2b5c2 100644 --- a/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt @@ -1,7 +1,7 @@ package com.tangem.tap.domain import com.tangem.blockchain.common.Blockchain -import com.tangem.commands.common.network.Result +import com.tangem.common.services.Result import com.tangem.tap.network.payid.PayIdVerifyService import com.tangem.tap.network.payid.VerifyPayIdResponse import kotlinx.coroutines.Dispatchers 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 2a7810f725..56fe47fb45 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -1,23 +1,24 @@ package com.tangem.tap.domain -import androidx.activity.ComponentActivity -import com.tangem.* -import com.tangem.commands.CommandResponse -import com.tangem.commands.PinType -import com.tangem.commands.SetPinCommand -import com.tangem.commands.SetPinResponse -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.CardType -import com.tangem.commands.wallet.PurgeWalletCommand -import com.tangem.commands.wallet.PurgeWalletResponse +import android.content.Context +import com.tangem.Message +import com.tangem.TangemSdk +import com.tangem.common.CardFilter import com.tangem.common.CompletionResult -import com.tangem.common.TangemSdkConstants -import com.tangem.common.extensions.calculateSha256 -import com.tangem.tangem_sdk_new.extensions.init +import com.tangem.common.SuccessResponse +import com.tangem.common.card.Card +import com.tangem.common.card.FirmwareVersion +import com.tangem.common.core.CardSessionRunnable +import com.tangem.common.core.Config +import com.tangem.common.core.TangemSdkError +import com.tangem.operations.CommandResponse +import com.tangem.operations.pins.CheckUserCodesCommand +import com.tangem.operations.pins.CheckUserCodesResponse +import com.tangem.operations.pins.SetUserCodeCommand +import com.tangem.operations.wallet.PurgeWalletCommand import com.tangem.tap.common.analytics.AnalyticsEvent import com.tangem.tap.common.analytics.AnalyticsHandler import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler -import com.tangem.tap.domain.extensions.getDefaultWalletIndex import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.domain.tasks.ScanNoteTask @@ -25,23 +26,19 @@ import com.tangem.tap.domain.twins.isTwinCard import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import java.util.* import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine -class TangemSdkManager(val activity: ComponentActivity) { - private val tangemSdk = TangemSdk.init( - activity, Config(cardFilter = CardFilter(EnumSet.allOf(CardType::class.java))) - ) +class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Context) { suspend fun scanNote( - analyticsHandler: AnalyticsHandler, messageRes: Int? = null + analyticsHandler: AnalyticsHandler, messageRes: Int? = null, ): CompletionResult { analyticsHandler.triggerEvent(AnalyticsEvent.READY_TO_SCAN, null) - val result = runTaskAsyncReturnOnMain(ScanNoteTask(), - initialMessage = Message( - activity.getString(messageRes ?: R.string.initial_message_scan_header) - )) + val result = runTaskAsyncReturnOnMain(ScanNoteTask(), + initialMessage = Message( + context.getString(messageRes ?: R.string.initial_message_scan_header) + )) if (result is CompletionResult.Failure) { (result.error as? TangemSdkError)?.let { error -> analyticsHandler.logCardSdkError(error, FirebaseAnalyticsHandler.ActionToLog.Scan) @@ -52,53 +49,57 @@ class TangemSdkManager(val activity: ComponentActivity) { suspend fun createWallet(cardId: String?): CompletionResult { return runTaskAsyncReturnOnMain(CreateWalletAndRescanTask(), cardId, - initialMessage = Message(activity.getString(R.string.initial_message_create_wallet_body))) + initialMessage = Message(context.getString(R.string.initial_message_create_wallet_body))) } - suspend fun eraseWallet(cardId: String?): CompletionResult { - return runTaskAsyncReturnOnMain(PurgeWalletCommand( - TangemSdkConstants.getDefaultWalletIndex()), - cardId, - initialMessage = Message(activity.getString(R.string.initial_message_purge_wallet_body))) + suspend fun eraseWallet(card: Card): CompletionResult { + return runTaskAsyncReturnOnMain( + PurgeWalletCommand(card.wallets.first().publicKey), + card.cardId, + initialMessage = Message(context.getString(R.string.initial_message_purge_wallet_body))) } - suspend fun setPasscode(cardId: String?): CompletionResult { - return runTaskAsyncReturnOnMain(SetPinCommand( - pinType = PinType.Pin2, - newPin1 = tangemSdk.config.defaultPin1.calculateSha256(), - newPin2 = null - ), cardId, initialMessage = Message(activity.getString(R.string.initial_message_change_passcode_body))) + suspend fun setPasscode(cardId: String?): CompletionResult { + return runTaskAsyncReturnOnMain( + SetUserCodeCommand.changePasscode(null), + cardId, + initialMessage = Message(context.getString(R.string.initial_message_change_passcode_body))) } - suspend fun setAccessCode(cardId: String?): CompletionResult { - return runTaskAsyncReturnOnMain(SetPinCommand( - pinType = PinType.Pin1, - newPin1 = null, - newPin2 = tangemSdk.config.defaultPin2.calculateSha256() - ), cardId, initialMessage = Message(activity.getString(R.string.initial_message_change_access_code_body))) + suspend fun setAccessCode(cardId: String?): CompletionResult { + return runTaskAsyncReturnOnMain( + SetUserCodeCommand.changeAccessCode(null), + cardId, + initialMessage = Message(context.getString(R.string.initial_message_change_access_code_body))) } - suspend fun setLongTap(cardId: String?): CompletionResult { - return runTaskAsyncReturnOnMain(SetPinCommand( - pinType = PinType.Pin1, - newPin1 = tangemSdk.config.defaultPin1.calculateSha256(), - newPin2 = tangemSdk.config.defaultPin2.calculateSha256() - ), cardId, initialMessage = Message(activity.getString(R.string.initial_message_tap_header))) + suspend fun setLongTap(cardId: String?): CompletionResult { + return runTaskAsyncReturnOnMain( + SetUserCodeCommand.resetUserCodes(), + cardId, + initialMessage = Message(context.getString(R.string.initial_message_tap_header))) + } + + suspend fun checkUserCodes(cardId: String?): CompletionResult { + return runTaskAsyncReturnOnMain( + CheckUserCodesCommand(), + cardId, + initialMessage = Message(context.getString(R.string.initial_message_tap_header))) } suspend fun runTaskAsync( - runnable: CardSessionRunnable, cardId: String? = null, initialMessage: Message? = null, + runnable: CardSessionRunnable, cardId: String? = null, initialMessage: Message? = null, ): CompletionResult = - withContext(Dispatchers.IO) { - suspendCoroutine { continuation -> - tangemSdk.startSessionWithRunnable(runnable, cardId, initialMessage) { result -> - continuation.resume(result) - } + withContext(Dispatchers.Main) { + suspendCoroutine { continuation -> + tangemSdk.startSessionWithRunnable(runnable, cardId, initialMessage) { result -> + continuation.resume(result) } } + } 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 } @@ -107,4 +108,12 @@ class TangemSdkManager(val activity: ComponentActivity) { fun changeDisplayedCardIdNumbersCount(card: Card) { tangemSdk.config.cardIdDisplayedNumbersCount = if (card.isTwinCard()) 4 else null } + + companion object { + val config = Config( + filter = CardFilter( + allowedCardTypes = FirmwareVersion.FirmwareType.values().toList() + ) + ) + } } \ No newline at end of file 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 7a3556b33a..978ca5288f 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt @@ -3,26 +3,25 @@ package com.tangem.tap.domain import com.tangem.Message import com.tangem.TangemSdk import com.tangem.blockchain.common.TransactionSigner -import com.tangem.commands.SignCommand -import com.tangem.commands.SignResponse -import com.tangem.commands.wallet.WalletIndex import com.tangem.common.CompletionResult +import com.tangem.tap.domain.tasks.SignHashTask +import com.tangem.tap.domain.tasks.SignHashesTask import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine class TangemSigner( private val tangemSdk: TangemSdk, private val initialMessage: Message, - private val signerCallback: (SignResponse) -> Unit + private val signerCallback: (TangemSignerResponse) -> Unit, ) : TransactionSigner { override suspend fun sign( hash: ByteArray, cardId: String, - walletPublicKey: ByteArray + walletPublicKey: ByteArray, ): CompletionResult = suspendCoroutine { continuation -> - val command = SignCommand(arrayOf(hash), WalletIndex.PublicKey(walletPublicKey)) + val command = SignHashTask(hash, walletPublicKey) tangemSdk.startSessionWithRunnable( runnable = command, cardId = cardId, @@ -30,8 +29,13 @@ class TangemSigner( ) { result -> when (result) { is CompletionResult.Success -> { - signerCallback(result.data) - continuation.resume(CompletionResult.Success(result.data.signatures.first())) + signerCallback( + TangemSignerResponse( + result.data.totalSignedHashes, + result.data.remainingSignatures + ) + ) + continuation.resume(CompletionResult.Success(result.data.signature)) } is CompletionResult.Failure -> continuation.resume(CompletionResult.Failure(result.error)) @@ -43,18 +47,23 @@ class TangemSigner( override suspend fun sign( hashes: List, cardId: String, - walletPublicKey: ByteArray + walletPublicKey: ByteArray, ): CompletionResult> = suspendCoroutine { continuation -> - val command = SignCommand(hashes.toTypedArray(), WalletIndex.PublicKey(walletPublicKey)) + val task = SignHashesTask(hashes, walletPublicKey) tangemSdk.startSessionWithRunnable( - runnable = command, + runnable = task, cardId = cardId, initialMessage = initialMessage, ) { result -> when (result) { is CompletionResult.Success -> { - signerCallback(result.data) + signerCallback( + TangemSignerResponse( + result.data.totalSignedHashes, + result.data.remainingSignatures + ) + ) continuation.resume(CompletionResult.Success(result.data.signatures)) } is CompletionResult.Failure -> @@ -62,4 +71,9 @@ class TangemSigner( } } } -} \ No newline at end of file +} + +data class TangemSignerResponse( + val totalSignedHashes: Int?, + val remainingSignatures: Int?, +) \ No newline at end of file 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 521ed462b4..ca57897238 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt @@ -1,7 +1,7 @@ package com.tangem.tap.domain import androidx.annotation.StringRes -import com.tangem.TangemError +import com.tangem.common.core.TangemError import com.tangem.wallet.R interface TapErrors 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 992ddbc606..466e463f19 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -1,9 +1,8 @@ package com.tangem.tap.domain import com.tangem.blockchain.common.* -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.CardStatus -import com.tangem.commands.common.network.Result +import com.tangem.common.card.Card +import com.tangem.common.services.Result import com.tangem.tap.common.analytics.AnalyticsEvent import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.redux.global.FiatCurrencyName @@ -89,7 +88,7 @@ class TapWalletManager { suspend fun onCardScanned(data: ScanNoteResponse, addAnalyticsEvent: Boolean = false) { if (addAnalyticsEvent) { - FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card) + FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card, data.walletData?.blockchain) } store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(data.card) updateConfigManager(data) @@ -109,7 +108,7 @@ class TapWalletManager { } } - val blockchain = data.card.getBlockchain() + val blockchain = data.getBlockchain() if (blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet) { store.dispatch(TokensAction.LoadCardTokens) @@ -120,12 +119,12 @@ class TapWalletManager { private fun updateConfigManager(data: ScanNoteResponse) { val configManager = store.state.globalState.configManager - val blockchain = data.card.getBlockchain() + val blockchain = data.getBlockchain() if (data.card.isStart2Coin) { configManager?.turnOff(ConfigManager.isSendingToPayIdEnabled) configManager?.turnOff(ConfigManager.isTopUpEnabled) } else if (blockchain == Blockchain.Bitcoin - || data.card.cardData?.blockchainName == Blockchain.Bitcoin.id) { + || data.walletData?.blockchain == Blockchain.Bitcoin.id) { configManager?.resetToDefault(ConfigManager.isSendingToPayIdEnabled) configManager?.resetToDefault(ConfigManager.isTopUpEnabled) } else { @@ -136,25 +135,25 @@ class TapWalletManager { suspend fun loadData(data: ScanNoteResponse) { withContext(Dispatchers.Main) { - val artworkId = data.verifyResponse?.artworkInfo?.id + + store.dispatch(WalletAction.LoadCardInfo(data.card)) + when { - data.card.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> { + data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> { store.dispatch(WalletAction.LoadData.Failure(TapError.UnknownBlockchain)) - store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) } - data.card.getStatus() == CardStatus.Empty || + data.card.wallets.isEmpty() || (data.card.isTwinCard() && data.secondTwinPublicKey == null) -> { store.dispatch(WalletAction.EmptyWallet) - store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) } else -> { val config = store.state.globalState.configManager?.config ?: return@withContext - val blockchain = data.card.getBlockchain() + val blockchain = data.getBlockchain() val primaryWalletManager = walletManagerFactory.makePrimaryWalletManager(data) if (blockchain != null && primaryWalletManager != null) { - val primaryToken = data.card.getToken() + val primaryToken = data.getPrimaryToken() store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(blockchain)) if (primaryToken != null) { @@ -173,17 +172,14 @@ class TapWalletManager { loadMultiWalletData(data.card, blockchain, null) } } - store.dispatch(WalletAction.SetArtworkId(data.verifyResponse?.artworkInfo?.id)) val moonPayUserStatus = store.state.globalState.moonPayUserStatus store.dispatch(WalletAction.LoadWallet( allowToBuy = config.isTopUpEnabled && moonPayUserStatus?.isBuyAllowed == true, allowToSell = config.isTopUpEnabled && moonPayUserStatus?.isSellAllowed == true, )) - store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) store.dispatch(WalletAction.LoadFiatRate()) } } - store.dispatch(WalletAction.Warnings.CheckIfNeeded) } } @@ -236,10 +232,10 @@ class TapWalletManager { suspend fun reloadData(data: ScanNoteResponse) { withContext(Dispatchers.Main) { when { - data.card.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> { + data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> { store.dispatch(WalletAction.LoadData.Failure(TapError.UnknownBlockchain)) } - data.card.getStatus() == CardStatus.Empty || + data.card.wallets.isEmpty() || (data.card.isTwinCard() && data.secondTwinPublicKey == null) -> { store.dispatch(WalletAction.EmptyWallet) } diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index 6a6723cd83..8af0e99415 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -1,10 +1,13 @@ package com.tangem.tap.domain -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.EllipticCurve -import com.tangem.commands.common.card.masks.Product +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.tap.domain.TapWorkarounds.isNote import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.extensions.getSingleWallet +import com.tangem.tap.domain.twins.isTwinCard import java.util.* object TapWorkarounds { @@ -14,21 +17,37 @@ object TapWorkarounds { } val Card.isStart2Coin: Boolean - get() = isStart2CoinIssuer(cardData?.issuerName) - - fun Card.isExcluded(): Boolean { - val cardData = this.cardData ?: return false - val productMask = cardData.productMask - val excludedBatch = excludedBatches.contains(cardData.batchId) - val excludedIssuerName = excludedIssuers.contains(cardData.issuerName?.uppercase(Locale.ROOT)) - val excludedProductMask = (productMask != null && // product mask is on cards v2.30 and later - !productMask.contains(Product.Note) && !productMask.contains(Product.TwinCard)) - return excludedBatch || excludedIssuerName || excludedProductMask - - } + get() = isStart2CoinIssuer(issuer.name) val Card.isTestCard: Boolean - get() = cardData?.batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH) + get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH) + + fun Card.isExcluded(): Boolean { + val excludedBatch = excludedBatches.contains(batchId) + val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT)) + return excludedBatch || excludedIssuerName + } + + fun Card.isNote(): Boolean { + return notesBatches.contains(batchId) + } + + fun Card.isMultiCurrencyWallet(): Boolean { + return multiCurrencyWalletsBatches.contains(batchId) + } + + val Card.noteCurrency: Blockchain? + get() { + return when (batchId) { + "AB01" -> Blockchain.Bitcoin + "AB02" -> Blockchain.Ethereum + "AB03" -> Blockchain.CardanoShelley + "AB04" -> Blockchain.Dogecoin + "AB05" -> Blockchain.Binance + "AB06" -> Blockchain.XRP + else -> null + } + } private const val START_2_COIN_ISSUER = "start2coin" private const val TEST_CARD_BATCH = "99FF" @@ -44,12 +63,22 @@ object TapWorkarounds { private val excludedIssuers = listOf( "TTM BANK" ) + + private val notesBatches = listOf( + "AB01", + "AB02", + "AB03", + "AB04", + "AB05", + "AB06", + ) + + private val multiCurrencyWalletsBatches = listOf("AC01") } val Card.isMultiwalletAllowed: Boolean get() { - return cardData?.productMask?.contains(Product.TwinCard) != true - && !isStart2Coin - && (firmwareVersion.major >= 4 || + return !isTwinCard() && !isStart2Coin && !isNote() + && (firmwareVersion >= FirmwareVersion.MultiWalletAvailable || getSingleWallet()?.curve == EllipticCurve.Secp256k1) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt index 5822a252bc..e08ba924b5 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt @@ -1,7 +1,7 @@ package com.tangem.tap.domain.configurable.config import com.tangem.blockchain.common.BlockchainSdkConfig -import com.tangem.tangem_sdk_new.ui.animation.VoidCallback +import com.tangem.common.extensions.VoidCallback import com.tangem.tap.domain.configurable.Loader /** diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt index 86b1cf4eff..3cdf14dfea 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt @@ -1,7 +1,7 @@ package com.tangem.tap.domain.configurable.warningMessage import com.tangem.blockchain.common.Blockchain -import com.tangem.tangem_sdk_new.ui.animation.VoidCallback +import com.tangem.common.extensions.VoidCallback import com.tangem.tap.common.extensions.containsAny import com.tangem.tap.common.extensions.removeBy import com.tangem.wallet.R 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 0c8ed31dae..be6eb20dcb 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,48 +1,18 @@ package com.tangem.tap.domain.extensions -import com.tangem.FirmwareConstraints -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Token -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.CardStatus -import com.tangem.commands.wallet.CardWallet -import com.tangem.commands.wallet.WalletStatus -import com.tangem.common.TangemSdkConstants - -fun Card.getToken(): Token? { - val symbol = cardData?.tokenSymbol ?: return null - val contractAddress = cardData?.tokenContractAddress ?: return null - val decimals = cardData?.tokenDecimal ?: return null - val blockchain = cardData?.blockchainName?.let { Blockchain.fromId(it) } ?: return null - if (symbol.isBlank() || contractAddress.isBlank()) return null - return Token(symbol, contractAddress, decimals, blockchain) -} - -fun Card.getBlockchain(): Blockchain? { - val blockchainName: String = cardData?.blockchainName ?: return null - return Blockchain.fromId(blockchainName) -} +import com.tangem.common.card.Card +import com.tangem.common.card.CardWallet fun Card.getSingleWallet(): CardWallet? { - return wallet(TangemSdkConstants.getDefaultWalletIndex()) -} - -fun Card.getStatus(): CardStatus { - if (firmwareVersion < FirmwareConstraints.AvailabilityVersions.walletData) return status!! - - return if (wallets.any { it.status == WalletStatus.Loaded }) { - CardStatus.Loaded - } else { - CardStatus.Empty - } + return wallets.firstOrNull() } fun Card.hasSignedHashes(): Boolean { - return wallets.any { it.status == WalletStatus.Loaded && it.signedHashes ?: 0 > 0 } + return wallets.any { it.totalSignedHashes ?: 0 > 0 } } fun Card.signedHashesCount(): Int { - return wallets.map { it.signedHashes ?: 0 }.sum() + return wallets.map { it.totalSignedHashes ?: 0 }.sum() } val Card.remainingSignatures: Int? diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/TangemSdkConstants.kt b/app/src/main/java/com/tangem/tap/domain/extensions/TangemSdkConstants.kt deleted file mode 100644 index c8710e3aeb..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/extensions/TangemSdkConstants.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.tap.domain.extensions - -import com.tangem.commands.wallet.WalletIndex -import com.tangem.common.TangemSdkConstants - -fun TangemSdkConstants.Companion.getDefaultWalletIndex(): WalletIndex { - return WalletIndex.Index(oldCardDefaultWalletIndex) -} \ 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 88583ddf84..5ec3f1afa9 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 @@ -3,9 +3,9 @@ package com.tangem.tap.domain.extensions import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.WalletManagerFactory -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.EllipticCurve -import com.tangem.commands.wallet.CardWallet +import com.tangem.common.card.Card +import com.tangem.common.card.CardWallet +import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.hexToBytes import com.tangem.tap.domain.TapWorkarounds.isTestCard import com.tangem.tap.domain.tasks.ScanNoteResponse @@ -54,9 +54,9 @@ fun WalletManagerFactory.makePrimaryWalletManager( ): WalletManager? { val card = data.card val blockchain = if (card.isTestCard) { - card.getBlockchain()?.getTestnetVersion() + data.getBlockchain()?.getTestnetVersion() } else { - card.getBlockchain() + data.getBlockchain() } val supportedCurves = blockchain?.getSupportedCurves() ?: return null val wallets = card.wallets.filter { wallet -> supportedCurves.contains(wallet.curve) } diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt index 19b87612a0..ee2cda0d50 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt @@ -1,28 +1,27 @@ package com.tangem.tap.domain.tasks -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.FirmwareConstraints -import com.tangem.TangemSdkError -import com.tangem.commands.common.card.Card import com.tangem.common.CompletionResult -import com.tangem.tasks.CreateWalletTask -import com.tangem.tasks.PreflightReadCapable -import com.tangem.tasks.PreflightReadSettings -import com.tangem.tasks.PreflightReadTask +import com.tangem.common.card.Card +import com.tangem.common.card.FirmwareVersion +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.common.core.TangemSdkError +import com.tangem.common.extensions.guard +import com.tangem.operations.PreflightReadMode +import com.tangem.operations.PreflightReadTask +import com.tangem.operations.wallet.CreateWalletCommand -class CreateWalletAndRescanTask : CardSessionRunnable, PreflightReadCapable { - override val requiresPin2 = false - override fun preflightReadSettings() = PreflightReadSettings.FullCardRead +class CreateWalletAndRescanTask : CardSessionRunnable { override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val firmwareVerion = session.environment.card?.firmwareVersion - if (firmwareVerion == null) { + val card = session.environment.card.guard { callback(CompletionResult.Failure(TangemSdkError.CardError())) return } - val task = if (firmwareVerion < FirmwareConstraints.AvailabilityVersions.walletData) { - CreateWalletTask() + val firmwareVersion = card.firmwareVersion + + val task = if (firmwareVersion < FirmwareVersion.MultiWalletAvailable) { + CreateWalletCommand(card.supportedCurves.first(), false) } else { CreateWalletsTask() } @@ -30,7 +29,7 @@ class CreateWalletAndRescanTask : CardSessionRunnable, PreflightReadCapabl task.run(session) { result -> when (result) { is CompletionResult.Success -> - PreflightReadTask(PreflightReadSettings.FullCardRead).run(session, callback) + PreflightReadTask(PreflightReadMode.FullCardRead).run(session, callback) is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) } } diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletsTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletsTask.kt index b72cf26ae3..1443371141 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletsTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletsTask.kt @@ -1,51 +1,47 @@ package com.tangem.tap.domain.tasks -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.EllipticCurve -import com.tangem.commands.wallet.CreateWalletCommand -import com.tangem.commands.wallet.WalletConfig import com.tangem.common.CompletionResult -import com.tangem.tasks.PreflightReadSettings -import com.tangem.tasks.PreflightReadTask +import com.tangem.common.card.Card +import com.tangem.common.card.EllipticCurve +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.operations.PreflightReadMode +import com.tangem.operations.PreflightReadTask +import com.tangem.operations.wallet.CreateWalletCommand -class CreateWalletsTask(wallets: List = emptyList()) : CardSessionRunnable { - override val requiresPin2 = false +class CreateWalletsTask(curves: List = emptyList()) : CardSessionRunnable { - val wallets = if (wallets.isEmpty()) { + private val curves = if (curves.isEmpty()) { listOf( - WalletConfig(null, null, EllipticCurve.Secp256k1, null), - WalletConfig(null, null, EllipticCurve.Ed25519, null), - WalletConfig(null, null, EllipticCurve.Secp256r1, null), + EllipticCurve.Secp256k1, + EllipticCurve.Ed25519, + EllipticCurve.Secp256r1, ) } else { - wallets + curves } var index = 0 override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val walletConfig = wallets[index] - createWallet(walletConfig, session, callback) + val curve = curves[index] + createWallet(curve, session, callback) } private fun createWallet( - walletConfig: WalletConfig, session: CardSession, + curve: EllipticCurve, session: CardSession, callback: (result: CompletionResult) -> Unit ) { - CreateWalletCommand( - walletConfig, walletIndexValue = walletConfig.curveId!!.toWalletIndex() - ).run(session) { result -> + CreateWalletCommand(curve, false).run(session) { result -> when (result) { is CompletionResult.Success -> { - if (index == wallets.lastIndex) { - PreflightReadTask(PreflightReadSettings.FullCardRead).run(session, callback) + if (index == curves.lastIndex) { + PreflightReadTask(PreflightReadMode.FullCardRead).run(session, callback) return@run } index += 1 - createWallet(wallets[index], session, callback) + createWallet(curves[index], session, callback) } is CompletionResult.Failure -> { callback(CompletionResult.Failure(result.error)) diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt index 0415316f32..ca90ead2c5 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt @@ -1,50 +1,67 @@ package com.tangem.tap.domain.tasks import com.tangem.* +import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.BlockchainSdkConfig +import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.WalletManagerFactory -import com.tangem.commands.CommandResponse -import com.tangem.commands.ReadIssuerDataCommand -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.CardStatus -import com.tangem.commands.common.card.EllipticCurve -import com.tangem.commands.verification.VerifyCardCommand -import com.tangem.commands.verification.VerifyCardResponse -import com.tangem.commands.wallet.WalletConfig import com.tangem.common.CompletionResult +import com.tangem.common.card.Card +import com.tangem.common.card.EllipticCurve +import com.tangem.common.card.WalletData +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.common.core.TangemError import com.tangem.common.extensions.toHexString +import com.tangem.operations.CommandResponse +import com.tangem.operations.ScanTask +import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand import com.tangem.tap.domain.TapSdkError import com.tangem.tap.domain.TapWorkarounds.isExcluded +import com.tangem.tap.domain.TapWorkarounds.isMultiCurrencyWallet +import com.tangem.tap.domain.TapWorkarounds.noteCurrency import com.tangem.tap.domain.extensions.getSingleWallet -import com.tangem.tap.domain.extensions.getStatus import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tap.store -import com.tangem.tasks.PreflightReadCapable -import com.tangem.tasks.PreflightReadSettings -import com.tangem.tasks.ScanTask +import com.tangem.wallet.R data class ScanNoteResponse( - val card: Card, - val verifyResponse: VerifyCardResponse? = null, - val secondTwinPublicKey: String? = null, -) : CommandResponse + val card: Card, + val walletData: WalletData?, + val secondTwinPublicKey: String? = null, +) : CommandResponse { -class ScanNoteTask(val card: Card? = null) : CardSessionRunnable, PreflightReadCapable { - override val requiresPin2 = false + fun getBlockchain(): Blockchain? { + if (card.noteCurrency != null) return card.noteCurrency + val blockchainName: String = walletData?.blockchain ?: return null + return Blockchain.fromId(blockchainName) + } - override fun preflightReadSettings() = PreflightReadSettings.FullCardRead + fun getPrimaryToken(): Token? { + val cardToken = walletData?.token ?: return null + return Token( + cardToken.name, + cardToken.symbol, + cardToken.contractAddress, + cardToken.decimals, + Blockchain.fromId(walletData.blockchain) + ) + } +} - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { +class ScanNoteTask(val card: Card? = null) : CardSessionRunnable { + + override fun run( + session: CardSession, + callback: (result: CompletionResult) -> Unit, + ) { ScanTask().run(session) { result -> when (result) { is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) is CompletionResult.Success -> { - val card = this.card?.copy( - isPin1Default = result.data.isPin1Default, - isPin2Default = result.data.isPin2Default, - ) ?: result.data + val card = this.card ?: result.data val error = getErrorIfExcludedCard(card) if (error != null) { @@ -52,39 +69,28 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable) -> Unit - ) { - VerifyCardCommand(true).run(session) { verifyResult -> - when (verifyResult) { - is CompletionResult.Success -> { if (card.isTwinCard()) { - dealWithTwinCard(card, session, verifyResult.data, callback) + dealWithTwinCard(card, session, callback) } else if (card.firmwareVersion.major >= 4) { - createMissingWalletsIfNeeded(card, session, verifyResult.data, callback) + createMissingWalletsIfNeeded(card, session, callback) } else { - callback(CompletionResult.Success(ScanNoteResponse(card, verifyResult.data))) + callback(CompletionResult.Success( + ScanNoteResponse(card, session.environment.walletData))) } } - is CompletionResult.Failure -> { - callback(CompletionResult.Failure(TangemSdkError.CardVerificationFailed())) - } } } } private fun createMissingWalletsIfNeeded( - card: Card, session: CardSession, verifyResponse: VerifyCardResponse, - callback: (result: CompletionResult) -> Unit + card: Card, session: CardSession, + callback: (result: CompletionResult) -> Unit, ) { - if (card.getStatus() == CardStatus.Empty) { - callback(CompletionResult.Success(ScanNoteResponse(card, verifyResponse))) + val walletData = session.environment.walletData + if (card.wallets.isEmpty()) { + callback(CompletionResult.Success( + ScanNoteResponse(card, walletData) + )) return } @@ -92,20 +98,14 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable - WalletConfig( - isReusable = null, prohibitPurgeWallet = null, curveId = curve, - signingMethods = null - ) - } - CreateWalletsTask(configs).run(session) { result -> + CreateWalletsTask(curvesToCreate.toList()).run(session) { result -> when (result) { is CompletionResult.Success -> - callback(CompletionResult.Success(ScanNoteResponse(result.data, verifyResponse))) + callback(CompletionResult.Success(ScanNoteResponse(result.data, walletData))) is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) } } @@ -113,8 +113,8 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable) -> Unit + card: Card, session: CardSession, + callback: (result: CompletionResult) -> Unit, ) { ReadIssuerDataCommand().run(session) { readDataResult -> when (readDataResult) { @@ -125,12 +125,15 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable { + override fun run(session: CardSession, callback: CompletionCallback) { + SignHashCommand(hash, walletPublicKey).run(session) { response -> + + when (response) { + is CompletionResult.Success -> { + callback(CompletionResult.Success(TangemSignHashResponse( + response.data.signature, + response.data.totalSignedHashes, + session.environment.card?.wallet(walletPublicKey)?.remainingSignatures + ))) + } + is CompletionResult.Failure -> + callback(CompletionResult.Failure(response.error)) + } + } + } +} diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/SignHashesTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/SignHashesTask.kt new file mode 100644 index 0000000000..2755d9aa82 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/tasks/SignHashesTask.kt @@ -0,0 +1,35 @@ +package com.tangem.tap.domain.tasks + +import com.tangem.common.CompletionResult +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.common.core.CompletionCallback +import com.tangem.operations.CommandResponse +import com.tangem.operations.sign.SignHashesCommand + +class TangemSignHashesResponse( + val signatures: List, + val totalSignedHashes: Int?, + val remainingSignatures: Int?, +) : CommandResponse + +class SignHashesTask( + private val hashes: Collection, + private val walletPublicKey: ByteArray, +) : CardSessionRunnable { + override fun run(session: CardSession, callback: CompletionCallback) { + SignHashesCommand(hashes.toTypedArray(), walletPublicKey).run(session) { response -> + when (response) { + is CompletionResult.Success -> { + callback(CompletionResult.Success(TangemSignHashesResponse( + response.data.signatures, + response.data.totalSignedHashes, + session.environment.card?.wallet(walletPublicKey)?.remainingSignatures + ))) + } + is CompletionResult.Failure -> + callback(CompletionResult.Failure(response.error)) + } + } + } +} \ No newline at end of file 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 c5d9d91396..032c0b97ca 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,7 +3,7 @@ package com.tangem.tap.domain.termsOfUse import android.content.res.Resources import android.net.Uri import androidx.core.os.ConfigurationCompat -import com.tangem.commands.common.card.Card +import com.tangem.common.card.Card import java.util.* /** @@ -13,8 +13,8 @@ class CardTou { private val locale: Locale = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0) fun getUrl(card: Card): Uri? { - val issuerName = card.cardData?.issuerName ?: return null - if (issuerName.toLowerCase() != "start2coin") return null + val issuerName = card.issuer.name ?: return null + if (issuerName.lowercase(Locale.getDefault()) != "start2coin") return null val baseUrl = "https://app.tangem.com/tou/" val regionCode = regionCode(card.cardId) ?: "fr" 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 054698b51b..26aa55369c 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 @@ -8,7 +8,7 @@ import com.squareup.moshi.JsonClass import com.squareup.moshi.Types import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token -import com.tangem.commands.common.card.FirmwareVersion +import com.tangem.common.card.FirmwareVersion import com.tangem.tap.common.extensions.readJsonFileToString import com.tangem.tap.network.createMoshi @@ -127,7 +127,7 @@ class CurrenciesRepository(val context: Application) { cardFirmware: FirmwareVersion?, isTestNet: Boolean = false ): List { - return if (cardFirmware == null || cardFirmware.major < 4) { + return if (cardFirmware == null || cardFirmware < FirmwareVersion.MultiWalletAvailable) { Blockchain.secp256k1Blockchains(isTestNet) } else { Blockchain.secp256k1Blockchains(isTestNet) + Blockchain.ed25519OnlyBlockchains(isTestNet) diff --git a/app/src/main/java/com/tangem/tap/domain/topup/TopUpManager.kt b/app/src/main/java/com/tangem/tap/domain/topup/TopUpManager.kt index 568c65f7d0..775d3748a7 100644 --- a/app/src/main/java/com/tangem/tap/domain/topup/TopUpManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/topup/TopUpManager.kt @@ -34,9 +34,9 @@ class TopUpManager { ) { signResponse -> store.dispatch( GlobalAction.UpdateWalletSignedHashes( - walletSignedHashes = signResponse.walletSignedHashes, - remainingSignatures = signResponse.walletRemainingSignatures, - walletPublicKey = walletManager.wallet.publicKey + walletSignedHashes = signResponse.totalSignedHashes, + walletPublicKey = walletManager.wallet.publicKey, + remainingSignatures = signResponse.remainingSignatures ) ) } 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 0251173136..0ca3f113c3 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 @@ -1,34 +1,34 @@ package com.tangem.tap.domain.twins -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.commands.wallet.CreateWalletResponse -import com.tangem.commands.wallet.PurgeWalletCommand import com.tangem.common.CompletionResult -import com.tangem.common.TangemSdkConstants -import com.tangem.tap.domain.extensions.getDefaultWalletIndex +import com.tangem.common.card.EllipticCurve +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.operations.wallet.CreateWalletCommand +import com.tangem.operations.wallet.CreateWalletResponse +import com.tangem.operations.wallet.PurgeWalletCommand import com.tangem.tap.domain.extensions.getSingleWallet -import com.tangem.tasks.CreateWalletTask class CreateFirstTwinWalletTask : CardSessionRunnable { - override val requiresPin2 = false - override fun run( session: CardSession, callback: (result: CompletionResult) -> Unit, ) { - if (session.environment.card?.getSingleWallet()?.publicKey != null) { - PurgeWalletCommand(TangemSdkConstants.getDefaultWalletIndex()).run(session) { response -> + val publicKey = session.environment.card?.getSingleWallet()?.publicKey + if (publicKey != null) { + PurgeWalletCommand(publicKey).run(session) { response -> when (response) { is CompletionResult.Success -> { - session.environment.card = session.environment.card?.changeStatusToEmpty() - CreateWalletTask().run(session) { callback(it) } + session.environment.card = session.environment.card?.setWallets(emptyList()) + CreateWalletCommand(EllipticCurve.Secp256k1, false) + .run(session) { callback(it) } } is CompletionResult.Failure -> callback(CompletionResult.Failure(response.error)) } } } else { - CreateWalletTask().run(session) { callback(it) } + CreateWalletCommand(EllipticCurve.Secp256k1, false) + .run(session) { callback(it) } } } } \ No newline at end of file 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 c8e936bcce..1c0af37da4 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 @@ -1,31 +1,29 @@ package com.tangem.tap.domain.twins -import com.tangem.CardSession -import com.tangem.CardSessionRunnable import com.tangem.Message -import com.tangem.commands.wallet.CreateWalletResponse -import com.tangem.commands.wallet.PurgeWalletCommand import com.tangem.common.CompletionResult -import com.tangem.common.TangemSdkConstants +import com.tangem.common.card.EllipticCurve +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable import com.tangem.common.extensions.hexToBytes -import com.tangem.tap.domain.extensions.getDefaultWalletIndex +import com.tangem.operations.wallet.CreateWalletCommand +import com.tangem.operations.wallet.CreateWalletResponse +import com.tangem.operations.wallet.PurgeWalletCommand import com.tangem.tap.domain.extensions.getSingleWallet -import com.tangem.tasks.CreateWalletTask class CreateSecondTwinWalletTask( private val firstPublicKey: String, private val preparingMessage: Message, private val creatingWalletMessage: Message ) : CardSessionRunnable { - override val requiresPin2 = true - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - if (session.environment.card?.getSingleWallet()?.publicKey != null) { + val publicKey = session.environment.card?.getSingleWallet()?.publicKey + if (publicKey != null) { session.setInitialMessage(preparingMessage) - PurgeWalletCommand(TangemSdkConstants.getDefaultWalletIndex()).run(session) { response -> + PurgeWalletCommand(publicKey).run(session) { response -> when (response) { is CompletionResult.Success -> { - session.environment.card = session.environment.card?.changeStatusToEmpty() + session.environment.card = session.environment.card?.setWallets(emptyList()) finishTask(session, callback) } is CompletionResult.Failure -> callback(CompletionResult.Failure(response.error)) @@ -38,10 +36,10 @@ class CreateSecondTwinWalletTask( private fun finishTask(session: CardSession, callback: (result: CompletionResult) -> Unit) { session.setInitialMessage(creatingWalletMessage) - CreateWalletTask().run(session) { result -> + CreateWalletCommand(EllipticCurve.Secp256k1, false).run(session) { result -> when (result) { is CompletionResult.Success -> { - session.environment.card = session.environment.card?.changeStatusToLoaded() + session.environment.card = session.environment.card?.updateWallet(result.data.wallet) WriteProtectedIssuerDataTask( firstPublicKey.hexToBytes(), TwinCardsManager.issuerKeys diff --git a/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt b/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt index 8eb0315241..aeef1b9481 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt @@ -1,18 +1,17 @@ package com.tangem.tap.domain.twins -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.KeyPair import com.tangem.common.CompletionResult +import com.tangem.common.KeyPair +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.operations.PreflightReadMode +import com.tangem.operations.PreflightReadTask import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.domain.tasks.ScanNoteTask -import com.tangem.tasks.PreflightReadSettings -import com.tangem.tasks.PreflightReadTask class FinalizeTwinTask( private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair, ) : CardSessionRunnable { - override val requiresPin2 = true override fun run( session: CardSession, @@ -21,7 +20,7 @@ class FinalizeTwinTask( WriteProtectedIssuerDataTask(twinPublicKey, issuerKeys).run(session) { result -> when (result) { is CompletionResult.Success -> - PreflightReadTask(PreflightReadSettings.FullCardRead).run(session) { readResult -> + PreflightReadTask(PreflightReadMode.FullCardRead).run(session) { readResult -> when (readResult) { is CompletionResult.Success -> ScanNoteTask(readResult.data).run(session, callback) 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 af088dc421..0282a18d65 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 @@ -1,11 +1,11 @@ package com.tangem.tap.domain.twins -import com.tangem.KeyPair import com.tangem.Message -import com.tangem.TangemSdkError import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult import com.tangem.common.CompletionResult +import com.tangem.common.KeyPair +import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString import com.tangem.crypto.CryptoUtils @@ -27,7 +27,7 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) { ) when (response) { is CompletionResult.Success -> { - currentCardPublicKey = response.data.walletPublicKey.toHexString() + currentCardPublicKey = response.data.wallet.publicKey.toHexString() return SimpleResult.Success } is CompletionResult.Failure -> { @@ -56,7 +56,7 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) { ) when (response) { is CompletionResult.Success -> { - secondCardPublicKey = response.data.walletPublicKey.toHexString() + secondCardPublicKey = response.data.wallet.publicKey.toHexString() return SimpleResult.Success } is CompletionResult.Failure -> { diff --git a/app/src/main/java/com/tangem/tap/domain/twins/TwinsHelper.kt b/app/src/main/java/com/tangem/tap/domain/twins/TwinsHelper.kt index c534afbec6..9a6a892264 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/TwinsHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/TwinsHelper.kt @@ -1,10 +1,8 @@ package com.tangem.tap.domain.twins -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.CardStatus -import com.tangem.commands.common.card.masks.Product -import com.tangem.commands.wallet.WalletStatus +import com.tangem.common.card.Card import com.tangem.tap.common.extensions.isEven +import com.tangem.tap.domain.twins.TwinsHelper.Companion.getTwinCardNumber class TwinsHelper { companion object { @@ -78,19 +76,9 @@ enum class TwinCardNumber(val number: Int) { } fun Card.isTwinCard(): Boolean { - return this.cardData?.productMask?.contains(Product.TwinCard) == true + return getTwinCardNumber(cardId) != null } fun Card.getTwinCardIdForUser(): String { return TwinsHelper.getTwinCardIdForUser(this.cardId) -} - -fun Card.changeStatusToLoaded(): Card { - val wallets = wallets.map { it.copy(status = WalletStatus.Loaded) } - return copy(status = CardStatus.Loaded, wallets = wallets) -} - -fun Card.changeStatusToEmpty(): Card { - val wallets = wallets.map { it.copy(status = WalletStatus.Empty) } - return copy(status = CardStatus.Empty, wallets = wallets) } \ 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 bf6c735be5..94ce765f12 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 @@ -1,49 +1,61 @@ package com.tangem.tap.domain.twins -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.KeyPair -import com.tangem.TangemSdkError -import com.tangem.commands.* import com.tangem.common.CompletionResult -import com.tangem.common.TangemSdkConstants +import com.tangem.common.KeyPair +import com.tangem.common.SuccessResponse +import com.tangem.common.core.CardSession +import com.tangem.common.core.CardSessionRunnable +import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.calculateSha256 import com.tangem.common.extensions.guard import com.tangem.common.files.FileHashHelper -import com.tangem.tap.domain.extensions.getDefaultWalletIndex +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 -) : CardSessionRunnable { - override val requiresPin2 = true + private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair, +) : CardSessionRunnable { - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val hashes = arrayOf(twinPublicKey.calculateSha256()) - SignCommand(hashes, TangemSdkConstants.getDefaultWalletIndex()).run(session) { signResult -> - when (signResult) { - is CompletionResult.Success -> { - ReadIssuerDataCommand().run(session) { readResult -> - when (readResult) { - is CompletionResult.Success -> { - writeIssuerData( - twinPublicKey, issuerKeys, signResult.data.signatures[0], + override fun run( + session: CardSession, + callback: (result: CompletionResult) -> Unit, + ) { + SignHashCommand( + twinPublicKey.calculateSha256(), + session.environment.card!!.getSingleWallet()!!.publicKey + ) + .run(session) { signResult -> + when (signResult) { + is CompletionResult.Success -> { + ReadIssuerDataCommand().run(session) { readResult -> + when (readResult) { + is CompletionResult.Success -> { + writeIssuerData( + twinPublicKey, issuerKeys, signResult.data.signature, readResult.data, session, callback - ) + ) + } + is CompletionResult.Failure -> callback(CompletionResult.Failure( + readResult.error)) } - is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error)) } } + is CompletionResult.Failure -> callback(CompletionResult.Failure(signResult.error)) } - is CompletionResult.Failure -> callback(CompletionResult.Failure(signResult.error)) } - } } private fun writeIssuerData( - twinPublicKey: ByteArray, issuerKeys: KeyPair, cardSignature: ByteArray, - readResponse: ReadIssuerDataResponse, - session: CardSession, callback: (result: CompletionResult - ) -> Unit) { + twinPublicKey: ByteArray, issuerKeys: KeyPair, cardSignature: ByteArray, + readResponse: ReadIssuerDataResponse, + session: CardSession, + callback: ( + result: CompletionResult, + ) -> Unit, + ) { val cardId = session.environment.card?.cardId.guard { callback(CompletionResult.Failure(TangemSdkError.CardError())) return @@ -51,11 +63,11 @@ class WriteProtectedIssuerDataTask( val counter = (readResponse.issuerDataCounter ?: 0) + 1 val data = twinPublicKey + cardSignature val signedByIssuer = FileHashHelper.prepareHashes( - cardId, data, counter, issuerKeys.privateKey + cardId, data, counter, issuerKeys.privateKey ) WriteIssuerDataCommand( - data, signedByIssuer.finalizingSignature!!, - counter, issuerKeys.publicKey + data, signedByIssuer.finalizingSignature!!, + counter, issuerKeys.publicKey ).run(session, callback) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt index 7cff86a035..5ebfb1cb14 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt @@ -1,7 +1,6 @@ package com.tangem.tap.domain.walletconnect import com.tangem.Message -import com.tangem.TangemSdkError import com.tangem.blockchain.blockchains.ethereum.EthereumGasLoader import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras import com.tangem.blockchain.blockchains.ethereum.EthereumUtils @@ -11,10 +10,10 @@ import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.common.TransactionSender import com.tangem.blockchain.extensions.* -import com.tangem.commands.SignCommand -import com.tangem.commands.wallet.WalletIndex import com.tangem.common.CompletionResult +import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.hexToBytes +import com.tangem.operations.sign.SignHashCommand import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.extensions.toFormattedString import com.tangem.tap.features.details.redux.walletconnect.* @@ -150,9 +149,9 @@ class WalletConnectSdkHelper { gasLimit = null ) ?: return null - val command = SignCommand( - hashes = arrayOf(dataToSign.hash), - walletIndex = WalletIndex.PublicKey(data.walletManager.wallet.publicKey) + val command = SignHashCommand( + hash = dataToSign.hash, + walletPublicKey = data.walletManager.wallet.publicKey ) val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message()) return when (result) { @@ -210,13 +209,10 @@ class WalletConnectSdkHelper { suspend fun signPersonalMessage(hashToSign: ByteArray, wallet: WalletForSession): String? { val publicKey = wallet.walletPublicKey.hexToBytes() - val command = SignCommand( - arrayOf(hashToSign), - WalletIndex.PublicKey(publicKey)) + val command = SignHashCommand(hashToSign, publicKey) return when (val result = tangemSdkManager.runTaskAsync(command, wallet.cardId)) { is CompletionResult.Success -> { - val hash = result.data.signatures.first() - + val hash = result.data.signature return EthereumUtils.prepareSignedMessageData( hash, hashToSign, publicKey ) 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 f37ef1c696..79067f026e 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 @@ -2,7 +2,8 @@ package com.tangem.tap.features.details.redux import com.tangem.Message import com.tangem.blockchain.common.Wallet -import com.tangem.commands.common.card.Card +import com.tangem.common.card.Card +import com.tangem.operations.pins.CheckUserCodesResponse import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.common.redux.global.FiatCurrencyName import com.tangem.tap.domain.tasks.ScanNoteResponse @@ -90,6 +91,8 @@ sealed class DetailsAction : Action { } sealed class ManageSecurity : DetailsAction() { + data class CheckCurrentSecurityOption(val cardId: String?) : ManageSecurity() + data class SetCurrentOption(val userCodes: CheckUserCodesResponse) : ManageSecurity() object OpenSecurity : ManageSecurity() data class SelectOption(val option: SecurityOption) : ManageSecurity() object SaveChanges : ManageSecurity() { 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 90f75c3efe..15eca00858 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 @@ -1,9 +1,10 @@ package com.tangem.tap.features.details.redux -import com.tangem.TangemSdkError -import com.tangem.commands.common.network.Result import com.tangem.common.CompletionResult +import com.tangem.common.core.TangemSdkError +import com.tangem.common.services.Result import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler +import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen @@ -83,10 +84,9 @@ class DetailsMiddleware { store.dispatch(NavigationAction.PopBackTo()) } is DetailsAction.EraseWallet.Confirm -> { + val card = store.state.detailsState.card ?: return scope.launch { - val result = tangemSdkManager.eraseWallet( - store.state.detailsState.card?.cardId - ) + val result = tangemSdkManager.eraseWallet(card) withContext(Dispatchers.Main) { when (result) { is CompletionResult.Success -> { @@ -124,6 +124,21 @@ class DetailsMiddleware { class ManageSecurityMiddleware { fun handle(action: DetailsAction.ManageSecurity) { when (action) { + is DetailsAction.ManageSecurity.CheckCurrentSecurityOption -> { + scope.launch { + when (val response = tangemSdkManager.checkUserCodes(action.cardId)) { + is CompletionResult.Success -> { + store.dispatchOnMain( + DetailsAction.ManageSecurity.SetCurrentOption(response.data) + ) + store.dispatchOnMain(DetailsAction.ManageSecurity.OpenSecurity) + } + is CompletionResult.Failure -> { + + } + } + } + } is DetailsAction.ManageSecurity.OpenSecurity -> { store.dispatch(NavigationAction.NavigateTo(AppScreen.DetailsSecurity)) } 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 132dbddb18..f9a55c5271 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,8 +1,7 @@ package com.tangem.tap.features.details.redux -import com.tangem.commands.common.card.Card -import com.tangem.commands.common.card.masks.Settings +import com.tangem.common.card.Card import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.extensions.isWalletDataSupported @@ -47,17 +46,6 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { } private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: DetailsState): DetailsState { - val securityOption = when { - action.card.isPin1Default == false -> { - SecurityOption.AccessCode - } - action.card.isPin2Default == false -> { - SecurityOption.PassCode - } - else -> { - SecurityOption.LongTap - } - } val twinsState = if (action.card.isTwinCard()) { CreateTwinWalletState( scanResponse = action.scanNoteResponse, @@ -76,7 +64,6 @@ private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: Deta appCurrencyState = AppCurrencyState( action.fiatCurrencyName ), - securityScreenState = SecurityScreenState(currentOption = securityOption), createTwinWalletState = twinsState, cardTermsOfUseUrl = action.cardTou.getUrl(action.card) ) @@ -86,8 +73,7 @@ private fun handleEraseWallet(action: DetailsAction.EraseWallet, state: DetailsS return when (action) { DetailsAction.EraseWallet.Check -> { val notAllowedByCard = - state.card?.settingsMask?.contains(Settings.ProhibitPurgeWallet) == true - || state.card?.settingsMask?.contains(Settings.IsReusable) == false + state.card?.settings?.isPermanentWallet == true || state.card?.isWalletDataSupported == true val notEmpty = state.wallets.any { !it.recentTransactions.toPendingTransactions(it.address).isNullOrEmpty() @@ -142,6 +128,20 @@ private fun handleSecurityAction( action: DetailsAction.ManageSecurity, state: DetailsState ): DetailsState { return when (action) { + is DetailsAction.ManageSecurity.SetCurrentOption -> { + val securityOption = when { + action.userCodes.isAccessCodeSet -> { + SecurityOption.AccessCode + } + action.userCodes.isPasscodeSet -> { + SecurityOption.PassCode + } + else -> { + SecurityOption.LongTap + } + } + state.copy(securityScreenState = SecurityScreenState(currentOption = securityOption)) + } is DetailsAction.ManageSecurity.OpenSecurity -> { if (state.card?.isStart2Coin == true) { return state.copy(securityScreenState = state.securityScreenState?.copy( @@ -149,13 +149,10 @@ private fun handleSecurityAction( selectedOption = state.securityScreenState.currentOption )) } - if (state.card?.isPin2Default == null) { - return state.copy(securityScreenState = state.securityScreenState?.copy( - allowedOptions = EnumSet.noneOf(SecurityOption::class.java) - )) - } - val allowedSecurityOptions = prepareAllowedSecurityOptions(state.card) + val allowedSecurityOptions = prepareAllowedSecurityOptions( + state.card, state.securityScreenState?.currentOption + ) state.copy(securityScreenState = state.securityScreenState?.copy( allowedOptions = allowedSecurityOptions, selectedOption = state.securityScreenState.currentOption @@ -177,7 +174,6 @@ private fun handleSecurityAction( is DetailsAction.ManageSecurity.SaveChanges.Success -> { // Setting options to show only LongTap from now on state.copy( - card = state.card?.copy(isPin1Default = true, isPin2Default = true), securityScreenState = state.securityScreenState?.copy( currentOption = state.securityScreenState.selectedOption, allowedOptions = EnumSet.of(SecurityOption.LongTap) @@ -188,19 +184,19 @@ private fun handleSecurityAction( } } -private fun prepareAllowedSecurityOptions(card: Card): EnumSet { - val prohibitDefaultPin = card.settingsMask?.contains(Settings.ProhibitDefaultPIN1) == true - val isDefaultPin1 = card.isPin1Default != false - val isDefaultPin2 = card.isPin2Default != false +private fun prepareAllowedSecurityOptions( + card: Card?, currentSecurityOption: SecurityOption? +): EnumSet { + val prohibitDefaultPin = card?.settings?.isRemovingAccessCodeAllowed != true val allowedSecurityOptions = EnumSet.noneOf(SecurityOption::class.java) - if ((isDefaultPin1 && isDefaultPin2) || !prohibitDefaultPin) { + if ((currentSecurityOption == SecurityOption.LongTap) || !prohibitDefaultPin) { allowedSecurityOptions.add(SecurityOption.LongTap) } - if (!isDefaultPin1) { + if (currentSecurityOption == SecurityOption.AccessCode) { allowedSecurityOptions.add(SecurityOption.AccessCode) } - if (!isDefaultPin2) { + if (currentSecurityOption == SecurityOption.PassCode) { allowedSecurityOptions.add(SecurityOption.PassCode) } return allowedSecurityOptions @@ -209,6 +205,6 @@ private fun prepareAllowedSecurityOptions(card: Card): EnumSet { private fun Card.toCardInfo(): CardInfo? { val cardId = this.cardId.chunked(4).joinToString(separator = " ") - val issuer = this.cardData?.issuerName ?: return null + val issuer = this.issuer.name val signedHashes = this.signedHashesCount() return CardInfo(cardId, issuer, signedHashes)} \ No newline at end of file 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 5ef1033e2f..bf16dd3674 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.commands.common.card.Card +import com.tangem.common.card.Card import com.tangem.tap.common.entities.Button import com.tangem.tap.common.entities.TapCurrency.Companion.DEFAULT_FIAT_CURRENCY import com.tangem.tap.common.redux.global.FiatCurrencyName 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 6b9dfc4b07..813dba5494 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 @@ -1,8 +1,8 @@ package com.tangem.tap.features.details.redux.walletconnect import com.tangem.blockchain.common.* -import com.tangem.commands.common.card.Card import com.tangem.common.CompletionResult +import com.tangem.common.card.Card import com.tangem.common.extensions.toHexString import com.tangem.tap.* import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt index 3b0e9c83a1..55f9711482 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt @@ -126,7 +126,7 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber) { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt index 3da9747dd3..33a7313b5d 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt @@ -2,7 +2,7 @@ package com.tangem.tap.features.send.redux.middlewares import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Wallet -import com.tangem.commands.common.network.Result +import com.tangem.common.services.Result import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.isPayIdSupported 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 d24bfa3949..2c5b8ebd58 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 @@ -1,12 +1,12 @@ package com.tangem.tap.features.send.redux.middlewares import com.google.firebase.crashlytics.FirebaseCrashlytics -import com.tangem.TangemSdkError import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder import com.tangem.blockchain.common.* import com.tangem.blockchain.extensions.SimpleResult -import com.tangem.commands.common.card.Card +import com.tangem.common.card.Card +import com.tangem.common.core.TangemSdkError import com.tangem.tap.common.analytics.AnalyticsEvent import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.extensions.dispatchOnMain @@ -136,9 +136,9 @@ private fun sendTransaction( ) { signResponse -> store.dispatch( GlobalAction.UpdateWalletSignedHashes( - walletSignedHashes = signResponse.walletSignedHashes, - remainingSignatures = signResponse.walletRemainingSignatures, - walletPublicKey = walletManager.wallet.publicKey + walletSignedHashes = signResponse.totalSignedHashes, + walletPublicKey = walletManager.wallet.publicKey, + remainingSignatures = signResponse.remainingSignatures ) ) } @@ -150,7 +150,7 @@ private fun sendTransaction( FirebaseAnalyticsHandler.triggerEvent( event = AnalyticsEvent.TRANSACTION_IS_SENT, card = card, - blockchain = walletManager.wallet.blockchain + blockchain = walletManager.wallet.blockchain.currency ) dispatch(SendAction.SendSuccess) 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 cff630a1a8..488adca48d 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 @@ -3,7 +3,7 @@ package com.tangem.tap.features.wallet.redux import android.content.Context import com.tangem.blockchain.common.* import com.tangem.blockchain.common.address.AddressType -import com.tangem.commands.common.card.Card +import com.tangem.common.card.Card import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.domain.TapError @@ -93,6 +93,8 @@ sealed class WalletAction : Action { object Failure : WalletAction() } + class LoadCardInfo(val card: Card) : WalletAction() + data class LoadArtwork(val card: Card, val artworkId: String?) : WalletAction() { data class Success(val artwork: Artwork) : WalletAction() object Failure : WalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 8dc207048b..8c0b638587 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -3,13 +3,16 @@ package com.tangem.tap.features.wallet.redux.middlewares import android.content.Intent import android.net.Uri import androidx.core.content.ContextCompat -import com.tangem.TangemSdkError import com.tangem.blockchain.common.* import com.tangem.common.CompletionResult +import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.isZero +import com.tangem.common.services.Result +import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.* import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.extensions.copyToClipboard +import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.extensions.shareText import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction @@ -155,6 +158,32 @@ class WalletMiddleware { } } } + is WalletAction.LoadCardInfo -> { + scope.launch { + val response = OnlineCardVerifier().getCardInfo( + action.card.cardId, action.card.cardPublicKey + ) + when (response) { + is Result.Success -> { + store.dispatchOnMain( + WalletAction.SetArtworkId(response.data.artwork?.id) + ) + store.dispatchOnMain( + WalletAction.LoadArtwork(action.card, response.data.artwork?.id) + ) + store.dispatchOnMain( + GlobalAction.SetIfCardVerifiedOnline(response.data.passed) + ) + } + is Result.Failure -> { + store.dispatchOnMain( + GlobalAction.SetIfCardVerifiedOnline(false) + ) + } + } + store.dispatchOnMain(WalletAction.Warnings.CheckIfNeeded) + } + } is WalletAction.LoadData -> { scope.launch { val scanNoteResponse = globalState?.scanNoteResponse 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 32694c8282..d3a6c2d046 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,10 +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.commands.common.card.Card -import com.tangem.commands.common.card.CardType -import com.tangem.commands.verification.VerifyCardState -import com.tangem.common.extensions.getType +import com.tangem.common.card.Card +import com.tangem.common.card.FirmwareVersion import com.tangem.tap.common.analytics.AnalyticsEvent import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.extensions.isGreaterThan @@ -91,15 +89,13 @@ class WarningsMiddleware { } showWarningLowRemainingSignaturesIfNeeded(card) - if (card.getType() != CardType.Release) { + if (card.firmwareVersion.type != FirmwareVersion.FirmwareType.Release) { addWarningMessage(WarningMessagesManager.devCardWarning()) } else if (!preferencesStorage.wasCardScannedBefore(card.cardId)) { checkIfWarningNeeded(card)?.let { warning -> addWarningMessage(warning) } } - if (card.getType() == CardType.Release) { - if (globalState.scanNoteResponse.verifyResponse?.verificationState == - VerifyCardState.VerifiedOffline - ) { + if (card.firmwareVersion.type == FirmwareVersion.FirmwareType.Release) { + if (!globalState.cardVerifiedOnline) { addWarningMessage(WarningMessagesManager.onlineVerificationFailed()) } } @@ -161,7 +157,7 @@ class WarningsMiddleware { val validator = store.state.walletState.walletManagers.firstOrNull() as? SignatureCountValidator scope.launch { - val signedHashes = card.getSingleWallet()?.signedHashes ?: 0 + val signedHashes = card.getSingleWallet()?.totalSignedHashes ?: 0 val result = validator?.validateSignatureCount(signedHashes) withContext(Dispatchers.Main) { when (result) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index 3298b8a9cc..9bdef4b340 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -2,8 +2,8 @@ package com.tangem.tap.features.wallet.redux.reducers import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Wallet -import com.tangem.commands.common.network.TangemService import com.tangem.common.extensions.toHexString +import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.FiatCurrencyName @@ -216,21 +216,27 @@ private fun internalReduce(action: Action, state: AppState): WalletState { newState = setNewFiatRate(action.fiatRate, state.globalState.appCurrency, newState) is WalletAction.LoadArtwork -> { val cardId = action.card.cardId - val cardPublicKey = action.card.cardPublicKey?.toHexString() - val artworkUrl = if (cardPublicKey != null && action.artworkId != null) { - TangemService.getUrlForArtwork(cardId, cardPublicKey, action.artworkId) - } else if (action.card.cardId.startsWith(Artwork.SERGIO_CARD_ID)) { - Artwork.SERGIO_CARD_URL - } else if (action.card.cardId.startsWith(Artwork.MARTA_CARD_ID)) { - Artwork.MARTA_CARD_URL - } else if (newState.twinCardsState?.cardNumber != null) { - when (newState.twinCardsState?.cardNumber) { - TwinCardNumber.First -> Artwork.TWIN_CARD_1 - TwinCardNumber.Second -> Artwork.TWIN_CARD_2 - null -> Artwork.DEFAULT_IMG_URL + val cardPublicKey = action.card.cardPublicKey.toHexString() + val artworkUrl = when { + action.artworkId != null -> { + OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey, action.artworkId) + } + action.card.cardId.startsWith(Artwork.SERGIO_CARD_ID) -> { + Artwork.SERGIO_CARD_URL + } + action.card.cardId.startsWith(Artwork.MARTA_CARD_ID) -> { + Artwork.MARTA_CARD_URL + } + newState.twinCardsState?.cardNumber != null -> { + when (newState.twinCardsState?.cardNumber) { + TwinCardNumber.First -> Artwork.TWIN_CARD_1 + TwinCardNumber.Second -> Artwork.TWIN_CARD_2 + null -> Artwork.DEFAULT_IMG_URL + } + } + else -> { + Artwork.DEFAULT_IMG_URL } - } else { - Artwork.DEFAULT_IMG_URL } newState = newState.copy(cardImage = Artwork(artworkId = artworkUrl)) } diff --git a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt index fffc439820..cf497373cd 100644 --- a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt +++ b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt @@ -1,7 +1,7 @@ package com.tangem.tap.network.coinmarketcap -import com.tangem.commands.common.network.Result -import com.tangem.commands.common.network.performRequest +import com.tangem.common.services.Result +import com.tangem.common.services.performRequest import com.tangem.tap.common.redux.global.FiatCurrencyName import com.tangem.tap.store import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/tangem/tap/network/moonpay/MoonpayService.kt b/app/src/main/java/com/tangem/tap/network/moonpay/MoonpayService.kt index c20d22863e..9ef4b8b678 100644 --- a/app/src/main/java/com/tangem/tap/network/moonpay/MoonpayService.kt +++ b/app/src/main/java/com/tangem/tap/network/moonpay/MoonpayService.kt @@ -1,8 +1,8 @@ package com.tangem.tap.network.moonpay import com.squareup.moshi.JsonClass -import com.tangem.commands.common.network.Result -import com.tangem.commands.common.network.performRequest +import com.tangem.common.services.Result +import com.tangem.common.services.performRequest import com.tangem.tap.network.createRetrofitInstance class MoonpayService { diff --git a/app/src/main/java/com/tangem/tap/network/payid/PayIdService.kt b/app/src/main/java/com/tangem/tap/network/payid/PayIdService.kt index 2e691228ea..6eab298c6f 100644 --- a/app/src/main/java/com/tangem/tap/network/payid/PayIdService.kt +++ b/app/src/main/java/com/tangem/tap/network/payid/PayIdService.kt @@ -1,8 +1,8 @@ package com.tangem.tap.network.payid import com.squareup.moshi.JsonClass -import com.tangem.commands.common.network.Result -import com.tangem.commands.common.network.performRequest +import com.tangem.common.services.Result +import com.tangem.common.services.performRequest import com.tangem.tap.network.createRetrofitInstance import retrofit2.Retrofit diff --git a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt index 109dc5e97f..13d79d4591 100644 --- a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt +++ b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt @@ -1,7 +1,7 @@ package com.tangem.tap.network.payid -import com.tangem.commands.common.network.Result -import com.tangem.commands.common.network.performRequest +import com.tangem.common.services.Result +import com.tangem.common.services.performRequest import com.tangem.tap.network.createRetrofitInstance /** diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 01bdb3d5d6..9404210575 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -166,4 +166,6 @@ this wallet. Do you want to buy or sell crypto? + + Oops, the current version of the application is not ready to work with this card, please check for updates. diff --git a/dependencies.gradle b/dependencies.gradle index e4beaa5aaa..5567b6aa65 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,4 +1,4 @@ ext.versions = [ kotlin : '1.5.20', - build_gradle: '4.2.2', + build_gradle: '7.0.0', ] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c6dab66ff6..8e5b6ad562 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip From a6331b229166feb0bffe5ff2d77f0415e8bcd6f0 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 9 Aug 2021 09:14:41 +0300 Subject: [PATCH 5/5] Updated on 2026-08-14 --- app/build.gradle | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 14a1f59a8a..e97b9251f0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,18 +67,17 @@ dependencies { implementation fileTree(include: ['*.aar'], dir: 'libs') implementation 'androidx.core:core-ktx:1.6.0' - implementation 'androidx.appcompat:appcompat:1.3.0' - implementation 'androidx.fragment:fragment-ktx:1.3.5' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.constraintlayout:constraintlayout:2.1.0' implementation 'com.google.android.material:material:1.4.0' implementation "androidx.core:core-ktx:1.6.0" implementation 'com.google.android.play:core:1.10.0' implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:develop-34' - implementation 'com.tangem:core:fixes_for_app_release-44' - implementation 'com.tangem:sdk:fixes_for_app_release-44' + implementation 'com.tangem:blockchain:develop-36' + implementation 'com.tangem.tangem-sdk-kotlin:core:develop-47' + implementation 'com.tangem.tangem-sdk-kotlin:android:develop-47' // WebView implementation "androidx.browser:browser:1.3.0"