chore(dApps) support multiple actions in DAppRequestModal
Also fix minor issue and add improvements Updates #15126
This commit is contained in:
parent
8bc24c5803
commit
dfe53c4c7c
|
@ -50,10 +50,10 @@ Item {
|
||||||
dappName: settings.dappName
|
dappName: settings.dappName
|
||||||
dappUrl: settings.dappUrl
|
dappUrl: settings.dappUrl
|
||||||
dappIcon: settings.dappIcon
|
dappIcon: settings.dappIcon
|
||||||
signContent: d.signTestContent
|
payloadData: d.currentPayload ? d.currentPayload.payloadData : null
|
||||||
method: "eth_signTypedData_v4"
|
method: d.currentPayload ? d.currentPayload.method : ""
|
||||||
maxFeesText: "1.82 EUR"
|
maxFeesText: d.currentPayload ? d.currentPayload.maxFeesText : ""
|
||||||
estimatedTimeText: "3-5 mins"
|
estimatedTimeText: d.currentPayload ? d.currentPayload.estimatedTimeText : ""
|
||||||
|
|
||||||
account: d.selectedAccount
|
account: d.selectedAccount
|
||||||
network: d.selectedNetwork
|
network: d.selectedNetwork
|
||||||
|
@ -107,6 +107,18 @@ Item {
|
||||||
text: settings.accountDisplay
|
text: settings.accountDisplay
|
||||||
onTextChanged: settings.accountDisplay = text
|
onTextChanged: settings.accountDisplay = text
|
||||||
}
|
}
|
||||||
|
StatusComboBox {
|
||||||
|
id: methodsComboBox
|
||||||
|
|
||||||
|
model: d.methodsModel
|
||||||
|
control.textRole: "method"
|
||||||
|
currentIndex: settings.payloadMethod
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
d.currentPayload = null
|
||||||
|
settings.payloadMethod = currentIndex
|
||||||
|
d.currentPayload = d.payloadOptions[currentIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item { Layout.fillHeight: true }
|
Item { Layout.fillHeight: true }
|
||||||
}
|
}
|
||||||
|
@ -119,17 +131,44 @@ Item {
|
||||||
property string dappUrl: "opensea.io"
|
property string dappUrl: "opensea.io"
|
||||||
property string dappIcon: "https://opensea.io/static/images/logos/opensea-logo.svg"
|
property string dappIcon: "https://opensea.io/static/images/logos/opensea-logo.svg"
|
||||||
property string accountDisplay: "helloworld"
|
property string accountDisplay: "helloworld"
|
||||||
|
property int payloadMethod: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
Component.onCompleted: methodsModel.append(payloadOptions)
|
||||||
|
|
||||||
readonly property var accountsModel: WalletAccountsModel{}
|
readonly property var accountsModel: WalletAccountsModel{}
|
||||||
readonly property var selectedAccount: accountsModel.data[0]
|
readonly property var selectedAccount: accountsModel.data[0]
|
||||||
|
|
||||||
readonly property var selectedNetwork: NetworksModel.flatNetworks.get(0)
|
readonly property var selectedNetwork: NetworksModel.flatNetworks.get(0)
|
||||||
|
|
||||||
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!\"}}"
|
readonly property ListModel methodsModel: ListModel {}
|
||||||
|
property var currentPayload: payloadOptions[settings.payloadMethod]
|
||||||
|
property string maxFeesText: ""
|
||||||
|
property string estimatedTimeText: ""
|
||||||
|
|
||||||
|
readonly property var payloadOptions: [
|
||||||
|
{
|
||||||
|
payloadData: {"message":"This is a message to sign.\nSigning this will prove ownership of the account."},
|
||||||
|
method: "personal_sign",
|
||||||
|
maxFeesText: "",
|
||||||
|
estimatedTimeText: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
payloadData: {"message": "{\"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!\"}}"},
|
||||||
|
method: "eth_signTypedData_v4",
|
||||||
|
maxFeesText: "",
|
||||||
|
estimatedTimeText: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
payloadData: {"tx":{"data":"0x","from":"0xE2d622C817878dA5143bBE06866ca8E35273Ba8a","gasLimit":"0x5208","gasPrice":"0x048ddbc5","nonce":"0x2a","to":"0xE2d622C817878dA5143bBE06866ca8E35273Ba8a","value":"0x00"}},
|
||||||
|
method: "eth_signTransaction",
|
||||||
|
maxFeesText: "1.82 EUR",
|
||||||
|
estimatedTimeText: "3-5 mins"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,6 @@ Item {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
wcService: walletConnectService
|
wcService: walletConnectService
|
||||||
|
|
||||||
onDisplayToastMessage: (message, isErr) => {
|
|
||||||
if(isErr) {
|
|
||||||
console.log(`Storybook.displayToastMessage(${message}, "", "warning", false, Constants.ephemeralNotificationType.danger, "")`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
console.log(`Storybook.displayToastMessage(${message}, "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "")`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColumnLayout {}
|
ColumnLayout {}
|
||||||
|
@ -299,6 +291,10 @@ Item {
|
||||||
function signTypedDataV4(topic, id, address, password, typedDataJson) {
|
function signTypedDataV4(topic, id, address, password, typedDataJson) {
|
||||||
return "0xf8ceb3468319cc215523b67c24c4504b3addd9bf8de31c278038d7478c9b6de554f7d8a516cd5d6a066b7d48b81f03d9d6bb7d5d754513c08325674ebcc7efbc1b"
|
return "0xf8ceb3468319cc215523b67c24c4504b3addd9bf8de31c278038d7478c9b6de554f7d8a516cd5d6a066b7d48b81f03d9d6bb7d5d754513c08325674ebcc7efbc1b"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function signTransaction(topic, id, address, password, tx) {
|
||||||
|
return "0xf8ceb3468319cc215523b67c24c4504b3addd9bf8de31c278038d7478c9b6de554f7d8a516cd5d6a066b7d48b81f03d9d6bb7d5d754513c08325674ebcc7efbc1b"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
walletStore: WalletStore {
|
walletStore: WalletStore {
|
||||||
|
@ -310,7 +306,13 @@ Item {
|
||||||
readonly property ListModel ownAccounts: accounts
|
readonly property ListModel ownAccounts: accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
onDisplayToastMessage: (message, error) => console.info("Storybook - toast message: ", message, !!error ? "; error: " + error: "")
|
onDisplayToastMessage: (message, isErr) => {
|
||||||
|
if(isErr) {
|
||||||
|
console.log(`Storybook.displayToastMessage(${message}, "", "warning", false, Constants.ephemeralNotificationType.danger, "")`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`Storybook.displayToastMessage(${message}, "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "")`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ ConnectedDappsButton {
|
||||||
|
|
||||||
signal dappsListReady()
|
signal dappsListReady()
|
||||||
signal pairWCReady()
|
signal pairWCReady()
|
||||||
signal displayToastMessage(string message, bool error)
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
dappsListLoader.active = true
|
dappsListLoader.active = true
|
||||||
|
@ -128,7 +127,7 @@ ConnectedDappsButton {
|
||||||
dappUrl: request.dappUrl
|
dappUrl: request.dappUrl
|
||||||
dappIcon: request.dappIcon
|
dappIcon: request.dappIcon
|
||||||
|
|
||||||
signContent: request.data.message
|
payloadData: request.data
|
||||||
method: request.method
|
method: request.method
|
||||||
maxFeesText: request.maxFeesText
|
maxFeesText: request.maxFeesText
|
||||||
estimatedTimeText: request.estimatedTimeText
|
estimatedTimeText: request.estimatedTimeText
|
||||||
|
@ -156,7 +155,7 @@ ConnectedDappsButton {
|
||||||
Connections {
|
Connections {
|
||||||
target: root.wcService ? root.wcService.requestHandler : null
|
target: root.wcService ? root.wcService.requestHandler : null
|
||||||
|
|
||||||
function onSessionRequestResult(request, payload, isSuccess) {
|
function onSessionRequestResult(request, isSuccess) {
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
sessionRequestLoader.active = false
|
sessionRequestLoader.active = false
|
||||||
} else {
|
} else {
|
||||||
|
@ -201,9 +200,5 @@ ConnectedDappsButton {
|
||||||
sessionRequestLoader.request = request
|
sessionRequestLoader.request = request
|
||||||
sessionRequestLoader.active = true
|
sessionRequestLoader.active = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDisplayToastMessage(message, err) {
|
|
||||||
root.displayToastMessage(message, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,16 +83,6 @@ Item {
|
||||||
enabled: !!Global.walletConnectService
|
enabled: !!Global.walletConnectService
|
||||||
|
|
||||||
wcService: Global.walletConnectService
|
wcService: Global.walletConnectService
|
||||||
|
|
||||||
onDisplayToastMessage: (message, isErr) => {
|
|
||||||
if (isErr) {
|
|
||||||
Global.displayToastMessage(message, "", "warning", false,
|
|
||||||
Constants.ephemeralNotificationType.danger, "")
|
|
||||||
} else {
|
|
||||||
Global.displayToastMessage(message, "", "checkmark-circle", false,
|
|
||||||
Constants.ephemeralNotificationType.success, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
|
|
||||||
import AppLayouts.Wallet.services.dapps 1.0
|
import AppLayouts.Wallet.services.dapps 1.0
|
||||||
|
import AppLayouts.Wallet.services.dapps.types 1.0
|
||||||
|
|
||||||
import StatusQ.Core.Utils 0.1
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
@ -30,31 +31,7 @@ QObject {
|
||||||
|
|
||||||
signal sessionRequest(SessionRequestResolved request)
|
signal sessionRequest(SessionRequestResolved request)
|
||||||
signal displayToastMessage(string message, bool error)
|
signal displayToastMessage(string message, bool error)
|
||||||
signal sessionRequestResult(/*model entry of SessionRequestResolved*/ var request, var payload, bool isSuccess)
|
signal sessionRequestResult(/*model entry of SessionRequestResolved*/ var request, bool isSuccess)
|
||||||
|
|
||||||
/// Supported methods
|
|
||||||
property QtObject methods: QtObject {
|
|
||||||
readonly property QtObject personalSign: QtObject {
|
|
||||||
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, signTypedData_v4, sendTransaction]
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSupportedMethods() {
|
|
||||||
return methods.all.map(function(method) {
|
|
||||||
return method.name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: sdk
|
target: sdk
|
||||||
|
@ -75,7 +52,7 @@ QObject {
|
||||||
console.error("Error finding event for topic", topic, "id", id)
|
console.error("Error finding event for topic", topic, "id", id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let methodStr = d.methodToUserString(request.method)
|
let methodStr = SessionRequest.methodToUserString(request.method)
|
||||||
if (!methodStr) {
|
if (!methodStr) {
|
||||||
console.error("Error finding user string for method", request.method)
|
console.error("Error finding user string for method", request.method)
|
||||||
return
|
return
|
||||||
|
@ -87,7 +64,7 @@ QObject {
|
||||||
if (error) {
|
if (error) {
|
||||||
root.displayToastMessage(qsTr("Fail to %1 from %2").arg(methodStr).arg(session.peer.metadata.url), true)
|
root.displayToastMessage(qsTr("Fail to %1 from %2").arg(methodStr).arg(session.peer.metadata.url), true)
|
||||||
|
|
||||||
root.sessionRequestResult(request, "", false /*isSuccessful*/)
|
root.sessionRequestResult(request, false /*isSuccessful*/)
|
||||||
|
|
||||||
console.error(`Error accepting session request for topic: ${topic}, id: ${id}, accept: ${accept}, error: ${error}`)
|
console.error(`Error accepting session request for topic: ${topic}, id: ${id}, accept: ${accept}, error: ${error}`)
|
||||||
return
|
return
|
||||||
|
@ -96,7 +73,7 @@ QObject {
|
||||||
let actionStr = accept ? qsTr("accepted") : qsTr("rejected")
|
let actionStr = accept ? qsTr("accepted") : qsTr("rejected")
|
||||||
root.displayToastMessage("%1 %2 %3".arg(session.peer.metadata.url).arg(methodStr).arg(actionStr), false)
|
root.displayToastMessage("%1 %2 %3".arg(session.peer.metadata.url).arg(methodStr).arg(actionStr), false)
|
||||||
|
|
||||||
root.sessionRequestResult(request, "", true /*isSuccessful*/)
|
root.sessionRequestResult(request, true /*isSuccessful*/)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +92,7 @@ QObject {
|
||||||
|
|
||||||
function onUserAuthenticationFailed(topic, id) {
|
function onUserAuthenticationFailed(topic, id) {
|
||||||
var request = requests.findRequest(topic, id)
|
var request = requests.findRequest(topic, id)
|
||||||
let methodStr = d.methodToUserString(request.method)
|
let methodStr = SessionRequest.methodToUserString(request.method)
|
||||||
if (request === null || !methodStr) {
|
if (request === null || !methodStr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -150,9 +127,9 @@ QObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check later to have a valid request object
|
// Check later to have a valid request object
|
||||||
if (!getSupportedMethods().includes(method)
|
if (!SessionRequest.getSupportedMethods().includes(method)
|
||||||
// TODO #14927: support method eth_sendTransaction
|
// TODO #14927: support method eth_sendTransaction
|
||||||
|| method == root.methods.sendTransaction.name) {
|
|| method == SessionRequest.methods.sendTransaction.name) {
|
||||||
console.error("Unsupported method", method)
|
console.error("Unsupported method", method)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -172,23 +149,30 @@ QObject {
|
||||||
/// Returns null if the account is not found
|
/// Returns null if the account is not found
|
||||||
function lookupAccountFromEvent(event, method) {
|
function lookupAccountFromEvent(event, method) {
|
||||||
var address = ""
|
var address = ""
|
||||||
if (method === root.methods.personalSign.name) {
|
if (method === SessionRequest.methods.personalSign.name) {
|
||||||
if (event.params.request.params.length < 2) {
|
if (event.params.request.params.length < 2) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
address = event.params.request.params[1]
|
address = event.params.request.params[1]
|
||||||
} else if(method === root.methods.signTypedData_v4.name) {
|
} else if(method === SessionRequest.methods.signTypedData_v4.name) {
|
||||||
if (event.params.request.params.length < 2) {
|
if (event.params.request.params.length < 2) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
address = event.params.request.params[0]
|
address = event.params.request.params[0]
|
||||||
|
} else if (method === SessionRequest.methods.signTransaction.name) {
|
||||||
|
if (event.params.request.params.length == 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
address = event.params.request.params[0].from
|
||||||
}
|
}
|
||||||
return ModelUtils.getByKey(walletStore.ownAccounts, "address", address)
|
return ModelUtils.getByKey(walletStore.ownAccounts, "address", address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns null if the network is not found
|
/// Returns null if the network is not found
|
||||||
function lookupNetworkFromEvent(event, method) {
|
function lookupNetworkFromEvent(event, method) {
|
||||||
if (method === root.methods.personalSign.name || method === root.methods.signTypedData_v4.name) {
|
if (SessionRequest.getSupportedMethods().includes(method) === false) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
let chainId = Helpers.chainIdFromEip155(event.params.chainId)
|
let chainId = Helpers.chainIdFromEip155(event.params.chainId)
|
||||||
for (let i = 0; i < walletStore.flatNetworks.count; i++) {
|
for (let i = 0; i < walletStore.flatNetworks.count; i++) {
|
||||||
let network = ModelUtils.get(walletStore.flatNetworks, i)
|
let network = ModelUtils.get(walletStore.flatNetworks, i)
|
||||||
|
@ -196,12 +180,11 @@ QObject {
|
||||||
return network
|
return network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractMethodData(event, method) {
|
function extractMethodData(event, method) {
|
||||||
if (method === root.methods.personalSign.name) {
|
if (method === SessionRequest.methods.personalSign.name) {
|
||||||
if (event.params.request.params.length == 0) {
|
if (event.params.request.params.length == 0) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -213,27 +196,24 @@ QObject {
|
||||||
} else {
|
} else {
|
||||||
message = messageParam
|
message = messageParam
|
||||||
}
|
}
|
||||||
return {message}
|
return SessionRequest.methods.personalSign.buildDataObject(message)
|
||||||
} else if (method === root.methods.signTypedData_v4.name) {
|
} else if (method === SessionRequest.methods.signTypedData_v4.name) {
|
||||||
if (event.params.request.params.length < 2) {
|
if (event.params.request.params.length < 2) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let jsonMessage = event.params.request.params[1]
|
let jsonMessage = event.params.request.params[1]
|
||||||
return {
|
return SessionRequest.methods.signTypedData_v4.buildDataObject(jsonMessage)
|
||||||
message: 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 {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function methodToUserString(method) {
|
|
||||||
for (let i = 0; i < methods.all.length; i++) {
|
|
||||||
if (methods.all[i].name === method) {
|
|
||||||
return methods.all[i].userString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function lookupSession(topicToLookup, callback) {
|
function lookupSession(topicToLookup, callback) {
|
||||||
sdk.getActiveSessions((res) => {
|
sdk.getActiveSessions((res) => {
|
||||||
Object.keys(res).forEach((topic) => {
|
Object.keys(res).forEach((topic) => {
|
||||||
|
@ -246,35 +226,40 @@ QObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeSessionRequest(request, password, pin) {
|
function executeSessionRequest(request, password, pin) {
|
||||||
if (request.method === root.methods.personalSign.name || request.method === root.methods.signTypedData_v4.name) {
|
if (!SessionRequest.getSupportedMethods().includes(request.method)) {
|
||||||
|
console.error("Unsupported method to execute: ", request.method)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (password !== "") {
|
if (password !== "") {
|
||||||
//let originalMessage = request.data.message
|
var signedMessage = ""
|
||||||
|
if (request.method === SessionRequest.methods.personalSign.name) {
|
||||||
// TODO #14756: clarify why prefixing the message fails the test app https://react-app.walletconnect.com/
|
// 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 = "\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,
|
signedMessage = store.signMessage(request.topic, request.id,
|
||||||
request.account.address, password, finalMessage)
|
request.account.address, password,
|
||||||
} else if (request.method === root.methods.signTypedData_v4.name) {
|
SessionRequest.methods.personalSign.getMessageFromData(request.data))
|
||||||
|
} else if (request.method === SessionRequest.methods.signTypedData_v4.name) {
|
||||||
signedMessage = store.signTypedDataV4(request.topic, request.id,
|
signedMessage = store.signTypedDataV4(request.topic, request.id,
|
||||||
request.account.address, password, finalMessage)
|
request.account.address, password,
|
||||||
|
SessionRequest.methods.signTypedData_v4.getMessageFromData(request.data))
|
||||||
|
} else if (request.method === SessionRequest.methods.signTransaction.name) {
|
||||||
|
signedMessage = store.signTransaction(request.topic, request.id,
|
||||||
|
request.account.address, password,
|
||||||
|
SessionRequest.methods.signTransaction.getTxFromData(request.data))
|
||||||
}
|
}
|
||||||
let isSuccessful = signedMessage != ""
|
let isSuccessful = (signedMessage != "")
|
||||||
if (isSuccessful) {
|
if (isSuccessful) {
|
||||||
// acceptSessionRequest will trigger an sdk.sessionRequestUserAnswerResult signal
|
// acceptSessionRequest will trigger an sdk.sessionRequestUserAnswerResult signal
|
||||||
sdk.acceptSessionRequest(request.topic, request.id, signedMessage)
|
sdk.acceptSessionRequest(request.topic, request.id, signedMessage)
|
||||||
} else {
|
} else {
|
||||||
root.sessionRequestResult(request, request.data.message, isSuccessful)
|
root.sessionRequestResult(request, isSuccessful)
|
||||||
}
|
}
|
||||||
} else if (pin !== "") {
|
} else if (pin !== "") {
|
||||||
console.debug("TODO #14927 sign message using keycard: ", request.data.message)
|
console.debug("TODO #15097 sign message using keycard: ", request.data)
|
||||||
} else {
|
} else {
|
||||||
console.error("No password or pin provided to sign message")
|
console.error("No password or pin provided to sign message")
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.error("Unsupported method to execute: ", request.method)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
import AppLayouts.Wallet 1.0
|
import AppLayouts.Wallet 1.0
|
||||||
import AppLayouts.Wallet.services.dapps 1.0
|
import AppLayouts.Wallet.services.dapps 1.0
|
||||||
|
import AppLayouts.Wallet.services.dapps.types 1.0
|
||||||
import AppLayouts.Profile.stores 1.0
|
import AppLayouts.Profile.stores 1.0
|
||||||
import shared.stores 1.0
|
import shared.stores 1.0
|
||||||
import shared.popups.walletconnect 1.0
|
import shared.popups.walletconnect 1.0
|
||||||
|
@ -56,7 +57,7 @@ QObject {
|
||||||
let approvedNamespaces = JSON.parse(
|
let approvedNamespaces = JSON.parse(
|
||||||
Helpers.buildSupportedNamespaces(approvedChainIds,
|
Helpers.buildSupportedNamespaces(approvedChainIds,
|
||||||
[approvedAccount.address],
|
[approvedAccount.address],
|
||||||
requestHandler.getSupportedMethods())
|
SessionRequest.getSupportedMethods())
|
||||||
)
|
)
|
||||||
wcSDK.buildApprovedNamespaces(sessionProposal.params, approvedNamespaces)
|
wcSDK.buildApprovedNamespaces(sessionProposal.params, approvedNamespaces)
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,7 @@ QObject {
|
||||||
d.currentSessionProposal = sessionProposal
|
d.currentSessionProposal = sessionProposal
|
||||||
|
|
||||||
let supportedNamespacesStr = Helpers.buildSupportedNamespacesFromModels(
|
let supportedNamespacesStr = Helpers.buildSupportedNamespacesFromModels(
|
||||||
root.flatNetworks, root.validAccounts, requestHandler.getSupportedMethods())
|
root.flatNetworks, root.validAccounts, SessionRequest.getSupportedMethods())
|
||||||
wcSDK.buildApprovedNamespaces(sessionProposal.params, JSON.parse(supportedNamespacesStr))
|
wcSDK.buildApprovedNamespaces(sessionProposal.params, JSON.parse(supportedNamespacesStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQml 2.15
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
/// Supported methods
|
||||||
|
property QtObject methods: QtObject {
|
||||||
|
readonly property QtObject personalSign: QtObject {
|
||||||
|
readonly property string name: Constants.personal_sign
|
||||||
|
readonly property string userString: qsTr("sign")
|
||||||
|
readonly property string requestDisplay: qsTr("sign this message")
|
||||||
|
|
||||||
|
function buildDataObject(message) { return {message} }
|
||||||
|
function getMessageFromData(data) { return data.message }
|
||||||
|
}
|
||||||
|
readonly property QtObject signTypedData_v4: QtObject {
|
||||||
|
readonly property string name: "eth_signTypedData_v4"
|
||||||
|
readonly property string userString: qsTr("sign typed data")
|
||||||
|
readonly property string requestDisplay: qsTr("sign this message")
|
||||||
|
|
||||||
|
function buildDataObject(message) { return {message} }
|
||||||
|
function getMessageFromData(data) { return data.message }
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property QtObject signTransaction: QtObject {
|
||||||
|
readonly property string name: "eth_signTransaction"
|
||||||
|
readonly property string userString: qsTr("sign transaction")
|
||||||
|
readonly property string requestDisplay: qsTr("sign this transaction")
|
||||||
|
|
||||||
|
function buildDataObject(tx) { return {tx} }
|
||||||
|
function getTxFromData(data) { return data.tx }
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property QtObject sendTransaction: QtObject {
|
||||||
|
readonly property string name: "eth_sendTransaction"
|
||||||
|
readonly property string userString: qsTr("send transaction")
|
||||||
|
//function buildDataObject(message) { return {/* TODO #15126 */}}
|
||||||
|
}
|
||||||
|
readonly property var all: [personalSign, signTypedData_v4, signTransaction, sendTransaction]
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSupportedMethods() {
|
||||||
|
return methods.all.map(function(method) {
|
||||||
|
return method.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function methodToUserString(method) {
|
||||||
|
for (let i = 0; i < methods.all.length; i++) {
|
||||||
|
if (methods.all[i].name === method) {
|
||||||
|
return methods.all[i].userString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
SessionRequestResolved 1.0 SessionRequestResolved.qml
|
SessionRequestResolved 1.0 SessionRequestResolved.qml
|
||||||
|
singleton SessionRequest 1.0 SessionRequest.qml
|
|
@ -2054,8 +2054,11 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
onDisplayToastMessage: (message, isErr) => {
|
onDisplayToastMessage: (message, isErr) => {
|
||||||
Global.displayToastMessage(message, "", isErr ? "warning" : "checkmark-circle", false,
|
Global.displayToastMessage(message, "",
|
||||||
isErr ? Constants.ephemeralNotificationType.danger : Constants.ephemeralNotificationType.success, "")
|
isErr ? "warning" : "checkmark-circle", false,
|
||||||
|
isErr ? Constants.ephemeralNotificationType.danger
|
||||||
|
: Constants.ephemeralNotificationType.success,
|
||||||
|
"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import StatusQ.Core.Utils 0.1 as StatusQ
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
|
import AppLayouts.Wallet.services.dapps.types 1.0
|
||||||
|
|
||||||
StatusDialog {
|
StatusDialog {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ StatusDialog {
|
||||||
required property string dappUrl
|
required property string dappUrl
|
||||||
required property url dappIcon
|
required property url dappIcon
|
||||||
required property string method
|
required property string method
|
||||||
required property string signContent
|
required property var payloadData
|
||||||
required property string maxFeesText
|
required property string maxFeesText
|
||||||
required property string estimatedTimeText
|
required property string estimatedTimeText
|
||||||
|
|
||||||
|
@ -36,9 +38,9 @@ StatusDialog {
|
||||||
|
|
||||||
padding: 20
|
padding: 20
|
||||||
|
|
||||||
onSignContentChanged: d.updatePayloadToDisplay()
|
onPayloadDataChanged: d.updateDisplay()
|
||||||
onMethodChanged: d.updatePayloadToDisplay()
|
onMethodChanged: d.updateDisplay()
|
||||||
Component.onCompleted: d.updatePayloadToDisplay()
|
Component.onCompleted: d.updateDisplay()
|
||||||
|
|
||||||
contentItem: StatusScrollView {
|
contentItem: StatusScrollView {
|
||||||
id: scrollView
|
id: scrollView
|
||||||
|
@ -59,7 +61,7 @@ StatusDialog {
|
||||||
|
|
||||||
ContentPanel {
|
ContentPanel {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 340
|
Layout.maximumHeight: 340
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: externalize as a TargetPanel
|
// TODO: externalize as a TargetPanel
|
||||||
|
@ -319,7 +321,7 @@ StatusDialog {
|
||||||
|
|
||||||
// Names and intentions
|
// Names and intentions
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
text: qsTr("%1 wants you to sign this transaction with %2").arg(dappName).arg(account.name)
|
text: qsTr("%1 wants you to %2 with %3").arg(dappName).arg(d.userDisplayNaming).arg(account.name)
|
||||||
|
|
||||||
Layout.preferredWidth: 400
|
Layout.preferredWidth: 400
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
@ -380,9 +382,12 @@ StatusDialog {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
radius: 8
|
radius: 8
|
||||||
|
|
||||||
|
implicitHeight: contentScrollView.implicitHeight + (2 * contentText.anchors.margins)
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: contentScrollView.enabled ? undefined : Qt.PointingHandCursor
|
cursorShape: contentScrollView.enabled || !enabled ? undefined : Qt.PointingHandCursor
|
||||||
|
enabled: contentScrollView.height < contentScrollView.contentHeight
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
contentScrollView.enabled = !contentScrollView.enabled
|
contentScrollView.enabled = !contentScrollView.enabled
|
||||||
|
@ -395,7 +400,7 @@ StatusDialog {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
contentWidth: availableWidth
|
contentWidth: availableWidth
|
||||||
contentHeight: contentText.implicitHeight
|
contentHeight: contentText.contentHeight
|
||||||
|
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
|
@ -419,13 +424,31 @@ StatusDialog {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
property string payloadToDisplay: ""
|
property string payloadToDisplay: ""
|
||||||
|
property string userDisplayNaming: ""
|
||||||
|
|
||||||
function updatePayloadToDisplay() {
|
function updateDisplay() {
|
||||||
if (root.method === "eth_signTypedData_v4" && root.signContent) {
|
if (!root.payloadData)
|
||||||
payloadToDisplay = JSON.stringify(JSON.parse(root.signContent), null, 2)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
switch (root.method) {
|
||||||
|
case SessionRequest.methods.personalSign.name: {
|
||||||
|
payloadToDisplay = SessionRequest.methods.personalSign.getMessageFromData(root.payloadData)
|
||||||
|
userDisplayNaming = SessionRequest.methods.personalSign.requestDisplay
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case SessionRequest.methods.signTypedData_v4.name: {
|
||||||
|
let messageObject = SessionRequest.methods.signTypedData_v4.getMessageFromData(root.payloadData)
|
||||||
|
payloadToDisplay = JSON.stringify(JSON.parse(messageObject), null, 2)
|
||||||
|
userDisplayNaming = SessionRequest.methods.signTypedData_v4.requestDisplay
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case SessionRequest.methods.signTransaction.name: {
|
||||||
|
let tx = SessionRequest.methods.signTransaction.getTxFromData(root.payloadData)
|
||||||
|
payloadToDisplay = JSON.stringify(tx, null, 2)
|
||||||
|
userDisplayNaming = SessionRequest.methods.signTransaction.requestDisplay
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
payloadToDisplay = root.signContent
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue