fix(WalletConnect): Fixing disconnect notifications
The disconnect notifications were operating on `WalletConnectService.currentSessionProposal`. This object stores the current session object on connect, but it's not necessarily the same session the user wants to disconnect.
To fix this I'm getting the active sessions from status-go when the disconnect request is received (from Status or dapp). If the topic matches to any connection topic owned by the users accounts we'll show a notification.
(cherry picked from commit fea4e8ed76
)
This commit is contained in:
parent
c0e5111fe5
commit
833848188c
|
@ -1,5 +1,5 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
import chronicles
|
import chronicles, times, json
|
||||||
|
|
||||||
import app_service/service/wallet_connect/service as wallet_connect_service
|
import app_service/service/wallet_connect/service as wallet_connect_service
|
||||||
import app_service/service/wallet_account/service as wallet_account_service
|
import app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
@ -47,6 +47,20 @@ QtObject:
|
||||||
self.dappsListReceived(res)
|
self.dappsListReceived(res)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
proc activeSessionsReceived(self: Controller, activeSessionsJson: string) {.signal.}
|
||||||
|
|
||||||
|
# Emits signal activeSessionsReceived with the list of active sessions
|
||||||
|
# TODO: make it async
|
||||||
|
proc getActiveSessions(self: Controller): bool {.slot.} =
|
||||||
|
let validAtTimestamp = now().toTime().toUnix()
|
||||||
|
let res = self.service.getActiveSessions(validAtTimestamp)
|
||||||
|
if res.isNil:
|
||||||
|
return false
|
||||||
|
else:
|
||||||
|
let resultStr = $res
|
||||||
|
self.activeSessionsReceived(resultStr)
|
||||||
|
return true
|
||||||
|
|
||||||
proc userAuthenticationResult*(self: Controller, topic: string, id: string, error: bool, password: string, pin: string, payload: string) {.signal.}
|
proc userAuthenticationResult*(self: Controller, topic: string, id: string, error: bool, password: string, pin: string, payload: string) {.signal.}
|
||||||
|
|
||||||
# Beware, it will fail if an authentication is already in progress
|
# Beware, it will fail if an authentication is already in progress
|
||||||
|
|
|
@ -114,6 +114,11 @@ QtObject:
|
||||||
let testChains = self.settingsService.areTestNetworksEnabled()
|
let testChains = self.settingsService.areTestNetworksEnabled()
|
||||||
# TODO #14588: call it async
|
# TODO #14588: call it async
|
||||||
return status_go.getDapps(validAtEpoch, testChains)
|
return status_go.getDapps(validAtEpoch, testChains)
|
||||||
|
|
||||||
|
proc getActiveSessions*(self: Service, validAtTimestamp: int64): JsonNode =
|
||||||
|
# TODO #14588: call it async
|
||||||
|
return status_go.getActiveSessions(validAtTimestamp)
|
||||||
|
|
||||||
|
|
||||||
# Will fail if another authentication is in progress
|
# Will fail if another authentication is in progress
|
||||||
proc authenticateUser*(self: Service, keyUid: string, callback: AuthenticationResponseFn): bool =
|
proc authenticateUser*(self: Service, keyUid: string, callback: AuthenticationResponseFn): bool =
|
||||||
|
|
|
@ -18,7 +18,7 @@ rpc(disconnectWalletConnectSession, "wallet"):
|
||||||
topic: string
|
topic: string
|
||||||
|
|
||||||
rpc(getWalletConnectActiveSessions, "wallet"):
|
rpc(getWalletConnectActiveSessions, "wallet"):
|
||||||
validAtTimestamp: int
|
validAtTimestamp: int64
|
||||||
|
|
||||||
rpc(hashMessageEIP191, "wallet"):
|
rpc(hashMessageEIP191, "wallet"):
|
||||||
message: string
|
message: string
|
||||||
|
@ -50,13 +50,14 @@ proc disconnectSession*(topic: string): bool =
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# returns nil if error
|
# returns nil if error
|
||||||
proc getActiveSessions*(validAtTimestamp: int): JsonNode =
|
proc getActiveSessions*(validAtTimestamp: int64): JsonNode =
|
||||||
try:
|
try:
|
||||||
let rpcRes = getWalletConnectActiveSessions(validAtTimestamp)
|
let rpcRes = getWalletConnectActiveSessions(validAtTimestamp)
|
||||||
|
|
||||||
if(not isSuccessResponse(rpcRes)):
|
if(not isSuccessResponse(rpcRes)):
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
let jsonResultStr = rpcRes.result.getStr()
|
let jsonResultStr = $rpcRes.result
|
||||||
if jsonResultStr == "null" or jsonResultStr == "":
|
if jsonResultStr == "null" or jsonResultStr == "":
|
||||||
return newJArray()
|
return newJArray()
|
||||||
|
|
||||||
|
|
|
@ -236,16 +236,7 @@ QObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSessionDelete(topic, err) {
|
function onSessionDelete(topic, err) {
|
||||||
store.deactivateWalletConnectSession(topic)
|
d.disconnectSessionRequested(topic, err)
|
||||||
dappsProvider.updateDapps()
|
|
||||||
|
|
||||||
const app_url = d.currentSessionProposal ? d.currentSessionProposal.params.proposer.metadata.url : "-"
|
|
||||||
const app_domain = StringUtils.extractDomainFromLink(app_url)
|
|
||||||
if(err) {
|
|
||||||
root.displayToastMessage(qsTr("Failed to disconnect from %1").arg(app_domain), true)
|
|
||||||
} else {
|
|
||||||
root.displayToastMessage(qsTr("Disconnected from %1").arg(app_domain), false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,6 +258,54 @@ QObject {
|
||||||
timeoutTimer.stop()
|
timeoutTimer.stop()
|
||||||
root.pairingValidated(state)
|
root.pairingValidated(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disconnectSessionRequested(topic, err) {
|
||||||
|
// Get all sessions and filter the active ones for known accounts
|
||||||
|
// Act on the first matching session with the same topic
|
||||||
|
const activeSessionsCallback = (allSessions, success) => {
|
||||||
|
store.activeSessionsReceived.disconnect(activeSessionsCallback)
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
// TODO #14754: implement custom dApp notification
|
||||||
|
d.notifyDappDisconnect("-", true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to original format
|
||||||
|
const webSdkSessions = allSessions.map((session) => {
|
||||||
|
return JSON.parse(session.sessionJson)
|
||||||
|
})
|
||||||
|
|
||||||
|
const sessions = DAppsHelpers.filterActiveSessionsForKnownAccounts(webSdkSessions, root.validAccounts)
|
||||||
|
|
||||||
|
for (const sessionID in sessions) {
|
||||||
|
const session = sessions[sessionID]
|
||||||
|
if (session.topic === topic) {
|
||||||
|
store.deactivateWalletConnectSession(topic)
|
||||||
|
dappsProvider.updateDapps()
|
||||||
|
|
||||||
|
const dappUrl = session.peer.metadata.url ?? "-"
|
||||||
|
d.notifyDappDisconnect(dappUrl, err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
store.activeSessionsReceived.connect(activeSessionsCallback)
|
||||||
|
if (!store.getActiveSessions()) {
|
||||||
|
store.activeSessionsReceived.disconnect(activeSessionsCallback)
|
||||||
|
// TODO #14754: implement custom dApp notification
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function notifyDappDisconnect(dappUrl, err) {
|
||||||
|
const appDomain = StringUtils.extractDomainFromLink(dappUrl)
|
||||||
|
if(err) {
|
||||||
|
root.displayToastMessage(qsTr("Failed to disconnect from %1").arg(appDomain), true)
|
||||||
|
} else {
|
||||||
|
root.displayToastMessage(qsTr("Disconnected from %1").arg(appDomain), false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
|
@ -8,6 +8,7 @@ QObject {
|
||||||
required property var controller
|
required property var controller
|
||||||
/// \c dappsJson serialized from status-go.wallet.GetDapps
|
/// \c dappsJson serialized from status-go.wallet.GetDapps
|
||||||
signal dappsListReceived(string dappsJson)
|
signal dappsListReceived(string dappsJson)
|
||||||
|
signal activeSessionsReceived(var activeSessionsJsonObj, bool success)
|
||||||
signal userAuthenticated(string topic, string id, string password, string pin, string payload)
|
signal userAuthenticated(string topic, string id, string password, string pin, string payload)
|
||||||
signal userAuthenticationFailed(string topic, string id)
|
signal userAuthenticationFailed(string topic, string id)
|
||||||
|
|
||||||
|
@ -106,6 +107,12 @@ QObject {
|
||||||
function getDapps() {
|
function getDapps() {
|
||||||
return controller.getDapps()
|
return controller.getDapps()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \c getActiveSessions triggers an async response to \c activeSessionsReceived
|
||||||
|
/// \returns true if the request was sent successfully
|
||||||
|
function getActiveSessions() {
|
||||||
|
return controller.getActiveSessions()
|
||||||
|
}
|
||||||
|
|
||||||
function hexToDec(hex) {
|
function hexToDec(hex) {
|
||||||
return controller.hexToDecBigString(hex)
|
return controller.hexToDecBigString(hex)
|
||||||
|
@ -124,6 +131,17 @@ QObject {
|
||||||
root.dappsListReceived(dappsJson)
|
root.dappsListReceived(dappsJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onActiveSessionsReceived(activeSessionsJson) {
|
||||||
|
try {
|
||||||
|
const jsonObj = JSON.parse(activeSessionsJson)
|
||||||
|
root.activeSessionsReceived(jsonObj, true)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to parse activeSessionsJson", e)
|
||||||
|
root.activeSessionsReceived({}, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onUserAuthenticationResult(topic, id, success, password, pin, payload) {
|
function onUserAuthenticationResult(topic, id, success, password, pin, payload) {
|
||||||
if (success) {
|
if (success) {
|
||||||
root.userAuthenticated(topic, id, password, pin, payload)
|
root.userAuthenticated(topic, id, password, pin, payload)
|
||||||
|
|
Loading…
Reference in New Issue