diff --git a/app/build.gradle b/app/build.gradle index 5e41bbe87f..e188911f47 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,9 +77,9 @@ 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-17' - implementation 'com.tangem:core:develop-36' - implementation 'com.tangem:sdk:develop-36' + implementation 'com.tangem:blockchain:develop-26' + implementation 'com.tangem:core:fixes_for_app_release-44' + implementation 'com.tangem:sdk:fixes_for_app_release-44' // WebView implementation "androidx.browser:browser:1.3.0" @@ -117,10 +117,6 @@ dependencies { implementation 'com.squareup.moshi:moshi:1.9.2' implementation "com.squareup.moshi:moshi-kotlin:1.9.2" implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2' -// -// //Crypto - implementation "com.madgag.spongycastle:core:1.58.0.0" - testImplementation 'junit:junit:4.13.2' testImplementation "com.google.truth:truth:1.0.1" diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 491f1c9cfb..166ae2183f 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -5,6 +5,7 @@ import com.google.firebase.ktx.Firebase import com.google.firebase.remoteconfig.ktx.remoteConfig import com.google.firebase.remoteconfig.ktx.remoteConfigSettings import com.tangem.Log +import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder import com.tangem.tap.common.images.PicassoHelper import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer @@ -58,6 +59,8 @@ class TapApplication : Application() { initFeedbackManager() loadConfigs() + + BlockchainSdkRetrofitBuilder.enableNetworkLogging = BuildConfig.DEBUG } private fun loadConfigs() { 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 dd997b7997..96992a5d7a 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -4,11 +4,9 @@ import android.app.Dialog import android.content.Context 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.ApproveWcSessionDialog -import com.tangem.tap.features.details.ui.walletconnect.dialogs.ClipboardOrScanQrDialog -import com.tangem.tap.features.details.ui.walletconnect.dialogs.PersonalSignDialog -import com.tangem.tap.features.details.ui.walletconnect.dialogs.TransactionDialog +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 { @@ -40,9 +38,21 @@ class DialogManager : StoreSubscriber { if (dialog != null) return when (state.dialog) { + is WalletConnectDialog.UnsupportedCard -> + 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 -> dialog = ClipboardOrScanQrDialog.create(state.dialog.clipboardUri, context) is WalletConnectDialog.RequestTransaction -> 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 dc12172a82..0ca68b4ea3 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 @@ -19,5 +19,6 @@ fun Blockchain.getIconRes(): Int { Blockchain.Tezos -> R.drawable.ic_tezos Blockchain.XRP -> R.drawable.ic_xrp Blockchain.Stellar -> R.drawable.ic_stellar + else -> R.drawable.shape_circle } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 357db63124..acdc924fd4 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -9,6 +9,7 @@ import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.redux.global.FiatCurrencyName import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.currenciesRepository +import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.configurable.config.ConfigManager import com.tangem.tap.domain.extensions.* import com.tangem.tap.domain.tasks.ScanNoteResponse @@ -89,7 +90,6 @@ class TapWalletManager { if (addAnalyticsEvent) { FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card) } - TapWorkarounds.updateCard(data.card) store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(data.card) updateConfigManager(data) @@ -119,7 +119,7 @@ class TapWalletManager { private fun updateConfigManager(data: ScanNoteResponse) { val configManager = store.state.globalState.configManager val blockchain = data.card.getBlockchain() - if (TapWorkarounds.isStart2Coin) { + if (data.card.isStart2Coin) { configManager?.turnOff(ConfigManager.isSendingToPayIdEnabled) configManager?.turnOff(ConfigManager.isTopUpEnabled) } else if (blockchain == Blockchain.Bitcoin diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index ace735abd2..5807bd024e 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -3,18 +3,19 @@ package com.tangem.tap.domain import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.EllipticCurve import com.tangem.commands.common.card.masks.Product +import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.extensions.getSingleWallet import java.util.* object TapWorkarounds { - var isStart2Coin: Boolean = false - private set - - fun updateCard(card: Card) { - isStart2Coin = card.cardData?.issuerName?.toLowerCase(Locale.US) == START_2_COIN_ISSUER + fun isStart2CoinIssuer(cardIssuer: String?): Boolean { + return cardIssuer?.toLowerCase(Locale.US) == START_2_COIN_ISSUER } + val Card.isStart2Coin: Boolean + get() = isStart2CoinIssuer(cardData?.issuerName) + fun Card.isExcluded(): Boolean { val cardData = this.cardData ?: return false val productMask = cardData.productMask @@ -43,7 +44,7 @@ object TapWorkarounds { val Card.isMultiwalletAllowed: Boolean get() { return cardData?.productMask?.contains(Product.TwinCard) != true - && !TapWorkarounds.isStart2Coin + && !isStart2Coin && (firmwareVersion.major >= 4 || getSingleWallet()?.curve == EllipticCurve.Secp256k1) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt index 17cac3c3e6..a89f4fe24c 100644 --- a/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt @@ -31,10 +31,11 @@ fun Blockchain.getSupportedCurves(): List? { Blockchain.Unknown -> null Blockchain.Bitcoin, Blockchain.BitcoinTestnet, Blockchain.BitcoinCash, Blockchain.Litecoin, Blockchain.Ducatus, Blockchain.Ethereum, Blockchain.EthereumTestnet, Blockchain.RSK, - Blockchain.XRP, Blockchain.Binance, Blockchain.BinanceTestnet -> listOf(EllipticCurve.Secp256k1) - Blockchain.Tezos -> listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519) + Blockchain.Binance, Blockchain.BinanceTestnet -> listOf(EllipticCurve.Secp256k1) + Blockchain.Tezos, Blockchain.XRP -> listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519) Blockchain.Cardano, Blockchain.CardanoShelley, Blockchain.Stellar -> listOf(EllipticCurve.Ed25519) + else -> listOf(EllipticCurve.Secp256k1) } } 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 417c3cb79e..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 @@ -37,6 +37,10 @@ class CurrenciesRepository(val context: Application) { saveTokens(cardId, tokens) } + fun saveAddedTokens(cardId: String, tokens: Collection) { + saveTokens(cardId, loadSavedTokens(cardId) + tokens) + } + fun saveAddedBlockchain(cardId: String, blockchain: Blockchain) { val blockchains = loadSavedBlockchains(cardId) + blockchain saveBlockchains(cardId, blockchains) @@ -96,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 } } @@ -111,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) } } 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/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index 3a7b39e788..132dbddb18 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -4,7 +4,7 @@ package com.tangem.tap.features.details.redux import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.masks.Settings import com.tangem.tap.common.redux.AppState -import com.tangem.tap.domain.TapWorkarounds +import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.extensions.isWalletDataSupported import com.tangem.tap.domain.extensions.signedHashesCount import com.tangem.tap.domain.extensions.toSendableAmounts @@ -143,7 +143,7 @@ private fun handleSecurityAction( ): DetailsState { return when (action) { is DetailsAction.ManageSecurity.OpenSecurity -> { - if (TapWorkarounds.isStart2Coin) { + if (state.card?.isStart2Coin == true) { return state.copy(securityScreenState = state.securityScreenState?.copy( allowedOptions = EnumSet.of(SecurityOption.LongTap), selectedOption = state.securityScreenState.currentOption 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..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 @@ -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( @@ -37,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 896e3c06d2..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,19 @@ 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 + handleScanCard(action.wcUri) + } - 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) - } - } + is WalletConnectAction.FailureEstablishingSession -> { + if (action.session != null) { + walletConnectManager.disconnect(action.session) } } + is WalletConnectAction.UnsupportedCard -> { + store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedCard)) + } + is WalletConnectAction.OpenSession -> { walletConnectManager.connect( wcUri = action.wcUri, @@ -111,6 +77,12 @@ class WalletConnectMiddleware { ) } + is WalletConnectAction.RefuseOpeningSession -> { + store.dispatch(GlobalAction.ShowDialog( + WalletConnectDialog.OpeningSessionRejected + )) + } + is WalletConnectAction.AcceptOpeningSession -> { store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.ApproveWcSession( action.session))) @@ -153,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 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 84ef36046b..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 @@ -26,6 +26,8 @@ class WalletConnectReducer { } is WalletConnectAction.ScanCard -> state.copy(loading = true) + 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 75dad54452..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 @@ -40,6 +40,8 @@ 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/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) } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/SimpleAlertDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/SimpleAlertDialog.kt new file mode 100644 index 0000000000..f4efd59532 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/SimpleAlertDialog.kt @@ -0,0 +1,28 @@ +package com.tangem.tap.features.details.ui.walletconnect.dialogs + +import android.content.Context +import androidx.appcompat.app.AlertDialog +import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.store +import com.tangem.wallet.R + +class SimpleAlertDialog { + companion object { + fun create( + titleRes: Int, + messageRes: Int, + buttonRes: Int = R.string.common_ok, + context: Context, + ): AlertDialog { + + return AlertDialog.Builder(context).apply { + setTitle(context.getString(titleRes)) + setMessage(context.getText(messageRes)) + setPositiveButton(context.getText(buttonRes)) { _, _ -> } + setOnDismissListener { + store.dispatch(GlobalAction.HideDialog) + } + }.create() + } + } +} \ No newline at end of file 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..bab36b6f67 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,10 +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 import java.io.FileWriter @@ -50,7 +49,11 @@ class FeedbackManager( } private fun getSupportEmail(): String { - return if (TapWorkarounds.isStart2Coin) S2C_SUPPORT_EMAIL else DEFAULT_SUPPORT_EMAIL + return if (TapWorkarounds.isStart2CoinIssuer(infoHolder.cardIssuer)) { + S2C_SUPPORT_EMAIL + } else { + DEFAULT_SUPPORT_EMAIL + } } private fun sendTo(email: String, subject: String, message: String, fileLog: File? = null) { @@ -145,6 +148,7 @@ class AdditionalEmailInfo { // card var cardId: String = "" var cardFirmwareVersion: String = "" + var cardIssuer: String = "" // wallets internal val walletsInfo = mutableListOf() @@ -173,7 +177,10 @@ class AdditionalEmailInfo { fun setCardInfo(card: Card) { cardId = card.cardId cardFirmwareVersion = card.firmwareVersion.version - signedHashesCount = card.signedHashesCount().toString() + cardIssuer = card.cardData?.issuerName ?: "" + signedHashesCount = card.wallets + .filter { it.status == WalletStatus.Loaded } + .joinToString(";") { "${it.curve?.curve} - ${it.signedHashes}" } } fun setWalletsInfo(walletManagers: List) { @@ -191,7 +198,6 @@ class AdditionalEmailInfo { } fun updateOnSendError(wallet: Wallet, host: String, amountToSend: Amount, feeAmount: Amount, destinationAddress: String) { - val amountState = store.state.sendState.amountState onSendErrorWalletInfo = EmailWalletInfo( blockchain = wallet.blockchain, address = getAddress(wallet), @@ -202,9 +208,7 @@ class AdditionalEmailInfo { this.destinationAddress = destinationAddress amount = amountToSend.value?.stripZeroPlainString() ?: "0" fee = feeAmount.value?.stripZeroPlainString() ?: "0" - if (amountState.typeOfAmount is AmountType.Token) { - token = amountState.amountToExtract?.currencySymbol ?: "" - } + token = if (amountToSend.type is AmountType.Token) amountToSend.currencySymbol else "" } private fun getAddress(wallet: Wallet): String { @@ -289,6 +293,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 +306,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) @@ -316,6 +322,6 @@ class FeedbackEmail : EmailData { } } -fun StringBuilder.appendKeyValue(key: String, value: String): StringBuilder { - return this.append("$key: $value\n") +private fun StringBuilder.appendKeyValue(key: String, value: String): StringBuilder { + return if (value.isNotBlank()) this.append("$key: $value\n") else this } \ 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 3d2b5e9c37..7dcececcda 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 @@ -14,7 +14,7 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TangemSigner import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.TapWorkarounds +import com.tangem.tap.domain.TapWorkarounds.isStart2Coin import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.extensions.minimalAmount import com.tangem.tap.features.send.redux.* @@ -108,7 +108,7 @@ private fun sendTransaction( scope.launch { walletManager.update() val isLinkedTerminal = tangemSdk.config.linkedTerminal - if (TapWorkarounds.isStart2Coin) { + if (card.isStart2Coin) { tangemSdk.config.linkedTerminal = false } val signer = TangemSigner( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index d35eea4fd3..905ecce398 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -44,14 +44,14 @@ class MultiWalletMiddleware { addTokens(action.tokens, walletState, globalState) } is WalletAction.MultiWallet.AddBlockchain -> { - if (walletState?.blockchains?.contains(action.blockchain) == true) return - globalState?.scanNoteResponse?.card?.let { card -> currenciesRepository.saveAddedBlockchain(card.cardId, action.blockchain) - globalState.tapWalletManager.walletManagerFactory + if (walletState?.blockchains?.contains(action.blockchain) != true) { + globalState.tapWalletManager.walletManagerFactory .makeWalletManagerForApp(card, action.blockchain)?.let { store.dispatch(WalletAction.MultiWallet.AddWalletManagers(it)) } + } } store.dispatch(WalletAction.LoadFiatRate(currency = Currency.Blockchain(action.blockchain))) store.dispatch(WalletAction.LoadWallet(blockchain = action.blockchain)) @@ -87,12 +87,12 @@ class MultiWalletMiddleware { val wallet = walletManager.wallet val coinAmount = wallet.amounts[AmountType.Coin]?.value if (coinAmount != null && !coinAmount.isZero()) { - if (walletState?.getWalletData(wallet.blockchain) == null) { - scope.launch(Dispatchers.Main) { + scope.launch(Dispatchers.Main) { + if (walletState?.getWalletData(wallet.blockchain) == null) { store.dispatch(WalletAction.MultiWallet.AddWalletManagers( - listOfNotNull(walletManager))) + listOfNotNull(walletManager))) store.dispatch(WalletAction.MultiWallet.AddBlockchain( - wallet.blockchain + wallet.blockchain )) store.dispatch(WalletAction.LoadWallet.Success(wallet)) } @@ -118,6 +118,7 @@ class MultiWalletMiddleware { when (result) { is Result.Success -> { if (result.data.isNotEmpty()) { + currenciesRepository.saveAddedTokens(card.cardId, result.data) store.dispatch( WalletAction.MultiWallet.AddWalletManagers( walletManager 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 6c0328c7ce..62e9849d04 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 @@ -18,9 +18,6 @@ import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.item_currency_wallet.view.* -import kotlinx.android.synthetic.main.item_currency_wallet.view.iv_currency -import kotlinx.android.synthetic.main.item_currency_wallet.view.tv_currency_symbol -import kotlinx.android.synthetic.main.item_currency_wallet.view.tv_token_letter import java.math.BigDecimal class WalletAdapter @@ -57,7 +54,7 @@ class WalletAdapter val sorted = listModified.sortedWith( compareByDescending { it.currencyData.fiatAmount ?: BigDecimal.ZERO } - .thenBy { it.currencyData.currencySymbol } + .thenBy { it.currencyData.currency } ) val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + sorted super.submitList(sortedList) 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"> - - - + + Clipboard contain WalletConnect code. Use copied value or scan QR-code 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. diff --git a/build.gradle b/build.gradle index 576034574e..f2dcf4b2fe 100644 --- a/build.gradle +++ b/build.gradle @@ -19,28 +19,10 @@ buildscript { allprojects { repositories { google() + jcenter() + mavenLocal() + maven { url "https://nexus.tangem-tech.com/repository/maven-releases/" } maven { url 'https://jitpack.io' } - def nexusUser = "viewer" - def nexusPass = "smartcash124" - repositories { - google() - jcenter() - maven { - credentials { - username = nexusUser - password = nexusPass - } - url "https://nexus.tangem-tech.com/repository/maven-releases/" - } - maven { - credentials { - username = nexusUser - password = nexusPass - } - url "https://nexus.tangem-tech.com/repository/maven-snapshots/" - } - maven { url 'https://jitpack.io' } - } } }