From 565cbbe2b3ae63a5fdfb5eeda2769668a1960d0f Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 10 May 2023 19:17:40 +0400 Subject: [PATCH 1/7] Updated on 2026-08-14 --- gradle/dependencies.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 47877b952c..5aa61ccaef 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -72,7 +72,7 @@ arrow = "1.2.0-RC" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-209" +tangemBlockchainSdk = "release-app_4.5-212" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-229" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds From f669f626ebea52a9b990c3ac55c57660842248ba Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 10 May 2023 19:36:41 +0300 Subject: [PATCH 2/7] Updated on 2026-08-14 --- .../tap/features/details/redux/DetailsMiddleware.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index cfcc202a2b..b10ad9de2a 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -10,6 +10,7 @@ import com.tangem.core.analytics.Analytics import com.tangem.domain.common.TapWorkarounds.isTangemTwins import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.models.scan.ScanResponse +import com.tangem.tap.* import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchDialogShow @@ -31,14 +32,6 @@ import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.foregroundActivityObserver -import com.tangem.tap.preferencesStorage -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.tap.tangemSdkManager -import com.tangem.tap.userTokensRepository -import com.tangem.tap.userWalletsListManager -import com.tangem.tap.walletStoresManager import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -84,6 +77,8 @@ class DetailsMiddleware { allowsRequestAccessCodeFromRepository = true, ) .doOnSuccess { scanResponse -> + // if we use biometric, scanResponse in GlobalState is null, and crashes NPE on twin cards + store.dispatch(GlobalAction.SaveScanResponse(scanResponse)) val currentUserWalletId = state.scanResponse ?.let { UserWalletIdBuilder.scanResponse(it).build() } val scannedUserWalletId = UserWalletIdBuilder.scanResponse(scanResponse) From c65798e39fe16900ab6ec3b6c036712e75cef01a Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 11 May 2023 11:42:24 +0300 Subject: [PATCH 3/7] Updated on 2026-08-14 --- .../java/com/tangem/tap/features/wallet/ui/WalletFragment.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 1d0cc810ed..4522299310 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 @@ -239,7 +239,10 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), SafeStoreSubscriber Date: Thu, 11 May 2023 13:39:03 +0300 Subject: [PATCH 4/7] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 fc1d4e3958..7d5a21594a 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -14,6 +14,7 @@ import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.extensions.setContext import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.model.UserWallet +import com.tangem.tap.domain.model.builders.UserWalletIdBuilder import com.tangem.tap.domain.walletStores.WalletStoresError import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction import com.tangem.tap.features.disclaimer.createDisclaimer @@ -36,7 +37,10 @@ class TapWalletManager { suspend fun onWalletSelected(userWallet: UserWallet, refresh: Boolean, sendAnalyticsEvent: Boolean) { // do nothing if its the same wallet - if (store.state.globalState.scanResponse == userWallet.scanResponse) return + store.state.globalState.scanResponse?.let { + val userWalletId = UserWalletIdBuilder.scanResponse(it).build() + if (userWalletId == userWallet.walletId) return + } Analytics.setContext(userWallet.scanResponse) if (sendAnalyticsEvent) { From 35566a092c044894bc62c2353cf3628b7a768269 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 11 May 2023 13:26:54 +0400 Subject: [PATCH 5/7] Updated on 2026-08-14 --- .../tangem/tap/features/wallet/redux/WalletState.kt | 6 +++++- .../tap/features/wallet/ui/WalletDetailsFragment.kt | 12 +++++++++--- .../features/wallet/ui/utils/WalletDataOperations.kt | 7 +++---- .../features/wallet/ui/wallet/SingleWalletView.kt | 10 ++-------- 4 files changed, 19 insertions(+), 16 deletions(-) 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 a7e540bf43..772bd7a3e7 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 @@ -1,6 +1,7 @@ package com.tangem.tap.features.wallet.redux import android.graphics.Bitmap +import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.WalletManager import com.tangem.domain.common.util.cardTypesResolver @@ -16,6 +17,7 @@ import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.store import org.rekotlin.StateType +import java.math.BigDecimal import kotlin.properties.ReadOnlyProperty data class WalletState( @@ -103,6 +105,9 @@ data class WalletState( it.derivationPath?.rawPath == currency.derivationPath } } + + fun getBlockchainAmount(currency: Currency): BigDecimal = + getWalletManager(currency)?.wallet?.amounts?.get(AmountType.Coin)?.value ?: BigDecimal.ZERO } enum class ProgressState : WidgetState { Loading, Refreshing, Done, Error } @@ -114,7 +119,6 @@ enum class ErrorType { sealed class WalletMainButton(enabled: Boolean) : Button(enabled) { class SendButton(enabled: Boolean) : WalletMainButton(enabled) - class CreateWalletButton(enabled: Boolean) : WalletMainButton(enabled) } data class Artwork( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index d4556d790b..4ea69fa30f 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -55,6 +55,7 @@ import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import timber.log.Timber +import java.math.BigDecimal import javax.inject.Inject /** @@ -128,7 +129,8 @@ class WalletDetailsFragment : (WalletState::selectedWalletData or WalletState::isExchangeServiceFeatureOn) { state -> val selectedWallet = state.selectedWalletData if (selectedWallet != null) { - setupButtonsRow(selectedWallet, state.isExchangeServiceFeatureOn) + val blockchainAmount: BigDecimal = state.getBlockchainAmount(selectedWallet.currency) + setupButtonsRow(selectedWallet, state.isExchangeServiceFeatureOn, blockchainAmount) } } (WalletState::state or WalletState::error) { state -> @@ -281,7 +283,11 @@ class WalletDetailsFragment : } } - private fun setupButtonsRow(selectedWallet: WalletDataModel, isExchangeServiceFeatureOn: Boolean) { + private fun setupButtonsRow( + selectedWallet: WalletDataModel, + isExchangeServiceFeatureOn: Boolean, + blockchainAmount: BigDecimal, + ) { val exchangeManager = store.state.globalState.exchangeManager binding.rowButtons.apply { onBuyClick = { store.dispatch(WalletAction.TradeCryptoAction.Buy()) } @@ -310,7 +316,7 @@ class WalletDetailsFragment : binding.rowButtons.updateButtonsVisibility( actions = actions, exchangeServiceFeatureOn = isExchangeServiceFeatureOn, - sendAllowed = selectedWallet.mainButton.enabled, + sendAllowed = selectedWallet.mainButton(blockchainAmount).enabled, ) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt index 042426cb80..f40f0d38dc 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt @@ -18,10 +18,9 @@ import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import java.math.BigDecimal -internal val WalletDataModel.mainButton: WalletMainButton - get() = WalletMainButton.SendButton( - enabled = !status.amount.isZero() && status.pendingTransactions.isEmpty(), - ) +internal fun WalletDataModel.mainButton(blockchainAmount: BigDecimal): WalletMainButton = WalletMainButton.SendButton( + enabled = !isEmptyAmount && status.pendingTransactions.isEmpty() && !blockchainAmount.isZero(), +) internal fun WalletDataModel.getFormattedAmount(): String { return status.amount.toFormattedCurrencyString( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index 5668693e18..5d49193785 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -12,7 +12,6 @@ import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.features.wallet.redux.WalletMainButton import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.features.wallet.ui.BalanceWidget import com.tangem.tap.features.wallet.ui.MultipleAddressUiHelper @@ -175,15 +174,10 @@ class SingleWalletView : WalletView() { binding?.rowButtons?.updateButtonsVisibility( actions = actions, exchangeServiceFeatureOn = isExchangeServiceFeatureEnabled, - sendAllowed = walletData.mainButton.enabled, + sendAllowed = walletData.mainButton(walletData.status.amount).enabled, ) - rowButtons.onSendClick = { - when (walletData.mainButton) { - is WalletMainButton.SendButton -> store.dispatch(WalletAction.Send()) - is WalletMainButton.CreateWalletButton -> store.dispatch(WalletAction.CreateWallet) - } - } + rowButtons.onSendClick = { store.dispatch(WalletAction.Send()) } } private fun setupAddressCard(state: WalletState, binding: FragmentWalletBinding) = with(binding.lAddress) { From 111ef128250bc40c88b356f6c8740aeb4f4aef94 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 11 May 2023 16:39:12 +0500 Subject: [PATCH 6/7] Updated on 2026-08-14 --- gradle/dependencies.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 5aa61ccaef..050f3cb2bc 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -72,7 +72,7 @@ arrow = "1.2.0-RC" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_4.5-212" +tangemBlockchainSdk = "release-app_4.5-215" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-229" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds From c8e900df8fd29f6ac0812c196605e82b878d356e Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 12 May 2023 17:53:20 +0800 Subject: [PATCH 7/7] Updated on 2026-08-14 --- .../BiometricUserWalletsListManager.kt | 25 +------------------ gradle/dependencies.toml | 2 +- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt index ad29020162..78f74e0c3d 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt @@ -54,16 +54,6 @@ internal class BiometricUserWalletsListManager( get() = keysRepository.hasSavedEncryptionKeys() override suspend fun unlock(): CompletionResult { - // Occurs when user has locked user wallets after unlocking with biometry - // e.g. after biometric storage master key invalidation - if (state.value.hasLockedUserWalletsAfterUnlock) { - return CompletionResult.Failure( - error = UserWalletsListError.UnableToUnlockUserWallets( - cause = IllegalStateException("Permanently locked"), - ), - ) - } - return unlockWithBiometryInternal() .mapFailure { error -> if (error is UserWalletsListError) { @@ -216,10 +206,7 @@ internal class BiometricUserWalletsListManager( .map { state.update { prevState -> val hasLockedUserWallets = prevState.userWallets.any { it.isLocked } - prevState.copy( - isLocked = hasLockedUserWallets, - hasLockedUserWalletsAfterUnlock = hasLockedUserWallets, - ) + prevState.copy(isLocked = hasLockedUserWallets) } } } @@ -262,15 +249,6 @@ internal class BiometricUserWalletsListManager( } } } - .doOnFailure { error -> - if (error is UserWalletsListError.EncryptionKeyInvalidated) { - state.update { prevState -> - prevState.copy( - hasLockedUserWalletsAfterUnlock = true, - ) - } - } - } } private suspend fun getSavedUserWallets(): CompletionResult> { @@ -334,6 +312,5 @@ internal class BiometricUserWalletsListManager( val userWallets: List = emptyList(), val selectedUserWalletId: UserWalletId? = null, val isLocked: Boolean = true, - val hasLockedUserWalletsAfterUnlock: Boolean = false, ) } \ No newline at end of file diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 050f3cb2bc..91c34ec357 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -74,7 +74,7 @@ arrow = "1.2.0-RC" # region Tangem tangemBlockchainSdk = "release-app_4.5-215" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "develop-229" +tangemCardSdk = "develop-235" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds # endregion Tangem