From 94192eba6804e681372fe97a33713ba0a1e78add Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Jun 2021 10:04:37 +0300 Subject: [PATCH 1/6] Updated on 2026-08-14 --- .../java/com/tangem/tap/common/DialogManager.kt | 14 +++++++++++++- .../domain/walletconnect/WalletConnectManager.kt | 4 ++++ .../redux/walletconnect/WalletConnectAction.kt | 2 ++ .../walletconnect/WalletConnectMiddleware.kt | 6 ++++++ .../redux/walletconnect/WalletConnectReducer.kt | 3 ++- .../redux/walletconnect/WalletConnectState.kt | 1 + ...pportedCardDialog.kt => SimpleAlertDialog.kt} | 16 ++++++++++------ app/src/main/res/values/strings_untranslated.xml | 2 ++ 8 files changed, 40 insertions(+), 8 deletions(-) rename app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/{UnsupportedCardDialog.kt => SimpleAlertDialog.kt} (53%) 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 1de2e9cb6d..96992a5d7a 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -6,6 +6,7 @@ import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.features.details.redux.walletconnect.WalletConnectDialog import com.tangem.tap.features.details.ui.walletconnect.dialogs.* import com.tangem.tap.store +import com.tangem.wallet.R import org.rekotlin.StoreSubscriber class DialogManager : StoreSubscriber { @@ -38,7 +39,18 @@ class DialogManager : StoreSubscriber { when (state.dialog) { is WalletConnectDialog.UnsupportedCard -> - dialog = UnsupportedCardDialog.create(context) + dialog = SimpleAlertDialog.create( + titleRes = R.string.wallet_connect, + messageRes = R.string.wallet_connect_scanner_error_no_ethereum_wallet, + context = context + ) + is WalletConnectDialog.OpeningSessionRejected -> { + dialog = SimpleAlertDialog.create( + titleRes = R.string.wallet_connect, + messageRes = R.string.wallet_connect_same_wcuri, + context = context + ) + } is WalletConnectDialog.ApproveWcSession -> dialog = ApproveWcSessionDialog.create(state.dialog.session, context) is WalletConnectDialog.ClipboardOrScanQr -> 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 442b46ce83..44eece7399 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 @@ -44,6 +44,10 @@ class WalletConnectManager { fun connect(wcUri: String, wallet: WalletForSession) { val session = WCSession.from(wcUri) ?: return + if (sessions[session] != null) { + store.dispatchOnMain(WalletConnectAction.RefuseOpeningSession) + return + } val client = WCClient(httpClient = okHttpClient) setListeners(client) val peerId = UUID.randomUUID().toString() 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 6e950a1cab..a2308891de 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 @@ -29,6 +29,8 @@ sealed class WalletConnectAction : Action { val wallet: WalletForSession, ) : WalletConnectAction() + object RefuseOpeningSession : WalletConnectAction() + data class AcceptOpeningSession(val session: WalletConnectSession) : WalletConnectAction() data class ApproveSession( 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 2aa35ae196..f3c581daf4 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 @@ -115,6 +115,12 @@ class WalletConnectMiddleware { ) } + is WalletConnectAction.RefuseOpeningSession -> { + store.dispatch(GlobalAction.ShowDialog( + WalletConnectDialog.OpeningSessionRejected + )) + } + is WalletConnectAction.AcceptOpeningSession -> { store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.ApproveWcSession( action.session))) 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 17669f9451..df3eec9834 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 @@ -25,8 +25,9 @@ class WalletConnectReducer { state.copy(sessions = sessions) } is WalletConnectAction.ScanCard -> state.copy(loading = true) - is WalletConnectAction.UnsupportedCard -> state.copy(loading = false) + is WalletConnectAction.UnsupportedCard -> state.copy(loading = false) + is WalletConnectAction.RefuseOpeningSession -> state.copy(loading = false) is WalletConnectAction.FailureEstablishingSession -> state.copy(loading = false) else -> state 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 369ae46dc0..f5b7ce0c5f 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 @@ -41,6 +41,7 @@ data class WalletForSession( sealed class WalletConnectDialog : StateDialog { data class ClipboardOrScanQr(val clipboardUri: String) : WalletConnectDialog() object UnsupportedCard : WalletConnectDialog() + object OpeningSessionRejected : WalletConnectDialog() data class ApproveWcSession(val session: WalletConnectSession) : WalletConnectDialog() data class RequestTransaction(val dialogData: TransactionRequestDialogData) : WalletConnectDialog() diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/UnsupportedCardDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/SimpleAlertDialog.kt similarity index 53% rename from app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/UnsupportedCardDialog.kt rename to app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/SimpleAlertDialog.kt index cd408d7cd2..f4efd59532 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/UnsupportedCardDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/SimpleAlertDialog.kt @@ -6,15 +6,19 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.store import com.tangem.wallet.R -class UnsupportedCardDialog { +class SimpleAlertDialog { companion object { - fun create(context: Context): AlertDialog { + fun create( + titleRes: Int, + messageRes: Int, + buttonRes: Int = R.string.common_ok, + context: Context, + ): AlertDialog { return AlertDialog.Builder(context).apply { - setTitle(context.getString(R.string.wallet_connect)) - setMessage(context.getText(R.string.wallet_connect_scanner_error_no_ethereum_wallet)) - setPositiveButton(context.getText(R.string.common_ok)) { _, _ -> } -// setNegativeButton(context.getText(R.string.common_reject)) { _, _ -> } + setTitle(context.getString(titleRes)) + setMessage(context.getText(messageRes)) + setPositiveButton(context.getText(buttonRes)) { _, _ -> } setOnDismissListener { store.dispatch(GlobalAction.HideDialog) } diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index ef04081bbb..d6c4426536 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -154,4 +154,6 @@ this wallet. Paste from clipboard Scan new code This card can’t be used to establish WalletConnect session + The operation couldn\'t be completed + The operation couldn\'t be completed. \n\nYou have already established a WalletConnect session with this parameters. From 3bb9672c2138bd23682c0b7130d432f68c8f7b43 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Jun 2021 10:23:42 +0300 Subject: [PATCH 2/6] Updated on 2026-08-14 --- .../details/redux/walletconnect/WalletConnectAction.kt | 2 +- .../redux/walletconnect/WalletConnectMiddleware.kt | 10 +++++++++- .../ui/walletconnect/dialogs/ApproveWcSessionDialog.kt | 4 +++- 3 files changed, 13 insertions(+), 3 deletions(-) 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 a2308891de..728a8d0446 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 @@ -39,7 +39,7 @@ sealed class WalletConnectAction : Action { data class Success(val session: WalletConnectSession) : WalletConnectAction() } - object FailureEstablishingSession : WalletConnectAction() + data class FailureEstablishingSession(val session: WCSession?) : WalletConnectAction() data class SetSessionsRestored(val sessions: List) : 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 f3c581daf4..a58ba756ec 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 @@ -98,12 +98,20 @@ class WalletConnectMiddleware { )) } is CompletionResult.Failure -> - store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession) + store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession( + null + )) } } } } + is WalletConnectAction.FailureEstablishingSession -> { + if (action.session != null) { + walletConnectManager.disconnect(action.session) + } + } + is WalletConnectAction.UnsupportedCard -> { store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedCard)) } 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 0b6a55899b..84b9151436 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 @@ -25,7 +25,9 @@ class ApproveWcSessionDialog { session.session )) } - setNegativeButton(context.getText(R.string.common_reject)) { _, _ -> } + setNegativeButton(context.getText(R.string.common_reject)) { _, _ -> + store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session)) + } setOnDismissListener { store.dispatch(GlobalAction.HideDialog) } From 7e9b5d1cdc0216c1696610ba1b4b47464fb7de78 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Jun 2021 10:24:27 +0300 Subject: [PATCH 3/6] Updated on 2026-08-14 --- .../layout/fragment_wallet_connect_sessions.xml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/layout/fragment_wallet_connect_sessions.xml b/app/src/main/res/layout/fragment_wallet_connect_sessions.xml index cf92a1ed6d..a2990696a4 100644 --- a/app/src/main/res/layout/fragment_wallet_connect_sessions.xml +++ b/app/src/main/res/layout/fragment_wallet_connect_sessions.xml @@ -31,14 +31,6 @@ android:layout_marginTop="16dp" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - - - + + Date: Fri, 18 Jun 2021 10:51:27 +0300 Subject: [PATCH 4/6] Updated on 2026-08-14 --- .../walletconnect/WalletConnectMiddleware.kt | 117 ++++++++++-------- 1 file changed, 68 insertions(+), 49 deletions(-) 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 a58ba756ec..89bec71f1f 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.details.redux.walletconnect import com.tangem.blockchain.common.* +import com.tangem.commands.common.card.Card import com.tangem.common.CompletionResult import com.tangem.common.extensions.toHexString import com.tangem.tap.* @@ -14,6 +15,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.extensions.makeWalletManagerForApp import com.tangem.tap.domain.isMultiwalletAllowed import com.tangem.tap.domain.walletconnect.WalletConnectManager +import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -55,55 +57,7 @@ class WalletConnectMiddleware { } is WalletConnectAction.ScanCard -> { - scope.launch { - val result = tangemSdkManager.scanNote( - FirebaseAnalyticsHandler, - R.string.wallet_connect_scan_card_message - ) - withContext(Dispatchers.Main) { - when (result) { - is CompletionResult.Success -> { - val card = result.data.card - val factory = - store.state.globalState.tapWalletManager.walletManagerFactory - - val walletManager = if (card.isMultiwalletAllowed) { - if (currenciesRepository.loadCardCurrencies(card.cardId)?.blockchains?.contains( - Blockchain.Ethereum) == true - ) { - factory.makeWalletManagerForApp(result.data.card, - Blockchain.Ethereum) - } else { - factory.makeWalletManagerForApp(result.data.card, - Blockchain.Ethereum)?.also { - currenciesRepository.saveAddedBlockchain(card.cardId, - Blockchain.Ethereum) - } - } - } else { - null - } - if (walletManager == null) { - store.dispatchOnMain(WalletConnectAction.UnsupportedCard) - return@withContext - }; - - val key = walletManager.wallet.publicKey - store.dispatchOnMain(WalletConnectAction.OpenSession( - wcUri = action.wcUri, - wallet = WalletForSession( - card.cardId, key.toHexString(), - isTestNet = false - ), - )) - } - is CompletionResult.Failure -> - store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession( - null - )) - } - } - } + handleScanCard(action.wcUri) } is WalletConnectAction.FailureEstablishingSession -> { @@ -171,4 +125,69 @@ class WalletConnectMiddleware { } } } + + private fun handleScanCard(wcUri: String) { + scope.launch { + val result = tangemSdkManager.scanNote( + FirebaseAnalyticsHandler, + R.string.wallet_connect_scan_card_message + ) + withContext(Dispatchers.Main) { + when (result) { + is CompletionResult.Success -> { + val card = result.data.card + + if (!card.isMultiwalletAllowed) { + store.dispatchOnMain(WalletConnectAction.UnsupportedCard) + return@withContext + } + + val walletManager = getWalletManager(card) + if (walletManager == null) { + store.dispatchOnMain(WalletConnectAction.UnsupportedCard) + return@withContext + } + + val key = walletManager.wallet.publicKey + store.dispatchOnMain(WalletConnectAction.OpenSession( + wcUri = wcUri, + wallet = WalletForSession( + card.cardId, key.toHexString(), + isTestNet = false + ), + )) + } + is CompletionResult.Failure -> + store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession( + null + )) + } + } + } + } + + private fun getWalletManager(card: Card): WalletManager? { + val factory = store.state.globalState.tapWalletManager.walletManagerFactory + + return if (store.state.globalState.scanNoteResponse?.card?.cardId == card.cardId) { + store.state.walletState.getWalletManager(Blockchain.Ethereum) + ?: factory.makeWalletManagerForApp(card, Blockchain.Ethereum) + ?.also { walletManager -> + store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManager)) + store.dispatch(WalletAction.MultiWallet.AddBlockchain(walletManager.wallet.blockchain)) + } + } else { + if (currenciesRepository.loadCardCurrencies(card.cardId)?.blockchains?.contains( + Blockchain.Ethereum) == true + ) { + factory.makeWalletManagerForApp(card, Blockchain.Ethereum) + } else { + factory.makeWalletManagerForApp(card, + Blockchain.Ethereum) + ?.also { + currenciesRepository.saveAddedBlockchain(card.cardId, Blockchain.Ethereum) + } + } + } + } } \ No newline at end of file From 2ac23370916f7291ddf333c8565a674f5d193c93 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Jun 2021 11:09:35 +0300 Subject: [PATCH 5/6] Updated on 2026-08-14 --- .../com/tangem/tap/features/feedback/FeedbackManager.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt index c3ff7b8de0..4d4a3522e3 100644 --- a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt @@ -14,9 +14,9 @@ import com.tangem.Log import com.tangem.TangemSdkLogger import com.tangem.blockchain.common.* import com.tangem.commands.common.card.Card +import com.tangem.commands.wallet.WalletStatus import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.domain.TapWorkarounds -import com.tangem.tap.domain.extensions.signedHashesCount import com.tangem.tap.store import timber.log.Timber import java.io.File @@ -173,7 +173,9 @@ class AdditionalEmailInfo { fun setCardInfo(card: Card) { cardId = card.cardId cardFirmwareVersion = card.firmwareVersion.version - signedHashesCount = card.signedHashesCount().toString() + signedHashesCount = card.wallets + .filter { it.status == WalletStatus.Loaded } + .joinToString(";") { "${it.curve?.curve} - ${it.signedHashes}" } } fun setWalletsInfo(walletManagers: List) { @@ -289,6 +291,7 @@ class SendTransactionFailedEmail(private val error: String) : EmailData { appendKeyValue("OS version", infoHolder.osVersion) appendKeyValue("App version", infoHolder.appVersion) appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion) + appendKeyValue("Signed hashes", infoHolder.signedHashesCount) // appendKeyValue("Transaction HEX", infoHolder.transactionHex) }.toString() } @@ -301,6 +304,7 @@ class FeedbackEmail : EmailData { val builder = StringBuilder() builder.appendKeyValue("Card ID", infoHolder.cardId) builder.appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion) + builder.appendKeyValue("Signed hashes", infoHolder.signedHashesCount) infoHolder.walletsInfo.forEach { builder.appendKeyValue("Blockchain", it.blockchain.fullName) From 1a0a53420c73200a0a69be54eb5e8a7ccd0477bd Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 18 Jun 2021 11:55:59 +0300 Subject: [PATCH 6/6] Updated on 2026-08-14 --- app/build.gradle | 2 +- .../tap/domain/tokens/CurrenciesRepository.kt | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index febc5293ea..9348b311d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,7 +77,7 @@ dependencies { implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:develop-22' + implementation 'com.tangem:blockchain:develop-24' implementation 'com.tangem:core:develop-36' implementation 'com.tangem:sdk:develop-36' diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt index 8ddbc8b5d1..754d7ea239 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt @@ -100,9 +100,9 @@ class CurrenciesRepository(val context: Application) { fun getBlockchains(cardFirmware: FirmwareVersion?): List { return if (cardFirmware == null || cardFirmware.major < 4) { - secp256k1Blochcains + secp256k1Blockchains } else { - secp256k1Blochcains + ed25519Blockchains + secp256k1Blockchains + ed25519Blockchains } } @@ -115,10 +115,19 @@ class CurrenciesRepository(val context: Application) { fun getFileNameForBlockchains(cardId: String): String = "${FILE_NAME_PREFIX_BLOCKCHAINS}_$cardId" - private val secp256k1Blochcains = listOf( - Blockchain.Bitcoin, Blockchain.BitcoinCash, Blockchain.Binance, Blockchain.Litecoin, - Blockchain.XRP, Blockchain.Tezos, - Blockchain.Ethereum, Blockchain.RSK) + private val secp256k1Blockchains = listOf( + Blockchain.Bitcoin, + Blockchain.BitcoinCash, + Blockchain.Binance, + Blockchain.BSC, + Blockchain.Litecoin, + Blockchain.XRP, + Blockchain.Tezos, + Blockchain.Ethereum, + Blockchain.RSK, + Blockchain.Polygon, + Blockchain.Dogecoin, + ) private val ed25519Blockchains = listOf(Blockchain.CardanoShelley, Blockchain.Stellar) } }