2024-05-06 17:55:11 +00:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
import QtQuick.Layouts 1.15
|
|
|
|
|
2024-06-29 20:24:05 +00:00
|
|
|
import StatusQ 0.1
|
2024-07-17 10:46:43 +00:00
|
|
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
2024-06-29 20:24:05 +00:00
|
|
|
import SortFilterProxyModel 0.2
|
|
|
|
|
2024-07-09 17:49:00 +00:00
|
|
|
import AppLayouts.Wallet 1.0
|
2024-05-06 17:55:11 +00:00
|
|
|
import AppLayouts.Wallet.controls 1.0
|
2024-05-06 20:22:43 +00:00
|
|
|
import AppLayouts.Wallet.services.dapps 1.0
|
2024-05-31 09:58:47 +00:00
|
|
|
import AppLayouts.Wallet.services.dapps.types 1.0
|
2024-05-06 20:22:43 +00:00
|
|
|
|
2024-07-09 17:49:00 +00:00
|
|
|
import shared.popups.walletconnect 1.0
|
|
|
|
|
2024-05-31 09:34:59 +00:00
|
|
|
import utils 1.0
|
2024-05-06 17:55:11 +00:00
|
|
|
|
2024-06-19 13:13:32 +00:00
|
|
|
DappsComboBox {
|
2024-05-06 17:55:11 +00:00
|
|
|
id: root
|
|
|
|
|
2024-05-06 20:22:43 +00:00
|
|
|
required property WalletConnectService wcService
|
2024-07-11 21:00:15 +00:00
|
|
|
// Values mapped to Constants.LoginType
|
|
|
|
required property int loginType
|
|
|
|
property string selectedAccountAddress
|
2024-05-06 20:22:43 +00:00
|
|
|
|
|
|
|
signal pairWCReady()
|
2024-05-06 17:55:11 +00:00
|
|
|
|
2024-06-19 13:13:32 +00:00
|
|
|
model: root.wcService.dappsModel
|
2024-05-06 17:55:11 +00:00
|
|
|
|
2024-06-19 13:13:32 +00:00
|
|
|
onPairDapp: {
|
|
|
|
pairWCLoader.active = true
|
|
|
|
}
|
2024-05-06 17:55:11 +00:00
|
|
|
|
2024-06-24 21:26:53 +00:00
|
|
|
onDisconnectDapp: (dappUrl) => {
|
2024-07-15 09:23:35 +00:00
|
|
|
disconnectdAppDialogLoader.dAppUrl = dappUrl
|
|
|
|
disconnectdAppDialogLoader.active = true
|
|
|
|
}
|
|
|
|
|
|
|
|
Loader {
|
|
|
|
id: disconnectdAppDialogLoader
|
|
|
|
|
|
|
|
property string dAppUrl
|
|
|
|
|
|
|
|
active: false
|
|
|
|
|
|
|
|
onLoaded: {
|
|
|
|
const dApp = wcService.getDApp(dAppUrl);
|
|
|
|
if (dApp) {
|
|
|
|
item.dappName = dApp.name;
|
|
|
|
item.dappIcon = dApp.iconUrl;
|
|
|
|
item.dappUrl = disconnectdAppDialogLoader.dAppUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
item.open();
|
|
|
|
}
|
|
|
|
|
|
|
|
sourceComponent: DAppConfirmDisconnectPopup {
|
|
|
|
|
|
|
|
visible: true
|
|
|
|
|
|
|
|
onClosed: {
|
|
|
|
disconnectdAppDialogLoader.active = false
|
|
|
|
}
|
|
|
|
|
|
|
|
onAccepted: {
|
|
|
|
root.wcService.disconnectDapp(dappUrl)
|
|
|
|
}
|
|
|
|
}
|
2024-06-24 21:26:53 +00:00
|
|
|
}
|
|
|
|
|
2024-05-06 17:55:11 +00:00
|
|
|
Loader {
|
2024-05-06 20:22:43 +00:00
|
|
|
id: pairWCLoader
|
2024-05-06 17:55:11 +00:00
|
|
|
|
|
|
|
active: false
|
|
|
|
|
|
|
|
onLoaded: {
|
|
|
|
item.open()
|
2024-05-06 20:22:43 +00:00
|
|
|
root.pairWCReady()
|
2024-05-06 17:55:11 +00:00
|
|
|
}
|
|
|
|
|
2024-05-06 20:22:43 +00:00
|
|
|
sourceComponent: PairWCModal {
|
2024-05-06 17:55:11 +00:00
|
|
|
visible: true
|
|
|
|
|
2024-05-06 20:22:43 +00:00
|
|
|
onClosed: pairWCLoader.active = false
|
2024-05-06 17:55:11 +00:00
|
|
|
|
|
|
|
onPair: (uri) => {
|
2024-05-06 20:22:43 +00:00
|
|
|
this.isPairing = true
|
2024-07-05 09:32:31 +00:00
|
|
|
root.wcService.pair(uri)
|
|
|
|
}
|
|
|
|
|
|
|
|
onPairUriChanged: (uri) => {
|
|
|
|
root.wcService.validatePairingUri(uri)
|
2024-05-06 17:55:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-06 20:22:43 +00:00
|
|
|
Loader {
|
|
|
|
id: connectDappLoader
|
|
|
|
|
|
|
|
active: false
|
|
|
|
|
|
|
|
property var dappChains: []
|
|
|
|
property var sessionProposal: null
|
|
|
|
property var availableNamespaces: null
|
|
|
|
property var sessionTopic: null
|
2024-06-29 20:24:05 +00:00
|
|
|
readonly property var proposalMedatada: !!sessionProposal
|
|
|
|
? sessionProposal.params.proposer.metadata
|
|
|
|
: { name: "", url: "", icons: [] }
|
2024-05-06 20:22:43 +00:00
|
|
|
|
|
|
|
sourceComponent: ConnectDAppModal {
|
|
|
|
visible: true
|
|
|
|
|
|
|
|
onClosed: connectDappLoader.active = false
|
2024-06-04 20:45:03 +00:00
|
|
|
accounts: root.wcService.validAccounts
|
2024-06-29 20:24:05 +00:00
|
|
|
flatNetworks: SortFilterProxyModel {
|
|
|
|
sourceModel: root.wcService.flatNetworks
|
|
|
|
filters: [
|
|
|
|
FastExpressionFilter {
|
|
|
|
inverted: true
|
|
|
|
expression: connectDappLoader.dappChains.indexOf(chainId) === -1
|
|
|
|
expectedRoles: ["chainId"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2024-07-11 21:00:15 +00:00
|
|
|
selectedAccountAddress: root.selectedAccountAddress
|
2024-06-29 20:24:05 +00:00
|
|
|
|
|
|
|
dAppUrl: proposalMedatada.url
|
|
|
|
dAppName: proposalMedatada.name
|
|
|
|
dAppIconUrl: !!proposalMedatada.icons && proposalMedatada.icons.length > 0 ? proposalMedatada.icons[0] : ""
|
2024-05-06 20:22:43 +00:00
|
|
|
|
|
|
|
onConnect: {
|
2024-06-15 21:33:12 +00:00
|
|
|
root.wcService.approvePairSession(sessionProposal, selectedChains, selectedAccount)
|
2024-05-06 20:22:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onDecline: {
|
|
|
|
connectDappLoader.active = false
|
|
|
|
root.wcService.rejectPairSession(sessionProposal.id)
|
|
|
|
}
|
|
|
|
|
|
|
|
onDisconnect: {
|
|
|
|
connectDappLoader.active = false
|
2024-06-24 21:26:53 +00:00
|
|
|
root.wcService.disconnectSession(sessionTopic)
|
2024-05-06 20:22:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-31 09:58:47 +00:00
|
|
|
Loader {
|
|
|
|
id: sessionRequestLoader
|
|
|
|
|
|
|
|
active: false
|
|
|
|
|
|
|
|
onLoaded: item.open()
|
|
|
|
|
|
|
|
property SessionRequestResolved request: null
|
2024-07-15 17:30:27 +00:00
|
|
|
property bool requestHandled: false
|
2024-05-31 09:58:47 +00:00
|
|
|
|
2024-07-11 21:00:15 +00:00
|
|
|
sourceComponent: DAppSignRequestModal {
|
2024-07-09 17:49:00 +00:00
|
|
|
id: dappRequestModal
|
2024-07-11 21:00:15 +00:00
|
|
|
objectName: "dappsRequestModal"
|
|
|
|
loginType: request.account.migragedToKeycard ? Constants.LoginType.Keycard : root.loginType
|
|
|
|
visible: true
|
2024-05-31 09:58:47 +00:00
|
|
|
|
2024-07-17 10:46:43 +00:00
|
|
|
property var feesInfo: null
|
|
|
|
|
2024-05-31 09:58:47 +00:00
|
|
|
dappUrl: request.dappUrl
|
|
|
|
dappIcon: request.dappIcon
|
2024-07-11 21:00:15 +00:00
|
|
|
dappName: request.dappName
|
2024-05-31 09:58:47 +00:00
|
|
|
|
2024-07-11 21:00:15 +00:00
|
|
|
accountColor: request.account.color
|
|
|
|
accountName: request.account.name
|
|
|
|
accountAddress: request.account.address
|
|
|
|
accountEmoji: request.account.emoji
|
|
|
|
|
|
|
|
networkName: request.network.chainName
|
|
|
|
networkIconPath: Style.svg(request.network.iconUrl)
|
|
|
|
|
|
|
|
currentCurrency: ""
|
|
|
|
fiatFees: request.maxFeesText
|
|
|
|
cryptoFees: request.maxFeesEthText
|
2024-07-09 17:49:00 +00:00
|
|
|
estimatedTime: ""
|
2024-07-11 21:00:15 +00:00
|
|
|
feesLoading: !request.maxFeesText || !request.maxFeesEthText
|
|
|
|
hasFees: signingTransaction
|
|
|
|
enoughFundsForTransaction: request.enoughFunds
|
|
|
|
enoughFundsForFees: request.enoughFunds
|
|
|
|
|
2024-07-17 16:36:32 +00:00
|
|
|
signingTransaction: !!request.method && (request.method === SessionRequest.methods.signTransaction.name
|
|
|
|
|| request.method === SessionRequest.methods.sendTransaction.name)
|
|
|
|
requestPayload: request.preparedData
|
2024-07-15 17:30:27 +00:00
|
|
|
onClosed: {
|
|
|
|
Qt.callLater( () => {
|
|
|
|
rejectRequest()
|
|
|
|
sessionRequestLoader.active = false
|
|
|
|
})
|
|
|
|
}
|
2024-05-31 09:58:47 +00:00
|
|
|
|
2024-07-11 21:00:15 +00:00
|
|
|
onAccepted: {
|
2024-06-04 20:45:03 +00:00
|
|
|
if (!request) {
|
|
|
|
console.error("Error signing: request is null")
|
|
|
|
return
|
|
|
|
}
|
2024-07-17 10:46:43 +00:00
|
|
|
|
2024-07-15 17:30:27 +00:00
|
|
|
requestHandled = true
|
2024-07-17 10:46:43 +00:00
|
|
|
root.wcService.requestHandler.authenticate(request, JSON.stringify(feesInfo))
|
2024-05-31 09:58:47 +00:00
|
|
|
}
|
|
|
|
|
2024-07-11 21:00:15 +00:00
|
|
|
onRejected: {
|
2024-07-15 17:30:27 +00:00
|
|
|
rejectRequest()
|
|
|
|
}
|
|
|
|
|
|
|
|
function rejectRequest() {
|
|
|
|
// Allow rejecting only once
|
|
|
|
if (requestHandled) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
requestHandled = true
|
2024-05-31 09:58:47 +00:00
|
|
|
let userRejected = true
|
2024-06-04 20:45:03 +00:00
|
|
|
root.wcService.requestHandler.rejectSessionRequest(request, userRejected)
|
2024-05-31 09:58:47 +00:00
|
|
|
}
|
2024-06-18 19:45:56 +00:00
|
|
|
|
|
|
|
Connections {
|
|
|
|
target: root.wcService.requestHandler
|
|
|
|
|
2024-07-17 10:46:43 +00:00
|
|
|
function onMaxFeesUpdated(fiatMaxFees, ethMaxFees, haveEnoughFunds, haveEnoughFees, symbol, feesInfo) {
|
|
|
|
dappRequestModal.hasFees = !!ethMaxFees
|
|
|
|
dappRequestModal.feesLoading = !dappRequestModal.hasFees
|
|
|
|
if (!hasFees) {
|
|
|
|
return
|
2024-06-23 08:27:29 +00:00
|
|
|
}
|
2024-07-17 10:46:43 +00:00
|
|
|
dappRequestModal.fiatFees = fiatMaxFees.toString()
|
|
|
|
dappRequestModal.cryptoFees = ethMaxFees.toString()
|
|
|
|
dappRequestModal.currentCurrency = symbol
|
|
|
|
dappRequestModal.enoughFundsForTransaction = haveEnoughFunds
|
|
|
|
dappRequestModal.enoughFundsForFees = haveEnoughFees
|
|
|
|
dappRequestModal.feesInfo = feesInfo
|
2024-06-18 19:45:56 +00:00
|
|
|
}
|
2024-07-09 17:49:00 +00:00
|
|
|
|
|
|
|
function onEstimatedTimeUpdated(estimatedTimeEnum) {
|
|
|
|
dappRequestModal.estimatedTime = WalletUtils.getLabelForEstimatedTxTime(estimatedTimeEnum)
|
2024-06-18 19:45:56 +00:00
|
|
|
}
|
|
|
|
}
|
2024-05-31 09:58:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-04 20:45:03 +00:00
|
|
|
Connections {
|
|
|
|
target: root.wcService ? root.wcService.requestHandler : null
|
|
|
|
|
2024-06-12 13:48:44 +00:00
|
|
|
function onSessionRequestResult(request, isSuccess) {
|
2024-06-07 16:54:19 +00:00
|
|
|
if (isSuccess) {
|
|
|
|
sessionRequestLoader.active = false
|
|
|
|
} else {
|
|
|
|
// TODO #14762 handle the error case
|
2024-07-17 10:46:43 +00:00
|
|
|
let userRejected = false
|
|
|
|
root.wcService.requestHandler.rejectSessionRequest(request, userRejected)
|
2024-06-07 16:54:19 +00:00
|
|
|
}
|
2024-06-04 20:45:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-06 20:22:43 +00:00
|
|
|
Connections {
|
|
|
|
target: root.wcService
|
|
|
|
|
2024-07-08 11:18:14 +00:00
|
|
|
function onPairingValidated(validationState) {
|
2024-07-05 09:32:31 +00:00
|
|
|
if (pairWCLoader.item) {
|
2024-07-08 11:18:14 +00:00
|
|
|
pairWCLoader.item.pairingValidated(validationState)
|
2024-07-05 09:32:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-06 20:22:43 +00:00
|
|
|
function onConnectDApp(dappChains, sessionProposal, availableNamespaces) {
|
|
|
|
connectDappLoader.dappChains = dappChains
|
|
|
|
connectDappLoader.sessionProposal = sessionProposal
|
|
|
|
connectDappLoader.availableNamespaces = availableNamespaces
|
|
|
|
connectDappLoader.sessionTopic = null
|
|
|
|
|
|
|
|
if (pairWCLoader.item) {
|
2024-07-24 15:37:08 +00:00
|
|
|
// Allow user to get the uri valid confirmation
|
|
|
|
pairWCLoader.item.pairingValidated(Pairing.errors.dappReadyForApproval)
|
|
|
|
connectDappTimer.start()
|
|
|
|
} else {
|
|
|
|
connectDappLoader.active = true
|
2024-05-06 20:22:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onApproveSessionResult(session, err) {
|
|
|
|
connectDappLoader.sessionTopic = session.topic
|
|
|
|
|
|
|
|
let modal = connectDappLoader.item
|
|
|
|
if (!!modal) {
|
|
|
|
if (err) {
|
|
|
|
modal.pairFailed(session, err)
|
|
|
|
} else {
|
|
|
|
modal.pairSuccessful(session)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-05-31 09:34:59 +00:00
|
|
|
|
2024-05-31 09:58:47 +00:00
|
|
|
function onSessionRequest(request) {
|
|
|
|
sessionRequestLoader.request = request
|
2024-07-15 17:30:27 +00:00
|
|
|
sessionRequestLoader.requestHandled = false
|
2024-05-31 09:58:47 +00:00
|
|
|
sessionRequestLoader.active = true
|
|
|
|
}
|
2024-05-06 20:22:43 +00:00
|
|
|
}
|
2024-07-24 15:37:08 +00:00
|
|
|
|
|
|
|
// Used between transitioning from PairWCModal to ConnectDAppModal
|
|
|
|
Timer {
|
|
|
|
id: connectDappTimer
|
|
|
|
|
|
|
|
interval: 500
|
|
|
|
running: false
|
|
|
|
repeat: false
|
|
|
|
|
|
|
|
onTriggered: {
|
|
|
|
pairWCLoader.item.close()
|
|
|
|
connectDappLoader.active = true
|
|
|
|
}
|
|
|
|
}
|
2024-05-06 17:55:11 +00:00
|
|
|
}
|