diff --git a/flake.lock b/flake.lock index bee5d90..eae8aaf 100644 --- a/flake.lock +++ b/flake.lock @@ -528,11 +528,11 @@ ] }, "locked": { - "lastModified": 1771237838, - "narHash": "sha256-UcdHiZ5IdfCSOy17WTz04ZV1n4qqycVfwYzI7BkXeuc=", + "lastModified": 1771705420, + "narHash": "sha256-DySEiVMYk2FWLJWar8rlPqfKDeWMqh5EqXSkn2csRO0=", "owner": "logos-co", "repo": "logos-design-system", - "rev": "596811cbb0a0644322267368e87fab80e34203d8", + "rev": "063c4b46accc621bc85fa8baab46b31ef65f3957", "type": "github" }, "original": { @@ -574,11 +574,11 @@ ] }, "locked": { - "lastModified": 1771584803, - "narHash": "sha256-F6Kk98wy2L1b/Fziq0dbkbvQcTn0pgHJzWoDcuDqaS8=", + "lastModified": 1771696930, + "narHash": "sha256-qEv/HZTBaKe6cDS/42EHmGRocorLqoeELR80LNyiI6c=", "owner": "logos-blockchain", "repo": "logos-execution-zone-module", - "rev": "1291c407777667664ff8973e099d4f7d0076f575", + "rev": "3b7c853d81b4c3bdd6ecea84c84df2d37daed8eb", "type": "github" }, "original": { diff --git a/src/LEZWalletBackend.cpp b/src/LEZWalletBackend.cpp index 57fc092..b1b7434 100644 --- a/src/LEZWalletBackend.cpp +++ b/src/LEZWalletBackend.cpp @@ -224,13 +224,14 @@ bool LEZWalletBackend::createNew( const QString& storagePath, const QString& password) { + const QString localPath = QUrl::fromUserInput(configPath).toLocalFile(); if (!m_walletClient) return false; QVariant result = m_walletClient->invokeRemoteMethod( - WALLET_MODULE_NAME, "create_new", configPath, storagePath, password); + WALLET_MODULE_NAME, "create_new", localPath, storagePath, password); int err = result.isValid() ? result.toInt() : -1; if (err != WALLET_FFI_SUCCESS) return false; - setConfigPath(configPath); + setConfigPath(localPath); setStoragePath(storagePath); setWalletOpen(true); refreshAccounts(); diff --git a/src/qml/ExecutionZoneWalletView.qml b/src/qml/ExecutionZoneWalletView.qml index 75184f7..f8e179e 100644 --- a/src/qml/ExecutionZoneWalletView.qml +++ b/src/qml/ExecutionZoneWalletView.qml @@ -6,34 +6,31 @@ import QtCore import LEZWalletBackend import Logos.Theme import Logos.Controls +import "views" Rectangle { id: root color: Theme.palette.background - SwipeView { - id: swipeView + StackView { anchors.fill: parent - interactive: false - currentIndex: backend && backend.isWalletOpen ? 1 : 0 + initialItem: backend && backend.isWalletOpen ? mainView: onboardingView - // Page 0: Onboarding placeholder (full OnboardingView added later) - Item { - Rectangle { - anchors.fill: parent - color: Theme.palette.background - LogosText { - anchors.centerIn: parent - text: qsTr("Wallet Setup") - font.pixelSize: Theme.typography.secondaryText - font.bold: true + Component { + id: onboardingView + OnboardingView { + onCreateWallet: function(configPath, storagePath, password) { + if (!backend || !backend.createNew(configPath, storagePath, password)) + createError = qsTr("Failed to create wallet. Check paths and try again.") } } } + // Page 1: Main screen placeholder (AccountsView / SendView added later) - Item { + Component { + id: mainView Rectangle { anchors.fill: parent color: Theme.palette.background diff --git a/src/qml/views/OnboardingView.qml b/src/qml/views/OnboardingView.qml new file mode 100644 index 0000000..ae32c1f --- /dev/null +++ b/src/qml/views/OnboardingView.qml @@ -0,0 +1,139 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Dialogs +import QtCore + +import Logos.Theme +import Logos.Controls + +Control { + id: root + + property string createError: "" + + signal createWallet(string configPath, string storagePath, string password) + + + ColumnLayout { + id: cardColumn + + anchors.fill: parent + anchors.margins: Theme.spacing.xlarge + spacing: Theme.spacing.large + + LogosText { + text: qsTr("Set up LEZ Wallet") + font.pixelSize: Theme.typography.titleText + font.weight: Theme.typography.weightBold + color: Theme.palette.text + } + LogosText { + text: qsTr("Configure storage and secure with a password.") + font.pixelSize: Theme.typography.secondaryText + color: Theme.palette.textSecondary + Layout.topMargin: -Theme.spacing.small + } + + LogosText { + text: qsTr("Storage") + font.pixelSize: Theme.typography.secondaryText + font.weight: Theme.typography.weightMedium + color: Theme.palette.text + } + RowLayout { + Layout.fillWidth: true + spacing: Theme.spacing.small + LogosTextField { + id: storagePathField + Layout.fillWidth: true + placeholderText: qsTr("/Users/you/.lez-wallet/") + } + LogosButton { + text: qsTr("Browse") + onClicked: storageFolderDialog.open() + } + } + LogosText { + text: qsTr("Config file") + font.pixelSize: Theme.typography.secondaryText + font.weight: Theme.typography.weightMedium + color: Theme.palette.text + } + RowLayout { + Layout.fillWidth: true + spacing: Theme.spacing.small + LogosTextField { + id: configPathField + Layout.fillWidth: true + placeholderText: qsTr("Add path to config") + } + LogosButton { + Layout.preferredHeight: configPathField.height + text: qsTr("Browse") + onClicked: configFileDialog.open() + } + } + + LogosText { + text: qsTr("Security") + font.pixelSize: Theme.typography.secondaryText + font.weight: Theme.typography.weightMedium + color: Theme.palette.text + Layout.topMargin: Theme.spacing.medium + } + LogosTextField { + id: passwordField + Layout.fillWidth: true + placeholderText: qsTr("Password") + echoMode: TextInput.Password + } + LogosTextField { + id: confirmField + Layout.fillWidth: true + placeholderText: qsTr("Confirm") + echoMode: TextInput.Password + } + + LogosText { + id: errorLabel + Layout.fillWidth: true + font.pixelSize: Theme.typography.secondaryText + color: Theme.palette.error + wrapMode: Text.WordWrap + visible: text.length > 0 + text: root.createError + } + + LogosButton { + Layout.alignment: Qt.AlignRight + text: qsTr("Create Wallet") + font.pixelSize: Theme.typography.secondaryText + onClicked: { + if (passwordField.text.length === 0) { + root.createError = qsTr("Password cannot be empty.") + } else if (passwordField.text !== confirmField.text) { + root.createError = qsTr("Passwords do not match.") + } else { + root.createError = "" + root.createWallet(configPathField.text, storagePathField.text, passwordField.text) + } + } + } + } + + FolderDialog { + id: storageFolderDialog + modality: Qt.NonModal + onAccepted: storagePathField.text = selectedFolder.toString().replace(/^file:\/\//, "") + } + + FileDialog { + id: configFileDialog + modality: Qt.NonModal + nameFilters: ["YAML files (*.yaml)"] + onAccepted: { + if (selectedFile) configPathField.text = selectedFile.toString().replace(/^file:\/\//, "") + } + } +} diff --git a/src/qml/views/qmldir b/src/qml/views/qmldir new file mode 100644 index 0000000..c331b23 --- /dev/null +++ b/src/qml/views/qmldir @@ -0,0 +1,2 @@ +module views +OnboardingView 1.0 OnboardingView.qml diff --git a/src/wallet_resources.qrc b/src/wallet_resources.qrc index 5d8ba7e..426e5e8 100644 --- a/src/wallet_resources.qrc +++ b/src/wallet_resources.qrc @@ -1,5 +1,7 @@ qml/ExecutionZoneWalletView.qml + qml/views/qmldir + qml/views/OnboardingView.qml