Skip to content

Commit c3b1b11

Browse files
committed
feat(dapp-browser-backend)_: async calls
feat(dapp-browser-eip1193)_: handle chainId changed signals fixes #19113
1 parent f097977 commit c3b1b11

File tree

9 files changed

+129
-7
lines changed

9 files changed

+129
-7
lines changed

src/app/core/signals/remote_signals/connector.nim

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ type ConnectorSignSignal* = ref object of Signal
3838
address*: string
3939
signMethod*: string
4040

41+
type ConnectorDAppChainIdSwitchedSignal* = ref object of Signal
42+
url*: string
43+
chainId*: string
44+
4145
proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal =
4246
result = ConnectorSendRequestAccountsSignal()
4347
result.signalType = SignalType.ConnectorSendRequestAccounts
@@ -81,4 +85,10 @@ proc fromEvent*(T: type ConnectorSignSignal, event: JsonNode): ConnectorSignSign
8185
result.requestId = event["event"]{"requestId"}.getStr()
8286
result.challenge = event["event"]{"challenge"}.getStr()
8387
result.address = event["event"]{"address"}.getStr()
84-
result.signMethod = event["event"]{"method"}.getStr()
88+
result.signMethod = event["event"]{"method"}.getStr()
89+
90+
proc fromEvent*(T: type ConnectorDAppChainIdSwitchedSignal, event: JsonNode): ConnectorDAppChainIdSwitchedSignal =
91+
result = ConnectorDAppChainIdSwitchedSignal()
92+
result.signalType = SignalType.ConnectorDAppChainIdSwitched
93+
result.url = event["event"]{"url"}.getStr()
94+
result.chainId = event["event"]{"chainId"}.getStr()

src/app/core/signals/remote_signals/signal_type.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type SignalType* {.pure.} = enum
7474
ConnectorGrantDAppPermission = "connector.dAppPermissionGranted"
7575
ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked"
7676
ConnectorSign = "connector.Sign"
77+
ConnectorDAppChainIdSwitched = "connector.dAppChainIdSwitched"
7778
LocalMessageBackupDone = "local.message.backup.done"
7879
Unknown
7980

src/app/core/signals/signals_manager.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ QtObject:
142142
of SignalType.ConnectorGrantDAppPermission: ConnectorGrantDAppPermissionSignal.fromEvent(jsonSignal)
143143
of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal)
144144
of SignalType.ConnectorSign: ConnectorSignSignal.fromEvent(jsonSignal)
145+
of SignalType.ConnectorDAppChainIdSwitched: ConnectorDAppChainIdSwitchedSignal.fromEvent(jsonSignal)
145146
# networks
146147
of SignalType.NetworksBlockchainHealthChanged: NetworksBlockchainHealthChangedSignal.fromEvent(jsonSignal)
147148
else:

src/app/modules/main/wallet_section/module.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ proc newModule*(
179179
result.walletConnectService = wc_service.newService(result.events, result.threadpool, settingsService, transactionService, keycardService)
180180
result.walletConnectController = wc_controller.newController(result.walletConnectService, walletAccountService, result.events)
181181

182-
result.dappsConnectorService = connector_service.newService(result.events)
182+
result.dappsConnectorService = connector_service.newService(result.events, result.threadpool)
183183
result.dappsConnectorController = connector_controller.newController(result.dappsConnectorService, result.events)
184184
result.view = newView(result, result.activityController, result.tmpActivityControllers, result.collectibleDetailsController, result.walletConnectController, result.dappsConnectorController)
185185
result.viewVariant = newQVariant(result.view)

src/app/modules/shared_modules/connector/controller.nim

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransac
1212
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
1313
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
1414
const SIGNAL_CONNECTOR_SIGN* = "ConnectorSign"
15+
const SIGNAL_CONNECTOR_CALL_RPC_RESULT* = "ConnectorCallRPCResult"
16+
const SIGNAL_CONNECTOR_DAPP_CHAIN_ID_SWITCHED* = "ConnectorDAppChainIdSwitched"
1517

1618
logScope:
1719
topics = "connector-controller"
@@ -28,6 +30,8 @@ QtObject:
2830
proc emitDisconnected*(self: Controller, payload: string)
2931
proc emitSendTransaction*(self: Controller, requestId: string, payload: string)
3032
proc emitSign*(self: Controller, requestId: string, payload: string)
33+
proc emitConnectorCallRPCResult*(self: Controller, requestId: int, payload: string)
34+
proc emitChainIdSwitched*(self: Controller, payload: string)
3135

3236
proc newController*(service: connector_service.Service, events: EventEmitter): Controller =
3337
new(result, delete)
@@ -98,6 +102,18 @@ QtObject:
98102

99103
controller.emitSign(params.requestId, dappInfo.toJson())
100104

105+
result.events.on(SIGNAL_CONNECTOR_CALL_RPC_RESULT) do(e: Args):
106+
let params = connector_service.ConnectorCallRPCResultArgs(e)
107+
controller.emitConnectorCallRPCResult(params.requestId, params.payload)
108+
109+
result.events.on(SIGNAL_CONNECTOR_DAPP_CHAIN_ID_SWITCHED) do(e: Args):
110+
let params = ConnectorDAppChainIdSwitchedSignal(e)
111+
let chainInfo = %*{
112+
"url": params.url,
113+
"chainId": params.chainId
114+
}
115+
controller.emitChainIdSwitched(chainInfo.toJson())
116+
101117
result.QObject.setup
102118

103119
proc connectRequested*(self: Controller, requestId: string, payload: string) {.signal.}
@@ -108,6 +124,8 @@ QtObject:
108124
proc sign(self: Controller, requestId: string, payload: string) {.signal.}
109125
proc approveConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}
110126
proc rejectConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}
127+
proc connectorCallRPCResult*(self: Controller, requestId: int, payload: string) {.signal.}
128+
proc chainIdSwitched*(self: Controller, payload: string) {.signal.}
111129

112130
proc approveTransactionResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
113131
proc rejectTransactionResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
@@ -124,6 +142,10 @@ QtObject:
124142
self.sendTransaction(requestId, payload)
125143
proc emitSign*(self: Controller, requestId: string, payload: string) =
126144
self.sign(requestId, payload)
145+
proc emitConnectorCallRPCResult*(self: Controller, requestId: int, payload: string) =
146+
self.connectorCallRPCResult(requestId, payload)
147+
proc emitChainIdSwitched*(self: Controller, payload: string) =
148+
self.chainIdSwitched(payload)
127149

128150
proc parseSingleUInt(chainIDsString: string): uint =
129151
try:
@@ -175,3 +197,5 @@ QtObject:
175197
proc delete*(self: Controller) =
176198
self.QObject.delete
177199

200+
proc connectorCallRPC*(self: Controller, requestId: int, message: string) {.slot.} =
201+
self.service.connectorCallRPC(requestId, message)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import json, json_serialization, chronicles
2+
import backend/connector as status_go
3+
import app/core/tasks/qt
4+
5+
logScope:
6+
topics = "connector-async-tasks"
7+
8+
type
9+
ConnectorCallRPCTaskArg* = ref object of QObjectTaskArg
10+
requestId*: int
11+
message*: string
12+
13+
proc connectorCallRPCTask*(argEncoded: string) {.gcsafe, nimcall.} =
14+
let arg = decode[ConnectorCallRPCTaskArg](argEncoded)
15+
try:
16+
let rpcResponse = status_go.connectorCallRPC(arg.message)
17+
let responseJson = %* {
18+
"requestId": arg.requestId,
19+
"result": $rpcResponse.result,
20+
"error": if rpcResponse.error.isNil: "" else: rpcResponse.error.message
21+
}
22+
23+
arg.finish(responseJson)
24+
except Exception as e:
25+
error "connectorCallRPCTask failed", error=e.msg
26+
arg.finish(%* {
27+
"requestId": arg.requestId,
28+
"error": e.msg
29+
})
30+

src/app_service/service/connector/service.nim

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,31 @@ import app/global/global_singleton
66

77
import app/core/eventemitter
88
import app/core/signals/types
9+
import app/core/tasks/[qt, threadpool]
910

1011
import strutils
1112

1213
logScope:
1314
topics = "connector-service"
1415

16+
include ./async_tasks
17+
1518
const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
1619
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
1720
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
1821
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
1922
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SIGN* = "ConnectorSign"
23+
const SIGNAL_CONNECTOR_CALL_RPC_RESULT* = "ConnectorCallRPCResult"
24+
const SIGNAL_CONNECTOR_DAPP_CHAIN_ID_SWITCHED* = "ConnectorDAppChainIdSwitched"
2025

2126
# Enum with events
2227
type Event* = enum
2328
DappConnect
2429

30+
type ConnectorCallRPCResultArgs* = ref object of Args
31+
requestId*: int
32+
payload*: string
33+
2534
# Event handler function
2635
type EventHandlerFn* = proc(event: Event, payload: string)
2736

@@ -31,15 +40,18 @@ QtObject:
3140
type Service* = ref object of QObject
3241
events: EventEmitter
3342
eventHandler: EventHandlerFn
43+
threadpool: ThreadPool
3444

3545
proc delete*(self: Service)
3646
proc newService*(
37-
events: EventEmitter
47+
events: EventEmitter,
48+
threadpool: ThreadPool
3849
): Service =
3950
new(result, delete)
4051
result.QObject.setup
4152

4253
result.events = events
54+
result.threadpool = threadpool
4355

4456
proc init*(self: Service) =
4557
self.events.on(SignalType.ConnectorSendRequestAccounts.event, proc(e: Args) =
@@ -94,6 +106,13 @@ QtObject:
94106

95107
self.events.emit(SIGNAL_CONNECTOR_EVENT_CONNECTOR_SIGN, data)
96108
)
109+
self.events.on(SignalType.ConnectorDAppChainIdSwitched.event, proc(e: Args) =
110+
if self.eventHandler == nil:
111+
return
112+
113+
var data = ConnectorDAppChainIdSwitchedSignal(e)
114+
self.events.emit(SIGNAL_CONNECTOR_DAPP_CHAIN_ID_SWITCHED, data)
115+
)
97116

98117
proc registerEventsHandler*(self: Service, handler: EventHandlerFn) =
99118
self.eventHandler = handler
@@ -105,7 +124,7 @@ QtObject:
105124
args.requestId = requestId
106125
args.account = account
107126
args.chainId = chainId
108-
127+
109128
return status_go.requestAccountsAcceptedFinishedRpc(args)
110129

111130
except Exception as e:
@@ -178,6 +197,32 @@ QtObject:
178197
proc rejectSigning*(self: Service, requestId: string): bool =
179198
rejectRequest(self, requestId, status_go.sendSignRejectedFinishedRpc, "sendSignRejectedFinishedRpc failed: ")
180199

200+
proc onConnectorCallRPCResolved*(self: Service, response: string) {.slot.} =
201+
try:
202+
let responseObj = response.parseJson
203+
let requestId = responseObj{"requestId"}.getInt(0)
204+
205+
var data = ConnectorCallRPCResultArgs()
206+
data.requestId = requestId
207+
data.payload = response
208+
209+
self.events.emit(SIGNAL_CONNECTOR_CALL_RPC_RESULT, data)
210+
except Exception as e:
211+
error "onConnectorCallRPCResolved failed", error=e.msg
212+
213+
proc connectorCallRPC*(self: Service, requestId: int, message: string) =
214+
try:
215+
let arg = ConnectorCallRPCTaskArg(
216+
tptr: connectorCallRPCTask,
217+
vptr: cast[uint](self.vptr),
218+
slot: "onConnectorCallRPCResolved",
219+
requestId: requestId,
220+
message: message
221+
)
222+
self.threadpool.start(arg)
223+
except:
224+
error "connectorCallRPC: starting async background task failed", requestId=requestId
225+
181226
proc delete*(self: Service) =
182227
self.QObject.delete
183228

src/app_service/service/wallet_connect/async_tasks.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,10 @@ proc asyncEstimateGasTask(argsEncoded: string) {.gcsafe, nimcall.} =
7777
let tx = parseJson(arg.txJson)
7878
let transaction = %*{
7979
"from": tx["from"].getStr,
80-
"to": tx["to"].getStr,
81-
"data": tx["data"].getStr
80+
"to": tx["to"].getStr
8281
}
82+
if tx.hasKey("data"):
83+
transaction["data"] = tx["data"]
8384
if tx.hasKey("value"):
8485
transaction["value"] = tx["value"]
8586

src/backend/connector.nim

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import options
22
import json, json_serialization
33
import core, response_type
4+
import chronicles
45

56
from gen import rpc
67

8+
logScope:
9+
topics = "connector-backend"
10+
711
const
812
EventConnectorSendRequestAccounts* = "connector.sendRequestAccounts"
913
EventConnectorSendTransaction* = "connector.sendTransaction"
@@ -51,6 +55,9 @@ rpc(signAccepted, "connector"):
5155
rpc(signRejected, "connector"):
5256
args: RejectedArgs
5357

58+
rpc(callRPC, "connector"):
59+
inputJSON: string
60+
5461
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
5562
return rpcResponse.error.isNil
5663

@@ -73,4 +80,7 @@ proc sendSignAcceptedFinishedRpc*(args: SignAcceptedArgs): bool =
7380
return isSuccessResponse(signAccepted(args))
7481

7582
proc sendSignRejectedFinishedRpc*(args: RejectedArgs): bool =
76-
return isSuccessResponse(signRejected(args))
83+
return isSuccessResponse(signRejected(args))
84+
85+
proc connectorCallRPC*(inputJSON: string): RpcResponse[JsonNode] {.raises: [Exception].} =
86+
return callRPC(inputJSON)

0 commit comments

Comments
 (0)