Compare commits
219 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef4a982dc | ||
|
|
f93c67740c | ||
|
|
4b8e0f36ab | ||
|
|
c247b96c4a | ||
|
|
085f4af1dc | ||
|
|
49a6c8ba9c | ||
|
|
df9b35e947 | ||
|
|
96b6e5972f | ||
|
|
b801ef594b | ||
|
|
ff0c068cb8 | ||
|
|
1b119eb8f5 | ||
|
|
6a8a123da8 | ||
|
|
6f2aafdd6c | ||
|
|
57fefba386 | ||
|
|
64a6ca7fc7 | ||
|
|
8b356605b4 | ||
|
|
131154ba80 | ||
|
|
fa55575973 | ||
|
|
0851609840 | ||
|
|
b1f1080111 | ||
|
|
6c3b1c56f8 | ||
|
|
210f3e301b | ||
|
|
c73bc32f8e | ||
|
|
62878a042c | ||
|
|
84c6d35634 | ||
|
|
0f94f1b416 | ||
|
|
0f43fbe6d4 | ||
|
|
10e28c5ba4 | ||
|
|
a3c25afb66 | ||
|
|
21831c9b24 | ||
|
|
d1f9b0eaf0 | ||
|
|
b0d5584d53 | ||
|
|
bbe4fe3763 | ||
|
|
87f9d28fea | ||
|
|
58ddd8c2bc | ||
|
|
264d3694c5 | ||
|
|
79d56af921 | ||
|
|
e668995673 | ||
|
|
8b2fe88824 | ||
|
|
80830584d1 | ||
|
|
ae21f79040 | ||
|
|
b7ab50759a | ||
|
|
91959d3e2e | ||
|
|
7184c45043 | ||
|
|
fc261502d1 | ||
|
|
f796be37ce | ||
|
|
fa3b49ca91 | ||
|
|
9e6f116bc9 | ||
|
|
b70a9842f5 | ||
|
|
064c145aa8 | ||
|
|
e197544903 | ||
|
|
ca1e66453e | ||
|
|
c795d4b2f1 | ||
|
|
cb28263cb1 | ||
|
|
d2768a4f6b | ||
|
|
c6af02353e | ||
|
|
425623d6d3 | ||
|
|
2a9c6c662f | ||
|
|
bd30c3babb | ||
|
|
aac43e8a1a | ||
|
|
b576b9e4f6 | ||
|
|
8199ef004d | ||
|
|
b26f38d37e | ||
|
|
87f25c49ad | ||
|
|
160eb8e074 | ||
|
|
39f0323a81 | ||
|
|
e9a8b042ab | ||
|
|
07e7628182 | ||
|
|
3d07d80648 | ||
|
|
887688f092 | ||
|
|
0184c3a314 | ||
|
|
b951338642 | ||
|
|
d514845e4a | ||
|
|
9bed4554eb | ||
|
|
a10d41642a | ||
|
|
c0b3789fda | ||
|
|
85d0c7575c | ||
|
|
d4de52974b | ||
|
|
96cca79b70 | ||
|
|
432650008c | ||
|
|
3f3eb643e4 | ||
|
|
6ba617d84f | ||
|
|
1c23ca3a76 | ||
|
|
17f657673f | ||
|
|
35d1546110 | ||
|
|
c4bebbf173 | ||
|
|
a67865b969 | ||
|
|
38a63ddcdb | ||
|
|
17dfd2e9ed | ||
|
|
49d8a6b91d | ||
|
|
953cb8d302 | ||
|
|
e1d3cf1b98 | ||
|
|
b1ee39cd28 | ||
|
|
3031e7c37f | ||
|
|
ab69b9c9b2 | ||
|
|
837f332ac9 | ||
|
|
59f189d264 | ||
|
|
8229979cec | ||
|
|
559106174e | ||
|
|
6e0b5e2be5 | ||
|
|
e16f8c8d07 | ||
|
|
c87482db9c | ||
|
|
7b729fc885 | ||
|
|
5977e61a02 | ||
|
|
372a591ac7 | ||
|
|
cddf3c3cdb | ||
|
|
20c4516c8e | ||
|
|
3ba976638f | ||
|
|
9b7bca6116 | ||
|
|
04c2d8437e | ||
|
|
bcaf9ba61d | ||
|
|
214ba8a34d | ||
|
|
434ac2182a | ||
|
|
1f5b22149c | ||
|
|
2e2ae5c88f | ||
|
|
2021d61d91 | ||
|
|
46d0b6b0ff | ||
|
|
8ae8019f5a | ||
|
|
1a6ea3302c | ||
|
|
4de4e82ee6 | ||
|
|
5da0d5768a | ||
|
|
58586ce2dc | ||
|
|
1cc9e8af49 | ||
|
|
37a5bdc331 | ||
|
|
cc4815a3db | ||
|
|
46eba838f5 | ||
|
|
b31cc36de2 | ||
|
|
76dd4fee2f | ||
|
|
55a4b67880 | ||
|
|
97fb3d4982 | ||
|
|
28f0645d9e | ||
|
|
85dff323c8 | ||
|
|
0468e0e43a | ||
|
|
2cc3ebd315 | ||
|
|
377a1a9680 | ||
|
|
877f822de0 | ||
|
|
0feef2268d | ||
|
|
002fe8eefa | ||
|
|
1dba06a7ff | ||
|
|
838b0179e5 | ||
|
|
b12ad939ad | ||
|
|
74fbf77f62 | ||
|
|
211ef24d18 | ||
|
|
a2e0ea4faf | ||
|
|
6ab104ead7 | ||
|
|
62748b6121 | ||
|
|
8bbf2bfcbb | ||
|
|
de81af0e8d | ||
|
|
346913f3db | ||
|
|
fd8983a7ff | ||
|
|
4ef5ca5721 | ||
|
|
119deb4e82 | ||
|
|
ea92f3f272 | ||
|
|
9c383bcc24 | ||
|
|
4fba8e654d | ||
|
|
14383a1922 | ||
|
|
1610b93975 | ||
|
|
8ece450f18 | ||
|
|
ced654707d | ||
|
|
ef561949ca | ||
|
|
da63ab2e05 | ||
|
|
ddd95f73b4 | ||
|
|
08e386f63f | ||
|
|
bf324ec2d9 | ||
|
|
e9afaa9cc8 | ||
|
|
78e3b947d1 | ||
|
|
05b4a3dd6b | ||
|
|
c2f706a28a | ||
|
|
4df925e8a8 | ||
|
|
adf88c63ec | ||
|
|
c2545e226b | ||
|
|
5c7c4dde14 | ||
|
|
2bbb6adb4f | ||
|
|
493105b457 | ||
|
|
2bf0dd840f | ||
|
|
0f67580e8f | ||
|
|
599033815a | ||
|
|
de49ddcf5b | ||
|
|
d752117ed3 | ||
|
|
fa9285a108 | ||
|
|
9194522b56 | ||
|
|
11a16952c5 | ||
|
|
a959919b8a | ||
|
|
6f88ad0a13 | ||
|
|
cb169f11d4 | ||
|
|
98b81fa1ee | ||
|
|
a6fadd2140 | ||
|
|
09bf4a1e71 | ||
|
|
f44fcb4459 | ||
|
|
c5d598f401 | ||
|
|
9476a9880c | ||
|
|
487f2ceecb | ||
|
|
d0950499da | ||
|
|
56df20ba27 | ||
|
|
41b827b65d | ||
|
|
0b6ceab25b | ||
|
|
2566f445b2 | ||
|
|
9199f95af5 | ||
|
|
f2b4e1ea3e | ||
|
|
621c11925b | ||
|
|
a4cc91cca2 | ||
|
|
db4123ccb5 | ||
|
|
98f8f194cd | ||
|
|
f8a3a26e0d | ||
|
|
f7792b72bf | ||
|
|
d160828cda | ||
|
|
e85b51e1c2 | ||
|
|
6b926b3199 | ||
|
|
008a38aae2 | ||
|
|
70e3c2d3ad | ||
|
|
817b015335 | ||
|
|
3e159e0ed6 | ||
|
|
23b74a3412 | ||
|
|
0ded8dcf25 | ||
|
|
06fe68b56c | ||
|
|
b811d6a84f | ||
|
|
841f061520 | ||
|
|
f30570d54b | ||
|
|
20579049fa |
24
.github/workflows/build.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: install dependencies
|
||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm libsodium miniupnpc ldns expat libunwind-headers protobuf qt5 pkg-config
|
||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm libsodium miniupnpc expat libunwind-headers protobuf qt5 pkg-config
|
||||
- name: build
|
||||
run: DEV_MODE=ON make release -j3
|
||||
- name: test qml
|
||||
@@ -52,9 +52,12 @@ jobs:
|
||||
- uses: eine/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-unbound git mingw-w64-x86_64-qt5 mingw-w64-x86_64-libgcrypt
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-pcre mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-unbound git mingw-w64-x86_64-qt5 mingw-w64-x86_64-libgcrypt
|
||||
- name: build
|
||||
run: DEV_MODE=ON make release-win64 -j2
|
||||
- name: deploy
|
||||
run: make deploy
|
||||
working-directory: build/release
|
||||
- name: test qml
|
||||
run: build/release/bin/monero-wallet-gui --test-qml
|
||||
|
||||
@@ -65,7 +68,7 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: install dependencies
|
||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm miniupnpc ldns expat libunwind-headers protobuf pkg-config python3 p7zip aria2
|
||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm miniupnpc expat libunwind-headers protobuf pkg-config python3 p7zip aria2
|
||||
- name: install dependencies
|
||||
run: pip3 install defusedxml
|
||||
- name: download qt
|
||||
@@ -92,7 +95,7 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: satackey/action-docker-layer-caching@v0.0.10
|
||||
- uses: satackey/action-docker-layer-caching@v0.0.11
|
||||
if: "!startsWith(github.ref, 'refs/tags/v')"
|
||||
continue-on-error: true
|
||||
with:
|
||||
@@ -100,7 +103,7 @@ jobs:
|
||||
restore-keys: |
|
||||
docker-linux-static-
|
||||
- name: install dependencies
|
||||
run: sudo apt -y install xvfb libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xkb1 libxkbcommon-x11-0
|
||||
run: sudo apt -y install xvfb libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xkb1 libxcb-shape0 libxkbcommon-x11-0
|
||||
- name: prepare build environment
|
||||
run: docker build --tag monero:build-env-linux --build-arg THREADS=3 --file Dockerfile.linux .
|
||||
- name: build
|
||||
@@ -122,7 +125,7 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: satackey/action-docker-layer-caching@v0.0.10
|
||||
- uses: satackey/action-docker-layer-caching@v0.0.11
|
||||
if: "!startsWith(github.ref, 'refs/tags/v')"
|
||||
continue-on-error: true
|
||||
with:
|
||||
@@ -148,10 +151,19 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: satackey/action-docker-layer-caching@v0.0.11
|
||||
if: "!startsWith(github.ref, 'refs/tags/v')"
|
||||
continue-on-error: true
|
||||
with:
|
||||
key: docker-android-static-{hash}
|
||||
restore-keys: |
|
||||
docker-android-static-
|
||||
- name: prepare build environment
|
||||
run: docker build --tag monero:build-env-android --build-arg THREADS=3 --file Dockerfile.android .
|
||||
- name: build
|
||||
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -e THREADS=3 monero:build-env-android
|
||||
- name: Remove obsolete docker layers
|
||||
run: docker images -a | grep none | awk '{ print $3; }' | xargs docker rmi || true
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ github.job }}
|
||||
|
||||
@@ -3,15 +3,17 @@ project(monero-gui)
|
||||
|
||||
message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
|
||||
|
||||
set(VERSION_MAJOR "17")
|
||||
set(VERSION_MINOR "3")
|
||||
set(VERSION_REVISION "0")
|
||||
set(VERSION_MAJOR "18")
|
||||
set(VERSION_MINOR "1")
|
||||
set(VERSION_REVISION "2")
|
||||
set(VERSION "0.${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
|
||||
|
||||
option(STATIC "Link libraries statically, requires static Qt")
|
||||
|
||||
option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
||||
option(WITH_SCANNER "Enable webcam QR scanner" OFF)
|
||||
option(WITH_DESKTOP_ENTRY "Ask to install desktop entry on first startup" ON)
|
||||
option(WITH_UPDATER "Regularly check for new updates" ON)
|
||||
option(DEV_MODE "Checkout latest monero master on build" OFF)
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
|
||||
@@ -19,10 +21,6 @@ include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckLinkerFlag)
|
||||
|
||||
if(DEBUG)
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
endif()
|
||||
|
||||
set(BUILD_GUI_DEPS ON)
|
||||
set(BUILD_64 ON CACHE BOOL "Build 64-bit binaries")
|
||||
|
||||
@@ -75,36 +73,10 @@ endif()
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# force version update
|
||||
function (monero_gui_add_library_with_deps)
|
||||
cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
|
||||
source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
|
||||
|
||||
# Define a ("virtual") object library and an actual library that links those
|
||||
# objects together. The virtual libraries can be arbitrarily combined to link
|
||||
# any subset of objects into one library archive. This is used for releasing
|
||||
# libwallet, which combines multiple components.
|
||||
set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
|
||||
add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
|
||||
add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
|
||||
if (MONERO_ADD_LIBRARY_DEPENDS)
|
||||
add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
|
||||
endif()
|
||||
set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
|
||||
target_compile_definitions(${objlib}
|
||||
PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
|
||||
endfunction ()
|
||||
|
||||
function (monero_gui_add_library name)
|
||||
monero_gui_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
|
||||
endfunction()
|
||||
|
||||
include_directories(${EASYLOGGING_INCLUDE})
|
||||
link_directories(${EASYLOGGING_LIBRARY_DIRS})
|
||||
|
||||
|
||||
include(VersionGui)
|
||||
monero_gui_add_library(gui_version SOURCES version.js DEPENDS genversiongui)
|
||||
|
||||
message(STATUS "${CMAKE_MODULE_PATH}")
|
||||
|
||||
@@ -112,6 +84,14 @@ if(WITH_SCANNER)
|
||||
add_definitions(-DWITH_SCANNER)
|
||||
endif()
|
||||
|
||||
if(WITH_DESKTOP_ENTRY)
|
||||
add_definitions(-DWITH_DESKTOP_ENTRY)
|
||||
endif()
|
||||
|
||||
if(WITH_UPDATER)
|
||||
add_definitions(-DWITH_UPDATER)
|
||||
endif()
|
||||
|
||||
# Sodium
|
||||
find_library(SODIUM_LIBRARY sodium)
|
||||
message(STATUS "libsodium: libraries at ${SODIUM_LIBRARY}")
|
||||
@@ -372,10 +352,7 @@ endif()
|
||||
list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
if(APPLE)
|
||||
include_directories(SYSTEM /usr/include/malloc)
|
||||
if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
|
||||
11
DEPLOY.md
@@ -8,11 +8,16 @@ Use macOS 10.12 - 10.13 for better backwards compability.
|
||||
|
||||
3. `git clone --recursive -b v0.X.Y.Z --depth 1 https://github.com/monero-project/monero-gui`
|
||||
|
||||
4. `CMAKE_PREFIX_PATH=~/Qt5.12.8/5.12.8/clang_64 make release`
|
||||
4. Compile `monero-wallet-gui.app`
|
||||
|
||||
5. `cd build/release && make deploy`
|
||||
```
|
||||
mkdir build && cd build
|
||||
cmake -D CMAKE_BUILD_TYPE=Release -D ARCH=default -D CMAKE_PREFIX_PATH=~/Qt5.12.8/5.12.8/clang_64 ..
|
||||
make
|
||||
make deploy
|
||||
```
|
||||
|
||||
6. Replace the `monerod` binary inside `monero-wallet-gui.app/Contents/MacOS/` with one built using deterministic builds / gitian.
|
||||
5. Replace the `monerod` binary inside `monero-wallet-gui.app/Contents/MacOS/` with one built using deterministic builds / gitian.
|
||||
|
||||
## Codesigning and notarizing
|
||||
|
||||
|
||||
@@ -1,47 +1,50 @@
|
||||
FROM debian:stretch
|
||||
FROM debian:buster
|
||||
|
||||
ARG THREADS=1
|
||||
ARG ANDROID_NDK_REVISION=21d
|
||||
ARG ANDROID_NDK_HASH=bcf4023eb8cb6976a4c7cff0a8a8f145f162bf4d
|
||||
ARG ANDROID_SDK_REVISION=4333796
|
||||
ARG ANDROID_SDK_HASH=92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
|
||||
ARG QT_VERSION=5.15.2
|
||||
ARG ANDROID_NDK_REVISION=21e
|
||||
ARG ANDROID_NDK_HASH=c3ebc83c96a4d7f539bd72c241b2be9dcd29bda9
|
||||
ARG ANDROID_SDK_REVISION=7302050_latest
|
||||
ARG ANDROID_SDK_HASH=7a00faadc0864f78edd8f4908a629a46d622375cbe2e5814e82934aebecdb622
|
||||
ARG QT_VERSION=v5.15.6-lts-lgpl
|
||||
|
||||
WORKDIR /opt/android
|
||||
ENV WORKDIR=/opt/android
|
||||
|
||||
ENV ANDROID_NATIVE_API_LEVEL=28
|
||||
ENV ANDROID_NATIVE_API_LEVEL=29
|
||||
ENV ANDROID_API=android-${ANDROID_NATIVE_API_LEVEL}
|
||||
ENV ANDROID_CLANG=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang
|
||||
ENV ANDROID_CLANGPP=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang++
|
||||
ENV ANDROID_NDK_ROOT=${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION}
|
||||
ENV ANDROID_SDK_ROOT=${WORKDIR}/tools
|
||||
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
|
||||
ENV ANDROID_SDK_ROOT=${WORKDIR}/cmdline-tools
|
||||
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
|
||||
ENV PATH=${JAVA_HOME}/bin:${PATH}
|
||||
ENV PREFIX=${WORKDIR}/prefix
|
||||
ENV TOOLCHAIN_DIR=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y ant automake build-essential ca-certificates-java file gettext git libc6 libncurses5 \
|
||||
libssl-dev libstdc++6 libtinfo5 libtool libz1 openjdk-8-jdk-headless openjdk-8-jre-headless pkg-config python3 \
|
||||
libssl-dev libstdc++6 libtinfo5 libtool libz1 openjdk-11-jdk-headless openjdk-11-jre-headless pkg-config python3 \
|
||||
unzip wget
|
||||
|
||||
RUN wget -q https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
|
||||
&& unzip -q sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
|
||||
&& rm -f sdk-tools-linux-${ANDROID_SDK_REVISION}.zip
|
||||
RUN PACKAGE_NAME=commandlinetools-linux-${ANDROID_SDK_REVISION}.zip \
|
||||
&& wget -q https://dl.google.com/android/repository/${PACKAGE_NAME} \
|
||||
&& echo "${ANDROID_SDK_HASH} ${PACKAGE_NAME}" | sha256sum -c \
|
||||
&& unzip -q ${PACKAGE_NAME} \
|
||||
&& rm -f ${PACKAGE_NAME}
|
||||
|
||||
RUN wget -q https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
|
||||
&& unzip -q android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
|
||||
&& rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip
|
||||
RUN PACKAGE_NAME=android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
|
||||
&& wget -q https://dl.google.com/android/repository/${PACKAGE_NAME} \
|
||||
&& echo "${ANDROID_NDK_HASH} ${PACKAGE_NAME}" | sha1sum -c \
|
||||
&& unzip -q ${PACKAGE_NAME} \
|
||||
&& rm -f ${PACKAGE_NAME}
|
||||
|
||||
RUN cd ${ANDROID_SDK_ROOT} && echo y | ./bin/sdkmanager "platform-tools" "platforms;${ANDROID_API}" "tools" > /dev/null
|
||||
RUN cp -r ${WORKDIR}/platforms ${WORKDIR}/platform-tools ${ANDROID_SDK_ROOT}
|
||||
RUN echo y | ${ANDROID_SDK_ROOT}/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "build-tools;28.0.3" "platforms;${ANDROID_API}" "tools" > /dev/null
|
||||
|
||||
ENV HOST_PATH=${PATH}
|
||||
ENV PATH=${TOOLCHAIN_DIR}/aarch64-linux-android/bin:${TOOLCHAIN_DIR}/bin:${PATH}
|
||||
|
||||
ARG ZLIB_VERSION=1.2.11
|
||||
ARG ZLIB_HASH=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
|
||||
ARG ZLIB_VERSION=1.2.12
|
||||
ARG ZLIB_HASH=91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9
|
||||
RUN wget -q https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \
|
||||
&& echo "${ZLIB_HASH} zlib-${ZLIB_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf zlib-${ZLIB_VERSION}.tar.gz \
|
||||
@@ -76,7 +79,6 @@ RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 \
|
||||
-skip qtpurchasing \
|
||||
-skip qtgamepad -skip qtscript -skip qtdoc \
|
||||
-no-warnings-are-errors \
|
||||
&& sed -i '213,215d' qtbase/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h \
|
||||
&& PATH=${HOST_PATH} make -j${THREADS} \
|
||||
&& PATH=${HOST_PATH} make -j${THREADS} install \
|
||||
&& cd qttools/src/linguist/lrelease \
|
||||
@@ -99,7 +101,7 @@ RUN wget -q http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz
|
||||
ARG BOOST_VERSION=1_74_0
|
||||
ARG BOOST_VERSION_DOT=1.74.0
|
||||
ARG BOOST_HASH=83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1
|
||||
RUN wget -q https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
RUN wget -q https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
|
||||
@@ -115,8 +117,8 @@ RUN wget -q https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSIO
|
||||
install -j${THREADS} \
|
||||
&& rm -rf $(pwd)
|
||||
|
||||
ARG OPENSSL_VERSION=1.1.1g
|
||||
ARG OPENSSL_HASH=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
|
||||
ARG OPENSSL_VERSION=1.1.1q
|
||||
ARG OPENSSL_HASH=d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca
|
||||
RUN wget -q https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
@@ -143,8 +145,8 @@ RUN wget https://github.com/libexpat/libexpat/releases/download/R_2_4_1/expat-${
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
ARG UNBOUND_VERSION=1.13.2
|
||||
ARG UNBOUND_HASH=0a13b547f3b92a026b5ebd0423f54c991e5718037fd9f72445817f6a040e1a83
|
||||
ARG UNBOUND_VERSION=1.16.2
|
||||
ARG UNBOUND_HASH=2e32f283820c24c51ca1dd8afecfdb747c7385a137abe865c99db4b257403581
|
||||
RUN wget https://www.nlnetlabs.nl/downloads/unbound/unbound-${UNBOUND_VERSION}.tar.gz && \
|
||||
echo "${UNBOUND_HASH} unbound-${UNBOUND_VERSION}.tar.gz" | sha256sum -c && \
|
||||
tar -xzf unbound-${UNBOUND_VERSION}.tar.gz && \
|
||||
@@ -155,8 +157,8 @@ RUN wget https://www.nlnetlabs.nl/downloads/unbound/unbound-${UNBOUND_VERSION}.t
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
ARG ZMQ_VERSION=v4.3.3
|
||||
ARG ZMQ_HASH=04f5bbedee58c538934374dc45182d8fc5926fa3
|
||||
ARG ZMQ_VERSION=v4.3.4
|
||||
ARG ZMQ_HASH=4097855ddaaa65ed7b5e8cb86d143842a594eebd
|
||||
RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} --depth 1 \
|
||||
&& cd libzmq \
|
||||
&& git checkout ${ZMQ_HASH} \
|
||||
@@ -178,33 +180,27 @@ RUN set -ex \
|
||||
&& make -j${THREADS} install \
|
||||
&& rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
|
||||
RUN git clone -b libgpg-error-1.41 --depth 1 git://git.gnupg.org/libgpg-error.git \
|
||||
&& cd libgpg-error \
|
||||
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
|
||||
&& git reset --hard 98032624ae89a67ee6fe3b1db5d95032e681d163 \
|
||||
&& ./autogen.sh \
|
||||
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --host=aarch64-linux-android --prefix=${PREFIX} --disable-rpath --disable-shared --enable-static --disable-doc --disable-tests \
|
||||
&& PATH=${TOOLCHAIN_DIR}/bin:${HOST_PATH} make -j${THREADS} \
|
||||
&& make -j${THREADS} install \
|
||||
&& rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b libgcrypt-1.8.5 --depth 1 git://git.gnupg.org/libgcrypt.git \
|
||||
RUN git clone -b libgcrypt-1.10.1 --depth 1 git://git.gnupg.org/libgcrypt.git \
|
||||
&& cd libgcrypt \
|
||||
&& git reset --hard 56606331bc2a80536db9fc11ad53695126007298 \
|
||||
&& git reset --hard ae0e567820c37f9640440b3cff77d7c185aa6742 \
|
||||
&& ./autogen.sh \
|
||||
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --host=aarch64-linux-android --prefix=${PREFIX} --with-gpg-error-prefix=${PREFIX} --disable-shared --enable-static --disable-doc --disable-tests \
|
||||
&& PATH=${TOOLCHAIN_DIR}/bin:${HOST_PATH} make -j${THREADS} \
|
||||
&& make -j${THREADS} install \
|
||||
&& rm -rf $(pwd)
|
||||
|
||||
RUN cd tools \
|
||||
&& wget -q http://dl-ssl.google.com/android/repository/tools_r25.2.5-linux.zip \
|
||||
&& unzip -q tools_r25.2.5-linux.zip \
|
||||
&& rm -f tools_r25.2.5-linux.zip \
|
||||
&& echo y | ${ANDROID_SDK_ROOT}/tools/android update sdk --no-ui --all --filter build-tools-28.0.3
|
||||
|
||||
RUN git clone -b v3.19.7 --depth 1 https://github.com/Kitware/CMake \
|
||||
RUN git clone -b v3.24.2 --depth 1 https://github.com/Kitware/CMake \
|
||||
&& cd CMake \
|
||||
&& git reset --hard 22612dd53a46c7f9b4c3f4b7dbe5c78f9afd9581 \
|
||||
&& git reset --hard 31f835410efeea50acd43512eb9e5646a26ea177 \
|
||||
&& PATH=${HOST_PATH} ./bootstrap \
|
||||
&& PATH=${HOST_PATH} make -j${THREADS} \
|
||||
&& PATH=${HOST_PATH} make -j${THREADS} install \
|
||||
@@ -226,7 +222,9 @@ CMD set -ex \
|
||||
-DBoost_USE_STATIC_RUNTIME=ON \
|
||||
-DLRELEASE_PATH="${PREFIX}/bin" \
|
||||
-DQT_ANDROID_APPLICATION_BINARY="monero-wallet-gui" \
|
||||
-DANDROID_SDK="${ANDROID_SDK_ROOT}" \
|
||||
-DWITH_SCANNER=ON \
|
||||
-DWITH_DESKTOP_ENTRY=OFF \
|
||||
../../.. \
|
||||
&& PATH=${HOST_PATH} make generate_translations_header \
|
||||
&& make -j${THREADS} -C src \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
ARG THREADS=1
|
||||
ARG QT_VERSION=5.15.2
|
||||
ARG QT_VERSION=v5.15.6-lts-lgpl
|
||||
|
||||
ENV CFLAGS="-fPIC"
|
||||
ENV CPPFLAGS="-fPIC"
|
||||
@@ -55,7 +55,7 @@ RUN git clone -b 0.4.0 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-
|
||||
git reset --hard acf790d7752f36e450d476ad79807d4012ec863b && \
|
||||
git submodule init && \
|
||||
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
|
||||
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
|
||||
git -C m4 reset --hard c617eee22ae5c285e79e81ec39ce96862fd3262f && \
|
||||
./autogen.sh --enable-shared --disable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
@@ -66,7 +66,7 @@ RUN git clone -b 0.4.0 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-
|
||||
git reset --hard d882052fb2ce439c6483fce944ba8f16f7294639 && \
|
||||
git submodule init && \
|
||||
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
|
||||
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
|
||||
git -C m4 reset --hard c617eee22ae5c285e79e81ec39ce96862fd3262f && \
|
||||
./autogen.sh --enable-shared --disable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
@@ -77,7 +77,7 @@ RUN git clone -b 0.4.0 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-
|
||||
git reset --hard 0e51ee5570a6a80bdf98770b975dfe8a57f4eeb1 && \
|
||||
git submodule init && \
|
||||
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
|
||||
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
|
||||
git -C m4 reset --hard c617eee22ae5c285e79e81ec39ce96862fd3262f && \
|
||||
./autogen.sh --enable-shared --disable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
@@ -88,7 +88,7 @@ RUN git clone -b 0.3.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-
|
||||
git reset --hard 0317caf63de532fd7a0493ed6afa871a67253747 && \
|
||||
git submodule init && \
|
||||
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
|
||||
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
|
||||
git -C m4 reset --hard c617eee22ae5c285e79e81ec39ce96862fd3262f && \
|
||||
./autogen.sh --enable-shared --disable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
@@ -99,7 +99,7 @@ RUN git clone -b 0.4.1 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-
|
||||
git reset --hard 24eb17df2e1245885e72c9d4bbb0a0f69f0700f2 && \
|
||||
git submodule init && \
|
||||
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
|
||||
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
|
||||
git -C m4 reset --hard c617eee22ae5c285e79e81ec39ce96862fd3262f && \
|
||||
./autogen.sh --enable-shared --disable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
@@ -155,40 +155,40 @@ RUN git clone -b release-64-2 --depth 1 https://github.com/unicode-org/icu && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN wget https://downloads.sourceforge.net/project/boost/boost/1.73.0/boost_1_73_0.tar.gz && \
|
||||
echo "9995e192e68528793755692917f9eb6422f3052a53c5e13ba278a228af6c7acf boost_1_73_0.tar.gz" | sha256sum -c && \
|
||||
tar -xzf boost_1_73_0.tar.gz && \
|
||||
rm boost_1_73_0.tar.gz && \
|
||||
cd boost_1_73_0 && \
|
||||
RUN wget https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.gz && \
|
||||
echo "4b2136f98bdd1f5857f1c3dea9ac2018effe65286cf251534b6ae20cc45e1847 boost_1_80_0.tar.gz" | sha256sum -c && \
|
||||
tar -xzf boost_1_80_0.tar.gz && \
|
||||
rm boost_1_80_0.tar.gz && \
|
||||
cd boost_1_80_0 && \
|
||||
./bootstrap.sh && \
|
||||
./b2 --with-atomic --with-system --with-filesystem --with-thread --with-date_time --with-chrono --with-regex --with-serialization --with-program_options --with-locale variant=release link=static runtime-link=static cflags="${CFLAGS}" cxxflags="${CXXFLAGS}" install -a --prefix=/usr && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz && \
|
||||
echo "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46 openssl-1.1.1g.tar.gz" | sha256sum -c && \
|
||||
tar -xzf openssl-1.1.1g.tar.gz && \
|
||||
rm openssl-1.1.1g.tar.gz && \
|
||||
cd openssl-1.1.1g && \
|
||||
RUN wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz && \
|
||||
echo "d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca openssl-1.1.1q.tar.gz" | sha256sum -c && \
|
||||
tar -xzf openssl-1.1.1q.tar.gz && \
|
||||
rm openssl-1.1.1q.tar.gz && \
|
||||
cd openssl-1.1.1q && \
|
||||
./config no-asm no-shared no-zlib-dynamic --prefix=/usr --openssldir=/usr && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN wget https://github.com/libexpat/libexpat/releases/download/R_2_4_1/expat-2.4.1.tar.bz2 && \
|
||||
echo "2f9b6a580b94577b150a7d5617ad4643a4301a6616ff459307df3e225bcfbf40 expat-2.4.1.tar.bz2" | sha256sum -c && \
|
||||
tar -xf expat-2.4.1.tar.bz2 && \
|
||||
rm expat-2.4.1.tar.bz2 && \
|
||||
cd expat-2.4.1 && \
|
||||
RUN wget https://github.com/libexpat/libexpat/releases/download/R_2_4_8/expat-2.4.8.tar.bz2 && \
|
||||
echo "a247a7f6bbb21cf2ca81ea4cbb916bfb9717ca523631675f99b3d4a5678dcd16 expat-2.4.8.tar.bz2" | sha256sum -c && \
|
||||
tar -xf expat-2.4.8.tar.bz2 && \
|
||||
rm expat-2.4.8.tar.bz2 && \
|
||||
cd expat-2.4.8 && \
|
||||
./configure --enable-static --disable-shared --prefix=/usr && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN wget https://www.nlnetlabs.nl/downloads/unbound/unbound-1.13.2.tar.gz && \
|
||||
echo "0a13b547f3b92a026b5ebd0423f54c991e5718037fd9f72445817f6a040e1a83 unbound-1.13.2.tar.gz" | sha256sum -c && \
|
||||
tar -xzf unbound-1.13.2.tar.gz && \
|
||||
rm unbound-1.13.2.tar.gz && \
|
||||
cd unbound-1.13.2 && \
|
||||
RUN wget https://www.nlnetlabs.nl/downloads/unbound/unbound-1.16.2.tar.gz && \
|
||||
echo "2e32f283820c24c51ca1dd8afecfdb747c7385a137abe865c99db4b257403581 unbound-1.16.2.tar.gz" | sha256sum -c && \
|
||||
tar -xzf unbound-1.16.2.tar.gz && \
|
||||
rm unbound-1.16.2.tar.gz && \
|
||||
cd unbound-1.16.2 && \
|
||||
./configure --disable-shared --enable-static --without-pyunbound --with-libexpat=/usr --with-ssl=/usr --with-libevent=no --without-pythonmodule --disable-flto --with-pthreads --with-libunbound-only --with-pic && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
@@ -234,62 +234,62 @@ RUN rm /usr/lib/x86_64-linux-gnu/libX11.a && \
|
||||
cd ../../../.. && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b v1.0.23 --depth 1 https://github.com/libusb/libusb && \
|
||||
RUN git clone -b v1.0.26 --depth 1 https://github.com/libusb/libusb && \
|
||||
cd libusb && \
|
||||
git reset --hard e782eeb2514266f6738e242cdcb18e3ae1ed06fa && \
|
||||
git reset --hard 4239bc3a50014b8e6a5a2a59df1fff3b7469543b && \
|
||||
./autogen.sh --disable-shared --enable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b hidapi-0.9.0 --depth 1 https://github.com/libusb/hidapi && \
|
||||
RUN git clone -b hidapi-0.12.0 --depth 1 https://github.com/libusb/hidapi && \
|
||||
cd hidapi && \
|
||||
git reset --hard 7da5cc91fc0d2dbe4df4f08cd31f6ca1a262418f && \
|
||||
git reset --hard 76108294092c023a4ece99eb3219559cea0d5066 && \
|
||||
./bootstrap && \
|
||||
./configure --disable-shared --enable-static && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b v4.3.2 --depth 1 https://github.com/zeromq/libzmq && \
|
||||
RUN git clone -b v4.3.4 --depth 1 https://github.com/zeromq/libzmq && \
|
||||
cd libzmq && \
|
||||
git reset --hard a84ffa12b2eb3569ced199660bac5ad128bff1f0 && \
|
||||
git reset --hard 4097855ddaaa65ed7b5e8cb86d143842a594eebd && \
|
||||
./autogen.sh && \
|
||||
./configure --disable-shared --enable-static --disable-libunwind --with-libsodium && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git && \
|
||||
RUN git clone -b libgpg-error-1.45 --depth 1 git://git.gnupg.org/libgpg-error.git && \
|
||||
cd libgpg-error && \
|
||||
git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 && \
|
||||
git reset --hard dbac537e5e865fb6f3aa8596d213aa8c47a9dea1 && \
|
||||
./autogen.sh && \
|
||||
./configure --disable-shared --enable-static --disable-doc --disable-tests && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b libgcrypt-1.8.5 --depth 1 git://git.gnupg.org/libgcrypt.git && \
|
||||
RUN git clone -b libgcrypt-1.10.1 --depth 1 git://git.gnupg.org/libgcrypt.git && \
|
||||
cd libgcrypt && \
|
||||
git reset --hard 56606331bc2a80536db9fc11ad53695126007298 && \
|
||||
git reset --hard ae0e567820c37f9640440b3cff77d7c185aa6742 && \
|
||||
./autogen.sh && \
|
||||
./configure --disable-shared --enable-static --disable-doc && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b v3.10.0 --depth 1 https://github.com/protocolbuffers/protobuf && \
|
||||
RUN git clone -b v21.5 --depth 1 https://github.com/protocolbuffers/protobuf && \
|
||||
cd protobuf && \
|
||||
git reset --hard 6d4e7fd7966c989e38024a8ea693db83758944f1 && \
|
||||
git reset --hard ab840345966d0fa8e7100d771c92a73bfbadd25c && \
|
||||
./autogen.sh && \
|
||||
./configure --enable-static --disable-shared && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
rm -rf $(pwd)
|
||||
|
||||
RUN git clone -b v3.18.4 --depth 1 https://github.com/Kitware/CMake && \
|
||||
RUN git clone -b v3.24.0 --depth 1 https://github.com/Kitware/CMake && \
|
||||
cd CMake && \
|
||||
git reset --hard 3cc3d42aba879fff5e85b363ae8f21386a3f9f9b && \
|
||||
git reset --hard 4be24f031a4829db75b85062cc67125035d8831e && \
|
||||
./bootstrap && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install && \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM ubuntu:20.04
|
||||
|
||||
ARG THREADS=1
|
||||
ARG QT_VERSION=5.15.2
|
||||
ARG QT_VERSION=v5.15.6-lts-lgpl
|
||||
ENV SOURCE_DATE_EPOCH=1397818193
|
||||
|
||||
RUN apt update && \
|
||||
@@ -12,9 +12,9 @@ RUN apt update && \
|
||||
RUN update-alternatives --set x86_64-w64-mingw32-g++ $(which x86_64-w64-mingw32-g++-posix) && \
|
||||
update-alternatives --set x86_64-w64-mingw32-gcc $(which x86_64-w64-mingw32-gcc-posix)
|
||||
|
||||
RUN git clone -b v0.17.3.0 --depth 1 https://github.com/monero-project/monero && \
|
||||
RUN git clone -b v0.18.1.0 --depth 1 https://github.com/monero-project/monero && \
|
||||
cd monero && \
|
||||
git reset --hard ab18fea3500841fc312630d49ed6840b3aedb34d && \
|
||||
git reset --hard 727bc5b6878170332bf2d838f2c60d1c8dc685c8 && \
|
||||
cp -a contrib/depends / && \
|
||||
cd .. && \
|
||||
rm -rf monero
|
||||
|
||||
@@ -120,7 +120,7 @@ Rectangle {
|
||||
width: 260
|
||||
height: 135
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: MoneroComponents.Style.blackTheme ? "qrc:///images/card-background-black.png" : "qrc:///images/card-background-white.png"
|
||||
source: MoneroComponents.Style.blackTheme ? "qrc:///images/card-background-black" + (currentAccountIndex % MoneroComponents.Style.accountColors.length) + ".png" : "qrc:///images/card-background-white.png"
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
@@ -360,7 +360,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Account") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "T" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "T" + translationManager.emptyString
|
||||
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
@@ -382,7 +382,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Send") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "S" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "S" + translationManager.emptyString
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
parent.previousButton = transferButton
|
||||
@@ -404,7 +404,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Address book") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "B" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "B" + translationManager.emptyString
|
||||
under: transferButton
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
@@ -426,7 +426,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Receive") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "R" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "R" + translationManager.emptyString
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
parent.previousButton = receiveButton
|
||||
@@ -448,7 +448,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Transactions") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "H" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "H" + translationManager.emptyString
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
parent.previousButton = historyButton
|
||||
@@ -470,7 +470,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Advanced") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "D" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "D" + translationManager.emptyString
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
parent.previousButton = advancedButton
|
||||
@@ -491,7 +491,7 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Settings") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌘" : qsTr("Ctrl+")) + "E" + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "E" + translationManager.emptyString
|
||||
onClicked: {
|
||||
parent.previousButton.checked = false
|
||||
parent.previousButton = settingsButton
|
||||
|
||||
6
Makefile
@@ -48,9 +48,7 @@ release:
|
||||
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D DEV_MODE=$(or ${DEV_MODE},OFF) -DMANUAL_SUBMODULES=${MANUAL_SUBMODULES} -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
|
||||
release-linux-armv8:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release
|
||||
cmake -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="armv8-a" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="linux-armv8" $(topdir) && $(MAKE)
|
||||
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="armv8-a" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="linux-armv8" $(topdir) && $(MAKE)
|
||||
|
||||
release-linux-ppc64le:
|
||||
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D DEV_MODE=$(or ${DEV_MODE},OFF) -DMANUAL_SUBMODULES=${MANUAL_SUBMODULES} -D ARCH="ppc64le" -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
@@ -63,7 +61,7 @@ debug-static-win64:
|
||||
|
||||
debug-static-mac64:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -D STATIC=ON -D DEV_MODE=$(or ${DEV_MODE},ON) -DMANUAL_SUBMODULES=${MANUAL_SUBMODULES} -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
|
||||
cd $(builddir)/debug && cmake -D STATIC=ON -D DEV_MODE=$(or ${DEV_MODE},ON) -DMANUAL_SUBMODULES=${MANUAL_SUBMODULES} -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
|
||||
|
||||
release-static-win64:
|
||||
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},OFF) -DMANUAL_SUBMODULES=${MANUAL_SUBMODULES} -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) -D MINGW=ON $(topdir) && $(MAKE)
|
||||
|
||||
@@ -66,7 +66,7 @@ Rectangle {
|
||||
signal paymentClicked(var recipients, string paymentId, int mixinCount, int priority, string description)
|
||||
signal sweepUnmixableClicked()
|
||||
signal generatePaymentIdInvoked()
|
||||
signal getProofClicked(string txid, string address, string message);
|
||||
signal getProofClicked(string txid, string address, string message, string amount);
|
||||
signal checkProofClicked(string txid, string address, string message, string signature);
|
||||
|
||||
Rectangle {
|
||||
|
||||
12
README.md
@@ -1,6 +1,6 @@
|
||||
# Monero GUI
|
||||
|
||||
Copyright (c) 2014-2019, The Monero Project
|
||||
Copyright (c) 2014-2022, The Monero Project
|
||||
|
||||
## Table of Contents
|
||||
* [Development resources](#development-resources)
|
||||
@@ -108,7 +108,7 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
```
|
||||
git clone --branch master --recursive https://github.com/monero-project/monero-gui.git
|
||||
```
|
||||
\* `master` - replace with the desired version tag (e.g. `v0.17.1.9`) to build the release binaries.
|
||||
\* `master` - replace with the desired version tag (e.g. `v0.18.1.2`) to build the release binaries.
|
||||
3. Prepare build environment
|
||||
```
|
||||
cd monero-gui
|
||||
@@ -131,7 +131,7 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
```
|
||||
git clone --branch master --recursive https://github.com/monero-project/monero-gui.git
|
||||
```
|
||||
\* `master` - replace with the desired version tag (e.g. `v0.17.1.9`) to build the release binaries.
|
||||
\* `master` - replace with the desired version tag (e.g. `v0.18.1.2`) to build the release binaries.
|
||||
3. Prepare build environment
|
||||
```
|
||||
cd monero-gui
|
||||
@@ -209,11 +209,11 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
|
||||
- For Debian distributions (Debian, Ubuntu, Mint, Tails...)
|
||||
|
||||
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler libgcrypt20-dev`
|
||||
`sudo apt install build-essential cmake miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler libgcrypt20-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev`
|
||||
|
||||
- For Gentoo
|
||||
|
||||
`sudo emerge app-arch/xz-utils app-doc/doxygen dev-cpp/gtest dev-libs/boost dev-libs/expat dev-libs/openssl dev-util/cmake media-gfx/graphviz net-dns/unbound net-libs/ldns net-libs/miniupnpc net-libs/zeromq sys-libs/libunwind dev-libs/libsodium dev-libs/hidapi dev-libs/libgcrypt`
|
||||
`sudo emerge app-arch/xz-utils app-doc/doxygen dev-cpp/gtest dev-libs/boost dev-libs/expat dev-libs/openssl dev-util/cmake media-gfx/graphviz net-dns/unbound net-libs/miniupnpc net-libs/zeromq sys-libs/libunwind dev-libs/libsodium dev-libs/hidapi dev-libs/libgcrypt`
|
||||
|
||||
- For Fedora
|
||||
|
||||
@@ -283,7 +283,7 @@ The executable can be found in the build/release/bin folder.
|
||||
|
||||
3. Install [monero](https://github.com/monero-project/monero) dependencies:
|
||||
|
||||
`brew install cmake openssl boost unbound hidapi zmq libpgm libsodium miniupnpc ldns expat libunwind-headers protobuf libgcrypt`
|
||||
`brew install cmake pkg-config openssl boost unbound hidapi zmq libpgm libsodium miniupnpc expat libunwind-headers protobuf libgcrypt`
|
||||
|
||||
4. Install Qt:
|
||||
|
||||
|
||||
@@ -74,19 +74,19 @@ if(APPLE OR (WIN32 AND NOT STATIC))
|
||||
)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
list(APPEND WIN_DEPLOY_DLLS
|
||||
libicudtd68.dll
|
||||
libicuind68.dll
|
||||
libicuiod68.dll
|
||||
libicutud68.dll
|
||||
libicuucd68.dll
|
||||
libicudtd71.dll
|
||||
libicuind71.dll
|
||||
libicuiod71.dll
|
||||
libicutud71.dll
|
||||
libicuucd71.dll
|
||||
)
|
||||
else() # assume release
|
||||
list(APPEND WIN_DEPLOY_DLLS
|
||||
libicudt68.dll
|
||||
libicuin68.dll
|
||||
libicuio68.dll
|
||||
libicutu68.dll
|
||||
libicuuc68.dll
|
||||
libicudt71.dll
|
||||
libicuin71.dll
|
||||
libicuio71.dll
|
||||
libicutu71.dll
|
||||
libicuuc71.dll
|
||||
)
|
||||
endif()
|
||||
list(TRANSFORM WIN_DEPLOY_DLLS PREPEND "$ENV{MSYSTEM_PREFIX}/bin/")
|
||||
|
||||
@@ -32,6 +32,7 @@ import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Window 2.0
|
||||
import moneroComponents.Wallet 1.0
|
||||
|
||||
import "../components" as MoneroComponents
|
||||
|
||||
@@ -79,6 +80,10 @@ Window {
|
||||
running: false;
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (currentWallet.connected() == Wallet.ConnectionStatus_Connected) {
|
||||
running = false;
|
||||
root.close();
|
||||
}
|
||||
countDown--;
|
||||
if(countDown < 0){
|
||||
running = false;
|
||||
|
||||
@@ -92,7 +92,7 @@ Rectangle {
|
||||
anchors.leftMargin: 20
|
||||
height: parent.height
|
||||
width: 2
|
||||
color: button.checked ? MoneroComponents.Style.buttonBackgroundColor : "transparent"
|
||||
color: button.checked ? MoneroComponents.Style.accountColors[currentAccountIndex % MoneroComponents.Style.accountColors.length] : "transparent"
|
||||
|
||||
// button text
|
||||
MoneroComponents.TextPlain {
|
||||
|
||||
@@ -32,6 +32,8 @@ import "." as MoneroComponents
|
||||
|
||||
Rectangle {
|
||||
default property list<MoneroComponents.NavbarItem> items
|
||||
property alias currentIndex: repeater.currentIndex
|
||||
property alias previousIndex: repeater.previousIndex
|
||||
|
||||
color: "transparent"
|
||||
height: grid.height
|
||||
@@ -100,7 +102,10 @@ Rectangle {
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: items.length
|
||||
property int currentIndex: 0
|
||||
property int previousIndex: 0
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
@@ -149,7 +154,11 @@ Rectangle {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onClicked: items[index].selected()
|
||||
onClicked: {
|
||||
repeater.previousIndex = repeater.currentIndex;
|
||||
repeater.currentIndex = index;
|
||||
items[index].selected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ Rectangle {
|
||||
case Wallet.ConnectionStatus_Connected:
|
||||
if (!appWindow.daemonSynced)
|
||||
return qsTr("Synchronizing");
|
||||
if (persistentSettings.useRemoteNode && persistentSettings.allowRemoteNodeMining && appWindow.isMining)
|
||||
return qsTr("Remote node") + " + " + qsTr("Mining");
|
||||
if (persistentSettings.useRemoteNode)
|
||||
return qsTr("Remote node");
|
||||
return appWindow.isMining ? qsTr("Connected") + " + " + qsTr("Mining"): qsTr("Connected");
|
||||
|
||||
@@ -42,6 +42,13 @@ MoneroComponents.Dialog {
|
||||
|
||||
onActiveFocusChanged: activeFocus && remoteNodeAddress.forceActiveFocus()
|
||||
|
||||
function onOk() {
|
||||
root.success = true;
|
||||
root.close();
|
||||
}
|
||||
|
||||
function onCancel() { root.close(); }
|
||||
|
||||
function add(callbackOnSuccess) {
|
||||
root.editMode = false;
|
||||
root.callbackOnSuccess = callbackOnSuccess;
|
||||
@@ -89,6 +96,11 @@ MoneroComponents.Dialog {
|
||||
|
||||
daemonAddrLabelText: qsTr("Address") + translationManager.emptyString
|
||||
daemonPortLabelText: qsTr("Port") + translationManager.emptyString
|
||||
|
||||
Keys.enabled: root.visible
|
||||
Keys.onEnterPressed: root.onOk()
|
||||
Keys.onReturnPressed: root.onOk()
|
||||
Keys.onEscapePressed: root.onCancel()
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@@ -116,6 +128,11 @@ MoneroComponents.Dialog {
|
||||
placeholderFontSize: 15
|
||||
labelFontSize: 14
|
||||
fontSize: 15
|
||||
|
||||
Keys.enabled: root.visible
|
||||
Keys.onEnterPressed: root.onOk()
|
||||
Keys.onReturnPressed: root.onOk()
|
||||
Keys.onEscapePressed: root.onCancel()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 80
|
||||
color: "transparent"
|
||||
property var trusted: remoteNodesModel.get(index).trusted
|
||||
property var trusted: remoteNodesModel.get(index) ? remoteNodesModel.get(index).trusted : false
|
||||
|
||||
MoneroComponents.TextPlain {
|
||||
id: addressText
|
||||
@@ -107,8 +107,9 @@ ColumnLayout {
|
||||
MoneroComponents.Label {
|
||||
id: trustedDaemonCheckMark
|
||||
anchors.left: addressText.right
|
||||
anchors.leftMargin: 6
|
||||
anchors.leftMargin: 3
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: 2
|
||||
z: itemMouseArea.z + 1
|
||||
fontSize: 16
|
||||
fontFamily: FontAwesome.fontFamilySolid
|
||||
@@ -144,6 +145,9 @@ ColumnLayout {
|
||||
tooltipLeft: true
|
||||
onClicked: remoteNodeDialog.edit(remoteNodesModel.get(index), function (remoteNode) {
|
||||
remoteNodesModel.set(index, remoteNode)
|
||||
if (index === remoteNodesModel.selected) {
|
||||
remoteNodesModel.applyRemoteNode(index)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@ import "../components" as MoneroComponents
|
||||
ColumnLayout {
|
||||
id: settingsListItem
|
||||
property alias iconText: iconLabel.text
|
||||
property alias symbol: symbolText.text
|
||||
property alias description: area.text
|
||||
property alias title: header.text
|
||||
property bool isLast: false
|
||||
property bool enabled: true
|
||||
signal clicked()
|
||||
|
||||
Layout.fillWidth: true
|
||||
@@ -37,6 +39,7 @@ ColumnLayout {
|
||||
width: parent.width
|
||||
height: header.height + area.contentHeight
|
||||
color: "transparent";
|
||||
opacity: settingsListItem.enabled ? 1 : 0.25
|
||||
anchors.left: parent.left
|
||||
anchors.bottomMargin: 4
|
||||
anchors.topMargin: 4
|
||||
@@ -102,6 +105,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
visible: settingsListItem.enabled
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
@@ -111,5 +115,17 @@ ColumnLayout {
|
||||
settingsListItem.clicked()
|
||||
}
|
||||
}
|
||||
|
||||
MoneroComponents.TextPlain {
|
||||
id: symbolText
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 44
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 12
|
||||
font.bold: true
|
||||
color: MoneroComponents.Style.menuButtonTextColor
|
||||
visible: appWindow.ctrlPressed
|
||||
themeTransition: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ QtObject {
|
||||
property string leftPanelBackgroundGradientStart: blackTheme ? _b_leftPanelBackgroundGradientStart : _w_leftPanelBackgroundGradientStart
|
||||
property string leftPanelBackgroundGradientStop: blackTheme ? _b_leftPanelBackgroundGradientStop : _w_leftPanelBackgroundGradientStop
|
||||
property string historyHeaderTextColor: blackTheme ? _b_historyHeaderTextColor : _w_historyHeaderTextColor
|
||||
property var accountColors: blackTheme ? _b_accountColors : _w_accountColors
|
||||
|
||||
property string _b_defaultFontColor: "white"
|
||||
property string _b_dimmedFontColor: "#BBBBBB"
|
||||
@@ -142,6 +143,7 @@ QtObject {
|
||||
property string _b_leftPanelBackgroundGradientStart: "#222222"
|
||||
property string _b_leftPanelBackgroundGradientStop: "#1a1a1a"
|
||||
property string _b_historyHeaderTextColor: "#C0C0C0"
|
||||
property var _b_accountColors: ["#6E513C", "#842129", "#458421", "#742184", "#291DBE", "#846F21", "#217F84", "#696969"]
|
||||
|
||||
property string _w_defaultFontColor: "black"
|
||||
property string _w_dimmedFontColor: "#3f3f3f"
|
||||
@@ -203,4 +205,5 @@ QtObject {
|
||||
property string _w_leftPanelBackgroundGradientStart: "white"
|
||||
property string _w_leftPanelBackgroundGradientStop: "#f5f5f5"
|
||||
property string _w_historyHeaderTextColor: "#515151"
|
||||
property var _w_accountColors: ["#6E513C", "#6E513C", "#842129", "#458421", "#742184", "#291DBE", "#846F21", "#217F84", "#696969"]
|
||||
}
|
||||
|
||||
@@ -57,17 +57,20 @@ Rectangle {
|
||||
signal minimizeClicked
|
||||
signal languageClicked
|
||||
signal closeWalletClicked
|
||||
signal lockWalletClicked
|
||||
|
||||
state: "default"
|
||||
states: [
|
||||
State {
|
||||
name: "default";
|
||||
PropertyChanges { target: btnCloseWallet; visible: true}
|
||||
PropertyChanges { target: btnLockWallet; visible: true}
|
||||
PropertyChanges { target: btnLanguageToggle; visible: true}
|
||||
}, State {
|
||||
// show only theme switcher and window controls
|
||||
name: "essentials";
|
||||
PropertyChanges { target: btnCloseWallet; visible: false}
|
||||
PropertyChanges { target: btnLockWallet; visible: false}
|
||||
PropertyChanges { target: btnLanguageToggle; visible: false}
|
||||
}
|
||||
]
|
||||
@@ -91,6 +94,46 @@ Rectangle {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
// lock wallet
|
||||
Rectangle {
|
||||
id: btnLockWallet
|
||||
color: "transparent"
|
||||
Layout.preferredWidth: parent.height
|
||||
Layout.preferredHeight: parent.height
|
||||
|
||||
Text {
|
||||
text: FontAwesome.lock
|
||||
font.family: FontAwesome.fontFamilySolid
|
||||
font.pixelSize: 16
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
font.styleName: "Solid"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
opacity: 0.75
|
||||
}
|
||||
|
||||
MoneroComponents.Tooltip {
|
||||
id: btnLockWalletTooltip
|
||||
anchors.fill: parent
|
||||
text: qsTr("Lock this wallet") + translationManager.emptyString
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onEntered: {
|
||||
parent.color = MoneroComponents.Style.titleBarButtonHoverColor
|
||||
btnLockWalletTooltip.tooltipPopup.open()
|
||||
}
|
||||
onExited: {
|
||||
parent.color = "transparent"
|
||||
btnLockWalletTooltip.tooltipPopup.close()
|
||||
}
|
||||
onClicked: root.lockWalletClicked(leftPanel.visible)
|
||||
}
|
||||
}
|
||||
|
||||
// collapse sidebar
|
||||
Rectangle {
|
||||
id: btnCloseWallet
|
||||
|
||||
@@ -338,8 +338,9 @@ Rectangle {
|
||||
spacing: 16
|
||||
|
||||
Text {
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
font.pixelSize: 15
|
||||
property bool maliciousTxFee: parseFloat(root.transactionFee) > 0.01
|
||||
color: maliciousTxFee ? "red" : MoneroComponents.Style.defaultFontColor
|
||||
font.pixelSize: maliciousTxFee ? 20 : 15
|
||||
text: {
|
||||
if (currentWallet) {
|
||||
if (!root.transactionFee) {
|
||||
@@ -349,7 +350,7 @@ Rectangle {
|
||||
return qsTr("Calculating fee") + "..." + translationManager.emptyString;
|
||||
}
|
||||
} else {
|
||||
return root.transactionFee + " XMR"
|
||||
return root.transactionFee + " XMR" + (maliciousTxFee ? " (HIGH FEE)" : "")
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
|
||||
@@ -53,6 +53,8 @@ Object {
|
||||
property string info : "\uf129"
|
||||
property string key : "\uf084"
|
||||
property string language : "\uf1ab"
|
||||
property string lock : "\uf023"
|
||||
property string magnifyingGlass : "\uf002"
|
||||
property string minus : "\uf068"
|
||||
property string minusCircle : "\uf056"
|
||||
property string moonO : "\uf186"
|
||||
|
||||
BIN
images/appicon.icns
Executable file → Normal file
0
images/card-background-black.png → images/card-background-black0.png
Executable file → Normal file
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
0
images/card-background-black@2x.png → images/card-background-black0@2x.png
Executable file → Normal file
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
BIN
images/card-background-black1.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
images/card-background-black1@2x.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
images/card-background-black2.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
images/card-background-black2@2x.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
images/card-background-black3.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
images/card-background-black3@2x.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
images/card-background-black4.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
images/card-background-black4@2x.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
images/card-background-black5.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
images/card-background-black5@2x.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
images/card-background-black6.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
images/card-background-black6@2x.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
images/card-background-black7.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
images/card-background-black7@2x.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
images/ledgerNanoSPlus.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
@@ -1,4 +1,4 @@
|
||||
; Monero Oxygen Orion GUI Wallet Installer for Windows
|
||||
; Monero Fluorine Fermi GUI Wallet Installer for Windows
|
||||
; Copyright (c) 2017-2020, The Monero Project
|
||||
; See LICENSE
|
||||
#define GuiVersion GetFileVersion("bin\monero-wallet-gui.exe")
|
||||
@@ -16,7 +16,7 @@ DefaultGroupName=Monero GUI Wallet
|
||||
UninstallDisplayIcon={app}\monero-wallet-gui.exe
|
||||
PrivilegesRequired=admin
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
ArchitecturesAllowed=x64
|
||||
ArchitecturesAllowed=x64 arm64
|
||||
WizardSmallImageFile=WizardSmallImage.bmp
|
||||
WizardImageFile=WelcomeImage.bmp
|
||||
DisableWelcomePage=no
|
||||
@@ -54,6 +54,9 @@ Name: "en"; MessagesFile: "compiler:Default.isl"
|
||||
; Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
|
||||
; Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
|
||||
|
||||
[Dirs]
|
||||
Name: "{app}";
|
||||
Name: "{app}\p2pool"; Permissions: users-full
|
||||
|
||||
[Files]
|
||||
; The use of the flag "ignoreversion" for the following entries leads to the following behaviour:
|
||||
@@ -135,6 +138,7 @@ Type: filesandordirs; Name: "{app}\QtQuick.2"
|
||||
Type: filesandordirs; Name: "{app}\Material"
|
||||
Type: filesandordirs; Name: "{app}\Universal"
|
||||
Type: filesandordirs; Name: "{app}\scenegraph"
|
||||
Type: filesandordirs; Name: "{app}\p2pool"
|
||||
Type: files; Name: "{app}\D3Dcompiler_47.dll"
|
||||
Type: files; Name: "{app}\libbz2-1.dll"
|
||||
Type: files; Name: "{app}\libEGL.dll"
|
||||
|
||||
@@ -6,7 +6,7 @@ Copyright (c) 2017-2020, The Monero Project
|
||||
|
||||
This is a *Inno Setup* script `Monero.iss` plus some related files
|
||||
that allows you to build a standalone Windows installer (.exe) for
|
||||
the GUI wallet that comes with the Oxygen Orion release of Monero.
|
||||
the GUI wallet that comes with the Fluorine Fermi release of Monero.
|
||||
|
||||
This turns the GUI wallet into a more or less standard Windows program,
|
||||
by default installed into a subdirectory of `C:\Program Files`, a
|
||||
@@ -18,7 +18,7 @@ Monero.
|
||||
As the setup script in file [Monero.iss](Monero.iss) has to list many
|
||||
files and directories of the GUI wallet package to install by name,
|
||||
this version of the script only works with exactly the GUI wallet
|
||||
for Monero release *Oxygen Orion* that you find on
|
||||
for Monero release *Fluorine Fermi* that you find on
|
||||
[the official download page](https://getmonero.org/downloads/).
|
||||
|
||||
It should however be easy to modify the script for future
|
||||
@@ -39,8 +39,8 @@ Note that the installer build process is now reproducible / deterministic. For d
|
||||
The build steps in detail:
|
||||
|
||||
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
|
||||
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally instead of simply using `master` you may have to checkout a specific branch, like `release-v0.17`.
|
||||
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.17.0.0`) to this `bin` subdirectory
|
||||
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however.
|
||||
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.18.0.0`) to this `bin` subdirectory
|
||||
4. Start Inno Setup, load `Monero.iss` and compile it
|
||||
5. The result i.e. the finished installer will be the file `mysetup.exe` in the `installers\windows\Output` subdirectory
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Monero Oxygen Orion GUI Wallet</title>
|
||||
<title>Monero Fluorine Fermi GUI Wallet</title>
|
||||
</head>
|
||||
|
||||
<body style="font-family: Arial, Helvetica, sans-serif">
|
||||
<h1>Monero Oxygen Orion GUI Wallet</h1>
|
||||
<h1>Monero Fluorine Fermi GUI Wallet</h1>
|
||||
|
||||
<p>Copyright (c) 2014-2020, The Monero Project</p>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<h2>Content of the Package</h2>
|
||||
|
||||
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Oxygen Orion, version {#GuiVersion}.
|
||||
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Fluorine Fermi, version {#GuiVersion}.
|
||||
The wallet enables you to send and receive Moneroj in a secure and very private way.
|
||||
</p>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 440 KiB |
@@ -61,15 +61,18 @@ function checkSignature(signature) {
|
||||
if ((signature.length - 12) % 88 != 0)
|
||||
return false;
|
||||
return check256(signature, signature.length);
|
||||
} else if (signature.indexOf("ReserveProofV") === 0) {
|
||||
if ((signature.length - 14) % 447 != 0)
|
||||
return false;
|
||||
return check256(signature, signature.length);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isValidOpenAliasAddress(address) {
|
||||
address = address.trim()
|
||||
var dot = address.indexOf('.')
|
||||
if (dot < 0)
|
||||
return false
|
||||
// we can get an awful lot of valid domains, including non ASCII chars... accept anything
|
||||
return true
|
||||
// there should be something after the .
|
||||
// make sure it is not some kind of floating number
|
||||
return address.length > 2 && isNaN(parseFloat(address)) && address.indexOf('.') >= 0
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var flagsCustomDecorations = (Qt.FramelessWindowHint | Qt.CustomizeWindowHint | Qt.WindowSystemMenuHint | Qt.Window);
|
||||
var flagsCustomDecorationsBase = (Qt.FramelessWindowHint | Qt.CustomizeWindowHint | Qt.WindowSystemMenuHint | Qt.Window);
|
||||
var flagsCustomDecorations = isWindows ? (flagsCustomDecorationsBase | Qt.WindowMinimizeButtonHint) : flagsCustomDecorationsBase;
|
||||
var flags = (Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint | Qt.WindowFullscreenButtonHint);
|
||||
|
||||
/**
|
||||
|
||||
@@ -164,9 +164,9 @@ function getApproximateBlockchainHeight(_date, _nettype){
|
||||
secondsPerBlock = secondsPerBlockV2;
|
||||
}
|
||||
|
||||
if(_nettype == "Testnet"){
|
||||
if(_nettype == "Testnet" || _nettype == "Stagenet"){
|
||||
// testnet got some huge rollbacks, so the estimation is way off
|
||||
var approximateTestnetRolledBackBlocks = 342100;
|
||||
var approximateTestnetRolledBackBlocks = _nettype == "Testnet" ? 342100 : 30000;
|
||||
if(approxBlockchainHeight > approximateTestnetRolledBackBlocks)
|
||||
approxBlockchainHeight -= approximateTestnetRolledBackBlocks
|
||||
}
|
||||
|
||||
BIN
lang/flags/el.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
lang/flags/is.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
lang/flags/vi.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
@@ -61,4 +61,9 @@ Lojban
|
||||
<!-- <language display_name="کورمانجی" locale="kmr_KMR" wallet_language="English" flag="/lang/flags/ku.png" qs="none"/> -->
|
||||
<!-- <language display_name="বাংলা" locale="bn_BN" wallet_language="English" flag="/lang/flags/bd.png" qs="none"/> -->
|
||||
<!-- <language display_name="Gaeilge" locale="ga_GA" wallet_language="English" flag="/lang/flags/irl.png" qs="none"/> -->
|
||||
<language display_name="Afrikaans" locale="af_AF" wallet_language="English" flag="/lang/flags/za.png" qs="none"/>
|
||||
<language display_name="Ελληνικά" locale="el_GR" wallet_language="English" flag="/lang/flags/el.png" qs="none"/>
|
||||
<language display_name="தமிழ்" locale="ta_IN" wallet_language="English" flag="/lang/flags/in.png" qs="none"/>
|
||||
<language display_name="Tiếng Việt" locale="vi_VN" wallet_language="English" flag="/lang/flags/vi.png" qs="none"/>
|
||||
<language display_name="Íslenska" locale="is_IS" wallet_language="English" flag="/lang/flags/is.png" qs="none"/>
|
||||
</languages>
|
||||
|
||||
149
main.qml
@@ -42,6 +42,7 @@ import moneroComponents.WalletManager 1.0
|
||||
import moneroComponents.PendingTransaction 1.0
|
||||
import moneroComponents.NetworkType 1.0
|
||||
import moneroComponents.Settings 1.0
|
||||
import moneroComponents.P2PoolManager 1.0
|
||||
|
||||
import "components"
|
||||
import "components" as MoneroComponents
|
||||
@@ -131,6 +132,17 @@ ApplicationWindow {
|
||||
leftPanel.selectItem(page)
|
||||
}
|
||||
|
||||
function lock() {
|
||||
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
|
||||
passwordDialog.onAcceptedCallback = function() {
|
||||
if(walletPassword === passwordDialog.password)
|
||||
passwordDialog.close();
|
||||
else
|
||||
passwordDialog.showError(qsTr("Wrong password") + translationManager.emptyString);
|
||||
}
|
||||
passwordDialog.open(usefulName(persistentSettings.wallet_path));
|
||||
}
|
||||
|
||||
function sequencePressed(obj, seq) {
|
||||
if(seq === undefined || !leftPanel.enabled)
|
||||
return
|
||||
@@ -139,6 +151,8 @@ ApplicationWindow {
|
||||
return
|
||||
}
|
||||
|
||||
// lock wallet on demand
|
||||
if(seq === "Ctrl+L" && !passwordDialog.visible) lock()
|
||||
if(seq === "Ctrl+S") middlePanel.state = "Transfer"
|
||||
else if(seq === "Ctrl+R") middlePanel.state = "Receive"
|
||||
else if(seq === "Ctrl+H") middlePanel.state = "History"
|
||||
@@ -307,27 +321,6 @@ ApplicationWindow {
|
||||
function connectWallet(wallet) {
|
||||
currentWallet = wallet
|
||||
|
||||
// TODO:
|
||||
// When the wallet variable is undefined, it yields a zero balance.
|
||||
// This can scare users, restart the GUI (as a quick fix).
|
||||
//
|
||||
// To reproduce, follow these steps:
|
||||
// 1) Open the GUI, load up a wallet that has a balance
|
||||
// 2) Settings -> close wallet
|
||||
// 3) Create a new wallet
|
||||
// 4) Settings -> close wallet
|
||||
// 5) Open the wallet from step 1
|
||||
|
||||
if(!wallet || wallet === undefined || wallet.path === undefined){
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("Couldn't open wallet: ") + 'please restart GUI.';
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.open()
|
||||
informationPopup.onCloseCallback = function() {
|
||||
appWindow.close();
|
||||
}
|
||||
}
|
||||
|
||||
walletName = usefulName(wallet.path)
|
||||
|
||||
viewOnly = currentWallet.viewOnly;
|
||||
@@ -488,7 +481,9 @@ ApplicationWindow {
|
||||
walletInitialized = true
|
||||
|
||||
// check if daemon was already mining and add mining logo if true
|
||||
middlePanel.advancedView.miningView.update();
|
||||
if (!persistentSettings.useRemoteNode || persistentSettings.allowRemoteNodeMining) {
|
||||
middlePanel.advancedView.miningView.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,6 +713,7 @@ ApplicationWindow {
|
||||
if (splash) {
|
||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to stop..."));
|
||||
}
|
||||
p2poolManager.exit()
|
||||
daemonManager.stopAsync(persistentSettings.nettype, function(result) {
|
||||
daemonStartStopInProgress = 0;
|
||||
if (splash) {
|
||||
@@ -730,14 +726,18 @@ ApplicationWindow {
|
||||
function onDaemonStarted(){
|
||||
console.log("daemon started");
|
||||
daemonStartStopInProgress = 0;
|
||||
currentWallet.connected(true);
|
||||
// resume refresh
|
||||
currentWallet.startRefresh();
|
||||
if (currentWallet) {
|
||||
currentWallet.connected(true);
|
||||
// resume refresh
|
||||
currentWallet.startRefresh();
|
||||
}
|
||||
// resume simplemode connection timer
|
||||
appWindow.disconnectedEpoch = Utils.epoch();
|
||||
}
|
||||
function onDaemonStopped(){
|
||||
currentWallet.connected(true);
|
||||
if (currentWallet) {
|
||||
currentWallet.connected(true);
|
||||
}
|
||||
}
|
||||
|
||||
function onDaemonStartFailure(error) {
|
||||
@@ -981,24 +981,28 @@ ApplicationWindow {
|
||||
}
|
||||
|
||||
// called on "getProof"
|
||||
function handleGetProof(txid, address, message) {
|
||||
console.log("Getting payment proof: ")
|
||||
console.log("\ttxid: ", txid,
|
||||
", address: ", address,
|
||||
", message: ", message);
|
||||
|
||||
function spendProofFallback(txid, result){
|
||||
if (!result || result.indexOf("error|") === 0) {
|
||||
currentWallet.getSpendProofAsync(txid, message, txProofComputed);
|
||||
} else {
|
||||
txProofComputed(txid, result);
|
||||
function handleGetProof(txid, address, message, amount) {
|
||||
if (amount !== null && amount.length > 0) {
|
||||
var result = currentWallet.getReserveProof(false, currentWallet.currentSubaddressAccount, walletManager.amountFromString(amount), message)
|
||||
txProofComputed(null, result)
|
||||
} else {
|
||||
console.log("Getting payment proof: ")
|
||||
console.log("\ttxid: ", txid,
|
||||
", address: ", address,
|
||||
", message: ", message);
|
||||
function spendProofFallback(txid, result){
|
||||
if (!result || result.indexOf("error|") === 0) {
|
||||
currentWallet.getSpendProofAsync(txid, message, txProofComputed);
|
||||
} else {
|
||||
txProofComputed(txid, result);
|
||||
}
|
||||
}
|
||||
if (address.length > 0)
|
||||
currentWallet.getTxProofAsync(txid, address, message, spendProofFallback);
|
||||
else
|
||||
spendProofFallback(txid, null);
|
||||
}
|
||||
|
||||
if (address.length > 0)
|
||||
currentWallet.getTxProofAsync(txid, address, message, spendProofFallback);
|
||||
else
|
||||
spendProofFallback(txid, null);
|
||||
informationPopup.open()
|
||||
}
|
||||
|
||||
function txProofComputed(txid, result){
|
||||
@@ -1021,12 +1025,18 @@ ApplicationWindow {
|
||||
", signature: ", signature);
|
||||
|
||||
var result;
|
||||
if (address.length > 0)
|
||||
var isReserveProof = signature.indexOf("ReserveProofV") === 0;
|
||||
if (address.length > 0 && !isReserveProof) {
|
||||
result = currentWallet.checkTxProof(txid, address, message, signature);
|
||||
else
|
||||
}
|
||||
else if (isReserveProof) {
|
||||
result = currentWallet.checkReserveProof(address, message, signature);
|
||||
}
|
||||
else {
|
||||
result = currentWallet.checkSpendProof(txid, message, signature);
|
||||
}
|
||||
var results = result.split("|");
|
||||
if (address.length > 0 && results.length == 5 && results[0] === "true") {
|
||||
if (address.length > 0 && results.length == 5 && results[0] === "true" && !isReserveProof) {
|
||||
var good = results[1] === "true";
|
||||
var received = results[2];
|
||||
var in_pool = results[3] === "true";
|
||||
@@ -1054,6 +1064,12 @@ ApplicationWindow {
|
||||
informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
|
||||
informationPopup.icon = good ? StandardIcon.Information : StandardIcon.Critical;
|
||||
informationPopup.text = good ? qsTr("Good signature") : qsTr("Bad signature");
|
||||
}
|
||||
else if (isReserveProof && results[0] === "true") {
|
||||
var good = results[1] === "true";
|
||||
informationPopup.title = qsTr("Reserve proof check") + translationManager.emptyString;
|
||||
informationPopup.icon = good ? StandardIcon.Information : StandardIcon.Critical;
|
||||
informationPopup.text = good ? qsTr("Good signature on %1 total and %2 spent.").arg(results[2]).arg(results[3]) : qsTr("Bad signature");
|
||||
}
|
||||
else {
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
@@ -1121,13 +1137,10 @@ ApplicationWindow {
|
||||
Timer {
|
||||
id: fiatPriceTimer
|
||||
interval: 1000 * 60;
|
||||
running: persistentSettings.fiatPriceEnabled;
|
||||
running: persistentSettings.fiatPriceEnabled && currentWallet !== undefined
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if(persistentSettings.fiatPriceEnabled)
|
||||
appWindow.fiatApiRefresh();
|
||||
}
|
||||
triggeredOnStart: false
|
||||
onTriggered: appWindow.fiatApiRefresh()
|
||||
triggeredOnStart: true
|
||||
}
|
||||
|
||||
function fiatApiParseTicker(url, resp, currency){
|
||||
@@ -1266,14 +1279,6 @@ ApplicationWindow {
|
||||
leftPanel.balanceFiatString = bFiat;
|
||||
}
|
||||
|
||||
function fiatTimerStart(){
|
||||
fiatPriceTimer.start();
|
||||
}
|
||||
|
||||
function fiatTimerStop(){
|
||||
fiatPriceTimer.stop();
|
||||
}
|
||||
|
||||
function fiatApiError(msg){
|
||||
console.log("fiatPriceError: " + msg);
|
||||
}
|
||||
@@ -1329,12 +1334,8 @@ ApplicationWindow {
|
||||
openWallet("wizard");
|
||||
}
|
||||
|
||||
if(persistentSettings.fiatPriceEnabled){
|
||||
appWindow.fiatApiRefresh();
|
||||
appWindow.fiatTimerStart();
|
||||
}
|
||||
|
||||
if (persistentSettings.askDesktopShortcut && !persistentSettings.portable) {
|
||||
const desktopEntryEnabled = (typeof builtWithDesktopEntry != "undefined") && builtWithDesktopEntry;
|
||||
if (persistentSettings.askDesktopShortcut && !persistentSettings.portable && desktopEntryEnabled) {
|
||||
persistentSettings.askDesktopShortcut = false;
|
||||
|
||||
if (isTails) {
|
||||
@@ -1365,13 +1366,18 @@ ApplicationWindow {
|
||||
}
|
||||
|
||||
property bool askDesktopShortcut: isLinux
|
||||
property bool askStopLocalNode: true
|
||||
property string language: 'English (US)'
|
||||
property string language_wallet: 'English'
|
||||
property string locale: 'en_US'
|
||||
property string account_name
|
||||
property string wallet_path
|
||||
property bool allow_background_mining : false
|
||||
property bool allow_p2pool_mining : false
|
||||
property bool allowRemoteNodeMining : false
|
||||
property bool miningIgnoreBattery : true
|
||||
property int miningModeSelected: 0
|
||||
property int chainDropdownSelected: 0
|
||||
property var nettype: NetworkType.MAINNET
|
||||
property int restore_height : 0
|
||||
property bool is_trusted_daemon : false // TODO: drop after v0.17.2.0 release
|
||||
@@ -1379,6 +1385,7 @@ ApplicationWindow {
|
||||
property bool is_recovering_from_device : false
|
||||
property bool customDecorations : true
|
||||
property string daemonFlags
|
||||
property string p2poolFlags
|
||||
property int logLevel: 0
|
||||
property string logCategories: ""
|
||||
property string daemonUsername: "" // TODO: drop after v0.17.2.0 release
|
||||
@@ -1688,6 +1695,9 @@ ApplicationWindow {
|
||||
informationPopup.open();
|
||||
}
|
||||
onRejectedNewPassword: {}
|
||||
Keys.enabled: !passwordDialog.visible && informationPopup.visible
|
||||
Keys.onEnterPressed: informationPopup.close()
|
||||
Keys.onReturnPressed: informationPopup.close()
|
||||
}
|
||||
|
||||
DevicePassphraseDialog {
|
||||
@@ -1899,6 +1909,7 @@ ApplicationWindow {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
onCloseClicked: appWindow.close();
|
||||
onLockWalletClicked: appWindow.lock();
|
||||
onLanguageClicked: appWindow.toggleLanguageView();
|
||||
onCloseWalletClicked: appWindow.showWizard();
|
||||
onMaximizeClicked: appWindow.visibility = appWindow.visibility !== Window.Maximized ? Window.Maximized : Window.Windowed
|
||||
@@ -2023,7 +2034,7 @@ ApplicationWindow {
|
||||
return;
|
||||
}
|
||||
|
||||
const simpleModeFlags = "--enable-dns-blocklist --out-peers 16";
|
||||
const simpleModeFlags = "--enable-dns-blocklist --out-peers 16 --no-igd";
|
||||
if (appWindow.daemonRunning) {
|
||||
appWindow.stopDaemon(function() {
|
||||
appWindow.startDaemon(simpleModeFlags)
|
||||
@@ -2120,7 +2131,7 @@ ApplicationWindow {
|
||||
showProcessingSplash(qsTr("Checking local node status..."));
|
||||
const handler = function(running) {
|
||||
hideProcessingSplash();
|
||||
if (running) {
|
||||
if (running && persistentSettings.askStopLocalNode) {
|
||||
showDaemonIsRunningDialog(closeAccepted);
|
||||
} else {
|
||||
closeAccepted();
|
||||
@@ -2139,7 +2150,7 @@ ApplicationWindow {
|
||||
console.log("close accepted");
|
||||
// Close wallet non async on exit
|
||||
daemonManager.exit();
|
||||
|
||||
p2poolManager.exit();
|
||||
closeWallet(Qt.quit);
|
||||
}
|
||||
|
||||
@@ -2245,7 +2256,7 @@ ApplicationWindow {
|
||||
}
|
||||
|
||||
function getDefaultDaemonRpcPort(networkType) {
|
||||
switch (networkType) {
|
||||
switch (parseInt(networkType)) {
|
||||
case NetworkType.STAGENET:
|
||||
return 38081;
|
||||
case NetworkType.TESTNET:
|
||||
|
||||
2
monero
@@ -238,7 +238,7 @@ Rectangle {
|
||||
Layout.fillHeight: true
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
color: "darkgrey"
|
||||
color: MoneroComponents.Style.accountColors[currentAccountIndex % MoneroComponents.Style.accountColors.length]
|
||||
width: 2
|
||||
}
|
||||
|
||||
|
||||
@@ -468,21 +468,25 @@ Rectangle {
|
||||
text: (root.editEntry ? qsTr("Save") : qsTr("Add")) + translationManager.emptyString
|
||||
enabled: root.checkInformation(addressLine.text, appWindow.persistentSettings.nettype)
|
||||
onClicked: {
|
||||
console.log("Add")
|
||||
if (!root.editEntry && !currentWallet.addressBook.addRow(addressLine.text.trim(),"", descriptionLine.text)) {
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
// TODO: check currentWallet.addressBook.errorString() instead.
|
||||
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
|
||||
informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
|
||||
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
|
||||
informationPopup.text = currentWallet.addressBook.errorString()
|
||||
else
|
||||
informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
|
||||
if (!root.editEntry) {
|
||||
if (currentWallet.addressBook.addRow(addressLine.text.trim(),"", descriptionLine.text)) {
|
||||
console.log("Entry added")
|
||||
} else {
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
// TODO: check currentWallet.addressBook.errorString() instead.
|
||||
if (currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
|
||||
informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
|
||||
else if (currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
|
||||
informationPopup.text = currentWallet.addressBook.errorString()
|
||||
else
|
||||
informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
|
||||
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open();
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open();
|
||||
}
|
||||
} else {
|
||||
currentWallet.addressBook.setDescription(addressBookListView.currentIndex, descriptionLine.text);
|
||||
console.log("Description edited")
|
||||
}
|
||||
root.showAddressBook()
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ ColumnLayout {
|
||||
property alias state: stateView.state
|
||||
|
||||
MoneroComponents.Navbar {
|
||||
id: navbarId
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: height
|
||||
Layout.bottomMargin: height
|
||||
@@ -128,7 +129,7 @@ ColumnLayout {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: 0 - target.width
|
||||
from: (navbarId.currentIndex < navbarId.previousIndex ? 1 : -1) * - target.width
|
||||
to: 0
|
||||
duration: 300
|
||||
easing.type: Easing.OutCubic
|
||||
@@ -137,7 +138,7 @@ ColumnLayout {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: target.width
|
||||
to: (navbarId.currentIndex < navbarId.previousIndex ? 1 : -1) * target.width
|
||||
duration: 300
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
|
||||
@@ -1013,6 +1013,7 @@ Rectangle {
|
||||
|
||||
MoneroComponents.StandardButton {
|
||||
visible: isout
|
||||
enabled: currentWallet ? !currentWallet.isHwBacked() : false
|
||||
anchors.left: btnDetails.right
|
||||
anchors.leftMargin: 10
|
||||
text: FontAwesome.productHunt
|
||||
@@ -1719,7 +1720,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
console.log("getProof: Generate clicked: txid " + hash + ", address " + address);
|
||||
middlePanel.getProofClicked(hash, address, '');
|
||||
middlePanel.getProofClicked(hash, address, '', null);
|
||||
informationPopup.title = qsTr("Payment proof") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("Generating payment proof") + "..." + translationManager.emptyString;
|
||||
informationPopup.onCloseCallback = null
|
||||
|
||||
357
pages/Mining.qml
@@ -26,11 +26,14 @@
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import QtQml.Models 2.2
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.2
|
||||
import "../components" as MoneroComponents
|
||||
import moneroComponents.Wallet 1.0
|
||||
import moneroComponents.P2PoolManager 1.0
|
||||
import moneroComponents.DaemonManager 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
@@ -52,13 +55,14 @@ Rectangle {
|
||||
MoneroComponents.Label {
|
||||
id: soloTitleLabel
|
||||
fontSize: 24
|
||||
text: qsTr("Solo mining") + translationManager.emptyString
|
||||
text: qsTr("Mining") + translationManager.emptyString
|
||||
}
|
||||
|
||||
MoneroComponents.WarningBox {
|
||||
Layout.bottomMargin: 8
|
||||
id: localDaemonWarning
|
||||
text: qsTr("Mining is only available on local daemons.") + translationManager.emptyString
|
||||
visible: persistentSettings.useRemoteNode
|
||||
visible: persistentSettings.useRemoteNode && !persistentSettings.allowRemoteNodeMining
|
||||
}
|
||||
|
||||
MoneroComponents.WarningBox {
|
||||
@@ -69,7 +73,7 @@ Rectangle {
|
||||
|
||||
MoneroComponents.TextPlain {
|
||||
id: soloMainLabel
|
||||
text: qsTr("Mining with your computer helps strengthen the Monero network. The more that people mine, the harder it is for the network to be attacked, and every little bit helps.\n\nMining also gives you a small chance to earn some Monero. Your computer will create hashes looking for block solutions. If you find a block, you will get the associated reward. Good luck!") + translationManager.emptyString
|
||||
text: qsTr("Mining with your computer helps strengthen the Monero network. The more people mine, the harder it is for the network to be attacked, and every little bit helps.\n\nMining also gives you a small chance to earn some Monero. Your computer will create hashes looking for block solutions. If you find a block, you will get the associated reward. Good luck!") + "\n\n" + qsTr("P2Pool mining is a decentralized way to pool mine that pays out more frequently compared to solo mining, while also supporting the network.") + translationManager.emptyString
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
font.family: MoneroComponents.Style.fontRegular.name
|
||||
@@ -90,6 +94,44 @@ Rectangle {
|
||||
columnSpacing: 20
|
||||
rowSpacing: 16
|
||||
|
||||
ListModel {
|
||||
id: miningModeModel
|
||||
|
||||
ListElement { column1: qsTr("Solo") ; column2: ""; priority: 0}
|
||||
ListElement { column1: "P2Pool" ; column2: ""; priority: 1}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
MoneroComponents.Label {
|
||||
id: miningModeLabel
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
text: qsTr("Mining mode") + translationManager.emptyString
|
||||
fontSize: 16
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.topMargin: 5
|
||||
spacing: 10
|
||||
|
||||
MoneroComponents.StandardDropdown {
|
||||
Layout.maximumWidth: 200
|
||||
id: miningModeDropdown
|
||||
visible: true
|
||||
currentIndex: persistentSettings.miningModeSelected
|
||||
dataModel: miningModeModel
|
||||
onChanged: {
|
||||
persistentSettings.allow_p2pool_mining = miningModeDropdown.currentIndex === 1;
|
||||
persistentSettings.miningModeSelected = miningModeDropdown.currentIndex;
|
||||
walletManager.stopMining();
|
||||
p2poolManager.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
@@ -194,6 +236,7 @@ Rectangle {
|
||||
MoneroComponents.Label {
|
||||
id: optionsLabel
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
visible: !persistentSettings.allow_p2pool_mining
|
||||
text: qsTr("Options") + translationManager.emptyString
|
||||
fontSize: 16
|
||||
wrapMode: Text.Wrap
|
||||
@@ -208,7 +251,8 @@ Rectangle {
|
||||
RowLayout {
|
||||
MoneroComponents.CheckBox {
|
||||
id: backgroundMining
|
||||
enabled: startSoloMinerButton.enabled
|
||||
visible: !persistentSettings.allow_p2pool_mining
|
||||
enabled: startSoloMinerButton.enabled && !persistentSettings.allow_p2pool_mining
|
||||
checked: persistentSettings.allow_background_mining
|
||||
onClicked: persistentSettings.allow_background_mining = checked
|
||||
text: qsTr("Background mining (experimental)") + translationManager.emptyString
|
||||
@@ -241,16 +285,52 @@ Rectangle {
|
||||
primary: !stopSoloMinerButton.enabled
|
||||
text: qsTr("Start mining") + translationManager.emptyString
|
||||
onClicked: {
|
||||
var success = walletManager.startMining(appWindow.currentWallet.address(0, 0), threads, persistentSettings.allow_background_mining, persistentSettings.miningIgnoreBattery)
|
||||
if (success) {
|
||||
update()
|
||||
} else {
|
||||
errorPopup.title = qsTr("Error starting mining") + translationManager.emptyString;
|
||||
errorPopup.text = qsTr("Couldn't start mining.<br>") + translationManager.emptyString
|
||||
if (persistentSettings.useRemoteNode)
|
||||
errorPopup.text += qsTr("Mining is only available on local daemons. Run a local daemon to be able to mine.<br>") + translationManager.emptyString
|
||||
errorPopup.icon = StandardIcon.Critical
|
||||
errorPopup.open()
|
||||
var daemonReady = appWindow.daemonSynced && appWindow.daemonRunning && !persistentSettings.useRemoteNode
|
||||
if (persistentSettings.allowRemoteNodeMining) {
|
||||
daemonReady = persistentSettings.useRemoteNode && appWindow.daemonSynced
|
||||
}
|
||||
if (daemonReady) {
|
||||
var success;
|
||||
if (persistentSettings.allow_p2pool_mining) {
|
||||
if (p2poolManager.isInstalled()) {
|
||||
if (persistentSettings.allowRemoteNodeMining) {
|
||||
startP2Pool()
|
||||
}
|
||||
else {
|
||||
daemonManager.stopAsync(persistentSettings.nettype, startP2PoolLocal)
|
||||
}
|
||||
}
|
||||
else {
|
||||
confirmationDialog.title = qsTr("P2Pool installation") + translationManager.emptyString;
|
||||
confirmationDialog.text = qsTr("P2Pool will be installed at %1. Proceed?").arg(applicationDirectory) + translationManager.emptyString;
|
||||
confirmationDialog.icon = StandardIcon.Question;
|
||||
confirmationDialog.cancelText = qsTr("No") + translationManager.emptyString;
|
||||
confirmationDialog.okText = qsTr("Yes") + translationManager.emptyString;
|
||||
confirmationDialog.onAcceptedCallback = function() {
|
||||
p2poolManager.download();
|
||||
statusMessageText.text = "Downloading P2Pool...";
|
||||
statusMessage.visible = true
|
||||
startSoloMinerButton.enabled = false;
|
||||
stopSoloMinerButton.enabled = false;
|
||||
}
|
||||
confirmationDialog.open();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = walletManager.startMining(appWindow.currentWallet.address(0, 0), threads, persistentSettings.allow_background_mining, persistentSettings.miningIgnoreBattery)
|
||||
if (success)
|
||||
{
|
||||
update()
|
||||
}
|
||||
else
|
||||
{
|
||||
miningError(qsTr("Couldn't start mining.<br>") + translationManager.emptyString)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
miningError(qsTr("Couldn't start mining.<br>") + translationManager.emptyString)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,6 +343,7 @@ Rectangle {
|
||||
text: qsTr("Stop mining") + translationManager.emptyString
|
||||
onClicked: {
|
||||
walletManager.stopMining()
|
||||
p2poolManager.exit()
|
||||
update()
|
||||
}
|
||||
}
|
||||
@@ -295,23 +376,162 @@ Rectangle {
|
||||
inputPaddingLeft: 0
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: chainModel
|
||||
|
||||
ListElement { column1: qsTr("Mini") ; column2: ""; priority: 0}
|
||||
ListElement { column1: qsTr("Main") ; column2: ""; priority: 1}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
MoneroComponents.Label {
|
||||
id: chainLabel
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
visible: persistentSettings.allow_p2pool_mining
|
||||
text: qsTr("Chain") + translationManager.emptyString
|
||||
fontSize: 16
|
||||
}
|
||||
|
||||
MoneroComponents.Tooltip {
|
||||
id: chainsHelpTooltip
|
||||
text: qsTr("Use the mini chain if you have a low hashrate.") + translationManager.emptyString
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: chainsTooltipArea
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
enabled: persistentSettings.allow_p2pool_mining
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
chainsHelpTooltip.tooltipPopup.open();
|
||||
}
|
||||
onExited: {
|
||||
chainsHelpTooltip.tooltipPopup.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.topMargin: 5
|
||||
spacing: 10
|
||||
|
||||
MoneroComponents.StandardDropdown {
|
||||
Layout.maximumWidth: 200
|
||||
id: chainDropdown
|
||||
visible: persistentSettings.allow_p2pool_mining
|
||||
currentIndex: persistentSettings.chainDropdownSelected
|
||||
dataModel: chainModel
|
||||
onChanged: persistentSettings.chainDropdownSelected = chainDropdown.currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
MoneroComponents.Label {
|
||||
id: flagsLabel
|
||||
visible: persistentSettings.allow_p2pool_mining
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
text: qsTr("Flags") + translationManager.emptyString
|
||||
fontSize: 16
|
||||
}
|
||||
|
||||
MoneroComponents.Tooltip {
|
||||
id: flagsHelpTooltip
|
||||
text: "
|
||||
Usage:<br>
|
||||
--wallet Wallet address to mine to. Subaddresses and integrated addresses are not supported!<br>
|
||||
--host IP address of your Monero node, default is 127.0.0.1<br>
|
||||
--rpc-port monerod RPC API port number, default is 18081<br>
|
||||
--zmq-port monerod ZMQ pub port number, default is 18083 (same port as in monerod\'s \"--zmq-pub\" command line parameter)<br>
|
||||
--stratum Comma-separated list of IP:port for stratum server to listen on<br>
|
||||
--p2p Comma-separated list of IP:port for p2p server to listen on<br>
|
||||
--addpeers Comma-separated list of IP:port of other p2pool nodes to connect to<br>
|
||||
--light-mode Don't allocate RandomX dataset, saves 2GB of RAM<br>
|
||||
--loglevel Verbosity of the log, integer number between 0 and 6<br>
|
||||
--config Name of the p2pool config file<br>
|
||||
--data-api Path to the p2pool JSON data (use it in tandem with an external web-server)<br>
|
||||
--local-api Enable /local/ path in api path for Stratum Server and built-in miner statistics<br>
|
||||
--stratum-api An alias for --local-api<br>
|
||||
--no-cache Disable p2pool.cache<br>
|
||||
--no-color Disable colors in console output<br>
|
||||
--no-randomx Disable internal RandomX hasher: p2pool will use RPC calls to monerod to check PoW hashes<br>
|
||||
--out-peers N Maximum number of outgoing connections for p2p server (any value between 10 and 1000)<br>
|
||||
--in-peers N Maximum number of incoming connections for p2p server (any value between 10 and 1000)<br>
|
||||
--start-mining N Start built-in miner using N threads (any value between 1 and 64)<br>
|
||||
--help Show this help message
|
||||
"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: flagsTooltipArea
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
enabled: persistentSettings.allow_p2pool_mining
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
flagsHelpTooltip.tooltipPopup.open();
|
||||
}
|
||||
onExited: {
|
||||
flagsHelpTooltip.tooltipPopup.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
MoneroComponents.LineEditMulti {
|
||||
id: p2poolFlags
|
||||
Layout.minimumWidth: 100
|
||||
Layout.bottomMargin: 20
|
||||
labelFontSize: 14
|
||||
fontSize: 15
|
||||
visible: persistentSettings.allow_p2pool_mining
|
||||
wrapMode: Text.WrapAnywhere
|
||||
labelText: qsTr("P2Pool startup flags") + translationManager.emptyString
|
||||
placeholderText: qsTr("(optional)") + translationManager.emptyString
|
||||
placeholderFontSize: 15
|
||||
text: persistentSettings.p2poolFlags
|
||||
addressValidation: false
|
||||
onEditingFinished: {
|
||||
persistentSettings.allowRemoteNodeMining = p2poolFlags.text.includes("--host");
|
||||
persistentSettings.p2poolFlags = p2poolFlags.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatusText() {
|
||||
function updateStatusText(p2poolHashrate) {
|
||||
if (appWindow.isMining) {
|
||||
var userHashRate = walletManager.miningHashRate();
|
||||
if (userHashRate === 0) {
|
||||
statusText.text = qsTr("Mining temporarily suspended.") + translationManager.emptyString;
|
||||
if (persistentSettings.allow_p2pool_mining) {
|
||||
if (p2poolHashrate === 0) {
|
||||
statusText.text = qsTr("Starting P2Pool") + translationManager.emptyString;
|
||||
}
|
||||
else {
|
||||
statusText.text = qsTr("Mining with P2Pool, at %1 H/s").arg(p2poolHashrate) + translationManager.emptyString;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var blockTime = 120;
|
||||
var blocksPerDay = 86400 / blockTime;
|
||||
var globalHashRate = walletManager.networkDifficulty() / blockTime;
|
||||
var probabilityFindNextBlock = userHashRate / globalHashRate;
|
||||
var probabilityFindBlockDay = 1 - Math.pow(1 - probabilityFindNextBlock, blocksPerDay);
|
||||
var chanceFindBlockDay = Math.round(1 / probabilityFindBlockDay);
|
||||
statusText.text = qsTr("Mining at %1 H/s. It gives you a 1 in %2 daily chance of finding a block.").arg(userHashRate).arg(chanceFindBlockDay) + translationManager.emptyString;
|
||||
var userHashRate = walletManager.miningHashRate();
|
||||
if (userHashRate === 0) {
|
||||
statusText.text = qsTr("Mining temporarily suspended.") + translationManager.emptyString;
|
||||
}
|
||||
else {
|
||||
var blockTime = 120;
|
||||
var blocksPerDay = 86400 / blockTime;
|
||||
var globalHashRate = walletManager.networkDifficulty() / blockTime;
|
||||
var probabilityFindNextBlock = userHashRate / globalHashRate;
|
||||
var probabilityFindBlockDay = 1 - Math.pow(1 - probabilityFindNextBlock, blocksPerDay);
|
||||
var chanceFindBlockDay = Math.round(1 / probabilityFindBlockDay);
|
||||
statusText.text = qsTr("Mining at %1 H/s. It gives you a 1 in %2 daily chance of finding a block.").arg(userHashRate).arg(chanceFindBlockDay) + translationManager.emptyString;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -319,16 +539,35 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
function onMiningStatus(isMining) {
|
||||
var daemonReady = !persistentSettings.useRemoteNode && appWindow.daemonSynced
|
||||
function onMiningStatus(isMining, hashrate) {
|
||||
var daemonReady = appWindow.daemonSynced
|
||||
if (!persistentSettings.allowRemoteNodeMining) {
|
||||
var daemonReady = !persistentSettings.useRemoteNode && daemonReady
|
||||
}
|
||||
appWindow.isMining = isMining;
|
||||
updateStatusText()
|
||||
updateStatusText(hashrate)
|
||||
startSoloMinerButton.enabled = !appWindow.isMining && daemonReady
|
||||
stopSoloMinerButton.enabled = !startSoloMinerButton.enabled && daemonReady
|
||||
}
|
||||
|
||||
function update() {
|
||||
walletManager.miningStatusAsync();
|
||||
persistentSettings.allow_p2pool_mining = miningModeDropdown.currentIndex === 1;
|
||||
if (persistentSettings.allow_p2pool_mining) {
|
||||
p2poolManager.getStatus();
|
||||
}
|
||||
else {
|
||||
walletManager.miningStatusAsync();
|
||||
}
|
||||
}
|
||||
|
||||
function miningError(message) {
|
||||
p2poolManager.exit()
|
||||
errorPopup.title = qsTr("Error starting mining") + translationManager.emptyString;
|
||||
errorPopup.text = message
|
||||
if (persistentSettings.useRemoteNode && !persistentSettings.allowRemoteNodeMining)
|
||||
errorPopup.text += qsTr("Mining is only available on local daemons. Run a local daemon to be able to mine.<br>") + translationManager.emptyString
|
||||
errorPopup.icon = StandardIcon.Critical
|
||||
errorPopup.open()
|
||||
}
|
||||
|
||||
MoneroComponents.StandardDialog {
|
||||
@@ -338,21 +577,67 @@ Rectangle {
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 2000; running: false; repeat: true
|
||||
interval: 2000
|
||||
running: middlePanel.advancedView.state === "Mining" && middlePanel.state === "Advanced" && currentWallet !== undefined && (!persistentSettings.useRemoteNode || persistentSettings.allowRemoteNodeMining)
|
||||
repeat: true
|
||||
onTriggered: update()
|
||||
}
|
||||
|
||||
function onPageCompleted() {
|
||||
console.log("Mining page loaded");
|
||||
update()
|
||||
timer.running = !persistentSettings.useRemoteNode
|
||||
function startP2PoolLocal() {
|
||||
var noSync = false;
|
||||
var customDaemonArgs = persistentSettings.daemonFlags.toLowerCase();
|
||||
var daemonArgs = "--zmq-pub " + "tcp://127.0.0.1:18083 " + "--disable-dns-checkpoints "
|
||||
if (!customDaemonArgs.includes("--zmq-pub") && !customDaemonArgs.includes("--disable-dns-checkpoints") && !customDaemonArgs.includes("--no-zmq")) {
|
||||
daemonArgs = daemonArgs + customDaemonArgs;
|
||||
}
|
||||
var success = daemonManager.start(daemonArgs, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress, noSync, persistentSettings.pruneBlockchain)
|
||||
if (success) {
|
||||
startP2Pool()
|
||||
}
|
||||
else {
|
||||
miningError(qsTr("Couldn't start mining.<br>") + translationManager.emptyString)
|
||||
}
|
||||
}
|
||||
|
||||
function onPageClosed() {
|
||||
timer.running = false
|
||||
function startP2Pool() {
|
||||
var address = currentWallet.address(0, 0);
|
||||
var chain = "mini"
|
||||
if (chainDropdown.currentIndex === 1) {
|
||||
chain = "main"
|
||||
}
|
||||
var p2poolArgs = persistentSettings.p2poolFlags;
|
||||
var success = p2poolManager.start(p2poolArgs, address, chain, threads);
|
||||
if (success)
|
||||
{
|
||||
update()
|
||||
}
|
||||
else {
|
||||
miningError(qsTr("Couldn't start mining.<br>") + translationManager.emptyString)
|
||||
}
|
||||
}
|
||||
|
||||
function p2poolDownloadFailed() {
|
||||
statusMessage.visible = false
|
||||
errorPopup.title = qsTr("P2Pool Installation Failed") + translationManager.emptyString;
|
||||
errorPopup.text = qsTr("P2Pool installation failed.") + isWindows ? (" " + qsTr("Try starting the program with administrator privileges.")) : ""
|
||||
errorPopup.icon = StandardIcon.Critical
|
||||
errorPopup.open()
|
||||
update()
|
||||
}
|
||||
|
||||
function p2poolDownloadSucceeded() {
|
||||
statusMessage.visible = false
|
||||
informationPopup.title = qsTr("P2Pool Installation Succeeded") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("P2Pool has successfully installed.");
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.open()
|
||||
update()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
walletManager.miningStatus.connect(onMiningStatus);
|
||||
p2poolManager.p2poolStatus.connect(onMiningStatus);
|
||||
p2poolManager.p2poolDownloadFailure.connect(p2poolDownloadFailed);
|
||||
p2poolManager.p2poolDownloadSuccess.connect(p2poolDownloadSucceeded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +580,8 @@ Rectangle {
|
||||
Layout.fillHeight: true
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
color: "darkgrey"
|
||||
property int currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
|
||||
color: MoneroComponents.Style.accountColors[currentAccountIndex % MoneroComponents.Style.accountColors.length]
|
||||
width: 2
|
||||
}
|
||||
|
||||
|
||||
@@ -957,7 +957,7 @@ Rectangle {
|
||||
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
|
||||
title: qsTr("Offline transaction signing") + translationManager.emptyString
|
||||
button1.text: qsTr("Create") + translationManager.emptyString
|
||||
button1.enabled: appWindow.viewOnly && pageRoot.checkInformation()
|
||||
button1.enabled: appWindow.viewOnly && pageRoot.checkInformation() && appWindow.daemonSynced
|
||||
button1.onClicked: {
|
||||
console.log("Transfer: saveTx Clicked")
|
||||
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
|
||||
@@ -1030,24 +1030,7 @@ Rectangle {
|
||||
// deleting transaction object, we don't want memleaks
|
||||
transaction.destroy();
|
||||
} else {
|
||||
confirmationDialog.text = qsTr("\nNumber of transactions: ") + transaction.txCount
|
||||
for (var i = 0; i < transaction.txCount; ++i) {
|
||||
confirmationDialog.text += qsTr("\nTransaction #%1").arg(i+1)
|
||||
+qsTr("\nRecipient: ") + transaction.recipientAddress[i]
|
||||
+ (transaction.paymentId[i] == "" ? "" : qsTr("\n\payment ID: ") + transaction.paymentId[i])
|
||||
+ qsTr("\nAmount: ") + walletManager.displayAmount(transaction.amount(i))
|
||||
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee(i))
|
||||
+ qsTr("\nRingsize: ") + (transaction.mixin(i)+1)
|
||||
|
||||
// TODO: add descriptions to unsigned_tx_set?
|
||||
// + (transactionDescription === "" ? "" : (qsTr("\n\nDescription: ") + transactionDescription))
|
||||
+ translationManager.emptyString
|
||||
if (i > 0) {
|
||||
confirmationDialog.text += "\n\n"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
confirmationDialog.text = qsTr("\nConfirmation message:\n ") + transaction.confirmationMessage
|
||||
console.log(transaction.confirmationMessage);
|
||||
|
||||
// Show confirmation dialog
|
||||
|
||||
@@ -60,13 +60,13 @@ Rectangle {
|
||||
MoneroComponents.Label {
|
||||
id: soloTitleLabel
|
||||
fontSize: 24
|
||||
text: qsTr("Prove Transaction") + translationManager.emptyString
|
||||
text: qsTr("Prove Transaction") + " / " + qsTr("Reserve") + translationManager.emptyString
|
||||
}
|
||||
|
||||
MoneroComponents.TextPlain {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Generate a proof of your incoming/outgoing payment by supplying the transaction ID, the recipient address and an optional message. \n" +
|
||||
"For the case of outgoing payments, you can get a 'Spend Proof' that proves the authorship of a transaction. In this case, you don't need to specify the recipient address.") + translationManager.emptyString
|
||||
"For the case of outgoing payments, you can get a 'Spend Proof' that proves the authorship of a transaction. In this case, you don't need to specify the recipient address.") + qsTr("\nFor reserve proofs you don't need to specify tx id or address.") + translationManager.emptyString
|
||||
wrapMode: Text.Wrap
|
||||
font.family: MoneroComponents.Style.fontRegular.name
|
||||
font.pixelSize: 14
|
||||
@@ -83,6 +83,7 @@ Rectangle {
|
||||
placeholderText: qsTr("Paste tx ID") + translationManager.emptyString
|
||||
readOnly: false
|
||||
copyButton: true
|
||||
enabled: getReserveProofAmtLine.text.length === 0
|
||||
}
|
||||
|
||||
MoneroComponents.LineEdit {
|
||||
@@ -95,6 +96,38 @@ Rectangle {
|
||||
placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString;
|
||||
readOnly: false
|
||||
copyButton: true
|
||||
enabled: getReserveProofAmtLine.text.length === 0
|
||||
}
|
||||
|
||||
MoneroComponents.LineEdit {
|
||||
id: getReserveProofAmtLine
|
||||
Layout.fillWidth: true
|
||||
labelFontSize: 14
|
||||
labelText: qsTr("Amount") + translationManager.emptyString
|
||||
fontSize: 16
|
||||
placeholderFontSize: 16
|
||||
placeholderText: qsTr("Paste amount of XMR (reserve proof only)") + translationManager.emptyString
|
||||
readOnly: false
|
||||
copyButton: true
|
||||
enabled: getProofAddressLine.text.length === 0 && getProofTxIdLine.text.length === 0
|
||||
onTextChanged: {
|
||||
text = text.trim().replace(",", ".");
|
||||
const match = text.match(/^0+(\d.*)/);
|
||||
if (match) {
|
||||
const cursorPosition = cursorPosition;
|
||||
text = match[1];
|
||||
cursorPosition = Math.max(cursorPosition, 1) - 1;
|
||||
} else if(text.indexOf('.') === 0) {
|
||||
text = '0' + text;
|
||||
if (text.length > 2) {
|
||||
cursorPosition = 1;
|
||||
}
|
||||
}
|
||||
error = walletManager.amountFromString(text) > appWindow.getUnlockedBalance();
|
||||
}
|
||||
validator: RegExpValidator {
|
||||
regExp: /^\s*(\d{1,8})?([\.,]\d{1,12})?\s*$/
|
||||
}
|
||||
}
|
||||
|
||||
MoneroComponents.LineEdit {
|
||||
@@ -113,10 +146,10 @@ Rectangle {
|
||||
Layout.topMargin: 16
|
||||
small: true
|
||||
text: qsTr("Generate") + translationManager.emptyString
|
||||
enabled: TxUtils.checkTxID(getProofTxIdLine.text) && (getProofAddressLine.text.length == 0 || TxUtils.checkAddress(getProofAddressLine.text, appWindow.persistentSettings.nettype))
|
||||
enabled: TxUtils.checkTxID(getProofTxIdLine.text) && (getProofAddressLine.text.length == 0 || TxUtils.checkAddress(getProofAddressLine.text, appWindow.persistentSettings.nettype)) || getReserveProofAmtLine.text.length != 0 && walletManager.amountFromString(getReserveProofAmtLine.text) < appWindow.getUnlockedBalance() && walletManager.amountFromString(getReserveProofAmtLine.text) > 0
|
||||
onClicked: {
|
||||
console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text);
|
||||
middlePanel.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text)
|
||||
middlePanel.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text, getReserveProofAmtLine.text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,12 +166,12 @@ Rectangle {
|
||||
MoneroComponents.Label {
|
||||
id: soloTitleLabel2
|
||||
fontSize: 24
|
||||
text: qsTr("Check Transaction") + translationManager.emptyString
|
||||
text: qsTr("Check Transaction") + " / " + qsTr("Reserve") + translationManager.emptyString
|
||||
}
|
||||
|
||||
MoneroComponents.TextPlain {
|
||||
text: qsTr("Verify that funds were paid to an address by supplying the transaction ID, the recipient address, the message used for signing and the signature.\n" +
|
||||
"For the case with Spend Proof, you don't need to specify the recipient address.") + translationManager.emptyString
|
||||
"For the case with Spend Proof, you don't need to specify the recipient address.") + "\n" + qsTr("Transaction is not needed for reserve proof.") + translationManager.emptyString
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
font.family: MoneroComponents.Style.fontRegular.name
|
||||
@@ -189,7 +222,7 @@ Rectangle {
|
||||
labelFontSize: 14
|
||||
labelText: qsTr("Signature") + translationManager.emptyString
|
||||
placeholderFontSize: 16
|
||||
placeholderText: qsTr("Paste tx proof") + translationManager.emptyString;
|
||||
placeholderText: qsTr("Paste tx proof") + " / " + qsTr("reserve proof") + translationManager.emptyString;
|
||||
readOnly: false
|
||||
copyButton: true
|
||||
}
|
||||
@@ -198,7 +231,7 @@ Rectangle {
|
||||
Layout.topMargin: 16
|
||||
small: true
|
||||
text: qsTr("Check") + translationManager.emptyString
|
||||
enabled: TxUtils.checkTxID(checkProofTxIdLine.text) && TxUtils.checkSignature(checkProofSignatureLine.text) && ((checkProofSignatureLine.text.indexOf("SpendProofV") === 0 && checkProofAddressLine.text.length == 0) || (checkProofSignatureLine.text.indexOf("SpendProofV") !== 0 && TxUtils.checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.nettype)))
|
||||
enabled: (TxUtils.checkTxID(checkProofTxIdLine.text) && TxUtils.checkSignature(checkProofSignatureLine.text) && ((checkProofSignatureLine.text.indexOf("SpendProofV") === 0 && checkProofAddressLine.text.length == 0) || (checkProofSignatureLine.text.indexOf("SpendProofV") !== 0 && TxUtils.checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.nettype)))) || (TxUtils.checkSignature(checkProofSignatureLine.text) && checkProofSignatureLine.text.indexOf("ReserveProofV") === 0 && TxUtils.checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.nettype))
|
||||
onClicked: {
|
||||
console.log("checkProof: Check clicked: txid " + checkProofTxIdLine.text + ", address " + checkProofAddressLine.text + ", message " + checkProofMessageLine.text + ", signature " + checkProofSignatureLine.text);
|
||||
middlePanel.checkProofClicked(checkProofTxIdLine.text, checkProofAddressLine.text, checkProofMessageLine.text, checkProofSignatureLine.text)
|
||||
|
||||
@@ -49,6 +49,7 @@ ColumnLayout {
|
||||
property alias settingsStateViewState: settingsStateView.state
|
||||
|
||||
MoneroComponents.Navbar {
|
||||
id: navbarId
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: height
|
||||
Layout.bottomMargin: height
|
||||
@@ -145,7 +146,7 @@ ColumnLayout {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: 0 - target.width
|
||||
from: (navbarId.currentIndex < navbarId.previousIndex ? 1 : -1) * - target.width
|
||||
to: 0
|
||||
duration: 300
|
||||
easing.type: Easing.OutCubic
|
||||
@@ -154,7 +155,7 @@ ColumnLayout {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: target.width
|
||||
to: (navbarId.currentIndex < navbarId.previousIndex ? 1 : -1) * target.width
|
||||
duration: 300
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ Rectangle {
|
||||
inputDialog.onAcceptedCallback = function() {
|
||||
var _restoreHeight;
|
||||
if (inputDialog.inputText) {
|
||||
_restoreHeight = Utils.parseDateStringOrRestoreHeightAsInteger(inputDialog.inputText);
|
||||
_restoreHeight = Utils.parseDateStringOrRestoreHeightAsInteger(inputDialog.inputText.trim());
|
||||
}
|
||||
if (!isNaN(_restoreHeight)) {
|
||||
if(_restoreHeight >= 0) {
|
||||
@@ -409,7 +409,7 @@ Rectangle {
|
||||
small: true
|
||||
text: qsTr("Donate to Monero") + translationManager.emptyString
|
||||
onClicked: {
|
||||
middlePanel.sendTo("888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H", "", "Donation to Monero Core Team");
|
||||
middlePanel.sendTo("888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H", "", qsTr("Donation to Monero Core Team") + translationManager.emptyString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,12 @@ Rectangle {
|
||||
onMoved: persistentSettings.lockOnUserInActivityInterval = value
|
||||
}
|
||||
|
||||
MoneroComponents.CheckBox {
|
||||
checked: persistentSettings.askStopLocalNode
|
||||
onClicked: persistentSettings.askStopLocalNode = !persistentSettings.askStopLocalNode
|
||||
text: qsTr("Ask to stop local node during program exit") + translationManager.emptyString
|
||||
}
|
||||
|
||||
//! Manage pricing
|
||||
RowLayout {
|
||||
MoneroComponents.CheckBox {
|
||||
@@ -165,7 +171,6 @@ Rectangle {
|
||||
if (!checked) {
|
||||
console.log("Disabled price conversion");
|
||||
persistentSettings.fiatPriceEnabled = false;
|
||||
appWindow.fiatTimerStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,8 +237,6 @@ Rectangle {
|
||||
onClicked: {
|
||||
console.log("Enabled price conversion");
|
||||
persistentSettings.fiatPriceEnabled = true;
|
||||
appWindow.fiatApiRefresh();
|
||||
appWindow.fiatTimerStart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,14 @@ Rectangle {
|
||||
anchors.topMargin: 0
|
||||
spacing: 0
|
||||
|
||||
MoneroComponents.SettingsListItem {
|
||||
iconText: FontAwesome.lock
|
||||
description: qsTr("Locks the wallet on demand.") + translationManager.emptyString
|
||||
title: qsTr("Lock this wallet") + translationManager.emptyString
|
||||
symbol: (isMac ? "⌃" : qsTr("Ctrl+")) + "L" + translationManager.emptyString
|
||||
onClicked: appWindow.lock();
|
||||
}
|
||||
|
||||
MoneroComponents.SettingsListItem {
|
||||
iconText: FontAwesome.signOutAlt
|
||||
description: qsTr("Logs out of this wallet.") + translationManager.emptyString
|
||||
@@ -91,6 +99,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
MoneroComponents.SettingsListItem {
|
||||
enabled: leftPanel.progressBar.fillLevel == 100
|
||||
iconText: FontAwesome.repeat
|
||||
description: qsTr("Use this feature if you think the shown balance is not accurate.") + translationManager.emptyString
|
||||
title: qsTr("Rescan wallet balance") + translationManager.emptyString
|
||||
@@ -100,7 +109,11 @@ Rectangle {
|
||||
if (!currentWallet.rescanSpent()) {
|
||||
console.error("Error: ", currentWallet.errorString);
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("Error: ") + currentWallet.errorString
|
||||
if (currentWallet.errorString == "Rescan spent can only be used with a trusted daemon") {
|
||||
informationPopup.text = qsTr("Error: ") + qsTr("Rescan spent can only be used with a trusted remote node. If you trust the current node you are connected to (%1), you can mark it as trusted in Settings > Node page.").arg(remoteNodesModel.currentRemoteNode().address) + translationManager.emptyString;
|
||||
} else {
|
||||
informationPopup.text = qsTr("Error: ") + currentWallet.errorString;
|
||||
}
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open();
|
||||
@@ -114,6 +127,27 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
MoneroComponents.SettingsListItem {
|
||||
enabled: leftPanel.progressBar.fillLevel == 100
|
||||
iconText: FontAwesome.magnifyingGlass
|
||||
description: qsTr("Use this feature if a transaction is missing in your wallet history. This will expose the transaction ID to the remote node, which can harm your privacy.") + translationManager.emptyString
|
||||
title: qsTr("Scan transaction") + translationManager.emptyString
|
||||
|
||||
onClicked: {
|
||||
inputDialog.labelText = qsTr("Enter a transaction ID:") + translationManager.emptyString;
|
||||
inputDialog.onAcceptedCallback = function() {
|
||||
var txid = inputDialog.inputText.trim();
|
||||
if (currentWallet.scanTransactions([txid])) {
|
||||
appWindow.showStatusMessage(qsTr("Transaction successfully scanned"), 3);
|
||||
} else {
|
||||
appWindow.showStatusMessage(qsTr("Failed to scan transaction") + ": " + currentWallet.errorString, 5);
|
||||
}
|
||||
}
|
||||
inputDialog.onRejectedCallback = null;
|
||||
inputDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
MoneroComponents.SettingsListItem {
|
||||
iconText: FontAwesome.ellipsisH
|
||||
description: qsTr("Change the password of your wallet.") + translationManager.emptyString
|
||||
|
||||
22
qml.qrc
@@ -97,6 +97,9 @@
|
||||
<file>lang/flags/gb.png</file>
|
||||
<file>lang/flags/us.png</file>
|
||||
<file>lang/flags/nb_NO.png</file>
|
||||
<file>lang/flags/el.png</file>
|
||||
<file>lang/flags/vi.png</file>
|
||||
<file>lang/flags/is.png</file>
|
||||
<file>pages/Receive.qml</file>
|
||||
<file>pages/TxKey.qml</file>
|
||||
<file>pages/SharedRingDB.qml</file>
|
||||
@@ -116,8 +119,22 @@
|
||||
<file>components/RemoteNodeEdit.qml</file>
|
||||
<file>pages/Keys.qml</file>
|
||||
<file>images/appicon.ico</file>
|
||||
<file>images/card-background-black.png</file>
|
||||
<file>images/card-background-black@2x.png</file>
|
||||
<file>images/card-background-black0.png</file>
|
||||
<file>images/card-background-black1.png</file>
|
||||
<file>images/card-background-black2.png</file>
|
||||
<file>images/card-background-black3.png</file>
|
||||
<file>images/card-background-black4.png</file>
|
||||
<file>images/card-background-black5.png</file>
|
||||
<file>images/card-background-black6.png</file>
|
||||
<file>images/card-background-black7.png</file>
|
||||
<file>images/card-background-black0@2x.png</file>
|
||||
<file>images/card-background-black1@2x.png</file>
|
||||
<file>images/card-background-black2@2x.png</file>
|
||||
<file>images/card-background-black3@2x.png</file>
|
||||
<file>images/card-background-black4@2x.png</file>
|
||||
<file>images/card-background-black5@2x.png</file>
|
||||
<file>images/card-background-black6@2x.png</file>
|
||||
<file>images/card-background-black7@2x.png</file>
|
||||
<file>images/card-background-white.png</file>
|
||||
<file>images/card-background-white@2x.png</file>
|
||||
<file>images/moneroLogo_white.png</file>
|
||||
@@ -261,6 +278,7 @@
|
||||
<file>components/SuccessfulTxDialog.qml</file>
|
||||
<file>components/TxConfirmationDialog.qml</file>
|
||||
<file>images/ledgerNanoS.png</file>
|
||||
<file>images/ledgerNanoSPlus.png</file>
|
||||
<file>images/ledgerNanoX.png</file>
|
||||
<file>images/trezor.png</file>
|
||||
<file>images/trezor@2x.png</file>
|
||||
|
||||
@@ -36,6 +36,8 @@ file(GLOB SOURCE_FILES
|
||||
"libwalletqt/UnsignedTransaction.h"
|
||||
"daemon/*.h"
|
||||
"daemon/*.cpp"
|
||||
"p2pool/*.h"
|
||||
"p2pool/*.cpp"
|
||||
"model/*.h"
|
||||
"model/*.cpp"
|
||||
"qt/*.h"
|
||||
@@ -97,6 +99,7 @@ target_include_directories(monero-wallet-gui PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/monero/external/qrcodegen
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/daemon
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/p2pool
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libwalletqt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/model
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/QR-Code-scanner
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "PendingTransaction.h"
|
||||
#include "UnsignedTransaction.h"
|
||||
@@ -99,20 +101,30 @@ NetworkType::Type Wallet::nettype() const
|
||||
void Wallet::updateConnectionStatusAsync()
|
||||
{
|
||||
m_scheduler.run([this] {
|
||||
qDebug() << "updateConnectionStatusAsync current status:" << m_connectionStatus;
|
||||
if (m_connectionStatus == Wallet::ConnectionStatus_Disconnected)
|
||||
{
|
||||
setConnectionStatus(ConnectionStatus_Connecting);
|
||||
}
|
||||
ConnectionStatus newStatus = static_cast<ConnectionStatus>(m_walletImpl->connected());
|
||||
setConnectionStatus(newStatus);
|
||||
qDebug() << "Newest wallet status:" << newStatus;
|
||||
if (m_connectionStatus != newStatus)
|
||||
{
|
||||
setConnectionStatus(newStatus);
|
||||
if (newStatus == ConnectionStatus_Connected)
|
||||
{
|
||||
startRefresh();
|
||||
}
|
||||
}
|
||||
// Release lock
|
||||
m_connectionStatusRunning = false;
|
||||
m_connectionStatusTime.restart();
|
||||
});
|
||||
}
|
||||
|
||||
Wallet::ConnectionStatus Wallet::connected(bool forceCheck)
|
||||
{
|
||||
if (!m_initialized)
|
||||
if (!m_initialized || m_initializing)
|
||||
{
|
||||
return ConnectionStatus_Connecting;
|
||||
}
|
||||
@@ -121,7 +133,6 @@ Wallet::ConnectionStatus Wallet::connected(bool forceCheck)
|
||||
if (forceCheck || (m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl && !m_connectionStatusRunning) || m_connectionStatusTime.elapsed() > 30000) {
|
||||
qDebug() << "Checking connection status";
|
||||
m_connectionStatusRunning = true;
|
||||
m_connectionStatusTime.restart();
|
||||
updateConnectionStatusAsync();
|
||||
}
|
||||
|
||||
@@ -154,10 +165,9 @@ void Wallet::setConnectionStatus(ConnectionStatus value)
|
||||
}
|
||||
|
||||
m_connectionStatus = value;
|
||||
emit connectionStatusChanged(m_connectionStatus);
|
||||
emit connectionStatusChanged(value);
|
||||
|
||||
bool disconnected = m_connectionStatus == Wallet::ConnectionStatus_Connecting ||
|
||||
m_connectionStatus == Wallet::ConnectionStatus_Disconnected;
|
||||
bool disconnected = value != Wallet::ConnectionStatus_Connected;
|
||||
|
||||
if (m_disconnected != disconnected)
|
||||
{
|
||||
@@ -278,6 +288,8 @@ void Wallet::initAsync(
|
||||
const QString &proxyAddress /* = "" */)
|
||||
{
|
||||
qDebug() << "initAsync: " + daemonAddress;
|
||||
m_initializing = true;
|
||||
pauseRefresh();
|
||||
const auto future = m_scheduler.run([this, daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight, proxyAddress] {
|
||||
m_initialized = init(
|
||||
daemonAddress,
|
||||
@@ -287,12 +299,12 @@ void Wallet::initAsync(
|
||||
isRecoveringFromDevice,
|
||||
restoreHeight,
|
||||
proxyAddress);
|
||||
m_initializing = false;
|
||||
if (m_initialized)
|
||||
{
|
||||
emit walletCreationHeightChanged();
|
||||
qDebug() << "init async finished - starting refresh";
|
||||
qDebug() << "init async finished: " + daemonAddress;
|
||||
connected(true);
|
||||
startRefresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -507,6 +519,16 @@ bool Wallet::importOutputs(const QString& path) {
|
||||
return m_walletImpl->importOutputs(path.toStdString());
|
||||
}
|
||||
|
||||
bool Wallet::scanTransactions(const QVector<QString> &txids)
|
||||
{
|
||||
std::vector<std::string> c;
|
||||
for (const auto &v : txids)
|
||||
{
|
||||
c.push_back(v.toStdString());
|
||||
}
|
||||
return m_walletImpl->scanTransactions(c);
|
||||
}
|
||||
|
||||
bool Wallet::refresh(bool historyAndSubaddresses /* = true */)
|
||||
{
|
||||
refreshingSet(true);
|
||||
@@ -532,11 +554,14 @@ bool Wallet::refresh(bool historyAndSubaddresses /* = true */)
|
||||
|
||||
void Wallet::startRefresh()
|
||||
{
|
||||
qDebug() << "Starting refresh";
|
||||
m_refreshEnabled = true;
|
||||
m_refreshNow = true;
|
||||
}
|
||||
|
||||
void Wallet::pauseRefresh()
|
||||
{
|
||||
qDebug() << "Pausing refresh";
|
||||
m_refreshEnabled = false;
|
||||
}
|
||||
|
||||
@@ -844,6 +869,25 @@ Q_INVOKABLE QString Wallet::checkSpendProof(const QString &txid, const QString &
|
||||
return QString::fromStdString(result);
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString Wallet::getReserveProof(bool all, quint32 account_index, quint64 amount, const QString &message) const
|
||||
{
|
||||
qDebug("Generating reserve proof");
|
||||
std::string result = m_walletImpl->getReserveProof(all, account_index, amount, message.toStdString());
|
||||
if (result.empty())
|
||||
result = "error|" + m_walletImpl->errorString();
|
||||
return QString::fromStdString(result);
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString Wallet::checkReserveProof(const QString &address, const QString &message, const QString &signature) const
|
||||
{
|
||||
bool good;
|
||||
uint64_t total;
|
||||
uint64_t spent;
|
||||
bool success = m_walletImpl->checkReserveProof(address.toStdString(), message.toStdString(), signature.toStdString(), good, total, spent);
|
||||
std::string result = std::string(success ? "true" : "false") + "|" + std::string(good ? "true" : "false") + "|" + QString::number(total).toStdString() + "|" + QString::number(spent).toStdString();
|
||||
return QString::fromStdString(result);
|
||||
}
|
||||
|
||||
QString Wallet::signMessage(const QString &message, bool filename) const
|
||||
{
|
||||
if (filename) {
|
||||
@@ -1106,11 +1150,13 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
|
||||
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
|
||||
, m_disconnected(true)
|
||||
, m_initialized(false)
|
||||
, m_initializing(false)
|
||||
, m_currentSubaddressAccount(0)
|
||||
, m_subaddress(new Subaddress(m_walletImpl->subaddress(), this))
|
||||
, m_subaddressModel(nullptr)
|
||||
, m_subaddressAccount(new SubaddressAccount(m_walletImpl->subaddressAccount(), this))
|
||||
, m_subaddressAccountModel(nullptr)
|
||||
, m_refreshNow(false)
|
||||
, m_refreshEnabled(false)
|
||||
, m_refreshing(false)
|
||||
, m_scheduler(this)
|
||||
@@ -1164,10 +1210,11 @@ void Wallet::startRefreshThread()
|
||||
{
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const auto elapsed = now - last;
|
||||
if (elapsed >= refreshInterval)
|
||||
if (elapsed >= refreshInterval || m_refreshNow)
|
||||
{
|
||||
refresh(false);
|
||||
last = std::chrono::steady_clock::now();
|
||||
m_refreshNow = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -212,6 +212,9 @@ public:
|
||||
Q_INVOKABLE bool exportOutputs(const QString& path, bool all = false);
|
||||
Q_INVOKABLE bool importOutputs(const QString& path);
|
||||
|
||||
//! scan transactions
|
||||
Q_INVOKABLE bool scanTransactions(const QVector<QString> &txids);
|
||||
|
||||
//! refreshes the wallet
|
||||
Q_INVOKABLE bool refresh(bool historyAndSubaddresses = true);
|
||||
|
||||
@@ -318,6 +321,8 @@ public:
|
||||
Q_INVOKABLE QString getSpendProof(const QString &txid, const QString &message) const;
|
||||
Q_INVOKABLE void getSpendProofAsync(const QString &txid, const QString &message, const QJSValue &callback);
|
||||
Q_INVOKABLE QString checkSpendProof(const QString &txid, const QString &message, const QString &signature) const;
|
||||
Q_INVOKABLE QString getReserveProof(bool all, quint32 account_index, quint64 amount, const QString &message) const;
|
||||
Q_INVOKABLE QString checkReserveProof(const QString &address, const QString &message, const QString &signature) const;
|
||||
// Rescan spent outputs
|
||||
Q_INVOKABLE bool rescanSpent();
|
||||
|
||||
@@ -456,6 +461,7 @@ private:
|
||||
mutable QElapsedTimer m_connectionStatusTime;
|
||||
bool m_disconnected;
|
||||
std::atomic<bool> m_initialized;
|
||||
std::atomic<bool> m_initializing;
|
||||
uint32_t m_currentSubaddressAccount;
|
||||
Subaddress * m_subaddress;
|
||||
mutable SubaddressModel * m_subaddressModel;
|
||||
@@ -468,6 +474,7 @@ private:
|
||||
QString m_daemonPassword;
|
||||
QString m_proxyAddress;
|
||||
mutable QMutex m_proxyMutex;
|
||||
std::atomic<bool> m_refreshNow;
|
||||
std::atomic<bool> m_refreshEnabled;
|
||||
std::atomic<bool> m_refreshing;
|
||||
WalletListenerImpl *m_walletListener;
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <QObject>
|
||||
#include <QDesktopWidget>
|
||||
#include <QScreen>
|
||||
#include <QRegExp>
|
||||
#include <QThread>
|
||||
|
||||
#include <version.h>
|
||||
@@ -79,6 +78,7 @@
|
||||
// IOS exclusions
|
||||
#ifndef Q_OS_IOS
|
||||
#include "daemon/DaemonManager.h"
|
||||
#include "p2pool/P2PoolManager.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
@@ -205,6 +205,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
qputenv("QML_DISABLE_DISK_CACHE", "1");
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (QString(argv[i]).contains("platformpluginpath")) {
|
||||
qCritical() << "Setting -platformpluginpath as an argument is disabled"; // CVE-2021-3401
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
MainApp app(argc, argv);
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
@@ -401,6 +408,8 @@ Verify update binary using 'shasum'-compatible (SHA256 algo) output signed by tw
|
||||
#ifndef Q_OS_IOS
|
||||
qmlRegisterUncreatableType<DaemonManager>("moneroComponents.DaemonManager", 1, 0, "DaemonManager",
|
||||
"DaemonManager can't be instantiated directly");
|
||||
qmlRegisterUncreatableType<P2PoolManager>("moneroComponents.P2PoolManager", 1, 0, "P2PoolManager",
|
||||
"P2PoolManager can't be instantiated directly");
|
||||
#endif
|
||||
qmlRegisterUncreatableType<AddressBookModel>("moneroComponents.AddressBookModel", 1, 0, "AddressBookModel",
|
||||
"AddressBookModel can't be instantiated directly");
|
||||
@@ -462,7 +471,9 @@ Verify update binary using 'shasum'-compatible (SHA256 algo) output signed by tw
|
||||
// Exclude daemon manager from IOS
|
||||
#ifndef Q_OS_IOS
|
||||
DaemonManager daemonManager;
|
||||
P2PoolManager p2poolManager;
|
||||
engine.rootContext()->setContextProperty("daemonManager", &daemonManager);
|
||||
engine.rootContext()->setContextProperty("p2poolManager", &p2poolManager);
|
||||
#endif
|
||||
|
||||
engine.rootContext()->setContextProperty("isWindows", isWindows);
|
||||
@@ -493,7 +504,11 @@ Verify update binary using 'shasum'-compatible (SHA256 algo) output signed by tw
|
||||
engine.rootContext()->setContextProperty("homePath", QDir::homePath());
|
||||
engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
|
||||
engine.rootContext()->setContextProperty("idealThreadCount", QThread::idealThreadCount());
|
||||
#ifdef WITH_UPDATER
|
||||
engine.rootContext()->setContextProperty("disableCheckUpdatesFlag", parser.isSet(disableCheckUpdatesOption));
|
||||
#else
|
||||
engine.rootContext()->setContextProperty("disableCheckUpdatesFlag", true);
|
||||
#endif
|
||||
engine.rootContext()->setContextProperty("socksProxyFlag", parser.value(socksProxyOption));
|
||||
engine.rootContext()->setContextProperty("socksProxyFlagSet", parser.isSet(socksProxyOption));
|
||||
|
||||
@@ -503,6 +518,12 @@ Verify update binary using 'shasum'-compatible (SHA256 algo) output signed by tw
|
||||
#endif
|
||||
engine.rootContext()->setContextProperty("builtWithScanner", builtWithScanner);
|
||||
|
||||
bool builtWithDesktopEntry = false;
|
||||
#ifdef WITH_DESKTOP_ENTRY
|
||||
builtWithDesktopEntry = true;
|
||||
#endif
|
||||
engine.rootContext()->setContextProperty("builtWithDesktopEntry", builtWithDesktopEntry);
|
||||
|
||||
engine.rootContext()->setContextProperty("moneroVersion", MONERO_VERSION_FULL);
|
||||
|
||||
// Load main window (context properties needs to be defined obove this line)
|
||||
|
||||
@@ -174,7 +174,7 @@ bool OSHelper::openContainingFolder(const QString &filePath) const
|
||||
}
|
||||
#endif
|
||||
|
||||
QUrl url = QUrl::fromLocalFile(canonicalFilePath);
|
||||
QUrl url = QUrl::fromLocalFile(QFileInfo(filePath).canonicalPath());
|
||||
if (!url.isValid())
|
||||
{
|
||||
qWarning() << "Malformed file path" << canonicalFilePath << url.errorString();
|
||||
|
||||
245
src/p2pool/P2PoolManager.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright (c) 2014-2022, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "P2PoolManager.h"
|
||||
#include "net/http_client.h"
|
||||
#include "common/util.h"
|
||||
#include "qt/utils.h"
|
||||
#include <QElapsedTimer>
|
||||
#include <QFile>
|
||||
#include <QMutexLocker>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QApplication>
|
||||
#include <QProcess>
|
||||
#include <QMap>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
void P2PoolManager::download() {
|
||||
m_scheduler.run([this] {
|
||||
QUrl url;
|
||||
QString fileName;
|
||||
QString validHash;
|
||||
#ifdef Q_OS_WIN
|
||||
url = "https://github.com/SChernykh/p2pool/releases/download/v2.2.1/p2pool-v2.2.1-windows-x64.zip";
|
||||
fileName = m_p2poolPath + "/p2pool-v2.2.1-windows-x64.zip";
|
||||
validHash = "06b6fe302600c959007bf94e7a5b445f45f823dc4e43ae6cf03b3b98a805167a";
|
||||
#elif defined(Q_OS_LINUX)
|
||||
url = "https://github.com/SChernykh/p2pool/releases/download/v2.2.1/p2pool-v2.2.1-linux-x64.tar.gz";
|
||||
fileName = m_p2poolPath + "/p2pool-v2.2.1-linux-x64.tar.gz";
|
||||
validHash = "02f1daea0f8f99076b7da3368a43cc3989b800f8b5afaf4dfc7e8f9bdc27d274";
|
||||
#elif defined(Q_OS_MACOS)
|
||||
url = "https://github.com/SChernykh/p2pool/releases/download/v2.2.1/p2pool-v2.2.1-macos-x64.tar.gz";
|
||||
fileName = m_p2poolPath + "/p2pool-v2.2.1-macos-x64.tar.gz";
|
||||
validHash = "d973a8dca922f209dfb6f203006f93664e19d870975621bec07e9d855e79d7d5";
|
||||
#endif
|
||||
QFile file(fileName);
|
||||
epee::net_utils::http::http_simple_client http_client;
|
||||
const epee::net_utils::http::http_response_info* response = NULL;
|
||||
std::string userAgent = randomUserAgent().toStdString();
|
||||
std::chrono::milliseconds timeout = std::chrono::seconds(10);
|
||||
http_client.set_server(url.host().toStdString(), "443", {});
|
||||
bool success = http_client.invoke_get(url.path().toStdString(), timeout, {}, std::addressof(response), {{"User-Agent", userAgent}});
|
||||
if (response->m_response_code == 302) {
|
||||
epee::net_utils::http::fields_list fields = response->m_header_info.m_etc_fields;
|
||||
for (std::pair<std::string, std::string> i : fields) {
|
||||
if (i.first == "Location") {
|
||||
url = QString::fromStdString(i.second);
|
||||
http_client.set_server(url.host().toStdString(), "443", {});
|
||||
std::string query = url.query(QUrl::FullyEncoded).toStdString();
|
||||
std::string path = url.path().toStdString() + "?" + query;
|
||||
http_client.wipe_response();
|
||||
success = http_client.invoke_get(path, timeout, {}, std::addressof(response), {{"User-Agent", userAgent}});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
emit p2poolDownloadFailure();
|
||||
}
|
||||
else {
|
||||
std::string stringData = response->m_body;
|
||||
QByteArray data(stringData.c_str(), stringData.length());
|
||||
QByteArray hashData = QCryptographicHash::hash(data, QCryptographicHash::Sha256);
|
||||
QString hash = hashData.toHex();
|
||||
if (hash != validHash) {
|
||||
emit p2poolDownloadFailure();
|
||||
}
|
||||
else {
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(data);
|
||||
file.close();
|
||||
QProcess::execute("tar", {"-xzf", fileName, "--strip=1", "-C", m_p2poolPath});
|
||||
QFile::remove(fileName);
|
||||
if (isInstalled()) {
|
||||
emit p2poolDownloadSuccess();
|
||||
}
|
||||
else {
|
||||
emit p2poolDownloadFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
bool P2PoolManager::isInstalled() {
|
||||
if (!QFileInfo(m_p2pool).isFile())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void P2PoolManager::getStatus() {
|
||||
QString statsPath = m_p2poolPath + "/stats/local/miner";
|
||||
bool status = true;
|
||||
if (!QFileInfo(statsPath).isFile() || !started)
|
||||
{
|
||||
status = started;
|
||||
emit p2poolStatus(status, 0);
|
||||
return;
|
||||
}
|
||||
QFile statsFile(statsPath);
|
||||
statsFile.open(QIODevice::ReadOnly);
|
||||
QTextStream statsOut(&statsFile);
|
||||
QByteArray data;
|
||||
statsOut >> data;
|
||||
statsFile.close();
|
||||
QJsonDocument json = QJsonDocument::fromJson(data);
|
||||
QJsonObject jsonObj = json.object();
|
||||
int hashrate = jsonObj.value("current_hashrate").toInt();
|
||||
emit p2poolStatus(status, hashrate);
|
||||
return;
|
||||
}
|
||||
|
||||
bool P2PoolManager::start(const QString &flags, const QString &address, const QString &chain, const QString &threads)
|
||||
{
|
||||
// prepare command line arguments and pass to p2pool
|
||||
QStringList arguments;
|
||||
|
||||
// Custom startup flags for p2pool
|
||||
foreach (const QString &str, flags.split(" ")) {
|
||||
qDebug() << QString(" [%1] ").arg(str);
|
||||
if (!str.isEmpty())
|
||||
arguments << str;
|
||||
}
|
||||
|
||||
if (!arguments.contains("--local-api")) {
|
||||
arguments << "--local-api";
|
||||
}
|
||||
|
||||
if (!arguments.contains("--data-api")) {
|
||||
QDir dir;
|
||||
QString dirName = m_p2poolPath + "/stats/";
|
||||
QDir statsDir(dirName);
|
||||
if (dir.exists(dirName)) {
|
||||
statsDir.removeRecursively();
|
||||
}
|
||||
dir.mkdir(dirName);
|
||||
arguments << "--data-api" << dirName;
|
||||
}
|
||||
|
||||
if (!arguments.contains("--start-mining")) {
|
||||
arguments << "--start-mining" << threads;
|
||||
}
|
||||
|
||||
if (chain == "mini") {
|
||||
arguments << "--mini";
|
||||
}
|
||||
|
||||
if (!arguments.contains("--wallet")) {
|
||||
arguments << "--wallet" << address;
|
||||
}
|
||||
|
||||
qDebug() << "starting p2pool " + m_p2pool;
|
||||
qDebug() << "With command line arguments " << arguments;
|
||||
|
||||
QMutexLocker locker(&m_p2poolMutex);
|
||||
|
||||
m_p2poold.reset(new QProcess());
|
||||
|
||||
// Set program parameters
|
||||
m_p2poold->setProgram(m_p2pool);
|
||||
m_p2poold->setArguments(arguments);
|
||||
m_p2poold->setWorkingDirectory(m_p2poolPath);
|
||||
|
||||
// Start p2pool
|
||||
started = m_p2poold->startDetached();
|
||||
|
||||
if (!started) {
|
||||
qDebug() << "P2Pool start error: " + m_p2poold->errorString();
|
||||
emit p2poolStartFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void P2PoolManager::exit()
|
||||
{
|
||||
qDebug("P2PoolManager: exit()");
|
||||
if (started) {
|
||||
#ifdef Q_OS_WIN
|
||||
QProcess::execute("taskkill", {"/F", "/IM", "p2pool.exe"});
|
||||
#else
|
||||
QProcess::execute("pkill", {"p2pool"});
|
||||
#endif
|
||||
started = false;
|
||||
QString dirName = m_p2poolPath + "/stats/";
|
||||
QDir dir(dirName);
|
||||
dir.removeRecursively();
|
||||
}
|
||||
}
|
||||
|
||||
P2PoolManager::P2PoolManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_scheduler(this)
|
||||
{
|
||||
started = false;
|
||||
// Platform dependent path to p2pool
|
||||
#ifdef Q_OS_WIN
|
||||
m_p2poolPath = QApplication::applicationDirPath() + "/p2pool";
|
||||
if (!QDir(m_p2poolPath).exists()) {
|
||||
QDir().mkdir(m_p2poolPath);
|
||||
}
|
||||
m_p2pool = m_p2poolPath + "/p2pool.exe";
|
||||
#elif defined(Q_OS_UNIX)
|
||||
m_p2poolPath = QApplication::applicationDirPath();
|
||||
m_p2pool = m_p2poolPath + "/p2pool";
|
||||
#endif
|
||||
if (m_p2pool.length() == 0) {
|
||||
qCritical() << "no p2pool binary defined for current platform";
|
||||
}
|
||||
}
|
||||
|
||||
P2PoolManager::~P2PoolManager() {
|
||||
m_scheduler.shutdownWaitForFinished();
|
||||
}
|
||||
73
src/p2pool/P2PoolManager.h
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright (c) 2014-2022, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef P2POOLMANAGER_H
|
||||
#define P2POOLMANAGER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QProcess>
|
||||
#include "NetworkType.h"
|
||||
#include "qt/FutureScheduler.h"
|
||||
|
||||
class P2PoolManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit P2PoolManager(QObject *parent = 0);
|
||||
~P2PoolManager();
|
||||
|
||||
Q_INVOKABLE bool start(const QString &flags, const QString &address, const QString &chain, const QString &threads);
|
||||
Q_INVOKABLE void exit();
|
||||
Q_INVOKABLE bool isInstalled();
|
||||
Q_INVOKABLE void getStatus();
|
||||
Q_INVOKABLE void download();
|
||||
private:
|
||||
|
||||
bool running(NetworkType::Type nettype) const;
|
||||
signals:
|
||||
void p2poolStartFailure() const;
|
||||
void p2poolStatus(bool isMining, int hashrate) const;
|
||||
void p2poolDownloadFailure() const;
|
||||
void p2poolDownloadSuccess() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<QProcess> m_p2poold;
|
||||
QMutex m_p2poolMutex;
|
||||
QString m_p2pool;
|
||||
QString m_p2poolPath;
|
||||
bool started = false;
|
||||
|
||||
mutable FutureScheduler m_scheduler;
|
||||
};
|
||||
|
||||
#endif // P2POOLMANAGER_H
|
||||
@@ -53,9 +53,6 @@ private:
|
||||
return qMakePair(false, QFuture<T>());
|
||||
}
|
||||
|
||||
QFutureWatcher<void> schedule(std::function<void()> function);
|
||||
QFutureWatcher<QJSValueList> schedule(std::function<QJSValueList() noexcept> function, const QJSValue &callback);
|
||||
|
||||
private:
|
||||
size_t Alive;
|
||||
QWaitCondition Condition;
|
||||
|
||||
@@ -115,12 +115,12 @@ void WalletKeysFilesModel::findWallets(const QString &moneroAccountsDir)
|
||||
QFileInfo keysFileinfo = it.fileInfo();
|
||||
|
||||
constexpr const char keysFileExtension[] = "keys";
|
||||
if (!keysFileinfo.isFile() || keysFileinfo.completeSuffix() != keysFileExtension)
|
||||
if (!keysFileinfo.isFile() || keysFileinfo.suffix() != keysFileExtension)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString wallet(keysFileinfo.path() + QDir::separator() + keysFileinfo.baseName());
|
||||
QString wallet(keysFileinfo.path() + QDir::separator() + keysFileinfo.completeBaseName());
|
||||
quint8 networkType = NetworkType::MAINNET;
|
||||
QString address = QString("");
|
||||
|
||||
@@ -128,7 +128,7 @@ void WalletKeysFilesModel::findWallets(const QString &moneroAccountsDir)
|
||||
if(fileExists(wallet + ".address.txt")){
|
||||
QFile file(wallet + ".address.txt");
|
||||
file.open(QFile::ReadOnly | QFile::Text);
|
||||
QString _address = QTextCodec::codecForMib(106)->toUnicode(file.readAll());
|
||||
QString _address = QString(file.readAll());
|
||||
|
||||
if(!_address.isEmpty()){
|
||||
address = _address;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <QRegExp>
|
||||
#include <QMessageBox>
|
||||
#include <QPixmap>
|
||||
#include <QTranslator>
|
||||
|
||||
@@ -109,8 +109,7 @@ void IPC::handleConnection(){
|
||||
clientConnection, &QLocalSocket::deleteLater);
|
||||
|
||||
clientConnection->waitForReadyRead(2);
|
||||
QByteArray cmdArray = clientConnection->readAll();
|
||||
QString cmdString = QTextCodec::codecForMib(106)->toUnicode(cmdArray); // UTF-8
|
||||
QString cmdString = QString(clientConnection->readAll());
|
||||
qDebug() << cmdString;
|
||||
|
||||
this->parseCommand(cmdString);
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#if defined(_WIN32) && !defined(MONERO_GUI_STATIC)
|
||||
#include <Winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "updater.h"
|
||||
|
||||
#include <common/util.h>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define UTILS_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QRegExp>
|
||||
#include <QRegularExpression>
|
||||
#include <QApplication>
|
||||
|
||||
bool fileExists(QString path);
|
||||
@@ -42,7 +42,7 @@ QString getAccountName();
|
||||
QString xdgMime();
|
||||
void registerXdgMime();
|
||||
#endif
|
||||
const static QRegExp reURI = QRegExp("^\\w+:\\/\\/([\\w+\\-?\\-_\\-=\\-&]+)");
|
||||
const static QRegularExpression reURI = QRegularExpression("^\\w+:\\/\\/([\\w+\\-?\\-_\\-=\\-&]+)");
|
||||
QString randomUserAgent();
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||