Skip to content

Commit

Permalink
feat(BC): Unify dapp sessions between WalletConnect and BrowserConnect
Browse files Browse the repository at this point in the history
New component introduced (DAppsModel) to provide a common model for WC and BC. The WCDappsProvider and BCDappsProvider components are responsible to fill the model from different sources
  • Loading branch information
alexjba committed Nov 20, 2024
1 parent 7e1e827 commit bb483b3
Show file tree
Hide file tree
Showing 14 changed files with 305 additions and 152 deletions.
4 changes: 4 additions & 0 deletions src/app/core/signals/remote_signals/connector.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type ConnectorGrantDAppPermissionSignal* = ref object of Signal
url*: string
name*: string
iconUrl*: string
chains*: string
sharedAccount*: string

type ConnectorRevokeDAppPermissionSignal* = ref object of Signal
url*: string
Expand Down Expand Up @@ -48,6 +50,8 @@ proc fromEvent*(T: type ConnectorGrantDAppPermissionSignal, event: JsonNode): Co
result.url = event["event"]{"url"}.getStr()
result.name = event["event"]{"name"}.getStr()
result.iconUrl = event["event"]{"iconUrl"}.getStr()
result.chains = $(event["event"]{"chains"})
result.sharedAccount = event["event"]{"sharedAccount"}.getStr()

proc fromEvent*(T: type ConnectorRevokeDAppPermissionSignal, event: JsonNode): ConnectorRevokeDAppPermissionSignal =
result = ConnectorRevokeDAppPermissionSignal()
Expand Down
51 changes: 33 additions & 18 deletions src/app/modules/shared_modules/connector/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ QtObject:
proc delete*(self: Controller) =
self.QObject.delete

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 connectRequested*(self: Controller, requestId: string, payload: string) {.signal.}
proc connected*(self: Controller, payload: string) {.signal.}
proc disconnected*(self: Controller, payload: string) {.signal.}

proc signRequested*(self: Controller, requestId: string, payload: string) {.signal.}
proc approveConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}
proc rejectConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}

proc approveTransactionResponse*(self: Controller, requestId: string, error: bool) {.signal.}
proc rejectTransactionResponse*(self: Controller, requestId: string, error: bool) {.signal.}

proc newController*(service: connector_service.Service, events: EventEmitter): Controller =
new(result, delete)
Expand All @@ -51,7 +57,7 @@ QtObject:
"url": params.url,
}

controller.dappRequestsToConnect(params.requestId, dappInfo.toJson())
controller.connectRequested(params.requestId, dappInfo.toJson())

result.events.on(SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION) do(e: Args):
let params = ConnectorSendTransactionSignal(e)
Expand All @@ -63,17 +69,19 @@ QtObject:
"txArgs": params.txArgs,
}

controller.dappValidatesTransaction(params.requestId, dappInfo.toJson())
controller.signRequested(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,
"chains": params.chains,
"sharedAccount": params.sharedAccount,
}

controller.dappGrantDAppPermission(dappInfo.toJson())
controller.connected(dappInfo.toJson())

result.events.on(SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION) do(e: Args):
let params = ConnectorRevokeDAppPermissionSignal(e)
Expand All @@ -83,7 +91,7 @@ QtObject:
"url": params.url,
}

controller.dappRevokeDAppPermission(dappInfo.toJson())
controller.disconnected(dappInfo.toJson())

result.QObject.setup

Expand All @@ -97,20 +105,27 @@ QtObject:
except JsonParsingError:
raise newException(ValueError, "Failed to parse JSON")

proc approveDappConnectRequest*(self: Controller, requestId: string, account: string, chainIDString: string): bool {.slot.} =
proc approveConnection*(self: Controller, requestId: string, account: string, chainIDString: string): bool {.slot.} =
let chainId = parseSingleUInt(chainIDString)
return self.service.approveDappConnect(requestId, account, chainId)
result = self.service.approveDappConnect(requestId, account, chainId)
self.approveConnectResponse(requestId, not result)

proc rejectDappConnectRequest*(self: Controller, requestId: string): bool {.slot.} =
return self.service.rejectDappConnect(requestId)
proc rejectConnection*(self: Controller, requestId: string): bool {.slot.} =
result = self.service.rejectDappConnect(requestId)
self.rejectConnectResponse(requestId, not result)

proc approveTransactionRequest*(self: Controller, requestId: string, signature: string): bool {.slot.} =
proc approveTransaction*(self: Controller, requestId: string, signature: string): bool {.slot.} =
let hash = utils.createHash(signature)

return self.service.approveTransactionRequest(requestId, hash)
result = self.service.approveTransactionRequest(requestId, hash)
self.approveTransactionResponse(requestId, not result)

proc rejectTransaction*(self: Controller, requestId: string): bool {.slot.} =
result = self.service.rejectTransactionSigning(requestId)
self.rejectTransactionResponse(requestId, not result)

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

proc recallDAppPermission*(self: Controller, dAppUrl: string): bool {.slot.} =
return self.service.recallDAppPermission(dAppUrl)
proc getDApps*(self: Controller): string {.slot.} =
return self.service.getDApps()
15 changes: 14 additions & 1 deletion src/app_service/service/connector/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,17 @@ QtObject:

except Exception as e:
error "recallDAppPermissionFinishedRpc failed: ", err=e.msg
return false
return false

proc getDApps*(self: Service): string =
try:
let response = status_go.getPermittedDAppsList()
if not response.error.isNil:
raise newException(Exception, "Error getting connector dapp list: " & response.error.message)

# Expect nil golang array to be valid empty array
let jsonArray = $response.result
return if jsonArray != "null": jsonArray else: "[]"
except Exception as e:
error "getDApps failed: ", err=e.msg
return "[]"
3 changes: 3 additions & 0 deletions src/backend/connector.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ rpc(requestAccountsRejected, "connector"):
rpc(recallDAppPermission, "connector"):
dAppUrl: string

rpc(getPermittedDAppsList, "connector"):
discard

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

Expand Down
72 changes: 72 additions & 0 deletions ui/app/AppLayouts/Wallet/services/dapps/BCDappsProvider.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import QtQuick 2.15

import AppLayouts.Wallet.services.dapps 1.0
import StatusQ.Core.Utils 0.1

import shared.stores 1.0
import utils 1.0

DAppsModel {
id: root

required property BrowserConnectStore store

readonly property int connectorId: Constants.StatusConnect
property bool enabled: true

Connections {
target: root.store
enabled: root.enabled

function onConnected(dappJson) {
const dapp = JSON.parse(dappJson)
const { url, name, icon, sharedAccount } = dapp

if (!url) {
console.warn(invalidDAppUrlError)
return
}
root.append({
name,
url,
iconUrl: icon,
topic: url,
connectorId: root.connectorId,
accountAddresses: [{address: sharedAccount}],
rawSessions: [dapp]
})
}

function onDisconnected(dappJson) {
const dapp = JSON.parse(dappJson)
const { url } = dapp

if (!url) {
console.warn(invalidDAppUrlError)
return
}
root.remove(dapp.url)
}
}

Component.onCompleted: {
if (root.enabled) {
const dappsStr = root.store.getDApps()
if (dappsStr) {
const dapps = JSON.parse(dappsStr)
dapps.forEach(dapp => {
const { url, name, iconUrl, sharedAccount } = dapp
root.append({
name,
url,
iconUrl,
topic: url,
connectorId: root.connectorId,
accountAddresses: [{address: sharedAccount}],
rawSessions: [dapp]
})
})
}
}
}
}
106 changes: 0 additions & 106 deletions ui/app/AppLayouts/Wallet/services/dapps/ConnectorDAppsListProvider.qml

This file was deleted.

Loading

0 comments on commit bb483b3

Please sign in to comment.