Skip to content

Commit

Permalink
feature(connector)_: Add model join to handle connected dApps (#15954)
Browse files Browse the repository at this point in the history
* feature(connector)_: Add model join to handle connected dApps

* Fix review comments

* chore: bump status-go
  • Loading branch information
kounkou committed Aug 6, 2024
1 parent 767215e commit b4e07a5
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 9 deletions.
22 changes: 22 additions & 0 deletions src/app/core/signals/remote_signals/connector.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ type ConnectorSendTransactionSignal* = ref object of Signal
chainId*: int
txArgs*: string

type ConnectorGrantDAppPermissionSignal* = ref object of Signal
url*: string
name*: string
iconUrl*: string

type ConnectorRevokeDAppPermissionSignal* = ref object of Signal
url*: string
name*: string
iconUrl*: string

proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal =
result = ConnectorSendRequestAccountsSignal()
result.url = event["event"]{"url"}.getStr()
Expand All @@ -32,3 +42,15 @@ proc fromEvent*(T: type ConnectorSendTransactionSignal, event: JsonNode): Connec
result.requestId = event["event"]{"requestId"}.getStr()
result.chainId = event["event"]{"chainId"}.getInt()
result.txArgs = event["event"]{"txArgs"}.getStr()

proc fromEvent*(T: type ConnectorGrantDAppPermissionSignal, event: JsonNode): ConnectorGrantDAppPermissionSignal =
result = ConnectorGrantDAppPermissionSignal()
result.url = event["event"]{"url"}.getStr()
result.name = event["event"]{"name"}.getStr()
result.iconUrl = event["event"]{"iconUrl"}.getStr()

proc fromEvent*(T: type ConnectorRevokeDAppPermissionSignal, event: JsonNode): ConnectorRevokeDAppPermissionSignal =
result = ConnectorRevokeDAppPermissionSignal()
result.url = event["event"]{"url"}.getStr()
result.name = event["event"]{"name"}.getStr()
result.iconUrl = event["event"]{"iconUrl"}.getStr()
2 changes: 2 additions & 0 deletions src/app/core/signals/remote_signals/signal_type.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ type SignalType* {.pure.} = enum
CommunityTokenAction = "communityToken.communityTokenAction"
ConnectorSendRequestAccounts = "connector.sendRequestAccounts"
ConnectorSendTransaction = "connector.sendTransaction"
ConnectorGrantDAppPermission = "connector.dAppPermissionGranted"
ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked"
Unknown

proc event*(self:SignalType):string =
Expand Down
2 changes: 2 additions & 0 deletions src/app/core/signals/signals_manager.nim
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ QtObject:
of SignalType.CommunityTokenAction: CommunityTokenActionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorSendRequestAccounts: ConnectorSendRequestAccountsSignal.fromEvent(jsonSignal)
of SignalType.ConnectorSendTransaction: ConnectorSendTransactionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorGrantDAppPermission: ConnectorGrantDAppPermissionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal)
else: Signal()

result.signalType = signalType
27 changes: 27 additions & 0 deletions src/app/modules/shared_modules/connector/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import app_service/common/utils

const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"

logScope:
topics = "connector-controller"
Expand All @@ -26,6 +28,8 @@ QtObject:

proc dappRequestsToConnect*(self: Controller, requestId: string, payload: string) {.signal.}
proc dappValidatesTransaction*(self: Controller, requestId: string, payload: string) {.signal.}
proc dappGrantDAppPermission*(self: Controller, payload: string) {.signal.}
proc dappRevokeDAppPermission*(self: Controller, payload: string) {.signal.}

proc newController*(service: connector_service.Service, events: EventEmitter): Controller =
new(result, delete)
Expand Down Expand Up @@ -61,6 +65,26 @@ QtObject:

controller.dappValidatesTransaction(params.requestId, dappInfo.toJson())

result.events.on(SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION) do(e: Args):
let params = ConnectorGrantDAppPermissionSignal(e)
let dappInfo = %*{
"icon": params.iconUrl,
"name": params.name,
"url": params.url,
}

controller.dappGrantDAppPermission(dappInfo.toJson())

result.events.on(SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION) do(e: Args):
let params = ConnectorRevokeDAppPermissionSignal(e)
let dappInfo = %*{
"icon": params.iconUrl,
"name": params.name,
"url": params.url,
}

controller.dappRevokeDAppPermission(dappInfo.toJson())

result.QObject.setup

proc parseSingleUInt(chainIDsString: string): uint =
Expand All @@ -87,3 +111,6 @@ QtObject:

proc rejectTransactionSigning*(self: Controller, requestId: string): bool {.slot.} =
return self.service.rejectTransactionSigning(requestId)

proc recallDAppPermission*(self: Controller, dAppUrl: string): bool {.slot.} =
return self.service.recallDAppPermission(dAppUrl)
26 changes: 26 additions & 0 deletions src/app_service/service/connector/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ logScope:

const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"

# Enum with events
type Event* = enum
Expand Down Expand Up @@ -65,6 +67,22 @@ QtObject:

self.events.emit(SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION, data)
)
self.events.on(SignalType.ConnectorGrantDAppPermission.event, proc(e: Args) =
if self.eventHandler == nil:
return

var data = ConnectorGrantDAppPermissionSignal(e)

self.events.emit(SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION, data)
)
self.events.on(SignalType.ConnectorRevokeDAppPermission.event, proc(e: Args) =
if self.eventHandler == nil:
return

var data = ConnectorRevokeDAppPermissionSignal(e)

self.events.emit(SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION, data)
)

proc registerEventsHandler*(self: Service, handler: EventHandlerFn) =
self.eventHandler = handler
Expand Down Expand Up @@ -112,3 +130,11 @@ QtObject:

proc rejectDappConnect*(self: Service, requestId: string): bool =
rejectRequest(self, requestId, status_go.requestAccountsRejectedFinishedRpc, "requestAccountsRejectedFinishedRpc failed: ")

proc recallDAppPermission*(self: Service, dAppUrl: string): bool =
try:
return status_go.recallDAppPermissionFinishedRpc(dAppUrl)

except Exception as e:
error "recallDAppPermissionFinishedRpc failed: ", err=e.msg
return false
11 changes: 10 additions & 1 deletion src/backend/connector.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type SendTransactionAcceptedArgs* = ref object of RootObj
type RejectedArgs* = ref object of RootObj
requestId* {.serializedFieldName("requestId").}: string

type RecallDAppPermissionArgs* = ref object of RootObj
dAppUrl* {.serializedFieldName("dAppUrl").}: string

rpc(requestAccountsAccepted, "connector"):
args: RequestAccountsAcceptedArgs

Expand All @@ -32,6 +35,9 @@ rpc(sendTransactionRejected, "connector"):
rpc(requestAccountsRejected, "connector"):
args: RejectedArgs

rpc(recallDAppPermission, "connector"):
dAppUrl: string

proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
return rpcResponse.error.isNil

Expand All @@ -45,4 +51,7 @@ proc sendTransactionAcceptedFinishedRpc*(args: SendTransactionAcceptedArgs): boo
return isSuccessResponse(sendTransactionAccepted(args))

proc sendTransactionRejectedFinishedRpc*(args: RejectedArgs): bool =
return isSuccessResponse(sendTransactionRejected(args))
return isSuccessResponse(sendTransactionRejected(args))

proc recallDAppPermissionFinishedRpc*(dAppUrl: string): bool =
return isSuccessResponse(recallDAppPermission(dAppUrl))
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import QtQuick 2.15
import StatusQ.Core.Utils 0.1
import AppLayouts.Wallet.services.dapps 1.0
import shared.stores 1.0
import utils 1.0

QObject {
id: root

readonly property alias dappsModel: d.dappsModel

function addSession(session) {
d.addSession(session)
}

function revokeSession(session) {
d.revokeSession(session)
}

function getActiveSession(dAppUrl) {
return d.getActionSession(dAppUrl)
}

QObject {
id: d

property ListModel dappsModel: ListModel {
id: dapps
}

function addSession(dappInfo) {
let dappItem = JSON.parse(dappInfo)
dapps.append(dappItem)
}

function revokeSession(dappInfo) {
let dappItem = JSON.parse(dappInfo)
for (let i = 0; i < dapps.count; i++) {
let existingDapp = dapps.get(i)
if (existingDapp.url === dappItem.url) {
dapps.remove(i)
break
}
}
}

function revokeAllSessions() {
for (let i = 0; i < dapps.count; i++) {
dapps.remove(i)
}
}

function getActionSession(dAppUrl) {
for (let i = 0; i < dapps.count; i++) {
let existingDapp = dapps.get(i)

if (existingDapp.url === dAppUrl) {
return JSON.stringify({
name: existingDapp.name,
url: existingDapp.url,
icon: existingDapp.iconUrl
});
}
}

return null
}
}
}
73 changes: 67 additions & 6 deletions ui/app/AppLayouts/Wallet/services/dapps/DappsConnectorSDK.qml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ WalletConnectSDKBase {
property string requestId: ""
property alias requestsModel: requests

readonly property string invalidDAppUrlError: "Invalid dappInfo: URL is missing"

projectId: ""

implicitWidth: 1
Expand Down Expand Up @@ -103,10 +105,10 @@ WalletConnectSDKBase {
return null
}

let session = getActiveSessions(root.dappInfo)
let session = getActiveSession(root.dappInfo)

if (session === null) {
console.error("DAppsRequestHandler.lookupSession: error finding session for topic", obj.topic)
console.error("Connector.lookupSession: error finding session for requestId ", obj.requestId)
return
}
obj.resolveDappInfoFromSession(session)
Expand Down Expand Up @@ -254,15 +256,15 @@ WalletConnectSDKBase {
}

function acceptSessionRequest(topic, method, id, signature) {
console.debug(`WC DappsConnectorSDK.acceptSessionRequest; topic: "${topic}", id: ${root.requestId}, signature: "${signature}"`)
console.debug(`Connector DappsConnectorSDK.acceptSessionRequest; requestId: ${root.requestId}, signature: "${signature}"`)

sessionRequestLoader.active = false
controller.approveTransactionRequest(requestId, signature)

root.wcService.displayToastMessage(qsTr("Successfully signed transaction from %1").arg(root.dappInfo.url), false)
}

function getActiveSessions(dappInfos) {
function getActiveSession(dappInfos) {
let sessionTemplate = (dappUrl, dappName, dappIcon) => {
return {
"peer": {
Expand All @@ -279,7 +281,16 @@ WalletConnectSDKBase {
};
}

return sessionTemplate(dappInfos.url, dappInfos.name, dappInfos.icon)
let sessionString = root.wcService.connectorDAppsProvider.getActiveSession(dappInfos.url)
if (sessionString === null) {
console.error("Connector.lookupSession: error finding session for requestId ", root.requestId)

return
}

let session = JSON.parse(sessionString);

return sessionTemplate(session.url, session.name, session.icon)
}

function authenticate(request) {
Expand Down Expand Up @@ -350,6 +361,11 @@ WalletConnectSDKBase {
connectDappLoader.active = false
rejectSession(root.requestId)
}

onDisconnect: {
connectDappLoader.active = false;
controller.recallDAppPermission(root.dappInfo.url)
}
}
}

Expand Down Expand Up @@ -454,6 +470,22 @@ WalletConnectSDKBase {
id: requests
}

Connections {
target: root.wcService

function onRevokeSession(dAppUrl) {
if (!dAppUrl) {
console.warn(invalidDAppUrlError)
return
}

controller.recallDAppPermission(dAppUrl)
const session = { url: dAppUrl, name: "", icon: "" }
root.wcService.connectorDAppsProvider.revokeSession(JSON.stringify(session))
root.wcService.displayToastMessage(qsTr("Disconnected from %1").arg(dAppUrl), false)
}
}

Connections {
target: controller

Expand Down Expand Up @@ -518,11 +550,40 @@ WalletConnectSDKBase {
connectDappLoader.active = true
root.requestId = requestId
}

onDappGrantDAppPermission: function(dappInfoString) {
let dappItem = JSON.parse(dappInfoString)
const { url, name, icon: iconUrl } = dappItem

if (!url) {
console.warn(invalidDAppUrlError)
return
}
const session = { url, name, iconUrl }
root.wcService.connectorDAppsProvider.addSession(JSON.stringify(session))
}

onDappRevokeDAppPermission: function(dappInfoString) {
let dappItem = JSON.parse(dappInfoString)
let session = {
"url": dappItem.url,
"name": dappItem.name,
"iconUrl": dappItem.icon
}

if (!session.url) {
console.warn(invalidDAppUrlError)
return
}
root.wcService.connectorDAppsProvider.revokeSession(JSON.stringify(session))
root.wcService.displayToastMessage(qsTr("Disconnected from %1").arg(dappItem.url), false)
}
}

approveSession: function(requestId, account, selectedChains) {
controller.approveDappConnectRequest(requestId, account, JSON.stringify(selectedChains))
root.wcService.displayToastMessage(qsTr("Successfully authenticated %1").arg(root.dappInfo.url), false)
const { url, name, icon: iconUrl } = root.dappInfo;
root.wcService.displayToastMessage(qsTr("Successfully authenticated %1").arg(url), false);
}

rejectSession: function(requestId) {
Expand Down
Loading

0 comments on commit b4e07a5

Please sign in to comment.