From 699dbd21b81567ba0498f1b84f943363d21c28fc Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 3 Dec 2020 12:13:22 +0300 Subject: [PATCH 01/42] Updated on 2026-08-14 --- app/src/main/assets/features_prod.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/assets/features_prod.json b/app/src/main/assets/features_prod.json index 39b226d053..236d0285bd 100644 --- a/app/src/main/assets/features_prod.json +++ b/app/src/main/assets/features_prod.json @@ -1,14 +1,14 @@ [ { "name": "isWalletPayIdEnabled", - "value": false + "value": true }, { "name": "isTopUpEnabled", - "value": false + "value": true }, { "name": "isCreatingTwinCardsAllowed", - "value": true + "value": false } ] \ No newline at end of file From f51ee2eb30882e45e0a6779ce612764b3d0b2918 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 3 Dec 2020 14:02:18 +0300 Subject: [PATCH 02/42] Updated on 2026-08-14 --- .../details/ui/twins/CreateTwinWalletFragment.kt | 14 ++++++++++++++ .../details/ui/twins/TwinWalletWarningFragment.kt | 14 ++++++++++++++ .../tap/features/wallet/redux/WalletReducer.kt | 7 +++++++ .../tap/features/wallet/redux/WalletState.kt | 2 ++ .../wallet/ui/dialogs/TwinsOnboardingFragment.kt | 15 +++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt index 10c7bb5b43..01924048e8 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt @@ -8,12 +8,14 @@ import androidx.core.content.ContextCompat.getColor import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.squareup.picasso.Picasso import com.tangem.Message import com.tangem.tap.domain.TwinCardNumber import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.features.details.redux.twins.CreateTwinWallet import com.tangem.tap.features.details.redux.twins.CreateTwinWalletStep +import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_details_twin_cards.* @@ -56,6 +58,18 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards), toolbar.setNavigationOnClickListener { store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel) } + + Picasso.get() + .load(Artwork.TWIN_CARD_1) + .placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_card_1) + + Picasso.get() + .load(Artwork.TWIN_CARD_2) + .placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_card_2) } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/twins/TwinWalletWarningFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/twins/TwinWalletWarningFragment.kt index 9896b988f7..40d31fc11e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/twins/TwinWalletWarningFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/twins/TwinWalletWarningFragment.kt @@ -5,12 +5,15 @@ import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import com.squareup.picasso.Picasso import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.twins.CreateTwinWallet +import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_details_twin_cards_warning.* +import kotlinx.android.synthetic.main.layout_twin_cards_orange.* class TwinWalletWarningFragment : Fragment(R.layout.fragment_details_twin_cards_warning) { @@ -35,6 +38,17 @@ class TwinWalletWarningFragment : Fragment(R.layout.fragment_details_twin_cards_ null, createTwinWallet = CreateTwinWallet.RecreateWallet )) } + Picasso.get() + .load(Artwork.TWIN_CARD_1) + .placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_twin_card_1) + + Picasso.get() + .load(Artwork.TWIN_CARD_2) + .placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_twin_card_2) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt index 05436a495a..7fe82a18f5 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt @@ -11,6 +11,7 @@ import com.tangem.tap.common.extensions.toFormattedString import com.tangem.tap.common.extensions.toQrCode import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapError +import com.tangem.tap.domain.TwinCardNumber import com.tangem.tap.domain.getFirstToken import com.tangem.tap.features.wallet.models.removeUnknownTransactions import com.tangem.tap.features.wallet.models.toPendingTransactions @@ -164,6 +165,12 @@ private fun internalReduce(action: Action, state: AppState): WalletState { 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 + } } else { Artwork.DEFAULT_IMG_URL } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 7593182093..29ef153b3d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -93,6 +93,8 @@ data class Artwork( const val MARTA_CARD_URL = "https://app.tangem.com/cards/card_tg083.png" const val SERGIO_CARD_ID = "BC01" const val MARTA_CARD_ID = "BC02" + const val TWIN_CARD_1 = "https://app.tangem.com/cards/card_tg085.png" + const val TWIN_CARD_2 = "https://app.tangem.com/cards/card_tg086.png" } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt index 799b4e0789..dde5046558 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt @@ -5,12 +5,15 @@ import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import com.squareup.picasso.Picasso import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_twin_cards.* +import kotlinx.android.synthetic.main.layout_twin_cards.* class TwinsOnboardingFragment : Fragment(R.layout.fragment_twin_cards) { @@ -36,6 +39,18 @@ class TwinsOnboardingFragment : Fragment(R.layout.fragment_twin_cards) { tv_twin_cards_description_1.text = text setOnClickListeners() + + Picasso.get() + .load(Artwork.TWIN_CARD_1) + .placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_twin_card_1) + + Picasso.get() + .load(Artwork.TWIN_CARD_2) + .placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_twin_card_2) } private fun setOnClickListeners() { From 8d41a63361228d0feebd83a8cd63e996cf83dcad Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 3 Dec 2020 19:24:33 +0300 Subject: [PATCH 03/42] Updated on 2026-08-14 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index aab2ec4bb8..c1faaf0498 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,8 +72,8 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' implementation 'com.tangem:blockchain:1.119.0' - implementation 'com.tangem:core:1.86.0' - implementation 'com.tangem:sdk:1.86.0' + implementation 'com.tangem:core:1.87.0' + implementation 'com.tangem:sdk:1.87.0' // WebView implementation "androidx.browser:browser:1.2.0" From e3d0d7e212e09225981ef73aaf9255a382b4df0a Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Dec 2020 11:48:21 +0300 Subject: [PATCH 04/42] Updated on 2026-08-14 --- .../tangem/tap/domain/twins/TwinsHelper.kt | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 ddb6d6854b..7492bca931 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 @@ -8,10 +8,10 @@ class TwinsHelper { fun getTwinCardNumber(cardId: String): TwinCardNumber? { return when { - firstCardBatches.map { cardId.startsWith(it) }.contains(true) -> { + firstCardSeries.map { cardId.startsWith(it) }.contains(true) -> { TwinCardNumber.First } - secondCardBatches.map { cardId.startsWith(it) }.contains(true) -> { + secondCardSeries.map { cardId.startsWith(it) }.contains(true) -> { TwinCardNumber.Second } else -> { @@ -21,23 +21,23 @@ class TwinsHelper { } fun getTwinsCardId(cardId: String): String? { - val cardIdWithNewBatch = when (getTwinCardNumber(cardId) ?: return null) { + val cardIdWithNewSeries = when (getTwinCardNumber(cardId) ?: return null) { TwinCardNumber.First -> { - val batchIndex = if (cardId.startsWith(firstCardBatches[1])) 1 else 2 - cardId.replace(firstCardBatches[batchIndex], secondCardBatches[batchIndex]) + val index = if (cardId.startsWith(firstCardSeries[0])) 0 else 1 + cardId.replace(firstCardSeries[index], secondCardSeries[index]) } TwinCardNumber.Second -> { - val batchIndex = if (cardId.startsWith(secondCardBatches[1])) 1 else 2 - cardId.replace(secondCardBatches[batchIndex], firstCardBatches[batchIndex]) + val index = if (cardId.startsWith(secondCardSeries[0])) 0 else 1 + cardId.replace(secondCardSeries[index], firstCardSeries[index]) } } - val cardIdWithoutChecksum = cardIdWithNewBatch.dropLast(1) + val cardIdWithoutChecksum = cardIdWithNewSeries.dropLast(1) val checkSum = cardIdWithoutChecksum.calculateLuhn() return cardIdWithoutChecksum + checkSum } - private val firstCardBatches = listOf("CB61", "CB64") - private val secondCardBatches = listOf("CB62", "CB65") + private val firstCardSeries = listOf("CB61", "CB64") + private val secondCardSeries = listOf("CB62", "CB65") } } From 737e55b49b6e6af43410e3ea5df361b0024a8fb6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Dec 2020 11:50:00 +0300 Subject: [PATCH 05/42] Updated on 2026-08-14 --- .../java/com/tangem/tap/domain/TapWalletManager.kt | 1 + .../java/com/tangem/tap/domain/tasks/ScanNoteTask.kt | 2 +- .../com/tangem/tap/domain/twins/TwinCardsManager.kt | 1 - .../java/com/tangem/tap/domain/twins/TwinsHelper.kt | 2 +- .../tangem/tap/features/details/redux/DetailsAction.kt | 2 +- .../tap/features/details/redux/DetailsReducer.kt | 2 +- .../details/redux/twins/CreateTwinWalletState.kt | 2 +- .../details/ui/twins/CreateTwinWalletFragment.kt | 2 +- .../tangem/tap/features/wallet/redux/WalletAction.kt | 2 +- .../tap/features/wallet/redux/WalletMiddleware.kt | 2 +- .../tangem/tap/features/wallet/redux/WalletReducer.kt | 2 +- .../tangem/tap/features/wallet/redux/WalletState.kt | 10 +++++----- .../tangem/tap/features/wallet/ui/WalletFragment.kt | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) 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 11fa152761..6f5b4eb380 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -16,6 +16,7 @@ import com.tangem.tap.domain.config.ConfigManager import com.tangem.tap.domain.extensions.amountToCreateAccount import com.tangem.tap.domain.extensions.isNoAccountError import com.tangem.tap.domain.tasks.ScanNoteResponse +import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tap.features.send.redux.AddressPayIdActionUi import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity 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 1f0c9bcd06..1e0b0dc71e 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 @@ -20,7 +20,7 @@ import com.tangem.common.tlv.Tlv import com.tangem.common.tlv.TlvDecoder import com.tangem.common.tlv.TlvTag import com.tangem.tap.domain.TapSdkError -import com.tangem.tap.domain.TwinsHelper +import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tasks.ScanTask data class ScanNoteResponse( 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 0255ed6f5a..f33030c138 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 @@ -12,7 +12,6 @@ import com.tangem.common.extensions.toHexString import com.tangem.common.tlv.TlvEncoder import com.tangem.common.tlv.TlvTag import com.tangem.common.tlv.serialize -import com.tangem.tap.domain.TwinsHelper import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.tangemSdkManager 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 7492bca931..c14680c6dd 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,4 +1,4 @@ -package com.tangem.tap.domain +package com.tangem.tap.domain.twins import com.tangem.tap.common.extensions.isEven 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 fe8c56708e..8a8fcd36d0 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 @@ -5,8 +5,8 @@ import com.tangem.blockchain.common.Wallet import com.tangem.commands.common.card.Card import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.common.redux.global.FiatCurrencyName -import com.tangem.tap.domain.TwinCardNumber import com.tangem.tap.domain.tasks.ScanNoteResponse +import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.details.redux.twins.CreateTwinWallet import com.tangem.tap.network.coinmarketcap.FiatCurrency import com.tangem.wallet.R 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 58997e57b6..e94971f658 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 @@ -6,8 +6,8 @@ import com.tangem.commands.common.card.masks.Product import com.tangem.commands.common.card.masks.Settings import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapWorkarounds -import com.tangem.tap.domain.TwinsHelper import com.tangem.tap.domain.extensions.toSendableAmounts +import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tap.features.details.redux.twins.CreateTwinWalletReducer import com.tangem.tap.features.details.redux.twins.CreateTwinWalletState import org.rekotlin.Action diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletState.kt index d42808e26e..488ac431bc 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletState.kt @@ -1,7 +1,7 @@ package com.tangem.tap.features.details.redux.twins -import com.tangem.tap.domain.TwinCardNumber import com.tangem.tap.domain.tasks.ScanNoteResponse +import com.tangem.tap.domain.twins.TwinCardNumber data class CreateTwinWalletState( val scanResponse: ScanNoteResponse?, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt index 01924048e8..3d4552c09d 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt @@ -10,7 +10,7 @@ import androidx.transition.TransitionInflater import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.squareup.picasso.Picasso import com.tangem.Message -import com.tangem.tap.domain.TwinCardNumber +import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.features.details.redux.twins.CreateTwinWallet 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 58ffdb8acc..0656a9583f 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 @@ -9,7 +9,7 @@ import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.TwinCardNumber +import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.wallet.R import org.rekotlin.Action import java.math.BigDecimal diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index bdd1a724cb..94c96264e1 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -20,8 +20,8 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapError import com.tangem.tap.domain.TopUpHelper -import com.tangem.tap.domain.TwinsHelper import com.tangem.tap.domain.extensions.toSendableAmounts +import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.twins.CreateTwinWallet import com.tangem.tap.features.send.redux.PrepareSendScreen diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt index 7fe82a18f5..533121bbe8 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt @@ -11,8 +11,8 @@ import com.tangem.tap.common.extensions.toFormattedString import com.tangem.tap.common.extensions.toQrCode import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.TwinCardNumber import com.tangem.tap.domain.getFirstToken +import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.wallet.models.removeUnknownTransactions import com.tangem.tap.features.wallet.models.toPendingTransactions import com.tangem.tap.features.wallet.ui.BalanceStatus diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 29ef153b3d..29b239d41e 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -7,7 +7,7 @@ import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.address.AddressType import com.tangem.tap.common.entities.Button import com.tangem.tap.common.redux.global.CryptoCurrencyName -import com.tangem.tap.domain.TwinCardNumber +import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.ui.BalanceWidgetData import org.rekotlin.StateType @@ -105,8 +105,8 @@ data class TopUpState( ) data class TwinCardsState( - val secondCardId: String?, - val cardNumber: TwinCardNumber?, - val showTwinOnboarding: Boolean, - val isCreatingTwinCardsAllowed: Boolean + val secondCardId: String?, + val cardNumber: TwinCardNumber?, + val showTwinOnboarding: Boolean, + val isCreatingTwinCardsAllowed: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 6e921e5b9b..20db7eb00e 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -18,7 +18,7 @@ import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction -import com.tangem.tap.domain.TwinCardNumber +import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.wallet.redux.* import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog From 41a8573cdbf79c31c94ccc6e410b92182ddc0c78 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Dec 2020 11:54:18 +0300 Subject: [PATCH 06/42] Updated on 2026-08-14 From 79db1feb0d95e690c87a59bbd10c87e71b4cc394 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Dec 2020 16:51:21 +0300 Subject: [PATCH 07/42] Updated on 2026-08-14 --- .../layout/fragment_details_twin_cards_warning.xml | 10 +++++++++- app/src/main/res/layout/fragment_twin_cards.xml | 11 +++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/fragment_details_twin_cards_warning.xml b/app/src/main/res/layout/fragment_details_twin_cards_warning.xml index 35a4fdcf5a..1343fbe116 100644 --- a/app/src/main/res/layout/fragment_details_twin_cards_warning.xml +++ b/app/src/main/res/layout/fragment_details_twin_cards_warning.xml @@ -13,14 +13,22 @@ android:layout_height="match_parent" android:layout_marginBottom="33dp"> + + + + + app:layout_constraintStart_toStartOf="parent"/> Date: Fri, 4 Dec 2020 16:53:04 +0300 Subject: [PATCH 08/42] Updated on 2026-08-14 --- .../features/details/ui/twins/CreateTwinWalletFragment.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt index 3d4552c09d..a8cc0f892e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt @@ -110,7 +110,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards), tv_step_number.text = getString(R.string.details_twins_recreate_step_format, "2") - v_step_1.setBackgroundColor(defaultColor) + v_step_1.setBackgroundColor(selectedColor) v_step_2.setBackgroundColor(selectedColor) v_step_3.setBackgroundColor(defaultColor) btn_tap.setOnClickListener { @@ -128,8 +128,8 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards), tv_step_number.text = getString(R.string.details_twins_recreate_step_format, "3") - v_step_1.setBackgroundColor(defaultColor) - v_step_2.setBackgroundColor(defaultColor) + v_step_1.setBackgroundColor(selectedColor) + v_step_2.setBackgroundColor(selectedColor) v_step_3.setBackgroundColor(selectedColor) btn_tap.setOnClickListener { store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchThirdStep( From decc341529a9dafdf544c2656a4209daa40750f3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Dec 2020 17:18:20 +0300 Subject: [PATCH 09/42] Updated on 2026-08-14 --- .../java/com/tangem/tap/domain/config/ConfigManager.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index 49a2af61f1..00bd1926bd 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -28,11 +28,12 @@ class ConfigManager( localLoader.loadConfig { config -> config.features?.forEach { setupFeature(it.name, it.value) } config.configValues?.forEach { setupKey(it.name, it.value) } - } - remoteLoader.loadConfig { config -> - config.features?.forEach { setupFeature(it.name, it.value) } onComplete?.invoke() } +// remoteLoader.loadConfig { config -> +// config.features?.forEach { setupFeature(it.name, it.value) } +// onComplete?.invoke() +// } } fun turnOff(name: String) { From 735a3ced4073ccb06697f7fb11065434681ee615 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Dec 2020 17:22:05 +0300 Subject: [PATCH 10/42] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c1faaf0498..f39f7ed5aa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,7 +71,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' - implementation 'com.tangem:blockchain:1.119.0' + implementation 'com.tangem:blockchain:1.121.0' implementation 'com.tangem:core:1.87.0' implementation 'com.tangem:sdk:1.87.0' From 0c78788a568a5bf3d7b7b07a70796f6667e30dde Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 7 Dec 2020 16:51:17 +0300 Subject: [PATCH 11/42] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/domain/twins/TwinsHelper.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 c14680c6dd..62bf089c7a 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 @@ -42,7 +42,7 @@ class TwinsHelper { } private fun String.calculateLuhn(): Int { - return 10 - this.reversed() + val checksum = this.reversed() .mapIndexed { index, c -> val digit = if (c in '0'..'9') c - '0' else c - 'A' if (!index.isEven()) { @@ -51,8 +51,9 @@ private fun String.calculateLuhn(): Int { val newDigit = digit * 2 if (newDigit >= 10) newDigit - 9 else newDigit } - } - .sum() % 10 + }.sum() + .rem(10) + return (10 - checksum) % 10 } enum class TwinCardNumber(val number: Int) { From 336a49a63ca97b3d8a12df917b1eed0eff6141a1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 7 Dec 2020 18:17:58 +0300 Subject: [PATCH 12/42] Updated on 2026-08-14 --- .../features/details/redux/twins/CreateTwinWalletMiddleware.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt index 279ae9a5c0..1f42e8203f 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt @@ -34,7 +34,7 @@ class CreateTwinWalletMiddleware { } is DetailsAction.CreateTwinWalletAction.Cancel.Confirm -> { twinsManager = null - store.dispatch(NavigationAction.PopBackTo()) + store.dispatch(NavigationAction.PopBackTo(AppScreen.Home)) } is DetailsAction.CreateTwinWalletAction.LaunchFirstStep -> { store.state.globalState.scanNoteResponse?.let { From c31e826d713ba2b85e890edd86bf761d1fcb472e Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 7 Dec 2020 18:26:53 +0300 Subject: [PATCH 13/42] Updated on 2026-08-14 --- .../ui/twins/CreateTwinWalletFragment.kt | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt index a8cc0f892e..7dc481b077 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt @@ -147,16 +147,21 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards), tv_twin_title.text = getString(R.string.details_twins_recreate_title_format, cardNumber) if (state.createTwinWalletState?.showAlert == true) { - dialog = MaterialAlertDialogBuilder(requireContext()) - .setMessage(R.string.details_twins_recreate_alert) - .setPositiveButton(R.string.common_ok) { _, _ -> - store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel.Confirm) - } - .setNegativeButton(R.string.common_cancel) { _, _ -> - store.dispatch(DetailsAction.CreateTwinWalletAction.HideAlert) - } - .create() - dialog?.show() + if (dialog == null) { + dialog = MaterialAlertDialogBuilder(requireContext()) + .setMessage(R.string.details_twins_recreate_alert) + .setPositiveButton(R.string.common_ok) { _, _ -> + store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel.Confirm) + } + .setNegativeButton(R.string.common_cancel) { _, _ -> + dialog?.cancel() + } + .setOnCancelListener { + store.dispatch(DetailsAction.CreateTwinWalletAction.HideAlert) + } + .create() + dialog?.show() + } } else { dialog?.cancel() dialog = null From 42ba2512cd8d1d09335f24a9db4fd6cc692817a3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 7 Dec 2020 18:31:50 +0300 Subject: [PATCH 14/42] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1e0b0dc71e..b51110845a 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 @@ -89,7 +89,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable) -> Unit ) { - ReadFileDataCommand(readPrivateFiles = true).run(session) { filesResult -> + ReadFileDataCommand().run(session) { filesResult -> when (filesResult) { is CompletionResult.Success -> { val decoder = Tlv.deserialize(filesResult.data.fileData)?.let { TlvDecoder(it) } From 89fa5f5f7c6d4c01f052b155d181e9786a3cc9ab Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 8 Dec 2020 12:27:26 +0000 Subject: [PATCH 15/42] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index f39f7ed5aa..243ab4ed96 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,7 +71,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' - implementation 'com.tangem:blockchain:1.121.0' + implementation 'com.tangem:blockchain:1.122.0' implementation 'com.tangem:core:1.87.0' implementation 'com.tangem:sdk:1.87.0' From 17dae34fb22d26e4ee3a0da16a2ee8ac2ca3b010 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 13:46:38 +0300 Subject: [PATCH 16/42] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 b51110845a..9af980f7d8 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 @@ -116,8 +116,9 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable Date: Wed, 9 Dec 2020 13:53:19 +0300 Subject: [PATCH 17/42] Updated on 2026-08-14 --- app/src/main/res/layout/layout_address.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/layout/layout_address.xml b/app/src/main/res/layout/layout_address.xml index 699cd908ed..28f45a220f 100644 --- a/app/src/main/res/layout/layout_address.xml +++ b/app/src/main/res/layout/layout_address.xml @@ -153,7 +153,8 @@ android:layout_margin="16dp" android:src="@drawable/ic_payid" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/v_payid_divider" /> + app:layout_constraintTop_toBottomOf="@id/v_payid_divider" + app:layout_constraintBottom_toBottomOf="parent"/> + tools:text="romafdffdfdfn$payid.tangem.com" /> Date: Wed, 9 Dec 2020 14:42:35 +0300 Subject: [PATCH 18/42] Updated on 2026-08-14 --- .../features/send/redux/middlewares/AddressPayIdMiddleware.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 74fdac0d5d..95255e9e42 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 @@ -117,7 +117,7 @@ internal class AddressPayIdMiddleware { private fun isValidBlockchainAddressAndNotTheSameAsWallet(wallet: Wallet, address: String): Error? { return if (wallet.blockchain.validateAddress(address)) { - if (wallet.address != address) { + if (wallet.addresses.all { it.value != address } ) { null } else { Error.ADDRESS_SAME_AS_WALLET From abba81ed418773984bb3de79f2bf6d83e36ca825 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 15:24:50 +0300 Subject: [PATCH 19/42] Updated on 2026-08-14 --- app/src/main/assets/features_dev.json | 4 ++++ app/src/main/assets/features_prod.json | 4 ++++ .../main/java/com/tangem/tap/domain/TapWalletManager.kt | 6 +++++- .../java/com/tangem/tap/domain/config/ConfigManager.kt | 8 ++++++++ .../tangem/tap/features/send/redux/SendScreenAction.kt | 2 +- .../send/redux/middlewares/AddressPayIdMiddleware.kt | 2 +- .../features/send/redux/reducers/AddressPayIdReducer.kt | 2 +- .../tap/features/send/redux/states/AddressPayIdState.kt | 2 +- .../send/ui/stateSubscribers/SendStateSubscriber.kt | 2 +- 9 files changed, 26 insertions(+), 6 deletions(-) diff --git a/app/src/main/assets/features_dev.json b/app/src/main/assets/features_dev.json index 236d0285bd..d6feffa030 100644 --- a/app/src/main/assets/features_dev.json +++ b/app/src/main/assets/features_dev.json @@ -3,6 +3,10 @@ "name": "isWalletPayIdEnabled", "value": true }, + { + "name": "isSendingToPayIdEnabled", + "value": true + }, { "name": "isTopUpEnabled", "value": true diff --git a/app/src/main/assets/features_prod.json b/app/src/main/assets/features_prod.json index 236d0285bd..d6feffa030 100644 --- a/app/src/main/assets/features_prod.json +++ b/app/src/main/assets/features_prod.json @@ -3,6 +3,10 @@ "name": "isWalletPayIdEnabled", "value": true }, + { + "name": "isSendingToPayIdEnabled", + "value": true + }, { "name": "isTopUpEnabled", "value": true 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 6f5b4eb380..07eca76467 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -1,5 +1,6 @@ package com.tangem.tap.domain +import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager @@ -17,7 +18,6 @@ import com.tangem.tap.domain.extensions.amountToCreateAccount import com.tangem.tap.domain.extensions.isNoAccountError import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.domain.twins.TwinsHelper -import com.tangem.tap.features.send.redux.AddressPayIdActionUi import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.network.coinmarketcap.CoinMarketCapService @@ -87,7 +87,11 @@ class TapWalletManager { val configManager = store.state.globalState.configManager if (TapWorkarounds.isStart2Coin) { configManager?.turnOff(ConfigManager.isWalletPayIdEnabled) + configManager?.turnOff(ConfigManager.isSendingToPayIdEnabled) configManager?.turnOff(ConfigManager.isTopUpEnabled) + } else if (data.walletManager?.wallet?.blockchain == Blockchain.Bitcoin + || data.card.cardData?.blockchainName == Blockchain.Bitcoin.id){ + configManager?.turnOff(ConfigManager.isWalletPayIdEnabled) } else { configManager?.resetToDefault(ConfigManager.isWalletPayIdEnabled) configManager?.resetToDefault(ConfigManager.isTopUpEnabled) diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index 00bd1926bd..c9b0d20151 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -10,6 +10,7 @@ data class Config( val moonPayApiKey: String = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE", val moonPayApiSecretKey: String = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C", val isWalletPayIdEnabled: Boolean = true, + val isSendingToPayIdEnabled: Boolean = true, val isTopUpEnabled: Boolean = false, val isCreatingTwinCardsAllowed: Boolean = false ) @@ -39,6 +40,7 @@ class ConfigManager( fun turnOff(name: String) { when (name) { isWalletPayIdEnabled -> config = config.copy(isWalletPayIdEnabled = false) + isSendingToPayIdEnabled -> config = config.copy(isSendingToPayIdEnabled = false) isTopUpEnabled -> config = config.copy(isTopUpEnabled = false) isCreatingTwinCardsAllowed -> config = config.copy(isCreatingTwinCardsAllowed = false) } @@ -47,6 +49,7 @@ class ConfigManager( fun resetToDefault(name: String) { when (name) { isWalletPayIdEnabled -> config = config.copy(isWalletPayIdEnabled = defaultConfig.isWalletPayIdEnabled) + isSendingToPayIdEnabled -> config = config.copy(isSendingToPayIdEnabled = defaultConfig.isSendingToPayIdEnabled) isTopUpEnabled -> config = config.copy(isTopUpEnabled = defaultConfig.isTopUpEnabled) isCreatingTwinCardsAllowed -> config = config.copy(isCreatingTwinCardsAllowed = defaultConfig.isCreatingTwinCardsAllowed) @@ -61,6 +64,10 @@ class ConfigManager( config = config.copy(isWalletPayIdEnabled = newValue) defaultConfig = defaultConfig.copy(isWalletPayIdEnabled = newValue) } + isSendingToPayIdEnabled -> { + config = config.copy(isSendingToPayIdEnabled = newValue) + defaultConfig = defaultConfig.copy(isSendingToPayIdEnabled = newValue) + } isTopUpEnabled -> { config = config.copy(isTopUpEnabled = newValue) defaultConfig = defaultConfig.copy(isTopUpEnabled = newValue) @@ -91,6 +98,7 @@ class ConfigManager( companion object { const val isWalletPayIdEnabled = "isWalletPayIdEnabled" + const val isSendingToPayIdEnabled = "isSendingToPayIdEnabled" const val isCreatingTwinCardsAllowed = "isCreatingTwinCardsAllowed" const val isTopUpEnabled = "isTopUpEnabled" const val coinMarketCapKey = "coinMarketCapKey" diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index e54f0f07dc..8a22ed35b0 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -33,7 +33,7 @@ sealed class AddressPayIdActionUi : SendScreenActionUi { object CheckAddressPayId : AddressPayIdActionUi() data class SetTruncateHandler(val handler: (String) -> String) : AddressPayIdActionUi() data class TruncateOrRestore(val truncate: Boolean) : AddressPayIdActionUi() - data class ChangePayIdState(val walletPayIdEnabled: Boolean): AddressPayIdActionUi() + data class ChangePayIdState(val sendingToPayIdEnabled: Boolean): AddressPayIdActionUi() } sealed class AddressPayIdVerifyAction : SendScreenAction { 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 95255e9e42..4380bdbf49 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 @@ -160,6 +160,6 @@ internal class AddressPayIdMiddleware { } private fun isPayIdEnabled(): Boolean { - return store.state.globalState.configManager?.config?.isWalletPayIdEnabled ?: false + return store.state.globalState.configManager?.config?.isSendingToPayIdEnabled ?: false } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt index d7a1c97f10..bca0259bee 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt @@ -30,7 +30,7 @@ class AddressPayIdReducer : SendInternalReducer { is AddressPayIdActionUi.PasteAddressPayId -> return sendState is AddressPayIdActionUi.CheckClipboard -> return sendState is AddressPayIdActionUi.CheckAddressPayId -> return sendState - is AddressPayIdActionUi.ChangePayIdState -> state.copy(walletPayIdEnabled = action.walletPayIdEnabled) + is AddressPayIdActionUi.ChangePayIdState -> state.copy(sendingToPayIdEnabled = action.sendingToPayIdEnabled) } return updateLastState(sendState.copy(addressPayIdState = result), result) } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt index b7a1622789..0ba27e4466 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt @@ -9,7 +9,7 @@ data class AddressPayIdState( val recipientWalletAddress: String? = null, val error: AddressPayIdVerifyAction.Error? = null, val truncateHandler: ((String) -> String)? = null, - val walletPayIdEnabled: Boolean = false, + val sendingToPayIdEnabled: Boolean = false, val pasteIsEnabled: Boolean = false ) : SendScreenState { diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 087c63af7a..711493fb25 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -104,7 +104,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val til = fg.tilAddressOrPayId val parsedError = parseError(til.context, state.error) - val hintResId = if (state.walletPayIdEnabled) { + val hintResId = if (state.sendingToPayIdEnabled) { R.string.send_destination_hint_address_payid }else { R.string.send_destination_hint_address From 044c9b98672d5e2634508667d910fda065f6659c Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 15:25:40 +0300 Subject: [PATCH 20/42] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/domain/TapWalletManager.kt | 2 -- .../tap/features/send/redux/middlewares/SendMiddleware.kt | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-) 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 07eca76467..590d8bd92c 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -99,8 +99,6 @@ class TapWalletManager { withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) store.dispatch(GlobalAction.SaveScanNoteResponse(data)) - store.dispatch(AddressPayIdActionUi.ChangePayIdState(configManager?.config?.isWalletPayIdEnabled - ?: false)) if (data.card.cardData?.productMask?.contains(Product.TwinCard) == true) { val secondCardId = TwinsHelper.getTwinsCardId(data.card.cardId) val cardNumber = TwinsHelper.getTwinCardNumber(data.card.cardId) 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 1c7db4b842..ecc52b09f3 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 @@ -39,6 +39,7 @@ val sendMiddleware: Middleware = { dispatch, appState -> is RequestFee -> RequestFeeMiddleware().handle(appState(), dispatch) is SendActionUi.SendAmountToRecipient -> verifyAndSendTransaction(action, appState(), dispatch) + is PrepareSendScreen -> setIfSendingToPayIdEnabled(appState(), dispatch) } nextDispatch(action) } @@ -185,3 +186,9 @@ fun createValidateTransactionError(errorList: EnumSet, walletM return TapError.ValidateTransactionErrors(tapErrors) { it.joinToString("\r\n") } } +private fun setIfSendingToPayIdEnabled(appState: AppState?, dispatch: (Action) -> Unit) { + val isSendingToPayIdEnabled = + appState?.globalState?.configManager?.config?.isSendingToPayIdEnabled ?: false + dispatch(AddressPayIdActionUi.ChangePayIdState(isSendingToPayIdEnabled)) +} + From 3afa7e8313997a978f9a376409d5de4827086d94 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 20:31:13 +0300 Subject: [PATCH 21/42] Updated on 2026-08-14 --- .../tangem/tap/features/wallet/redux/WalletMiddleware.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 94c96264e1..2d7032ba07 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -126,6 +126,12 @@ class WalletMiddleware { is CompletionResult.Success -> { store.state.globalState.tapWalletManager .onCardScanned(result.data, true) + if (store.state.walletState.twinCardsState != null) { + val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown() + if (showOnboarding) { + store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding)) + } + } } } } From 19de351c7d7d9c2fcfce1b8f29223551e8dee63a Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 20:39:18 +0300 Subject: [PATCH 22/42] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/common/extensions/Navigation.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index 603c004f13..28b425b515 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -18,13 +18,13 @@ import com.tangem.wallet.R fun FragmentActivity.openFragment(screen: AppScreen, addToBackStack: Boolean = true) { val transaction = this.supportFragmentManager.beginTransaction() - .replace( + .add( R.id.fragment_container, fragmentFactory(screen), screen.name ) if (addToBackStack && screen != AppScreen.Home) transaction.addToBackStack(null) - transaction.commit(); + transaction.commitAllowingStateLoss(); } fun FragmentActivity.popBackTo(screen: AppScreen?, inclusive: Boolean = false) { From b59f33f86bce56a027761715ba7e8e0d1f182140 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 20:52:31 +0300 Subject: [PATCH 23/42] Updated on 2026-08-14 --- .../tap/features/details/redux/twins/CreateTwinWalletReducer.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt index 6b9ff37533..9e04272b2b 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt @@ -30,6 +30,7 @@ class CreateTwinWalletReducer { createTwinWallet = action.createTwinWallet, showAlert = false, step = CreateTwinWalletStep.FirstStep, + allowRecreatingWallet = state.createTwinWalletState?.allowRecreatingWallet )) } DetailsAction.CreateTwinWalletAction.Cancel -> state From 7862c8978cea39587cf0159d30ffd70742a29a77 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 9 Dec 2020 20:54:49 +0300 Subject: [PATCH 24/42] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt | 3 +++ 1 file changed, 3 insertions(+) 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 590d8bd92c..d79796a64c 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -92,8 +92,11 @@ class TapWalletManager { } else if (data.walletManager?.wallet?.blockchain == Blockchain.Bitcoin || data.card.cardData?.blockchainName == Blockchain.Bitcoin.id){ configManager?.turnOff(ConfigManager.isWalletPayIdEnabled) + configManager?.resetToDefault(ConfigManager.isSendingToPayIdEnabled) + configManager?.resetToDefault(ConfigManager.isTopUpEnabled) } else { configManager?.resetToDefault(ConfigManager.isWalletPayIdEnabled) + configManager?.resetToDefault(ConfigManager.isSendingToPayIdEnabled) configManager?.resetToDefault(ConfigManager.isTopUpEnabled) } withContext(Dispatchers.Main) { From 6c0ee12698813d082a1e9ffa5dbc50a38f5f41a3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 10 Dec 2020 17:41:57 +0000 Subject: [PATCH 25/42] Updated on 2026-08-14 --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 243ab4ed96..3428782d33 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,9 +71,9 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' - implementation 'com.tangem:blockchain:1.122.0' - implementation 'com.tangem:core:1.87.0' - implementation 'com.tangem:sdk:1.87.0' + implementation 'com.tangem:blockchain:1.123.0' + implementation 'com.tangem:core:1.88.0' + implementation 'com.tangem:sdk:1.88.0' // WebView implementation "androidx.browser:browser:1.2.0" From 2522072ec6ca5216ded9f79726077a87de7c8cd5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 11 Dec 2020 11:01:36 +0300 Subject: [PATCH 26/42] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/MainActivity.kt | 2 +- .../com/tangem/tap/common/extensions/Navigation.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index ef059014db..ccc80bb0db 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -87,7 +87,7 @@ class MainActivity : AppCompatActivity() { val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) if (tag != null) { intent.action = null - store.dispatch(NavigationAction.NavigateTo(AppScreen.Home, false)) + store.dispatch(NavigationAction.NavigateTo(AppScreen.Home)) store.dispatch(HomeAction.ReadCard) } } diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index 28b425b515..8f6f36f982 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -18,13 +18,13 @@ import com.tangem.wallet.R fun FragmentActivity.openFragment(screen: AppScreen, addToBackStack: Boolean = true) { val transaction = this.supportFragmentManager.beginTransaction() - .add( - R.id.fragment_container, - fragmentFactory(screen), - screen.name - ) + if (screen == AppScreen.Home) { + transaction.replace(R.id.fragment_container, fragmentFactory(screen), screen.name) + } else { + transaction.add(R.id.fragment_container, fragmentFactory(screen), screen.name) + } if (addToBackStack && screen != AppScreen.Home) transaction.addToBackStack(null) - transaction.commitAllowingStateLoss(); + transaction.commitAllowingStateLoss() } fun FragmentActivity.popBackTo(screen: AppScreen?, inclusive: Boolean = false) { From abccafead4eaf8bb85d46761cbbd9f5a0927a0af Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 11 Dec 2020 13:13:08 +0300 Subject: [PATCH 27/42] Updated on 2026-08-14 --- .../com/tangem/tap/features/wallet/redux/WalletMiddleware.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 2d7032ba07..ca8e438a96 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -282,9 +282,10 @@ private class TopUpMiddleware { when (action) { is WalletAction.TopUpAction.TopUp -> { val config = store.state.globalState.configManager?.config ?: return + val defaultAddress = store.state.walletState.walletAddresses!!.list[0].address val url = TopUpHelper.getUrl( store.state.walletState.currencyData.currencySymbol!!, - store.state.walletState.walletAddresses!!.selectedAddress.address, + defaultAddress, config.moonPayApiKey, config.moonPayApiSecretKey ) From ea875f01126e7003cbb48ca3cfc6116389835715 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 11 Dec 2020 13:14:58 +0300 Subject: [PATCH 28/42] Updated on 2026-08-14 --- .../java/com/tangem/tap/common/extensions/Navigation.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index 8f6f36f982..56f0d70061 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -18,11 +18,7 @@ import com.tangem.wallet.R fun FragmentActivity.openFragment(screen: AppScreen, addToBackStack: Boolean = true) { val transaction = this.supportFragmentManager.beginTransaction() - if (screen == AppScreen.Home) { - transaction.replace(R.id.fragment_container, fragmentFactory(screen), screen.name) - } else { - transaction.add(R.id.fragment_container, fragmentFactory(screen), screen.name) - } + transaction.replace(R.id.fragment_container, fragmentFactory(screen), screen.name) if (addToBackStack && screen != AppScreen.Home) transaction.addToBackStack(null) transaction.commitAllowingStateLoss() } From 993e166299c5216d5f08448e3324b5e30ba9edd7 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 11 Dec 2020 13:24:00 +0300 Subject: [PATCH 29/42] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/MainActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index ccc80bb0db..2a20c88628 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -88,6 +88,7 @@ class MainActivity : AppCompatActivity() { if (tag != null) { intent.action = null store.dispatch(NavigationAction.NavigateTo(AppScreen.Home)) + store.dispatch(NavigationAction.PopBackTo(AppScreen.Home)) store.dispatch(HomeAction.ReadCard) } } From 77d33e794d8a8950910a6df665eb9203106748d1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 17 Dec 2020 15:20:32 +0300 Subject: [PATCH 30/42] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 d79796a64c..c26f2b36a2 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -107,8 +107,7 @@ class TapWalletManager { val cardNumber = TwinsHelper.getTwinCardNumber(data.card.cardId) if (secondCardId != null && cardNumber != null) { store.dispatch(WalletAction.TwinsAction.SetTwinCard( - secondCardId, cardNumber, - configManager?.config?.isCreatingTwinCardsAllowed ?: false + secondCardId, cardNumber, isCreatingTwinCardsAllowed = true )) } } From 16f6dcebb55baef5581190bbc0c39540a005a9d1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 12:20:06 +0300 Subject: [PATCH 31/42] Updated on 2026-08-14 --- app/src/main/assets/features_dev.json | 2 +- app/src/main/assets/features_prod.json | 2 +- .../tangem/tap/domain/tasks/ScanNoteTask.kt | 28 ++++----- .../domain/twins/CreateFirstTwinWalletTask.kt | 16 +---- .../twins/CreateSecondTwinWalletTask.kt | 26 ++++---- .../tap/domain/twins/TwinCardsManager.kt | 27 +++++---- .../twins/WriteProtectedIssuerDataTask.kt | 59 +++++++++++++++++++ .../layout/fragment_details_twin_cards.xml | 4 +- 8 files changed, 107 insertions(+), 57 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt diff --git a/app/src/main/assets/features_dev.json b/app/src/main/assets/features_dev.json index d6feffa030..e416a046a7 100644 --- a/app/src/main/assets/features_dev.json +++ b/app/src/main/assets/features_dev.json @@ -13,6 +13,6 @@ }, { "name": "isCreatingTwinCardsAllowed", - "value": false + "value": true } ] \ No newline at end of file diff --git a/app/src/main/assets/features_prod.json b/app/src/main/assets/features_prod.json index d6feffa030..e416a046a7 100644 --- a/app/src/main/assets/features_prod.json +++ b/app/src/main/assets/features_prod.json @@ -13,6 +13,6 @@ }, { "name": "isCreatingTwinCardsAllowed", - "value": false + "value": true } ] \ 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 9af980f7d8..f106f2a930 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 @@ -7,20 +7,16 @@ import com.tangem.TangemSdkError import com.tangem.blockchain.common.WalletManager 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.masks.Product -import com.tangem.commands.file.ReadFileDataCommand import com.tangem.commands.verifycard.VerifyCardCommand import com.tangem.commands.verifycard.VerifyCardResponse import com.tangem.common.CompletionResult -import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString -import com.tangem.common.tlv.Tlv -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag import com.tangem.tap.domain.TapSdkError -import com.tangem.tap.domain.twins.TwinsHelper +import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tasks.ScanTask data class ScanNoteResponse( @@ -75,7 +71,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable { callback(CompletionResult.Success(ScanNoteResponse( - walletManager, card, verifyResult.data + walletManager, card, verifyResult.data, publicKey ))) } is CompletionResult.Failure -> { @@ -89,20 +85,21 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable) -> Unit ) { - ReadFileDataCommand().run(session) { filesResult -> - when (filesResult) { + ReadIssuerDataCommand().run(session) { readDataResult -> + when (readDataResult) { is CompletionResult.Success -> { - val decoder = Tlv.deserialize(filesResult.data.fileData)?.let { TlvDecoder(it) } - val name = decoder?.decodeOptional(TlvTag.FileName) - if (name != null && name == TwinsHelper.TWIN_FILE_NAME) { - val publicKey = decoder.decodeOptional(TlvTag.FileData)?.toHexString() + val verified = TwinCardsManager.verifyTwinPublicKey( + readDataResult.data.issuerData, card.walletPublicKey + ) + if (verified) { + val twinPublicKey = readDataResult.data.issuerData.sliceArray(0 until 65) val walletManager = try { - WalletManagerFactory.makeMultisigWalletManager(card, publicKey!!.hexToBytes()) + WalletManagerFactory.makeMultisigWalletManager(card, twinPublicKey) } catch (exception: Exception) { callback(CompletionResult.Success(ScanNoteResponse(null, card))) return@run } - verifyCard(walletManager, card, publicKey, session, callback) + verifyCard(walletManager, card, twinPublicKey.toHexString(), session, callback) return@run } else { callback(CompletionResult.Success(ScanNoteResponse(null, card))) @@ -111,7 +108,6 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable callback(CompletionResult.Success(ScanNoteResponse(null, card))) } - } } 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 4b008408e6..7296c72a11 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 @@ -7,7 +7,6 @@ import com.tangem.commands.PurgeWalletCommand import com.tangem.commands.common.card.CardStatus import com.tangem.common.CompletionResult import com.tangem.tasks.CreateWalletTask -import com.tangem.tasks.file.DeleteFilesTask class CreateFirstTwinWalletTask : CardSessionRunnable { override val requiresPin2 = false @@ -18,24 +17,13 @@ class CreateFirstTwinWalletTask : CardSessionRunnable { when (response) { is CompletionResult.Success -> { session.environment.card = session.environment.card?.copy(status = CardStatus.Empty) - finishTask(session, callback) + CreateWalletTask().run(session) { callback(it) } } is CompletionResult.Failure -> callback(CompletionResult.Failure(response.error)) } } } else { - finishTask(session, callback) - } - } - - private fun finishTask(session: CardSession, callback: (result: CompletionResult) -> Unit) { - DeleteFilesTask().run(session) { deleteResponse -> - when (deleteResponse) { - is CompletionResult.Success -> - CreateWalletTask().run(session) { callback(it) } - is CompletionResult.Failure -> - callback(CompletionResult.Failure(deleteResponse.error)) - } + CreateWalletTask().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 4885e78f38..c3fde9061d 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 @@ -5,10 +5,9 @@ import com.tangem.CardSessionRunnable import com.tangem.commands.CreateWalletResponse import com.tangem.commands.PurgeWalletCommand import com.tangem.commands.common.card.CardStatus -import com.tangem.commands.file.WriteFileDataCommand import com.tangem.common.CompletionResult +import com.tangem.common.extensions.hexToBytes import com.tangem.tasks.CreateWalletTask -import com.tangem.tasks.file.DeleteFilesTask class CreateSecondTwinWalletTask(private val firstPublicKey: String) : CardSessionRunnable { override val requiresPin2 = true @@ -31,20 +30,23 @@ class CreateSecondTwinWalletTask(private val firstPublicKey: String) : CardSessi } private fun finishTask(session: CardSession, callback: (result: CompletionResult) -> Unit) { - DeleteFilesTask().run(session) { deleteResponse -> - when (deleteResponse) { + CreateWalletTask().run(session) { result -> + when (result) { is CompletionResult.Success -> { - val file = TwinCardsManager.createFileWithPublicKey(firstPublicKey) - WriteFileDataCommand(file).run(session) { result -> - when (result) { - is CompletionResult.Success -> CreateWalletTask().run(session, callback) - is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) + session.environment.card = + session.environment.card?.copy(status = CardStatus.Loaded) + WriteProtectedIssuerDataTask( + firstPublicKey.hexToBytes(), TwinCardsManager.issuerKeys + ).run(session) { writeResult -> + when (writeResult) { + is CompletionResult.Success -> callback(result) + is CompletionResult.Failure -> + callback(CompletionResult.Failure(writeResult.error)) } } } - is CompletionResult.Failure -> - callback(CompletionResult.Failure(deleteResponse.error)) + is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt index f33030c138..f63f2b1ea3 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,17 +1,14 @@ package com.tangem.tap.domain.twins +import com.tangem.KeyPair import com.tangem.Message import com.tangem.blockchain.common.WalletManagerFactory import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult -import com.tangem.commands.file.FileData -import com.tangem.commands.file.WriteFileDataCommand import com.tangem.common.CompletionResult import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString -import com.tangem.common.tlv.TlvEncoder -import com.tangem.common.tlv.TlvTag -import com.tangem.common.tlv.serialize +import com.tangem.crypto.CryptoUtils import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.tangemSdkManager @@ -54,7 +51,7 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) { suspend fun complete(message: Message): Result { val response = tangemSdkManager.runTaskAsync( - WriteFileDataCommand(createFileWithPublicKey(secondCardPublicKey!!)), + WriteProtectedIssuerDataTask(secondCardPublicKey!!.hexToBytes(), issuerKeys), currentCardId, message ) return when (response) { @@ -72,11 +69,19 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) { } companion object { - fun createFileWithPublicKey(publicKey: String): FileData { - val nameTlv = TlvEncoder().encode(TlvTag.FileName, "TwinPublicKey") - val pubKey = TlvEncoder().encode(TlvTag.FileData, publicKey.hexToBytes()) - val tlvs = listOf(nameTlv, pubKey).serialize() - return FileData.DataProtectedByPasscode(tlvs) + val issuerKeys = KeyPair( + privateKey = "F9F4C50636C9E6FC65F92655BD5C21C85A5F6A34DCD0F1E75FCEA1980FE242F5".hexToBytes(), + publicKey = ("048196AA4B410AC44A3B9CCE18E7BE226AEA070ACC83A9CF67540F" + + "AC49AF25129F6A538A28AD6341358E3C4F9963064F" + + "7E365372A651D374E5C23CDD37FD099BF2").hexToBytes() + ) + + fun verifyTwinPublicKey(issuerData: ByteArray, cardWalletPublicKey: ByteArray?): Boolean { + if (issuerData.size < 65) return false + val publicKey = issuerData.sliceArray(0 until 65) + val signedKey = issuerData.sliceArray(65 until issuerData.size) + return (cardWalletPublicKey != null && + CryptoUtils.verify(cardWalletPublicKey, publicKey, signedKey)) } } } \ 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 new file mode 100644 index 0000000000..30d3b688dd --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt @@ -0,0 +1,59 @@ +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.extensions.calculateSha256 +import com.tangem.common.extensions.guard +import com.tangem.common.files.FileHashHelper + +class WriteProtectedIssuerDataTask( + private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair +) : CardSessionRunnable { + override val requiresPin2 = true + + override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { + val hashes = arrayOf(twinPublicKey.calculateSha256()) + SignCommand(hashes).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(signResult.error)) + } + } + } + + private fun writeIssuerData( + 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 + } + val counter = (readResponse.issuerDataCounter ?: 0) + 1 + val data = twinPublicKey + cardSignature + val signedByIssuer = FileHashHelper.prepareHashes( + cardId, data, counter, issuerKeys.privateKey + ) + WriteIssuerDataCommand( + data, signedByIssuer.finalizingSignature!!, + counter, issuerKeys.publicKey + ).run(session, callback) + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_details_twin_cards.xml b/app/src/main/res/layout/fragment_details_twin_cards.xml index 02b5a83991..7549f32998 100644 --- a/app/src/main/res/layout/fragment_details_twin_cards.xml +++ b/app/src/main/res/layout/fragment_details_twin_cards.xml @@ -38,12 +38,12 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="8dp" - android:gravity="center" + android:gravity="start" android:text="@string/details_twins_recreate_step_format" android:textColor="@color/colorSecondary" android:textSize="20sp" + android:textStyle="bold" app:layout_constraintEnd_toEndOf="@+id/v_step_1" - app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@id/v_step_1" app:layout_constraintTop_toTopOf="parent" /> From 4b02556fe1453d8284a70066d0ce0a67250b3d79 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 12:54:47 +0300 Subject: [PATCH 32/42] Updated on 2026-08-14 --- .../tap/domain/twins/FinalizeTwinTask.kt | 31 +++++++++++++++++++ .../tap/domain/twins/TwinCardsManager.kt | 13 ++------ .../redux/twins/CreateTwinWalletMiddleware.kt | 6 ++-- 3 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt 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 new file mode 100644 index 0000000000..073c47b344 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/twins/FinalizeTwinTask.kt @@ -0,0 +1,31 @@ +package com.tangem.tap.domain.twins + +import com.tangem.CardSession +import com.tangem.CardSessionRunnable +import com.tangem.KeyPair +import com.tangem.commands.ReadCommand +import com.tangem.common.CompletionResult +import com.tangem.tap.domain.tasks.ScanNoteResponse +import com.tangem.tap.domain.tasks.ScanNoteTask + +class FinalizeTwinTask( + private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair + ) : CardSessionRunnable { + override val requiresPin2 = true + + override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { + WriteProtectedIssuerDataTask(twinPublicKey, issuerKeys).run(session) { result -> + when (result) { + is CompletionResult.Success -> { + ReadCommand().run(session) { readResult -> + when (readResult) { + is CompletionResult.Success -> ScanNoteTask(readResult.data).run(session, callback) + is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error)) + } + } + } + is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt index f63f2b1ea3..b5e221eb08 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 @@ -2,7 +2,6 @@ package com.tangem.tap.domain.twins import com.tangem.KeyPair import com.tangem.Message -import com.tangem.blockchain.common.WalletManagerFactory import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult import com.tangem.common.CompletionResult @@ -51,19 +50,11 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) { suspend fun complete(message: Message): Result { val response = tangemSdkManager.runTaskAsync( - WriteProtectedIssuerDataTask(secondCardPublicKey!!.hexToBytes(), issuerKeys), + FinalizeTwinTask(secondCardPublicKey!!.hexToBytes(), issuerKeys), currentCardId, message ) return when (response) { - is CompletionResult.Success -> { - val walletManager = WalletManagerFactory.makeMultisigWalletManager( - scanNoteResponse.card, secondCardPublicKey!!.hexToBytes() - ) - return Result.Success(scanNoteResponse.copy( - walletManager = walletManager, - secondTwinPublicKey = secondCardPublicKey - )) - } + is CompletionResult.Success -> Result.Success(response.data) is CompletionResult.Failure -> Result.failure(response.error) } } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt index 1f42e8203f..d4c2be1cf6 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt @@ -2,7 +2,6 @@ package com.tangem.tap.features.details.redux.twins import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult -import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.twins.TwinCardsManager @@ -93,8 +92,11 @@ class CreateTwinWalletMiddleware { } } is DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Success -> { - store.dispatch(GlobalAction.SaveScanNoteResponse(action.scanNoteResponse)) + scope.launch { + store.state.globalState.tapWalletManager.onCardScanned(action.scanNoteResponse) + } store.dispatch(NavigationAction.PopBackTo(AppScreen.Home)) + store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) } DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure -> { From 928d1cef1afaf4056d56642470fba6b0628ca333 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 13:03:24 +0300 Subject: [PATCH 33/42] Updated on 2026-08-14 --- .../tap/features/details/redux/DetailsAction.kt | 3 +++ .../redux/twins/CreateTwinWalletMiddleware.kt | 13 +++++++++++-- .../details/redux/twins/CreateTwinWalletReducer.kt | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) 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 8a8fcd36d0..fcf3fcdbea 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 @@ -46,6 +46,9 @@ sealed class DetailsAction : Action { sealed class CreateTwinWalletAction : DetailsAction() { object ShowWarning : CreateTwinWalletAction() + object NotEmpty : CreateTwinWalletAction(), NotificationAction { + override val messageResource = R.string.details_notification_erase_wallet_not_possible + } object ShowAlert : CreateTwinWalletAction() object HideAlert : CreateTwinWalletAction() data class Proceed( diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt index d4c2be1cf6..8ba375fea4 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt @@ -4,6 +4,7 @@ import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.scope @@ -16,8 +17,16 @@ class CreateTwinWalletMiddleware { var twinsManager: TwinCardsManager? = null fun handle(action: DetailsAction.CreateTwinWalletAction) { when (action) { - DetailsAction.CreateTwinWalletAction.ShowWarning -> - store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning)) + DetailsAction.CreateTwinWalletAction.ShowWarning -> { + val wallet = store.state.detailsState.wallet + val notEmpty = wallet?.recentTransactions?.isNullOrEmpty() != true || + wallet.amounts.toSendableAmounts().isNotEmpty() + if (notEmpty) { + store.dispatch(DetailsAction.CreateTwinWalletAction.NotEmpty) + } else { + store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning)) + } + } is DetailsAction.CreateTwinWalletAction.Proceed -> store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWallet)) is DetailsAction.CreateTwinWalletAction.Cancel -> { diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt index 9e04272b2b..1a7abc6398 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt @@ -12,6 +12,7 @@ class CreateTwinWalletReducer { DetailsAction.CreateTwinWalletAction.ShowWarning -> { state } + DetailsAction.CreateTwinWalletAction.NotEmpty -> state DetailsAction.CreateTwinWalletAction.ShowAlert -> { state.copy(createTwinWalletState = state.createTwinWalletState?.copy( showAlert = true From 2fd2ef699c23169204cc160a0fe331825eb401d8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 15:40:41 +0300 Subject: [PATCH 34/42] Updated on 2026-08-14 --- app/src/main/res/values/strings.xml | 6 +++--- app/src/main/res/values/strings_untranslated.xml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c90c4534da..6fe394b9ea 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,7 +25,7 @@ Scan Send - Create wallet + Create twin wallet Tangem Tap Choice wallet option @@ -37,8 +37,8 @@ Account is not created Load %1$s+ %2$s to create account - Empty card - Create wallet to start using Tangem card + Create twin wallet + Generate wallet keys on both cards to start using your Twins This card is not supported Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index dd823ac37c..f1597e5c14 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -14,11 +14,11 @@ this wallet. Card %s of 2 Re-create twin wallet - This action is irreversible. If, after deleting the old wallet, someone sends funds to it, then you will not be able to withdraw them. + This action is irreversible. You will not have access to the old wallet.\nThe wallet re-creation procedure consists of three steps. You must complete it to the end, otherwise you will have to start from the beginning. Re-create wallet Step %s Tap the #%s twin card - If the process of re-creating the wallet gets interrupted in any way, you’ll have to start over. + The wallet creation procedure consists of three steps. You must complete it to the end, otherwise you will have to start from the beginning. Tap the card #%s You have already started the process of recreating twin wallet. If you interrupt it, you won\'t be able to use your twin cards until you start it again and complete recreating the wallet. From 23211c69b0ef91a5d3645a2123144588a24a66ba Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 16:48:22 +0300 Subject: [PATCH 35/42] Updated on 2026-08-14 --- .../java/com/tangem/tap/domain/twins/TwinsHelper.kt | 12 ++++++++++++ .../tap/features/details/ui/DetailsFragment.kt | 13 ++++++++++++- .../tap/features/wallet/redux/WalletMiddleware.kt | 4 ++++ app/src/main/res/layout/fragment_details.xml | 11 +++++++---- 4 files changed, 35 insertions(+), 5 deletions(-) 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 62bf089c7a..32cbc3153f 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,5 +1,7 @@ package com.tangem.tap.domain.twins +import com.tangem.commands.common.card.Card +import com.tangem.commands.common.card.masks.Product import com.tangem.tap.common.extensions.isEven class TwinsHelper { @@ -63,4 +65,14 @@ enum class TwinCardNumber(val number: Int) { First -> Second Second -> First } +} + +fun Card.isTwinCard(): Boolean { + return this.cardData?.productMask?.contains(Product.TwinCard) == true +} + +fun Card.getTwinCardIdForUser(): String { + val twinCardId = this.cardId.substring(11..14) + val twinCardNumber = TwinsHelper.getTwinCardNumber(this.cardId)?.number ?: 1 + return "$twinCardId #$twinCardNumber" } \ No newline at end of file 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 6ad375022a..59cd043015 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 @@ -8,6 +8,8 @@ import androidx.transition.TransitionInflater import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.twins.getTwinCardIdForUser +import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.features.details.redux.SecurityOption @@ -61,11 +63,20 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber 0) { @@ -255,6 +257,8 @@ class WalletMiddleware { val card = store.state.globalState.scanNoteResponse?.card if (card == null || preferencesStorage.wasCardScannedBefore(card.cardId)) return + if (card.isTwinCard()) return + val validator = store.state.globalState.scanNoteResponse?.walletManager as? SignatureCountValidator scope.launch { diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index 65db1c16db..7a99598875 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -47,7 +47,7 @@ android:id="@+id/tv_card_id_title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingBottom="14dp" + android:paddingBottom="7dp" android:text="@string/details_row_title_cid" android:textColor="@color/darkGray6" android:textSize="16sp" @@ -59,7 +59,7 @@ android:id="@+id/tv_card_id" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingBottom="14dp" + android:paddingBottom="7dp" android:textColor="@color/darkGray1" android:textSize="16sp" app:layout_constraintEnd_toEndOf="parent" @@ -70,7 +70,8 @@ android:id="@+id/tv_issuer_title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingBottom="14dp" + android:paddingTop="7dp" + android:paddingBottom="7dp" android:text="@string/details_row_title_issuer" android:textColor="@color/darkGray6" android:textSize="16sp" @@ -81,7 +82,8 @@ android:id="@+id/tv_issuer" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingBottom="14dp" + android:paddingTop="7dp" + android:paddingBottom="7dp" android:textColor="@color/darkGray1" android:textSize="16sp" app:layout_constraintEnd_toEndOf="parent" @@ -92,6 +94,7 @@ android:id="@+id/tv_signed_hashes_title" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingTop="7dp" android:paddingBottom="7dp" android:text="@string/details_row_title_signed_hashes" android:textColor="@color/darkGray6" From 1d6c728e4d51f048d69f08c23292215dc4519839 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 17:18:43 +0300 Subject: [PATCH 36/42] Updated on 2026-08-14 --- .../features/details/redux/DetailsAction.kt | 9 ++++---- .../redux/twins/CreateTwinWalletMiddleware.kt | 2 +- .../redux/twins/CreateTwinWalletReducer.kt | 21 +++++++++---------- .../features/details/ui/DetailsFragment.kt | 5 ++++- .../ui/twins/TwinWalletWarningFragment.kt | 11 +++++++--- .../features/wallet/redux/WalletMiddleware.kt | 2 +- .../main/res/values/strings_untranslated.xml | 2 +- 7 files changed, 30 insertions(+), 22 deletions(-) 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 fcf3fcdbea..1e90daa2e1 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 @@ -45,15 +45,16 @@ sealed class DetailsAction : Action { } sealed class CreateTwinWalletAction : DetailsAction() { - object ShowWarning : CreateTwinWalletAction() + data class ShowWarning( + val twinCardNumber: TwinCardNumber?, + val createTwinWallet: CreateTwinWallet = CreateTwinWallet.RecreateWallet + ) : CreateTwinWalletAction() object NotEmpty : CreateTwinWalletAction(), NotificationAction { override val messageResource = R.string.details_notification_erase_wallet_not_possible } object ShowAlert : CreateTwinWalletAction() object HideAlert : CreateTwinWalletAction() - data class Proceed( - val twinCardNumber: TwinCardNumber?, val createTwinWallet: CreateTwinWallet - ) : CreateTwinWalletAction() + object Proceed: CreateTwinWalletAction() object Cancel : CreateTwinWalletAction() { object Confirm : CreateTwinWalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt index 8ba375fea4..c2b5853228 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt @@ -17,7 +17,7 @@ class CreateTwinWalletMiddleware { var twinsManager: TwinCardsManager? = null fun handle(action: DetailsAction.CreateTwinWalletAction) { when (action) { - DetailsAction.CreateTwinWalletAction.ShowWarning -> { + is DetailsAction.CreateTwinWalletAction.ShowWarning -> { val wallet = store.state.detailsState.wallet val notEmpty = wallet?.recentTransactions?.isNullOrEmpty() != true || wallet.amounts.toSendableAmounts().isNotEmpty() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt index 1a7abc6398..7de266d076 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletReducer.kt @@ -9,8 +9,15 @@ class CreateTwinWalletReducer { action: DetailsAction.CreateTwinWalletAction, state: DetailsState ): DetailsState { return when (action) { - DetailsAction.CreateTwinWalletAction.ShowWarning -> { - state + is DetailsAction.CreateTwinWalletAction.ShowWarning -> { + state.copy(createTwinWalletState = CreateTwinWalletState( + scanResponse = null, + twinCardNumber = action.twinCardNumber + ?: state.createTwinWalletState?.twinCardNumber, + createTwinWallet = action.createTwinWallet, + showAlert = false, + allowRecreatingWallet = state.createTwinWalletState?.allowRecreatingWallet + )) } DetailsAction.CreateTwinWalletAction.NotEmpty -> state DetailsAction.CreateTwinWalletAction.ShowAlert -> { @@ -24,15 +31,7 @@ class CreateTwinWalletReducer { )) } is DetailsAction.CreateTwinWalletAction.Proceed -> { - state.copy(createTwinWalletState = CreateTwinWalletState( - scanResponse = null, - twinCardNumber = action.twinCardNumber - ?: state.createTwinWalletState?.twinCardNumber, - createTwinWallet = action.createTwinWallet, - showAlert = false, - step = CreateTwinWalletStep.FirstStep, - allowRecreatingWallet = state.createTwinWalletState?.allowRecreatingWallet - )) + state } DetailsAction.CreateTwinWalletAction.Cancel -> state DetailsAction.CreateTwinWalletAction.Cancel.Confirm -> state 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 59cd043015..262482b360 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 @@ -13,6 +13,7 @@ import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.features.details.redux.SecurityOption +import com.tangem.tap.features.details.redux.twins.CreateTwinWallet import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_details.* @@ -84,7 +85,9 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber { if (store.state.walletState.twinCardsState != null) { - store.dispatch(DetailsAction.CreateTwinWalletAction.Proceed( + store.dispatch(DetailsAction.CreateTwinWalletAction.ShowWarning( store.state.globalState.scanNoteResponse?.card?.cardId?.let { TwinsHelper.getTwinCardNumber(it) }, diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index f1597e5c14..cbee4d51ec 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -18,7 +18,7 @@ this wallet. Re-create wallet Step %s Tap the #%s twin card - The wallet creation procedure consists of three steps. You must complete it to the end, otherwise you will have to start from the beginning. + The wallet creation procedure consists of three steps. You must complete it to the end, otherwise you will have to start from the beginning. Tap the card #%s You have already started the process of recreating twin wallet. If you interrupt it, you won\'t be able to use your twin cards until you start it again and complete recreating the wallet. From 555be3d3e47130dc147382d443e708d38c506cf5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 17:29:07 +0300 Subject: [PATCH 37/42] Updated on 2026-08-14 --- .../com/tangem/tap/features/wallet/ui/BalanceWidget.kt | 10 ++++++++-- .../tangem/tap/features/wallet/ui/WalletFragment.kt | 10 ++++++++-- app/src/main/res/values/strings.xml | 6 +++--- app/src/main/res/values/strings_untranslated.xml | 4 ++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index cc65bff46d..ce7fec6959 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -40,6 +40,7 @@ data class TokenData( class BalanceWidget( val fragment: Fragment, val data: BalanceWidgetData, + val isTwinCard: Boolean, ) { fun setup() { @@ -100,8 +101,13 @@ class BalanceWidget( BalanceStatus.EmptyCard -> { fragment.l_balance.hide() fragment.l_balance_error.show() - fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_empty_card) - fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_error_empty_card_subtitle) + if (isTwinCard) { + fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_empty_twin_card) + fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_error_empty_twin_card_subtitle) + } else { + fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_empty_card) + fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_error_empty_card_subtitle) + } } BalanceStatus.NoAccount -> { fragment.l_balance.hide() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 20db7eb00e..464764cf68 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -132,7 +132,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber R.string.wallet_button_send - is WalletMainButton.CreateWalletButton -> R.string.wallet_button_create_wallet + is WalletMainButton.CreateWalletButton -> { + if (state.twinCardsState == null) { + R.string.wallet_button_create_wallet + } else { + R.string.wallet_button_create_twin_wallet + } + } } btnConfirm.text = getString(buttonTitle) btnConfirm.isEnabled = state.mainButton.enabled diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6fe394b9ea..c90c4534da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,7 +25,7 @@ Scan Send - Create twin wallet + Create wallet Tangem Tap Choice wallet option @@ -37,8 +37,8 @@ Account is not created Load %1$s+ %2$s to create account - Create twin wallet - Generate wallet keys on both cards to start using your Twins + Empty card + Create wallet to start using Tangem card This card is not supported Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index f1597e5c14..617d2759dc 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -4,6 +4,10 @@ Compatibility Legacy + Create twin wallet + Create twin wallet + Generate wallet keys on both cards to start using your Twins + Tangem Twin One wallet. Two cards. This one that you are holding in your hands From f59c35616ef92134298d0a9f6305b8803a8664bb Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 17:52:19 +0300 Subject: [PATCH 38/42] Updated on 2026-08-14 --- .../java/com/tangem/tap/domain/twins/TwinsHelper.kt | 12 +++++++++--- .../wallet/ui/dialogs/TwinsOnboardingFragment.kt | 6 ++++-- 2 files changed, 13 insertions(+), 5 deletions(-) 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 32cbc3153f..a1ca7dcc53 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 @@ -38,6 +38,14 @@ class TwinsHelper { return cardIdWithoutChecksum + checkSum } + fun getTwinCardIdForUser(cardId: String): String { + if (cardId.length < 16) return cardId + + val twinCardId = cardId.substring(11..14) + val twinCardNumber = getTwinCardNumber(cardId)?.number ?: 1 + return "$twinCardId #$twinCardNumber" + } + private val firstCardSeries = listOf("CB61", "CB64") private val secondCardSeries = listOf("CB62", "CB65") } @@ -72,7 +80,5 @@ fun Card.isTwinCard(): Boolean { } fun Card.getTwinCardIdForUser(): String { - val twinCardId = this.cardId.substring(11..14) - val twinCardNumber = TwinsHelper.getTwinCardNumber(this.cardId)?.number ?: 1 - return "$twinCardId #$twinCardNumber" + return TwinsHelper.getTwinCardIdForUser(this.cardId) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt index dde5046558..a20b06aa72 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/TwinsOnboardingFragment.kt @@ -8,6 +8,7 @@ import androidx.transition.TransitionInflater import com.squareup.picasso.Picasso import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store @@ -34,8 +35,9 @@ class TwinsOnboardingFragment : Fragment(R.layout.fragment_twin_cards) { store.dispatch(WalletAction.TwinsAction.SetOnboardingShown) - val secondCardId = store.state.walletState.twinCardsState?.secondCardId - val text = getString(R.string.twins_onboarding_description_format, secondCardId) + val secondCardId = store.state.walletState.twinCardsState?.secondCardId ?: "" + val secondTwinCardId = TwinsHelper.getTwinCardIdForUser(secondCardId) + val text = getString(R.string.twins_onboarding_description_format, secondTwinCardId) tv_twin_cards_description_1.text = text setOnClickListeners() From bf0a1ee7b8eb8083818a872667ba21eaaf096b0f Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 19:53:52 +0300 Subject: [PATCH 39/42] Updated on 2026-08-14 --- app/build.gradle | 4 ++-- .../java/com/tangem/tap/domain/TangemSdkManager.kt | 10 ++++++++-- .../java/com/tangem/tap/domain/TapWalletManager.kt | 7 +++---- .../java/com/tangem/tap/domain/tasks/ScanNoteTask.kt | 3 ++- .../tap/features/details/redux/DetailsReducer.kt | 4 ++-- .../tangem/tap/features/home/redux/HomeMiddleware.kt | 1 + .../tap/features/wallet/redux/WalletMiddleware.kt | 1 + 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3428782d33..5e3c0acf1d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,8 +72,8 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' implementation 'com.tangem:blockchain:1.123.0' - implementation 'com.tangem:core:1.88.0' - implementation 'com.tangem:sdk:1.88.0' + implementation 'com.tangem:core:1.89.0' + implementation 'com.tangem:sdk:1.89.0' // WebView implementation "androidx.browser:browser:1.2.0" 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 e34ddfe8c7..77d26702ab 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -3,6 +3,7 @@ package com.tangem.tap.domain import androidx.activity.ComponentActivity import com.tangem.* import com.tangem.commands.* +import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.CardType import com.tangem.common.CompletionResult import com.tangem.common.extensions.calculateSha256 @@ -12,6 +13,7 @@ import com.tangem.tap.common.analytics.AnalyticsHandler import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.domain.tasks.ScanNoteTask +import com.tangem.tap.domain.twins.isTwinCard import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -65,7 +67,7 @@ class TangemSdkManager(val activity: ComponentActivity) { } 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 -> @@ -76,9 +78,13 @@ class TangemSdkManager(val activity: ComponentActivity) { } 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 } } + + fun changeDisplayedCardIdNumbersCount(card: Card) { + tangemSdk.config.cardIdDisplayedNumbersCount = if (card.isTwinCard()) 4 else null + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index c26f2b36a2..36dd3c238c 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -5,7 +5,6 @@ import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.commands.common.card.CardStatus -import com.tangem.commands.common.card.masks.Product import com.tangem.commands.common.network.Result import com.tangem.common.extensions.toHexString import com.tangem.tap.common.analytics.AnalyticsEvent @@ -18,6 +17,7 @@ import com.tangem.tap.domain.extensions.amountToCreateAccount import com.tangem.tap.domain.extensions.isNoAccountError import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.domain.twins.TwinsHelper +import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.network.coinmarketcap.CoinMarketCapService @@ -102,7 +102,7 @@ class TapWalletManager { withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) store.dispatch(GlobalAction.SaveScanNoteResponse(data)) - if (data.card.cardData?.productMask?.contains(Product.TwinCard) == true) { + if (data.card.isTwinCard()) { val secondCardId = TwinsHelper.getTwinsCardId(data.card.cardId) val cardNumber = TwinsHelper.getTwinCardNumber(data.card.cardId) if (secondCardId != null && cardNumber != null) { @@ -131,8 +131,7 @@ class TapWalletManager { store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) store.dispatch(WalletAction.LoadFiatRate) store.dispatch(WalletAction.LoadPayId) - } else if (data.card.status == CardStatus.Empty || - data.card.cardData?.productMask?.contains(Product.TwinCard) == true) { + } else if (data.card.status == CardStatus.Empty || data.card.isTwinCard()) { store.dispatch(WalletAction.EmptyWallet) store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) } else { 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 f106f2a930..dfa1752929 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 @@ -17,6 +17,7 @@ import com.tangem.common.CompletionResult import com.tangem.common.extensions.toHexString import com.tangem.tap.domain.TapSdkError import com.tangem.tap.domain.twins.TwinCardsManager +import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tasks.ScanTask data class ScanNoteResponse( @@ -46,7 +47,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable { + tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card) store.dispatch(GlobalAction.RestoreAppCurrency) store.state.globalState.tapWalletManager.onCardScanned(result.data) showDisclaimerOrNavigateToWallet() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index c838228c2b..2f2c041924 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -125,6 +125,7 @@ class WalletMiddleware { val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler) when (result) { is CompletionResult.Success -> { + tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card) store.state.globalState.tapWalletManager .onCardScanned(result.data, true) if (store.state.walletState.twinCardsState != null) { From f88f21668a8e8dc14a03b391d8b1f419d274f0a7 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 21:10:43 +0300 Subject: [PATCH 40/42] Updated on 2026-08-14 --- .../details/redux/twins/CreateTwinWalletMiddleware.kt | 7 +++++-- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt index c2b5853228..d522a5b285 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt @@ -19,8 +19,11 @@ class CreateTwinWalletMiddleware { when (action) { is DetailsAction.CreateTwinWalletAction.ShowWarning -> { val wallet = store.state.detailsState.wallet - val notEmpty = wallet?.recentTransactions?.isNullOrEmpty() != true || - wallet.amounts.toSendableAmounts().isNotEmpty() + if (wallet == null) { + store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning)) + return + } + val notEmpty = wallet.recentTransactions.isNotEmpty() || wallet.amounts.toSendableAmounts().isNotEmpty() if (notEmpty) { store.dispatch(DetailsAction.CreateTwinWalletAction.NotEmpty) } else { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c90c4534da..05ea986b66 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -197,7 +197,7 @@ Tap to scan Tap the card - You balance on this wallet is not zero, or you have unconfirmed transactions + Your balance on this wallet is not zero, or you have unconfirmed transactions This is the currently active option From bd23a653458db206acb5086fe128a171fe6d1784 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Dec 2020 22:52:13 +0300 Subject: [PATCH 41/42] Updated on 2026-08-14 --- app/build.gradle | 4 ++-- .../tap/domain/twins/CreateSecondTwinWalletTask.kt | 9 ++++++++- .../java/com/tangem/tap/domain/twins/TwinCardsManager.kt | 9 +++++++-- .../tangem/tap/features/details/redux/DetailsAction.kt | 6 +++++- .../details/redux/twins/CreateTwinWalletMiddleware.kt | 3 ++- .../details/ui/twins/CreateTwinWalletFragment.kt | 6 +++--- app/src/main/res/values/strings_untranslated.xml | 2 ++ 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5e3c0acf1d..e35b177dba 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,8 +72,8 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' implementation 'com.tangem:blockchain:1.123.0' - implementation 'com.tangem:core:1.89.0' - implementation 'com.tangem:sdk:1.89.0' + implementation 'com.tangem:core:1.90.0' + implementation 'com.tangem:sdk:1.90.0' // WebView implementation "androidx.browser:browser:1.2.0" 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 c3fde9061d..5587faa1ab 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 @@ -2,6 +2,7 @@ package com.tangem.tap.domain.twins import com.tangem.CardSession import com.tangem.CardSessionRunnable +import com.tangem.Message import com.tangem.commands.CreateWalletResponse import com.tangem.commands.PurgeWalletCommand import com.tangem.commands.common.card.CardStatus @@ -9,11 +10,16 @@ import com.tangem.common.CompletionResult import com.tangem.common.extensions.hexToBytes import com.tangem.tasks.CreateWalletTask -class CreateSecondTwinWalletTask(private val firstPublicKey: String) : CardSessionRunnable { +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?.walletPublicKey != null) { + session.setInitialMessage(preparingMessage) PurgeWalletCommand().run(session) { response -> when (response) { is CompletionResult.Success -> { @@ -30,6 +36,7 @@ class CreateSecondTwinWalletTask(private val firstPublicKey: String) : CardSessi } private fun finishTask(session: CardSession, callback: (result: CompletionResult) -> Unit) { + session.setInitialMessage(creatingWalletMessage) CreateWalletTask().run(session) { result -> when (result) { is CompletionResult.Success -> { 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 b5e221eb08..43d313f8a6 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 @@ -34,9 +34,14 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) { } - suspend fun createSecondWallet(message: Message): SimpleResult { + suspend fun createSecondWallet( + initialMessage: Message, + preparingMessage: Message, + creatingWalletMessage: Message + ): SimpleResult { val response = tangemSdkManager.runTaskAsync( - CreateSecondTwinWalletTask(currentCardPublicKey!!), secondCardId, message + CreateSecondTwinWalletTask(currentCardPublicKey!!, preparingMessage, creatingWalletMessage), + secondCardId, initialMessage ) when (response) { is CompletionResult.Success -> { 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 1e90daa2e1..2ec73c0f00 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 @@ -65,7 +65,11 @@ sealed class DetailsAction : Action { object Failure : CreateTwinWalletAction() } - data class LaunchSecondStep(val message: Message) : CreateTwinWalletAction() { + data class LaunchSecondStep( + val initialMessage: Message, + val preparingMessage: Message, + val creatingWalletMessage: Message, + ) : CreateTwinWalletAction() { object Success : CreateTwinWalletAction() object Failure : CreateTwinWalletAction() } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt index d522a5b285..38cfac39bc 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/twins/CreateTwinWalletMiddleware.kt @@ -71,7 +71,8 @@ class CreateTwinWalletMiddleware { } is DetailsAction.CreateTwinWalletAction.LaunchSecondStep -> scope.launch { - val result = twinsManager?.createSecondWallet(action.message) + val result = twinsManager?.createSecondWallet(action.initialMessage, + action.preparingMessage, action.creatingWalletMessage) withContext(Dispatchers.Main) { when (result) { SimpleResult.Success -> diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt index 7dc481b077..0cb261610b 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/twins/CreateTwinWalletFragment.kt @@ -115,9 +115,9 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards), v_step_3.setBackgroundColor(defaultColor) btn_tap.setOnClickListener { store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchSecondStep( - Message(getString( - R.string.details_twins_recreate_title_format, twinCardNumberString) - ) + Message(getString(R.string.details_twins_recreate_title_format, twinCardNumberString)), + Message(getString(R.string.details_twins_recreate_title_preparing)), + Message(getString(R.string.details_twins_recreate_title_creating_wallet)), )) } btn_tap.text = getString(R.string.details_twins_recreate_button_format, "2") diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 9378124536..2f0501ac9f 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -22,6 +22,8 @@ this wallet. Re-create wallet Step %s Tap the #%s twin card + Preparing card + Creating wallet The wallet creation procedure consists of three steps. You must complete it to the end, otherwise you will have to start from the beginning. Tap the card #%s You have already started the process of recreating twin wallet. If you interrupt it, you won\'t be able to use your twin cards until you start it again and complete recreating the wallet. From 08f4e1c31e42b3a69d03692b20ccc974b8f38aa2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 21 Dec 2020 15:21:50 +0300 Subject: [PATCH 42/42] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/network/Retrofit.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/com/tangem/tap/network/Retrofit.kt b/app/src/main/java/com/tangem/tap/network/Retrofit.kt index 169baa076b..dd16923173 100644 --- a/app/src/main/java/com/tangem/tap/network/Retrofit.kt +++ b/app/src/main/java/com/tangem/tap/network/Retrofit.kt @@ -12,6 +12,7 @@ import retrofit2.Converter import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory import java.math.BigDecimal +import java.util.concurrent.TimeUnit fun createRetrofitInstance( baseUrl: String, @@ -19,6 +20,7 @@ fun createRetrofitInstance( ): Retrofit { val okHttpBuilder = OkHttpClient.Builder() interceptors.forEach { okHttpBuilder.addInterceptor(it) } + addTimeOuts(okHttpBuilder) if (BuildConfig.DEBUG) okHttpBuilder.addInterceptor(createHttpLoggingInterceptor()) return Retrofit.Builder() @@ -28,6 +30,13 @@ fun createRetrofitInstance( .build() } +private fun addTimeOuts(okHttpBuilder: OkHttpClient.Builder) { + okHttpBuilder.callTimeout(1, TimeUnit.SECONDS) + okHttpBuilder.connectTimeout(20, TimeUnit.SECONDS) + okHttpBuilder.readTimeout(20, TimeUnit.SECONDS) + okHttpBuilder.writeTimeout(20, TimeUnit.SECONDS) +} + fun createMoshiConverterFactory(): Converter.Factory = MoshiConverterFactory.create(createMoshi()) fun createMoshi(): Moshi = Moshi.Builder()