chore(dapps) implement service tests and basic workflow tests
Abstract WalletConnectSDK to make it testable Implement WC service pairing test Bring back DAppsWorkflow tests back to life and add a pair modal test Updates: #14927
This commit is contained in:
parent
e896267874
commit
145053e34f
|
@ -53,6 +53,14 @@ Item {
|
|||
spacing: 8
|
||||
|
||||
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 {}
|
||||
|
@ -83,6 +91,15 @@ Item {
|
|||
// spacer
|
||||
ColumnLayout {}
|
||||
|
||||
CheckBox {
|
||||
|
||||
text: "Enable SDK"
|
||||
checked: settings.enableSDK
|
||||
onCheckedChanged: {
|
||||
settings.enableSDK = checked
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text { text: "URI" }
|
||||
TextField {
|
||||
|
@ -170,7 +187,7 @@ Item {
|
|||
id: walletConnectService
|
||||
|
||||
wcSDK: WalletConnectSDK {
|
||||
active: true
|
||||
active: settings.enableSDK
|
||||
|
||||
projectId: projectIdText.projectId
|
||||
}
|
||||
|
@ -246,6 +263,7 @@ Item {
|
|||
property int testCase: d.noTestCase
|
||||
property string pairUri: ""
|
||||
property bool testNetworks: false
|
||||
property bool enableSDK: true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
|
||||
const requiredEventsJsonString = `["chainChanged", "accountsChanged"]`
|
||||
const requiredMethodsJsonString = `["eth_sendTransaction","personal_sign"]`
|
||||
const optionalNamespacesJsonString = `{
|
||||
"eip155": {
|
||||
"chains": [
|
||||
"eip155:1",
|
||||
"eip155:10"
|
||||
],
|
||||
"events": [
|
||||
"chainChanged",
|
||||
"accountsChanged",
|
||||
"message",
|
||||
"disconnect",
|
||||
"connect"
|
||||
],
|
||||
"methods": [
|
||||
"eth_sign",
|
||||
"eth_signTransaction",
|
||||
"eth_signTypedData",
|
||||
"eth_signTypedData_v3",
|
||||
"eth_signTypedData_v4",
|
||||
"eth_sendTransaction"
|
||||
],
|
||||
"rpcMap": {
|
||||
"1": "https://cloudflare-eth.com",
|
||||
"10": "https://mainnet.optimism.io/"
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const requiredNamespacesJsonString = `{
|
||||
"eip155": {
|
||||
"chains": [
|
||||
"eip155:1"
|
||||
],
|
||||
"events": ${requiredEventsJsonString},
|
||||
"methods": ${requiredMethodsJsonString},
|
||||
"rpcMap": {
|
||||
"1": "https://mainnet.io/123"
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const dappMetadataJsonString = `{
|
||||
"description": "Test dApp description",
|
||||
"icons": [
|
||||
"https://test.com/icon.png"
|
||||
],
|
||||
"name": "TestApp",
|
||||
"url": "https://app.test.org"
|
||||
}`
|
||||
|
||||
function formatSessionProposal() {
|
||||
return `{
|
||||
"id": 1715976881734096,
|
||||
"params": {
|
||||
"expiryTimestamp": 1715977219,
|
||||
"id": 1715976881734096,
|
||||
"optionalNamespaces": ${optionalNamespacesJsonString},
|
||||
"pairingTopic": "50fba141cdb5c015493c2907c46bacf9f7cbd7c8e3d4e97df891f18dddcff69c",
|
||||
"proposer": {
|
||||
"metadata": ${dappMetadataJsonString},
|
||||
"publicKey": "095d9992ca0eb6081cabed26faf48919162fd70cc66d639f118a60507ae0463d"
|
||||
},
|
||||
"relays": [
|
||||
{
|
||||
"protocol": "irn"
|
||||
}
|
||||
],
|
||||
"requiredNamespaces": ${requiredNamespacesJsonString}
|
||||
},
|
||||
"verifyContext": {
|
||||
"verified": {
|
||||
"origin": "https://app.test.org",
|
||||
"validation": "UNKNOWN",
|
||||
"verifyUrl": "https://verify.walletconnect.com"
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
function formatBuildApprovedNamespacesResult(networksArray, accountsArray) {
|
||||
let requiredChainsStr = networksArray.map(chainId => `"eip155:${chainId}"`).join(',')
|
||||
let requiredAccountsStr = accountsArray.map(address => networksArray.map(chainId => `"eip155:${chainId}:${address}"`).join(',')).join(',')
|
||||
return `{
|
||||
"eip155": {
|
||||
"chains": [${requiredChainsStr}],
|
||||
"accounts": [${requiredAccountsStr}],
|
||||
"events": ${requiredEventsJsonString},
|
||||
"methods": ${requiredMethodsJsonString}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
function formatApproveSessionResponse(networksArray, accountsArray) {
|
||||
let chainsStr = networksArray.map(chainId => `"eip155:${chainId}"`).join(',')
|
||||
let accountsStr = accountsArray.map(address => networksArray.map(chainId => `"eip155:${chainId}:${address}"`).join(',')).join(',')
|
||||
return `{
|
||||
"acknowledged": true,
|
||||
"controller": "da4a87d5f0f54951afe870ebf020cf03f8a3522fbd219398c3fa159a37e16d54",
|
||||
"expiry": 1716581732,
|
||||
"namespaces": {
|
||||
"eip155": {
|
||||
"accounts": [${accountsStr}],
|
||||
"chains": [${chainsStr}],
|
||||
"events": ${requiredEventsJsonString},
|
||||
"methods": ${requiredMethodsJsonString}
|
||||
}
|
||||
},
|
||||
"optionalNamespaces": ${optionalNamespacesJsonString},
|
||||
"pairingTopic": "50fba141cdb5c015493c2907c46bacf9f7cbd7c8e3d4e97df891f18dddcff69c",
|
||||
"peer": {
|
||||
"metadata": ${dappMetadataJsonString},
|
||||
"publicKey": "095d9992ca0eb6081cabed26faf48919162fd70cc66d639f118a60507ae0463d"
|
||||
},
|
||||
"relay": {
|
||||
"protocol": "irn"
|
||||
},
|
||||
"requiredNamespaces": ${requiredNamespacesJsonString},
|
||||
"self": {
|
||||
"metadata": {
|
||||
"description": "Status Wallet",
|
||||
"icons": [
|
||||
"https://status.im/img/status-footer-logo.svg"
|
||||
],
|
||||
"name": "Status",
|
||||
"url": "http://localhost"
|
||||
},
|
||||
"publicKey": "da4a87d5f0f54951afe870ebf020cf03f8a3522fbd219398c3fa159a37e16d54"
|
||||
},
|
||||
"topic": "e39e1f435a46b5ee6b31484d1751cfbc35be1275653af2ea340974a7592f1a19"
|
||||
}`
|
||||
}
|
|
@ -2,56 +2,286 @@ import QtQuick 2.15
|
|||
import QtTest 1.15
|
||||
|
||||
import StatusQ 0.1 // See #10218
|
||||
import StatusQ.Core.Utils 0.1 // See #10218
|
||||
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
//import AppLayouts.Wallet.panels 1.0
|
||||
|
||||
import AppLayouts.Wallet.services.dapps 1.0
|
||||
import AppLayouts.Profile.stores 1.0
|
||||
import shared.stores 1.0
|
||||
|
||||
import QtQml.Models 2.15
|
||||
import AppLayouts.Wallet.panels 1.0
|
||||
|
||||
import "helpers/wallet_connect.js" as Testing
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 600
|
||||
height: 400
|
||||
|
||||
// TODO: mock WalletConnectSDK
|
||||
// Component {
|
||||
// id: componentUnderTest
|
||||
// DAppsWorkflow {
|
||||
// }
|
||||
// }
|
||||
|
||||
// TestCase {
|
||||
// name: "DAppsWorkflow"
|
||||
// when: windowShown
|
||||
Component {
|
||||
id: sdkComponent
|
||||
|
||||
// property DAppsWorkflow controlUnderTest: null
|
||||
WalletConnectSDKBase {
|
||||
property bool sdkReady: true
|
||||
|
||||
// function init() {
|
||||
// controlUnderTest = createTemporaryObject(componentUnderTest, root)
|
||||
// }
|
||||
property int pairCalled: 0
|
||||
|
||||
// function test_ClickToOpenAndClosePopup() {
|
||||
// verify(!!controlUnderTest)
|
||||
// waitForRendering(controlUnderTest)
|
||||
getActiveSessions: function() {
|
||||
return []
|
||||
}
|
||||
pair: function() {
|
||||
pairCalled++
|
||||
}
|
||||
|
||||
// mouseClick(controlUnderTest, Qt.LeftButton)
|
||||
// waitForRendering(controlUnderTest)
|
||||
property var buildApprovedNamespacesCalls: []
|
||||
buildApprovedNamespaces: function(params, supportedNamespaces) {
|
||||
buildApprovedNamespacesCalls.push({params, supportedNamespaces})
|
||||
}
|
||||
|
||||
// let popup = findChild(controlUnderTest, "dappsPopup")
|
||||
// verify(!!popup)
|
||||
// verify(popup.opened)
|
||||
property var approveSessionCalls: []
|
||||
approveSession: function(sessionProposalJson, approvedNamespaces) {
|
||||
approveSessionCalls.push({sessionProposalJson, approvedNamespaces})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mouseClick(Overlay.overlay, Qt.LeftButton)
|
||||
// waitForRendering(controlUnderTest)
|
||||
Component {
|
||||
id: serviceComponent
|
||||
|
||||
// verify(!popup.opened)
|
||||
// }
|
||||
// }
|
||||
WalletConnectService {
|
||||
property var onApproveSessionResultTriggers: []
|
||||
onApproveSessionResult: function(session, error) {
|
||||
onApproveSessionResultTriggers.push({session, error})
|
||||
}
|
||||
|
||||
property var onDisplayToastMessageTriggers: []
|
||||
onDisplayToastMessage: function(message, error) {
|
||||
onDisplayToastMessageTriggers.push({message, error})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: dappsStoreComponent
|
||||
|
||||
DAppsStore {
|
||||
signal dappsListReceived(string dappsJson)
|
||||
|
||||
// By default, return no dapps in store
|
||||
function getDapps() {
|
||||
dappsListReceived('[]')
|
||||
return true
|
||||
}
|
||||
|
||||
property var addWalletConnectSessionCalls: []
|
||||
function addWalletConnectSession(sessionJson) {
|
||||
addWalletConnectSessionCalls.push({sessionJson})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: walletStoreComponent
|
||||
|
||||
WalletStore {
|
||||
readonly property ListModel flatNetworks: ListModel {
|
||||
ListElement { chainId: 1 }
|
||||
ListElement { chainId: 2 }
|
||||
}
|
||||
|
||||
readonly property ListModel accounts: ListModel {
|
||||
ListElement { address: "0x1" }
|
||||
ListElement { address: "0x2" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TestCase {
|
||||
id: walletConnectServiceTest
|
||||
name: "WalletConnectService"
|
||||
|
||||
property WalletConnectService service: null
|
||||
|
||||
SignalSpy {
|
||||
id: connectDAppSpy
|
||||
target: walletConnectServiceTest.service
|
||||
signalName: "connectDApp"
|
||||
|
||||
property var argPos: {
|
||||
"dappChains": 0,
|
||||
"sessionProposalJson": 1,
|
||||
"availableNamespaces": 0
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
let walletStore = createTemporaryObject(walletStoreComponent, root)
|
||||
verify(!!walletStore)
|
||||
let sdk = createTemporaryObject(sdkComponent, root, { projectId: "12ab" })
|
||||
verify(!!sdk)
|
||||
let store = createTemporaryObject(dappsStoreComponent, root)
|
||||
verify(!!store)
|
||||
service = createTemporaryObject(serviceComponent, root, {wcSDK: sdk, store: store, walletStore: walletStore})
|
||||
verify(!!service)
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
service.destroy()
|
||||
connectDAppSpy.clear()
|
||||
}
|
||||
|
||||
function test_TestPairing() {
|
||||
// All calls to SDK are expected as events to be made by the wallet connect SDK
|
||||
let sdk = service.wcSDK
|
||||
let walletStore = service.walletStore
|
||||
let store = service.store
|
||||
|
||||
service.pair("wc:12ab@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&key=12ab")
|
||||
compare(sdk.pairCalled, 1, "expected a call to sdk.pair")
|
||||
|
||||
sdk.sessionProposal(JSON.parse(Testing.formatSessionProposal()))
|
||||
compare(sdk.buildApprovedNamespacesCalls.length, 1, "expected a call to sdk.buildApprovedNamespaces")
|
||||
var args = sdk.buildApprovedNamespacesCalls[0]
|
||||
verify(!!args.supportedNamespaces, "expected supportedNamespaces to be set")
|
||||
let chainsForApproval = args.supportedNamespaces.eip155.chains
|
||||
let networksArray = ModelUtils.modelToArray(walletStore.flatNetworks).map(entry => entry.chainId)
|
||||
verify(networksArray.every(chainId => chainsForApproval.some(eip155Chain => eip155Chain === `eip155:${chainId}`)),
|
||||
"expect all the networks to be present")
|
||||
// We test here all accounts for one chain only, we have separate tests to validate that all accounts are present
|
||||
let allAccountsForApproval = args.supportedNamespaces.eip155.accounts
|
||||
let accountsArray = ModelUtils.modelToArray(walletStore.accounts).map(entry => entry.address)
|
||||
verify(accountsArray.every(address => allAccountsForApproval.some(eip155Address => eip155Address === `eip155:${networksArray[0]}:${address}`)),
|
||||
"expect at least all accounts for the first chain to be present"
|
||||
)
|
||||
|
||||
let allApprovedNamespaces = JSON.parse(Testing.formatBuildApprovedNamespacesResult(networksArray, accountsArray))
|
||||
sdk.buildApprovedNamespacesResult(allApprovedNamespaces, "")
|
||||
compare(connectDAppSpy.count, 1, "expected a call to service.connectDApp")
|
||||
let connectArgs = connectDAppSpy.signalArguments[0]
|
||||
compare(connectArgs[connectDAppSpy.argPos.dappChains], networksArray, "expected all provided networks (walletStore.flatNetworks) for the dappChains")
|
||||
verify(!!connectArgs[connectDAppSpy.argPos.sessionProposalJson], "expected sessionProposalJson to be set")
|
||||
verify(!!connectArgs[connectDAppSpy.argPos.availableNamespaces], "expected availableNamespaces to be set")
|
||||
|
||||
let selectedAccount = walletStore.accounts.get(1)
|
||||
service.approvePairSession(connectArgs[connectDAppSpy.argPos.sessionProposalJson], connectArgs[connectDAppSpy.argPos.dappChains], selectedAccount)
|
||||
compare(sdk.buildApprovedNamespacesCalls.length, 2, "expected a call to sdk.buildApprovedNamespaces")
|
||||
args = sdk.buildApprovedNamespacesCalls[1]
|
||||
verify(!!args.supportedNamespaces, "expected supportedNamespaces to be set")
|
||||
// We test here that only one account for all chains is provided
|
||||
let accountsForApproval = args.supportedNamespaces.eip155.accounts
|
||||
compare(accountsForApproval.length, networksArray.length, "expect only one account per chain")
|
||||
compare(accountsForApproval[0], `eip155:${networksArray[0]}:${selectedAccount.address}`)
|
||||
compare(accountsForApproval[1], `eip155:${networksArray[1]}:${selectedAccount.address}`)
|
||||
|
||||
let approvedNamespaces = JSON.parse(Testing.formatBuildApprovedNamespacesResult(networksArray, [selectedAccount.address]))
|
||||
sdk.buildApprovedNamespacesResult(approvedNamespaces, "")
|
||||
|
||||
compare(sdk.approveSessionCalls.length, 1, "expected a call to sdk.approveSession")
|
||||
verify(!!sdk.approveSessionCalls[0].sessionProposalJson, "expected sessionProposalJson to be set")
|
||||
verify(!!sdk.approveSessionCalls[0].approvedNamespaces, "expected approvedNamespaces to be set")
|
||||
|
||||
let finalApprovedNamespaces = JSON.parse(Testing.formatApproveSessionResponse(networksArray, [selectedAccount.address]))
|
||||
sdk.approveSessionResult(finalApprovedNamespaces, "")
|
||||
verify(store.addWalletConnectSessionCalls.length === 1)
|
||||
verify(store.addWalletConnectSessionCalls[0].sessionJson, "expected sessionJson to be set")
|
||||
|
||||
verify(service.onApproveSessionResultTriggers.length === 1)
|
||||
verify(service.onApproveSessionResultTriggers[0].session, "expected session to be set")
|
||||
|
||||
compare(service.onDisplayToastMessageTriggers.length, 1, "expected a success message to be displayed")
|
||||
verify(!service.onDisplayToastMessageTriggers[0].error, "expected no error")
|
||||
verify(service.onDisplayToastMessageTriggers[0].message, "expected message to be set")
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: componentUnderTest
|
||||
DAppsWorkflow {
|
||||
}
|
||||
}
|
||||
|
||||
TestCase {
|
||||
id: dappsWorkflowTest
|
||||
name: "DAppsWorkflow"
|
||||
when: windowShown
|
||||
|
||||
property DAppsWorkflow controlUnderTest: null
|
||||
|
||||
SignalSpy {
|
||||
id: dappsListReadySpy
|
||||
target: dappsWorkflowTest.controlUnderTest
|
||||
signalName: "dappsListReady"
|
||||
}
|
||||
|
||||
SignalSpy {
|
||||
id: pairWCReadySpy
|
||||
target: dappsWorkflowTest.controlUnderTest
|
||||
signalName: "pairWCReady"
|
||||
}
|
||||
|
||||
function init() {
|
||||
let walletStore = createTemporaryObject(walletStoreComponent, root)
|
||||
verify(!!walletStore)
|
||||
let sdk = createTemporaryObject(sdkComponent, root, { projectId: "12ab" })
|
||||
verify(!!sdk)
|
||||
let store = createTemporaryObject(dappsStoreComponent, root)
|
||||
verify(!!store)
|
||||
let service = createTemporaryObject(serviceComponent, root, {wcSDK: sdk, store: store, walletStore: walletStore})
|
||||
verify(!!service)
|
||||
controlUnderTest = createTemporaryObject(componentUnderTest, root, {wcService: service})
|
||||
verify(!!controlUnderTest)
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
controlUnderTest.destroy()
|
||||
dappsListReadySpy.reset()
|
||||
pairWCReadySpy.reset()
|
||||
}
|
||||
|
||||
function test_OpenAndCloseDappList() {
|
||||
waitForRendering(controlUnderTest)
|
||||
|
||||
compare(dappsListReadySpy.count, 0, "expected NO dappsListReady signal to be emitted")
|
||||
mouseClick(controlUnderTest, Qt.LeftButton)
|
||||
waitForRendering(controlUnderTest)
|
||||
compare(dappsListReadySpy.count, 1, "expected dappsListReady signal to be emitted")
|
||||
|
||||
let popup = findChild(controlUnderTest, "dappsPopup")
|
||||
verify(!!popup)
|
||||
verify(popup.opened)
|
||||
|
||||
mouseClick(Overlay.overlay, Qt.LeftButton)
|
||||
waitForRendering(controlUnderTest)
|
||||
|
||||
verify(!popup.opened)
|
||||
}
|
||||
|
||||
function test_OpenPairModal() {
|
||||
waitForRendering(controlUnderTest)
|
||||
|
||||
mouseClick(controlUnderTest, Qt.LeftButton)
|
||||
waitForRendering(controlUnderTest)
|
||||
|
||||
let popup = findChild(controlUnderTest, "dappsPopup")
|
||||
verify(!!popup)
|
||||
verify(popup.opened)
|
||||
|
||||
let connectButton = findChild(popup, "connectDappButton")
|
||||
verify(!!connectButton)
|
||||
|
||||
verify(pairWCReadySpy.count === 0, "expected NO pairWCReady signal to be emitted")
|
||||
mouseClick(connectButton, Qt.LeftButton)
|
||||
waitForRendering(controlUnderTest)
|
||||
verify(pairWCReadySpy.count === 1, "expected pairWCReady signal to be emitted")
|
||||
|
||||
let pairWCModal = findChild(controlUnderTest, "pairWCModal")
|
||||
verify(!!pairWCModal)
|
||||
}
|
||||
}
|
||||
|
||||
TestCase {
|
||||
name: "ServiceHelpers"
|
||||
|
|
|
@ -8,6 +8,7 @@ import shared.popups.walletconnect 1.0
|
|||
import AppLayouts.Wallet.services.dapps 1.0
|
||||
|
||||
import shared.stores 1.0
|
||||
import utils 1.0
|
||||
|
||||
ConnectedDappsButton {
|
||||
id: root
|
||||
|
@ -16,6 +17,7 @@ ConnectedDappsButton {
|
|||
|
||||
signal dappsListReady()
|
||||
signal pairWCReady()
|
||||
signal displayToastMessage(string message, bool error)
|
||||
|
||||
onClicked: {
|
||||
dappsListLoader.active = true
|
||||
|
@ -138,5 +140,9 @@ ConnectedDappsButton {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onDisplayToastMessage(message, err) {
|
||||
root.displayToastMessage(message, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,16 @@ Item {
|
|||
enabled: !!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 {
|
||||
|
|
|
@ -9,7 +9,7 @@ import utils 1.0
|
|||
QObject {
|
||||
id: root
|
||||
|
||||
required property WalletConnectSDK sdk
|
||||
required property WalletConnectSDKBase sdk
|
||||
required property DAppsStore store
|
||||
|
||||
readonly property alias dappsModel: d.dappsModel
|
||||
|
|
|
@ -8,10 +8,9 @@ import QtWebChannel 1.15
|
|||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
Item {
|
||||
WalletConnectSDKBase {
|
||||
id: root
|
||||
|
||||
required property string projectId
|
||||
readonly property alias sdkReady: d.sdkReady
|
||||
readonly property alias webEngineLoader: loader
|
||||
|
||||
|
@ -21,66 +20,49 @@ Item {
|
|||
implicitWidth: 1
|
||||
implicitHeight: 1
|
||||
|
||||
signal statusChanged(string message)
|
||||
signal sdkInit(bool success, var result)
|
||||
signal pairResponse(bool success)
|
||||
signal sessionProposal(var sessionProposal)
|
||||
signal sessionProposalExpired()
|
||||
signal buildApprovedNamespacesResult(var session, string error)
|
||||
signal approveSessionResult(var approvedNamespaces, string error)
|
||||
signal rejectSessionResult(string error)
|
||||
signal sessionRequestEvent(var sessionRequest)
|
||||
signal sessionRequestUserAnswerResult(bool accept, string error)
|
||||
|
||||
signal authRequest(var request)
|
||||
signal authMessageFormated(string formatedMessage, string address)
|
||||
signal authRequestUserAnswerResult(bool accept, string error)
|
||||
|
||||
signal sessionDelete(var topic, string error)
|
||||
|
||||
/// Generates \c pairResponse signal and expects to receive
|
||||
/// a \c sessionProposal signal with the sessionProposal object
|
||||
function pair(pairLink) {
|
||||
pair: function(pairLink) {
|
||||
wcCalls.pair(pairLink)
|
||||
}
|
||||
|
||||
function getPairings(callback) {
|
||||
getPairings: function(callback) {
|
||||
wcCalls.getPairings(callback)
|
||||
}
|
||||
|
||||
function getActiveSessions(callback) {
|
||||
getActiveSessions: function(callback) {
|
||||
wcCalls.getActiveSessions(callback)
|
||||
}
|
||||
|
||||
function disconnectSession(topic) {
|
||||
disconnectSession: function(topic) {
|
||||
wcCalls.disconnectSession(topic)
|
||||
}
|
||||
|
||||
function disconnectPairing(topic) {
|
||||
disconnectPairing: function(topic) {
|
||||
wcCalls.disconnectPairing(topic)
|
||||
}
|
||||
|
||||
function ping(topic) {
|
||||
ping: function(topic) {
|
||||
wcCalls.ping(topic)
|
||||
}
|
||||
|
||||
function buildApprovedNamespaces(params, supportedNamespaces) {
|
||||
buildApprovedNamespaces: function(params, supportedNamespaces) {
|
||||
wcCalls.buildApprovedNamespaces(params, supportedNamespaces)
|
||||
}
|
||||
|
||||
function approveSession(sessionProposal, supportedNamespaces) {
|
||||
approveSession: function(sessionProposal, supportedNamespaces) {
|
||||
wcCalls.approveSession(sessionProposal, supportedNamespaces)
|
||||
}
|
||||
|
||||
function rejectSession(id) {
|
||||
rejectSession: function(id) {
|
||||
wcCalls.rejectSession(id)
|
||||
}
|
||||
|
||||
function acceptSessionRequest(topic, id, signature) {
|
||||
acceptSessionRequest: function(topic, id, signature) {
|
||||
wcCalls.acceptSessionRequest(topic, id, signature)
|
||||
}
|
||||
|
||||
function rejectSessionRequest(topic, id, error) {
|
||||
rejectSessionRequest: function(topic, id, error) {
|
||||
wcCalls.rejectSessionRequest(topic, id, error)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
/// SDK requires a visible parent to embed WebEngineView
|
||||
Item {
|
||||
required property string projectId
|
||||
|
||||
signal statusChanged(string message)
|
||||
signal sdkInit(bool success, var result)
|
||||
signal pairResponse(bool success)
|
||||
signal sessionProposal(var sessionProposal)
|
||||
signal sessionProposalExpired()
|
||||
signal buildApprovedNamespacesResult(var session, string error)
|
||||
signal approveSessionResult(var approvedNamespaces, string error)
|
||||
signal rejectSessionResult(string error)
|
||||
signal sessionRequestEvent(var sessionRequest)
|
||||
signal sessionRequestUserAnswerResult(bool accept, string error)
|
||||
|
||||
signal authRequest(var request)
|
||||
signal authMessageFormated(string formatedMessage, string address)
|
||||
signal authRequestUserAnswerResult(bool accept, string error)
|
||||
|
||||
signal sessionDelete(var topic, string error)
|
||||
|
||||
property var pair: function(pairLink) {
|
||||
console.error("pair not implemented")
|
||||
}
|
||||
property var getPairings: function(callback) {
|
||||
console.error("getPairings not implemented")
|
||||
}
|
||||
property var getActiveSessions: function(callback) {
|
||||
console.error("getActiveSessions not implemented")
|
||||
}
|
||||
property var disconnectSession: function(topic) {
|
||||
console.error("disconnectSession not implemented")
|
||||
}
|
||||
property var disconnectPairing: function(topic) {
|
||||
console.error("disconnectPairing not implemented")
|
||||
}
|
||||
|
||||
property var ping: function(topic) {
|
||||
console.error("ping not implemented")
|
||||
}
|
||||
|
||||
property var buildApprovedNamespaces: function(params, supportedNamespaces) {
|
||||
console.error("buildApprovedNamespaces not implemented")
|
||||
}
|
||||
property var approveSession: function(sessionProposal, supportedNamespaces) {
|
||||
console.error("approveSession not implemented")
|
||||
}
|
||||
|
||||
property var rejectSession: function(id) {
|
||||
console.error("rejectSession not implemented")
|
||||
}
|
||||
|
||||
property var acceptSessionRequest: function(topic, id, signature) {
|
||||
console.error("acceptSessionRequest not implemented")
|
||||
}
|
||||
|
||||
property var rejectSessionRequest: function(topic, id, error) {
|
||||
console.error("rejectSessionRequest not implemented")
|
||||
}
|
||||
}
|
|
@ -14,11 +14,11 @@ import utils 1.0
|
|||
QObject {
|
||||
id: root
|
||||
|
||||
required property WalletConnectSDK wcSDK
|
||||
required property WalletConnectSDKBase wcSDK
|
||||
required property DAppsStore store
|
||||
required property WalletStore walletStore
|
||||
|
||||
readonly property alias dappsModel: d.dappsProvider.dappsModel
|
||||
readonly property alias dappsModel: dappsProvider.dappsModel
|
||||
|
||||
readonly property var validAccounts: SortFilterProxyModel {
|
||||
sourceModel: walletStore.accounts
|
||||
|
@ -51,6 +51,7 @@ QObject {
|
|||
|
||||
signal connectDApp(var dappChains, var sessionProposal, var approvedNamespaces)
|
||||
signal approveSessionResult(var session, var error)
|
||||
signal displayToastMessage(string message, bool error)
|
||||
|
||||
readonly property Connections sdkConnections: Connections {
|
||||
target: wcSDK
|
||||
|
@ -78,9 +79,6 @@ QObject {
|
|||
}
|
||||
|
||||
function onApproveSessionResult(session, err) {
|
||||
// Notify client
|
||||
root.approveSessionResult(session, err)
|
||||
|
||||
if (err) {
|
||||
// TODO #14676: handle the error
|
||||
console.error("Failed to approve session", err)
|
||||
|
@ -89,44 +87,42 @@ QObject {
|
|||
|
||||
// TODO #14754: implement custom dApp notification
|
||||
let app_url = d.currentSessionProposal ? d.currentSessionProposal.params.proposer.metadata.url : "-"
|
||||
Global.displayToastMessage(qsTr("Connected to %1 via WalletConnect").arg(app_url), "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "")
|
||||
root.displayToastMessage(qsTr("Connected to %1 via WalletConnect").arg(app_url), false)
|
||||
|
||||
// Persist session
|
||||
store.addWalletConnectSession(JSON.stringify(session))
|
||||
|
||||
d.dappsProvider.updateDapps()
|
||||
// Notify client
|
||||
root.approveSessionResult(session, err)
|
||||
|
||||
dappsProvider.updateDapps()
|
||||
}
|
||||
|
||||
function onRejectSessionResult(err) {
|
||||
let app_url = d.currentSessionProposal ? d.currentSessionProposal.params.proposer.metadata.url : "-"
|
||||
if(err) {
|
||||
Global.displayToastMessage(qsTr("Failed to reject connection request for %1").arg(app_url), "", "warning", false, Constants.ephemeralNotificationType.danger, "")
|
||||
root.displayToastMessage(qsTr("Failed to reject connection request for %1").arg(app_url), true)
|
||||
} else {
|
||||
Global.displayToastMessage(qsTr("Connection request for %1 was rejected").arg(app_url), "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "")
|
||||
root.displayToastMessage(qsTr("Connection request for %1 was rejected").arg(app_url), false)
|
||||
}
|
||||
}
|
||||
|
||||
function onSessionDelete(topic, err) {
|
||||
let app_url = d.currentSessionProposal ? d.currentSessionProposal.params.proposer.metadata.url : "-"
|
||||
if(err) {
|
||||
Global.displayToastMessage(qsTr("Failed to disconnect from %1").arg(app_url), "", "warning", false, Constants.ephemeralNotificationType.danger, "")
|
||||
root.displayToastMessage(qsTr("Failed to disconnect from %1").arg(app_url), true)
|
||||
} else {
|
||||
Global.displayToastMessage(qsTr("Disconnected from %1").arg(app_url), "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "")
|
||||
root.displayToastMessage(qsTr("Disconnected from %1").arg(app_url), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
QObject {
|
||||
id: d
|
||||
|
||||
property var currentSessionProposal: null
|
||||
property var acceptedSessionProposal: null
|
||||
|
||||
readonly property DAppsListProvider dappsProvider: DAppsListProvider {
|
||||
sdk: root.wcSDK
|
||||
store: root.store
|
||||
}
|
||||
|
||||
// TODO #14676: use it to check if already paired
|
||||
function getPairingTopicFromPairingUrl(url)
|
||||
{
|
||||
|
@ -146,6 +142,13 @@ QObject {
|
|||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
d.dappsProvider.updateDapps()
|
||||
dappsProvider.updateDapps()
|
||||
}
|
||||
|
||||
DAppsListProvider {
|
||||
id: dappsProvider
|
||||
|
||||
sdk: root.wcSDK
|
||||
store: root.store
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
WalletConnectSDKBase 1.0 WalletConnectSDKBase.qml
|
||||
WalletConnectSDK 1.0 WalletConnectSDK.qml
|
||||
WalletConnectService 1.0 WalletConnectService.qml
|
||||
DAppsListProvider 1.0 DAppsListProvider.qml
|
||||
|
|
|
@ -95,6 +95,7 @@ Popup {
|
|||
}
|
||||
|
||||
StatusButton {
|
||||
objectName: "connectDappButton"
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: implicitHeight
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ import "PairWCModal"
|
|||
StatusDialog {
|
||||
id: root
|
||||
|
||||
objectName: "pairWCModal"
|
||||
|
||||
width: 480
|
||||
implicitHeight: 633
|
||||
|
||||
|
|
Loading…
Reference in New Issue