feat(wallet): WalletConnect web engine view runs SDK in background
Validated that WebEngineView runs SDK in background and can be hidden from view. Closes: #12639
This commit is contained in:
parent
a87a11f92f
commit
0d10d30b30
|
@ -1,5 +1,4 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtWebView 1.15
|
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
@ -44,31 +43,31 @@ Item {
|
||||||
text: "Pair"
|
text: "Pair"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
statusText.text = "Pairing..."
|
statusText.text = "Pairing..."
|
||||||
d.sdkView.pair(pairLinkInput.text)
|
sdkView.pair(pairLinkInput.text)
|
||||||
}
|
}
|
||||||
enabled: pairLinkInput.text.length > 0 && d.sdkView.sdkReady
|
enabled: pairLinkInput.text.length > 0 && sdkView.sdkReady
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
text: "Auth"
|
text: "Auth"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
statusText.text = "Authenticating..."
|
statusText.text = "Authenticating..."
|
||||||
d.sdkView.auth()
|
sdkView.auth()
|
||||||
}
|
}
|
||||||
enabled: false && pairLinkInput.text.length > 0 && d.sdkView.sdkReady
|
enabled: false && pairLinkInput.text.length > 0 && sdkView.sdkReady
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
text: "Accept"
|
text: "Accept"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
d.sdkView.approvePairSession(d.sessionProposal, d.supportedNamespaces)
|
sdkView.approvePairSession(d.sessionProposal, d.supportedNamespaces)
|
||||||
}
|
}
|
||||||
visible: root.state === d.waitingPairState
|
visible: root.state === d.waitingPairState
|
||||||
}
|
}
|
||||||
StatusButton {
|
StatusButton {
|
||||||
text: "Reject"
|
text: "Reject"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
d.sdkView.rejectPairSession(d.sessionProposal.id)
|
sdkView.rejectPairSession(d.sessionProposal.id)
|
||||||
}
|
}
|
||||||
visible: root.state === d.waitingPairState
|
visible: root.state === d.waitingPairState
|
||||||
}
|
}
|
||||||
|
@ -81,14 +80,14 @@ Item {
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
text: "Pairings"
|
text: "Pairings"
|
||||||
visible: d.sdkView.pairingsModel.count > 0
|
visible: sdkView.pairingsModel.count > 0
|
||||||
}
|
}
|
||||||
StatusListView {
|
StatusListView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: contentHeight
|
Layout.preferredHeight: contentHeight
|
||||||
Layout.maximumHeight: 200
|
Layout.maximumHeight: 200
|
||||||
|
|
||||||
model: d.sdkView.pairingsModel
|
model: sdkView.pairingsModel
|
||||||
|
|
||||||
delegate: StatusBaseText {
|
delegate: StatusBaseText {
|
||||||
text: `${SQUtils.Utils.elideText(topic, 6, 6)} - ${new Date(expiry * 1000).toLocaleString()}`
|
text: `${SQUtils.Utils.elideText(topic, 6, 6)} - ${new Date(expiry * 1000).toLocaleString()}`
|
||||||
|
@ -127,7 +126,7 @@ Item {
|
||||||
StatusButton {
|
StatusButton {
|
||||||
text: "Reject"
|
text: "Reject"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
d.sdkView.rejectSessionRequest(d.sessionRequest.topic, d.sessionRequest.id, false)
|
sdkView.rejectSessionRequest(d.sessionRequest.topic, d.sessionRequest.id, false)
|
||||||
}
|
}
|
||||||
visible: root.state === d.waitingUserResponseToSessionRequest
|
visible: root.state === d.waitingUserResponseToSessionRequest
|
||||||
}
|
}
|
||||||
|
@ -143,62 +142,20 @@ Item {
|
||||||
ColumnLayout { /* spacer */ }
|
ColumnLayout { /* spacer */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: DEBUG JS Loading in DMG
|
|
||||||
// RowLayout {
|
|
||||||
// TextField {
|
|
||||||
// id: urlInput
|
|
||||||
|
|
||||||
// Layout.fillWidth: true
|
|
||||||
|
|
||||||
// placeholderText: "Insert URL here"
|
|
||||||
// }
|
|
||||||
// Button {
|
|
||||||
// text: "Set URL"
|
|
||||||
// onClicked: {
|
|
||||||
// d.sdkView.url = urlInput.text
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Button {
|
|
||||||
// text: "Set HTML"
|
|
||||||
// onClicked: {
|
|
||||||
// d.sdkView.loadHtml(htmlContent.text, "http://status.im")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// StatusInput {
|
|
||||||
// id: htmlContent
|
|
||||||
|
|
||||||
// Layout.fillWidth: true
|
|
||||||
// Layout.minimumHeight: 200
|
|
||||||
// Layout.maximumHeight: 300
|
|
||||||
|
|
||||||
// text: `<!DOCTYPE html><html><head><title>TODO: Test</title>\n<!--<script src="http://127.0.0.1:8080/bundle.js" defer></script>-->\n<script type='text/javascript'>\n console.log("@dd loaded dummy script!")\n</script>\n</head><body style='background-color: ${root.backgroundColor.toString()};'></body></html>`
|
|
||||||
|
|
||||||
// multiline: true
|
|
||||||
// minimumHeight: Layout.minimumHeight
|
|
||||||
// maximumHeight: Layout.maximumHeight
|
|
||||||
|
|
||||||
// }
|
|
||||||
// END DEBUGGING
|
|
||||||
|
|
||||||
// Separator
|
// Separator
|
||||||
ColumnLayout {}
|
ColumnLayout {}
|
||||||
|
|
||||||
// TODO: use it in tests to load a dummy SDK
|
|
||||||
Loader {
|
|
||||||
id: sdkViewLoader
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
// Note that a too smaller height might cause the webview to generate rendering errors
|
|
||||||
Layout.preferredHeight: 10
|
|
||||||
|
|
||||||
sourceComponent: SdkViewComponent {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component SdkViewComponent: WalletConnectSDK {
|
WalletConnectSDK {
|
||||||
|
id: sdkView
|
||||||
|
|
||||||
|
// SDK runs fine if WebEngineView is not visible
|
||||||
|
visible: false
|
||||||
|
anchors.top: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: 100
|
||||||
|
height: 100
|
||||||
|
|
||||||
projectId: controller.projectId
|
projectId: controller.projectId
|
||||||
|
|
||||||
onSdkInit: function(success, info) {
|
onSdkInit: function(success, info) {
|
||||||
|
@ -287,8 +244,6 @@ Item {
|
||||||
readonly property string waitingUserResponseToSessionRequest: "waiting_user_response_to_session_request"
|
readonly property string waitingUserResponseToSessionRequest: "waiting_user_response_to_session_request"
|
||||||
readonly property string pairedState: "paired"
|
readonly property string pairedState: "paired"
|
||||||
|
|
||||||
property var sdkView: sdkViewLoader.item
|
|
||||||
|
|
||||||
function setStatusText(message, textColor) {
|
function setStatusText(message, textColor) {
|
||||||
statusText.text = message
|
statusText.text = message
|
||||||
if (textColor === undefined) {
|
if (textColor === undefined) {
|
||||||
|
@ -324,14 +279,14 @@ Item {
|
||||||
console.log("@dd respondSessionRequest", sessionRequestJson, signedJson, error)
|
console.log("@dd respondSessionRequest", sessionRequestJson, signedJson, error)
|
||||||
if (error) {
|
if (error) {
|
||||||
d.setStatusText("Session Request error", "red")
|
d.setStatusText("Session Request error", "red")
|
||||||
d.sdkView.rejectSessionRequest(d.sessionRequest.topic, d.sessionRequest.id, true)
|
sdkView.rejectSessionRequest(d.sessionRequest.topic, d.sessionRequest.id, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d.sessionRequest = JSON.parse(sessionRequestJson)
|
d.sessionRequest = JSON.parse(sessionRequestJson)
|
||||||
d.signedData = JSON.parse(signedJson)
|
d.signedData = JSON.parse(signedJson)
|
||||||
|
|
||||||
d.sdkView.acceptSessionRequest(d.sessionRequest.topic, d.sessionRequest.id, d.signedData)
|
sdkView.acceptSessionRequest(d.sessionRequest.topic, d.sessionRequest.id, d.signedData)
|
||||||
|
|
||||||
d.setStatusText("Session Request accepted")
|
d.setStatusText("Session Request accepted")
|
||||||
d.setDetailsText(d.signedData)
|
d.setDetailsText(d.signedData)
|
||||||
|
|
|
@ -317,6 +317,10 @@ Item {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
console.debug(`@dd WalletConnectSDK.WebEngineView.onCompleted; url: ${url}; debug? ${SQUtils.isDebug()};`)
|
||||||
|
}
|
||||||
|
|
||||||
url: "qrc:/app/AppLayouts/Wallet/views/walletconnect/sdk/src/index.html"
|
url: "qrc:/app/AppLayouts/Wallet/views/walletconnect/sdk/src/index.html"
|
||||||
webChannel: statusChannel
|
webChannel: statusChannel
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,7 @@
|
||||||
|
|
||||||
### Design questions
|
### Design questions
|
||||||
|
|
||||||
- [ ] Do we report all chains and all accounts combination or let user select?
|
|
||||||
- Wallet Connect require to report all chainIDs that were requested
|
|
||||||
- Show error to user workflow.
|
|
||||||
- [ ] Can't respond to sign messages if the wallet-connect dialog/view is closed (app is minimized)
|
|
||||||
- Only apps that use deep links are expected to work seamlessly
|
|
||||||
- [ ] Do we report **disabled chains**? **Update session** in case of enabled/disabled chains?
|
- [ ] Do we report **disabled chains**? **Update session** in case of enabled/disabled chains?
|
||||||
- [ ] Allow user to **disconnect session**? Manage sessions?
|
|
||||||
- [ ] Support update session if one account is added/removed?
|
|
||||||
- [ ] User awareness of session expiration?
|
|
||||||
- Support extend session?
|
|
||||||
- [ ] User error workflow: retry?
|
- [ ] User error workflow: retry?
|
||||||
- [ ] Check the `Auth` request for verifyContext <https://docs.walletconnect.com/web3wallet/verify>
|
- [ ] Check the `Auth` request for verifyContext <https://docs.walletconnect.com/web3wallet/verify>
|
||||||
- [ ] What `description` and `icons` to use for the app? See `metadata` parameter in `Web3Wallet.init` call
|
- [ ] What `description` and `icons` to use for the app? See `metadata` parameter in `Web3Wallet.init` call
|
||||||
|
@ -37,18 +28,6 @@ Install dependencies steps by executing commands in this directory:
|
||||||
|
|
||||||
Use the web demo test client https://react-app.walletconnect.com/ for wallet pairing and https://react-auth-dapp.walletconnect.com/ for authentication
|
Use the web demo test client https://react-app.walletconnect.com/ for wallet pairing and https://react-auth-dapp.walletconnect.com/ for authentication
|
||||||
|
|
||||||
## Log
|
|
||||||
|
|
||||||
Initial setup
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm init -y
|
|
||||||
npm install --save-dev webpack webpack-cli webpack-dev-server
|
|
||||||
npm install --save @walletconnect/web3wallet
|
|
||||||
npm run build
|
|
||||||
# npm run build:dev # for development
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dev - to be removed
|
## Dev - to be removed
|
||||||
|
|
||||||
To test SDK loading add the following to `ui/app/mainui/AppMain.qml`
|
To test SDK loading add the following to `ui/app/mainui/AppMain.qml`
|
||||||
|
@ -75,3 +54,29 @@ StatusDialog {
|
||||||
clip: true
|
clip: true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Log
|
||||||
|
|
||||||
|
Initial setup
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm init -y
|
||||||
|
npm install --save-dev webpack webpack-cli webpack-dev-server
|
||||||
|
npm install --save @walletconnect/web3wallet
|
||||||
|
npm run build
|
||||||
|
# npm run build:dev # for development
|
||||||
|
```
|
||||||
|
|
||||||
|
- [x] Do we report all chains and all accounts combination or let user select?
|
||||||
|
- Wallet Connect require to report all chainIDs that were requested
|
||||||
|
- Answer: We only report the available chains for the current account. We will look into adding others to he same session instead of requiring a new link
|
||||||
|
- [x] Can't respond to sign messages if the wallet-connect dialog/view is closed (app is minimized)
|
||||||
|
- Only apps that use deep links are expected to work seamlessly
|
||||||
|
- Also the main workflow will be driven by user
|
||||||
|
- [x] Allow user to **disconnect session**? Manage sessions?
|
||||||
|
- Yes, in settings
|
||||||
|
- [x] Support update session if one account is added/removed?
|
||||||
|
- Not at first
|
||||||
|
- [X] User awareness of session expiration?
|
||||||
|
- Support extend session?
|
||||||
|
- Yes
|
||||||
|
|
|
@ -22,8 +22,7 @@ continueUserActivity:(NSUserActivity *)userActivity
|
||||||
if (!url)
|
if (!url)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
QUrl deeplink = QUrl::fromNSURL(url);
|
QUrl deeplink = QUrl::fromNSURL(url);
|
||||||
// TODO #12434: Check if WalletConnect link and redirect the workflow
|
// TODO #12434: Check if WalletConnect link and redirect the workflow to Pair or Authenticate
|
||||||
qDebug() << "@dd deeplink " << deeplink;
|
|
||||||
|
|
||||||
// TODO #12245: set it to nim
|
// TODO #12245: set it to nim
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in New Issue