Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-03 19:35:00 +01:00
parent 3e5bf1d8c3
commit afe5ec2c57
23 changed files with 23 additions and 1383 deletions

View file

@ -1,118 +1,26 @@
package com.tangem.tap.features.details.redux.walletconnect
import com.tangem.blockchain.common.Blockchain
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.redux.NotificationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.walletconnect.Topic
import com.tangem.tap.domain.walletconnect2.domain.WcPreparedRequest
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectError
import com.tangem.tap.features.details.ui.walletconnect.WcSessionForScreen
import com.tangem.wallet.R
import com.trustwallet.walletconnect.models.binance.WCBinanceTradeOrder
import com.trustwallet.walletconnect.models.binance.WCBinanceTransferOrder
import com.trustwallet.walletconnect.models.ethereum.WCEthereumSignMessage
import com.trustwallet.walletconnect.models.ethereum.WCEthereumTransaction
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()
data class RestoreSessions(val scanResponse: ScanResponse) : WalletConnectAction()
data class StartWalletConnect(
val copiedUri: String?,
) : WalletConnectAction()
data class ShowClipboardOrScanQrDialog(val wcUri: String) : WalletConnectAction()
object UnsupportedCard : WalletConnectAction()
data class OpenSession(
val wcUri: String,
) : WalletConnectAction()
data class SetNewSessionData(
val newSession: NewWcSessionData,
) : WalletConnectAction()
data class DisconnectSession(val topic: String) : WalletConnectAction()
object RefuseOpeningSession : WalletConnectAction()
data class OpeningSessionTimeout(val session: WCSession) : WalletConnectAction()
data class ScanCard(
val session: WalletConnectSession,
val chainId: Int?,
) : WalletConnectAction()
data class ApproveSession(
val session: WCSession,
) : WalletConnectAction() {
data class Success(val session: WalletConnectSession) : WalletConnectAction()
}
data class SwitchBlockchain(
val blockchain: Blockchain?,
val session: WalletConnectSession,
) : WalletConnectAction()
data class SelectNetwork(val session: WalletConnectSession, val networks: List<Blockchain>) : WalletConnectAction()
data class ChooseNetwork(val blockchain: Blockchain) : WalletConnectAction()
data class UpdateBlockchain(
val updatedSession: WalletConnectSession,
) : WalletConnectAction()
data class FailureEstablishingSession(val session: WCSession?, val error: TapError? = null) : WalletConnectAction()
data class SetSessionsRestored(val sessions: List<WalletConnectSession>) : WalletConnectAction()
data class DisconnectSession(val topic: String, val session: WCSession?) : WalletConnectAction()
data class RemoveSession(val session: WCSession) : WalletConnectAction()
data class HandleTransactionRequest(
val transaction: WCEthereumTransaction,
val session: WalletConnectSession,
val id: Long,
val type: WcEthTransactionType,
) :
WalletConnectAction()
data class HandlePersonalSignRequest(
val message: WCEthereumSignMessage,
val session: WalletConnectSession,
val id: Long,
) : WalletConnectAction()
data class SendTransaction(val topic: Topic) : WalletConnectAction()
data class SignMessage(val topic: Topic) : WalletConnectAction()
data class RejectRequest(val topic: Topic, val id: Long) : WalletConnectAction()
object NotEnoughFunds : WalletConnectAction(), NotificationAction {
override val messageResource = R.string.wallet_connect_create_tx_not_enough_funds
}
object NotifyCameraPermissionIsRequired : WalletConnectAction(), NotificationAction {
override val messageResource = R.string.common_camera_denied_alert_message
}
object BinanceTransaction : WalletConnectAction() {
data class Trade(
val id: Long,
val order: WCBinanceTradeOrder,
val sessionData: WalletConnectSession,
) : WalletConnectAction()
data class Transfer(
val id: Long,
val order: WCBinanceTransferOrder,
val sessionData: WalletConnectSession,
) : WalletConnectAction()
data class Sign(
val id: Long,
val data: ByteArray,
val topic: Topic,
) : WalletConnectAction()
}
data class RejectRequest(val topic: String, val id: Long) : WalletConnectAction()
data class ShowClipboardOrScanQrDialog(val wcUri: String) : WalletConnectAction()
//region WalletConnect 2.0
object ApproveProposal : WalletConnectAction()
object RejectProposal : WalletConnectAction()

View file

@ -1,44 +1,28 @@
package com.tangem.tap.features.details.redux.walletconnect
import androidx.core.os.bundleOf
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.derivation.DerivationStyle
import com.tangem.common.extensions.guard
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toNetworkId
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.qrscanning.models.SourceType
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.walletconnect.WalletConnectActions
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.qrscanning.QrScanningRouter
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.inject
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.walletconnect.BnbHelper
import com.tangem.tap.domain.walletconnect.WalletConnectManager
import com.tangem.tap.domain.walletconnect.WalletConnectNetworkUtils
import com.tangem.tap.domain.walletconnect.extensions.toWcEthTransaction
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectRepository
import com.tangem.tap.domain.walletconnect2.domain.WcPreparedRequest
import com.tangem.tap.domain.walletconnect2.domain.models.Account
import com.tangem.tap.domain.walletconnect2.domain.models.BnbData
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectError
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.userWalletsListManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.Middleware
@ -46,7 +30,6 @@ import timber.log.Timber
@Suppress("LargeClass")
class WalletConnectMiddleware {
private var walletConnectManager = WalletConnectManager()
private val walletConnectInteractor: WalletConnectInteractor
get() = store.inject(DaggerGraphState::walletConnectInteractor)
private val walletConnectRepository: WalletConnectRepository
@ -88,18 +71,18 @@ class WalletConnectMiddleware {
wcInteractor.setUserChains(getAccountsForWc(wcInteractor, userWallet))
}
}
is WalletConnectAction.ResetState -> walletConnectManager = WalletConnectManager()
is WalletConnectAction.RestoreSessions -> {
walletConnectManager.restoreSessions(action.scanResponse)
}
is WalletConnectAction.HandleDeepLink -> {
if (!action.wcUri.isNullOrBlank()) {
store.dispatchOnMain(WalletConnectAction.OpenSession(action.wcUri))
}
}
is WalletConnectAction.DisconnectSession -> {
walletConnectInteractor.disconnectSession(action.topic)
}
is WalletConnectAction.StartWalletConnect -> {
val uri = action.copiedUri
if (uri != null && isWalletConnectUri(uri)) {
// TODO check
store.dispatchOnMain(WalletConnectAction.ShowClipboardOrScanQrDialog(uri))
} else {
store.dispatchOnMain(
@ -112,27 +95,6 @@ class WalletConnectMiddleware {
)
}
}
is WalletConnectAction.SelectNetwork -> {
store.dispatch(
GlobalAction.ShowDialog(
WalletConnectDialog.ChooseNetwork(
session = action.session,
networks = action.networks,
),
),
)
}
is WalletConnectAction.ChooseNetwork -> {
val data = state()?.walletConnectState?.newSessionData ?: return
scope.launch {
prepareWalletManager(
scanResponse = data.scanResponse,
blockchain = action.blockchain,
session = data.session,
walletConnectManager = walletConnectManager,
)
}
}
is WalletConnectAction.ShowClipboardOrScanQrDialog -> {
store.dispatchOnMain(
GlobalAction.ShowDialog(
@ -142,176 +104,15 @@ class WalletConnectMiddleware {
),
)
}
is WalletConnectAction.OpeningSessionTimeout -> {
Timber.e("OpeningSessionTimeout for topic ${action.session.topic}")
// do not show dialog for now, it shows always to user if cannot establish connection
// store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.SessionTimeout))
}
is WalletConnectAction.FailureEstablishingSession -> {
Timber.e("FailureEstablishingSession for topic ${action.session?.topic}")
// disable alerts in release to avoid annoying users
// if (action.error != null) {
// store.dispatch(
// GlobalAction.ShowDialog(
// AppDialog.SimpleOkDialogRes(
// headerId = R.string.common_warning,
// messageId = action.error.messageResource,
// ),
// ),
// )
// }
if (action.session != null) {
walletConnectManager.disconnect(action.session)
}
}
is WalletConnectAction.UnsupportedCard -> {
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedCard))
}
is WalletConnectAction.OpenSession -> {
val index = action.wcUri.indexOf("@")
when (action.wcUri[index + 1]) {
'1' -> {
walletConnectManager.connect(wcUri = action.wcUri)
}
'2' -> walletConnectRepository.pair(uri = action.wcUri)
}
}
is WalletConnectAction.RefuseOpeningSession -> {
Timber.e("RefuseOpeningSession")
// do not show for now to avoid anoying users with alert
// store.dispatch(
// GlobalAction.ShowDialog(
// WalletConnectDialog.OpeningSessionRejected,
// ),
// )
}
is WalletConnectAction.ScanCard -> {
val scanResponse = userWalletsListManager.selectedUserWalletSync.guard {
Timber.w("Unable to get selected user wallet for WC session")
return
}
scope.launch(Dispatchers.Main) {
scanCard(scanResponse, action.session, action.chainId)
}
}
is WalletConnectAction.ApproveSession -> {
walletConnectManager.approve(action.session)
}
is WalletConnectAction.DisconnectSession -> {
if (action.session != null) {
walletConnectManager.disconnect(action.session)
} else {
walletConnectInteractor.disconnectSession(action.topic)
}
}
is WalletConnectAction.HandleTransactionRequest -> {
walletConnectManager.handleTransactionRequest(
transaction = action.transaction.toWcEthTransaction(),
session = action.session,
id = action.id,
type = action.type,
)
}
is WalletConnectAction.HandlePersonalSignRequest -> {
walletConnectManager.handlePersonalSignRequest(
message = action.message,
session = action.session,
id = action.id,
)
}
is WalletConnectAction.RejectRequest -> {
walletConnectManager.rejectRequest(action.topic, action.id)
walletConnectInteractor.cancelRequest(action.topic, action.id)
}
is WalletConnectAction.SendTransaction -> {
walletConnectManager.completeTransaction(action.topic)
}
is WalletConnectAction.SignMessage -> {
walletConnectManager.sendSignedMessage(action.topic)
}
is WalletConnectAction.BinanceTransaction.Trade -> {
val messageData = BnbHelper.createMessageData(action.order)
store.dispatchOnMain(
GlobalAction.ShowDialog(
WalletConnectDialog.BnbTransactionDialog(
WcPreparedRequest.BnbTransaction(
preparedRequestData = BnbData(
data = messageData,
topic = action.sessionData.session.topic,
requestId = action.id,
dAppName = action.sessionData.peerMeta.name,
),
topic = action.sessionData.session.topic,
requestId = action.id,
derivationPath = action.sessionData.wallet.derivationPath?.rawPath,
),
),
),
)
}
is WalletConnectAction.BinanceTransaction.Transfer -> {
val messageData = BnbHelper.createMessageData(action.order)
store.dispatchOnMain(
GlobalAction.ShowDialog(
WalletConnectDialog.BnbTransactionDialog(
WcPreparedRequest.BnbTransaction(
preparedRequestData = BnbData(
data = messageData,
topic = action.sessionData.session.topic,
requestId = action.id,
dAppName = action.sessionData.peerMeta.name,
),
topic = action.sessionData.session.topic,
requestId = action.id,
derivationPath = action.sessionData.wallet.derivationPath?.rawPath,
),
),
),
)
}
is WalletConnectAction.BinanceTransaction.Sign -> {
walletConnectManager.signBnb(
id = action.id,
data = action.data,
topic = action.topic,
)
}
is WalletConnectAction.SwitchBlockchain -> {
if (action.session.wallet.derivationStyle == DerivationStyle.LEGACY) {
Timber.d("Cannot switch chains on AC01/AC02 wallets")
return
}
val blockchain = action.blockchain.guard {
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedNetwork()))
return
}
scope.launch {
val walletManager = getWalletManager(
wallet = action.session.wallet,
blockchain = blockchain,
).guard {
store.dispatchOnMain(
GlobalAction.ShowDialog(
WalletConnectDialog.AddNetwork(listOf(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 updatedSession = action.session.copy(wallet = updatedWallet)
store.dispatchOnMain(WalletConnectAction.UpdateBlockchain(updatedSession))
}
}
is WalletConnectAction.UpdateBlockchain -> {
walletConnectManager.updateBlockchain(action.updatedSession)
}
is WalletConnectAction.ApproveProposal -> {
scope.launch {
val accounts = getWalletManagers()
@ -402,119 +203,8 @@ class WalletConnectMiddleware {
return walletManagerFacade.getStoredWalletManagers(userWallet.walletId)
}
private suspend fun scanCard(userWallet: UserWallet, session: WalletConnectSession, chainId: Int?) {
val blockchain = WalletConnectNetworkUtils.parseBlockchain(
chainId = chainId,
peer = session.peerMeta,
).guard {
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedNetwork()))
return
}
handleScanResponse(userWallet, session, blockchain)
}
private suspend fun getAvailableEvmBlockchains(userWalletId: UserWalletId): List<Blockchain> {
val currenciesRepository = store.inject(DaggerGraphState::currenciesRepository)
return currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId)
.asSequence()
.filterIsInstance<CryptoCurrency.Coin>()
.filterNot { it.isCustom }
.mapNotNull { Blockchain.fromNetworkId(it.network.id.value) }
.filter { it.isEvm() }
.toList()
}
private suspend fun prepareWalletManager(
scanResponse: ScanResponse,
blockchain: Blockchain,
session: WalletConnectSession,
walletConnectManager: WalletConnectManager,
) {
val walletManager = getWalletManager(session.wallet, blockchain).guard {
store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession(session.session))
store.dispatchOnMain(
GlobalAction.ShowDialog(
WalletConnectDialog.AddNetwork(listOf(blockchain.fullName)),
),
)
return
}
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.derivationStyleProvider.getDerivationStyle(),
blockchain = wallet.blockchain,
)
withMainContext {
val updatedSession = session.copy(wallet = walletForSession)
walletConnectManager.updateSession(updatedSession)
store.dispatch(WalletConnectAction.ApproveSession(session.session))
}
}
private suspend fun handleScanResponse(
userWallet: UserWallet,
session: WalletConnectSession,
blockchain: Blockchain,
) {
val scanResponse = userWallet.scanResponse
if (!scanResponse.cardTypesResolver.isMultiwalletAllowed()) {
store.dispatchOnMain(WalletConnectAction.UnsupportedCard)
return
}
val updatedSession = session.copy(wallet = session.wallet.copy(blockchain = blockchain))
store.dispatch(
WalletConnectAction.SetNewSessionData(
NewWcSessionData(updatedSession, scanResponse, blockchain),
),
)
val blockchains = if (blockchain.isEvm()) {
getAvailableEvmBlockchains(userWallet.walletId)
} else {
emptyList()
}
store.dispatch(
GlobalAction.ShowDialog(
WalletConnectDialog.ApproveWcSession(session = updatedSession, networks = blockchains),
),
)
}
private suspend fun getWalletManager(wallet: WalletForSession, blockchain: Blockchain): WalletManager? {
val blockchainToMake = if (blockchain == Blockchain.Ethereum && wallet.isTestNet) {
Blockchain.EthereumTestnet
} else {
blockchain
}
val userWallet = userWalletsListManager.selectedUserWalletSync ?: return null
val derivation = blockchainToMake.derivationPath(
style = userWallet.scanResponse.derivationStyleProvider.getDerivationStyle(),
)?.rawPath
val walletManagerFacade = store.inject(DaggerGraphState::walletManagersFacade)
return walletManagerFacade.getOrCreateWalletManager(
userWalletId = userWallet.walletId,
blockchain = blockchainToMake,
derivationPath = derivation,
)
}
private fun isWalletConnectUri(uri: String): Boolean {
return WalletConnectManager.isCorrectWcUri(uri) || walletConnectInteractor.isWalletConnectUri(uri)
return walletConnectInteractor.isWalletConnectUri(uri)
}
private suspend fun getAccountsForWc(wcInteractor: WalletConnectInteractor, userWallet: UserWallet): List<Account> {

View file

@ -7,36 +7,9 @@ object WalletConnectReducer {
if (action !is WalletConnectAction) return state
return when (action) {
is WalletConnectAction.ResetState -> return WalletConnectState()
is WalletConnectAction.ApproveSession.Success -> {
state.copy(
loading = false,
sessions = state.sessions + action.session,
)
}
is WalletConnectAction.OpenSession -> {
state.copy(loading = true)
}
is WalletConnectAction.SetNewSessionData -> {
state.copy(newSessionData = action.newSession)
}
is WalletConnectAction.SetSessionsRestored -> state.copy(
sessions = action.sessions,
)
is WalletConnectAction.RemoveSession -> {
val sessions =
state.sessions.filterNot { it.session.toUri() == action.session.toUri() }
state.copy(sessions = sessions)
}
is WalletConnectAction.UnsupportedCard,
is WalletConnectAction.RefuseOpeningSession,
is WalletConnectAction.OpeningSessionTimeout,
is WalletConnectAction.FailureEstablishingSession,
-> state.copy(loading = false)
is WalletConnectAction.UpdateBlockchain -> state.copy(
sessions = state.sessions
.filterNot { it.peerId == action.updatedSession.peerId } + action.updatedSession,
)
is WalletConnectAction.ApproveProposal -> state.copy(loading = true)
is WalletConnectAction.RejectProposal,
is WalletConnectAction.SessionEstablished,

View file

@ -14,12 +14,9 @@ import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectEvents
import com.tangem.tap.features.details.ui.walletconnect.WcSessionForScreen
import com.tangem.tap.features.details.ui.walletconnect.dialogs.PersonalSignDialogData
import com.tangem.tap.features.details.ui.walletconnect.dialogs.TransactionRequestDialogData
import com.trustwallet.walletconnect.models.WCPeerMeta
import com.trustwallet.walletconnect.models.session.WCSession
data class WalletConnectState(
val loading: Boolean = false,
val sessions: List<WalletConnectSession> = listOf(),
val wc2Sessions: List<WcSessionForScreen> = listOf(),
val newSessionData: NewWcSessionData? = null,
)
@ -34,8 +31,6 @@ data class WalletConnectSession(
val peerId: String,
val remotePeerId: String?,
val wallet: WalletForSession,
val session: WCSession,
val peerMeta: WCPeerMeta,
) {
fun getAddress(): String? {
val key = wallet.derivedPublicKey ?: wallet.walletPublicKey ?: return null

View file

@ -11,7 +11,6 @@ import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.common.analytics.events.WalletConnect
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
import com.tangem.tap.store
import dagger.hilt.android.AndroidEntryPoint
@ -42,13 +41,6 @@ internal class WalletConnectFragment : ComposeFragment(), StoreSubscriber<Wallet
modifier = modifier,
state = state,
onBackClick = {
if (state.isLoading) {
store.dispatch(
WalletConnectAction.FailureEstablishingSession(
store.state.walletConnectState.newSessionData?.session?.session,
),
)
}
store.dispatch(NavigationAction.PopBackTo())
},
)

View file

@ -1,6 +1,5 @@
package com.tangem.tap.features.details.ui.walletconnect
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession
import kotlinx.collections.immutable.ImmutableList
internal data class WalletConnectScreenState(
@ -13,13 +12,4 @@ internal data class WalletConnectScreenState(
data class WcSessionForScreen(
val description: String,
val sessionId: String,
) {
companion object {
fun fromSession(session: WalletConnectSession): WcSessionForScreen {
return WcSessionForScreen(
description = session.peerMeta.name,
sessionId = session.session.toUri(),
)
}
}
}
)

View file

@ -5,7 +5,6 @@ import arrow.core.getOrElse
import com.tangem.domain.qrscanning.models.SourceType
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
import com.tangem.tap.store
import dagger.hilt.android.lifecycle.HiltViewModel
@ -31,28 +30,18 @@ internal class WalletConnectViewModel @Inject constructor(
fun updateState(state: WalletConnectState): WalletConnectScreenState {
Timber.d("WC2 Sessions: ${state.wc2Sessions}")
val sessions = state.sessions.map { wcSession -> WcSessionForScreen.fromSession(wcSession) } + state.wc2Sessions
val sessions = state.wc2Sessions
return WalletConnectScreenState(
sessions.toImmutableList(),
isLoading = state.loading,
onRemoveSession = { sessionUri -> onRemoveSession(sessionUri, state.sessions, state.wc2Sessions) },
onRemoveSession = { sessionUri -> onRemoveSession(sessionUri, sessions) },
onAddSession = { copiedUri -> store.dispatch(WalletConnectAction.StartWalletConnect(copiedUri)) },
)
}
private fun onRemoveSession(
sessionUri: String,
sessions: List<WalletConnectSession>,
wc2sessions: List<WcSessionForScreen>,
) {
sessions
.firstOrNull { it.session.toUri() == sessionUri }
?.let { baseSession ->
store.dispatch(WalletConnectAction.DisconnectSession(baseSession.session.topic, baseSession.session))
return
}
private fun onRemoveSession(sessionUri: String, wc2sessions: List<WcSessionForScreen>) {
wc2sessions.firstOrNull { it.sessionId == sessionUri }?.let {
store.dispatch(WalletConnectAction.DisconnectSession(sessionUri, null))
store.dispatch(WalletConnectAction.DisconnectSession(sessionUri))
}
}
}

View file

@ -1,45 +0,0 @@
package com.tangem.tap.features.details.ui.walletconnect.dialogs
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.common.redux.global.GlobalAction
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
object ApproveWcSessionDialog {
fun create(session: WalletConnectSession, networks: List<Blockchain>, context: Context): AlertDialog {
val sessionBlockchain = requireNotNull(session.wallet.blockchain) { "session network is null" }
val message = context.getString(
R.string.wallet_connect_request_session_start,
session.peerMeta.name,
sessionBlockchain.fullName,
session.peerMeta.url,
)
return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply {
setTitle(context.getString(R.string.wallet_connect_title))
setMessage(message)
setPositiveButton(context.getText(R.string.common_start)) { _, _ ->
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.ChooseNetwork(sessionBlockchain))
}
if (networks.size > 1) {
setNeutralButton(context.getText(R.string.wallet_connect_select_network)) { _, _ ->
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.SelectNetwork(session = session, networks = networks))
}
}
setNegativeButton(context.getText(R.string.common_reject)) { _, _ ->
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session))
}
setOnCancelListener {
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session))
}
}.create()
}
}

View file

@ -42,13 +42,6 @@ object BnbTransactionDialog {
setTitle(context.getString(R.string.wallet_connect_title))
setMessage(fullMessage)
setPositiveButton(positiveButtonTitle) { _, _ ->
store.dispatch(
WalletConnectAction.BinanceTransaction.Sign(
id = preparedData.requestId,
data = data.data,
topic = preparedData.topic,
),
)
store.dispatch(WalletConnectAction.PerformRequestedAction(preparedData))
}
setNegativeButton(context.getText(R.string.common_reject)) { _, _ ->

View file

@ -1,35 +0,0 @@
package com.tangem.tap.features.details.ui.walletconnect.dialogs
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.common.redux.global.GlobalAction
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
object ChooseNetworkDialog {
fun create(session: WalletConnectSession, networks: List<Blockchain>, context: Context): AlertDialog {
return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog)
.setTitle(context.getString(R.string.wallet_connect_select_network))
.setNegativeButton(context.getString(R.string.common_cancel)) { _, _ ->
store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session))
}
.setOnDismissListener {
store.dispatch(GlobalAction.HideDialog)
}
.setSingleChoiceItems(networks.map { it.fullName }.toTypedArray(), 0) { _, which ->
networks.getOrNull(which)?.let { selectedBlockchain ->
store.dispatch(
WalletConnectAction.ChooseNetwork(
blockchain = selectedBlockchain,
),
)
store.dispatch(GlobalAction.HideDialog)
}
}
.create()
}
}

View file

@ -17,7 +17,6 @@ object PersonalSignDialog {
setTitle(context.getString(R.string.wallet_connect_title))
setMessage(message)
setPositiveButton(context.getText(R.string.common_sign)) { _, _ ->
store.dispatch(WalletConnectAction.SignMessage(data.topic))
store.dispatch(WalletConnectAction.PerformRequestedAction(preparedData))
}
setNegativeButton(context.getText(R.string.common_reject)) { _, _ ->

View file

@ -32,11 +32,9 @@ object TransactionDialog {
setMessage(message)
setPositiveButton(positiveButtonTitle) { _, _ ->
if (data.isEnoughFundsToSend) {
store.dispatch(WalletConnectAction.SendTransaction(data.topic))
store.dispatch(WalletConnectAction.PerformRequestedAction(preparedData))
} else {
store.dispatch(WalletConnectAction.RejectRequest(data.topic, data.id))
store.dispatch(WalletConnectAction.NotEnoughFunds)
}
}
setNegativeButton(context.getText(R.string.common_reject)) { _, _ ->

View file

@ -3,7 +3,6 @@ package com.tangem.tap.features.intentHandler.handlers
import android.content.Intent
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.removePrefixOrNull
import com.tangem.tap.domain.walletconnect.WalletConnectManager
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.intentHandler.IntentHandler
import com.tangem.tap.store
@ -20,7 +19,7 @@ class WalletConnectLinkIntentHandler : IntentHandler {
val scheme = intent.scheme ?: return false
val wcUri = when (scheme) {
WalletConnectManager.WC_SCHEME -> intentData.toString()
WC_SCHEME -> intentData.toString()
TANGEM_SCHEME -> intentData.toString().removePrefixOrNull(TANGEM_WC_PREFIX)
else -> null
}
@ -40,8 +39,9 @@ class WalletConnectLinkIntentHandler : IntentHandler {
}
private companion object {
private const val TANGEM_SCHEME = "tangem"
private const val TANGEM_WC_PREFIX = "tangem://wc?uri="
private const val DEFAULT_CHARSET_NAME = "UTF-8"
const val TANGEM_SCHEME = "tangem"
const val TANGEM_WC_PREFIX = "tangem://wc?uri="
const val DEFAULT_CHARSET_NAME = "UTF-8"
const val WC_SCHEME = "wc"
}
}