Updated on 2026-08-14

This commit is contained in:
Tangem 2023-08-14 12:03:17 +04:00
parent fc173d3a1f
commit 982c8fdc66
4 changed files with 72 additions and 19 deletions

View file

@ -8,6 +8,7 @@ import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.core.analytics.Analytics
import com.tangem.datasource.config.ConfigManager
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.models.scan.ScanResponse
@ -20,6 +21,8 @@ import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.walletStores.WalletStoresError
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
import com.tangem.tap.domain.walletconnect2.domain.models.Account
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.disclaimer.createDisclaimer
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
@ -92,7 +95,8 @@ class TapWalletManager(
null
}
scope.launch {
store.state.daggerGraphState.walletConnectInteractor?.startListening(
val wcInteractor = store.state.daggerGraphState.walletConnectInteractor ?: return@launch
wcInteractor.startListening(
userWalletId = userWallet.walletId.stringValue,
cardId = cardId,
)
@ -106,6 +110,9 @@ class TapWalletManager(
store.dispatchOnMain(WalletAction.LoadData.Success)
store.state.globalState.topUpController?.loadDataSuccess()
store.dispatchWithMain(WalletAction.Warnings.CheckHashesCount.VerifyOnlineIfNeeded)
val wcInteractor = store.state.daggerGraphState.walletConnectInteractor
wcInteractor?.setUserChains(getAccountsForWc(wcInteractor))
}
.doOnFailure { error ->
val errorAction = when (error) {
@ -135,6 +142,23 @@ class TapWalletManager(
}
}
private fun getAccountsForWc(wcInteractor: WalletConnectInteractor): List<Account> {
return store.state.walletState.walletManagers
.mapNotNull {
val wallet = it.wallet
val chainId = wcInteractor.blockchainHelper.networkIdToChainIdOrNull(
wallet.blockchain.toNetworkId(),
)
chainId?.let {
Account(
chainId,
wallet.address,
wallet.publicKey.derivationPath?.rawPath,
)
}
}
}
fun updateConfigManager(data: ScanResponse) {
val configManager = store.state.globalState.configManager

View file

@ -100,6 +100,28 @@ class WalletConnectRepositoryImpl @Inject constructor(
Timber.d("sessionProposal: $sessionProposal")
this@WalletConnectRepositoryImpl.sessionProposal = sessionProposal
val missingNetworks = findMissingNetworks(
namespaces = sessionProposal.requiredNamespaces,
userNamespaces = this@WalletConnectRepositoryImpl.userNamespaces ?: emptyMap(),
)
if (missingNetworks.isNotEmpty()) {
Timber.w("Not added blockchains: $missingNetworks")
scope.launch {
_events.emit(
WalletConnectEvents.SessionApprovalError(
WalletConnectError.ApprovalErrorMissingNetworks(missingNetworks.toList()),
),
)
}
return
}
val optionalWithoutMissingNetworks = removeMissingNetworks(
namespaces = sessionProposal.optionalNamespaces,
userNamespaces = this@WalletConnectRepositoryImpl.userNamespaces ?: emptyMap(),
)
scope.launch {
_events.emit(
WalletConnectEvents.SessionProposal(
@ -108,7 +130,7 @@ class WalletConnectRepositoryImpl @Inject constructor(
sessionProposal.url,
sessionProposal.icons,
sessionProposal.requiredNamespaces.values.flatMap { it.chains ?: emptyList() },
sessionProposal.optionalNamespaces.values.flatMap { it.chains ?: emptyList() },
optionalWithoutMissingNetworks.toList(),
),
)
}
@ -211,6 +233,10 @@ class WalletConnectRepositoryImpl @Inject constructor(
}
}
override fun setUserNamespaces(userNamespaces: Map<NetworkNamespace, List<Account>>) {
this.userNamespaces = userNamespaces
}
override fun pair(uri: String) {
Web3Wallet.pair(Wallet.Params.Pair(uri))
}
@ -220,23 +246,6 @@ class WalletConnectRepositoryImpl @Inject constructor(
val sessionProposal: Wallet.Model.SessionProposal = requireNotNull(this.sessionProposal)
val missingNetworks = findMissingNetworks(
namespaces = sessionProposal.requiredNamespaces,
userNamespaces = userNamespaces,
)
if (missingNetworks.isNotEmpty()) {
Timber.e("Not added blockchains: $missingNetworks")
scope.launch {
_events.emit(
WalletConnectEvents.SessionApprovalError(
WalletConnectError.ApprovalErrorMissingNetworks(missingNetworks.toList()),
),
)
}
return
}
val userChains = userNamespaces.flatMap { namespace ->
namespace.value.map { it.chainId to "${it.chainId}:${it.walletAddress}" }
}.groupBy { pair -> pair.first }
@ -430,4 +439,13 @@ class WalletConnectRepositoryImpl @Inject constructor(
val userChains = userNamespaces.flatMap { it.value.map { account -> account.chainId } }
return requiredChains.subtract(userChains.toSet())
}
private fun removeMissingNetworks(
namespaces: Map<String, Wallet.Model.Namespace.Proposal>,
userNamespaces: Map<NetworkNamespace, List<Account>>,
): Collection<String> {
val wcProvidedChains = namespaces.values.flatMap { it.chains ?: emptyList() }
val userChains = userNamespaces.flatMap { it.value.map { account -> account.chainId } }
return wcProvidedChains.intersect(userChains.toSet())
}
}

View file

@ -44,6 +44,15 @@ class WalletConnectInteractor(
}
}
fun setUserChains(accounts: List<Account>) {
val userNamespaces: Map<NetworkNamespace, List<Account>> = accounts
.groupBy { account ->
blockchainHelper.getNamespaceFromFullChainIdOrNull(account.chainId)
?.let { NetworkNamespace(it) }
}.filterNotNull()
walletConnectRepository.setUserNamespaces(userNamespaces)
}
private suspend fun subscribeToEvents() {
events
.onEach { wcEvent ->

View file

@ -11,6 +11,8 @@ interface WalletConnectRepository {
fun init(projectId: String)
fun setUserNamespaces(userNamespaces: Map<NetworkNamespace, List<Account>>)
fun updateSessions()
fun pair(uri: String)