From 34b543aa72b4f2cee73449e5abb95ff5658c5800 Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Fri, 20 Feb 2026 18:10:59 +0100 Subject: [PATCH 1/2] feat: add onboarding view --- flake.lock | 15 +-- flake.nix | 2 +- src/LEZWalletBackend.cpp | 5 +- src/qml/ExecutionZoneWalletView.qml | 27 ++--- src/qml/views/OnboardingView.qml | 171 ++++++++++++++++++++++++++++ src/qml/views/qmldir | 2 + src/wallet_resources.qrc | 2 + 7 files changed, 197 insertions(+), 27 deletions(-) create mode 100644 src/qml/views/OnboardingView.qml create mode 100644 src/qml/views/qmldir diff --git a/flake.lock b/flake.lock index bee5d90..497dbfa 100644 --- a/flake.lock +++ b/flake.lock @@ -574,17 +574,14 @@ ] }, "locked": { - "lastModified": 1771584803, - "narHash": "sha256-F6Kk98wy2L1b/Fziq0dbkbvQcTn0pgHJzWoDcuDqaS8=", - "owner": "logos-blockchain", - "repo": "logos-execution-zone-module", - "rev": "1291c407777667664ff8973e099d4f7d0076f575", - "type": "github" + "lastModified": 1771606875, + "narHash": "sha256-g6YPUN8LtRGAj5OG4PAZNuKyNQL0uTP+5IZEcQVaozE=", + "path": "/Users/khushboomehta/Documents/logos/logos-execution-zone-module", + "type": "path" }, "original": { - "owner": "logos-blockchain", - "repo": "logos-execution-zone-module", - "type": "github" + "path": "/Users/khushboomehta/Documents/logos/logos-execution-zone-module", + "type": "path" } }, "logos-liblogos": { diff --git a/flake.nix b/flake.nix index bd6578d..eddd990 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ nixpkgs.follows = "logos-liblogos/nixpkgs"; logos-cpp-sdk.url = "github:logos-co/logos-cpp-sdk"; logos-liblogos.url = "github:logos-co/logos-liblogos"; - logos-execution-zone-module.url = "github:logos-blockchain/logos-execution-zone-module"; + logos-execution-zone-module.url = "path:/Users/khushboomehta/Documents/logos/logos-execution-zone-module"; logos-capability-module.url = "github:logos-co/logos-capability-module"; logos-design-system.url = "github:logos-co/logos-design-system"; logos-design-system.inputs.nixpkgs.follows = "nixpkgs"; 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..f047c5c --- /dev/null +++ b/src/qml/views/OnboardingView.qml @@ -0,0 +1,171 @@ +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 + CustomTextField { + id: storagePathField + placeholderText: qsTr("/Users/you/.lez-wallet/") + } + LogosButton { + text: qsTr("Browse") + onClicked: storageFolderDialog.open() + } + } + LogosText { + text: qsTr("Config file (optional)") + font.pixelSize: Theme.typography.secondaryText + font.weight: Theme.typography.weightMedium + color: Theme.palette.text + } + RowLayout { + Layout.fillWidth: true + spacing: Theme.spacing.small + CustomTextField { + id: configPathField + placeholderText: qsTr("Use default config") + } + LogosButton { + 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 + } + CustomTextField { + id: passwordField + placeholderText: qsTr("Password") + echoMode: TextInput.Password + } + CustomTextField { + id: confirmField + 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) + } + } + } + + component CustomTextField: Item { + id: textFieldRoot + Layout.fillWidth: true + implicitHeight: 40 + property alias text: input.text + property string placeholderText: "" + property int echoMode: TextInput.Normal + Rectangle { + anchors.fill: parent + radius: Theme.spacing.radiusSmall + color: Theme.palette.backgroundSecondary + border.width: 1 + border.color: input.activeFocus ? Theme.palette.overlayOrange : Theme.palette.backgroundElevated + } + Text { + id: placeholder + anchors.fill: parent + anchors.leftMargin: 12 + anchors.rightMargin: 12 + verticalAlignment: Text.AlignVCenter + text: textFieldRoot.placeholderText + color: Theme.palette.textMuted + font.pixelSize: Theme.typography.secondaryText + visible: input.text.length === 0 + } + TextInput { + id: input + anchors.fill: parent + anchors.leftMargin: 12 + anchors.rightMargin: 12 + verticalAlignment: Text.AlignVCenter + font.pixelSize: Theme.typography.secondaryText + color: Theme.palette.text + echoMode: textFieldRoot.echoMode + } + } + } + + 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 From 2deaee74d7b3b86f4cfc6fe0c64d94b99907dd00 Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Sat, 21 Feb 2026 21:26:04 +0100 Subject: [PATCH 2/2] feat: add onboarding view --- flake.lock | 21 +++++++------ flake.nix | 2 +- src/qml/views/OnboardingView.qml | 54 +++++++------------------------- 3 files changed, 24 insertions(+), 53 deletions(-) diff --git a/flake.lock b/flake.lock index 497dbfa..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,14 +574,17 @@ ] }, "locked": { - "lastModified": 1771606875, - "narHash": "sha256-g6YPUN8LtRGAj5OG4PAZNuKyNQL0uTP+5IZEcQVaozE=", - "path": "/Users/khushboomehta/Documents/logos/logos-execution-zone-module", - "type": "path" + "lastModified": 1771696930, + "narHash": "sha256-qEv/HZTBaKe6cDS/42EHmGRocorLqoeELR80LNyiI6c=", + "owner": "logos-blockchain", + "repo": "logos-execution-zone-module", + "rev": "3b7c853d81b4c3bdd6ecea84c84df2d37daed8eb", + "type": "github" }, "original": { - "path": "/Users/khushboomehta/Documents/logos/logos-execution-zone-module", - "type": "path" + "owner": "logos-blockchain", + "repo": "logos-execution-zone-module", + "type": "github" } }, "logos-liblogos": { diff --git a/flake.nix b/flake.nix index eddd990..bd6578d 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ nixpkgs.follows = "logos-liblogos/nixpkgs"; logos-cpp-sdk.url = "github:logos-co/logos-cpp-sdk"; logos-liblogos.url = "github:logos-co/logos-liblogos"; - logos-execution-zone-module.url = "path:/Users/khushboomehta/Documents/logos/logos-execution-zone-module"; + logos-execution-zone-module.url = "github:logos-blockchain/logos-execution-zone-module"; logos-capability-module.url = "github:logos-co/logos-capability-module"; logos-design-system.url = "github:logos-co/logos-design-system"; logos-design-system.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/src/qml/views/OnboardingView.qml b/src/qml/views/OnboardingView.qml index f047c5c..ae32c1f 100644 --- a/src/qml/views/OnboardingView.qml +++ b/src/qml/views/OnboardingView.qml @@ -44,8 +44,9 @@ Control { RowLayout { Layout.fillWidth: true spacing: Theme.spacing.small - CustomTextField { + LogosTextField { id: storagePathField + Layout.fillWidth: true placeholderText: qsTr("/Users/you/.lez-wallet/") } LogosButton { @@ -54,7 +55,7 @@ Control { } } LogosText { - text: qsTr("Config file (optional)") + text: qsTr("Config file") font.pixelSize: Theme.typography.secondaryText font.weight: Theme.typography.weightMedium color: Theme.palette.text @@ -62,11 +63,13 @@ Control { RowLayout { Layout.fillWidth: true spacing: Theme.spacing.small - CustomTextField { + LogosTextField { id: configPathField - placeholderText: qsTr("Use default config") + Layout.fillWidth: true + placeholderText: qsTr("Add path to config") } LogosButton { + Layout.preferredHeight: configPathField.height text: qsTr("Browse") onClicked: configFileDialog.open() } @@ -79,13 +82,15 @@ Control { color: Theme.palette.text Layout.topMargin: Theme.spacing.medium } - CustomTextField { + LogosTextField { id: passwordField + Layout.fillWidth: true placeholderText: qsTr("Password") echoMode: TextInput.Password } - CustomTextField { + LogosTextField { id: confirmField + Layout.fillWidth: true placeholderText: qsTr("Confirm") echoMode: TextInput.Password } @@ -115,43 +120,6 @@ Control { } } } - - component CustomTextField: Item { - id: textFieldRoot - Layout.fillWidth: true - implicitHeight: 40 - property alias text: input.text - property string placeholderText: "" - property int echoMode: TextInput.Normal - Rectangle { - anchors.fill: parent - radius: Theme.spacing.radiusSmall - color: Theme.palette.backgroundSecondary - border.width: 1 - border.color: input.activeFocus ? Theme.palette.overlayOrange : Theme.palette.backgroundElevated - } - Text { - id: placeholder - anchors.fill: parent - anchors.leftMargin: 12 - anchors.rightMargin: 12 - verticalAlignment: Text.AlignVCenter - text: textFieldRoot.placeholderText - color: Theme.palette.textMuted - font.pixelSize: Theme.typography.secondaryText - visible: input.text.length === 0 - } - TextInput { - id: input - anchors.fill: parent - anchors.leftMargin: 12 - anchors.rightMargin: 12 - verticalAlignment: Text.AlignVCenter - font.pixelSize: Theme.typography.secondaryText - color: Theme.palette.text - echoMode: textFieldRoot.echoMode - } - } } FolderDialog {