From 347e0df8b03ae07710b1bbc0756a492798559896 Mon Sep 17 00:00:00 2001 From: Godfrain Jacques Date: Mon, 22 Jul 2024 11:02:35 -0700 Subject: [PATCH] feat(connector)_: add sign transaction flow (#15662) fixes #15182 - Implement the sign transaction popup for Accept or Rejecting transactions --- .../core/signals/remote_signals/connector.nim | 19 +- .../signals/remote_signals/signal_type.nim | 1 + src/app/core/signals/signals_manager.nim | 1 + .../shared_modules/connector/controller.nim | 26 +- src/app_service/common/utils.nim | 7 +- src/app_service/service/connector/service.nim | 40 +- src/backend/connector.nim | 19 +- .../services/dapps/DappsConnectorSDK.qml | 419 +++++++++++++++++- ui/app/mainui/AppMain.qml | 4 + 9 files changed, 520 insertions(+), 16 deletions(-) diff --git a/src/app/core/signals/remote_signals/connector.nim b/src/app/core/signals/remote_signals/connector.nim index 58c14dde6d..0055f9752d 100644 --- a/src/app/core/signals/remote_signals/connector.nim +++ b/src/app/core/signals/remote_signals/connector.nim @@ -9,9 +9,26 @@ type ConnectorSendRequestAccountsSignal* = ref object of Signal iconUrl*: string requestId*: string +type ConnectorSendTransactionSignal* = ref object of Signal + url*: string + name*: string + iconUrl*: string + requestId*: string + chainId*: int + txArgs*: string + proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal = result = ConnectorSendRequestAccountsSignal() result.url = event["event"]{"url"}.getStr() result.name = event["event"]{"name"}.getStr() result.iconUrl = event["event"]{"iconUrl"}.getStr() - result.requestId = event["event"]{"requestId"}.getStr() \ No newline at end of file + result.requestId = event["event"]{"requestId"}.getStr() + +proc fromEvent*(T: type ConnectorSendTransactionSignal, event: JsonNode): ConnectorSendTransactionSignal = + result = ConnectorSendTransactionSignal() + result.url = event["event"]{"url"}.getStr() + result.name = event["event"]{"name"}.getStr() + result.iconUrl = event["event"]{"iconUrl"}.getStr() + result.requestId = event["event"]{"requestId"}.getStr() + result.chainId = event["event"]{"chainId"}.getInt() + result.txArgs = event["event"]{"txArgs"}.getStr() diff --git a/src/app/core/signals/remote_signals/signal_type.nim b/src/app/core/signals/remote_signals/signal_type.nim index 54efc22c31..94ad9963ae 100644 --- a/src/app/core/signals/remote_signals/signal_type.nim +++ b/src/app/core/signals/remote_signals/signal_type.nim @@ -67,6 +67,7 @@ type SignalType* {.pure.} = enum CommunityTokenTransactionStatusChanged = "communityToken.communityTokenTransactionStatusChanged" CommunityTokenAction = "communityToken.communityTokenAction" ConnectorSendRequestAccounts = "connector.sendRequestAccounts" + ConnectorSendTransaction = "connector.sendTransaction" Unknown proc event*(self:SignalType):string = diff --git a/src/app/core/signals/signals_manager.nim b/src/app/core/signals/signals_manager.nim index 1eb1095571..9f5eff5e7a 100644 --- a/src/app/core/signals/signals_manager.nim +++ b/src/app/core/signals/signals_manager.nim @@ -136,6 +136,7 @@ QtObject: of SignalType.CommunityTokenTransactionStatusChanged: CommunityTokenTransactionStatusChangedSignal.fromEvent(jsonSignal) of SignalType.CommunityTokenAction: CommunityTokenActionSignal.fromEvent(jsonSignal) of SignalType.ConnectorSendRequestAccounts: ConnectorSendRequestAccountsSignal.fromEvent(jsonSignal) + of SignalType.ConnectorSendTransaction: ConnectorSendTransactionSignal.fromEvent(jsonSignal) else: Signal() result.signalType = signalType diff --git a/src/app/modules/shared_modules/connector/controller.nim b/src/app/modules/shared_modules/connector/controller.nim index 2f66b20b9a..7a35db2890 100644 --- a/src/app/modules/shared_modules/connector/controller.nim +++ b/src/app/modules/shared_modules/connector/controller.nim @@ -7,7 +7,10 @@ import app/core/signals/types import app_service/service/connector/service as connector_service +import app_service/common/utils + const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts" +const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction" logScope: topics = "connector-controller" @@ -22,6 +25,7 @@ QtObject: self.QObject.delete proc dappRequestsToConnect*(self: Controller, requestId: string, payload: string) {.signal.} + proc dappValidatesTransaction*(self: Controller, requestId: string, payload: string) {.signal.} proc newController*(service: connector_service.Service, events: EventEmitter): Controller = new(result, delete) @@ -45,6 +49,18 @@ QtObject: controller.dappRequestsToConnect(params.requestId, dappInfo.toJson()) + result.events.on(SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION) do(e: Args): + let params = ConnectorSendTransactionSignal(e) + let dappInfo = %*{ + "icon": params.iconUrl, + "name": params.name, + "url": params.url, + "chainId": params.chainId, + "txArgs": params.txArgs, + } + + controller.dappValidatesTransaction(params.requestId, dappInfo.toJson()) + result.QObject.setup proc parseSingleUInt(chainIDsString: string): uint = @@ -62,4 +78,12 @@ QtObject: return self.service.approveDappConnect(requestId, account, chainId) proc rejectDappConnectRequest*(self: Controller, requestId: string): bool {.slot.} = - return self.service.rejectDappConnect(requestId) \ No newline at end of file + return self.service.rejectDappConnect(requestId) + + proc approveTransactionRequest*(self: Controller, requestId: string, signature: string): bool {.slot.} = + let hash = utils.createHash(signature) + + return self.service.approveTransactionRequest(requestId, hash) + + proc rejectTransactionSigning*(self: Controller, requestId: string): bool {.slot.} = + return self.service.rejectTransactionSigning(requestId) diff --git a/src/app_service/common/utils.nim b/src/app_service/common/utils.nim index aefac4fb81..5d799ef110 100644 --- a/src/app_service/common/utils.nim +++ b/src/app_service/common/utils.nim @@ -90,4 +90,9 @@ proc stringToUint256*(value: string): Uint256 = parsedValue = value.parse(Uint256) except Exception as e: discard - return parsedValue \ No newline at end of file + return parsedValue + +proc createHash*(signature: string): string = + let signatureHex = if signature.startsWith("0x"): signature[2..^1] else: signature + + return hashPassword(signatureHex, true) \ No newline at end of file diff --git a/src/app_service/service/connector/service.nim b/src/app_service/service/connector/service.nim index 882ba03db3..adb387bbd5 100644 --- a/src/app_service/service/connector/service.nim +++ b/src/app_service/service/connector/service.nim @@ -13,6 +13,7 @@ logScope: topics = "connector-service" const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts" +const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction" # Enum with events type Event* = enum @@ -52,6 +53,18 @@ QtObject: self.events.emit(SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS, data) ) + self.events.on(SignalType.ConnectorSendTransaction.event, proc(e: Args) = + if self.eventHandler == nil: + return + + var data = ConnectorSendTransactionSignal(e) + + if not data.requestId.len() == 0: + error "ConnectorSendTransactionSignal failed, requestId is empty" + return + + self.events.emit(SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION, data) + ) proc registerEventsHandler*(self: Service, handler: EventHandlerFn) = self.eventHandler = handler @@ -69,14 +82,33 @@ QtObject: except Exception as e: error "requestAccountsAcceptedFinishedRpc failed: ", err=e.msg return false + + proc approveTransactionRequest*(self: Service, requestId: string, hash: string): bool = + try: + var args = SendTransactionAcceptedArgs() - proc rejectDappConnect*(self: Service, requestId: string): bool = + args.requestId = requestId + args.hash = hash + + return status_go.sendTransactionAcceptedFinishedRpc(args) + + except Exception as e: + error "sendTransactionAcceptedFinishedRpc failed: ", err=e.msg + return false + + proc rejectRequest*(self: Service, requestId: string, rpcCall: proc(args: RejectedArgs): bool, message: static[string]): bool = try: var args = RejectedArgs() args.requestId = requestId - return status_go.requestAccountsRejectedFinishedRpc(args) + return rpcCall(args) except Exception as e: - error "requestAccountsRejectedFinishedRpc failed: ", err=e.msg - return false \ No newline at end of file + error message, err=e.msg + return false + + proc rejectTransactionSigning*(self: Service, requestId: string): bool = + rejectRequest(self, requestId, status_go.sendTransactionRejectedFinishedRpc, "sendTransactionRejectedFinishedRpc failed: ") + + proc rejectDappConnect*(self: Service, requestId: string): bool = + rejectRequest(self, requestId, status_go.requestAccountsRejectedFinishedRpc, "requestAccountsRejectedFinishedRpc failed: ") diff --git a/src/backend/connector.nim b/src/backend/connector.nim index 374ec58f6b..6779533205 100644 --- a/src/backend/connector.nim +++ b/src/backend/connector.nim @@ -6,18 +6,29 @@ from gen import rpc const EventConnectorSendRequestAccounts* = "connector.sendRequestAccounts" + EventConnectorSendTransaction* = "connector.sendTransaction" type RequestAccountsAcceptedArgs* = ref object of RootObj requestId* {.serializedFieldName("requestId").}: string account* {.serializedFieldName("account").}: string chainId* {.serializedFieldName("chainId").}: uint +type SendTransactionAcceptedArgs* = ref object of RootObj + requestId* {.serializedFieldName("requestId").}: string + hash* {.serializedFieldName("hash").}: string + type RejectedArgs* = ref object of RootObj requestId* {.serializedFieldName("requestId").}: string rpc(requestAccountsAccepted, "connector"): args: RequestAccountsAcceptedArgs +rpc(sendTransactionAccepted, "connector"): + args: SendTransactionAcceptedArgs + +rpc(sendTransactionRejected, "connector"): + aargs: RejectedArgs + rpc(requestAccountsRejected, "connector"): args: RejectedArgs @@ -28,4 +39,10 @@ proc requestAccountsAcceptedFinishedRpc*(args: RequestAccountsAcceptedArgs): boo return isSuccessResponse(requestAccountsAccepted(args)) proc requestAccountsRejectedFinishedRpc*(args: RejectedArgs): bool = - return isSuccessResponse(requestAccountsRejected(args)) \ No newline at end of file + return isSuccessResponse(requestAccountsRejected(args)) + +proc sendTransactionAcceptedFinishedRpc*(args: SendTransactionAcceptedArgs): bool = + return isSuccessResponse(sendTransactionAccepted(args)) + +proc sendTransactionRejectedFinishedRpc*(args: RejectedArgs): bool = + return isSuccessResponse(sendTransactionRejected(args)) \ No newline at end of file diff --git a/ui/app/AppLayouts/Wallet/services/dapps/DappsConnectorSDK.qml b/ui/app/AppLayouts/Wallet/services/dapps/DappsConnectorSDK.qml index 951dae02ee..b2d8463ec2 100644 --- a/ui/app/AppLayouts/Wallet/services/dapps/DappsConnectorSDK.qml +++ b/ui/app/AppLayouts/Wallet/services/dapps/DappsConnectorSDK.qml @@ -26,19 +26,292 @@ import "types" WalletConnectSDKBase { id: root - // Nim connector.controller instance - property var controller - property bool sdkReady: true - property bool active: true required property WalletConnectService wcService required property var walletStore + required property DAppsStore store + required property int loginType + + property var controller + property var dappInfo: null + property var txArgs: null + property bool sdkReady: true + property bool active: true property string requestId: "" + property alias requestsModel: requests projectId: "" implicitWidth: 1 implicitHeight: 1 + // TODO Refactor this code to avoid code duplication from Wallet Connect DAppsRequestHandler + // https://github.com/status-im/status-desktop/issues/15711 + QtObject { + id: d + + function sessionRequestEvent(event) { + let obj = d.resolveAsync(event) + if (obj === null) { + let error = true + controller.rejectTransactionSigning(root.requestId) + return + } + sessionRequestLoader.request = obj + requests.enqueue(obj) + } + + function resolveAsync(event) { + let method = event.params.request.method + let account = lookupAccountFromEvent(event, method) + if(!account) { + console.error("Error finding account for event", JSON.stringify(event)) + return null + } + let network = lookupNetworkFromEvent(event, method) + if(!network) { + console.error("Error finding network for event", JSON.stringify(event)) + return null + } + let data = extractMethodData(event, method) + if(!data) { + console.error("Error in event data lookup", JSON.stringify(event)) + return null + } + let enoughFunds = !isTransactionMethod(method) + let obj = sessionRequestComponent.createObject(null, { + event, + topic: event.topic, + id: event.id, + method, + account, + network, + data, + maxFeesText: "?", + maxFeesEthText: "?", + enoughFunds: enoughFunds, + estimatedTimeText: "?" + }) + if (obj === null) { + console.error("Error creating SessionRequestResolved for event") + return null + } + + // Check later to have a valid request object + if (!SessionRequest.getSupportedMethods().includes(method)) { + console.error("Unsupported method", method) + return null + } + + let session = getActiveSessions(root.dappInfo) + + if (session === null) { + console.error("DAppsRequestHandler.lookupSession: error finding session for topic", obj.topic) + return + } + obj.resolveDappInfoFromSession(session) + + return obj + } + + function isTransactionMethod(method) { + return method === SessionRequest.methods.signTransaction.name + || method === SessionRequest.methods.sendTransaction.name + } + + /// Returns null if the account is not found + function lookupAccountFromEvent(event, method) { + var address = "" + if (method === SessionRequest.methods.personalSign.name) { + if (event.params.request.params.length < 2) { + return null + } + address = event.params.request.params[0] + } else if (method === SessionRequest.methods.sign.name) { + if (event.params.request.params.length === 1) { + return null + } + address = event.params.request.params[0] + } else if(method === SessionRequest.methods.signTypedData_v4.name || + method === SessionRequest.methods.signTypedData.name) + { + if (event.params.request.params.length < 2) { + return null + } + address = event.params.request.params[0] + } else if (method === SessionRequest.methods.signTransaction.name + || method === SessionRequest.methods.sendTransaction.name) { + if (event.params.request.params.length == 0) { + return null + } + address = event.params.request.params[0] + } + return SQUtils.ModelUtils.getFirstModelEntryIf(root.wcService.validAccounts, (account) => { + return account.address.toLowerCase() === address.toLowerCase(); + }) + } + + /// Returns null if the network is not found + function lookupNetworkFromEvent(event, method) { + if (SessionRequest.getSupportedMethods().includes(method) === false) { + return null + } + let chainId = Helpers.chainIdFromEip155(event.params.chainId) + return SQUtils.ModelUtils.getByKey(networksModule.flatNetworks, "chainId", chainId) + } + + function extractMethodData(event, method) { + if (method === SessionRequest.methods.personalSign.name || + method === SessionRequest.methods.sign.name) + { + if (event.params.request.params.length < 1) { + return null + } + var message = "" + let messageIndex = (method === SessionRequest.methods.personalSign.name ? 0 : 1) + let messageParam = event.params.request.tx.data + + // There is no standard on how data is encoded. Therefore we support hex or utf8 + if (Helpers.isHex(messageParam)) { + message = Helpers.hexToString(messageParam) + } else { + message = messageParam + } + return SessionRequest.methods.personalSign.buildDataObject(message) + } else if (method === SessionRequest.methods.signTypedData_v4.name || + method === SessionRequest.methods.signTypedData.name) + { + if (event.params.request.params.length < 2) { + return null + } + let jsonMessage = event.params.request.params[1] + let methodObj = method === SessionRequest.methods.signTypedData_v4.name + ? SessionRequest.methods.signTypedData_v4 + : SessionRequest.methods.signTypedData + return methodObj.buildDataObject(jsonMessage) + } else if (method === SessionRequest.methods.signTransaction.name) { + if (event.params.request.params.length == 0) { + return null + } + let tx = event.params.request.params[0] + return SessionRequest.methods.signTransaction.buildDataObject(tx) + } else if (method === SessionRequest.methods.sendTransaction.name) { + if (event.params.request.params.length == 0) { + return null + } + let tx = event.params.request.params[0] + return SessionRequest.methods.sendTransaction.buildDataObject(tx) + } else { + return null + } + } + + function executeSessionRequest(request, password, pin) { + if (!SessionRequest.getSupportedMethods().includes(request.method)) { + console.error("Unsupported method to execute: ", request.method) + return + } + + if (password !== "") { + var actionResult = "" + if (request.method === SessionRequest.methods.sign.name) { + actionResult = store.signMessageUnsafe(request.topic, request.id, + request.account.address, password, + SessionRequest.methods.personalSign.getMessageFromData(request.data)) + } else if (request.method === SessionRequest.methods.personalSign.name) { + actionResult = store.signMessage(request.topic, request.id, + request.account.address, password, + SessionRequest.methods.personalSign.getMessageFromData(request.data)) + } else if (request.method === SessionRequest.methods.signTypedData_v4.name || + request.method === SessionRequest.methods.signTypedData.name) + { + let legacy = request.method === SessionRequest.methods.signTypedData.name + actionResult = store.safeSignTypedData(request.topic, request.id, + request.account.address, password, + SessionRequest.methods.signTypedData.getMessageFromData(request.data), + request.network.chainId, legacy) + } else if (request.method === SessionRequest.methods.signTransaction.name) { + let txObj = SessionRequest.methods.signTransaction.getTxObjFromData(request.data) + actionResult = store.signTransaction(request.topic, request.id, + request.account.address, request.network.chainId, password, txObj) + } else if (request.method === SessionRequest.methods.sendTransaction.name) { + let txObj = SessionRequest.methods.sendTransaction.getTxObjFromData(request.data) + actionResult = store.sendTransaction(request.topic, request.id, + request.account.address, request.network.chainId, password, txObj) + } + let isSuccessful = (actionResult != "") + if (isSuccessful) { + // acceptSessionRequest will trigger an sdk.sessionRequestUserAnswerResult signal + acceptSessionRequest(request.topic, request.method, request.id, actionResult) + } else { + root.sessionRequestResult(request, isSuccessful) + } + } else if (pin !== "") { + console.debug("TODO #15097 sign message using keycard: ", request.data) + } else { + console.error("No password or pin provided to sign message") + } + } + + function acceptSessionRequest(topic, method, id, signature) { + console.debug(`WC DappsConnectorSDK.acceptSessionRequest; topic: "${topic}", id: ${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) { + let sessionTemplate = (dappUrl, dappName, dappIcon) => { + return { + "peer": { + "metadata": { + "description": "-", + "icons": [ + dappIcon + ], + "name": dappName, + "url": dappUrl + } + }, + "topic": dappUrl + }; + } + + return sessionTemplate(dappInfos.url, dappInfos.name, dappInfos.icon) + } + + function authenticate(request) { + return store.authenticateUser(request.topic, request.id, request.account.address) + } + } + + Connections { + target: root.store + + function onUserAuthenticated(topic, id, password, pin) { + var request = requests.findRequest(topic, id) + if (request === null) { + console.error(">Error finding event for topic", topic, "id", id) + return + } + d.executeSessionRequest(request, password, pin) + } + + function onUserAuthenticationFailed(topic, id) { + var request = requests.findRequest(topic, id) + let methodStr = SessionRequest.methodToUserString(request.method) + if (request === null || !methodStr) { + return + } + d.lookupSession(topic, function(session) { + if (session === null) + return + root.displayToastMessage(qsTr("Failed to authenticate %1").arg(session.peer.metadata.url), true) + }) + } + } + Loader { id: connectDappLoader @@ -59,9 +332,8 @@ WalletConnectSDKBase { rejectSession(root.requestId) connectDappLoader.active = false } - accounts: root.wcService.validAccounts flatNetworks: root.walletStore.filteredFlatModel - selectedAccountAddress: root.wcService.selectedAccountAddress + accounts: root.wcService.validAccounts dAppUrl: proposalMedatada.url dAppName: proposalMedatada.name @@ -80,12 +352,141 @@ WalletConnectSDKBase { } } + Loader { + id: sessionRequestLoader + + active: false + + onLoaded: item.open() + + property SessionRequestResolved request: null + + property var dappInfo: null + + sourceComponent: DAppSignRequestModal { + id: dappRequestModal + objectName: "connectorDappsRequestModal" + loginType: request.account.migragedToKeycard ? Constants.LoginType.Keycard : root.loginType + visible: true + + dappName: request.dappName + dappUrl: request.dappUrl + dappIcon: request.dappIcon + + accountColor: request.account.color + accountName: request.account.name + accountAddress: request.account.address + accountEmoji: request.account.emoji + + networkName: request.network.chainName + networkIconPath: Style.svg(request.network.iconUrl) + + currentCurrency: "" + fiatFees: request.maxFeesText + cryptoFees: request.maxFeesEthText + estimatedTime: "" + feesLoading: !request.maxFeesText || !request.maxFeesEthText + hasFees: signingTransaction + enoughFundsForTransaction: request.enoughFunds + enoughFundsForFees: request.enoughFunds + + signingTransaction: request.method === SessionRequest.methods.signTransaction.name || request.method === SessionRequest.methods.sendTransaction.name + + requestPayload: { + switch(request.method) { + case SessionRequest.methods.personalSign.name: + return SessionRequest.methods.personalSign.getMessageFromData(request.data) + case SessionRequest.methods.sign.name: { + return SessionRequest.methods.sign.getMessageFromData(request.data) + } + case SessionRequest.methods.signTypedData_v4.name: { + const stringPayload = SessionRequest.methods.signTypedData_v4.getMessageFromData(request.data) + return JSON.stringify(JSON.parse(stringPayload), null, 2) + } + case SessionRequest.methods.signTypedData.name: { + const stringPayload = SessionRequest.methods.signTypedData.getMessageFromData(root.payloadData) + return JSON.stringify(JSON.parse(stringPayload), null, 2) + } + case SessionRequest.methods.signTransaction.name: { + const jsonPayload = SessionRequest.methods.signTransaction.getTxObjFromData(request.data) + return JSON.stringify(jsonPayload, null, 2) + } + case SessionRequest.methods.sendTransaction.name: { + const jsonPayload = SessionRequest.methods.sendTransaction.getTxObjFromData(request.data) + return JSON.stringify(jsonPayload, null, 2) + } + } + } + + onClosed: { + Qt.callLater( () => { + sessionRequestLoader.active = false + }) + } + + onAccepted: { + if (!request) { + console.error("Error signing: request is null") + return + } + + d.authenticate(request) + } + + onRejected: { + sessionRequestLoader.active = false + controller.rejectTransactionSigning(root.requestId) + root.wcService.displayToastMessage(qsTr("Failed to sign transaction from %1").arg(request.dappUrl), true) + } + } + } + + Component { + id: sessionRequestComponent + + SessionRequestResolved { + } + } + + SessionRequestsModel { + id: requests + } + Connections { target: controller + onDappValidatesTransaction: function(requestId, dappInfoString) { + var dappInfo = JSON.parse(dappInfoString) + root.dappInfo = dappInfo + var txArgsParams = JSON.parse(dappInfo.txArgs) + root.txArgs = txArgsParams + let event = { + "id": root.requestId, + "topic": dappInfo.url, + "params": { + "chainId": `eip155:${dappInfo.chainId}`, + "request": { + "method": SessionRequest.methods.personalSign.name, + "tx": { + "data": txArgsParams.data, + }, + "params": [ + txArgsParams.from, + txArgsParams.to, + ], + } + } + } + + d.sessionRequestEvent(event) + + sessionRequestLoader.active = true + root.requestId = requestId + } + onDappRequestsToConnect: function(requestId, dappInfoString) { var dappInfo = JSON.parse(dappInfoString) - + root.dappInfo = dappInfo let sessionProposal = { "params": { "optionalNamespaces": {}, @@ -105,7 +506,7 @@ WalletConnectSDKBase { `eip155:${dappInfo.chainId}` ], "events": [], - "methods": ["eth_sendTransaction"] + "methods": [SessionRequest.methods.personalSign.name] } } } @@ -119,10 +520,12 @@ WalletConnectSDKBase { approveSession: function(requestId, account, selectedChains) { controller.approveDappConnectRequest(requestId, account, JSON.stringify(selectedChains)) + root.wcService.displayToastMessage(qsTr("Successfully authenticated %1").arg(root.dappInfo.url), false) } rejectSession: function(requestId) { controller.rejectDappConnectRequest(requestId) + root.wcService.displayToastMessage(qsTr("Failed to authenticate %1").arg(root.dappInfo.url), true) } // We don't expect requests for these. They are here only to spot errors diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index 7533b278a5..b7dc8e689a 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -2054,6 +2054,10 @@ Item { controller: WalletStore.RootStore.dappsConnectorController wcService: Global.walletConnectService walletStore: WalletStore.RootStore + store: DAppsStore { + controller: WalletStore.RootStore.walletConnectController + } + loginType: appMain.rootStore.loginType } }