From ccd8c5b65f973718aa935d37736edc90b763957f Mon Sep 17 00:00:00 2001 From: Stefan Date: Tue, 3 Oct 2023 18:43:35 +0300 Subject: [PATCH] feat(wallet) Wallet Connect integration prototype Implement a prototype of integrating [WalletConnect Web SDK]() - integrate WalletConnect Web SDK using Node.js and packing it using [webpack](https://webpack.js.org/guides/getting-started/) - this way, we achieve the same versioning strategy for the SDK - add WalletConnectSDK view - it is used to load the web SDK via a WebView (validated working on Mac and Windows) - add new app dependency of WebView QT - also update vendor packages `Dotherside` and `nimqml` to add required WebView::initialize API used to initialize the WebView integration at the app start - add WalletConnectPage to Storybook for quick prototyping - Also add dependency for WebView Qt lib - index.js is the wrapper used to provide a simple stateful interface with the WC SDK - Entry in ui/generate-rcc.go ensures the node_modules cache is excluded from the resource file Notes: - Added `com.apple.security.cs.allow-jit` entitlement when signing the app package. This allows Execution of JIT-compiled Code Entitlement required by the fast-path of the JavaScriptCore framework on MacOS platforms. - Keep some debugging entries expected to help debugging Linux package - Removed outdated `DerivationPathInputRegressionTests` qml test Closes #12301 --- Makefile | 2 +- resources/Entitlements.plist | 4 + scripts/sign-macos-pkg.sh | 2 +- src/nim_status_client.nim | 3 + storybook/CMakeLists.txt | 7 +- storybook/main.cpp | 11 + storybook/pages/WalletConnectPage.qml | 58 + .../tests/tst_DerivationPathInput.qml | 20 - storybook/systemutils.cpp | 9 + storybook/systemutils.h | 13 + ui/StatusQ/src/stringutilsinternal.cpp | 24 +- .../views/walletconnect/WalletConnect.qml | 141 + .../views/walletconnect/WalletConnectSDK.qml | 208 + .../Wallet/views/walletconnect/qmldir | 1 + .../Wallet/views/walletconnect/sdk/README.md | 58 + .../walletconnect/sdk/generated/bundle.js | 2 + .../sdk/generated/bundle.js.LICENSE.txt | 23 + .../views/walletconnect/sdk/package-lock.json | 4585 +++++++++++++++++ .../views/walletconnect/sdk/package.json | 20 + .../views/walletconnect/sdk/src/index.js | 197 + .../views/walletconnect/sdk/webpack.config.js | 22 + ui/generate-rcc.go | 2 +- vendor/DOtherSide/lib/CMakeLists.txt | 6 +- .../lib/include/DOtherSide/DOtherSide.h | 2 + vendor/DOtherSide/lib/meson.build | 2 +- vendor/DOtherSide/lib/src/DOtherSide.cpp | 6 + .../DOtherSide/lib/src/Status/AppDelegate.mm | 5 +- vendor/nimqml | 2 +- 28 files changed, 5401 insertions(+), 34 deletions(-) create mode 100644 storybook/pages/WalletConnectPage.qml create mode 100644 storybook/systemutils.cpp create mode 100644 storybook/systemutils.h create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/WalletConnect.qml create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/WalletConnectSDK.qml create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/qmldir create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/README.md create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/generated/bundle.js create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/generated/bundle.js.LICENSE.txt create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/package-lock.json create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/package.json create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/src/index.js create mode 100644 ui/app/AppLayouts/Wallet/views/walletconnect/sdk/webpack.config.js diff --git a/Makefile b/Makefile index fa58f8f4c6..94d5af2082 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ ifneq ($(detected_OS),Windows) endif DOTHERSIDE_LIBFILE := vendor/DOtherSide/build/lib/libDOtherSideStatic.a # order matters here, due to "-Wl,-as-needed" - NIM_PARAMS += --passL:"$(DOTHERSIDE_LIBFILE)" --passL:"$(shell PKG_CONFIG_PATH="$(QT5_PCFILEDIR)" pkg-config --libs Qt5Core Qt5Qml Qt5Gui Qt5Quick Qt5QuickControls2 Qt5Widgets Qt5Svg Qt5Multimedia)" + NIM_PARAMS += --passL:"$(DOTHERSIDE_LIBFILE)" --passL:"$(shell PKG_CONFIG_PATH="$(QT5_PCFILEDIR)" pkg-config --libs Qt5Core Qt5Qml Qt5Gui Qt5Quick Qt5QuickControls2 Qt5Widgets Qt5Svg Qt5Multimedia Qt5WebView)" else NIM_EXTRA_PARAMS := --passL:"-lsetupapi -lhid" endif diff --git a/resources/Entitlements.plist b/resources/Entitlements.plist index 8eec77611c..2c1d24a00c 100644 --- a/resources/Entitlements.plist +++ b/resources/Entitlements.plist @@ -10,5 +10,9 @@ applinks:status.app --> + + + com.apple.security.cs.allow-jit + diff --git a/scripts/sign-macos-pkg.sh b/scripts/sign-macos-pkg.sh index 09524c7e1e..9c0cbfaa54 100755 --- a/scripts/sign-macos-pkg.sh +++ b/scripts/sign-macos-pkg.sh @@ -55,7 +55,7 @@ if [[ -n "${MACOS_KEYCHAIN_FILE}" ]]; then echo -e "\n### Storing original keychain search list..." # We want to restore the normal keychains and ignore Jenkis created ones ORIG_KEYCHAIN_LIST=$(security list-keychains | grep -v -e "^/private" -e "secretFiles" | xargs) - + # The keychain file needs to be locked afterwards trap clean_up EXIT ERR diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 5dc8395c9d..88fd40debd 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -132,6 +132,9 @@ proc mainProc() = let app = newQGuiApplication() + # Required by the WalletConnectSDK view right after creating the QGuiApplication instance + initializeWebView() + let singleInstance = newSingleInstance($toMD5(DATADIR), openUri) let urlSchemeEvent = newStatusUrlSchemeEventObject() # init url manager before app controller diff --git a/storybook/CMakeLists.txt b/storybook/CMakeLists.txt index 75852e968b..155e1afaa6 100644 --- a/storybook/CMakeLists.txt +++ b/storybook/CMakeLists.txt @@ -20,7 +20,7 @@ endif() find_package( Qt5 - COMPONENTS Core Gui Quick QuickControls2 Test QuickTest Qml + COMPONENTS Core Gui Quick QuickControls2 Test QuickTest Qml WebView REQUIRED) set(STATUSQ_BUILD_SANDBOX OFF) @@ -53,6 +53,7 @@ add_library(${PROJECT_LIB} pagesmodel.h pagesmodel.cpp sectionsdecoratormodel.cpp sectionsdecoratormodel.h testsrunner.h testsrunner.cpp + systemutils.cpp systemutils.h ) add_executable( @@ -72,7 +73,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE ) target_link_libraries( - ${PROJECT_LIB} PUBLIC Qt5::Core Qt5::Gui Qt5::Quick Qt5::QuickControls2) + ${PROJECT_LIB} PUBLIC Qt5::Core Qt5::Gui Qt5::Quick Qt5::QuickControls2 Qt5::WebView) target_link_libraries( ${PROJECT_NAME} PRIVATE ${PROJECT_LIB}) @@ -87,7 +88,7 @@ add_executable( ) target_link_libraries( - PagesValidator PUBLIC Qt5::Core Qt5::Gui Qt5::Quick Qt5::QuickControls2) + PagesValidator PUBLIC Qt5::Core Qt5::Gui Qt5::Quick Qt5::QuickControls2 Qt5::WebView) add_dependencies(PagesValidator StatusQ) diff --git a/storybook/main.cpp b/storybook/main.cpp index 8aa8995470..106ca98e37 100644 --- a/storybook/main.cpp +++ b/storybook/main.cpp @@ -2,12 +2,15 @@ #include #include +#include + #include "cachecleaner.h" #include "directorieswatcher.h" #include "figmalinks.h" #include "pagesmodel.h" #include "sectionsdecoratormodel.h" #include "testsrunner.h" +#include "systemutils.h" struct PagesModelInitialized : public PagesModel { explicit PagesModelInitialized(QObject *parent = nullptr) @@ -16,6 +19,9 @@ struct PagesModelInitialized : public PagesModel { int main(int argc, char *argv[]) { + // Required by the WalletConnectSDK view + QtWebView::initialize(); + #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif @@ -79,6 +85,11 @@ int main(int argc, char *argv[]) qmlRegisterSingletonType( "Storybook", 1, 0, "TestsRunner", runnerFactory); + qmlRegisterSingletonType( + "Storybook", 1, 0, "SystemUtils", [](QQmlEngine*, QJSEngine*) { + return new SystemUtils; + }); + #ifdef Q_OS_WIN const QUrl url(QUrl::fromLocalFile(QML_IMPORT_ROOT + QStringLiteral("/main.qml"))); #else diff --git a/storybook/pages/WalletConnectPage.qml b/storybook/pages/WalletConnectPage.qml new file mode 100644 index 0000000000..2183922ade --- /dev/null +++ b/storybook/pages/WalletConnectPage.qml @@ -0,0 +1,58 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtQml 2.15 + +import StatusQ.Core 0.1 +import StatusQ.Core.Utils 0.1 +import StatusQ.Controls 0.1 +import StatusQ.Components 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Popups.Dialog 0.1 + +import Models 1.0 +import Storybook 1.0 + +import AppLayouts.Wallet.views.walletconnect 1.0 + +import SortFilterProxyModel 0.2 + +import utils 1.0 + +Item { + id: root + + // qml Splitter + SplitView { + anchors.fill: parent + + WalletConnect { + id: walletConnect + + SplitView.preferredWidth: 400 + + projectId: SystemUtils.getEnvVar("WALLET_CONNECT_PROJECT_ID") + backgroundColor: Theme.palette.statusAppLayout.backgroundColor + + clip: true + } + + ColumnLayout { + id: optionsSpace + + RowLayout { + id: optionsHeader + + Text { text: "projectId" } + Text { + text: walletConnect.projectId.substring(0, 3) + "..." + walletConnect.projectId.substring(walletConnect.projectId.length - 3) + font.bold: true + } + } + // spacer + ColumnLayout {} + } + } +} + +// category: Popups diff --git a/storybook/qmlTests/tests/tst_DerivationPathInput.qml b/storybook/qmlTests/tests/tst_DerivationPathInput.qml index 4ae1655c3c..6159609091 100644 --- a/storybook/qmlTests/tests/tst_DerivationPathInput.qml +++ b/storybook/qmlTests/tests/tst_DerivationPathInput.qml @@ -161,24 +161,4 @@ Item { verify(/^