feat(connector)_: create connection between connector service and status-desktop
fix #15179 that triggers connection request from client - Setup the initial architecture for connecting Status-go and UI screens - Implement the request Connection popup for Accept or Rejecting connection
This commit is contained in:
parent
bb4c94438f
commit
a50a6b96f0
|
@ -0,0 +1,17 @@
|
|||
import json, tables, chronicles
|
||||
import base
|
||||
|
||||
include app_service/common/json_utils
|
||||
|
||||
type ConnectorSendRequestAccountsSignal* = ref object of Signal
|
||||
url*: string
|
||||
name*: string
|
||||
iconUrl*: string
|
||||
requestID*: string
|
||||
|
||||
proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal =
|
||||
result = ConnectorSendRequestAccountsSignal()
|
||||
result.url = event["event"]{"url"}.getStr()
|
||||
result.name = event["event"]{"name"}.getStr()
|
||||
result.iconUrl = event["event"]{"iconUrl"}.getStr()
|
||||
result.requestID = event["event"]{"requestId"}.getStr()
|
|
@ -66,6 +66,7 @@ type SignalType* {.pure.} = enum
|
|||
DBReEncryptionFinished = "db.reEncryption.finished"
|
||||
CommunityTokenTransactionStatusChanged = "communityToken.communityTokenTransactionStatusChanged"
|
||||
CommunityTokenAction = "communityToken.communityTokenAction"
|
||||
ConnectorSendRequestAccounts = "connector.sendRequestAccounts"
|
||||
Unknown
|
||||
|
||||
proc event*(self:SignalType):string =
|
||||
|
|
|
@ -135,6 +135,7 @@ QtObject:
|
|||
of SignalType.LocalPairing: LocalPairingSignal.fromEvent(jsonSignal)
|
||||
of SignalType.CommunityTokenTransactionStatusChanged: CommunityTokenTransactionStatusChangedSignal.fromEvent(jsonSignal)
|
||||
of SignalType.CommunityTokenAction: CommunityTokenActionSignal.fromEvent(jsonSignal)
|
||||
of SignalType.ConnectorSendRequestAccounts: ConnectorSendRequestAccountsSignal.fromEvent(jsonSignal)
|
||||
else: Signal()
|
||||
|
||||
result.signalType = signalType
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{.used.}
|
||||
|
||||
import ./remote_signals/[base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages,
|
||||
import ./remote_signals/[base, chronicles_logs, community, connector, discovery_summary, envelope, expired, mailserver, messages,
|
||||
peerstats, signal_type, stats, wallet, whisper_filter, update_available, status_updates, waku_backed_up_profile,
|
||||
waku_backed_up_settings, waku_backed_up_keypair, waku_backed_up_watch_only_account,
|
||||
waku_fetching_backup_progress, pairing, node]
|
||||
|
||||
export base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats,
|
||||
export base, chronicles_logs, community, connector, discovery_summary, envelope, expired, mailserver, messages, peerstats,
|
||||
signal_type, stats, wallet, whisper_filter, update_available, status_updates, waku_backed_up_profile,
|
||||
waku_backed_up_settings, waku_backed_up_keypair, waku_backed_up_watch_only_account,
|
||||
waku_fetching_backup_progress, pairing, node
|
|
@ -19,6 +19,7 @@ import ./activity/details_controller as activity_detailsc
|
|||
|
||||
import app/modules/shared_modules/collectible_details/controller as collectible_detailsc
|
||||
import app/modules/shared_modules/wallet_connect/controller as wc_controller
|
||||
import app/modules/shared_modules/connector/controller as connector_controller
|
||||
|
||||
import app/global/global_singleton
|
||||
import app/core/eventemitter
|
||||
|
@ -39,6 +40,7 @@ import app_service/service/network_connection/service as network_connection_serv
|
|||
import app_service/service/devices/service as devices_service
|
||||
import app_service/service/community_tokens/service as community_tokens_service
|
||||
import app_service/service/wallet_connect/service as wc_service
|
||||
import app_service/service/connector/service as connector_service
|
||||
|
||||
import backend/collectibles as backend_collectibles
|
||||
|
||||
|
@ -81,6 +83,8 @@ type
|
|||
devicesService: devices_service.Service
|
||||
walletConnectService: wc_service.Service
|
||||
walletConnectController: wc_controller.Controller
|
||||
dappsConnectorService: connector_service.Service
|
||||
dappsConnectorController: connector_controller.Controller
|
||||
|
||||
activityController: activityc.Controller
|
||||
collectibleDetailsController: collectible_detailsc.Controller
|
||||
|
@ -171,7 +175,9 @@ proc newModule*(
|
|||
result.walletConnectService = wc_service.newService(result.events, result.threadpool, settingsService, transactionService)
|
||||
result.walletConnectController = wc_controller.newController(result.walletConnectService, walletAccountService)
|
||||
|
||||
result.view = newView(result, result.activityController, result.tmpActivityControllers, result.activityDetailsController, result.collectibleDetailsController, result.walletConnectController)
|
||||
result.dappsConnectorService = connector_service.newService(result.events)
|
||||
result.dappsConnectorController = connector_controller.newController(result.dappsConnectorService, result.events)
|
||||
result.view = newView(result, result.activityController, result.tmpActivityControllers, result.activityDetailsController, result.collectibleDetailsController, result.walletConnectController, result.dappsConnectorController)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
|
||||
method delete*(self: Module) =
|
||||
|
@ -348,6 +354,7 @@ method load*(self: Module) =
|
|||
self.sendModule.load()
|
||||
self.networksModule.load()
|
||||
self.walletConnectService.init()
|
||||
self.dappsConnectorService.init()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
|
|
@ -6,6 +6,7 @@ import app/modules/shared_modules/collectible_details/controller as collectible_
|
|||
import ./io_interface
|
||||
import app/modules/shared_models/currency_amount
|
||||
import app/modules/shared_modules/wallet_connect/controller as wc_controller
|
||||
import app/modules/shared_modules/connector/controller as connector_controller
|
||||
|
||||
type
|
||||
ActivityControllerArray* = array[2, activityc.Controller]
|
||||
|
@ -26,6 +27,7 @@ QtObject:
|
|||
isNonArchivalNode: bool
|
||||
keypairOperabilityForObservedAccount: string
|
||||
wcController: QVariant
|
||||
dappsConnectorController: QVariant
|
||||
walletReady: bool
|
||||
addressFilters: string
|
||||
currentCurrency: string
|
||||
|
@ -37,6 +39,7 @@ QtObject:
|
|||
|
||||
proc delete*(self: View) =
|
||||
self.wcController.delete
|
||||
self.dappsConnectorController.delete
|
||||
|
||||
self.QObject.delete
|
||||
|
||||
|
@ -45,7 +48,8 @@ QtObject:
|
|||
tmpActivityControllers: ActivityControllerArray,
|
||||
activityDetailsController: activity_detailsc.Controller,
|
||||
collectibleDetailsController: collectible_detailsc.Controller,
|
||||
wcController: wc_controller.Controller): View =
|
||||
wcController: wc_controller.Controller,
|
||||
dappsConnectorController: connector_controller.Controller): View =
|
||||
new(result, delete)
|
||||
result.delegate = delegate
|
||||
result.activityController = activityController
|
||||
|
@ -53,6 +57,7 @@ QtObject:
|
|||
result.activityDetailsController = activityDetailsController
|
||||
result.collectibleDetailsController = collectibleDetailsController
|
||||
result.wcController = newQVariant(wcController)
|
||||
result.dappsConnectorController = newQVariant(dappsConnectorController)
|
||||
|
||||
result.setup()
|
||||
|
||||
|
@ -248,6 +253,14 @@ QtObject:
|
|||
QtProperty[QVariant] walletConnectController:
|
||||
read = getWalletConnectController
|
||||
|
||||
proc getDappsConnectorController(self: View): QVariant {.slot.} =
|
||||
if self.dappsConnectorController == nil:
|
||||
return newQVariant()
|
||||
return self.dappsConnectorController
|
||||
|
||||
QtProperty[QVariant] dappsConnectorController:
|
||||
read = getDappsConnectorController
|
||||
|
||||
proc walletReadyChanged*(self: View) {.signal.}
|
||||
|
||||
proc getWalletReady*(self: View): bool {.slot.} =
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
import NimQml
|
||||
import json, strutils
|
||||
import chronicles
|
||||
import app/core/eventemitter
|
||||
|
||||
import app/core/signals/types
|
||||
|
||||
import app_service/service/connector/service as connector_service
|
||||
|
||||
const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
|
||||
|
||||
logScope:
|
||||
topics = "connector-controller"
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Controller* = ref object of QObject
|
||||
service: connector_service.Service
|
||||
events: EventEmitter
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
self.QObject.delete
|
||||
|
||||
proc dappRequestsToConnect*(self: Controller, requestID: string, payload: string) {.signal.}
|
||||
|
||||
proc newController*(service: connector_service.Service, events: EventEmitter): Controller =
|
||||
new(result, delete)
|
||||
|
||||
result.events = events
|
||||
result.service = service
|
||||
|
||||
let controller = result # Capture result in a local variable
|
||||
|
||||
service.registerEventsHandler(proc (event: connector_service.Event, payload: string) =
|
||||
discard
|
||||
)
|
||||
|
||||
result.events.on(SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS) do(e: Args):
|
||||
let params = ConnectorSendRequestAccountsSignal(e)
|
||||
let dappInfo = %*{
|
||||
"icon": params.iconUrl,
|
||||
"name": params.name,
|
||||
"url": params.url,
|
||||
}
|
||||
|
||||
controller.dappRequestsToConnect(params.requestID, dappInfo.toJson())
|
||||
|
||||
result.QObject.setup
|
||||
|
||||
proc parseSingleUInt(chainIDsString: string): uint =
|
||||
try:
|
||||
let chainIds = parseJson(chainIDsString)
|
||||
if chainIds.kind == JArray and chainIds.len == 1 and chainIds[0].kind == JInt:
|
||||
return uint(chainIds[0].getInt())
|
||||
else:
|
||||
raise newException(ValueError, "Invalid JSON array format")
|
||||
except JsonParsingError:
|
||||
raise newException(ValueError, "Failed to parse JSON")
|
||||
|
||||
proc approveDappConnectRequest*(self: Controller, requestID: string, account: string, chainIDString: string): bool {.slot.} =
|
||||
let chainID = parseSingleUInt(chainIDString)
|
||||
return self.service.approveDappConnect(requestID, account, chainID)
|
||||
|
||||
proc rejectDappConnectRequest*(self: Controller, requestID: string): bool {.slot.} =
|
||||
return self.service.rejectDappConnect(requestID)
|
|
@ -0,0 +1,63 @@
|
|||
import NimQml, chronicles, json
|
||||
|
||||
import backend/connector as status_go
|
||||
|
||||
import app/global/global_singleton
|
||||
|
||||
import app/core/eventemitter
|
||||
import app/core/signals/types
|
||||
|
||||
import strutils
|
||||
|
||||
logScope:
|
||||
topics = "connector-service"
|
||||
|
||||
const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
|
||||
|
||||
# Enum with events
|
||||
type Event* = enum
|
||||
DappConnect
|
||||
|
||||
# Event handler function
|
||||
type EventHandlerFn* = proc(event: Event, payload: string)
|
||||
|
||||
# This can be ditched for now and process everything in the controller;
|
||||
# However, it would be good to have the DB based calls async and this might be needed
|
||||
QtObject:
|
||||
type Service* = ref object of QObject
|
||||
events: EventEmitter
|
||||
eventHandler: EventHandlerFn
|
||||
|
||||
proc delete*(self: Service) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newService*(
|
||||
events: EventEmitter
|
||||
): Service =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
|
||||
result.events = events
|
||||
|
||||
proc init*(self: Service) =
|
||||
self.events.on(SignalType.ConnectorSendRequestAccounts.event, proc(e: Args) =
|
||||
if self.eventHandler == nil:
|
||||
return
|
||||
|
||||
var data = ConnectorSendRequestAccountsSignal(e)
|
||||
|
||||
if not data.requestID.len() == 0:
|
||||
echo "ConnectorSendRequestAccountsSignal failed, requestID is empty"
|
||||
return
|
||||
|
||||
self.events.emit(SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS, data)
|
||||
)
|
||||
|
||||
proc registerEventsHandler*(self: Service, handler: EventHandlerFn) =
|
||||
self.eventHandler = handler
|
||||
|
||||
proc approveDappConnect*(self: Service, requestID: string, account: string, chainID: uint): bool =
|
||||
return status_go.requestAccountsAcceptedFinishedRpc(requestID, account, chainID)
|
||||
|
||||
proc rejectDappConnect*(self: Service, requestID: string): bool =
|
||||
return status_go.requestAccountsRejectedFinishedRpc(requestID)
|
|
@ -0,0 +1,53 @@
|
|||
import options, logging
|
||||
import json, json_serialization
|
||||
import core, response_type
|
||||
|
||||
from gen import rpc
|
||||
|
||||
const
|
||||
EventConnectorSendRequestAccounts* = "connector.sendRequestAccounts"
|
||||
|
||||
type RequestAccountsAcceptedArgs* = ref object of RootObj
|
||||
requestID* {.serializedFieldName("requestId").}: string
|
||||
account* {.serializedFieldName("account").}: string
|
||||
chainID* {.serializedFieldName("chainId").}: uint
|
||||
|
||||
type RejectedArgs* = ref object of RootObj
|
||||
requestID* {.serializedFieldName("requestId").}: string
|
||||
|
||||
rpc(requestAccountsAccepted, "connector"):
|
||||
args: RequestAccountsAcceptedArgs
|
||||
|
||||
rpc(requestAccountsRejected, "connector"):
|
||||
args: RejectedArgs
|
||||
|
||||
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
|
||||
return rpcResponse.error.isNil
|
||||
|
||||
proc requestAccountsAcceptedFinishedRpc*(requestID: string, account: string, chainID: uint): bool =
|
||||
try:
|
||||
var args = RequestAccountsAcceptedArgs()
|
||||
|
||||
args.requestID = requestID
|
||||
args.account = account
|
||||
args.chainID = chainID
|
||||
|
||||
let rpcRes = requestAccountsAccepted(args)
|
||||
|
||||
return isSuccessResponse(rpcRes)
|
||||
|
||||
except Exception as e:
|
||||
error "requestAccountsAcceptedFinishedRpc failed: ", "msg", e.msg
|
||||
return false
|
||||
|
||||
proc requestAccountsRejectedFinishedRpc*(requestID: string): bool =
|
||||
try:
|
||||
var args = RejectedArgs()
|
||||
args.requestID = requestID
|
||||
let rpcRes = requestAccountsRejected(args)
|
||||
|
||||
return isSuccessResponse(rpcRes)
|
||||
|
||||
except Exception as e:
|
||||
error "requestAccountsRejectedFinishedRpc failed: ", "msg", e.msg
|
||||
return false
|
|
@ -0,0 +1,133 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import QtWebEngine 1.10
|
||||
import QtWebChannel 1.15
|
||||
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import StatusQ 0.1
|
||||
import SortFilterProxyModel 0.2
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import shared.popups.walletconnect 1.0
|
||||
import AppLayouts.Wallet.services.dapps 1.0
|
||||
import AppLayouts.Wallet.services.dapps.types 1.0
|
||||
|
||||
import shared.stores 1.0
|
||||
import utils 1.0
|
||||
|
||||
import "types"
|
||||
|
||||
// Act as another layer of abstraction to the WalletConnectSDKBase
|
||||
// Quick hack until the WalletConnectSDKBase could be refactored to a more generic DappProviderBase with API to match
|
||||
// the UX requirements
|
||||
WalletConnectSDKBase {
|
||||
id: root
|
||||
|
||||
// Nim connector.controller instance
|
||||
property var controller
|
||||
property bool sdkReady: true
|
||||
property bool active: true
|
||||
required property WalletConnectService wcService
|
||||
property string requestID: ""
|
||||
|
||||
projectId: ""
|
||||
|
||||
implicitWidth: 1
|
||||
implicitHeight: 1
|
||||
|
||||
Loader {
|
||||
id: connectDappLoader
|
||||
|
||||
active: false
|
||||
|
||||
property var dappChains: []
|
||||
property var sessionProposal: null
|
||||
property var availableNamespaces: null
|
||||
property var sessionTopic: null
|
||||
readonly property var proposalMedatada: !!sessionProposal
|
||||
? sessionProposal.params.proposer.metadata
|
||||
: { name: "", url: "", icons: [] }
|
||||
|
||||
sourceComponent: ConnectDAppModal {
|
||||
visible: true
|
||||
|
||||
onClosed: connectDappLoader.active = false
|
||||
accounts: root.wcService.validAccounts
|
||||
property SortFilterProxyModel filteredFlatModel: SortFilterProxyModel {
|
||||
sourceModel: networksModule.flatNetworks
|
||||
filters: ValueFilter { roleName: "isTest"; value: networksModule.areTestNetworksEnabled }
|
||||
}
|
||||
flatNetworks: filteredFlatModel
|
||||
selectedAccountAddress: root.wcService.selectedAccountAddress
|
||||
|
||||
dAppUrl: proposalMedatada.url
|
||||
dAppName: proposalMedatada.name
|
||||
dAppIconUrl: !!proposalMedatada.icons && proposalMedatada.icons.length > 0 ? proposalMedatada.icons[0] : ""
|
||||
multipleChainSelection: false
|
||||
|
||||
onConnect: {
|
||||
connectDappLoader.active = false
|
||||
approveSession(root.requestID, selectedAccount.address, selectedChains)
|
||||
}
|
||||
|
||||
onDecline: {
|
||||
connectDappLoader.active = false
|
||||
rejectSession(root.requestID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: controller
|
||||
|
||||
onDappRequestsToConnect: function(requestID, dappInfoString) {
|
||||
var dappInfo = JSON.parse(dappInfoString)
|
||||
|
||||
let sessionProposal = {
|
||||
"params": {
|
||||
"optionalNamespaces": {},
|
||||
"proposer": {
|
||||
"metadata": {
|
||||
"description": "-",
|
||||
"icons": [
|
||||
dappInfo.icon
|
||||
],
|
||||
"name": dappInfo.name,
|
||||
"url": dappInfo.url
|
||||
}
|
||||
},
|
||||
"requiredNamespaces": {
|
||||
"eip155": {
|
||||
"chains": [
|
||||
`eip155:${dappInfo.chainId}`
|
||||
],
|
||||
"events": [],
|
||||
"methods": ["eth_sendTransaction"]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connectDappLoader.sessionProposal = sessionProposal
|
||||
connectDappLoader.active = true
|
||||
root.requestID = requestID
|
||||
}
|
||||
}
|
||||
|
||||
approveSession: function(requestID, account, selectedChains) {
|
||||
controller.approveDappConnectRequest(requestID, account, JSON.stringify(selectedChains))
|
||||
}
|
||||
|
||||
rejectSession: function(requestID) {
|
||||
controller.rejectDappConnectRequest(requestID)
|
||||
}
|
||||
|
||||
// We don't expect requests for these. They are here only to spot errors
|
||||
pair: function(pairLink) { console.error("ConnectorSDK.pair: not implemented") }
|
||||
getPairings: function(callback) { console.error("ConnectorSDK.getPairings: not implemented") }
|
||||
disconnectPairing: function(topic) { console.error("ConnectorSDK.disconnectPairing: not implemented") }
|
||||
buildApprovedNamespaces: function(params, supportedNamespaces) { console.error("ConnectorSDK.buildApprovedNamespaces: not implemented") }
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
WalletConnectSDKBase 1.0 WalletConnectSDKBase.qml
|
||||
WalletConnectSDK 1.0 WalletConnectSDK.qml
|
||||
WalletConnectService 1.0 WalletConnectService.qml
|
||||
DappsConnectorSDK 1.0 DappsConnectorSDK.qml
|
||||
|
||||
DAppsListProvider 1.0 DAppsListProvider.qml
|
||||
DAppsRequestHandler 1.0 DAppsRequestHandler.qml
|
||||
|
|
|
@ -104,6 +104,7 @@ QtObject {
|
|||
readonly property var tmpActivityController1: walletSectionInst.tmpActivityController1
|
||||
readonly property var activityDetailsController: walletSectionInst.activityDetailsController
|
||||
readonly property var walletConnectController: walletSectionInst.walletConnectController
|
||||
readonly property var dappsConnectorController: walletSectionInst.dappsConnectorController
|
||||
|
||||
readonly property bool isAccountTokensReloading: walletSectionInst.isAccountTokensReloading
|
||||
readonly property double lastReloadTimestamp: walletSectionInst.lastReloadTimestamp
|
||||
|
|
|
@ -2046,19 +2046,55 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: walletConnectSDK
|
||||
|
||||
WalletConnectSDK {
|
||||
active: WalletStore.RootStore.walletSectionInst.walletReady
|
||||
projectId: WalletStore.RootStore.appSettings.walletConnectProjectID
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: dappsConnectorSDK
|
||||
|
||||
DappsConnectorSDK {
|
||||
active: WalletStore.RootStore.walletSectionInst.walletReady
|
||||
controller: WalletStore.RootStore.dappsConnectorController
|
||||
wcService: Global.walletConnectService
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: walletConnectSDKLoader
|
||||
active: Global.featureFlags.dappsEnabled
|
||||
sourceComponent: walletConnectSDK
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: dappsConnectorSDKLoader
|
||||
active: Global.featureFlags.connectorEnabled
|
||||
sourceComponent: dappsConnectorSDK
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: sdkLoader
|
||||
|
||||
onLoaded: {
|
||||
walletConnectSDKLoader.active = Global.featureFlags.dappsEnabled
|
||||
dappsConnectorSDKLoader.active = Global.featureFlags.connectorEnabled
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: walletConnectServiceLoader
|
||||
|
||||
active: Global.featureFlags.dappsEnabled
|
||||
active: Global.featureFlags.dappsEnabled || Global.featureFlags.connectorEnabled
|
||||
|
||||
sourceComponent: WalletConnectService {
|
||||
id: walletConnectService
|
||||
|
||||
wcSDK: WalletConnectSDK {
|
||||
active: WalletStore.RootStore.walletSectionInst.walletReady
|
||||
|
||||
projectId: WalletStore.RootStore.appSettings.walletConnectProjectID
|
||||
}
|
||||
wcSDK: sdkLoader.item
|
||||
store: DAppsStore {
|
||||
controller: WalletStore.RootStore.walletConnectController
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ StatusDialog {
|
|||
*/
|
||||
property string selectedAccountAddress: contextCard.selectedAccount.address ?? ""
|
||||
|
||||
property bool multipleChainSelection: true
|
||||
|
||||
readonly property alias selectedAccount: contextCard.selectedAccount
|
||||
readonly property alias selectedChains: d.selectedChains
|
||||
|
||||
|
@ -118,6 +120,7 @@ StatusDialog {
|
|||
Layout.maximumWidth: root.availableWidth
|
||||
Layout.fillWidth: true
|
||||
|
||||
multipleChainSelection: root.multipleChainSelection
|
||||
selectedAccountAddress: root.selectedAccountAddress
|
||||
connectionAttempted: d.connectionAttempted
|
||||
accountsModel: d.accountsProxy
|
||||
|
|
|
@ -16,6 +16,7 @@ Rectangle {
|
|||
property var accountsModel
|
||||
property var chainsModel
|
||||
property alias chainSelection: networkFilter.selection
|
||||
property bool multipleChainSelection: true
|
||||
|
||||
readonly property alias selectedAccount: accountsDropdown.currentAccount
|
||||
|
||||
|
@ -79,7 +80,7 @@ Rectangle {
|
|||
|
||||
flatNetworks: root.chainsModel
|
||||
showTitle: true
|
||||
multiSelection: true
|
||||
multiSelection: root.multipleChainSelection
|
||||
showAllSelectedText: false
|
||||
selectionAllowed: !root.connectionAttempted && root.chainsModel.ModelCount.count > 1
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue