chore(walletconnect): store wallet connect sessions instead of pairings

Closes: #13008
This commit is contained in:
Sale Djenic 2023-12-14 08:39:38 +01:00 committed by saledjenic
parent 3d408e4966
commit 969998dd3f
9 changed files with 110 additions and 89 deletions

View File

@ -30,7 +30,7 @@ QtObject:
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
sessionRequestJson: JsonNode sessionRequestJson: JsonNode
txResponseDto: TxResponseDto txResponseDto: TxResponseDto
hasActivePairings: Option[bool] hasActivePairings: bool
## Forward declarations ## Forward declarations
proc invalidateData(self: Controller) proc invalidateData(self: Controller)
@ -38,7 +38,13 @@ QtObject:
proc finishSessionRequest(self: Controller, signature: string) proc finishSessionRequest(self: Controller, signature: string)
proc finishAuthRequest(self: Controller, signature: string) proc finishAuthRequest(self: Controller, signature: string)
## signals
proc requestOpenWalletConnectPopup*(self: Controller, uri: string) {.signal.} proc requestOpenWalletConnectPopup*(self: Controller, uri: string) {.signal.}
proc hasActivePairingsChanged*(self: Controller) {.signal.}
proc respondSessionProposal*(self: Controller, sessionProposalJson: string, supportedNamespacesJson: string, error: string) {.signal.}
proc respondSessionRequest*(self: Controller, sessionRequestJson: string, signedJson: string, error: bool) {.signal.}
proc respondAuthRequest*(self: Controller, signature: string, error: bool) {.signal.}
proc setup(self: Controller) = proc setup(self: Controller) =
self.QObject.setup self.QObject.setup
@ -88,9 +94,6 @@ QtObject:
else: else:
error "Unknown identifier" error "Unknown identifier"
# supportedNamespaces is a Namespace as defined in status-go: services/wallet/walletconnect/walletconnect.go
proc respondSessionProposal*(self: Controller, sessionProposalJson: string, supportedNamespacesJson: string, error: string) {.signal.}
proc sessionProposal(self: Controller, sessionProposalJson: string) {.slot.} = proc sessionProposal(self: Controller, sessionProposalJson: string) {.slot.} =
var var
supportedNamespacesJson: string supportedNamespacesJson: string
@ -107,27 +110,24 @@ QtObject:
error "pairing", msg=error error "pairing", msg=error
self.respondSessionProposal(sessionProposalJson, supportedNamespacesJson, error) self.respondSessionProposal(sessionProposalJson, supportedNamespacesJson, error)
proc recordSuccessfulPairing(self: Controller, sessionProposalJson: string) {.slot.} = proc saveOrUpdateSession(self: Controller, sessionJson: string) {.slot.} =
if backend_wallet_connect.recordSuccessfulPairing(sessionProposalJson): if not backend_wallet_connect.saveOrUpdateSession(sessionJson):
if not self.hasActivePairings.get(false): error "Failed to save/update session"
self.hasActivePairings = some(true)
proc deletePairing(self: Controller, topic: string) {.slot.} = proc deleteSession(self: Controller, topic: string) {.slot.} =
if backend_wallet_connect.deletePairing(topic): if not backend_wallet_connect.deleteSession(topic):
if self.hasActivePairings.get(false): error "Failed to delete session"
self.hasActivePairings = some(backend_wallet_connect.hasActivePairings())
else:
error "Failed to delete pairing"
proc getHasActivePairings*(self: Controller): bool {.slot.} = proc getHasActivePairings*(self: Controller): bool {.slot.} =
if self.hasActivePairings.isNone: return self.hasActivePairings
self.hasActivePairings = some(backend_wallet_connect.hasActivePairings())
return self.hasActivePairings.get(false) proc setHasActivePairings(self: Controller, value: bool) =
self.hasActivePairings = value
self.hasActivePairingsChanged()
QtProperty[bool] hasActivePairings: QtProperty[bool] hasActivePairings:
read = getHasActivePairings read = getHasActivePairings
notify = hasActivePairingsChanged
proc respondSessionRequest*(self: Controller, sessionRequestJson: string, signedJson: string, error: bool) {.signal.}
proc sendTransactionAndRespond(self: Controller, signature: string) = proc sendTransactionAndRespond(self: Controller, signature: string) =
let finalSignature = singletonInstance.utils.removeHexPrefix(signature) let finalSignature = singletonInstance.utils.removeHexPrefix(signature)
@ -213,8 +213,6 @@ QtObject:
let jsonObj = % self.walletAccountService.getWalletAccounts() let jsonObj = % self.walletAccountService.getWalletAccounts()
return $jsonObj return $jsonObj
proc respondAuthRequest*(self: Controller, signature: string, error: bool) {.signal.}
proc finishAuthRequest(self: Controller, signature: string) = proc finishAuthRequest(self: Controller, signature: string) =
if signature.len == 0: if signature.len == 0:
self.respondAuthRequest("", true) self.respondAuthRequest("", true)

View File

@ -26,16 +26,13 @@ rpc(wCSendTransactionWithSignature, "wallet"):
rpc(wCPairSessionProposal, "wallet"): rpc(wCPairSessionProposal, "wallet"):
sessionProposalJson: string sessionProposalJson: string
rpc(wCRecordSuccessfulPairing, "wallet"): rpc(wCSaveOrUpdateSession, "wallet"):
sessionProposalJson: string sessionJson: string
rpc(wCChangePairingState, "wallet"): rpc(wCChangeSessionState, "wallet"):
topic: string topic: string
active: bool active: bool
rpc(wCHasActivePairings, "wallet"):
discard
rpc(wCSessionRequest, "wallet"): rpc(wCSessionRequest, "wallet"):
sessionRequestJson: string sessionRequestJson: string
@ -63,32 +60,22 @@ proc pair*(res: var JsonNode, sessionProposalJson: string): string =
warn e.msg warn e.msg
return e.msg return e.msg
proc recordSuccessfulPairing*(sessionProposalJson: string): bool = proc saveOrUpdateSession*(sessionJson: string): bool =
try: try:
let response = wCRecordSuccessfulPairing(sessionProposalJson) let response = wCSaveOrUpdateSession(sessionJson)
return not isErrorResponse(response) return not isErrorResponse(response)
except Exception as e: except Exception as e:
warn e.msg warn e.msg
return false return false
proc deletePairing*(topic: string): bool = proc deleteSession*(topic: string): bool =
try: try:
let response = wCChangePairingState(topic, false) let response = wCChangeSessionState(topic, false)
return not isErrorResponse(response) return not isErrorResponse(response)
except Exception as e: except Exception as e:
warn e.msg warn e.msg
return false return false
proc hasActivePairings*(): bool =
try:
let response = wCHasActivePairings()
if isErrorResponse(response):
return false
return response.result.getBool()
except Exception as e:
warn e.msg
return false
proc sessionRequest*(res: var JsonNode, sessionRequestJson: string): string = proc sessionRequest*(res: var JsonNode, sessionRequestJson: string): string =
try: try:
let response = wCSessionRequest(sessionRequestJson) let response = wCSessionRequest(sessionRequestJson)

View File

@ -23,7 +23,7 @@ StatusListItem {
title: account.name title: account.name
subTitle: { subTitle: {
const elidedAddress = StatusQUtils.Utils.elideText(account.address,6,4) const elidedAddress = StatusQUtils.Utils.elideText(account.address,6,4)
let chainShortNames = root.getNetworkShortNames(model.account.preferredSharingChainIds) let chainShortNames = root.getNetworkShortNames(account.preferredSharingChainIds)
return sensor.containsMouse ? WalletUtils.colorizedChainPrefix(chainShortNames) + Utils.richColorText(elidedAddress, Theme.palette.directColor1) : chainShortNames + elidedAddress return sensor.containsMouse ? WalletUtils.colorizedChainPrefix(chainShortNames) + Utils.richColorText(elidedAddress, Theme.palette.directColor1) : chainShortNames + elidedAddress
} }
asset.color: !!account.colorId ? Utils.getColorForId(account.colorId): "" asset.color: !!account.colorId ? Utils.getColorForId(account.colorId): ""

View File

@ -28,9 +28,6 @@ Item {
onSessionRequestEvent: (details) => { onSessionRequestEvent: (details) => {
modal.openWithSessionRequestEvent(details) modal.openWithSessionRequestEvent(details)
} }
onSessionDelete: (deletePayload) => {
root.controller.deletePairing(deletePayload.topic)
}
} }
Connections { Connections {

View File

@ -208,7 +208,7 @@ Popup {
model: root.sdk.sessionsModel model: root.sdk.sessionsModel
onDisconnect: function (topic) { onDisconnect: function (topic) {
root.sdk.disconnectTopic(topic) root.sdk.disconnectSession(topic)
} }
onPing: function (topic) { onPing: function (topic) {
@ -227,7 +227,7 @@ Popup {
model: root.sdk.pairingsModel model: root.sdk.pairingsModel
onDisconnect: function (topic) { onDisconnect: function (topic) {
root.sdk.disconnectTopic(topic) root.sdk.disconnectPairing(topic)
} }
} }
} }
@ -292,6 +292,16 @@ Popup {
root.controller.sessionProposal(JSON.stringify(sessionProposal)) root.controller.sessionProposal(JSON.stringify(sessionProposal))
} }
function onSessionDelete(topic, error) {
if (!!error) {
d.setStatusText(`Error deleting session: ${error}`, "red")
d.setDetailsText("")
return
}
root.controller.deleteSession(topic)
}
function onSessionRequestEvent(sessionRequest) { function onSessionRequestEvent(sessionRequest) {
d.setStatusText("Approve session request") d.setStatusText("Approve session request")
d.setDetailsText(JSON.stringify(sessionRequest, null, 2)) d.setDetailsText(JSON.stringify(sessionRequest, null, 2))
@ -299,12 +309,15 @@ Popup {
root.state = d.waitingUserResponseToSessionRequest root.state = d.waitingUserResponseToSessionRequest
} }
function onApproveSessionResult(sessionProposal, error) { function onApproveSessionResult(session, error) {
d.setDetailsText("") d.setDetailsText("")
if (!error) { if (!error) {
d.setStatusText("Pairing OK") d.setStatusText("Pairing OK")
d.state = d.pairedState d.state = d.pairedState
root.controller.recordSuccessfulPairing(JSON.stringify(sessionProposal))
root.sdk.getActiveSessions((activeSession) => {
root.controller.saveOrUpdateSession(JSON.stringify(session))
})
} else { } else {
d.setStatusText("Pairing error", "red") d.setStatusText("Pairing error", "red")
d.state = "" d.state = ""

View File

@ -29,7 +29,7 @@ Item {
signal sdkInit(bool success, var result) signal sdkInit(bool success, var result)
signal sessionProposal(var sessionProposal) signal sessionProposal(var sessionProposal)
signal sessionProposalExpired() signal sessionProposalExpired()
signal approveSessionResult(var sessionProposal, string error) signal approveSessionResult(var session, string error)
signal rejectSessionResult(string error) signal rejectSessionResult(string error)
signal sessionRequestEvent(var sessionRequest) signal sessionRequestEvent(var sessionRequest)
signal sessionRequestUserAnswerResult(bool accept, string error) signal sessionRequestUserAnswerResult(bool accept, string error)
@ -38,14 +38,22 @@ Item {
signal authMessageFormated(string formatedMessage, string address) signal authMessageFormated(string formatedMessage, string address)
signal authRequestUserAnswerResult(bool accept, string error) signal authRequestUserAnswerResult(bool accept, string error)
signal sessionDelete(var deletePayload) signal sessionDelete(var topic, string error)
function pair(pairLink) { function pair(pairLink) {
wcCalls.pair(pairLink) wcCalls.pair(pairLink)
} }
function disconnectTopic(topic) { function getActiveSessions(callback) {
wcCalls.disconnectTopic(topic) wcCalls.getActiveSessions(callback)
}
function disconnectSession(topic) {
wcCalls.disconnectSession(topic)
}
function disconnectPairing(topic) {
wcCalls.disconnectPairing(topic)
} }
function ping(topic) { function ping(topic) {
@ -184,7 +192,11 @@ Item {
console.debug(`WC WalletConnectSDK.wcCall.getActiveSessions;`) console.debug(`WC WalletConnectSDK.wcCall.getActiveSessions;`)
d.engine.runJavaScript(`wc.getActiveSessions()`, function(result) { d.engine.runJavaScript(`wc.getActiveSessions()`, function(result) {
console.debug(`WC WalletConnectSDK.wcCall.getActiveSessions; result: ${JSON.stringify(result, null, 2)}`) let allSessions = ""
for (var key of Object.keys(result)) {
allSessions += `\nsessionTopic: ${key} relatedPairingTopic: ${result[key].pairingTopic}`;
}
console.debug(`WC WalletConnectSDK.wcCall.getActiveSessions; result: ${allSessions}`)
if (callback && result) { if (callback && result) {
callback(result) callback(result)
@ -212,11 +224,11 @@ Item {
d.engine.runJavaScript(` d.engine.runJavaScript(`
wc.approveSession(${JSON.stringify(sessionProposal)}, ${JSON.stringify(supportedNamespaces)}) wc.approveSession(${JSON.stringify(sessionProposal)}, ${JSON.stringify(supportedNamespaces)})
.then((value) => { .then((session) => {
wc.statusObject.onApproveSessionResponse(${JSON.stringify(sessionProposal)}, "") wc.statusObject.onApproveSessionResponse(session, "")
}) })
.catch((e) => { .catch((e) => {
wc.statusObject.onApproveSessionResponse(${JSON.stringify(sessionProposal)}, e.message) wc.statusObject.onApproveSessionResponse("", e.message)
}) })
` `
) )
@ -267,16 +279,31 @@ Item {
) )
} }
function disconnectTopic(topic) { function disconnectSession(topic) {
console.debug(`WC WalletConnectSDK.wcCall.disconnectTopic; topic: "${topic}"`) console.debug(`WC WalletConnectSDK.wcCall.disconnectSession; topic: "${topic}"`)
d.engine.runJavaScript(` d.engine.runJavaScript(`
wc.disconnect("${topic}") wc.disconnect("${topic}")
.then((value) => { .then(() => {
wc.statusObject.onDisconnectResponse("") wc.statusObject.onDisconnectSessionResponse("${topic}", "")
}) })
.catch((e) => { .catch((e) => {
wc.statusObject.onDisconnectResponse(e.message) wc.statusObject.onDisconnectSessionResponse("", e.message)
})
`
)
}
function disconnectPairing(topic) {
console.debug(`WC WalletConnectSDK.wcCall.disconnectPairing; topic: "${topic}"`)
d.engine.runJavaScript(`
wc.disconnect("${topic}")
.then(() => {
wc.statusObject.onDisconnectPairingResponse("${topic}", "")
})
.catch((e) => {
wc.statusObject.onDisconnectPairingResponse("", e.message)
}) })
` `
) )
@ -384,23 +411,22 @@ Item {
console.debug(`WC WalletConnectSDK.onPingResponse; error: ${error}`) console.debug(`WC WalletConnectSDK.onPingResponse; error: ${error}`)
} }
function onDisconnectResponse(error) { function onDisconnectSessionResponse(topic, error) {
console.debug(`WC WalletConnectSDK.onDisconnectResponse; error: ${error}`) console.debug(`WC WalletConnectSDK.onDisconnectSessionResponse; topic: ${topic}, error: ${error}`)
d.resetPairingsModel()
d.resetSessionsModel() d.resetSessionsModel()
root.sessionDelete(topic, error)
} }
function onApproveSessionResponse(sessionProposal, error) { function onDisconnectPairingResponse(topic, error) {
console.debug(`WC WalletConnectSDK.onApproveSessionResponse; sessionProposal: ${JSON.stringify(sessionProposal, null, 2)}, error: ${error}`) console.debug(`WC WalletConnectSDK.onDisconnectPairingResponse; topic: ${topic}, error: ${error}`)
d.resetPairingsModel()
}
// Update the temporary expiry with the one from the pairing function onApproveSessionResponse(session, error) {
d.resetPairingsModel((pairing) => { console.debug(`WC WalletConnectSDK.onApproveSessionResponse; sessionTopic: ${JSON.stringify(session, null, 2)}, error: ${error}`)
if (pairing.topic === sessionProposal.params.pairingTopic) { d.resetPairingsModel()
sessionProposal.params.expiry = pairing.expiry
root.approveSessionResult(sessionProposal, error)
}
})
d.resetSessionsModel() d.resetSessionsModel()
root.approveSessionResult(session, error)
} }
function onRejectSessionResponse(error) { function onRejectSessionResponse(error) {
@ -443,7 +469,7 @@ Item {
function onSessionDelete(details) { function onSessionDelete(details) {
console.debug(`WC WalletConnectSDK.onSessionDelete; details: ${JSON.stringify(details, null, 2)}`) console.debug(`WC WalletConnectSDK.onSessionDelete; details: ${JSON.stringify(details, null, 2)}`)
root.sessionDelete(details) root.sessionDelete(details.topic, "")
d.resetPairingsModel() d.resetPairingsModel()
d.resetSessionsModel() d.resetSessionsModel()
} }

File diff suppressed because one or more lines are too long

View File

@ -54,47 +54,47 @@ window.wc = {
}); });
// connect session responses https://specs.walletconnect.com/2.0/specs/clients/sign/session-events#events // connect session responses https://specs.walletconnect.com/2.0/specs/clients/sign/session-events#events
window.wc.web3wallet.on("session_proposal", async (details) => { window.wc.web3wallet.on("session_proposal", (details) => {
wc.statusObject.onSessionProposal(details) wc.statusObject.onSessionProposal(details)
}); });
window.wc.web3wallet.on("session_update", async (details) => { window.wc.web3wallet.on("session_update", (details) => {
wc.statusObject.onSessionUpdate(details) wc.statusObject.onSessionUpdate(details)
}); });
window.wc.web3wallet.on("session_extend", async (details) => { window.wc.web3wallet.on("session_extend", (details) => {
wc.statusObject.onSessionExtend(details) wc.statusObject.onSessionExtend(details)
}); });
window.wc.web3wallet.on("session_ping", async (details) => { window.wc.web3wallet.on("session_ping", (details) => {
wc.statusObject.onSessionPing(details) wc.statusObject.onSessionPing(details)
}); });
window.wc.web3wallet.on("session_delete", async (details) => { window.wc.web3wallet.on("session_delete", (details) => {
wc.statusObject.onSessionDelete(details) wc.statusObject.onSessionDelete(details)
}); });
window.wc.web3wallet.on("session_expire", async (details) => { window.wc.web3wallet.on("session_expire", (details) => {
wc.statusObject.onSessionExpire(details) wc.statusObject.onSessionExpire(details)
}); });
window.wc.web3wallet.on("session_request", async (details) => { window.wc.web3wallet.on("session_request", (details) => {
wc.statusObject.onSessionRequest(details) wc.statusObject.onSessionRequest(details)
}); });
window.wc.web3wallet.on("session_request_sent", async (details) => { window.wc.web3wallet.on("session_request_sent", (details) => {
wc.statusObject.onSessionRequestSent(details) wc.statusObject.onSessionRequestSent(details)
}); });
window.wc.web3wallet.on("session_event", async (details) => { window.wc.web3wallet.on("session_event", (details) => {
wc.statusObject.onSessionEvent(details) wc.statusObject.onSessionEvent(details)
}); });
window.wc.web3wallet.on("proposal_expire", async (details) => { window.wc.web3wallet.on("proposal_expire", (details) => {
wc.statusObject.onProposalExpire(details) wc.statusObject.onProposalExpire(details)
}); });
window.wc.authClient.on("auth_request", async (details) => { window.wc.authClient.on("auth_request", (details) => {
wc.statusObject.onAuthRequest(details) wc.statusObject.onAuthRequest(details)
}); });
@ -141,7 +141,7 @@ window.wc = {
} }
); );
await window.wc.web3wallet.approveSession( return await window.wc.web3wallet.approveSession(
{ {
id, id,
relayProtocol: relays[0].protocol, relayProtocol: relays[0].protocol,

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit b52a9ce0e5f72e62086f84a6a639a6de0bfd5c7e Subproject commit 9dea2e8875bba654328aaf0e6a5f37c8a45a5cdd