From 5d13f006d84fb0719e20869e74fe8806b62ab4dc Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 18 Aug 2022 12:35:41 +0400 Subject: [PATCH 01/68] Updated on 2026-08-14 --- .../tap/domain/walletconnect/WalletConnectNetworkUtils.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt index 3da00c517b..6b2a457e43 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt @@ -12,6 +12,9 @@ class WalletConnectNetworkUtils { peer: WCPeerMeta, ): Blockchain? { return when { + peer.url.contains("pancakeswap.finance") -> { + Blockchain.BSC + } chainId != null -> { Blockchain.fromChainId(chainId) } From 122a8ead52e11bd07a1ec6d69aca56fc463c2bde Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 18 Aug 2022 12:37:59 +0400 Subject: [PATCH 02/68] Updated on 2026-08-14 --- .../tap/features/details/redux/DetailsMiddleware.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 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 7825d58a8f..a465940186 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 @@ -98,14 +98,16 @@ class DetailsMiddleware { fun handle(action: DetailsAction.ResetToFactory) { when (action) { is DetailsAction.ResetToFactory.Start -> { - store.dispatch(NavigationAction.NavigateTo(AppScreen.ResetToFactory)) - } - is DetailsAction.ResetToFactory.Proceed -> { val card = store.state.detailsState.cardSettingsState?.card ?: return if (card.isTangemTwins()) { store.dispatch(DetailsAction.ReCreateTwinsWallet) return + } else { + store.dispatch(NavigationAction.NavigateTo(AppScreen.ResetToFactory)) } + } + is DetailsAction.ResetToFactory.Proceed -> { + val card = store.state.detailsState.cardSettingsState?.card ?: return scope.launch { val result = tangemSdkManager.resetToFactorySettings(card) withContext(Dispatchers.Main) { From e942dcb6c99d9cbe72debe7eb2673edf6402a467 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 18 Aug 2022 12:39:22 +0400 Subject: [PATCH 03/68] Updated on 2026-08-14 --- .../details/redux/walletconnect/WalletConnectMiddleware.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt index d98fb0b0f5..d209c6d1f8 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt @@ -222,7 +222,10 @@ class WalletConnectMiddleware { val blockchain = WalletConnectNetworkUtils.parseBlockchain( chainId = chainId, peer = session.peerMeta, - ) ?: Blockchain.Ethereum + ).guard { + store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedNetwork)) + return + } store.dispatch( GlobalAction.ScanCard( From c9d5d65799a858ba5bdeac7c9de90db381eb2bdd Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 18 Aug 2022 12:49:06 +0400 Subject: [PATCH 04/68] Updated on 2026-08-14 --- .../features/details/ui/resetcard/ResetCardScreen.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt index 2c07b092ad..eda04bf95c 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt @@ -2,6 +2,7 @@ package com.tangem.tap.features.details.ui.resetcard import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -86,11 +87,14 @@ fun ResetCardView( color = colorResource(id = R.color.text_secondary), ) - Spacer(modifier = modifier.size(44.dp)) + Spacer(modifier = modifier.size(28.dp)) Row( modifier = modifier .fillMaxWidth() - .padding(end = 20.dp), + .clickable( + onClick = { state.onAcceptWarningToggleClick(!state.accepted) }, + ) + .padding(top = 16.dp, bottom = 16.dp), ) { IconToggleButton( checked = state.accepted, @@ -117,10 +121,12 @@ fun ResetCardView( text = stringResource(id = R.string.reset_card_to_factory_warning_message), style = TangemTypography.body2, color = colorResource(id = R.color.text_secondary), + modifier = modifier + .padding(end = 20.dp), ) } - Spacer(modifier = modifier.size(32.dp)) + Spacer(modifier = modifier.size(16.dp)) Box( modifier = modifier .padding(start = 16.dp, end = 16.dp, bottom = 32.dp), From 4a418d0d6aa58d9f5d5b4277e9f6d656ac9cd528 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 18 Aug 2022 23:14:20 +0300 Subject: [PATCH 05/68] Updated on 2026-08-14 --- .../features/wallet/models/PendingTransaction.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt index 698a4c9eb9..f2cd8d24b1 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt @@ -1,6 +1,11 @@ package com.tangem.tap.features.wallet.models -import com.tangem.blockchain.common.* +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.AmountType +import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.TransactionData +import com.tangem.blockchain.common.TransactionStatus +import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.extensions.isAboveZero import com.tangem.tap.common.extensions.toFormattedString import java.math.BigDecimal @@ -10,8 +15,8 @@ data class PendingTransaction( val type: PendingTransactionType, ) { val address: String? = when (type) { - PendingTransactionType.Incoming -> transactionData.sourceAddress - PendingTransactionType.Outgoing -> transactionData.destinationAddress + PendingTransactionType.Incoming -> nullIfUnknown(transactionData.sourceAddress) + PendingTransactionType.Outgoing -> nullIfUnknown(transactionData.destinationAddress) PendingTransactionType.Unknown -> null } @@ -20,6 +25,8 @@ data class PendingTransaction( val amountValueUi: String? = amountValue?.toFormattedString(transactionData.amount.decimals) val currency: String = transactionData.amount.currencySymbol + + fun nullIfUnknown(address: String):String? = if (address == "unknown") null else address } enum class PendingTransactionType { Incoming, Outgoing, Unknown } From b168d40f52156f2172413bf5aeab088ec5522037 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 23 Aug 2022 16:45:21 +0300 Subject: [PATCH 06/68] Updated on 2026-08-14 --- .../send/redux/reducers/FeeReducer.kt | 59 ++++++++----------- .../send/redux/reducers/ReceiptReducer.kt | 22 +++++-- .../features/send/redux/states/FeeState.kt | 24 ++++---- .../tap/features/wallet/redux/WalletState.kt | 1 + dependencies.gradle | 2 +- 5 files changed, 52 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt index fd653557c7..4c2fae60ba 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt @@ -1,13 +1,9 @@ package com.tangem.tap.features.send.redux.reducers import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.AmountType -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.common.extensions.fullNameWithoutTestnet import com.tangem.tap.features.send.redux.FeeAction import com.tangem.tap.features.send.redux.FeeActionUi import com.tangem.tap.features.send.redux.SendScreenAction -import com.tangem.tap.features.send.redux.states.FeePrecision import com.tangem.tap.features.send.redux.states.FeeState import com.tangem.tap.features.send.redux.states.FeeType import com.tangem.tap.features.send.redux.states.SendState @@ -28,10 +24,9 @@ class FeeReducer : SendInternalReducer { is FeeActionUi.ChangeSelectedFee -> { val currentFee = createValueOfFeeAmount(action.feeType, state.feeList) state.copy( - selectedFeeType = action.feeType, - currentFee = currentFee + selectedFeeType = action.feeType, + currentFee = currentFee, ) - } is FeeActionUi.ChangeIncludeFee -> state.copy(feeIsIncluded = action.isIncluded) } @@ -46,9 +41,9 @@ class FeeReducer : SendInternalReducer { is FeeAction.ChangeLayoutVisibility -> { fun getVisibility(current: Boolean, proposed: Boolean?): Boolean = proposed ?: current state.copy( - mainLayoutIsVisible = getVisibility(state.mainLayoutIsVisible, action.main), - controlsLayoutIsVisible = getVisibility(state.controlsLayoutIsVisible, action.controls), - feeChipGroupIsVisible = getVisibility(state.feeChipGroupIsVisible, action.chipGroup) + mainLayoutIsVisible = getVisibility(state.mainLayoutIsVisible, action.main), + controlsLayoutIsVisible = getVisibility(state.controlsLayoutIsVisible, action.controls), + feeChipGroupIsVisible = getVisibility(state.feeChipGroupIsVisible, action.chipGroup), ) } is FeeAction.FeeCalculation.SetFeeResult -> { @@ -58,30 +53,30 @@ class FeeReducer : SendInternalReducer { val currentFee = createValueOfFeeAmount(feeType, fees) state.copy( - selectedFeeType = feeType, - feeList = fees, - currentFee = currentFee, - error = null, - feePrecision = getFeePrecision(sendState) + selectedFeeType = feeType, + feeList = fees, + currentFee = currentFee, + error = null, + feeIsApproximate = isFeeApproximate(sendState), ) } else { val feeType = getCurrentFeeType(state) val currentFee = createValueOfFeeAmount(feeType, fees) state.copy( - selectedFeeType = feeType, - feeList = fees, - currentFee = currentFee, - error = null, - feePrecision = getFeePrecision(sendState) + selectedFeeType = feeType, + feeList = fees, + currentFee = currentFee, + error = null, + feeIsApproximate = isFeeApproximate(sendState), ) } } is FeeAction.FeeCalculation.SetFeeError -> { state.copy( - feeList = null, - currentFee = null, - error = action.error + feeList = null, + currentFee = null, + error = action.error, ) } } @@ -104,20 +99,12 @@ class FeeReducer : SendInternalReducer { } } - private fun getFeePrecision(sendState: SendState): FeePrecision { - val blockchain = sendState.walletManager?.wallet?.blockchain - return if ( - (blockchain?.fullNameWithoutTestnet == Blockchain.Arbitrum.fullName || - blockchain?.fullNameWithoutTestnet == Blockchain.Tron.fullName || - blockchain?.fullNameWithoutTestnet == Blockchain.Gnosis.fullName) && - sendState.amountState.typeOfAmount is AmountType.Token - ) { - FeePrecision.CAN_BE_LOWER - } else { - FeePrecision.PRECISE - } - } + private fun isFeeApproximate(sendState: SendState): Boolean { + val blockchain = sendState.walletManager?.wallet?.blockchain ?: return false + val amountType = sendState.amountState.typeOfAmount + return blockchain.isFeeApproximate(amountType) + } private fun getCurrentFeeType(state: FeeState): FeeType { return if (state.selectedFeeType == FeeType.SINGLE) FeeType.NORMAL else state.selectedFeeType diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt index c15813fdaa..64d5cc23d3 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt @@ -6,7 +6,18 @@ import com.tangem.tap.common.extensions.scaleToFiat import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.features.send.redux.ReceiptAction.RefreshReceipt import com.tangem.tap.features.send.redux.SendScreenAction -import com.tangem.tap.features.send.redux.states.* +import com.tangem.tap.features.send.redux.states.AmountState +import com.tangem.tap.features.send.redux.states.FeeState +import com.tangem.tap.features.send.redux.states.MainCurrencyType +import com.tangem.tap.features.send.redux.states.ReceiptCrypto +import com.tangem.tap.features.send.redux.states.ReceiptFiat +import com.tangem.tap.features.send.redux.states.ReceiptLayoutType +import com.tangem.tap.features.send.redux.states.ReceiptState +import com.tangem.tap.features.send.redux.states.ReceiptSymbols +import com.tangem.tap.features.send.redux.states.ReceiptTokenCrypto +import com.tangem.tap.features.send.redux.states.ReceiptTokenFiat +import com.tangem.tap.features.send.redux.states.SendState +import com.tangem.tap.features.wallet.redux.WalletState.Companion.CAN_BE_LOWER_SIGN import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.store import java.math.BigDecimal @@ -125,8 +136,7 @@ class ReceiptReducer : SendInternalReducer { val totalFiat = amountFiat.plus(feeFiat) ReceiptTokenFiat( amountFiat = amountFiat.scaleToFiat(true).stripZeroPlainString(), - feeFiat = feeFiat.scaleToFiat(true) - .stripZeroPlainString().addPrecisionSign(), + feeFiat = feeFiat.scaleToFiat(true).stripZeroPlainString().addPrecisionSign(), totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(), willSentToken = tokensToSend.stripZeroPlainString(), willSentFeeCoin = feeCoin.stripZeroPlainString(), @@ -207,6 +217,8 @@ class ReceiptReducer : SendInternalReducer { } } - private fun String.addPrecisionSign(): String = - ("${feeState.feePrecision.symbol} $this").trim() + private fun String.addPrecisionSign(): String { + val result = if (feeState.feeIsApproximate) "$CAN_BE_LOWER_SIGN $this" else "" + return result.trim() + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt index 87b29f304b..4c9818a669 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt @@ -11,21 +11,17 @@ enum class FeeType { SINGLE, LOW, NORMAL, PRIORITY } -enum class FeePrecision(val symbol: String) { - PRECISE(""), CAN_BE_LOWER("<") -} - data class FeeState( - val selectedFeeType: FeeType = FeeType.NORMAL, - val feeList: List? = null, - val currentFee: Amount? = null, - val feeIsIncluded: Boolean = false, - val mainLayoutIsVisible: Boolean = false, - val controlsLayoutIsVisible: Boolean = false, - val feeChipGroupIsVisible: Boolean = true, - val includeFeeSwitcherIsEnabled: Boolean = true, - val error: FeeAction.Error? = null, - val feePrecision: FeePrecision = FeePrecision.PRECISE + val selectedFeeType: FeeType = FeeType.NORMAL, + val feeList: List? = null, + val currentFee: Amount? = null, + val feeIsIncluded: Boolean = false, + val feeIsApproximate: Boolean = false, + val mainLayoutIsVisible: Boolean = false, + val controlsLayoutIsVisible: Boolean = false, + val feeChipGroupIsVisible: Boolean = true, + val includeFeeSwitcherIsEnabled: Boolean = true, + val error: FeeAction.Error? = null, ) : SendScreenState { override val stateId: StateId = StateId.FEE 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 48c886d939..594676e0ec 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 @@ -287,6 +287,7 @@ data class WalletState( companion object { const val UNKNOWN_AMOUNT_SIGN = "—" const val ROUGH_SIGN = "≈" + const val CAN_BE_LOWER_SIGN = "<" } } diff --git a/dependencies.gradle b/dependencies.gradle index e1c383532f..8d2e4ea106 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -2,7 +2,7 @@ ext.versions = [ kotlin : '1.6.10', build_gradle : '7.1.3', tangem_card_sdk : 'develop-159', - tangem_blockchain_sdk: 'develop-105', + tangem_blockchain_sdk: 'develop-106', // tangem_blockchain_sdk: '0.0.1', ] From ac3688c1fa3cca7c7dcf1ba9f8b71193a0efe9cd Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 23 Aug 2022 18:39:11 +0300 Subject: [PATCH 07/68] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/MainActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 4e1c24d3c9..642624ce5b 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -5,7 +5,6 @@ import android.content.pm.ActivityInfo import android.os.Bundle import android.view.View import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsControllerCompat import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.snackbar.Snackbar @@ -85,7 +84,8 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { } private fun systemActions() { - WindowCompat.setDecorFitsSystemWindows(window, false) + // makes the status bar text dark + window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR val windowInsetsController = WindowInsetsControllerCompat(window, binding.root) windowInsetsController.isAppearanceLightStatusBars = true From 50c0e0d38e66be1261e8d2cab32060354c18f056 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 24 Aug 2022 20:55:01 +0300 Subject: [PATCH 08/68] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 642624ce5b..840cee766b 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -85,7 +85,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { private fun systemActions() { // makes the status bar text dark - window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN val windowInsetsController = WindowInsetsControllerCompat(window, binding.root) windowInsetsController.isAppearanceLightStatusBars = true From 8274288166e632db76f7808b3b5e9ec184c67926 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Aug 2022 18:28:31 +0300 Subject: [PATCH 09/68] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/MainActivity.kt | 6 ++++-- .../tap/features/details/ui/walletconnect/QrScanFragment.kt | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 840cee766b..a005e3f952 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -4,7 +4,9 @@ import android.content.Intent import android.content.pm.ActivityInfo import android.os.Bundle import android.view.View +import android.view.Window import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsControllerCompat import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.snackbar.Snackbar @@ -84,8 +86,8 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { } private fun systemActions() { - // makes the status bar text dark - window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN + + WindowCompat.setDecorFitsSystemWindows(window, false) val windowInsetsController = WindowInsetsControllerCompat(window, binding.root) windowInsetsController.isAppearanceLightStatusBars = true diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt index 9daba1f257..0ee7263879 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt @@ -9,6 +9,7 @@ import android.view.View import android.view.ViewGroup import androidx.activity.OnBackPressedCallback import androidx.core.content.ContextCompat +import androidx.core.view.WindowCompat import androidx.fragment.app.Fragment import com.google.zxing.Result import com.otaliastudios.cameraview.CameraView @@ -23,6 +24,7 @@ class QrScanFragment : Fragment(0), ZXingScannerView.ResultHandler { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + activity?.window?.let { WindowCompat.setDecorFitsSystemWindows(it, true) } activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { store.dispatch(NavigationAction.PopBackTo()) @@ -54,7 +56,7 @@ class QrScanFragment : Fragment(0), ZXingScannerView.ResultHandler { override fun handleResult(result: Result) { store.dispatch(NavigationAction.PopBackTo()) - + activity?.window?.let { WindowCompat.setDecorFitsSystemWindows(it, false) } if (!result.text.isNullOrBlank()) { store.dispatch(WalletConnectAction.OpenSession(result.text)) } From 1c1e1126214bd122ff886003cc449394e0f1a458 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 29 Aug 2022 20:50:10 +0300 Subject: [PATCH 10/68] Updated on 2026-08-14 --- .../com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index 4be9104bb1..9092292f99 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -62,7 +62,7 @@ class WalletAdapter fun bind(wallet: WalletData) = with(binding) { val status = wallet.currencyData.status // Skip changes when on refreshing status - if (status == BalanceStatus.Refreshing) return@with + if (status == BalanceStatus.Refreshing || wallet.fiatRateString == null) return@with val statusMessage = when (status) { BalanceStatus.TransactionInProgress -> { From 2621bad76b33699b12b1dc2ee51dced74e12a36c Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 Aug 2022 11:10:38 +0400 Subject: [PATCH 11/68] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/MainActivity.kt | 3 - .../com/tangem/tap/common/DialogManager.kt | 1 - .../com/tangem/tap/domain/TapWalletManager.kt | 7 +- .../walletconnect/WalletConnectManager.kt | 14 ++- .../walletconnect/WalletConnectSdkHelper.kt | 6 +- .../walletconnect/WcWalletManagerFactory.kt | 48 ++------- .../walletconnect/WalletConnectAction.kt | 7 +- .../walletconnect/WalletConnectMiddleware.kt | 102 ++++++++---------- .../walletconnect/WalletConnectReducer.kt | 1 + .../redux/walletconnect/WalletConnectState.kt | 6 +- .../ui/walletconnect/SessionsAdapter.kt | 55 ---------- .../ui/walletconnect/WalletConnectScreen.kt | 1 - .../walletconnect/WalletConnectScreenState.kt | 2 - .../dialogs/ApproveWcSessionDialog.kt | 1 - .../dialogs/BnbTransactionDialog.kt | 3 +- .../dialogs/PersonalSignDialog.kt | 11 +- .../dialogs/TransactionDialog.kt | 2 - .../ui/walletconnect/dialogs/WcDialog.kt | 1 - app/src/main/res/values-ru/strings.xml | 8 +- .../main/res/values/strings_untranslated.xml | 24 ++--- 20 files changed, 100 insertions(+), 203 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index a005e3f952..6a80a26d24 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -4,7 +4,6 @@ import android.content.Intent import android.content.pm.ActivityInfo import android.os.Bundle import android.view.View -import android.view.Window import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsControllerCompat @@ -26,7 +25,6 @@ import com.tangem.tap.common.shop.GooglePayService import com.tangem.tap.common.shop.GooglePayService.Companion.LOAD_PAYMENT_DATA_REQUEST_CODE import com.tangem.tap.common.shop.googlepay.GooglePayUtil.createPaymentsClient import com.tangem.tap.domain.TangemSdkManager -import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction import com.tangem.tap.features.shop.redux.ShopAction import com.tangem.wallet.R import com.tangem.wallet.databinding.ActivityMainBinding @@ -67,7 +65,6 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { backupService = BackupService.init(tangemSdk, this) store.dispatch(GlobalAction.SetResources(getAndroidResources())) - store.dispatch(WalletConnectAction.RestoreSessions) store.dispatch( ShopAction.CheckIfGooglePayAvailable( GooglePayService(createPaymentsClient(this), this) diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt index 96cf1b874b..ef357f782f 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -113,7 +113,6 @@ class DialogManager : StoreSubscriber { data = state.dialog.data, session = state.dialog.session, sessionId = state.dialog.sessionId, - cardId = state.dialog.cardId, dAppName = state.dialog.dAppName, context = context, ) 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 8bd8cf8ef7..55e86e7368 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -23,6 +23,7 @@ import com.tangem.tap.domain.extensions.makePrimaryWalletManager import com.tangem.tap.domain.extensions.makeWalletManagersForApp import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.demo.isDemoCard +import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.store @@ -88,14 +89,16 @@ class TapWalletManager { withMainContext { store.dispatch(WalletAction.ResetState(data.card.cardId)) + store.dispatch(WalletConnectAction.ResetState) store.dispatch(GlobalAction.SaveScanNoteResponse(data)) store.dispatch(WalletAction.SetIfTestnetCard(data.card.isTestCard)) store.dispatch(WalletAction.MultiWallet.SetIsMultiwalletAllowed(data.card.isMultiwalletAllowed)) + store.dispatch(WalletConnectAction.RestoreSessions(data)) store.dispatch( WalletAction.MultiWallet.ShowWalletBackupWarning( show = data.card.settings.isBackupAllowed - && data.card.backupStatus == Card.BackupStatus.NoBackup - ) + && data.card.backupStatus == Card.BackupStatus.NoBackup, + ), ) loadData(data) } diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt index 7e4fae297a..45c3dee2e3 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt @@ -1,7 +1,9 @@ package com.tangem.tap.domain.walletconnect import com.tangem.blockchain.common.Blockchain +import com.tangem.common.card.EllipticCurve import com.tangem.common.extensions.guard +import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.global.GlobalAction @@ -69,7 +71,7 @@ class WalletConnectManager { remotePeerId = null, session = session, client = client, - wallet = WalletForSession(cardId = "") + wallet = WalletForSession(), ) setupConnectionTimeoutCheck(session) } @@ -110,8 +112,12 @@ class WalletConnectManager { } } - fun restoreSessions() { + fun restoreSessions(scanResponse: ScanResponse) { + val walletPublicKey = scanResponse.card.wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 }?.publicKey + ?: return val sessions = walletConnectRepository.loadSavedSessions() + // filter sessions for this particular card + .filter { it.wallet.walletPublicKey.contentEquals(walletPublicKey) } this.sessions = sessions .map { session -> WalletConnectActiveData( @@ -126,8 +132,8 @@ class WalletConnectManager { setListeners(it.client) it.client.connect(it.session, tangemPeerMeta, it.peerId, it.remotePeerId) } - } - .map { it.session to it }.toMap().toMutableMap() + }.associateBy { it.session }.toMutableMap() + store.dispatchOnMain(WalletConnectAction.SetSessionsRestored(sessions)) } diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt index 04f1ec8141..b23a5e1456 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt @@ -92,7 +92,6 @@ class WalletConnectSdkHelper { ) ) val dialogData = TransactionRequestDialogData( - cardId = session.wallet.cardId, dAppName = session.peerMeta.name, dAppUrl = session.peerMeta.url, amount = value.toFormattedString(decimals), @@ -235,7 +234,6 @@ class WalletConnectSdkHelper { val dialogData = PersonalSignDialogData( - cardId = session.wallet.cardId, dAppName = session.peerMeta.name, message = messageString, session = session.session, @@ -272,11 +270,11 @@ class WalletConnectSdkHelper { suspend fun signPersonalMessage(hashToSign: ByteArray, wallet: WalletForSession): String? { val key = wallet.derivedPublicKey ?: wallet.walletPublicKey val command = SignHashCommand(hashToSign, wallet.walletPublicKey!!, wallet.derivationPath) - return when (val result = tangemSdkManager.runTaskAsync(command, wallet.cardId)) { + return when (val result = tangemSdkManager.runTaskAsync(command)) { is CompletionResult.Success -> { val hash = result.data.signature return EthereumUtils.prepareSignedMessageData( - hash, hashToSign, CryptoUtils.decompressPublicKey(key!!) + hash, hashToSign, CryptoUtils.decompressPublicKey(key!!), ) } is CompletionResult.Failure -> { diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WcWalletManagerFactory.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WcWalletManagerFactory.kt index 72134d880b..144f3b873d 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WcWalletManagerFactory.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WcWalletManagerFactory.kt @@ -1,13 +1,10 @@ package com.tangem.tap.domain.walletconnect import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.WalletManagerFactory -import com.tangem.common.card.EllipticCurve import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isTestCard -import com.tangem.tap.domain.extensions.getPrimaryCurve import com.tangem.tap.domain.extensions.makeWalletManagerForApp import com.tangem.tap.domain.tokens.CurrenciesRepository import com.tangem.tap.domain.tokens.models.BlockchainNetwork @@ -17,51 +14,25 @@ import com.tangem.tap.features.wallet.redux.WalletState class WcWalletManagerFactory( private val factory: WalletManagerFactory, private val currenciesRepository: CurrenciesRepository, - ) { - - suspend fun getWalletManager( - wallet: WalletForSession, blockchain: Blockchain, walletState: WalletState +) { + fun getWalletManager( + wallet: WalletForSession, blockchain: Blockchain, walletState: WalletState, ): WalletManager? { val blockchainToMake = if (blockchain == Blockchain.Ethereum && wallet.isTestNet) { Blockchain.EthereumTestnet } else { blockchain } - val blockchainNetwork = BlockchainNetwork( blockchain = blockchainToMake, derivationPath = wallet.derivationPath?.rawPath, - tokens = emptyList() + tokens = emptyList(), ) - - return if (walletState.cardId == wallet.cardId) { - walletState.getWalletManager(blockchainNetwork) - } else { - val blockchainNetworkWithTokens = currenciesRepository - .loadSavedCurrencies( - cardId = wallet.cardId, - isHdWalletSupported = wallet.derivationPath != null - ).firstOrNull { it == blockchainNetwork } - - if (blockchainNetworkWithTokens != null) { - factory.makeWalletManager( - blockchain = blockchainToMake, - publicKey = Wallet.PublicKey( - wallet.walletPublicKey!!, - wallet.derivedPublicKey, - wallet.derivationPath - ), - tokens = blockchainNetworkWithTokens.tokens, - curve = blockchainToMake.getPrimaryCurve() ?: EllipticCurve.Secp256k1 - ) - } else { - null - } - } + return walletState.getWalletManager(blockchainNetwork) } suspend fun getWalletManager( - scanResponse: ScanResponse, blockchain: Blockchain, walletState: WalletState + scanResponse: ScanResponse, blockchain: Blockchain, walletState: WalletState, ): WalletManager? { val card = scanResponse.card val blockchainToMake = if (blockchain == Blockchain.Ethereum && card.isTestCard) { @@ -69,14 +40,13 @@ class WcWalletManagerFactory( } else { blockchain } - val blockchainNetwork = BlockchainNetwork( blockchain = blockchainToMake, - card = card + card = card, ) return if (walletState.cardId == card.cardId) { - walletState.getWalletManager(blockchainNetwork) + walletState.getWalletManager(blockchainNetwork) } else { if (currenciesRepository .loadSavedCurrencies(card.cardId, card.settings.isHDWalletAllowed) @@ -84,7 +54,7 @@ class WcWalletManagerFactory( ) { factory.makeWalletManagerForApp( scanResponse = scanResponse, - blockchainNetwork = blockchainNetwork + blockchainNetwork = blockchainNetwork, ) } else { null diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt index 14a871fbd9..0258af7316 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.details.redux.walletconnect import com.tangem.blockchain.common.Blockchain +import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.redux.NotificationAction import com.tangem.wallet.R import com.trustwallet.walletconnect.models.binance.WCBinanceTradeOrder @@ -11,11 +12,9 @@ import com.trustwallet.walletconnect.models.session.WCSession import org.rekotlin.Action sealed class WalletConnectAction : Action { - + object ResetState : WalletConnectAction() data class HandleDeepLink(val wcUri: String?) : WalletConnectAction() - - object RestoreSessions : WalletConnectAction() - + data class RestoreSessions(val scanResponse: ScanResponse) : WalletConnectAction() data class StartWalletConnect( val copiedUri: String?, ) : WalletConnectAction() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt index d98fb0b0f5..8fdcfa10ce 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt @@ -22,14 +22,13 @@ import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.scope import com.tangem.tap.store -import com.tangem.wallet.R import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.Middleware import timber.log.Timber class WalletConnectMiddleware { - private val walletConnectManager = WalletConnectManager() + private var walletConnectManager = WalletConnectManager() val walletConnectMiddleware: Middleware = { dispatch, state -> { next -> { action -> @@ -43,8 +42,9 @@ class WalletConnectMiddleware { if (DemoHelper.tryHandle(state, action)) return when (action) { + is WalletConnectAction.ResetState -> walletConnectManager = WalletConnectManager() is WalletConnectAction.RestoreSessions -> { - walletConnectManager.restoreSessions() + walletConnectManager.restoreSessions(action.scanResponse) } is WalletConnectAction.HandleDeepLink -> { if (!action.wcUri.isNullOrBlank()) { @@ -74,7 +74,13 @@ class WalletConnectMiddleware { is WalletConnectAction.ChooseNetwork -> { val data = state()?.walletConnectState?.newSessionData ?: return scope.launch { - prepareWalletManager(data.scanResponse, store.state.walletState, action.blockchain, data.session) + prepareWalletManager( + scanResponse = data.scanResponse, + walletState = store.state.walletState, + blockchain = action.blockchain, + session = data.session, + walletConnectManager = walletConnectManager, + ) } } is WalletConnectAction.ShowClipboardOrScanQrDialog -> { @@ -110,7 +116,8 @@ class WalletConnectMiddleware { ) } is WalletConnectAction.ScanCard -> { - scanCard(action.session, action.chainId) + val scanResponse = store.state.globalState.scanResponse ?: return + scanCard(scanResponse, action.session, action.chainId) } is WalletConnectAction.ApproveSession -> { walletConnectManager.approve(action.session) @@ -150,7 +157,6 @@ class WalletConnectMiddleware { data = messageData, session = action.sessionData.session, sessionId = action.id, - cardId = action.sessionData.wallet.cardId, dAppName = action.sessionData.peerMeta.name, ), ), @@ -164,7 +170,6 @@ class WalletConnectMiddleware { data = messageData, session = action.sessionData.session, sessionId = action.id, - cardId = action.sessionData.wallet.cardId, dAppName = action.sessionData.peerMeta.name, ), ), @@ -189,28 +194,26 @@ class WalletConnectMiddleware { currenciesRepository = currenciesRepository, ) val walletState = store.state.walletState - scope.launch { - val walletManager = factory.getWalletManager( - wallet = action.session.wallet, - blockchain = blockchain, - walletState = walletState, - ).guard { - store.dispatchOnMain( - GlobalAction.ShowDialog( - WalletConnectDialog.AddNetwork(blockchain.fullName), - ), - ) - return@launch - } - val updatedWallet = action.session.wallet.copy( - walletPublicKey = walletManager.wallet.publicKey.seedKey, - derivedPublicKey = walletManager.wallet.publicKey.derivedKey, - derivationPath = walletManager.wallet.publicKey.derivationPath, - blockchain = action.blockchain, + val walletManager = factory.getWalletManager( + wallet = action.session.wallet, + blockchain = blockchain, + walletState = walletState, + ).guard { + store.dispatchOnMain( + GlobalAction.ShowDialog( + WalletConnectDialog.AddNetwork(blockchain.fullName), + ), ) - val updatedSession = action.session.copy(wallet = updatedWallet) - store.dispatchOnMain(WalletConnectAction.UpdateBlockchain(updatedSession)) + return } + val updatedWallet = action.session.wallet.copy( + walletPublicKey = walletManager.wallet.publicKey.seedKey, + derivedPublicKey = walletManager.wallet.publicKey.derivedKey, + derivationPath = walletManager.wallet.publicKey.derivationPath, + blockchain = action.blockchain, + ) + val updatedSession = action.session.copy(wallet = updatedWallet) + store.dispatchOnMain(WalletConnectAction.UpdateBlockchain(updatedSession)) } is WalletConnectAction.UpdateBlockchain -> { walletConnectManager.updateBlockchain(action.updatedSession) @@ -218,24 +221,13 @@ class WalletConnectMiddleware { } } - private fun scanCard(session: WalletConnectSession, chainId: Int?) { + private fun scanCard(scanResponse: ScanResponse, session: WalletConnectSession, chainId: Int?) { val blockchain = WalletConnectNetworkUtils.parseBlockchain( chainId = chainId, peer = session.peerMeta, ) ?: Blockchain.Ethereum - store.dispatch( - GlobalAction.ScanCard( - additionalBlockchainsToDerive = listOf(blockchain), - onSuccess = { scanResponse -> - handleScanResponse(scanResponse = scanResponse, session = session, blockchain = blockchain) - }, - onFailure = { - store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession(null)) - }, - R.string.wallet_connect_scan_card_message, - ), - ) + handleScanResponse(scanResponse = scanResponse, session = session, blockchain = blockchain) } private suspend fun getAvailableBlockchains(card: Card, walletState: WalletState): List { @@ -259,6 +251,7 @@ class WalletConnectMiddleware { walletState: WalletState, blockchain: Blockchain, session: WalletConnectSession, + walletConnectManager: WalletConnectManager, ) { val factory = WcWalletManagerFactory( factory = store.state.globalState.tapWalletManager.walletManagerFactory, @@ -273,21 +266,20 @@ class WalletConnectMiddleware { ) return } - val wallet = walletManager.wallet - val derivedKey = - if (wallet.publicKey.blockchainKey.contentEquals(wallet.publicKey.seedKey)) { - null - } else { - walletManager.wallet.publicKey.blockchainKey - } - val walletForSession = WalletForSession( - cardId = scanResponse.card.cardId, - walletPublicKey = wallet.publicKey.seedKey, - derivedPublicKey = derivedKey, - derivationPath = wallet.publicKey.derivationPath, - derivationStyle = scanResponse.card.derivationStyle, - blockchain = wallet.blockchain, - ) + val wallet = walletManager.wallet + val derivedKey = + if (wallet.publicKey.blockchainKey.contentEquals(wallet.publicKey.seedKey)) { + null + } else { + walletManager.wallet.publicKey.blockchainKey + } + val walletForSession = WalletForSession( + walletPublicKey = wallet.publicKey.seedKey, + derivedPublicKey = derivedKey, + derivationPath = wallet.publicKey.derivationPath, + derivationStyle = scanResponse.card.derivationStyle, + blockchain = wallet.blockchain, + ) withMainContext { val updatedSession = session.copy(wallet = walletForSession) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt index 544b6fa7be..e4cc76254c 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectReducer.kt @@ -10,6 +10,7 @@ class WalletConnectReducer { if (action !is WalletConnectAction) return state return when (action) { + is WalletConnectAction.ResetState -> return WalletConnectState() is WalletConnectAction.ApproveSession.Success -> { state.copy( loading = false, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt index 0bdfaf69f6..97afb372a2 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt @@ -40,7 +40,6 @@ data class WalletConnectSession( @JsonClass(generateAdapter = true) data class WalletForSession( - val cardId: String, val walletPublicKey: ByteArray? = null, val derivedPublicKey: ByteArray? = null, val derivationPath: DerivationPath? = null, @@ -59,7 +58,6 @@ data class WalletForSession( other as WalletForSession - if (cardId != other.cardId) return false if (walletPublicKey != null) { if (other.walletPublicKey == null) return false if (!walletPublicKey.contentEquals(other.walletPublicKey)) return false @@ -76,8 +74,7 @@ data class WalletForSession( } override fun hashCode(): Int { - var result = cardId.hashCode() - result = 31 * result + (walletPublicKey?.contentHashCode() ?: 0) + var result = (walletPublicKey?.contentHashCode() ?: 0) result = 31 * result + (derivedPublicKey?.contentHashCode() ?: 0) result = 31 * result + (derivationPath?.hashCode() ?: 0) result = 31 * result + isTestNet.hashCode() @@ -112,7 +109,6 @@ sealed class WalletConnectDialog : StateDialog { val data: BinanceMessageData, val session: WCSession, val sessionId: Long, - val cardId: String, val dAppName: String, ) : WalletConnectDialog() } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt deleted file mode 100644 index 95c28cf26a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.tangem.tap.features.details.ui.walletconnect - -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.chip.Chip -import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction -import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession -import com.tangem.tap.store -import com.tangem.wallet.R - -class WalletConnectSessionsAdapter - : ListAdapter( - DiffUtilCallback -) { - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SessionsViewHolder { - val layout = LayoutInflater.from(parent.context) - .inflate(R.layout.item_wallet_connect_session, parent, false) - return SessionsViewHolder(layout) - } - - override fun onBindViewHolder(holder: SessionsViewHolder, position: Int) { - holder.bind(currentList[position]) - } - - object DiffUtilCallback : DiffUtil.ItemCallback() { - override fun areContentsTheSame( - oldItem: WalletConnectSession, newItem: WalletConnectSession, - ) = oldItem == newItem - - override fun areItemsTheSame( - oldItem: WalletConnectSession, newItem: WalletConnectSession, - ) = oldItem == newItem - } - - class SessionsViewHolder(val view: View) : - RecyclerView.ViewHolder(view) { - - fun bind(session: WalletConnectSession) { - view.findViewById(R.id.tv_card_id).text = view.context.getString( - R.string.wallet_connect_card_number, session.wallet.cardId - ) - view.findViewById(R.id.tv_d_app_name).text = session.peerMeta.name - - view.findViewById(R.id.btn_disconnect).setOnClickListener { - store.dispatch(WalletConnectAction.DisconnectSession(session.session)) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt index 71a9386b36..8474878afc 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt @@ -169,7 +169,6 @@ fun WalletConnectScreenPreview() { sessions = listOf( WcSessionForScreen( description = "session from some dApp", - cardId = "12312312321", sessionId = "", ), ), diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreenState.kt index 44792f9623..e1d915dc5b 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreenState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreenState.kt @@ -11,14 +11,12 @@ data class WalletConnectScreenState( data class WcSessionForScreen( val description: String, - val cardId: String, val sessionId: String, ) { companion object { fun fromSession(session: WalletConnectSession): WcSessionForScreen { return WcSessionForScreen( description = session.peerMeta.name, - cardId = session.wallet.cardId, sessionId = session.session.toUri(), ) } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt index b9fd651bb8..ab95ef6ef8 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt @@ -14,7 +14,6 @@ class ApproveWcSessionDialog { fun create(session: WalletConnectSession, networks: List, context: Context): AlertDialog { val message = context.getString( R.string.wallet_connect_request_session_start, - session.wallet.cardId, session.peerMeta.name, session.peerMeta.url, ) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/BnbTransactionDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/BnbTransactionDialog.kt index 2ec39ca844..3d0fb57930 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/BnbTransactionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/BnbTransactionDialog.kt @@ -15,7 +15,6 @@ class BnbTransactionDialog { data: BinanceMessageData, session: WCSession, sessionId: Long, - cardId: String, dAppName: String, context: Context, ): AlertDialog { @@ -40,7 +39,7 @@ class BnbTransactionDialog { val fullMessage = context.getString( R.string.wallet_connect_bnb_sign_message, - dAppName, cardId, message + dAppName, message, ) val positiveButtonTitle = context.getText(R.string.common_sign) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/PersonalSignDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/PersonalSignDialog.kt index 789384c758..5d6e001087 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/PersonalSignDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/PersonalSignDialog.kt @@ -15,10 +15,12 @@ class PersonalSignDialog { context: Context, ): AlertDialog { val message = - context.getString(R.string.wallet_connect_alert_sign_message, data.cardId) + - context.getString(R.string.wallet_connect_personal_sign_message, - data.dAppName, - data.message) + context.getString(R.string.wallet_connect_alert_sign_message) + + context.getString( + R.string.wallet_connect_personal_sign_message, + data.dAppName, + data.message, + ) return AlertDialog.Builder(context).apply { setTitle(context.getString(R.string.wallet_connect)) setMessage(message) @@ -37,7 +39,6 @@ class PersonalSignDialog { } data class PersonalSignDialogData( - val cardId: String, val dAppName: String, val message: String, val session: WCSession, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/TransactionDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/TransactionDialog.kt index 192fc3d9e1..245cbd2ae0 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/TransactionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/TransactionDialog.kt @@ -17,7 +17,6 @@ class TransactionDialog { ): AlertDialog { val message = context.getString( R.string.wallet_connect_create_tx_message, - data.cardId, data.dAppName, data.dAppUrl, data.amount, @@ -53,7 +52,6 @@ class TransactionDialog { } data class TransactionRequestDialogData( - val cardId: String, val dAppName: String, val dAppUrl: String, val amount: String, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/WcDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/WcDialog.kt index 4bbb63e270..f71c14a348 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/WcDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/WcDialog.kt @@ -45,7 +45,6 @@ data class ButtonData( interface DialogMessageData data class WcTransactionDialogMessageData( - val cardId: String, val dAppName: String, val dAppUrl: String, val amount: String, diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d36add64ec..c0059a0e36 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -328,8 +328,8 @@ %1s (%2s) Эта карта не является векселем на предъявителя. В настоящее время мы не можем сопоставить количество подписей на карте с информацией в блокчейне. Это нормально, но в редких случаях может означать, что предыдущий владелец скрывает автономную подпись, что является проблемой безопасности.\n\nНе принимайте эту карту в качестве физического платежа от кого-то, кому Вы не доверяете.\n\nВо всех остальных отношениях - это совершенно безопасно.\n\nTangem — единственный аппаратный кошелек, предлагающий защиту от подсчета подписей. WalletConnect - Карта %1s\nЗапрос на создание транзакции для %2s\n%3s\n\nСумма: %4s\nКомиссия: %5s\nВсего: %6s\nБаланс: %7s - Запрос на запуск сеанса для карты с идентификатором %1s\nдля %2s\n\nURL: %3s + Запрос на создание транзакции для %1s\n%2s\n\nСумма: %3s\nКомиссия: %4s\nВсего: %5s\nБаланс: %6s + Запрос на запуск сеанса для %1s\n\nURL: %2s Сессии WalletConnect Сеанс WalletConnect открыт с %s Упс. Нет сессий. @@ -338,7 +338,7 @@ Карта: %s Коснитесь карты, чтобы привязать ее WalletConnect Не удается отправить транзакцию. Недостаточно средств. - Просьба подписать сообщение\nкартой %s\n\n + Просьба подписать сообщение\n Сообщение для %s:\n%s Буфер обмена содержит код WalletConnect. Использовать скопированное значение или отсканировать QR-код Вставить из буфера обмена @@ -348,7 +348,7 @@ Операция не может быть завершена. \n\nВы уже установили сеанс WalletConnect с этими параметрами. Не удалось установить сеанс WalletConnect: ошибка времени выполнения. Пожалуйста, повторите попытку позже. Транзакция BNB успешно подписана и отправлена в DApp - DApp %s, запрашивает\nподпись транзакции BNB с\nкартой: %s\n\n%s + DApp %s, запрашивает\nподпись транзакции BNB с\n%s Сведения о транзакции:\nОт: %s\nКому: %s\nСумма: %s Торговый ордер на %s\nЦена: %s\nСумма к получению: %s\nСумма к оплате: %s Мои предложения diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 405518a258..55c6923133 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -140,24 +140,23 @@ Card: %s Tap card to bind to wallet connect - Card: %1s\n - Request to create transaction for %2s - \n%3s + + Request to create transaction for %1s + \n%2s - \n\nAmount: %4s - \nFee: %5s - \nTotal: %6s - \nBalance: %7s + \n\nAmount: %3s + \nFee: %4s + \nTotal: %5s + \nBalance: %6s Can\'t send transaction. Not enough funds. - Request to start a session for card with ID %1s\n - for %2s\n\n + Request to start a session for %1s\n\n - URL: %3s + URL: %2s - Requesting to sign a message\nwith card %s\n\n + Requesting to sign a message\n Message for %s:\n%s @@ -305,8 +304,7 @@ The BNB transaction has been successfully signed and sent to the Dapp Dapp %s, requesting to\n -sign BNB transaction with\n -Card: %s\n +sign BNB transaction \n %s Transaction details:\n From 4e1a0d6c1feaad495dbc4dd98da3a0ade9429157 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Sep 2022 18:38:48 +0300 Subject: [PATCH 12/68] Updated on 2026-08-14 --- app/src/main/assets/testnet_tokens.json | 10 +++++ .../tap/common/extensions/Blockchain.kt | 2 + .../redux/middlewares/AmountMiddleware.kt | 45 ++++++++++++++----- .../send/redux/middlewares/SendMiddleware.kt | 35 ++------------- .../ui/dialogs/SendTransactionFailsDialog.kt | 23 +++++++++- .../features/wallet/models/WalletWarning.kt | 5 +++ .../tap/features/wallet/redux/WalletState.kt | 34 ++++++++++---- .../redux/reducers/MultiWalletReducer.kt | 21 ++++++++- .../wallet/ui/WalletWarningConverter.kt | 6 +++ app/src/main/res/values-de/strings_final.xml | 10 +---- app/src/main/res/values-fr/strings_final.xml | 10 +---- app/src/main/res/values-it/strings_final.xml | 11 +---- app/src/main/res/values-ru/strings_final.xml | 16 +------ app/src/main/res/values/strings_final.xml | 16 +------ dependencies.gradle | 2 +- .../domain/common/extensions/Blockchain.kt | 5 +++ 16 files changed, 137 insertions(+), 114 deletions(-) diff --git a/app/src/main/assets/testnet_tokens.json b/app/src/main/assets/testnet_tokens.json index 84c055f105..179a72b282 100644 --- a/app/src/main/assets/testnet_tokens.json +++ b/app/src/main/assets/testnet_tokens.json @@ -420,6 +420,16 @@ "networkId" : "stellar/test" } ] + }, + { + "id" : "polkadot", + "symbol" : "DOT", + "name" : "Polkadot", + "networks" : [ + { + "networkId" : "polkadot/test" + } + ] } ], diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt index e2490e7886..73f63aa2a8 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt @@ -28,6 +28,7 @@ fun Blockchain.getRoundIconRes(): Int { Blockchain.Dogecoin -> R.drawable.ic_dogecoin_round Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_round Blockchain.Gnosis -> R.drawable.ic_gnosis_round + Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.ic_polkadot_round else -> R.drawable.ic_tangem_logo } } @@ -55,6 +56,7 @@ fun Blockchain.getGreyedOutIconRes(): Int { Blockchain.Dogecoin -> R.drawable.ic_dogecoin_no_color Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_no_color Blockchain.Gnosis -> R.drawable.ic_gnosis_no_color + Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.ic_polkadot_no_color else -> R.drawable.ic_tangem_logo } } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index 3d59d0a270..bfcbc36889 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -4,11 +4,17 @@ import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.TransactionError import com.tangem.common.extensions.isZero import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.send.redux.* +import com.tangem.tap.features.send.redux.AmountAction +import com.tangem.tap.features.send.redux.AmountActionUi +import com.tangem.tap.features.send.redux.FeeAction +import com.tangem.tap.features.send.redux.FeeActionUi +import com.tangem.tap.features.send.redux.ReceiptAction +import com.tangem.tap.features.send.redux.SendAction import com.tangem.tap.features.send.redux.states.MainCurrencyType import com.tangem.tap.features.send.redux.states.SendState import org.rekotlin.Action import java.math.BigDecimal +import java.util.* /** [REDACTED_AUTHOR] @@ -62,18 +68,11 @@ class AmountMiddleware { val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend(inputCrypto)) val transactionErrors = walletManager.validateTransaction(amountToSend, sendState.feeState.currentFee) - transactionErrors.remove(TransactionError.TezosSendAll) - if (transactionErrors.isEmpty()) { + val amountFieldErrors = filterErrorsForAmountField(transactionErrors) + if (amountFieldErrors.isEmpty()) { dispatch(AmountAction.SetAmountError(null)) } else { - val amountErrors = extractErrorsForAmountField(transactionErrors) - if (amountErrors.isNotEmpty()) { - transactionErrors.removeAll(amountErrors) - dispatch(AmountAction.SetAmountError(createValidateTransactionError(amountErrors, walletManager))) - } - if (transactionErrors.isNotEmpty()) { - dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager))) - } + dispatch(AmountAction.SetAmountError(createValidateTransactionError(amountFieldErrors, walletManager))) } dispatch(ReceiptAction.RefreshReceipt) dispatch(SendAction.ChangeSendButtonState(sendState.getButtonState())) @@ -104,4 +103,28 @@ class AmountMiddleware { dispatch(AmountActionUi.SetMainCurrency(type)) } +} + +private fun filterErrorsForAmountField(errors: EnumSet): EnumSet { + val showIntoAmountField = EnumSet.noneOf(TransactionError::class.java) + errors.forEach { + when (it) { + TransactionError.AmountExceedsBalance -> { + showIntoAmountField.remove(TransactionError.TotalExceedsBalance) + showIntoAmountField.add(it) + } + TransactionError.FeeExceedsBalance -> { + showIntoAmountField.remove(TransactionError.TotalExceedsBalance) + showIntoAmountField.add(it) + } + TransactionError.TotalExceedsBalance -> { + val notAcceptable = listOf(TransactionError.AmountExceedsBalance, TransactionError.FeeExceedsBalance) + if (!showIntoAmountField.containsAll(notAcceptable)) showIntoAmountField.add(it) + } + else -> showIntoAmountField.add(it) + } + } + showIntoAmountField.remove(TransactionError.TezosSendAll) + + return showIntoAmountField } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index df1e3dd5ba..ee1b5eb1d2 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 @@ -114,9 +114,8 @@ private fun verifyAndSendTransaction( val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend()) val transactionErrors = walletManager.validateTransaction(amountToSend, feeAmount) - val hadTezosError = transactionErrors.remove(TransactionError.TezosSendAll) when { - hadTezosError -> { + transactionErrors.contains(TransactionError.TezosSendAll) -> { val reduceAmount = walletManager.wallet.blockchain.minimalAmount() dispatch( SendAction.Dialog.TezosWarningDialog( @@ -135,9 +134,6 @@ private fun verifyAndSendTransaction( ), ) } - transactionErrors.isNotEmpty() -> { - dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager))) - } else -> { sendTransaction( action, walletManager, amountToSend, feeAmount, destinationAddress, @@ -272,10 +268,8 @@ private fun sendTransaction( dispatch(SendAction.Dialog.SendTransactionFails.CardSdkError(tangemSdkError)) } is BlockchainSdkError.CreateAccountUnderfunded -> { - // from XLM, XRP - val reserve = error.minReserve.value?.stripZeroPlainString() ?: "0" - val symbol = error.minReserve.currencySymbol - dispatch(SendAction.SendError(TapError.CreateAccountUnderfunded(listOf(reserve, symbol)))) + // from XLM, XRP, Polkadot + dispatch(SendAction.Dialog.SendTransactionFails.BlockchainSdkError(error)) } else -> { when { @@ -300,29 +294,6 @@ private fun sendTransaction( } } -fun extractErrorsForAmountField(errors: EnumSet): EnumSet { - val showIntoAmountField = EnumSet.noneOf(TransactionError::class.java) - errors.forEach { - when (it) { - TransactionError.AmountExceedsBalance -> { - showIntoAmountField.remove(TransactionError.TotalExceedsBalance) - showIntoAmountField.add(it) - } - TransactionError.FeeExceedsBalance -> { - showIntoAmountField.remove(TransactionError.TotalExceedsBalance) - showIntoAmountField.add(it) - } - TransactionError.TotalExceedsBalance -> { - val notAcceptable = listOf(TransactionError.AmountExceedsBalance, TransactionError.FeeExceedsBalance) - if (!showIntoAmountField.containsAll(notAcceptable)) showIntoAmountField.add(it) - } - TransactionError.InvalidAmountValue -> showIntoAmountField.add(it) - TransactionError.InvalidFeeValue -> showIntoAmountField.add(it) - } - } - return showIntoAmountField -} - fun createValidateTransactionError( errorList: EnumSet, walletManager: WalletManager, diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/SendTransactionFailsDialog.kt b/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/SendTransactionFailsDialog.kt index a01c048058..a4b5ff7539 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/SendTransactionFailsDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/SendTransactionFailsDialog.kt @@ -2,7 +2,10 @@ package com.tangem.tap.features.send.ui.dialogs import android.content.Context import androidx.appcompat.app.AlertDialog +import com.tangem.blockchain.common.BlockchainSdkError +import com.tangem.common.module.ModuleMessageConverter import com.tangem.tangem_sdk_new.extensions.localizedDescription +import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.common.feedback.SendTransactionFailedEmail import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.send.redux.SendAction @@ -13,14 +16,14 @@ import com.tangem.wallet.R [REDACTED_AUTHOR] */ class SendTransactionFailsDialog { - companion object { fun create(context: Context, dialog: SendAction.Dialog.SendTransactionFails.CardSdkError): AlertDialog { return create(context, dialog.error.localizedDescription(context)) } fun create(context: Context, dialog: SendAction.Dialog.SendTransactionFails.BlockchainSdkError): AlertDialog { - return create(context, dialog.error.customMessage) + val errorConverter = BlockchainSdkErrorConverter(context) + return create(context, errorConverter.convert(dialog.error)) } private fun create(context: Context, errorMessage: String): AlertDialog { @@ -35,4 +38,20 @@ class SendTransactionFailsDialog { }.create() } } +} + +private class BlockchainSdkErrorConverter( + private val context: Context, +) : ModuleMessageConverter { + + override fun convert(message: BlockchainSdkError): String { + return when (message) { + is BlockchainSdkError.CreateAccountUnderfunded -> { + val reserve = message.minReserve.value?.stripZeroPlainString() ?: "0" + val symbol = message.minReserve.currencySymbol + context.getString(R.string.send_error_no_target_account, reserve, symbol) + } + else -> message.customMessage + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/WalletWarning.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/WalletWarning.kt index 0b4a56fa11..8923b18d6e 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/models/WalletWarning.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/models/WalletWarning.kt @@ -3,6 +3,11 @@ package com.tangem.tap.features.wallet.models sealed class WalletWarning( val showingPosition: Int, ) { + data class ExistentialDeposit( + val blockchainFullName: String, + val existentialDepositString: String, + ) : WalletWarning(1) + object TransactionInProgress : WalletWarning(10) data class BalanceNotEnoughForFee(val blockchainFullName: String) : WalletWarning(30) data class Rent(val walletRent: WalletRent) : WalletWarning(40) 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 48c886d939..a5c85a49fb 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 @@ -325,9 +325,6 @@ data class Artwork( 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" - - const val TEMP_CARDANO = - "https://verify.tangem.com/card/artwork?artworkId=card_ru039&CID=CB19000000040976&publicKey=0416E29423A6CC77CD07CBA52873E8F6F894B1AFB18EB3688ACC2C8D8E5AC84B80B0BA1B17B85E578E47044CE96BCFF3FB4499FA4941CAD3C1EF300A492B5B9659" } } @@ -342,6 +339,7 @@ data class WalletData( val mainButton: WalletMainButton = WalletMainButton.SendButton(false), val currency: Currency, val walletRent: WalletRent? = null, + val existentialDepositString: String? = null, ) { val isAvailableToBuy: Boolean get() = store.state.globalState.exchangeManager.availableForBuy(currency) @@ -362,18 +360,38 @@ data class WalletData( fun assembleWarnings(): List { val walletWarnings = mutableListOf() + assembleNonTypedWarnings(walletWarnings) + assembleBlockchainWarnings(walletWarnings) + assembleTokenWarnings(walletWarnings) + + return walletWarnings.sortedBy { it.showingPosition } + } + + private fun assembleNonTypedWarnings(walletWarnings: MutableList) { if (currencyData.status == BalanceStatus.SameCurrencyTransactionInProgress) { walletWarnings.add(WalletWarning.TransactionInProgress) } + } + + private fun assembleBlockchainWarnings(walletWarnings: MutableList) { + if (!currency.isBlockchain()) return + + val blockchainFullName = currency.blockchain.fullName + if (existentialDepositString != null) { + walletWarnings.add(WalletWarning.ExistentialDeposit(blockchainFullName, existentialDepositString)) + } if (walletRent != null) { walletWarnings.add(WalletWarning.Rent(walletRent)) } - if (!currency.isBlockchain() && (blockchainAmountIsEmpty() && !tokenAmountIsEmpty())) { - val fullName = currency.blockchain.fullName - walletWarnings.add(WalletWarning.BalanceNotEnoughForFee(fullName)) - } + } - return walletWarnings.sortedBy { it.showingPosition } + private fun assembleTokenWarnings(walletWarnings: MutableList){ + if (!currency.isToken()) return + + val blockchainFullName = currency.blockchain.fullName + if ((blockchainAmountIsEmpty() && !tokenAmountIsEmpty())) { + walletWarnings.add(WalletWarning.BalanceNotEnoughForFee(blockchainFullName)) + } } private fun blockchainAmountIsEmpty(): Boolean = currencyData.blockchainAmount?.isZero() == true diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index e8f9551910..9821f1f6a7 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -1,15 +1,25 @@ package com.tangem.tap.features.wallet.redux.reducers +import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.guard import com.tangem.tap.common.extensions.toFiatString import com.tangem.tap.common.extensions.toFormattedCurrencyString import com.tangem.tap.domain.getFirstToken import com.tangem.tap.domain.tokens.models.BlockchainNetwork -import com.tangem.tap.features.wallet.models.* -import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.models.Currency +import com.tangem.tap.features.wallet.models.WalletRent +import com.tangem.tap.features.wallet.models.filterByToken +import com.tangem.tap.features.wallet.models.getPendingTransactions +import com.tangem.tap.features.wallet.models.removeUnknownTransactions +import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.features.wallet.redux.WalletData +import com.tangem.tap.features.wallet.redux.WalletMainButton +import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN +import com.tangem.tap.features.wallet.redux.WalletStore import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.features.wallet.ui.TokenData @@ -25,6 +35,7 @@ class MultiWalletReducer { it.wallet.blockchain == blockchain.blockchain && (it.wallet.publicKey.derivationPath?.rawPath == blockchain.derivationPath) } ?: return@mapNotNull null + val wallet = walletManager.wallet val cardToken = if (!state.isMultiwalletAllowed) { wallet.getFirstToken()?.symbol?.let { TokenData("", tokenSymbol = it) } @@ -44,6 +55,7 @@ class MultiWalletReducer { blockchain.blockchain, blockchain.derivationPath ), + existentialDepositString = getExistentialDeposit(walletManager), ) WalletStore( @@ -79,6 +91,7 @@ class MultiWalletReducer { action.blockchain.blockchain, action.blockchain.derivationPath ), + existentialDepositString = getExistentialDeposit(walletManager), ) val walletStore = WalletStore( walletManager = walletManager, @@ -166,6 +179,10 @@ class MultiWalletReducer { it.walletRent != null }?.walletRent } + + private fun getExistentialDeposit(walletManager: WalletManager?): String? { + return (walletManager as? ExistentialDepositProvider)?.getExistentialDeposit()?.toPlainString() + } } private fun addTokens( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt index 1e9e127e59..1f319a2a0b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt @@ -15,6 +15,12 @@ class WalletWarningConverter( override fun convert(message: WalletWarning): WalletWarningDescription { val warningMessage = when (message) { + is WalletWarning.ExistentialDeposit -> { + context.getString( + R.string.warning_existential_deposit_message, + message.blockchainFullName, message.existentialDepositString + ) + } is WalletWarning.BalanceNotEnoughForFee -> { context.getString( R.string.token_details_send_blocked_fee_format, diff --git a/app/src/main/res/values-de/strings_final.xml b/app/src/main/res/values-de/strings_final.xml index 96c0876eff..20ebb2312d 100644 --- a/app/src/main/res/values-de/strings_final.xml +++ b/app/src/main/res/values-de/strings_final.xml @@ -38,30 +38,25 @@ You are currently running in Demo mode. All funds are not real. This feature is disabled in Demo mode Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first. - Available networks Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds. Tokens in Solana network are not supported by this card due to firmware limitation. Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss. Contract address copied! If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds - Custom Notice Attention The server is not available, please try again later - Hide token Hide %s Hide You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. - %s network not found. Please, add it first and try again. This network is not supported. Please select another network. %s network - Card Settings Security Mode Selected application protection method @@ -81,18 +76,15 @@ This will delete all the saved wallet access codes. Any further operation with the wallet will require submitting the access code. WalletConnect Connect to Dapps - Link More Cards You can synchronize up to three cards into one wallet. It can only be done once. - Privacy policy - Reset to factory settings This action will completely remove the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. I understand that after performing this action, I will no longer have access to the current wallet Reset the card Reset to Factory Settings Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. - Select network + %s network has a concept of Existential Deposit. If your account drops below %s it will be deactivated and any remaining funds will be destroyed. \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings_final.xml b/app/src/main/res/values-fr/strings_final.xml index 3fe6eb9f17..9433ca3e3a 100644 --- a/app/src/main/res/values-fr/strings_final.xml +++ b/app/src/main/res/values-fr/strings_final.xml @@ -38,30 +38,25 @@ You are currently running in Demo mode. All funds are not real. This feature is disabled in Demo mode Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first. - Available networks Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds. Tokens in Solana network are not supported by this card due to firmware limitation. Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss. Contract address copied! If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds - Custom The server is not available, please try again later Notice Attention - Hide token Hide %s Hide You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. - %s network not found. Please, add it first and try again. This network is not supported. Please select another network. %s network - Card Settings Security Mode Selected application protection method @@ -81,18 +76,15 @@ This will delete all the saved wallet access codes. Any further operation with the wallet will require submitting the access code. WalletConnect Connect to Dapps - Link More Cards You can synchronize up to three cards into one wallet. It can only be done once. - Privacy policy - Reset to factory settings This action will completely remove the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. I understand that after performing this action, I will no longer have access to the current wallet Reset the card Reset to Factory Settings Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. - Select network + %s network has a concept of Existential Deposit. If your account drops below %s it will be deactivated and any remaining funds will be destroyed. \ No newline at end of file diff --git a/app/src/main/res/values-it/strings_final.xml b/app/src/main/res/values-it/strings_final.xml index afe988cb58..9433ca3e3a 100644 --- a/app/src/main/res/values-it/strings_final.xml +++ b/app/src/main/res/values-it/strings_final.xml @@ -38,31 +38,25 @@ You are currently running in Demo mode. All funds are not real. This feature is disabled in Demo mode Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first. - Available networks Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds. Tokens in Solana network are not supported by this card due to firmware limitation. Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss. Contract address copied! If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds - Custom The server is not available, please try again later Notice Attention - Hide token Hide %s Hide You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. - %s network not found. Please, add it first and try again. This network is not supported. Please select another network. - %s network - Card Settings Security Mode Selected application protection method @@ -82,18 +76,15 @@ This will delete all the saved wallet access codes. Any further operation with the wallet will require submitting the access code. WalletConnect Connect to Dapps - Link More Cards You can synchronize up to three cards into one wallet. It can only be done once. - Privacy policy - Reset to factory settings This action will completely remove the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. I understand that after performing this action, I will no longer have access to the current wallet Reset the card Reset to Factory Settings Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. - Select network + %s network has a concept of Existential Deposit. If your account drops below %s it will be deactivated and any remaining funds will be destroyed. \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings_final.xml b/app/src/main/res/values-ru/strings_final.xml index 359b5c0488..f475af97dc 100644 --- a/app/src/main/res/values-ru/strings_final.xml +++ b/app/src/main/res/values-ru/strings_final.xml @@ -38,47 +38,36 @@ Приложение работает в демонстрационном режиме. Средства на всех счетах ненастоящие. Эта функция недоступна в демонстрационном режиме Недостаточно средств для комиссии на вашем %s кошельке для отправки транзакции. Сначала пополните свой %s кошелек. - Доступные сети Внимание! Валюты на разных сетях имеют разные адреса. Убедитесь, что адрес соответствует сети, в которой вы отправляете средства. Токены в сети Solana не поддерживаются этой картой из-за ограничений прошивки. Не осуществляйте перевод на токены в данной сети, иначе это может привести к их безвозвратной утере. Адрес контракта скопирован! Если вы совершили ошибку с выбором сети при переводе средств с биржи, эта инструкция поможет вам восстановить средства - Пользовательский Уведомление Внимание Сервер недоступен, повторите попытку позднее - Баланс В сумме учтены не все монеты Управление токенами Нет цены - Скрыть токен Скрыть %s Скрыть Вы скрываете токен с главного экрана, но в любой момент сможете добавить его обратно через страницу управления токенами. Невозможно скрыть %s - Токен %s является основной валютой в сети %s и не может быть скрыт до тех пор, пока у вас в списке есть другие токены этой сети. - Сеть %s не найдена. Пожалуйста, добавьте её и попробуйте заново. Сеть не поддерживается. Пожалуйста, выберите другую сеть. - Сеть %s - Бэкап кошелька не был произведен Чтобы защитить свои активы, мы советуем вам выполнить эту процедуру - Карты банков РФ в данный момент не принимаются У вас есть карта банка другой страны или платежной системы UnionPay? Да - Чат Tangem Bot - Настройки карты Тип безопасности Выбранный способ защиты приложения @@ -98,18 +87,15 @@ Все сохраненные коды доступа будут удалены. Вам потребуется вводить код доступа при работе с кошельком. WalletConnect Подключение к Dapps - Добавить еще карты Вы можете объединить до трех карт в одном кошельке. Это можно сделать только один раз. - Privacy policy - Сброс к заводским настройкам Это действие приведет к полному удалению кошелька на этой карте. Кошелек невозможно будет восстановить или использовать данную карту для восстановления кода доступа Я понимаю, что после выполнения этого действия у меня больше не будет доступа к текущему кошельку Сбросить карту Сброс к заводским настройкам Сброс к заводским настройкам приведет к полному удалению кошелька с выбранной карты. Вы не сможете восстановить текущий кошелек или использовать эту карту для восстановления кода доступа. - Выберите сеть + Сеть %s использует концепцию экзистенциального депозита. Если баланс вашего счета опустится ниже %s, он будет деактивирован, а все оставшиеся средства будут уничтожены. diff --git a/app/src/main/res/values/strings_final.xml b/app/src/main/res/values/strings_final.xml index ca04743898..c0c24db28f 100644 --- a/app/src/main/res/values/strings_final.xml +++ b/app/src/main/res/values/strings_final.xml @@ -38,49 +38,38 @@ You are currently running in Demo mode. All funds are not real. This feature is disabled in Demo mode Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first. - Available networks Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds. Tokens in Solana network are not supported by this card due to firmware limitation. Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss. Contract address copied! If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds - Custom Notice Attention The server is not available, please try again later - Total balance The amount does not include some of your funds Manage tokens No rate - Hide token Hide %s Hide You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. - %s network not found. Please, add it first and try again. This network is not supported. Please select another network. - %s network - Your wallet has not been backed up To protect your assets, we advise you to carry out this procedure Remove token - Russian bank cards are not accepted at the moment Do you have a bank card of another country or a UnionPay card? Yes No - Chat Tangem Bot - - Card Settings Security Mode Selected application protection method @@ -100,18 +89,15 @@ This will delete all the saved wallet access codes. Any further operation with the wallet will require submitting the access code. WalletConnect Connect to Dapps - Link More Cards You can synchronize up to three cards into one wallet. It can only be done once. - Privacy policy - Reset to factory settings This action will completely remove the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. I understand that after performing this action, I will no longer have access to the current wallet Reset the card Reset to Factory Settings Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code. - Select network + %s network has a concept of Existential Deposit. If your account drops below %s it will be deactivated and any remaining funds will be destroyed. diff --git a/dependencies.gradle b/dependencies.gradle index e1c383532f..4717ab51df 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -2,7 +2,7 @@ ext.versions = [ kotlin : '1.6.10', build_gradle : '7.1.3', tangem_card_sdk : 'develop-159', - tangem_blockchain_sdk: 'develop-105', + tangem_blockchain_sdk: 'develop-107', // tangem_blockchain_sdk: '0.0.1', ] diff --git a/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt b/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt index 8708f1a0a8..139bc99365 100644 --- a/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt +++ b/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt @@ -38,6 +38,8 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? { "tron/test" -> Blockchain.TronTestnet "xrp", "ripple" -> Blockchain.XRP "xdai" -> Blockchain.Gnosis + "polkadot" -> Blockchain.Polkadot + "polkadot/test" -> Blockchain.PolkadotTestnet else -> null } } @@ -80,6 +82,8 @@ fun Blockchain.toNetworkId(): String { Blockchain.Tron -> "tron" Blockchain.TronTestnet -> "tron/test" Blockchain.Gnosis -> "xdai" + Blockchain.Polkadot -> "polkadot" + Blockchain.PolkadotTestnet -> "polkadot/test" } } @@ -105,6 +109,7 @@ fun Blockchain.toCoinId(): String { Blockchain.Dogecoin -> "dogecoin" Blockchain.Tron, Blockchain.TronTestnet -> "tron" Blockchain.Gnosis -> "xdai" + Blockchain.Polkadot, Blockchain.PolkadotTestnet -> "polkadot" Blockchain.Unknown -> "unknown" } } \ No newline at end of file From 00740e43139b82394cf390458527fd607298326d Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Sep 2022 22:41:45 +0300 Subject: [PATCH 13/68] Updated on 2026-08-14 --- .idea/codeStyles/Project.xml | 2 -- .../tangem/tap/features/wallet/models/WalletWarning.kt | 3 ++- .../com/tangem/tap/features/wallet/redux/WalletState.kt | 8 ++++++-- .../tap/features/wallet/ui/WalletWarningConverter.kt | 6 +++--- app/src/main/res/values-de/strings_final.xml | 2 +- app/src/main/res/values-fr/strings_final.xml | 2 +- app/src/main/res/values-it/strings_final.xml | 2 +- app/src/main/res/values-ru/strings_final.xml | 2 +- app/src/main/res/values/strings_final.xml | 2 +- 9 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 3ab743df69..2add9b412a 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -29,7 +29,6 @@