feat(dapps) implement signing of messages
Implement infrastructure and integration with status-go to support general session requests Supported methods: - personal_sign - eth_signTypedData_v4 depends on status-go change that exposes the signing methods Also - support hex or utf8 encoding for personal_sign - format the typed data for display in the modal Tests are disabled for now, as they are crashing on CI Close: #14927
This commit is contained in:
parent
28a7b691cd
commit
758dbc55e5
|
@ -38,7 +38,7 @@ QtObject:
|
|||
self.dappsListReceived(res)
|
||||
return true
|
||||
|
||||
proc userAuthenticationResult*(self: Controller, topic: string, id: string, error: bool) {.signal.}
|
||||
proc userAuthenticationResult*(self: Controller, topic: string, id: string, error: bool, password: string, pin: string) {.signal.}
|
||||
|
||||
# Beware, it will fail if an authentication is already in progress
|
||||
proc authenticateUser*(self: Controller, topic: string, id: string, address: string): bool {.slot.} =
|
||||
|
@ -46,6 +46,12 @@ QtObject:
|
|||
if acc.keyUid == "":
|
||||
return false
|
||||
|
||||
return self.service.authenticateUser(acc.keyUid, proc(success: bool) =
|
||||
self.userAuthenticationResult(topic, id, success)
|
||||
)
|
||||
return self.service.authenticateUser(acc.keyUid, proc(password: string, pin: string, success: bool) =
|
||||
self.userAuthenticationResult(topic, id, success, password, pin)
|
||||
)
|
||||
|
||||
proc signMessage*(self: Controller, address: string, password: string, message: string): string {.slot.} =
|
||||
return self.service.signMessage(address, password, message)
|
||||
|
||||
proc signTypedDataV4*(self: Controller, address: string, password: string, typedDataJson: string): string {.slot.} =
|
||||
return self.service.signTypedDataV4(address, password, typedDataJson)
|
||||
|
|
|
@ -20,7 +20,7 @@ logScope:
|
|||
const UNIQUE_WALLET_CONNECT_MODULE_IDENTIFIER* = "WalletSection-WCModule"
|
||||
|
||||
type
|
||||
AuthenticationResponseFn* = proc(success: bool)
|
||||
AuthenticationResponseFn* = proc(password: string, pin: string, success: bool)
|
||||
|
||||
QtObject:
|
||||
type Service* = ref object of QObject
|
||||
|
@ -59,10 +59,10 @@ QtObject:
|
|||
|
||||
if args.password == "" and args.pin == "":
|
||||
info "fail to authenticate user"
|
||||
self.authenticationCallback(false)
|
||||
self.authenticationCallback("", "", false)
|
||||
return
|
||||
|
||||
self.authenticationCallback(true)
|
||||
self.authenticationCallback(args.password, args.pin, true)
|
||||
|
||||
proc addSession*(self: Service, session_json: string): bool =
|
||||
# TODO #14588: call it async
|
||||
|
@ -85,4 +85,10 @@ QtObject:
|
|||
keyUid: keyUid)
|
||||
|
||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
||||
return true
|
||||
return true
|
||||
|
||||
proc signMessage*(self: Service, address: string, password: string, message: string): string =
|
||||
return status_go.signMessage(address, password, message)
|
||||
|
||||
proc signTypedDataV4*(self: Service, address: string, password: string, typedDataJson: string): string =
|
||||
return status_go.signTypedData(address, password, typedDataJson)
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
import options, logging
|
||||
import json, json_serialization
|
||||
import core, response_type
|
||||
import strutils
|
||||
|
||||
from gen import rpc
|
||||
import backend
|
||||
|
||||
import status_go
|
||||
|
||||
import app_service/service/community/dto/sign_params
|
||||
|
||||
import app_service/common/utils
|
||||
|
||||
rpc(addWalletConnectSession, "wallet"):
|
||||
sessionJson: string
|
||||
|
||||
proc isErrorResponse(rpcResponse: RpcResponse[JsonNode]): bool =
|
||||
return not rpcResponse.error.isNil
|
||||
rpc(signTypedDataV4, "wallet"):
|
||||
typedJson: string
|
||||
address: string
|
||||
password: string
|
||||
|
||||
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
|
||||
return rpcResponse.error.isNil
|
||||
|
||||
proc addSession*(sessionJson: string): bool =
|
||||
try:
|
||||
let rpcRes = addWalletConnectSession(sessionJson)
|
||||
return isErrorResponse(rpcRes):
|
||||
return isSuccessResponse(rpcRes):
|
||||
except Exception as e:
|
||||
warn "AddWalletConnectSession failed: ", "msg", e.msg
|
||||
return false
|
||||
|
@ -33,3 +45,29 @@ proc getDapps*(validAtEpoch: int64, testChains: bool): string =
|
|||
except Exception as e:
|
||||
warn "GetWalletConnectDapps failed: ", "msg", e.msg
|
||||
return ""
|
||||
|
||||
proc signMessage*(address: string, password: string, message: string): string =
|
||||
try:
|
||||
let signParams = SignParamsDto(address: address, password: hashPassword(password), data: "0x" & toHex(message))
|
||||
let paramsStr = $toJson(signParams)
|
||||
let rpcResRaw = status_go.signMessage(paramsStr)
|
||||
|
||||
let rpcRes = Json.decode(rpcResRaw, RpcResponse[JsonNode])
|
||||
if(not rpcRes.error.isNil):
|
||||
return ""
|
||||
return rpcRes.result.getStr()
|
||||
except Exception as e:
|
||||
warn "status_go.signMessage failed: ", "msg", e.msg
|
||||
return ""
|
||||
|
||||
proc signTypedData*(address: string, password: string, typedDataJson: string): string =
|
||||
try:
|
||||
let rpcRes = signTypedDataV4(typedDataJson, address, hashPassword(password))
|
||||
|
||||
if not isSuccessResponse(rpcRes):
|
||||
return ""
|
||||
|
||||
return rpcRes.result.getStr()
|
||||
except Exception as e:
|
||||
warn "wallet_signTypedDataV4 failed: ", "msg", e.msg
|
||||
return ""
|
||||
|
|
|
@ -50,7 +50,8 @@ Item {
|
|||
dappName: settings.dappName
|
||||
dappUrl: settings.dappUrl
|
||||
dappIcon: settings.dappIcon
|
||||
signContent: JSON.stringify(d.signTestContent, null, 2)
|
||||
signContent: d.signTestContent
|
||||
method: "eth_signTypedData_v4"
|
||||
maxFeesText: "1.82 EUR"
|
||||
estimatedTimeText: "3-5 mins"
|
||||
|
||||
|
@ -128,36 +129,7 @@ Item {
|
|||
|
||||
readonly property var selectedNetwork: NetworksModel.flatNetworks.get(0)
|
||||
|
||||
readonly property var signTestContent: {
|
||||
"id": 1714038548266495,
|
||||
"params": {
|
||||
"chainld": "eip155:11155111",
|
||||
"request": {
|
||||
"expiryTimestamp": 1714038848,
|
||||
"method": "eth_signTransaction",
|
||||
"params": [
|
||||
{
|
||||
"data": "0x",
|
||||
"from": "0xE2d622C817878dA5143bBE06866ca8E35273Ba8",
|
||||
"gasLimit": "0x5208",
|
||||
"gasPrice": "0xa677ef31",
|
||||
"nonce": "0x27",
|
||||
"to": "0xE2d622C817878dA5143bBE06866ca8E35273Ba8a",
|
||||
"value": "0x00"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"topic": "a0f85b23a1f3a540d85760a523963165fb92169d57320c",
|
||||
"verifyContext": {
|
||||
"verified": {
|
||||
"isScam": false,
|
||||
"origin": "https://react-app.walletconnect.com/",
|
||||
"validation": "VALID",
|
||||
"verifyUrl": "https://verify.walletconnect.com/"
|
||||
}
|
||||
}
|
||||
}
|
||||
readonly property var signTestContent: "{\"types\":{\"EIP712Domain\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"chainId\",\"type\":\"uint256\"},{\"name\":\"verifyingContract\",\"type\":\"address\"}],\"Person\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"wallet\",\"type\":\"address\"}],\"Mail\":[{\"name\":\"from\",\"type\":\"Person\"},{\"name\":\"to\",\"type\":\"Person\"},{\"name\":\"contents\",\"type\":\"string\"}]},\"primaryType\":\"Mail\",\"domain\":{\"name\":\"Ether Mail\",\"version\":\"1\",\"chainId\":1,\"verifyingContract\":\"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC\"},\"message\":{\"from\":{\"name\":\"Cow\",\"wallet\":\"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826\"},\"to\":{\"name\":\"Bob\",\"wallet\":\"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB\"},\"contents\":\"Hello, Bob!\"}}"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ Item {
|
|||
StatusButton {
|
||||
text: qsTr("Authenticate")
|
||||
onClicked: {
|
||||
walletConnectService.store.userAuthenticated(authMockDialog.topic, authMockDialog.id)
|
||||
walletConnectService.store.userAuthenticated(authMockDialog.topic, authMockDialog.id, "0x1234567890", "123")
|
||||
authMockDialog.close()
|
||||
}
|
||||
}
|
||||
|
@ -260,9 +260,8 @@ Item {
|
|||
|
||||
store: DAppsStore {
|
||||
signal dappsListReceived(string dappsJson)
|
||||
signal userAuthenticated(string topic, string id)
|
||||
signal userAuthenticated(string topic, string id, string password, string pin)
|
||||
signal userAuthenticationFailed(string topic, string id)
|
||||
signal sessionRequestExecuted(var payload, bool success)
|
||||
|
||||
function addWalletConnectSession(sessionJson) {
|
||||
console.info("Persist Session", sessionJson)
|
||||
|
@ -276,6 +275,7 @@ Item {
|
|||
"iconUrl": firstIconUrl
|
||||
}
|
||||
d.persistedDapps.push(persistedDapp)
|
||||
return true
|
||||
}
|
||||
|
||||
function getDapps() {
|
||||
|
@ -289,6 +289,16 @@ Item {
|
|||
authMockDialog.open()
|
||||
return true
|
||||
}
|
||||
|
||||
// hardcoded for https://react-app.walletconnect.com/
|
||||
function signMessage(topic, id, address, password, message) {
|
||||
return "0x0b083acc1b3b612dd38e8e725b28ce9b2dd4936b4cf7922da4e4a3c6f44f7f4f6d3050ccb41455a2b85093f1bfadb10fc6a75d83bb590b2eb70e3447653459701c"
|
||||
}
|
||||
|
||||
// hardcoded for https://react-app.walletconnect.com/
|
||||
function signTypedDataV4(topic, id, address, password, typedDataJson) {
|
||||
return "0xf8ceb3468319cc215523b67c24c4504b3addd9bf8de31c278038d7478c9b6de554f7d8a516cd5d6a066b7d48b81f03d9d6bb7d5d754513c08325674ebcc7efbc1b"
|
||||
}
|
||||
}
|
||||
|
||||
walletStore: WalletStore {
|
||||
|
|
|
@ -25,6 +25,7 @@ Item {
|
|||
width: 600
|
||||
height: 400
|
||||
|
||||
// TODO #15151 fix CI crash and re-enable tests
|
||||
// Component {
|
||||
// id: sdkComponent
|
||||
|
||||
|
@ -79,9 +80,8 @@ Item {
|
|||
|
||||
// DAppsStore {
|
||||
// signal dappsListReceived(string dappsJson)
|
||||
// signal userAuthenticated(string topic, string id)
|
||||
// signal userAuthenticated(string topic, string id, string password, string pin)
|
||||
// signal userAuthenticationFailed(string topic, string id)
|
||||
// signal sessionRequestExecuted(var payload, bool success)
|
||||
|
||||
// // By default, return no dapps in store
|
||||
// function getDapps() {
|
||||
|
@ -100,8 +100,12 @@ Item {
|
|||
// }
|
||||
|
||||
// property var signMessageCalls: []
|
||||
// function signMessage(message) {
|
||||
// signMessageCalls.push({message})
|
||||
// function signMessage(topic, id, address, password, message) {
|
||||
// signMessageCalls.push({topic, id, address, password, message})
|
||||
// }
|
||||
// property var signTypedDataV4Calls: []
|
||||
// function signTypedDataV4(topic, id, address, password, message) {
|
||||
// signTypedDataV4Calls.push({topic, id, address, password, message})
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -173,7 +177,7 @@ Item {
|
|||
// compare(handler.store.authenticateUserCalls.length, 1, "expected a call to store.authenticateUser")
|
||||
|
||||
// let store = handler.store
|
||||
// store.userAuthenticated(td.topic, td.request.id)
|
||||
// store.userAuthenticated(td.topic, td.request.id, "password", "")
|
||||
// compare(store.signMessageCalls.length, 1, "expected a call to store.signMessage")
|
||||
// compare(store.signMessageCalls[0].message, td.request.data)
|
||||
// }
|
||||
|
@ -414,7 +418,7 @@ Item {
|
|||
// }
|
||||
// }
|
||||
|
||||
// // Beware this TestCase should be last; I had it before ServiceHelpers and it was not run with `when: windowShown`
|
||||
// TODO #15151: this TestCase if placed before ServiceHelpers was not run with `when: windowShown`. Check if related to the CI crash
|
||||
// TestCase {
|
||||
// id: dappsWorkflowTest
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ ConnectedDappsButton {
|
|||
dappIcon: request.dappIcon
|
||||
|
||||
signContent: request.data.message
|
||||
method: request.method
|
||||
maxFeesText: request.maxFeesText
|
||||
estimatedTimeText: request.estimatedTimeText
|
||||
|
||||
|
@ -155,9 +156,12 @@ ConnectedDappsButton {
|
|||
Connections {
|
||||
target: root.wcService ? root.wcService.requestHandler : null
|
||||
|
||||
function onSessionRequestResult(payload, isSuccess) {
|
||||
// TODO #14927 handle this properly
|
||||
sessionRequestLoader.active = false
|
||||
function onSessionRequestResult(request, payload, isSuccess) {
|
||||
if (isSuccess) {
|
||||
sessionRequestLoader.active = false
|
||||
} else {
|
||||
// TODO #14762 handle the error case
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ QObject {
|
|||
|
||||
signal sessionRequest(SessionRequestResolved request)
|
||||
signal displayToastMessage(string message, bool error)
|
||||
signal sessionRequestResult(var payload, bool isSuccess)
|
||||
signal sessionRequestResult(/*model entry of SessionRequestResolved*/ var request, var payload, bool isSuccess)
|
||||
|
||||
/// Supported methods
|
||||
property QtObject methods: QtObject {
|
||||
|
@ -38,11 +38,16 @@ QObject {
|
|||
readonly property string name: Constants.personal_sign
|
||||
readonly property string userString: qsTr("sign")
|
||||
}
|
||||
readonly property QtObject signTypedData_v4: QtObject {
|
||||
readonly property string name: "eth_signTypedData_v4"
|
||||
readonly property string userString: qsTr("sign typed data")
|
||||
}
|
||||
|
||||
readonly property QtObject sendTransaction: QtObject {
|
||||
readonly property string name: "eth_sendTransaction"
|
||||
readonly property string userString: qsTr("send transaction")
|
||||
}
|
||||
readonly property var all: [personalSign, sendTransaction]
|
||||
readonly property var all: [personalSign, signTypedData_v4, sendTransaction]
|
||||
}
|
||||
|
||||
function getSupportedMethods() {
|
||||
|
@ -81,14 +86,17 @@ QObject {
|
|||
return
|
||||
if (error) {
|
||||
root.displayToastMessage(qsTr("Fail to %1 from %2").arg(methodStr).arg(session.peer.metadata.url), true)
|
||||
// TODO #14757 handle SDK error on user accept/reject
|
||||
|
||||
root.sessionRequestResult(request, "", false /*isSuccessful*/)
|
||||
|
||||
console.error(`Error accepting session request for topic: ${topic}, id: ${id}, accept: ${accept}, error: ${error}`)
|
||||
return
|
||||
}
|
||||
|
||||
let actionStr = accept ? qsTr("accepted") : qsTr("rejected")
|
||||
root.displayToastMessage("%1 %2 %3".arg(session.peer.metadata.url).arg(methodStr).arg(actionStr), false)
|
||||
root.sessionRequestApprovalResult()
|
||||
|
||||
root.sessionRequestResult(request, "", true /*isSuccessful*/)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -96,13 +104,13 @@ QObject {
|
|||
Connections {
|
||||
target: root.store
|
||||
|
||||
function onUserAuthenticated(topic, id) {
|
||||
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)
|
||||
d.executeSessionRequest(request, password, pin)
|
||||
}
|
||||
|
||||
function onUserAuthenticationFailed(topic, id) {
|
||||
|
@ -117,11 +125,6 @@ QObject {
|
|||
root.displayToastMessage(qsTr("Failed to authenticate %1 from %2").arg(methodStr).arg(session.peer.metadata.url), true)
|
||||
})
|
||||
}
|
||||
|
||||
function onSessionRequestExecuted(payload, isSuccess) {
|
||||
// TODO #14927 handle this properly
|
||||
root.sessionRequestResult(payload, isSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
QObject {
|
||||
|
@ -168,24 +171,24 @@ QObject {
|
|||
|
||||
/// Returns null if the account is not found
|
||||
function lookupAccountFromEvent(event, method) {
|
||||
var address = ""
|
||||
if (method === root.methods.personalSign.name) {
|
||||
if (event.params.request.params.length < 2) {
|
||||
return null
|
||||
}
|
||||
var address = event.params.request.params[1]
|
||||
for (let i = 0; i < walletStore.ownAccounts.count; i++) {
|
||||
let acc = ModelUtils.get(walletStore.ownAccounts, i)
|
||||
if (acc.address === address) {
|
||||
return acc
|
||||
}
|
||||
address = event.params.request.params[1]
|
||||
} else if(method === root.methods.signTypedData_v4.name) {
|
||||
if (event.params.request.params.length < 2) {
|
||||
return null
|
||||
}
|
||||
address = event.params.request.params[0]
|
||||
}
|
||||
return null
|
||||
return ModelUtils.getByKey(walletStore.ownAccounts, "address", address)
|
||||
}
|
||||
|
||||
/// Returns null if the network is not found
|
||||
function lookupNetworkFromEvent(event, method) {
|
||||
if (method === root.methods.personalSign.name) {
|
||||
if (method === root.methods.personalSign.name || method === root.methods.signTypedData_v4.name) {
|
||||
let chainId = Helpers.chainIdFromEip155(event.params.chainId)
|
||||
for (let i = 0; i < walletStore.flatNetworks.count; i++) {
|
||||
let network = ModelUtils.get(walletStore.flatNetworks, i)
|
||||
|
@ -202,9 +205,22 @@ QObject {
|
|||
if (event.params.request.params.length == 0) {
|
||||
return null
|
||||
}
|
||||
let hexMessage = event.params.request.params[0]
|
||||
var message = ""
|
||||
let messageParam = event.params.request.params[0]
|
||||
// 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 {message}
|
||||
} else if (method === root.methods.signTypedData_v4.name) {
|
||||
if (event.params.request.params.length < 2) {
|
||||
return null
|
||||
}
|
||||
let jsonMessage = event.params.request.params[1]
|
||||
return {
|
||||
message: Helpers.hexToString(hexMessage)
|
||||
message: jsonMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,10 +245,33 @@ QObject {
|
|||
})
|
||||
}
|
||||
|
||||
function executeSessionRequest(request) {
|
||||
if (request.method === root.methods.personalSign.name) {
|
||||
store.signMessage(request.data.message)
|
||||
console.debug("TODO #14927 sign message: ", request.data.message)
|
||||
function executeSessionRequest(request, password, pin) {
|
||||
if (request.method === root.methods.personalSign.name || request.method === root.methods.signTypedData_v4.name) {
|
||||
if (password !== "") {
|
||||
//let originalMessage = request.data.message
|
||||
// TODO #14756: clarify why prefixing the message fails the test app https://react-app.walletconnect.com/
|
||||
//let finalMessage = "\x19Ethereum Signed Message:\n" + originalMessage.length + originalMessage
|
||||
let finalMessage = request.data.message
|
||||
var signedMessage = ""
|
||||
if (request.method === root.methods.personalSign.name) {
|
||||
signedMessage = store.signMessage(request.topic, request.id,
|
||||
request.account.address, password, finalMessage)
|
||||
} else if (request.method === root.methods.signTypedData_v4.name) {
|
||||
signedMessage = store.signTypedDataV4(request.topic, request.id,
|
||||
request.account.address, password, finalMessage)
|
||||
}
|
||||
let isSuccessful = signedMessage != ""
|
||||
if (isSuccessful) {
|
||||
// acceptSessionRequest will trigger an sdk.sessionRequestUserAnswerResult signal
|
||||
sdk.acceptSessionRequest(request.topic, request.id, signedMessage)
|
||||
} else {
|
||||
root.sessionRequestResult(request, request.data.message, isSuccessful)
|
||||
}
|
||||
} else if (pin !== "") {
|
||||
console.debug("TODO #14927 sign message using keycard: ", request.data.message)
|
||||
} else {
|
||||
console.error("No password or pin provided to sign message")
|
||||
}
|
||||
} else {
|
||||
console.error("Unsupported method to execute: ", request.method)
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ WalletConnectSDKBase {
|
|||
|
||||
if (d.engine) {
|
||||
d.engine.runJavaScript(`wc.getActiveSessions()`, function(result) {
|
||||
let allSessions = ""
|
||||
var allSessions = ""
|
||||
for (var key of Object.keys(result)) {
|
||||
allSessions += `\nsessionTopic: ${key} relatedPairingTopic: ${result[key].pairingTopic}`;
|
||||
}
|
||||
|
|
|
@ -99,7 +99,9 @@ QObject {
|
|||
root.displayToastMessage(qsTr("Connected to %1 via WalletConnect").arg(app_url), false)
|
||||
|
||||
// Persist session
|
||||
store.addWalletConnectSession(JSON.stringify(session))
|
||||
if(!store.addWalletConnectSession(JSON.stringify(session))) {
|
||||
console.error("Failed to persist session")
|
||||
}
|
||||
|
||||
// Notify client
|
||||
root.approveSessionResult(session, err)
|
||||
|
|
|
@ -4,6 +4,10 @@ function chainIdFromEip155(chain) {
|
|||
return parseInt(chain.split(':').pop().trim(), 10)
|
||||
}
|
||||
|
||||
function isHex(str) {
|
||||
return str.startsWith('0x') && str.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(str.slice(2))
|
||||
}
|
||||
|
||||
function hexToString(hex) {
|
||||
if (hex.startsWith("0x")) {
|
||||
hex = hex.substring(2);
|
||||
|
|
|
@ -21,6 +21,7 @@ StatusDialog {
|
|||
required property string dappName
|
||||
required property string dappUrl
|
||||
required property url dappIcon
|
||||
required property string method
|
||||
required property string signContent
|
||||
required property string maxFeesText
|
||||
required property string estimatedTimeText
|
||||
|
@ -35,6 +36,10 @@ StatusDialog {
|
|||
|
||||
padding: 20
|
||||
|
||||
onSignContentChanged: d.updatePayloadToDisplay()
|
||||
onMethodChanged: d.updatePayloadToDisplay()
|
||||
Component.onCompleted: d.updatePayloadToDisplay()
|
||||
|
||||
contentItem: StatusScrollView {
|
||||
id: scrollView
|
||||
padding: 0
|
||||
|
@ -50,7 +55,6 @@ StatusDialog {
|
|||
dappName: root.dappName
|
||||
dappIcon: root.dappIcon
|
||||
account: root.account
|
||||
signContent: root.signContent
|
||||
}
|
||||
|
||||
ContentPanel {
|
||||
|
@ -273,7 +277,6 @@ StatusDialog {
|
|||
required property string dappName
|
||||
required property url dappIcon
|
||||
required property var account
|
||||
required property string signContent
|
||||
|
||||
// Icons
|
||||
Item {
|
||||
|
@ -405,10 +408,24 @@ StatusDialog {
|
|||
|
||||
width: contentScrollView.availableWidth
|
||||
|
||||
text: signContent
|
||||
text: d.payloadToDisplay
|
||||
|
||||
wrapMode: Text.WrapAnywhere
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property string payloadToDisplay: ""
|
||||
|
||||
function updatePayloadToDisplay() {
|
||||
if (root.method === "eth_signTypedData_v4" && root.signContent) {
|
||||
payloadToDisplay = JSON.stringify(JSON.parse(root.signContent), null, 2)
|
||||
return
|
||||
}
|
||||
payloadToDisplay = root.signContent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,11 @@ QObject {
|
|||
|
||||
/// \c dappsJson serialized from status-go.wallet.GetDapps
|
||||
signal dappsListReceived(string dappsJson)
|
||||
signal userAuthenticated(string topic, string id)
|
||||
signal userAuthenticated(string topic, string id, string password, string pin)
|
||||
signal userAuthenticationFailed(string topic, string id)
|
||||
signal sessionRequestExecuted(var payload, bool success)
|
||||
|
||||
function addWalletConnectSession(sessionJson) {
|
||||
controller.addWalletConnectSession(sessionJson)
|
||||
return controller.addWalletConnectSession(sessionJson)
|
||||
}
|
||||
|
||||
function authenticateUser(topic, id, address) {
|
||||
|
@ -24,9 +23,14 @@ QObject {
|
|||
}
|
||||
}
|
||||
|
||||
function signMessage(message) {
|
||||
// TODO #14927 implement me
|
||||
root.sessionRequestExecuted(message, true)
|
||||
// Returns the hex encoded signature of the message or empty string if error
|
||||
function signMessage(topic, id, address, password, message) {
|
||||
return controller.signMessage(address, password, message)
|
||||
}
|
||||
|
||||
// Returns the hex encoded signature of the typedDataJson or empty string if error
|
||||
function signTypedDataV4(topic, id, address, password, typedDataJson) {
|
||||
return controller.signTypedDataV4(address, password, typedDataJson)
|
||||
}
|
||||
|
||||
/// \c getDapps triggers an async response to \c dappsListReceived
|
||||
|
@ -42,9 +46,9 @@ QObject {
|
|||
root.dappsListReceived(dappsJson)
|
||||
}
|
||||
|
||||
function onUserAuthenticationResult(topic, id, success) {
|
||||
function onUserAuthenticationResult(topic, id, success, password, pin) {
|
||||
if (success) {
|
||||
root.userAuthenticated(topic, id)
|
||||
root.userAuthenticated(topic, id, password, pin)
|
||||
} else {
|
||||
root.userAuthenticationFailed(topic, id)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue