Compare commits

..
Author SHA1 Message Date
tobtoht d41d526da0 Trigger CI 2020-12-05 19:35:57 +00:00
72 changed files with 8645 additions and 804 deletions
+15 -16
View File
@@ -14,10 +14,9 @@ steps:
commands: commands:
- git config --global url."http://gitea:3000/tor/".insteadOf https://git.torproject.org/ - git config --global url."http://gitea:3000/tor/".insteadOf https://git.torproject.org/
- git config --global url."http://gitea:3000/".insteadOf https://github.com/ - git config --global url."http://gitea:3000/".insteadOf https://github.com/
- git config --global url."http://gitea:3000/".insteadOf https://git.wownero.com/ - git submodule update --init --depth 120 monero
- git submodule update --init monero - git submodule update --init --depth 120 --recursive monero
- git submodule update --init --depth 1 --recursive monero - TOR="/usr/local/tor/bin/tor" XMRIG="/xmrig/xmrig" make -j6 release-static
- TOR_BIN="/usr/local/tor/bin/tor" make -j8 release-static
environment: environment:
OPENSSL_ROOT_DIR: /usr/local/openssl/ OPENSSL_ROOT_DIR: /usr/local/openssl/
CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off
@@ -46,19 +45,17 @@ volumes:
path: /build/feather_files/files/linux-release/ path: /build/feather_files/files/linux-release/
--- ---
kind: pipeline kind: pipeline
type: docker type: docker
name: linux-release-appimage name: linux-release-appimage
steps: steps:
- name: build - name: build
image: feather:appimage image: feather:appimage
volumes:
- name: files_linux_release
path: /files
commands: commands:
- export FN="feather-`echo $DRONE_COMMIT_AFTER | cut -c 1-7`.zip" - export FN="feather-`echo $DRONE_COMMIT_AFTER | cut -c 1-7`.zip"
- export BRANCH="$DRONE_SOURCE_BRANCH" - export BRANCH="$DRONE_SOURCE_BRANCH"
- cp /files/$BRANCH/$FN feather.zip
- bash ./contrib/build-appimage.sh - bash ./contrib/build-appimage.sh
- name: deploy - name: deploy
image: feather:appimage image: feather:appimage
@@ -72,18 +69,18 @@ steps:
- echo "writing to $TARGET_DIR/$FN" - echo "writing to $TARGET_DIR/$FN"
- mv "Feather-1.0-x86_64.AppImage" "$TARGET_DIR/$FN" - mv "Feather-1.0-x86_64.AppImage" "$TARGET_DIR/$FN"
- echo "[*] written to https://build.featherwallet.org/files/linux-release-appimage/$DRONE_SOURCE_BRANCH/$FN" - echo "[*] written to https://build.featherwallet.org/files/linux-release-appimage/$DRONE_SOURCE_BRANCH/$FN"
volumes: volumes:
- name: files_linux_appimage - name: files_linux_appimage
host: host:
path: /build/feather_files/files/linux-release-appimage/ path: /build/feather_files/files/linux-release-appimage/
- name: files_linux_release
host:
path: /build/feather_files/files/linux-release/
--- ---
kind: pipeline kind: pipeline
type: docker type: docker
name: windows-mxe-release name: windows-mxe-release
steps: steps:
- name: build - name: build
image: feather:win image: feather:win
@@ -95,10 +92,9 @@ steps:
commands: commands:
- git config --global url."http://gitea:3000/tor/".insteadOf https://git.torproject.org/ - git config --global url."http://gitea:3000/tor/".insteadOf https://git.torproject.org/
- git config --global url."http://gitea:3000/".insteadOf https://github.com/ - git config --global url."http://gitea:3000/".insteadOf https://github.com/
- git config --global url."http://gitea:3000/".insteadOf https://git.wownero.com/ - git submodule update --init --depth 120 monero
- git submodule update --init monero - git submodule update --init --depth 120 --recursive monero
- git submodule update --init --depth 1 --recursive monero - PATH="/mxe/usr/bin/:$PATH" TOR="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" XMRIG="/xmrig/xmrig.exe" make -j6 windows-mxe-release
- PATH="/mxe/usr/bin/:$PATH" TOR_BIN="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" make -j8 windows-mxe-release
environment: environment:
CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off
- name: deploy - name: deploy
@@ -115,6 +111,7 @@ steps:
- echo "writing to $TARGET_DIR/$FN" - echo "writing to $TARGET_DIR/$FN"
- zip -j "$TARGET_DIR/$FN" build/feather.log build/bin/feather.exe - zip -j "$TARGET_DIR/$FN" build/feather.log build/bin/feather.exe
- echo "[*] written to https://build.featherwallet.org/files/windows-mxe-release/$DRONE_SOURCE_BRANCH/$FN" - echo "[*] written to https://build.featherwallet.org/files/windows-mxe-release/$DRONE_SOURCE_BRANCH/$FN"
volumes: volumes:
- name: ccache_win_release - name: ccache_win_release
host: host:
@@ -124,6 +121,7 @@ volumes:
path: /build/feather_files/files/windows-mxe-release/ path: /build/feather_files/files/windows-mxe-release/
--- ---
kind: pipeline kind: pipeline
type: docker type: docker
name: mac-release name: mac-release
@@ -136,6 +134,7 @@ steps:
path: /files path: /files
commands: commands:
- mkdir -p build - mkdir -p build
- scp -P22 utils/build_macos.sh administrator@steve.jobs.xmr.pm:build_macos.sh
- ssh administrator@steve.jobs.xmr.pm "chmod +x build_macos.sh && PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin ~/build_macos.sh $DRONE_COMMIT_SHA" - ssh administrator@steve.jobs.xmr.pm "chmod +x build_macos.sh && PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin ~/build_macos.sh $DRONE_COMMIT_SHA"
- scp -P22 administrator@steve.jobs.xmr.pm:feather.zip build/feather.zip - scp -P22 administrator@steve.jobs.xmr.pm:feather.zip build/feather.zip
- name: deploy - name: deploy
@@ -157,6 +156,6 @@ volumes:
path: /build/feather_files/files/mac-release/ path: /build/feather_files/files/mac-release/
--- ---
kind: signature kind: signature
hmac: f16a0379280e2e89987930d635ec6fb938d67732fdaf4ddc488f2a9db64bda2c hmac: 527d334190a8a824b3b781a05ae4c7d87f4fa2bc37ebc53a96db91f925fa4a52
... ...
+3
View File
@@ -1,6 +1,9 @@
[submodule "monero"] [submodule "monero"]
path = monero path = monero
url = https://git.wownero.com/feather/monero.git url = https://git.wownero.com/feather/monero.git
[submodule "contrib/torsocks"]
path = contrib/torsocks
url = https://git.torproject.org/torsocks.git
[submodule "contrib/tor"] [submodule "contrib/tor"]
path = contrib/tor path = contrib/tor
url = https://git.torproject.org/tor.git url = https://git.torproject.org/tor.git
+36 -41
View File
@@ -10,44 +10,6 @@ Static builds via Docker are done in 3 steps:
2. Creating a base Docker image 2. Creating a base Docker image
3. Using the base image to compile a build 3. Using the base image to compile a build
### Linux (reproducible)
The docker image for reproducible Linux static builds uses Ubuntu 16.04 and compiles the required libraries statically
so that the resulting Feather binary is static. For more information, check the Dockerfile: `Dockerfile`.
#### 1. Clone
```bash
git clone --branch master --recursive https://git.wownero.com/feather/feather.git
cd feather
```
Replace `master` with the desired version tag (e.g. `beta-1`) to build the release binary.
#### 2. Base image
```bash
docker build --tag feather:linux --build-arg THREADS=4 .
```
Building the base image takes a while. You only need to build the base image once.
#### 3. Build
```bash
docker run --rm -it -v $PWD:/feather --env OPENSSL_ROOT_DIR=/usr/local/openssl/ -w /feather feather:linux sh -c 'TOR_BIN="/usr/local/tor/bin/tor" make release-static -j4'
```
If you're re-running a build make sure to `rm -rf build/` first.
The resulting binary can be found in `build/bin/feather`.
Hashes for tagged commits should match:
```
beta-1: d1a52e3bac1abbae4adda1fc88cb2a7a06fbd61085868421897c6a4f3f4eb091 feather
```
### Windows ### Windows
The docker image for Windows static compiles uses Ubuntu 18.04 and installs [mxe](https://mxe.cc) from [our git](https://git.wownero.com/feather/mxe/src/branch/feather-patch), The docker image for Windows static compiles uses Ubuntu 18.04 and installs [mxe](https://mxe.cc) from [our git](https://git.wownero.com/feather/mxe/src/branch/feather-patch),
@@ -73,12 +35,45 @@ Note: You only need to build the base image once.
#### 3. Build #### 3. Build
```bash ```bash
docker run --rm -it -v /tmp/ccache:/root/.ccache -v PATH_TO_FEATHER:/feather -w /feather feather:win /bin/bash -c 'PATH="/mxe/usr/bin/:$PATH" TOR_BIN="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" make windows-mxe-release -j8' docker run --rm -it -v /tmp/ccache:/root/.ccache -v /root/feather:/feather -w /feather feather:win /bin/bash -c 'PATH="/mxe/usr/bin/:$PATH" TOR="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" XMRIG="/xmrig/xmrig.exe" make windows-mxe-release -j8'
```
Replace `PATH_TO_FEATHER` with the absolute path to Feather locally.
The resulting binary can be found in `build/bin/feather.exe`.
### Linux
The docker image for Linux static compiles uses Ubuntu 18.04 and compiles the required libraries statically so that
the resulting Feather binary is static. It comes with OpenSSL 1.1.1g, Qt 5.15.0 (OpenGL disabled). For more information,
check the Dockerfile: `Dockerfile`.
#### 1. Clone
```bash
git clone --recursive https://git.wownero.com/feather/feather.git
cd feather
```
#### 2. Base image
Warning: Building the base image takes a while, go prepare some dinner.
```bash
docker build --tag feather:linux --build-arg THREADS=8 .
```
Note: You only need to build the base image once.
#### 3. Build
```bash
docker run --env OPENSSL_ROOT_DIR=/usr/local/openssl/ --rm -it -v /tmp/ccache:/root/.ccache -v PATH_TO_FEATHER:/feather -w /feather feather:linux sh -c 'TOR="/usr/local/tor/bin/tor" XMRIG="/xmrig/xmrig" make release-static -j8'
``` ```
Replace `PATH_TO_FEATHER` with the absolute path to Feather locally. Replace `PATH_TO_FEATHER` with the absolute path to Feather locally.
The resulting binary can be found in `build/bin/feather.exe`. The resulting binary can be found in `build/bin/feather`.
## macOS ## macOS
@@ -103,4 +98,4 @@ Build Feather.
CMAKE_PREFIX_PATH=~/Qt5.15.1/5.15.1/clang_64 make mac-release CMAKE_PREFIX_PATH=~/Qt5.15.1/5.15.1/clang_64 make mac-release
``` ```
The resulting Mac OS application can be found `build/bin/feather.app` and will **not** have Tor embedded. The resulting Mac OS application can be found `build/bin/feather.app` and will **not** have Tor embedded.
+28 -10
View File
@@ -7,14 +7,14 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
set(VERSION_MAJOR "0") set(VERSION_MAJOR "0")
set(VERSION_MINOR "1") set(VERSION_MINOR "1")
set(VERSION_REVISION "0") set(VERSION_REVISION "0")
set(VERSION "beta-2") set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
option(FETCH_DEPS "Download dependencies if they are not found" ON) option(FETCH_DEPS "Download dependencies if they are not found" ON)
option(XMRTO "Include Xmr.To module" ON) option(XMRTO "Include Xmr.To module" ON)
option(MORPHTOKEN "Include MorphToken module" ON) option(MORPHTOKEN "Include MorphToken module" ON)
option(XMRIG "Include XMRig module" ON) option(XMRIG "Path to XMRig binary to embed inside Feather" OFF)
option(TOR_BIN "Path to Tor binary to embed inside Feather" OFF) option(TOR "Path to Tor binary to embed inside Feather" OFF)
option(TOR_VERSION "Optional git hash or tag of embedded Tor version" "tor-0.4.3.5")
option(STATIC "Link libraries statically, requires static Qt") option(STATIC "Link libraries statically, requires static Qt")
option(USE_DEVICE_TREZOR "Trezor support compilation" OFF) option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
option(DONATE_BEG "Prompt donation window every once in a while" ON) option(DONATE_BEG "Prompt donation window every once in a while" ON)
@@ -31,7 +31,7 @@ if(DEBUG)
set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_VERBOSE_MAKEFILE ON)
endif() endif()
set(MONERO_HEAD "85b0b4f73aa6114e3ff91207aa94ad2a15c939a2") set(MONERO_HEAD "2c41634c13994a8a112a1e3a61e5e0b456791a97")
set(BUILD_GUI_DEPS ON) set(BUILD_GUI_DEPS ON)
set(ARCH "x86-64") set(ARCH "x86-64")
set(BUILD_64 ON) set(BUILD_64 ON)
@@ -181,8 +181,8 @@ if("$ENV{DRONE}" STREQUAL "true")
message(STATUS "We are inside a static compile with Drone CI") message(STATUS "We are inside a static compile with Drone CI")
endif() endif()
# To build Feather with embedded (and static) Tor, pass CMake -DTOR_BIN=/path/to/tor # To build Feather with embedded (and static) Tor, pass CMake -DTOR=/path/to/tor
if(TOR_BIN) if(TOR)
if(APPLE) if(APPLE)
execute_process(COMMAND bash -c "touch ${CMAKE_CURRENT_SOURCE_DIR}/src/tor/libevent-2.1.7.dylib") execute_process(COMMAND bash -c "touch ${CMAKE_CURRENT_SOURCE_DIR}/src/tor/libevent-2.1.7.dylib")
endif() endif()
@@ -191,16 +191,34 @@ if(TOR_BIN)
# - linux: See `Dockerfile` # - linux: See `Dockerfile`
# - windows: https://github.com/mxe/mxe/blob/1024dc7d2db5eb7d5d3c64a2c12b5f592572f1ce/plugins/apps/tor.mk # - windows: https://github.com/mxe/mxe/blob/1024dc7d2db5eb7d5d3c64a2c12b5f592572f1ce/plugins/apps/tor.mk
# - macos: taken from Tor Browser official release # - macos: taken from Tor Browser official release
set(TOR_COPY_CMD "cp ${TOR_BIN} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/tor") set(TOR_COPY_CMD "cp ${TOR} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/tor")
message(STATUS "${TOR_COPY_CMD}") message(STATUS "${TOR_COPY_CMD}")
execute_process(COMMAND bash -c "${TOR_COPY_CMD}" RESULT_VARIABLE ret) execute_process(COMMAND bash -c "${TOR_COPY_CMD}" RESULT_VARIABLE ret)
if(ret EQUAL "1") if(ret EQUAL "1")
message(FATAL_ERROR "Tor copy failure: ${TOR_COPY_CMD}") message(FATAL_ERROR "Tor copy failure: ${TOR_COPY_CMD}")
endif() endif()
message(STATUS "Embedding Tor binary at ${TOR_BIN}") message(STATUS "Embedding Tor binary at ${TOR}")
else() else()
message(STATUS "Skipping Tor inclusion because -DTOR_BIN=Off") message(STATUS "Skipping Tor inclusion because -DTOR=Off")
endif()
# To build Feather with embedded (and static) XMRig, pass CMake -DXMRIG=/path/to/xmrig
if(XMRIG)
# on the buildbot XMRig is baked into the image
# - linux: See `Dockerfile`
# - windows: See `Dockerfile_windows`
# - macos: manually downloaded an official release
set(XMRIG_COPY_CMD "cp ${XMRIG} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/xmrig")
message(STATUS "${XMRIG_COPY_CMD}")
execute_process(COMMAND bash -c "${XMRIG_COPY_CMD}" RESULT_VARIABLE ret)
if(ret EQUAL "1")
message(FATAL_ERROR "XMRig copy failure: ${XMRIG_COPY_CMD}")
endif()
message(STATUS "Embedding XMRig binary at ${XMRIG}")
else()
message(STATUS "Skipping XMRig inclusion because -DXMRIG=Off")
endif() endif()
if(MINGW) if(MINGW)
+138 -173
View File
@@ -1,214 +1,188 @@
FROM ubuntu:16.04 FROM ubuntu:18.04
ARG THREADS=1 ARG THREADS=1
ARG QT_VERSION=5.15.2
ENV CFLAGS="-fPIC" RUN apt clean && apt update
ENV CPPFLAGS="-fPIC" RUN apt install -y gnupg
ENV CXXFLAGS="-fPIC"
ENV SOURCE_DATE_EPOCH=1397818193
RUN apt-get update COPY utils/pubkeys/kitware.asc /kitware.asc
RUN apt-get install -y nano vim ccache software-properties-common RUN cat /kitware.asc | gpg --dearmor - | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
RUN apt install -y automake git pkg-config python wget python3.6-distutils software-properties-common
RUN apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' && apt update
RUN add-apt-repository ppa:git-core/ppa ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update ENV TZ=Europe/Amsterdam
RUN apt install -y build-essential nano vim aptitude ccache libusb-1.0-0-dev tzdata
RUN apt install -y automake git pkg-config python xutils-dev && \ RUN apt install -y xutils-dev && \
git clone -b xorgproto-2020.1 --depth 1 https://gitlab.freedesktop.org/xorg/proto/xorgproto && \ git clone -b xorgproto-2020.1 --depth 1 https://gitlab.freedesktop.org/xorg/proto/xorgproto && \
cd xorgproto && \ cd xorgproto && \
git reset --hard c62e8203402cafafa5ba0357b6d1c019156c9f36 && \ git reset --hard c62e8203402cafafa5ba0357b6d1c019156c9f36 && \
./autogen.sh && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b 1.12 --depth 1 https://gitlab.freedesktop.org/xorg/proto/xcbproto && \ RUN git clone -b xcb-proto-1.13 --depth 1 https://gitlab.freedesktop.org/xorg/proto/xcbproto && \
cd xcbproto && \ cd xcbproto && \
git reset --hard 6398e42131eedddde0d98759067dde933191f049 && \ git reset --hard 94228cde97d9aecfda04a8e699d462ba2b89e3a0 && \
./autogen.sh && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y libtool-bin && \ RUN apt install -y libtool-bin && \
git clone -b libXau-1.0.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxau && \ git clone -b libXau-1.0.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxau && \
cd libxau && \ cd libxau && \
git reset --hard d9443b2c57b512cfb250b35707378654d86c7dea && \ git reset --hard d9443b2c57b512cfb250b35707378654d86c7dea && \
./autogen.sh --enable-shared --disable-static && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y libpthread-stubs0-dev && \ RUN apt install -y libpthread-stubs0-dev && \
git clone -b 1.12 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb && \ git clone -b 1.13.1 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb && \
cd libxcb && \ cd libxcb && \
git reset --hard d34785a34f28fa6a00f8ce00d87e3132ff0f6467 && \ git reset --hard 8287ebd7b752c33b0cabc4982606fe4831106f7e && \
./autogen.sh --enable-shared --disable-static && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
make -j$THREADS clean && \
rm /usr/local/lib/libxcb-xinerama.so && \
./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
cp src/.libs/libxcb-xinerama.a /usr/local/lib/ && \
rm -rf $(pwd)
RUN git clone -b 0.4.0 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-util && \ RUN git clone -b 0.4.0 --depth 1 --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-util.git && \
cd libxcb-util && \ cd libxcb-util && \
git reset --hard acf790d7752f36e450d476ad79807d4012ec863b && \ git reset --hard acf790d7752f36e450d476ad79807d4012ec863b && \
git submodule init && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
./autogen.sh --enable-shared --disable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b 0.4.0 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-image && \ RUN git clone -b xtrans-1.3.5 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxtrans.git && \
cd libxtrans && \
git reset --hard 7cbad9fe2e61cd9d5caeaf361826a6f4bd320f03 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b 0.4.0 --depth 1 --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-image.git && \
cd libxcb-image && \ cd libxcb-image && \
git reset --hard d882052fb2ce439c6483fce944ba8f16f7294639 && \ git reset --hard d882052fb2ce439c6483fce944ba8f16f7294639 && \
git submodule init && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
./autogen.sh --enable-shared --disable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b 0.4.0 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-keysyms && \ RUN git clone -b 0.4.0 --depth 1 --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-keysyms.git && \
cd libxcb-keysyms && \ cd libxcb-keysyms && \
git reset --hard 0e51ee5570a6a80bdf98770b975dfe8a57f4eeb1 && \ git reset --hard 0e51ee5570a6a80bdf98770b975dfe8a57f4eeb1 && \
git submodule init && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
./autogen.sh --enable-shared --disable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b 0.3.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-render-util && \ RUN git clone -b 0.3.9 --depth 1 --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-render-util.git && \
cd libxcb-render-util && \ cd libxcb-render-util && \
git reset --hard 0317caf63de532fd7a0493ed6afa871a67253747 && \ git reset --hard 0317caf63de532fd7a0493ed6afa871a67253747 && \
git submodule init && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
./autogen.sh --enable-shared --disable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b 0.4.1 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb-wm && \ RUN git clone -b 0.4.1 --depth 1 --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-wm.git && \
cd libxcb-wm && \ cd libxcb-wm && \
git reset --hard 24eb17df2e1245885e72c9d4bbb0a0f69f0700f2 && \ git reset --hard 24eb17df2e1245885e72c9d4bbb0a0f69f0700f2 && \
git submodule init && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
git clone --depth 1 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 m4 && \
git -C m4 reset --hard f662e3a93ebdec3d1c9374382dcc070093a42fed && \
./autogen.sh --enable-shared --disable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y bison && \ RUN git clone -b libX11-1.6.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libx11 && \
git clone -b xkbcommon-0.5.0 --depth 1 https://github.com/xkbcommon/libxkbcommon && \ cd libx11 && \
cd libxkbcommon && \ git reset --hard db7cca17ad7807e92a928da9d4c68a00f4836da2 && \
git reset --hard c43c3c866eb9d52cd8f61e75cbef1c30d07f3a28 && \ ACLOCAL='aclocal -I /usr/local/share/aclocal/' CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
./autogen.sh --prefix=/usr --enable-shared --disable-static --enable-x11 --disable-docs && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b libXext-1.3.4 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxext && \
cd libxext && \
git reset --hard ebb167f34a3514783966775fb12573c4ed209625 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y libpthread-stubs0-dev && \
git clone -b libXinerama-1.1.4 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxinerama.git && \
cd libxinerama && \
git reset --hard c3ab2361f13154921df2992f9eacc1ea1b3f946b && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b v1.2.11 --depth 1 https://github.com/madler/zlib && \ RUN git clone -b v1.2.11 --depth 1 https://github.com/madler/zlib && \
cd zlib && \ cd zlib && \
git reset --hard cacf7f1d4e3d44d871b605da3b647f07d718623f && \ git reset --hard cacf7f1d4e3d44d871b605da3b647f07d718623f && \
./configure --static && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install && \
./configure --static --prefix=/usr/local/zlib && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --static --prefix=/usr/local/zlib && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b VER-2-10-2 --depth 1 https://git.savannah.gnu.org/git/freetype/freetype2.git && \ RUN git clone -b VER-2-10-2 https://git.sv.nongnu.org/r/freetype/freetype2.git && \
cd freetype2 && \ cd freetype2 && \
git reset --hard 132f19b779828b194b3fede187cee719785db4d8 && \ git reset --hard 132f19b779828b194b3fede187cee719785db4d8 && \
./autogen.sh && \ ./autogen.sh && \
./configure --disable-shared --enable-static --with-zlib=no && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --with-zlib=no && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b R_2_2_9 --depth 1 https://github.com/libexpat/libexpat && \ RUN git clone -b R_2_2_9 --depth 1 https://github.com/libexpat/libexpat && \
cd libexpat/expat && \ cd libexpat/expat && \
git reset --hard a7bc26b69768f7fb24f0c7976fae24b157b85b13 && \ git reset --hard a7bc26b69768f7fb24f0c7976fae24b157b85b13 && \
./buildconf.sh && \ ./buildconf.sh && \
./configure --disable-shared --enable-static && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y autopoint gettext gperf libpng12-dev && \ RUN apt install -y autopoint gettext gperf libpng-dev && \
git clone -b 2.13.92 --depth 1 https://gitlab.freedesktop.org/fontconfig/fontconfig && \ git clone -b 2.13.92 --depth 1 https://gitlab.freedesktop.org/fontconfig/fontconfig && \
cd fontconfig && \ cd fontconfig && \
git reset --hard b1df1101a643ae16cdfa1d83b939de2497b1bf27 && \ git reset --hard b1df1101a643ae16cdfa1d83b939de2497b1bf27 && \
./autogen.sh --disable-shared --enable-static --sysconfdir=/etc --localstatedir=/var && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static --sysconfdir=/etc --localstatedir=/var && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b release-64-2 --depth 1 https://github.com/unicode-org/icu && \ RUN git clone -b release-64-2 --depth 1 https://github.com/unicode-org/icu && \
cd icu/icu4c/source && \ cd icu/icu4c/source && \
git reset --hard e2d85306162d3a0691b070b4f0a73e4012433444 && \ git reset --hard e2d85306162d3a0691b070b4f0a73e4012433444 && \
./configure --disable-shared --enable-static --disable-tests --disable-samples && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-tests --disable-samples && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y wget && \ RUN apt install -y wget && \
wget https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.gz && \ wget https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.gz && \
echo "9995e192e68528793755692917f9eb6422f3052a53c5e13ba278a228af6c7acf boost_1_73_0.tar.gz" | sha256sum -c && \ echo "9995e192e68528793755692917f9eb6422f3052a53c5e13ba278a228af6c7acf boost_1_73_0.tar.gz" > hashsum.txt && \
tar -xzf boost_1_73_0.tar.gz && \ sha256sum -c hashsum.txt && \
rm boost_1_73_0.tar.gz && \ tar -xvzf boost_1_73_0.tar.gz && \
cd boost_1_73_0 && \ cd boost_1_73_0 && \
./bootstrap.sh && \ ./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 && \ ./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='-fPIC' cxxflags='-fPIC' install -a --prefix=/usr
rm -rf $(pwd)
RUN wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz && \ RUN wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz && \
echo "e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242 openssl-1.1.1i.tar.gz" | sha256sum -c && \ echo "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46 openssl-1.1.1g.tar.gz" > hashsum.txt && \
tar -xzf openssl-1.1.1i.tar.gz && \ sha256sum -c hashsum.txt && \
rm openssl-1.1.1i.tar.gz && \ tar -xzf openssl-1.1.1g.tar.gz && \
cd openssl-1.1.1i && \ cd openssl-1.1.1g && \
./config no-shared no-zlib-dynamic --prefix=/usr/local/openssl && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./config no-shared no-zlib-dynamic --prefix=/usr/local/openssl && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
./config no-shared no-zlib-dynamic --openssldir=/usr && \
make -j$THREADS && \
make -j$THREADS install && \
rm -rf $(pwd)
RUN apt install -y libgl1-mesa-dev libglib2.0-dev mesa-common-dev && \ RUN wget https://download.qt.io/archive/qt/5.15/5.15.0/single/qt-everywhere-src-5.15.0.tar.xz && \
rm /usr/lib/x86_64-linux-gnu/libX11.a && \ echo "22b63d7a7a45183865cc4141124f12b673e7a17b1fe2b91e433f6547c5d548c3 qt-everywhere-src-5.15.0.tar.xz" > hashsum.txt && \
rm /usr/lib/x86_64-linux-gnu/libXext.a && \ sha256sum -c hashsum.txt && \
rm /usr/lib/x86_64-linux-gnu/libX11-xcb.a && \ tar -xf qt-everywhere-src-5.15.0.tar.xz
git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
cd qt5 && \ COPY contrib/Qt5.15_LinuxPatch.json /qt-everywhere-src-5.15.0/qtbase/src/gui/configure.json
git clone git://code.qt.io/qt/qtbase.git -b ${QT_VERSION} --depth 1 && \ RUN apt install -y libgl1-mesa-dev libglib2.0-dev libxkbcommon-dev libxkbcommon-x11-dev
git clone git://code.qt.io/qt/qtimageformats.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtmultimedia.git -b ${QT_VERSION} --depth 1 && \ RUN cd /qt-everywhere-src-5.15.0 && \
git clone git://code.qt.io/qt/qtsvg.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qttools.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qttranslations.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtx11extras.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtwebsockets.git -b ${QT_VERSION} --depth 1 && \
sed -ri s/\(Libs:.*\)/\\1\ -lexpat/ /usr/local/lib/pkgconfig/fontconfig.pc && \ sed -ri s/\(Libs:.*\)/\\1\ -lexpat/ /usr/local/lib/pkgconfig/fontconfig.pc && \
sed -ri s/\(Libs:.*\)/\\1\ -lz/ /usr/local/lib/pkgconfig/freetype2.pc && \ sed -ri s/\(Libs:.*\)/\\1\ -lz/ /usr/local/lib/pkgconfig/freetype2.pc && \
sed -ri s/\(Libs:.*\)/\\1\ -lXau/ /usr/local/lib/pkgconfig/xcb.pc && \ sed -ri s/\(Libs:.*\)/\\1\ -lXau/ /usr/local/lib/pkgconfig/xcb.pc && \
sed -i s/\\/usr\\/X11R6\\/lib64/\\/usr\\/local\\/lib/ qtbase/mkspecs/linux-g++-64/qmake.conf && \
OPENSSL_LIBS="-lssl -lcrypto -lpthread -ldl" \ OPENSSL_LIBS="-lssl -lcrypto -lpthread -ldl" \
./configure --prefix=/usr -platform linux-g++-64 -opensource -confirm-license -release -static -no-avx \ ./configure --prefix=/usr -platform linux-g++-64 -opensource -confirm-license -release -static -no-avx \
-no-opengl -qpa xcb --xcb -xcb-xlib -feature-xlib -openssl-linked -I /usr/local/openssl/include \ -no-opengl -qpa xcb -openssl-linked -I /usr/local/openssl/include -L /usr/local/openssl/lib -system-freetype -fontconfig -glib \
-L /usr/local/openssl/lib -system-freetype -fontconfig -glib \
-no-dbus -no-sql-sqlite -no-use-gold-linker -no-kms \ -no-dbus -no-sql-sqlite -no-use-gold-linker -no-kms \
-qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \ -qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \
-skip qt3d -skip qtandroidextras -skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d \ -skip qt3d -skip qtandroidextras -skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d \
@@ -219,101 +193,82 @@ RUN apt install -y libgl1-mesa-dev libglib2.0-dev mesa-common-dev && \
-skip qtwinextras -skip qtx11extras -skip gamepad -skip serialbus -skip location -skip webengine \ -skip qtwinextras -skip qtx11extras -skip gamepad -skip serialbus -skip location -skip webengine \
-skip qtdeclarative \ -skip qtdeclarative \
-no-feature-cups -no-feature-ftp -no-feature-pdf -no-feature-animation \ -no-feature-cups -no-feature-ftp -no-feature-pdf -no-feature-animation \
-nomake examples -nomake tests -nomake tools && \ -nomake examples -nomake tests -nomake tools
RUN cd /qt-everywhere-src-5.15.0 && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
cd qttools/src/linguist/lrelease && \
../../../../qtbase/bin/qmake && \ RUN cd qt-everywhere-src-5.15.0/qttools/src/linguist/lrelease && \
qmake && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
cd ../../../.. && \
rm -rf $(pwd)
RUN apt install -y libudev-dev && \ RUN apt install -y libudev-dev && \
git clone -b v1.0.23 --depth 1 https://github.com/libusb/libusb && \ git clone -b v1.0.23 --depth 1 https://github.com/libusb/libusb && \
cd libusb && \ cd libusb && \
git reset --hard e782eeb2514266f6738e242cdcb18e3ae1ed06fa && \ git reset --hard e782eeb2514266f6738e242cdcb18e3ae1ed06fa && \
./autogen.sh --disable-shared --enable-static && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ 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.9.0 --depth 1 https://github.com/libusb/hidapi && \
cd hidapi && \ cd hidapi && \
git reset --hard 7da5cc91fc0d2dbe4df4f08cd31f6ca1a262418f && \ git reset --hard 7da5cc91fc0d2dbe4df4f08cd31f6ca1a262418f && \
./bootstrap && \ ./bootstrap && \
./configure --disable-shared --enable-static && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y libsodium-dev && \ RUN apt install -y libsodium-dev && \
git clone -b v4.3.2 --depth 1 https://github.com/zeromq/libzmq && \ git clone -b v4.3.2 --depth 1 https://github.com/zeromq/libzmq && \
cd libzmq && \ cd libzmq && \
git reset --hard a84ffa12b2eb3569ced199660bac5ad128bff1f0 && \ git reset --hard a84ffa12b2eb3569ced199660bac5ad128bff1f0 && \
./autogen.sh && \ ./autogen.sh && \
./configure --disable-shared --enable-static --disable-libunwind --with-libsodium && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-libunwind --with-libsodium && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ 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.38 --depth 1 git://git.gnupg.org/libgpg-error.git && \
cd libgpg-error && \ cd libgpg-error && \
git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 && \ git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 && \
./autogen.sh && \ ./autogen.sh && \
./configure --disable-shared --enable-static --disable-doc --disable-tests && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-doc --disable-tests && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ 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.8.5 --depth 1 git://git.gnupg.org/libgcrypt.git && \
cd libgcrypt && \ cd libgcrypt && \
git reset --hard 56606331bc2a80536db9fc11ad53695126007298 && \ git reset --hard 56606331bc2a80536db9fc11ad53695126007298 && \
./autogen.sh && \ ./autogen.sh && \
./configure --disable-shared --enable-static --disable-doc && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-doc && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ 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 v3.10.0 --depth 1 https://github.com/protocolbuffers/protobuf && \
cd protobuf && \ cd protobuf && \
git reset --hard 6d4e7fd7966c989e38024a8ea693db83758944f1 && \ git reset --hard 6d4e7fd7966c989e38024a8ea693db83758944f1 && \
./autogen.sh && \ ./autogen.sh && \
./configure --enable-static --disable-shared && \ CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --enable-static --disable-shared && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b v3.18.4 --depth 1 https://github.com/Kitware/CMake && \ RUN apt install -y zip cmake && git clone -b v4.0.2 --depth 1 https://github.com/fukuchi/libqrencode.git && \
cd CMake && \
git reset --hard 3cc3d42aba879fff5e85b363ae8f21386a3f9f9b && \
./bootstrap && \
make -j$THREADS && \
make -j$THREADS install && \
rm -rf $(pwd)
RUN apt install -y libusb-1.0-0-dev
RUN apt install -y zip && git clone -b v4.0.2 --depth 1 https://github.com/fukuchi/libqrencode.git && \
cd libqrencode && \ cd libqrencode && \
git reset --hard 59ee597f913fcfda7a010a6e106fbee2595f68e4 && \ git reset --hard 59ee597f913fcfda7a010a6e106fbee2595f68e4 && \
cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=/usr . && \ cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=/usr . && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN apt install -y libmbedtls-dev && git clone -b release-2.1.12-stable --depth 1 https://github.com/libevent/libevent.git && \ RUN apt install -y libmbedtls-dev && git clone -b release-2.1.12-stable --depth 1 https://github.com/libevent/libevent.git && \
cd libevent && \ cd libevent && \
git reset --hard 5df3037d10556bfcb675bc73e516978b75fc7bc7 && \
mkdir build && cd build && \ mkdir build && cd build && \
cmake -DEVENT_LIBRARY_STATIC=ON -DOPENSSL_ROOT_DIR=/usr/local/openssl -DCMAKE_INSTALL_PREFIX=/usr/local/libevent .. && \ cmake -DEVENT_LIBRARY_STATIC=ON -DOPENSSL_ROOT_DIR=/usr/local/openssl -DCMAKE_INSTALL_PREFIX=/usr/local/libevent .. && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone -b tor-0.4.4.6 --depth 1 https://git.torproject.org/tor.git && \ RUN git clone -b tor-0.4.3.5 --depth 1 https://git.torproject.org/tor.git && \
cd tor && \ cd tor && \
git reset --hard 2a8b789ea6f308d081f369d78fa7cfdc9d00bf90 && \
bash autogen.sh && \ bash autogen.sh && \
LDFLAGS="-L/usr/local/openssl/lib/" LIBS="-lssl -lcrypto -lpthread -ldl" CPPFLAGS="-I/usr/local/openssl/include/" ./configure \ LDFLAGS="-L/usr/local/openssl/lib/" LIBS="-lssl -lcrypto -lpthread -ldl" CPPFLAGS="-I/usr/local/openssl/include/" ./configure \
--enable-static-zlib \ --enable-static-zlib \
@@ -336,13 +291,23 @@ RUN git clone -b tor-0.4.4.6 --depth 1 https://git.torproject.org/tor.git && \
--disable-system-torrc \ --disable-system-torrc \
--prefix=/usr/local/tor && \ --prefix=/usr/local/tor && \
make -j$THREADS && \ make -j$THREADS && \
make -j$THREADS install && \ make -j$THREADS install
rm -rf $(pwd)
RUN git clone https://git.torproject.org/torsocks.git && \
cd torsocks && \
bash autogen.sh && \
./configure --prefix=/usr/local/torsocks && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone https://git.wownero.com/feather/monero-seed.git && \ RUN git clone https://git.wownero.com/feather/monero-seed.git && \
cd monero-seed && \ cd monero-seed && \
git reset --hard 4674ef09b6faa6fe602ab5ae0b9ca8e1fd7d5e1b && \
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \ cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
make -Cbuild -j$THREADS && \ make -Cbuild -j$THREADS && \
make -Cbuild install && \ make -Cbuild install
rm -rf $(pwd)
RUN apt install -y curl && \
curl -LO "https://github.com/xmrig/xmrig/releases/download/v6.3.5/xmrig-6.3.5-linux-static-x64.tar.gz" && \
echo "24d4f07cf5850f00ab513b228f95769a5a5ed68d35808d98f9959b58d97985a0 xmrig-6.3.5-linux-static-x64.tar.gz" > hashsum.txt && \
sha256sum -c hashsum.txt && \
tar xvf xmrig-6.3.5-linux-static-x64.tar.gz --one-top-level=/xmrig --strip 1
+2 -2
View File
@@ -3,7 +3,7 @@ FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN apt clean && apt update RUN apt clean && apt update
RUN apt install -y golang git build-essential wget curl ngrep unzip file squashfs-tools desktop-file-utils patchelf libxkbcommon-x11-dev libx11-xcb-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render0 libxcb-render-util0 libxcb-shape0 libxcb-sync1 libxcb-xfixes0 libxcb-shm0 libxcb-keysyms1 libxcb-xkb1 RUN apt install -y golang git build-essential wget curl ngrep unzip file squashfs-tools desktop-file-utils patchelf libxkbcommon-x11-dev
RUN go get github.com/probonopd/go-appimage/src/appimagetool RUN go get github.com/probonopd/go-appimage/src/appimagetool
RUN go build -trimpath -ldflags="-s -w" github.com/probonopd/go-appimage/src/appimagetool RUN go build -trimpath -ldflags="-s -w" github.com/probonopd/go-appimage/src/appimagetool
@@ -15,4 +15,4 @@ RUN cd /usr/bin && \
RUN cd / && \ RUN cd / && \
wget -c https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-x86_64 && \ wget -c https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-x86_64 && \
chmod +x runtime-x86_64 chmod +x runtime-x86_64
+7
View File
@@ -72,3 +72,10 @@ RUN git clone https://git.wownero.com/feather/monero-seed.git && \
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \ cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
make -Cbuild -j$THREADS && \ make -Cbuild -j$THREADS && \
make -Cbuild install make -Cbuild install
RUN apt install -y curl && \
curl -LO "https://github.com/xmrig/xmrig/releases/download/v6.3.5/xmrig-6.3.5-gcc-win64.zip" && \
echo "e45915ada7e6e30f6ab40abf33831056449d5914307d7706bb0ad439b6d64c12 xmrig-6.3.5-gcc-win64.zip" > hashsum.txt && \
sha256sum -c hashsum.txt && \
unzip -q xmrig-6.3.5-gcc-win64.zip -d /xmrig && \
mv /xmrig/xmrig-6.3.5/* /xmrig/
+3 -3
View File
@@ -42,9 +42,9 @@ via the `CMAKE_PREFIX_PATH` definition. For me this is:
There are some Monero/Feather related options/definitions that you may pass: There are some Monero/Feather related options/definitions that you may pass:
- `-DXMRTO=OFF` - disable Xmr.To feature - `-DXMRTO=OFF` - disable Xmr.To feature
- `-DMORPHTOKEN=OFF` - disable MorphToken feature - `-DMORPHTOKEN=OFF` - diable MorphToken feature
- `-DXMRIG=OFF` - disable XMRig feature - `-DTOR=/path/to/tor` - Embed a Tor executable inside Feather
- `-DTOR_BIN=/path/to/tor` - Embed a Tor executable inside Feather - `-DXMRIG=/path/to/xmrig` - Embed a XMRig executable inside Feather
- `-DDONATE_BEG=OFF` - disable the dreaded donate requests - `-DDONATE_BEG=OFF` - disable the dreaded donate requests
And: And:
+12 -8
View File
@@ -30,10 +30,10 @@ CMAKEFLAGS = \
-DARCH=x86_64 \ -DARCH=x86_64 \
-DBUILD_64=On \ -DBUILD_64=On \
-DBUILD_TESTS=Off \ -DBUILD_TESTS=Off \
-DXMRTO=On \ -DXMRTO=ON \
-DMORPHTOKEN=On \ -DMORPHTOKEN=ON \
-DXMRIG=On \ -DXMRIG=Off \
-DTOR_BIN=Off \ -DTOR=Off \
-DCMAKE_CXX_STANDARD=11 \ -DCMAKE_CXX_STANDARD=11 \
-DCMAKE_VERBOSE_MAKEFILE=On \ -DCMAKE_VERBOSE_MAKEFILE=On \
-DINSTALL_VENDORED_LIBUNBOUND=Off \ -DINSTALL_VENDORED_LIBUNBOUND=Off \
@@ -43,28 +43,32 @@ CMAKEFLAGS = \
$(CMAKEFLAGS_EXTRA) $(CMAKEFLAGS_EXTRA)
release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64" release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64"
release-static: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF) release-static: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
release-static: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
release-static: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release release-static: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
release-static: release-static:
cmake -Bbuild $(CMAKEFLAGS) cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild $(MAKE) -Cbuild
windows-mxe-release: CMAKEFLAGS += -DBUILD_TAG="win-x64" windows-mxe-release: CMAKEFLAGS += -DBUILD_TAG="win-x64"
windows-mxe-release: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF) windows-mxe-release: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
windows-mxe-release: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
windows-mxe-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release windows-mxe-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
windows-mxe-release: windows-mxe-release:
cmake -Bbuild $(CMAKEFLAGS) cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild $(MAKE) -Cbuild
windows-mxe-debug: CMAKEFLAGS += -DBUILD_TAG="win-x64" windows-mxe-debug: CMAKEFLAGS += -DBUILD_TAG="win-x64"
windows-mxe-debug: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF) windows-mxe-debug: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
windows-mxe-debug: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
windows-mxe-debug: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Debug windows-mxe-debug: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Debug
windows-mxe-debug: windows-mxe-debug:
cmake -Bbuild $(CMAKEFLAGS) cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild $(MAKE) -Cbuild
mac-release: CMAKEFLAGS += -DSTATIC=Off mac-release: CMAKEFLAGS += -DSTATIC=Off
mac-release: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF) mac-release: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
mac-release: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
mac-release: CMAKEFLAGS += -DBUILD_TAG="mac-x64" mac-release: CMAKEFLAGS += -DBUILD_TAG="mac-x64"
mac-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release mac-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
mac-release: mac-release:
+1 -1
View File
@@ -2,7 +2,7 @@
[![Build Status](https://build.featherwallet.org/api/badges/feather/feather/status.svg)](https://build.featherwallet.org/feather/feather) [![Build Status](https://build.featherwallet.org/api/badges/feather/feather/status.svg)](https://build.featherwallet.org/feather/feather)
Feather is a free, open-source Monero client Linux with ports for Mac OS and Windows written in C++ with the Qt framework. It is created and maintained by [dsc](dsc@xmr.pm) and [tobtoht](thotbot@protonmail.com). Feather is a free, open-source Monero client Linux with ports for Mac OS and Windows written in C++ with the Qt framework. It is created and maintained by [dsc](dsc@xmr.pm) and [tobtoht](thotbot@protonmail.com).
## Development resources ## Development resources
* Web: [featherwallet.org](https://featherwallet.org) * Web: [featherwallet.org](https://featherwallet.org)
+22
View File
@@ -2,11 +2,33 @@
set -e set -e
function verify_hash() {
local file=$1 expected_hash=$2
actual_hash=$(sha256sum $file | awk '{print $1}')
if [ "$actual_hash" == "$expected_hash" ]; then
return 0
else
echo "$file $actual_hash (unexpected hash)" >&2
rm "$file"
exit 1
fi
}
function download_if_not_exist() {
local file_name=$1 url=$2
if [ ! -e $file_name ] ; then
wget -q -O $file_name "$url"
fi
}
APPDIR="$PWD/feather.AppDir" APPDIR="$PWD/feather.AppDir"
mkdir -p "$APPDIR" mkdir -p "$APPDIR"
mkdir -p "$APPDIR/usr/share/applications/" mkdir -p "$APPDIR/usr/share/applications/"
mkdir -p "$APPDIR/usr/bin" mkdir -p "$APPDIR/usr/bin"
echo "Downloading dependencies"
download_if_not_exist "feather.zip" "https://build.featherwallet.org/files/linux-release/$BRANCH/$FN"
unzip -q feather.zip unzip -q feather.zip
cp "$PWD/src/assets/feather.desktop" "$APPDIR/usr/share/applications/feather.desktop" cp "$PWD/src/assets/feather.desktop" "$APPDIR/usr/share/applications/feather.desktop"
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/env bash
# this file is used by feather's CMake
# arguments: ./build.tor $TAG $ROOT_FEATHER_DIR
set -ex
ERR_WIN="This script does not work on Windows"
if [[ "$OSTYPE" == "msys" ]]; then
echo "$ERR_WIN"
exit 1
elif [[ "$OSTYPE" == "win32" ]]; then
echo "$ERR_WIN"
exit 1
fi
TOR_TAG="$1"
ROOT_DIR="$2"
STATIC="$3"
TOR_DIR="$ROOT_DIR/contrib/tor"
TORSOCKS_DIR="$ROOT_DIR/contrib/torsocks"
TARGET_DIR="$ROOT_DIR/src/tor"
CPU_CORE_COUNT="$(nproc)"
#
### tor
#
pushd "$TOR_DIR"
rm -rf "$TOR_DIR/build"
mkdir -p "$TOR_DIR/build"
# configure
git -C "$TOR_DIR" fetch
git -C "$TOR_DIR" checkout tor-0.4.3.5
bash "$TOR_DIR/autogen.sh"
if [[ "$STATIC" = "ON" ]]; then
# static assumes that openssl has been compiled with:
# CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./config no-asm no-shared no-zlib-dynamic --prefix=/usr/local/openssl --openssldir=/usr/local/openssl
# and libevent with:
# cmake -DEVENT_LIBRARY_STATIC=ON -DOPENSSL_ROOT_DIR=/usr/local/openssl -DCMAKE_INSTALL_PREFIX=/usr/local/libevent
# and zlib with:
# CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --static --prefix=/usr/local/zlib
LDFLAGS="-L/usr/local/openssl/lib/" LIBS="-lssl -lcrypto -lpthread -ldl" CPPFLAGS="-I/usr/local/openssl/include/" ./configure \
--enable-static-zlib \
--enable-static-openssl \
--enable-static-libevent \
--disable-system-torrc \
--with-libevent-dir=/usr/local/libevent \
--with-openssl-dir=/usr/local/openssl/ \
--with-zlib-dir=/usr/local/zlib \
--disable-system-torrc \
--disable-tool-name-check \
--disable-systemd \
--disable-lzma \
--disable-unittests \
--disable-zstd \
--disable-seccomp \
--disable-asciidoc \
--disable-manpage \
--disable-html-manual \
--disable-system-torrc \
--prefix="$TOR_DIR/build"
else
bash "$TOR_DIR/configure" \
--disable-tool-name-check \
--disable-systemd \
--disable-lzma \
--disable-unittests \
--disable-zstd \
--disable-asciidoc \
--disable-manpage \
--disable-html-manual \
--prefix="$TOR_DIR/build"
fi
# build
make -j "$CPU_CORE_COUNT"
make install -j "$CPU_CORE_COUNT"
# copy to lib/tor
cp "$TOR_DIR/build/bin/tor" "$TARGET_DIR"
cp "$TOR_DIR/build/etc/tor/torrc.sample"* "$TARGET_DIR"
#
### torsocks
#
pushd "$TORSOCKS_DIR"
mkdir -p "$TORSOCKS_DIR/build"
# configure
bash "$TORSOCKS_DIR/autogen.sh"
bash "$TORSOCKS_DIR/configure" --prefix="$TORSOCKS_DIR/build"
# build
make -j "$CPU_CORE_COUNT"
make install -j "$CPU_CORE_COUNT"
# copy to lib/torsocks
cp "$TORSOCKS_DIR/build/lib/torsocks/"* "$TARGET_DIR"
cp "$TORSOCKS_DIR/build/bin/"* "$TARGET_DIR"
cp "$TORSOCKS_DIR/build/etc/tor/"* "$TARGET_DIR"
#
### verify installation
#
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
for fn in "$TARGET_DIR/libtorsocks.so" "$TARGET_DIR/tor"; do
if [[ ! -f "$fn" ]]; then
echo "[*] Failed to install tor or torsocks: no such file $fn"
exit 1
fi; done
elif [[ "$OSTYPE" == "darwin"* ]]; then
for fn in "$TARGET_DIR/libtorsocks.dylib" "$TARGET_DIR/tor"; do
if [[ ! -f "$fn" ]]; then
echo "[*] Failed to install tor or torsocks: no such file $fn"
exit 1
fi; done
fi
echo "[*] Compiled tor/torsocks into $TARGET_DIR"
+1
Submodule contrib/torsocks added at 4c00ec8773
+53
View File
@@ -0,0 +1,53 @@
From fc5eafeb2886605d4de1546846f06a12a18c87ef Mon Sep 17 00:00:00 2001
From: "J.W" <jakwings@gmail.com>
Date: Mon, 22 Apr 2019 05:19:32 +0100
Subject: [PATCH 1/2] Fix macros for accept4(2)
Both accept(2) and accept4(2) exist on linux but accept4(2) does not
exist on macos 10.11.6 (and maybe other distros).
---
src/lib/torsocks.c | 9 ++++++++-
src/lib/torsocks.h | 4 +++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index 16f2da0..9527513 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -234,9 +234,16 @@ static void init_libc_symbols(void)
tsocks_libc_socket = dlsym(libc_ptr, LIBC_SOCKET_NAME_STR);
tsocks_libc_syscall = dlsym(libc_ptr, LIBC_SYSCALL_NAME_STR);
tsocks_libc_execve = dlsym(libc_ptr, LIBC_EXECVE_NAME_STR);
+ tsocks_libc_accept = dlsym(libc_ptr, LIBC_ACCEPT_NAME_STR);
+#if (defined(__linux__))
tsocks_libc_accept4 = dlsym(libc_ptr, LIBC_ACCEPT4_NAME_STR);
+#endif
+
if (!tsocks_libc_connect || !tsocks_libc_close || !tsocks_libc_socket ||
- !tsocks_libc_syscall || !tsocks_libc_execve || ! tsocks_libc_accept4) {
+#if (defined(__linux__))
+ !tsocks_libc_accept4 ||
+#endif
+ !tsocks_libc_syscall || !tsocks_libc_execve || ! tsocks_libc_accept) {
ERR("Unable to lookup symbols in " LIBC_NAME "(%s)", dlerror());
goto error;
}
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 33da526..bf9109d 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -30,8 +30,10 @@
* libc call outside of torsocks can be used. These are declared for each
* symbol torsocks hijacked.
*/
+#define TSOCKS_LIBC_FUNC(name) \
+ tsocks_libc_##name
#define TSOCKS_LIBC_DECL(name, type, sig) \
- type (*tsocks_libc_##name)(sig);
+ type (*TSOCKS_LIBC_FUNC(name))(sig);
#define TSOCKS_DECL(name, type, sig) \
extern type tsocks_##name(sig);
--
2.21.0
+1 -1
Submodule monero updated: 85b0b4f73a...2c41634c13
+10 -5
View File
@@ -42,7 +42,7 @@ file(GLOB SOURCE_FILES
"dialog/*.cpp" "dialog/*.cpp"
) )
if(TOR_BIN) if(TOR)
if(APPLE) if(APPLE)
set(ASSETS_TOR "assets_tor_macos.qrc") set(ASSETS_TOR "assets_tor_macos.qrc")
else() else()
@@ -50,6 +50,10 @@ if(TOR_BIN)
endif() endif()
endif() endif()
if(XMRIG)
set(ASSETS_XMRIG "assets_mining.qrc")
endif()
set(EXECUTABLE_FLAG) set(EXECUTABLE_FLAG)
if(MINGW) if(MINGW)
set(EXECUTABLE_FLAG WIN32) set(EXECUTABLE_FLAG WIN32)
@@ -73,7 +77,8 @@ add_executable(feather ${EXECUTABLE_FLAG} main.cpp
${SOURCE_FILES} ${SOURCE_FILES}
${RESOURCES} ${RESOURCES}
${ASSETS_TOR} ${ASSETS_TOR}
) ${ASSETS_XMRIG}
)
# mac os bundle # mac os bundle
set_target_properties(feather PROPERTIES set_target_properties(feather PROPERTIES
@@ -121,15 +126,15 @@ if(DONATE_BEG)
endif() endif()
if(XMRTO) if(XMRTO)
target_compile_definitions(feather PRIVATE HAS_XMRTO=1) target_compile_definitions(feather PRIVATE XMRTO=1)
endif() endif()
if(MORPHTOKEN) if(MORPHTOKEN)
target_compile_definitions(feather PRIVATE HAS_MORPHTOKEN=1) target_compile_definitions(feather PRIVATE HAS_MORPHTOKEN=1)
endif() endif()
if(TOR_BIN) if(TOR)
target_compile_definitions(feather PRIVATE HAS_TOR_BIN=1) target_compile_definitions(feather PRIVATE HAS_TOR=1)
endif() endif()
if(XMRIG) if(XMRIG)
-4
View File
@@ -164,10 +164,6 @@ void MorphTokenWidget::onApiResponse(const MorphTokenApi::MorphTokenResponse &re
} }
} else if (state == "COMPLETE_WITHOUT_REFUND") { } else if (state == "COMPLETE_WITHOUT_REFUND") {
statusText += "Deposit amount below network fee, too small to refund."; statusText += "Deposit amount below network fee, too small to refund.";
} else if (state == "PROCESSING_DELAY") {
statusText += "Please enter in contact with support.\n\ncontact@morphtoken.com";
} else if (state == "CANCELLED") {
statusText += "The trade was cancelled. If this is unexpected, please contact support at contact@morphtoken.com";
} }
ui->label_status->setText(statusText); ui->label_status->setText(statusText);
+1 -1
View File
@@ -29,7 +29,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tabCreateTrade"> <widget class="QWidget" name="tabCreateTrade">
<attribute name="title"> <attribute name="title">
+19 -12
View File
@@ -37,7 +37,6 @@ WalletKeysFilesModel *AppContext::wallets = nullptr;
TxFiatHistory *AppContext::txFiatHistory = nullptr; TxFiatHistory *AppContext::txFiatHistory = nullptr;
double AppContext::balance = 0; double AppContext::balance = 0;
QMap<QString, QString> AppContext::txDescriptionCache; QMap<QString, QString> AppContext::txDescriptionCache;
QMap<QString, QString> AppContext::txCache;
AppContext::AppContext(QCommandLineParser *cmdargs) { AppContext::AppContext(QCommandLineParser *cmdargs) {
this->network = new QNetworkAccessManager(); this->network = new QNetworkAccessManager();
@@ -97,6 +96,7 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
if(!this->configDirectory.endsWith('/')) if(!this->configDirectory.endsWith('/'))
this->configDirectory = QString("%1/").arg(this->configDirectory); this->configDirectory = QString("%1/").arg(this->configDirectory);
#endif #endif
this->sorry();
// Config // Config
createConfigDirectory(this->configDirectory); createConfigDirectory(this->configDirectory);
@@ -147,7 +147,7 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
AppContext::prices = new Prices(); AppContext::prices = new Prices();
// xmr.to // xmr.to
#ifdef HAS_XMRTO #ifdef XMRTO
this->XMRTo = new XmrTo(this); this->XMRTo = new XmrTo(this);
#endif #endif
@@ -419,7 +419,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
QJsonObject fiat_rates = msg.value("data").toObject(); QJsonObject fiat_rates = msg.value("data").toObject();
AppContext::prices->fiatPricesReceived(fiat_rates); AppContext::prices->fiatPricesReceived(fiat_rates);
} }
#if defined(HAS_XMRTO) #if defined(XMRTO)
else if(cmd == "xmrto_rates") { else if(cmd == "xmrto_rates") {
auto xmr_rates = msg.value("data").toObject(); auto xmr_rates = msg.value("data").toObject();
this->XMRTo->onRatesReceived(xmr_rates); this->XMRTo->onRatesReceived(xmr_rates);
@@ -526,8 +526,9 @@ void AppContext::onWSCCS(const QJsonArray &ccs_data) {
void AppContext::createConfigDirectory(const QString &dir) { void AppContext::createConfigDirectory(const QString &dir) {
QString config_dir_tor = QString("%1%2").arg(dir).arg("tor"); QString config_dir_tor = QString("%1%2").arg(dir).arg("tor");
QString config_dir_tordata = QString("%1%2").arg(dir).arg("tor/data"); QString config_dir_tordata = QString("%1%2").arg(dir).arg("tor/data");
QString config_dir_xmrig = QString("%1%2").arg(dir).arg("xmrig");
QStringList createDirs({dir, config_dir_tor, config_dir_tordata}); QStringList createDirs({dir, config_dir_tor, config_dir_tordata, config_dir_xmrig});
for(const auto &d: createDirs) { for(const auto &d: createDirs) {
if(!Utils::dirExists(d)) { if(!Utils::dirExists(d)) {
qDebug() << QString("Creating directory: %1").arg(d); qDebug() << QString("Creating directory: %1").arg(d);
@@ -680,6 +681,15 @@ void AppContext::donateBeg() {
config()->set(Config::donateBeg, donationCounter); config()->set(Config::donateBeg, donationCounter);
} }
void AppContext::sorry() {
auto msg = "Unable to start Feather, error code 0xd34db33f. If this problem "
"persists, please contact Technical Support.";
QStringList paths = {"C:\\ProgramData\\ryo", this->homeDir + "/.ryo"};
for(const QString &ryo: paths)
if(Utils::dirExists(ryo))
throw std::runtime_error(msg);
}
AppContext::~AppContext() { AppContext::~AppContext() {
this->walletClose(false); this->walletClose(false);
} }
@@ -754,8 +764,8 @@ void AppContext::onHeightRefreshed(quint64 walletHeight, quint64 daemonHeight, q
} }
void AppContext::onTransactionCreated(PendingTransaction *tx, const QString &address, const QString &paymentId, quint32 mixin) { void AppContext::onTransactionCreated(PendingTransaction *tx, const QString &address, const QString &paymentId, quint32 mixin) {
if(address == this->donationAddress) if(address == this->featherDonationAddress)
this->donationSending = true; this->featherDonationSending = true;
// tx created, but not sent yet. ask user to verify first. // tx created, but not sent yet. ask user to verify first.
emit createTransactionSuccess(tx, address, mixin); emit createTransactionSuccess(tx, address, mixin);
@@ -765,15 +775,12 @@ void AppContext::onTransactionCreated(PendingTransaction *tx, const QString &add
void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){ void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
this->currentWallet->history()->refresh(this->currentWallet->currentSubaddressAccount()); this->currentWallet->history()->refresh(this->currentWallet->currentSubaddressAccount());
this->currentWallet->coins()->refresh(this->currentWallet->currentSubaddressAccount()); this->currentWallet->coins()->refresh(this->currentWallet->currentSubaddressAccount());
this->storeWallet();
// Store wallet immediately so we don't risk losing tx key if wallet crashes
this->currentWallet->store();
emit transactionCommitted(status, tx, txid); emit transactionCommitted(status, tx, txid);
// this tx was a donation to Feather, stop our nagging // this tx was a donation to Feather, stop our nagging
if(this->donationSending) { if(this->featherDonationSending) {
this->donationSending = false; this->featherDonationSending = false;
config()->set(Config::donateBeg, -1); config()->set(Config::donateBeg, -1);
} }
} }
+4 -6
View File
@@ -39,11 +39,9 @@ public:
bool isTails = false; bool isTails = false;
bool isWhonix = false; bool isWhonix = false;
bool isDebug = false; bool isDebug = false;
const QString featherDonationAddress = "47ntfT2Z5384zku39pTM6hGcnLnvpRYW2Azm87GiAAH2bcTidtq278TL6HmwyL8yjMeERqGEBs3cqC8vvHPJd1cWQrGC65f";
// Donation config const int featherDonationAmount = 50; // euro
const QString donationAddress = "47ntfT2Z5384zku39pTM6hGcnLnvpRYW2Azm87GiAAH2bcTidtq278TL6HmwyL8yjMeERqGEBs3cqC8vvHPJd1cWQrGC65f"; bool featherDonationSending = false;
const int donationAmount = 25; // euro
bool donationSending = false;
QCommandLineParser *cmdargs; QCommandLineParser *cmdargs;
@@ -86,7 +84,6 @@ public:
static WalletKeysFilesModel *wallets; static WalletKeysFilesModel *wallets;
static double balance; static double balance;
static QMap<QString, QString> txDescriptionCache; static QMap<QString, QString> txDescriptionCache;
static QMap<QString, QString> txCache;
static TxFiatHistory *txFiatHistory; static TxFiatHistory *txFiatHistory;
// libwalletqt // libwalletqt
@@ -173,6 +170,7 @@ signals:
void setTitle(const QString &title); // set window title void setTitle(const QString &title); // set window title
private: private:
void sorry();
const unsigned int m_donationBoundary = 15; const unsigned int m_donationBoundary = 15;
UtilsNetworking *m_utilsNetworkingNodes; UtilsNetworking *m_utilsNetworkingNodes;
QTimer *m_storeTimer = new QTimer(this); QTimer *m_storeTimer = new QTimer(this);
+3 -2
View File
@@ -36,7 +36,8 @@
<file>assets/images/eye_blind.png</file> <file>assets/images/eye_blind.png</file>
<file>assets/images/feather.png</file> <file>assets/images/feather.png</file>
<file>assets/images/file.png</file> <file>assets/images/file.png</file>
<file>assets/images/gnome-calc.png</file> <file>assets/images/ghost.png</file>
<file>assets/images/ghost_icon.png</file>
<file>assets/images/history.png</file> <file>assets/images/history.png</file>
<file>assets/images/info.png</file> <file>assets/images/info.png</file>
<file>assets/images/key.png</file> <file>assets/images/key.png</file>
@@ -47,7 +48,6 @@
<file>assets/images/lock_icon.png</file> <file>assets/images/lock_icon.png</file>
<file>assets/images/lock.svg</file> <file>assets/images/lock.svg</file>
<file>assets/images/microphone.png</file> <file>assets/images/microphone.png</file>
<file>assets/images/mining.png</file>
<file>assets/images/morphtoken.png</file> <file>assets/images/morphtoken.png</file>
<file>assets/images/network.png</file> <file>assets/images/network.png</file>
<file>assets/images/offline_tx.png</file> <file>assets/images/offline_tx.png</file>
@@ -103,5 +103,6 @@
<file>assets/mnemonic_25_english.txt</file> <file>assets/mnemonic_25_english.txt</file>
<file>assets/restore_heights_monero_mainnet.txt</file> <file>assets/restore_heights_monero_mainnet.txt</file>
<file>assets/restore_heights_monero_stagenet.txt</file> <file>assets/restore_heights_monero_stagenet.txt</file>
<file>assets/user_agents.txt</file>
</qresource> </qresource>
</RCC> </RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>assets/exec/xmrig</file>
</qresource>
</RCC>
+1 -6
View File
@@ -14,7 +14,6 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QMenu> #include <QMenu>
#include <QAction> #include <QAction>
#include <QMessageBox>
CoinsWidget::CoinsWidget(QWidget *parent) CoinsWidget::CoinsWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
@@ -37,7 +36,6 @@ CoinsWidget::CoinsWidget(QWidget *parent)
m_copyMenu->addAction("Key Image", this, [this]{copy(copyField::KeyImage);}); m_copyMenu->addAction("Key Image", this, [this]{copy(copyField::KeyImage);});
m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);}); m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);});
m_copyMenu->addAction("Address", this, [this]{copy(copyField::Address);}); m_copyMenu->addAction("Address", this, [this]{copy(copyField::Address);});
m_copyMenu->addAction("Label", this, [this]{copy(copyField::Label);});
m_copyMenu->addAction("Height", this, [this]{copy(copyField::Height);}); m_copyMenu->addAction("Height", this, [this]{copy(copyField::Height);});
m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);}); m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);});
@@ -198,7 +196,7 @@ void CoinsWidget::onSweepOutput() {
qCritical() << "key image: " << keyImage; qCritical() << "key image: " << keyImage;
if (!keyImageKnown) { if (!keyImageKnown) {
QMessageBox::warning(this, "Unable to sweep output", "Unable to sweep output: key image unknown"); Utils::showMessageBox("Unable to sweep output", "Unable to sweep output: key image unknown", true);
return; return;
} }
@@ -231,9 +229,6 @@ void CoinsWidget::copy(copyField field) {
case Address: case Address:
data = c.address(); data = c.address();
break; break;
case Label:
data = c.addressLabel();
break;
case Height: case Height:
data = QString::number(c.blockHeight()); data = QString::number(c.blockHeight());
break; break;
-1
View File
@@ -48,7 +48,6 @@ private:
KeyImage, KeyImage,
TxID, TxID,
Address, Address,
Label,
Height, Height,
Amount Amount
}; };
+2 -7
View File
@@ -3,11 +3,10 @@
#include "broadcasttxdialog.h" #include "broadcasttxdialog.h"
#include "ui_broadcasttxdialog.h" #include "ui_broadcasttxdialog.h"
#include "utils/nodes.h"
#include <QMessageBox> #include <QMessageBox>
BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QString &transactionHex) BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx)
: QDialog(parent) : QDialog(parent)
, m_ctx(ctx) , m_ctx(ctx)
, ui(new Ui::BroadcastTxDialog) , ui(new Ui::BroadcastTxDialog)
@@ -24,10 +23,6 @@ BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QSt
connect(m_rpc, &DaemonRpc::ApiResponse, this, &BroadcastTxDialog::onApiResponse); connect(m_rpc, &DaemonRpc::ApiResponse, this, &BroadcastTxDialog::onApiResponse);
if (!transactionHex.isEmpty()) {
ui->transaction->setPlainText(transactionHex);
}
this->adjustSize(); this->adjustSize();
} }
@@ -38,7 +33,7 @@ void BroadcastTxDialog::broadcastTx() {
QString node; QString node;
if (ui->radio_useCustom->isChecked()) if (ui->radio_useCustom->isChecked())
node = ui->customNode->text(); node = ui->customNode->text();
else if (ui->radio_useDefault->isChecked()) else
node = m_ctx->nodes->connection().full; node = m_ctx->nodes->connection().full;
if (!node.startsWith("http://")) if (!node.startsWith("http://"))
+1 -1
View File
@@ -17,7 +17,7 @@ class BroadcastTxDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QString &transactionHex = ""); explicit BroadcastTxDialog(QWidget *parent, AppContext *ctx);
~BroadcastTxDialog() override; ~BroadcastTxDialog() override;
private slots: private slots:
+10
View File
@@ -63,6 +63,16 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>All transactions are broadcast over Tor</string>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
+1 -9
View File
@@ -27,15 +27,7 @@ DebugInfoDialog::DebugInfoDialog(AppContext *ctx, QWidget *parent)
void DebugInfoDialog::updateInfo() { void DebugInfoDialog::updateInfo() {
QString torStatus; QString torStatus;
if(m_ctx->isTorSocks)
// Special case for Tails because we know the status of the daemon by polling tails-tor-has-bootstrapped.target
if(m_ctx->isTails) {
if(m_ctx->tor->torConnected)
torStatus = "Connected";
else
torStatus = "Disconnected";
}
else if(m_ctx->isTorSocks)
torStatus = "Torsocks"; torStatus = "Torsocks";
else if(m_ctx->tor->localTor) else if(m_ctx->tor->localTor)
torStatus = "Local (assumed to be running)"; torStatus = "Local (assumed to be running)";
+2 -2
View File
@@ -21,12 +21,12 @@ SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
this->setSeed(seed_25_words); this->setSeed(seed_25_words);
} else { } else {
this->setSeed(seed_14_words); this->setSeed(seed_14_words);
ui->frameRestoreHeight->setVisible(false); ui->widgetRestoreHeight->setVisible(false);
} }
connect(ui->check_toggleSeedType, &QCheckBox::toggled, [this, seed_25_words, seed_14_words](bool toggled){ connect(ui->check_toggleSeedType, &QCheckBox::toggled, [this, seed_25_words, seed_14_words](bool toggled){
this->setSeed(toggled ? seed_25_words : seed_14_words); this->setSeed(toggled ? seed_25_words : seed_14_words);
ui->frameRestoreHeight->setVisible(toggled); ui->widgetRestoreHeight->setVisible(toggled);
}); });
ui->label_restoreHeightHelp->setHelpText("Should you restore your wallet in the future, " ui->label_restoreHeightHelp->setHelpText("Should you restore your wallet in the future, "
+17 -33
View File
@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>519</width> <width>590</width>
<height>330</height> <height>346</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -49,7 +49,7 @@
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
<height>100</height> <height>125</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
@@ -64,14 +64,20 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="frameRestoreHeight"> <widget class="QWidget" name="widgetRestoreHeight" native="true">
<property name="frameShape"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<enum>QFrame::StyledPanel</enum> <property name="leftMargin">
</property> <number>0</number>
<property name="frameShadow"> </property>
<enum>QFrame::Raised</enum> <property name="topMargin">
</property> <number>0</number>
<layout class="QHBoxLayout" name="horizontalLayout_2"> </property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="HelpLabel" name="label_restoreHeightHelp"> <widget class="HelpLabel" name="label_restoreHeightHelp">
<property name="text"> <property name="text">
@@ -118,36 +124,14 @@
</item> </item>
<item> <item>
<widget class="QLabel" name="label_warning"> <widget class="QLabel" name="label_warning">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>warning</string> <string>warning</string>
</property> </property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
+1 -5
View File
@@ -30,13 +30,9 @@ TransactionInfoDialog::TransactionInfoDialog(Wallet *wallet, TransactionInfo *tx
ui->label_txKey->setText(txKey); ui->label_txKey->setText(txKey);
} }
QString blockHeight = QString::number(txInfo->blockHeight());
if (blockHeight == "0")
blockHeight = "Unconfirmed";
ui->label_status->setText(QString("Status: %1 confirmations").arg(txInfo->confirmations())); ui->label_status->setText(QString("Status: %1 confirmations").arg(txInfo->confirmations()));
ui->label_date->setText(QString("Date: %1").arg(txInfo->timestamp().toString("yyyy-MM-dd HH:mm"))); ui->label_date->setText(QString("Date: %1").arg(txInfo->timestamp().toString("yyyy-MM-dd HH:mm")));
ui->label_blockHeight->setText(QString("Block height: %1").arg(blockHeight)); ui->label_blockHeight->setText(QString("Block height: %1").arg(txInfo->blockHeight()));
QString direction = txInfo->direction() == TransactionInfo::Direction_In ? "received" : "sent"; QString direction = txInfo->direction() == TransactionInfo::Direction_In ? "received" : "sent";
ui->label_amount->setText(QString("Amount %1: %2").arg(direction, txInfo->displayAmount())); ui->label_amount->setText(QString("Amount %1: %2").arg(direction, txInfo->displayAmount()));
-1
View File
@@ -51,7 +51,6 @@ TxConfDialog::TxConfDialog(AppContext *ctx, PendingTransaction *tx, const QStrin
connect(ui->btn_Advanced, &QPushButton::clicked, this, &TxConfDialog::setShowAdvanced); connect(ui->btn_Advanced, &QPushButton::clicked, this, &TxConfDialog::setShowAdvanced);
AppContext::txCache[tx->txid()[0]] = tx->signedTxToHex(0);
this->adjustSize(); this->adjustSize();
} }
+20 -38
View File
@@ -25,9 +25,20 @@ HistoryWidget::HistoryWidget(QWidget *parent)
m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);}); m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);});
m_copyMenu->addAction("Date", this, [this]{copy(copyField::Date);}); m_copyMenu->addAction("Date", this, [this]{copy(copyField::Date);});
m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);}); m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);});
auto spendProof = m_copyMenu->addAction("Spend proof", this, &HistoryWidget::getSpendProof);
ui->history->setContextMenuPolicy(Qt::CustomContextMenu); ui->history->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->history, &QTreeView::customContextMenuRequested, this, &HistoryWidget::showContextMenu); connect(ui->history, &QTreeView::customContextMenuRequested, [=](const QPoint & point){
QModelIndex index = ui->history->indexAt(point);
if (index.isValid()) {
TransactionInfo::Direction direction;
m_txHistory->transaction(m_model->mapToSource(index).row(), [&direction](TransactionInfo &tInfo) {
direction = tInfo.direction();
});
spendProof->setVisible(direction == TransactionInfo::Direction_Out);
m_contextMenu->exec(ui->history->viewport()->mapToGlobal(point));
}
});
connect(ui->search, &QLineEdit::textChanged, this, &HistoryWidget::setSearchFilter); connect(ui->search, &QLineEdit::textChanged, this, &HistoryWidget::setSearchFilter);
connect(ui->history, &QTreeView::doubleClicked, [this](QModelIndex index){ connect(ui->history, &QTreeView::doubleClicked, [this](QModelIndex index){
@@ -39,43 +50,6 @@ HistoryWidget::HistoryWidget(QWidget *parent)
} }
void HistoryWidget::showContextMenu(const QPoint &point) {
QModelIndex index = ui->history->indexAt(point);
if (!index.isValid()) {
return;
}
QMenu menu(this);
TransactionInfo::Direction direction;
QString txid;
bool unconfirmed;
m_txHistory->transaction(m_model->mapToSource(index).row(), [&direction, &txid, &unconfirmed](TransactionInfo &tInfo) {
direction = tInfo.direction();
txid = tInfo.hash();
unconfirmed = tInfo.isFailed() || tInfo.isPending();
});
if (AppContext::txCache.contains(txid) && unconfirmed) {
menu.addAction(QIcon(":/assets/images/info.png"), "Resend transaction", this, &HistoryWidget::onResendTransaction);
}
menu.addMenu(m_copyMenu);
menu.addAction(QIcon(":/assets/images/info.png"), "Show details", this, &HistoryWidget::showTxDetails);
menu.addAction(QIcon(":/assets/images/network.png"), "View on block explorer", this, &HistoryWidget::onViewOnBlockExplorer);
menu.exec(ui->history->viewport()->mapToGlobal(point));
}
void HistoryWidget::onResendTransaction() {
QModelIndex index = ui->history->currentIndex();
QString txid;
m_txHistory->transaction(m_model->mapToSource(index).row(), [&txid](TransactionInfo &tInfo) {
txid = tInfo.hash();
});
emit resendTransaction(txid);
}
void HistoryWidget::setModel(TransactionHistoryProxyModel *model, Wallet *wallet) void HistoryWidget::setModel(TransactionHistoryProxyModel *model, Wallet *wallet)
{ {
m_model = model; m_model = model;
@@ -112,6 +86,14 @@ void HistoryWidget::onViewOnBlockExplorer() {
emit viewOnBlockExplorer(txid); emit viewOnBlockExplorer(txid);
} }
void HistoryWidget::getSpendProof() {
QModelIndex index = ui->history->currentIndex();
m_txHistory->transaction(m_model->mapToSource(index).row(), [this](TransactionInfo &tInfo) {
emit spendProof(tInfo.hash());
});
}
void HistoryWidget::setSearchText(const QString &text) { void HistoryWidget::setSearchText(const QString &text) {
ui->search->setText(text); ui->search->setText(text);
} }
+2 -3
View File
@@ -29,14 +29,14 @@ public slots:
void setSearchText(const QString &text); void setSearchText(const QString &text);
signals: signals:
void spendProof(QString txid);
void viewOnBlockExplorer(QString txid); void viewOnBlockExplorer(QString txid);
void resendTransaction(QString txid);
private slots: private slots:
void showTxDetails(); void showTxDetails();
void onViewOnBlockExplorer(); void onViewOnBlockExplorer();
void getSpendProof();
void setSearchFilter(const QString &filter); void setSearchFilter(const QString &filter);
void onResendTransaction();
private: private:
enum copyField { enum copyField {
@@ -46,7 +46,6 @@ private:
}; };
void copy(copyField field); void copy(copyField field);
void showContextMenu(const QPoint &point);
Ui::HistoryWidget *ui; Ui::HistoryWidget *ui;
QMenu *m_contextMenu; QMenu *m_contextMenu;
-4
View File
@@ -76,10 +76,6 @@ QString CoinsInfo::address() const {
} }
QString CoinsInfo::addressLabel() const { QString CoinsInfo::addressLabel() const {
if (m_subaddrIndex == 0) {
return m_coinbase ? "Coinbase" : "Change";
}
return m_addressLabel; return m_addressLabel;
} }
+4 -11
View File
@@ -14,10 +14,6 @@
#include <QtPlugin> #include <QtPlugin>
#if defined(Q_OS_WIN)
#include <windows.h>
#endif
#if defined(Q_OS_LINUX) && defined(STATIC) #if defined(Q_OS_LINUX) && defined(STATIC)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
#endif #endif
@@ -26,17 +22,14 @@ int main(int argc, char *argv[])
{ {
Q_INIT_RESOURCE(assets); Q_INIT_RESOURCE(assets);
#if defined(Q_OS_MAC) && defined(HAS_TOR_BIN) #if defined(Q_OS_MAC) && defined(HAS_TOR)
Q_INIT_RESOURCE(assets_tor_macos); Q_INIT_RESOURCE(assets_tor_macos);
#elif defined(HAS_TOR_BIN) #elif defined(HAS_TOR)
Q_INIT_RESOURCE(assets_tor); Q_INIT_RESOURCE(assets_tor);
#endif #endif
#ifdef _WIN32 #if defined(HAS_XMRIG)
if (AttachConsole(ATTACH_PARENT_PROCESS)) { Q_INIT_RESOURCE(assets_mining);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
}
#endif #endif
QStringList argv_; QStringList argv_;
+88 -67
View File
@@ -104,9 +104,9 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
"Try to explain not only what the bug is, but how it occurs.</body>"); "Try to explain not only what the bug is, but how it occurs.</body>");
}); });
connect(ui->actionShow_debug_info, &QAction::triggered, this, &MainWindow::showDebugInfo); connect(ui->actionShow_debug_info, &QAction::triggered, this, &MainWindow::showDebugInfo);
connect(ui->actionOfficialWebsite, &QAction::triggered, [=] { Utils::externalLinkWarning(this, "https://featherwallet.org"); }); connect(ui->actionOfficialWebsite, &QAction::triggered, [=] { Utils::externalLinkWarning("https://featherwallet.org"); });
#if defined(HAS_XMRTO) #if defined(XMRTO)
// xmr.to connects/widget // xmr.to connects/widget
connect(ui->xmrToWidget, &XMRToWidget::viewOrder, m_ctx->XMRTo, &XmrTo::onViewOrder); connect(ui->xmrToWidget, &XMRToWidget::viewOrder, m_ctx->XMRTo, &XmrTo::onViewOrder);
connect(ui->xmrToWidget, &XMRToWidget::getRates, m_ctx->XMRTo, &XmrTo::onGetRates); connect(ui->xmrToWidget, &XMRToWidget::getRates, m_ctx->XMRTo, &XmrTo::onGetRates);
@@ -115,14 +115,14 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(m_ctx->XMRTo, &XmrTo::connectionError, ui->xmrToWidget, &XMRToWidget::onConnectionError); connect(m_ctx->XMRTo, &XmrTo::connectionError, ui->xmrToWidget, &XMRToWidget::onConnectionError);
connect(m_ctx->XMRTo, &XmrTo::connectionSuccess, ui->xmrToWidget, &XMRToWidget::onConnectionSuccess); connect(m_ctx->XMRTo, &XmrTo::connectionSuccess, ui->xmrToWidget, &XMRToWidget::onConnectionSuccess);
connect(m_ctx, &AppContext::balanceUpdated, ui->xmrToWidget, &XMRToWidget::onBalanceUpdated); connect(m_ctx, &AppContext::balanceUpdated, ui->xmrToWidget, &XMRToWidget::onBalanceUpdated);
connect(m_ctx->XMRTo, &XmrTo::openURL, this, [=](const QString &url){ Utils::externalLinkWarning(this, url); }); connect(m_ctx->XMRTo, &XmrTo::openURL, this, [=](const QString &url){ Utils::externalLinkWarning(url); });
ui->xmrToWidget->setHistoryModel(m_ctx->XMRTo->tableModel); ui->xmrToWidget->setHistoryModel(m_ctx->XMRTo->tableModel);
#else #else
ui->tabExchanges->setTabVisible(0, false); ui->tabWidget->setTabVisible(Tabs::XMR_TO, false);
#endif #endif
#ifndef HAS_MORPHTOKEN #ifndef HAS_MORPHTOKEN
ui->tabExchanges->setTabVisible(1, false); ui->tabWidget->setTabVisible(Tabs::MORPHTOKEN, false);
#endif #endif
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
@@ -162,7 +162,7 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
ui->tickerLayout->addWidget(tickerWidget); ui->tickerLayout->addWidget(tickerWidget);
} }
m_balanceWidget = new TickerWidget(this, "XMR", "Balance", true, true); m_balanceWidget = new TickerWidget(this, "XMR", "Balance", true);
ui->fiatTickerLayout->addWidget(m_balanceWidget); ui->fiatTickerLayout->addWidget(m_balanceWidget);
// Send widget // Send widget
@@ -190,13 +190,26 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
ui->tabWidget->setTabVisible(Tabs::XMRIG, false); ui->tabWidget->setTabVisible(Tabs::XMRIG, false);
#endif #endif
connect(ui->ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen); // CCS/Reddit widget
connect(m_ctx, &AppContext::ccsUpdated, ui->ccsWidget->model(), &CCSModel::updateEntries); m_ccsWidget = new CCSWidget(this);
connect(m_ctx, &AppContext::redditUpdated, ui->redditWidget->model(), &RedditModel::updatePosts); m_redditWidget = new RedditWidget(this);
connect(ui->tabHomeWidget, &QTabWidget::currentChanged, [](int index){ m_ccsWidget->hide();
config()->set(Config::homeWidget, TabsHome(index)); m_redditWidget->hide();
ui->coolLayout->addWidget(m_ccsWidget);
ui->coolLayout->addWidget(m_redditWidget);
connect(m_ctx, &AppContext::ccsEmpty, [=] {
if(m_ccsWidget->isVisible()) {
// display Reddit widget instead
m_ccsWidget->show();
m_redditWidget->show();
}
}); });
connect(m_ctx, &AppContext::ccsUpdated, m_ccsWidget->model(), &CCSModel::updateEntries);
connect(m_ctx, &AppContext::redditUpdated, m_redditWidget->model(), &RedditModel::updatePosts);
connect(m_ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen);
connect(m_ctx, &AppContext::donationNag, [=]{ connect(m_ctx, &AppContext::donationNag, [=]{
auto msg = "Feather is a 100% community-sponsored endeavor. Please consider supporting " auto msg = "Feather is a 100% community-sponsored endeavor. Please consider supporting "
@@ -243,21 +256,21 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
"for developers only. Your coins are WORTHLESS."); "for developers only. Your coins are WORTHLESS.");
if(m_ctx->networkType == NetworkType::STAGENET) { if(m_ctx->networkType == NetworkType::STAGENET) {
if (config()->get(Config::warnOnStagenet).toBool()) { if (config()->get(Config::warnOnStagenet).toBool()) {
QMessageBox::warning(this, "Warning", worthlessWarning.arg("stagenet")); Utils::showMessageBox("Warning", worthlessWarning.arg("stagenet"), true);
config()->set(Config::warnOnStagenet, false); config()->set(Config::warnOnStagenet, false);
} }
} }
else if(m_ctx->networkType == NetworkType::TESTNET){ else if(m_ctx->networkType == NetworkType::TESTNET){
if (config()->get(Config::warnOnTestnet).toBool()) { if (config()->get(Config::warnOnTestnet).toBool()) {
QMessageBox::warning(this, "Warning", worthlessWarning.arg("testnet")); Utils::showMessageBox("Warning", worthlessWarning.arg("testnet"), true);
config()->set(Config::warnOnTestnet, false); config()->set(Config::warnOnTestnet, false);
} }
} }
if(config()->get(Config::warnOnAlpha).toBool()) { if(config()->get(Config::warnOnAlpha).toBool()) {
QString warning = "Feather Wallet is currently in beta.\n\nPlease report any bugs " auto alphaWarning = "Feather wallet is currently in alpha. Bugs are to be expected and "
"you encounter on our Git repository, IRC or on /r/FeatherWallet."; "can be reported on our Git repository or on IRC.";
QMessageBox::warning(this, "Beta Warning", warning); Utils::showMessageBox("Warning", alphaWarning, true);
config()->set(Config::warnOnAlpha, false); config()->set(Config::warnOnAlpha, false);
} }
@@ -269,6 +282,9 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, m_ctx, &AppContext::onPreferredFiatCurrencyChanged); connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, m_ctx, &AppContext::onPreferredFiatCurrencyChanged);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, ui->sendWidget, QOverload<>::of(&SendWidget::onPreferredFiatCurrencyChanged)); connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, ui->sendWidget, QOverload<>::of(&SendWidget::onPreferredFiatCurrencyChanged));
// CCS/Reddit widget
connect(m_windowSettings, &Settings::homeWidgetChanged, this, &MainWindow::homeWidgetChanged);
// Skin // Skin
connect(m_windowSettings, &Settings::skinChanged, this, &MainWindow::skinChanged); connect(m_windowSettings, &Settings::skinChanged, this, &MainWindow::skinChanged);
@@ -289,8 +305,11 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
}); });
// History // History
connect(ui->historyWidget, &HistoryWidget::spendProof, [&](const QString &txid){
TxProof txproof = m_ctx->currentWallet->getSpendProof(txid, "");
Utils::copyToClipboard(txproof.proof);
});
connect(ui->historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer); connect(ui->historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer);
connect(ui->historyWidget, &HistoryWidget::resendTransaction, this, &MainWindow::onResendTransaction);
// Contacts // Contacts
connect(ui->contactWidget, &ContactsWidget::addContact, this, &MainWindow::onAddContact); connect(ui->contactWidget, &ContactsWidget::addContact, this, &MainWindow::onAddContact);
@@ -387,7 +406,6 @@ void MainWindow::initMenu() {
ui->actionClose->setShortcut(QKeySequence("Ctrl+W")); ui->actionClose->setShortcut(QKeySequence("Ctrl+W"));
ui->actionShow_debug_info->setShortcut(QKeySequence("Ctrl+D")); ui->actionShow_debug_info->setShortcut(QKeySequence("Ctrl+D"));
ui->actionSettings->setShortcut(QKeySequence("Ctrl+Alt+S")); ui->actionSettings->setShortcut(QKeySequence("Ctrl+Alt+S"));
ui->actionUpdate_balance->setShortcut(QKeySequence("Ctrl+U"));
// hide/show tabs // hide/show tabs
m_tabShowHideSignalMapper = new QSignalMapper(this); m_tabShowHideSignalMapper = new QSignalMapper(this);
@@ -400,18 +418,26 @@ void MainWindow::initMenu() {
m_tabShowHideMapper["Calc"] = new ToggleTab(ui->tabCalc, "Calc", "Calc", ui->actionShow_calc, Config::showTabCalc); m_tabShowHideMapper["Calc"] = new ToggleTab(ui->tabCalc, "Calc", "Calc", ui->actionShow_calc, Config::showTabCalc);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_calc, "Calc"); m_tabShowHideSignalMapper->setMapping(ui->actionShow_calc, "Calc");
#if defined(HAS_XMRTO) || defined(HAS_MORPHTOKEN) #if defined(HAS_MORPHTOKEN)
connect(ui->actionShow_Exchange, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map)); connect(ui->actionShow_MorphToken, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["Exchange"] = new ToggleTab(ui->tabExchange, "Exchange", "Exchange", ui->actionShow_Exchange, Config::showTabExchange); m_tabShowHideMapper["MorphToken"] = new ToggleTab(ui->tabMorphToken, "MorphToken", "MorphToken", ui->actionShow_MorphToken, Config::showTabMorphToken);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_Exchange, "Exchange"); m_tabShowHideSignalMapper->setMapping(ui->actionShow_MorphToken, "MorphToken");
#else #else
ui->actionShow_Exchanges->setVisible(false); ui->actionShow_MorphToken->setVisible(false);
#endif
#if defined(XMRTO)
connect(ui->actionShow_xmr_to, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["XMRto"] = new ToggleTab(ui->tabXmrTo, "XMRto", "XMR.to", ui->actionShow_xmr_to, Config::showTabXMRto);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_xmr_to, "XMRto");
#else
ui->actionShow_xmr_to->setVisible(false);
#endif #endif
#if defined(HAS_XMRIG) #if defined(HAS_XMRIG)
connect(ui->actionShow_XMRig, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map)); connect(ui->actionShow_XMRig, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["Mining"] = new ToggleTab(ui->tabXmrRig, "Mining", "Mining", ui->actionShow_XMRig, Config::showTabXMRig); m_tabShowHideMapper["XMRig"] = new ToggleTab(ui->tabXmrRig, "XMRig", "XMRig", ui->actionShow_XMRig, Config::showTabXMRig);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "Mining"); m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "XMRig");
#else #else
ui->actionShow_XMRig->setVisible(false); ui->actionShow_XMRig->setVisible(false);
#endif #endif
@@ -430,16 +456,15 @@ void MainWindow::initMenu() {
connect(ui->actionPassword, &QAction::triggered, this, &MainWindow::showPasswordDialog); connect(ui->actionPassword, &QAction::triggered, this, &MainWindow::showPasswordDialog);
connect(ui->actionKeys, &QAction::triggered, this, &MainWindow::showKeysDialog); connect(ui->actionKeys, &QAction::triggered, this, &MainWindow::showKeysDialog);
connect(ui->actionViewOnly, &QAction::triggered, this, &MainWindow::showViewOnlyDialog); connect(ui->actionViewOnly, &QAction::triggered, this, &MainWindow::showViewOnlyDialog);
connect(ui->actionStore_wallet, &QAction::triggered, [this]{ connect(ui->actionStore_wallet, &QAction::triggered, [&]{
m_ctx->currentWallet->store(); m_ctx->currentWallet->store();
}); });
connect(ui->actionRefresh_tabs, &QAction::triggered, [this]{ connect(ui->actionRefresh_tabs, &QAction::triggered, [&]{
m_ctx->refreshModels(); m_ctx->refreshModels();
}); });
connect(ui->actionUpdate_balance, &QAction::triggered, [this]{ connect(ui->actionUpdate_balance, &QAction::triggered, [&]{
m_ctx->updateBalance(); m_ctx->updateBalance();
}); });
connect(ui->actionRescan_spent, &QAction::triggered, this, &MainWindow::rescanSpent);
connect(ui->actionExportKeyImages, &QAction::triggered, this, &MainWindow::exportKeyImages); connect(ui->actionExportKeyImages, &QAction::triggered, this, &MainWindow::exportKeyImages);
connect(ui->actionImportKeyImages, &QAction::triggered, this, &MainWindow::importKeyImages); connect(ui->actionImportKeyImages, &QAction::triggered, this, &MainWindow::importKeyImages);
connect(ui->actionExportOutputs, &QAction::triggered, this, &MainWindow::exportOutputs); connect(ui->actionExportOutputs, &QAction::triggered, this, &MainWindow::exportOutputs);
@@ -461,7 +486,7 @@ void MainWindow::initMenu() {
if(fn.isEmpty()) return; if(fn.isEmpty()) return;
if(!fn.endsWith(".csv")) fn += ".csv"; if(!fn.endsWith(".csv")) fn += ".csv";
m_ctx->currentWallet->history()->writeCSV(fn); m_ctx->currentWallet->history()->writeCSV(fn);
QMessageBox::information(this, "CSV export", QString("Transaction history exported to %1").arg(fn)); Utils::showMessageBox("CSV export", QString("Transaction history exported to %1").arg(fn), false);
}); });
// Contact widget // Contact widget
@@ -469,7 +494,7 @@ void MainWindow::initMenu() {
if(m_ctx->currentWallet == nullptr) return; if(m_ctx->currentWallet == nullptr) return;
auto *model = m_ctx->currentWallet->addressBookModel(); auto *model = m_ctx->currentWallet->addressBookModel();
if (model->rowCount() <= 0){ if (model->rowCount() <= 0){
QMessageBox::warning(this, "Error", "Addressbook empty"); Utils::showMessageBox("Error", "Addressbook empty", true);
return; return;
} }
@@ -479,7 +504,7 @@ void MainWindow::initMenu() {
qint64 now = QDateTime::currentDateTime().currentMSecsSinceEpoch(); qint64 now = QDateTime::currentDateTime().currentMSecsSinceEpoch();
QString fn = QString("%1/monero-contacts_%2.csv").arg(targetDir, QString::number(now / 1000)); QString fn = QString("%1/monero-contacts_%2.csv").arg(targetDir, QString::number(now / 1000));
if(model->writeCSV(fn)) if(model->writeCSV(fn))
QMessageBox::information(this, "Address book exported", QString("Address book exported to %1").arg(fn)); Utils::showMessageBox("Address book exported", QString("Address book exported to %1").arg(fn), false);
}); });
connect(ui->actionImportContactsCSV, &QAction::triggered, this, &MainWindow::importContacts); connect(ui->actionImportContactsCSV, &QAction::triggered, this, &MainWindow::importContacts);
@@ -497,8 +522,9 @@ void MainWindow::initMenu() {
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::menuAboutClicked); connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::menuAboutClicked);
connect(ui->actionDonate_to_Feather, &QAction::triggered, this, &MainWindow::donateButtonClicked); connect(ui->actionDonate_to_Feather, &QAction::triggered, this, &MainWindow::donateButtonClicked);
// Close wallet // Close / Open
connect(ui->actionClose, &QAction::triggered, this, &MainWindow::menuWalletCloseClicked); connect(ui->actionClose, &QAction::triggered, this, &MainWindow::menuWalletCloseClicked);
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::menuWalletOpenClicked);
} }
void MainWindow::menuToggleTabVisible(const QString &key){ void MainWindow::menuToggleTabVisible(const QString &key){
@@ -511,8 +537,15 @@ void MainWindow::menuToggleTabVisible(const QString &key){
} }
void MainWindow::initWidgets() { void MainWindow::initWidgets() {
int homeWidget = config()->get(Config::homeWidget).toInt(); auto homeWidget = config()->get(Config::homeWidget).toString();
ui->tabHomeWidget->setCurrentIndex(TabsHome(homeWidget)); if(homeWidget == QString("ccs")) {
m_ccsWidget->show();
} else if (homeWidget == "reddit") {
m_redditWidget->show();
} else {
config()->set(Config::homeWidget, "ccs");
m_ccsWidget->show();
}
} }
WalletWizard *MainWindow::createWizard(WalletWizard::Page startPage){ WalletWizard *MainWindow::createWizard(WalletWizard::Page startPage){
@@ -558,7 +591,7 @@ void MainWindow::touchbarShowWallet() {
} }
void MainWindow::onWalletCreatedError(const QString &err) { void MainWindow::onWalletCreatedError(const QString &err) {
QMessageBox::warning(this, "Wallet creation error", err); Utils::showMessageBox("Wallet creation error", err, true);
this->showWizard(WalletWizard::Page_CreateWallet); this->showWizard(WalletWizard::Page_CreateWallet);
} }
@@ -735,12 +768,12 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QStrin
err = QString("%1 %2").arg(err).arg(tx_err); err = QString("%1 %2").arg(err).arg(tx_err);
qDebug() << Q_FUNC_INFO << err; qDebug() << Q_FUNC_INFO << err;
QMessageBox::warning(this, "Transactions error", err); Utils::showMessageBox("Transaction error", err, true);
m_ctx->currentWallet->disposeTransaction(tx); m_ctx->currentWallet->disposeTransaction(tx);
} else if (tx->txCount() == 0) { } else if (tx->txCount() == 0) {
err = QString("%1 %2").arg(err).arg("No unmixable outputs to sweep."); err = QString("%1 %2").arg(err).arg("No unmixable outputs to sweep.");
qDebug() << Q_FUNC_INFO << err; qDebug() << Q_FUNC_INFO << err;
QMessageBox::warning(this, "Transaction error", err); Utils::showMessageBox("Transaction error", err, true);
m_ctx->currentWallet->disposeTransaction(tx); m_ctx->currentWallet->disposeTransaction(tx);
} else { } else {
const auto &description = m_ctx->tmpTxDescription; const auto &description = m_ctx->tmpTxDescription;
@@ -966,12 +999,12 @@ void MainWindow::menuWalletOpenClicked() {
QFileInfo infoPath(path); QFileInfo infoPath(path);
if(!infoPath.isReadable()) { if(!infoPath.isReadable()) {
QMessageBox::warning(this, "Cannot read wallet file", "Permission error."); Utils::showMessageBox("Cannot read wallet file", "Permission error.", true);
return; return;
} }
if(path == m_ctx->walletPath) { if(path == m_ctx->walletPath) {
QMessageBox::warning(this, "Wallet already opened", "Please open another wallet."); Utils::showMessageBox("Wallet already opened", "Please open another wallet.", true);
return; return;
} }
@@ -1013,6 +1046,16 @@ void MainWindow::skinChanged(const QString &skinName) {
qDebug() << QString("Skin changed to %1").arg(skinName); qDebug() << QString("Skin changed to %1").arg(skinName);
} }
void MainWindow::homeWidgetChanged(const QString &widgetName) {
if(widgetName == "ccs"){
m_ccsWidget->show();
m_redditWidget->hide();
} else if(widgetName == "reddit") {
m_ccsWidget->hide();
m_redditWidget->show();
}
}
void MainWindow::closeEvent(QCloseEvent *event) { void MainWindow::closeEvent(QCloseEvent *event) {
cleanupBeforeClose(); cleanupBeforeClose();
@@ -1020,11 +1063,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
} }
void MainWindow::donateButtonClicked() { void MainWindow::donateButtonClicked() {
double donation = AppContext::prices->convert("EUR", "XMR", m_ctx->donationAmount); double donation = AppContext::prices->convert("EUR", "XMR", m_ctx->featherDonationAmount);
if (donation <= 0) if(donation <= 0)
donation = 0.1337; donation = 1.337;
ui->sendWidget->fill(m_ctx->donationAddress, "Donation to the Feather development team", donation); ui->sendWidget->fill(m_ctx->featherDonationAddress, "Donation to the Feather development team", donation);
ui->tabWidget->setCurrentIndex(Tabs::SEND); ui->tabWidget->setCurrentIndex(Tabs::SEND);
} }
@@ -1049,21 +1092,7 @@ void MainWindow::showSendScreen(const CCSEntry &entry) {
void MainWindow::onViewOnBlockExplorer(const QString &txid) { void MainWindow::onViewOnBlockExplorer(const QString &txid) {
QString blockExplorerLink = Utils::blockExplorerLink(config()->get(Config::blockExplorer).toString(), m_ctx->networkType, txid); QString blockExplorerLink = Utils::blockExplorerLink(config()->get(Config::blockExplorer).toString(), m_ctx->networkType, txid);
Utils::externalLinkWarning(this, blockExplorerLink); Utils::externalLinkWarning(blockExplorerLink);
}
void MainWindow::onResendTransaction(const QString &txid) {
if (!AppContext::txCache.contains(txid)) {
QMessageBox::warning(this, "Unable to resend transaction", "Transaction was not found in transaction cache. Unable to resend.");
return;
}
// Connect to a different node so chances of successful relay are higher
m_ctx->nodes->autoConnect(true);
auto dialog = new BroadcastTxDialog(this, m_ctx, AppContext::txCache[txid]);
dialog->exec();
dialog->deleteLater();
} }
void MainWindow::onAddContact(const QString &address, const QString &name) { void MainWindow::onAddContact(const QString &address, const QString &name) {
@@ -1314,14 +1343,6 @@ void MainWindow::updateNetStats() {
m_statusLabelNetStats->setText(QString("(D: %1)").arg(Utils::formatBytes(m_ctx->currentWallet->getBytesReceived()))); m_statusLabelNetStats->setText(QString("(D: %1)").arg(Utils::formatBytes(m_ctx->currentWallet->getBytesReceived())));
} }
void MainWindow::rescanSpent() {
if (!m_ctx->currentWallet->rescanSpent()) {
QMessageBox::warning(this, "Rescan spent", m_ctx->currentWallet->errorString());
} else {
QMessageBox::information(this, "Rescan spent", "Successfully rescanned spent outputs.");
}
}
MainWindow::~MainWindow() { MainWindow::~MainWindow() {
delete ui; delete ui;
} }
+6 -8
View File
@@ -76,15 +76,11 @@ public:
RECEIVE, RECEIVE,
COINS, COINS,
CALC, CALC,
EXCHANGES, MORPHTOKEN,
XMR_TO,
XMRIG XMRIG
}; };
enum TabsHome {
CCS,
REDDIT
};
public slots: public slots:
void initWidgets(); void initWidgets();
void initMenu(); void initMenu();
@@ -106,6 +102,7 @@ public slots:
void showSendTab(); void showSendTab();
void showHistoryTab(); void showHistoryTab();
void showSendScreen(const CCSEntry &entry); void showSendScreen(const CCSEntry &entry);
void homeWidgetChanged(const QString &widgetName);
void skinChanged(const QString &skinName); void skinChanged(const QString &skinName);
void menuTorClicked(); void menuTorClicked();
void onBlockchainSync(int height, int target); void onBlockchainSync(int height, int target);
@@ -117,7 +114,6 @@ public slots:
void menuWalletOpenClicked(); void menuWalletOpenClicked();
void onWalletOpenPasswordRequired(bool invalidPassword, const QString &path); void onWalletOpenPasswordRequired(bool invalidPassword, const QString &path);
void onViewOnBlockExplorer(const QString &txid); void onViewOnBlockExplorer(const QString &txid);
void onResendTransaction(const QString &txid);
void onAddContact(const QString &address, const QString &name); void onAddContact(const QString &address, const QString &name);
void importContacts(); void importContacts();
void showRestoreHeightDialog(); void showRestoreHeightDialog();
@@ -168,7 +164,6 @@ private:
void touchbarShowWallet(); void touchbarShowWallet();
void updatePasswordIcon(); void updatePasswordIcon();
void updateNetStats(); void updateNetStats();
void rescanSpent();
WalletWizard *createWizard(WalletWizard::Page startPage); WalletWizard *createWizard(WalletWizard::Page startPage);
@@ -182,6 +177,9 @@ private:
bool m_windowSpawned = false; bool m_windowSpawned = false;
CCSWidget *m_ccsWidget = nullptr;
RedditWidget *m_redditWidget = nullptr;
QSystemTrayIcon *m_trayIcon; QSystemTrayIcon *m_trayIcon;
QMenu m_trayMenu; QMenu m_trayMenu;
QAction *m_trayActionCalc; QAction *m_trayActionCalc;
+68 -136
View File
@@ -87,65 +87,31 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="Line" name="line"> <widget class="Line" name="homeLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QTabWidget" name="tabHomeWidget"> <layout class="QHBoxLayout" name="coolLayout">
<property name="currentIndex"> <property name="spacing">
<number>0</number> <number>9</number>
</property> </property>
<property name="documentMode"> <item>
<bool>true</bool> <spacer name="verticalSpacer">
</property> <property name="orientation">
<widget class="QWidget" name="tab"> <enum>Qt::Vertical</enum>
<attribute name="title">
<string>CCS</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property> </property>
<property name="topMargin"> <property name="sizeHint" stdset="0">
<number>0</number> <size>
<width>0</width>
<height>40</height>
</size>
</property> </property>
<property name="rightMargin"> </spacer>
<number>0</number> </item>
</property> </layout>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="CCSWidget" name="ccsWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>/r/Monero</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="RedditWidget" name="redditWidget" native="true"/>
</item>
</layout>
</widget>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@@ -261,7 +227,7 @@
<widget class="QWidget" name="tabCalc"> <widget class="QWidget" name="tabCalc">
<attribute name="icon"> <attribute name="icon">
<iconset resource="assets.qrc"> <iconset resource="assets.qrc">
<normaloff>:/assets/images/gnome-calc.png</normaloff>:/assets/images/gnome-calc.png</iconset> <normaloff>:/assets/images/coldcard.png</normaloff>:/assets/images/coldcard.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
<string>Calc</string> <string>Calc</string>
@@ -272,15 +238,29 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabExchange"> <widget class="QWidget" name="tabMorphToken">
<attribute name="icon"> <attribute name="icon">
<iconset resource="assets.qrc"> <iconset resource="assets.qrc">
<normaloff>:/assets/images/update.png</normaloff>:/assets/images/update.png</iconset> <normaloff>:/assets/images/morphtoken.png</normaloff>:/assets/images/morphtoken.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
<string>Exchange</string> <string>MorphToken</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="MorphTokenWidget" name="morphtokenWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabXmrTo">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/xmrto.png</normaloff>:/assets/images/xmrto.png</iconset>
</attribute>
<attribute name="title">
<string>XMR.to</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@@ -291,76 +271,36 @@
<number>0</number> <number>0</number>
</property> </property>
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>1</number>
</property> </property>
<item> <item>
<widget class="QTabWidget" name="tabExchanges"> <widget class="XMRToWidget" name="xmrToWidget" native="true"/>
<property name="currentIndex"> </item>
<number>0</number> <item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property> </property>
<widget class="QWidget" name="tabXMRto"> <property name="sizeType">
<attribute name="icon"> <enum>QSizePolicy::Preferred</enum>
<iconset resource="assets.qrc"> </property>
<normaloff>:/assets/images/xmrto.png</normaloff>:/assets/images/xmrto.png</iconset> <property name="sizeHint" stdset="0">
</attribute> <size>
<attribute name="title"> <width>20</width>
<string>XMR.to</string> <height>0</height>
</attribute> </size>
<layout class="QVBoxLayout" name="verticalLayout_10"> </property>
<property name="leftMargin"> </spacer>
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="XMRToWidget" name="xmrToWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabMorphToken">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/morphtoken.png</normaloff>:/assets/images/morphtoken.png</iconset>
</attribute>
<attribute name="title">
<string>MorphToken</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="MorphTokenWidget" name="morphtokenWidget" native="true"/>
</item>
</layout>
</widget>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabXmrRig"> <widget class="QWidget" name="tabXmrRig">
<attribute name="icon"> <attribute name="icon">
<iconset resource="assets.qrc"> <iconset resource="assets.qrc">
<normaloff>:/assets/images/mining.png</normaloff>:/assets/images/mining.png</iconset> <normaloff>:/assets/images/xmrig.ico</normaloff>:/assets/images/xmrig.ico</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
<string>Mining</string> <string>XMRig</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0"> <item row="0" column="0">
@@ -386,6 +326,7 @@
<property name="title"> <property name="title">
<string>File</string> <string>File</string>
</property> </property>
<addaction name="actionOpen"/>
<addaction name="actionClose"/> <addaction name="actionClose"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
<addaction name="separator"/> <addaction name="separator"/>
@@ -429,7 +370,6 @@
<addaction name="actionStore_wallet"/> <addaction name="actionStore_wallet"/>
<addaction name="actionUpdate_balance"/> <addaction name="actionUpdate_balance"/>
<addaction name="actionRefresh_tabs"/> <addaction name="actionRefresh_tabs"/>
<addaction name="actionRescan_spent"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionChange_restore_height"/> <addaction name="actionChange_restore_height"/>
<addaction name="menuExport"/> <addaction name="menuExport"/>
@@ -491,7 +431,8 @@
</property> </property>
<addaction name="actionShow_Coins"/> <addaction name="actionShow_Coins"/>
<addaction name="actionShow_calc"/> <addaction name="actionShow_calc"/>
<addaction name="actionShow_Exchange"/> <addaction name="actionShow_MorphToken"/>
<addaction name="actionShow_xmr_to"/>
<addaction name="actionShow_XMRig"/> <addaction name="actionShow_XMRig"/>
</widget> </widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
@@ -500,6 +441,14 @@
<addaction name="menuTools"/> <addaction name="menuTools"/>
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
</widget> </widget>
<action name="actionOpen">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Open wallet</string>
</property>
</action>
<action name="actionQuit"> <action name="actionQuit">
<property name="text"> <property name="text">
<string>Quit application</string> <string>Quit application</string>
@@ -692,7 +641,7 @@
</action> </action>
<action name="actionShow_XMRig"> <action name="actionShow_XMRig">
<property name="text"> <property name="text">
<string>Show Mining</string> <string>Show XMRig</string>
</property> </property>
</action> </action>
<action name="actionImportTransaction"> <action name="actionImportTransaction">
@@ -730,14 +679,9 @@
<string>Import transaction</string> <string>Import transaction</string>
</property> </property>
</action> </action>
<action name="actionShow_Exchange"> <action name="actionShow_MorphToken">
<property name="text"> <property name="text">
<string>Show Exchange</string> <string>Show MorphToken</string>
</property>
</action>
<action name="actionRescan_spent">
<property name="text">
<string>Rescan spent</string>
</property> </property>
</action> </action>
</widget> </widget>
@@ -790,18 +734,6 @@
<header>MorphTokenWidget.h</header> <header>MorphTokenWidget.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>CCSWidget</class>
<extends>QWidget</extends>
<header>widgets/ccswidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RedditWidget</class>
<extends>QWidget</extends>
<header>widgets/redditwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="assets.qrc"/> <include location="assets.qrc"/>
+5
View File
@@ -180,7 +180,12 @@ QVariant CoinsModel::parseTransactionInfo(const CoinsInfo &cInfo, int column, in
case Address: case Address:
return ModelUtils::displayAddress(cInfo.address(), 1, ""); return ModelUtils::displayAddress(cInfo.address(), 1, "");
case AddressLabel: case AddressLabel:
{
if (cInfo.subaddrIndex() == 0) {
return cInfo.coinbase() ? "Coinbase" : "Change";
}
return cInfo.addressLabel(); return cInfo.addressLabel();
}
case Spent: case Spent:
return cInfo.spent(); return cInfo.spent();
case SpentHeight: case SpentHeight:
+9 -5
View File
@@ -55,13 +55,17 @@ void SendWidget::fill(double amount) {
ui->lineAmount->setText(QString::number(amount)); ui->lineAmount->setText(QString::number(amount));
} }
void SendWidget::fill(const QString &address, const QString &description, double amount) { void SendWidget::fill(const QString &address, const QString& description){
ui->lineDescription->setText(description); ui->lineDescription->setText(description);
ui->lineAddress->setText(address); ui->lineAddress->setText(address);
ui->lineAddress->setCursorPosition(0); ui->lineAddress->setCursorPosition(0);
if (amount > 0) }
ui->lineAmount->setText(QString::number(amount));
this->updateConversionLabel(); void SendWidget::fill(const QString &address, const QString &description, double amount) {
ui->lineDescription->setText(description);
ui->lineAmount->setText(QString::number(amount));
ui->lineAddress->setText(address);
ui->lineAddress->setCursorPosition(0);
} }
void SendWidget::fillAddress(const QString &address) { void SendWidget::fillAddress(const QString &address) {
@@ -70,7 +74,7 @@ void SendWidget::fillAddress(const QString &address) {
} }
void SendWidget::sendClicked() { void SendWidget::sendClicked() {
double amount; double amount = 0.0;
QString currency = ui->comboCurrencySelection->currentText(); QString currency = ui->comboCurrencySelection->currentText();
QString recipient = ui->lineAddress->text().simplified().remove(' '); QString recipient = ui->lineAddress->text().simplified().remove(' ');
QString description = ui->lineDescription->text(); QString description = ui->lineDescription->text();
+2 -1
View File
@@ -19,7 +19,8 @@ Q_OBJECT
public: public:
explicit SendWidget(QWidget *parent = nullptr); explicit SendWidget(QWidget *parent = nullptr);
void fill(const CCSEntry &entry); void fill(const CCSEntry &entry);
void fill(const QString &address, const QString& description, double amount = 0); void fill(const QString &address, const QString& description);
void fill(const QString &address, const QString& description, double amount);
void fill(double amount); void fill(double amount);
void clearFields(); void clearFields();
~SendWidget() override; ~SendWidget() override;
+11
View File
@@ -38,11 +38,16 @@ Settings::Settings(QWidget *parent) :
ui->checkBox_hideBalance->setChecked(config()->get(Config::hideBalance).toBool()); ui->checkBox_hideBalance->setChecked(config()->get(Config::hideBalance).toBool());
// setup comboboxes // setup comboboxes
auto settingsHomeWidget = config()->get(Config::homeWidget).toString();
if (m_homeWidgets.contains(settingsHomeWidget))
ui->comboBox_homeWidget->setCurrentIndex(m_homeWidgets.indexOf(settingsHomeWidget));
this->setupSkinCombobox(); this->setupSkinCombobox();
auto settingsSkin = config()->get(Config::skin).toString(); auto settingsSkin = config()->get(Config::skin).toString();
if (m_skins.contains(settingsSkin)) if (m_skins.contains(settingsSkin))
ui->comboBox_skin->setCurrentIndex(m_skins.indexOf(settingsSkin)); ui->comboBox_skin->setCurrentIndex(m_skins.indexOf(settingsSkin));
connect(ui->comboBox_homeWidget, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_homeWidgetChanged);
connect(ui->comboBox_skin, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_skinChanged); connect(ui->comboBox_skin, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_skinChanged);
connect(ui->comboBox_blockExplorer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_blockExplorerChanged); connect(ui->comboBox_blockExplorer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_blockExplorerChanged);
@@ -78,6 +83,12 @@ void Settings::comboBox_skinChanged(int pos) {
emit skinChanged(m_skins.at(pos)); emit skinChanged(m_skins.at(pos));
} }
void Settings::comboBox_homeWidgetChanged(int pos) {
config()->set(Config::homeWidget, m_homeWidgets.at(pos));
emit homeWidgetChanged(m_homeWidgets.at(pos));
}
void Settings::comboBox_blockExplorerChanged(int pos) { void Settings::comboBox_blockExplorerChanged(int pos) {
QString blockExplorer = ui->comboBox_blockExplorer->currentText(); QString blockExplorer = ui->comboBox_blockExplorer->currentText();
config()->set(Config::blockExplorer, blockExplorer); config()->set(Config::blockExplorer, blockExplorer);
+3
View File
@@ -26,6 +26,7 @@ public:
signals: signals:
void closed(); void closed();
void preferredFiatCurrencyChanged(QString currency); void preferredFiatCurrencyChanged(QString currency);
void homeWidgetChanged(QString widgetName);
void skinChanged(QString skinName); void skinChanged(QString skinName);
void showHomeCCS(bool); void showHomeCCS(bool);
void blockExplorerChanged(QString blockExplorer); void blockExplorerChanged(QString blockExplorer);
@@ -34,10 +35,12 @@ public slots:
void copyToClipboard(); void copyToClipboard();
void checkboxExternalLinkWarn(); void checkboxExternalLinkWarn();
void fiatCurrencySelected(int index); void fiatCurrencySelected(int index);
void comboBox_homeWidgetChanged(int pos);
void comboBox_skinChanged(int pos); void comboBox_skinChanged(int pos);
void comboBox_blockExplorerChanged(int post); void comboBox_blockExplorerChanged(int post);
private: private:
const QStringList m_homeWidgets{"ccs", "reddit"};
QStringList m_skins{"Native", "QDarkStyle", "Breeze/Dark", "Breeze/Light"}; QStringList m_skins{"Native", "QDarkStyle", "Breeze/Dark", "Breeze/Light"};
private: private:
+27 -6
View File
@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1019</width> <width>1019</width>
<height>336</height> <height>358</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -121,23 +121,44 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Home screen widget:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBox_homeWidget">
<item>
<property name="text">
<string>CCS proposals</string>
</property>
</item>
<item>
<property name="text">
<string>/r/monero</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Appearance:</string> <string>Appearance:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="comboBox_skin"/> <widget class="QComboBox" name="comboBox_skin"/>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Block explorer:</string> <string>Block explorer:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QComboBox" name="comboBox_blockExplorer"> <widget class="QComboBox" name="comboBox_blockExplorer">
<item> <item>
<property name="text"> <property name="text">
@@ -161,14 +182,14 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QCheckBox" name="checkBox_externalLink"> <widget class="QCheckBox" name="checkBox_externalLink">
<property name="text"> <property name="text">
<string>Warn before opening external link</string> <string>Warn before opening external link</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QCheckBox" name="checkBox_hideBalance"> <widget class="QCheckBox" name="checkBox_hideBalance">
<property name="text"> <property name="text">
<string>Hide balance</string> <string>Hide balance</string>
+2 -1
View File
@@ -41,7 +41,8 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::nodeSource,{QS("nodeSource"), 0}}, {Config::nodeSource,{QS("nodeSource"), 0}},
{Config::useOnionNodes,{QS("useOnionNodes"), false}}, {Config::useOnionNodes,{QS("useOnionNodes"), false}},
{Config::showTabCoins,{QS("showTabCoins"), false}}, {Config::showTabCoins,{QS("showTabCoins"), false}},
{Config::showTabExchange, {QS("showTabExchange"), true}}, {Config::showTabMorphToken, {QS("showTabMorphToken"), false}},
{Config::showTabXMRto,{QS("showTabXMRto"), true}},
{Config::showTabXMRig,{QS("showTabXMRig"), false}}, {Config::showTabXMRig,{QS("showTabXMRig"), false}},
{Config::showTabCalc,{QS("showTabCalc"), true}}, {Config::showTabCalc,{QS("showTabCalc"), true}},
{Config::geometry, {QS("geometry"), {}}}, {Config::geometry, {QS("geometry"), {}}},
+2 -1
View File
@@ -39,7 +39,8 @@ public:
nodeSource, nodeSource,
useOnionNodes, useOnionNodes,
showTabCoins, showTabCoins,
showTabExchange, showTabMorphToken,
showTabXMRto,
showTabCalc, showTabCalc,
showTabXMRig, showTabXMRig,
geometry, geometry,
+1 -1
View File
@@ -43,7 +43,7 @@ Tor::Tor(AppContext *ctx, QObject *parent)
return; return;
} }
#ifndef HAS_TOR_BIN #ifndef HAS_TOR
qCritical() << "Feather built without embedded Tor. Assuming --use-local-tor"; qCritical() << "Feather built without embedded Tor. Assuming --use-local-tor";
this->localTor = true; this->localTor = true;
return; return;
+22 -2
View File
@@ -276,7 +276,7 @@ bool Utils::testSocks5(const QString &host, quint16 port){
return false; return false;
} }
void Utils::externalLinkWarning(QWidget *parent, const QString &url){ void Utils::externalLinkWarning(const QString &url){
if(!config()->get(Config::warnOnExternalLink).toBool()) { if(!config()->get(Config::warnOnExternalLink).toBool()) {
QDesktopServices::openUrl(QUrl(url)); QDesktopServices::openUrl(QUrl(url));
return; return;
@@ -286,7 +286,7 @@ void Utils::externalLinkWarning(QWidget *parent, const QString &url){
body += QString("%1\n\n").arg(url); body += QString("%1\n\n").arg(url);
body += "You will NOT be using Tor."; body += "You will NOT be using Tor.";
switch (QMessageBox::warning(parent, "External link warning", body, QMessageBox::Cancel|QMessageBox::Ok)) { switch (Utils::showMessageBox("External link warning", body, true)) {
case QMessageBox::Cancel: case QMessageBox::Cancel:
break; break;
default: default:
@@ -327,6 +327,26 @@ bool Utils::walletExists(QString name, const QString &path) {
return Utils::fileExists(walletPath); return Utils::fileExists(walletPath);
} }
int Utils::showMessageBox(const QString &windowTitle, const QString &body, bool warning){
QMessageBox msgBox(QApplication::activeWindow());
msgBox.setWindowTitle(windowTitle);
msgBox.setText(body);
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
if(warning) {
QPixmap iconWarning = QPixmap(":/assets/images/ghost_icon.png");
msgBox.setIconPixmap(iconWarning);
}
else {
QPixmap iconInfo = QPixmap(":/assets/images/info.png")
.scaled(QSize(48,48), Qt::KeepAspectRatio, Qt::SmoothTransformation);
msgBox.setIconPixmap(iconInfo);
}
return msgBox.exec();
}
void Utils::copyToClipboard(const QString &string){ void Utils::copyToClipboard(const QString &string){
QClipboard * clipboard = QApplication::clipboard(); QClipboard * clipboard = QApplication::clipboard();
if (!clipboard) { if (!clipboard) {
+4 -1
View File
@@ -75,7 +75,8 @@ public:
static QStringList readJsonStringToQStringList(const QString &input); static QStringList readJsonStringToQStringList(const QString &input);
static void applicationLogHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); static void applicationLogHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static void openWindow(QWidget *w); static void openWindow(QWidget *w);
static void externalLinkWarning(QWidget *parent, const QString &url); static void externalLinkWarning(const QString &url);
static int showMessageBox(const QString &windowTitle, const QString &body, bool warning);
static QList<processStruct> procList(); static QList<processStruct> procList();
static bool dirExists(const QString &path); static bool dirExists(const QString &path);
static QString barrayToString(const QByteArray &data); static QString barrayToString(const QByteArray &data);
@@ -97,6 +98,8 @@ public:
static QString formatBytes(quint64 bytes); static QString formatBytes(quint64 bytes);
static QString amountToCurrencyString(double amount, const QString &currencyCode); static QString amountToCurrencyString(double amount, const QString &currencyCode);
static QStringList randomHTTPAgents;
template<typename QEnum> template<typename QEnum>
static QString QtEnumToString (const QEnum value) static QString QtEnumToString (const QEnum value)
{ {
+35
View File
@@ -9,13 +9,22 @@
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/xmrig.h" #include "utils/xmrig.h"
#include "appcontext.h" #include "appcontext.h"
XmRig::XmRig(const QString &configDir, QObject *parent) : QObject(parent) { XmRig::XmRig(const QString &configDir, QObject *parent) : QObject(parent) {
this->rigDir = QDir(configDir).filePath("xmrig"); this->rigDir = QDir(configDir).filePath("xmrig");
} }
void XmRig::prepare() { void XmRig::prepare() {
// unpack and set process signals
if(!this->unpackBins()) {
qCritical() << "failed to write XMRig to config directory";
return;
}
m_process.setProcessChannelMode(QProcess::MergedChannels); m_process.setProcessChannelMode(QProcess::MergedChannels);
connect(&m_process, &QProcess::readyReadStandardOutput, this, &XmRig::handleProcessOutput); connect(&m_process, &QProcess::readyReadStandardOutput, this, &XmRig::handleProcessOutput);
connect(&m_process, &QProcess::errorOccurred, this, &XmRig::handleProcessError); connect(&m_process, &QProcess::errorOccurred, this, &XmRig::handleProcessError);
@@ -101,3 +110,29 @@ void XmRig::handleProcessError(QProcess::ProcessError err) {
emit error(QString("XMRig binary failed to start: %1").arg(path)); emit error(QString("XMRig binary failed to start: %1").arg(path));
} }
} }
bool XmRig::unpackBins() {
QString rigFile;
rigFile = ":/assets/exec/xmrig";
if (!Utils::fileExists(rigFile))
return false;
// write to disk
QFile f(rigFile);
QFileInfo fileInfo(f);
this->rigPath = QDir(this->rigDir).filePath(fileInfo.fileName());
#if defined(Q_OS_WIN)
if(!this->rigPath.endsWith(".exe"))
this->rigPath += ".exe";
#endif
qDebug() << "Writing XMRig executable to " << this->rigPath;
f.copy(rigPath);
f.close();
#if defined(Q_OS_UNIX)
QFile rigBin(this->rigPath);
rigBin.setPermissions(QFile::ExeGroup | QFile::ExeOther | QFile::ExeOther | QFile::ExeUser);
#endif
return true;
}
+1 -1
View File
@@ -42,7 +42,7 @@ void CCSWidget::linkClicked() {
auto entry = m_model->entry(index.row()); auto entry = m_model->entry(index.row());
if (entry) if (entry)
Utils::externalLinkWarning(this, entry->url); Utils::externalLinkWarning(entry->url);
} }
void CCSWidget::donateClicked() { void CCSWidget::donateClicked() {
+33
View File
@@ -48,6 +48,39 @@
</attribute> </attribute>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="warnLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Powered by ccs.getmonero.org</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
+2 -2
View File
@@ -113,14 +113,14 @@ void NodeWidget::onContextWSStatusURL() {
QModelIndex index = ui->wsView->currentIndex(); QModelIndex index = ui->wsView->currentIndex();
if (!index.isValid()) return; if (!index.isValid()) return;
FeatherNode node = m_wsModel->node(index.row()); FeatherNode node = m_wsModel->node(index.row());
Utils::externalLinkWarning(this, node.as_url()); Utils::externalLinkWarning(node.as_url());
} }
void NodeWidget::onContextCustomStatusURL() { void NodeWidget::onContextCustomStatusURL() {
QModelIndex index = ui->customView->currentIndex(); QModelIndex index = ui->customView->currentIndex();
if (!index.isValid()) return; if (!index.isValid()) return;
FeatherNode node = m_customModel->node(index.row()); FeatherNode node = m_customModel->node(index.row());
Utils::externalLinkWarning(this, node.as_url()); Utils::externalLinkWarning(node.as_url());
} }
void NodeWidget::onContextDisconnect() { void NodeWidget::onContextDisconnect() {
+1 -1
View File
@@ -37,7 +37,7 @@ void RedditWidget::linkClicked() {
auto post = m_model->post(index.row()); auto post = m_model->post(index.row());
if (post) { if (post) {
Utils::externalLinkWarning(this, post->url); Utils::externalLinkWarning(post->url);
} }
} }
+30
View File
@@ -51,6 +51,36 @@
</attribute> </attribute>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Powered by Reddit</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
+7 -6
View File
@@ -8,12 +8,11 @@
#include "utils/config.h" #include "utils/config.h"
#include "mainwindow.h" #include "mainwindow.h"
TickerWidget::TickerWidget(QWidget *parent, QString symbol, QString title, bool convertBalance, bool hidePercent) : TickerWidget::TickerWidget(QWidget *parent, QString symbol, QString title, bool convertBalance) :
QWidget(parent), QWidget(parent),
ui(new Ui::TickerWidget), ui(new Ui::TickerWidget),
m_symbol(std::move(symbol)), m_symbol(std::move(symbol)),
m_convertBalance(convertBalance), m_convertBalance(convertBalance)
m_hidePercent(hidePercent)
{ {
ui->setupUi(this); ui->setupUi(this);
m_ctx = MainWindow::getContext(); m_ctx = MainWindow::getContext();
@@ -28,8 +27,6 @@ TickerWidget::TickerWidget(QWidget *parent, QString symbol, QString title, bool
this->setPctText(defaultPct, true); this->setPctText(defaultPct, true);
this->setFiatText(defaultFiat, 0.0); this->setFiatText(defaultFiat, 0.0);
ui->tickerPct->setHidden(hidePercent);
connect(AppContext::prices, &Prices::fiatPricesUpdated, this, &TickerWidget::init); connect(AppContext::prices, &Prices::fiatPricesUpdated, this, &TickerWidget::init);
connect(AppContext::prices, &Prices::cryptoPricesUpdated, this, &TickerWidget::init); connect(AppContext::prices, &Prices::cryptoPricesUpdated, this, &TickerWidget::init);
if (convertBalance) if (convertBalance)
@@ -50,7 +47,7 @@ void TickerWidget::init() {
double amount = m_convertBalance ? AppContext::balance : 1.0; double amount = m_convertBalance ? AppContext::balance : 1.0;
double conversion = AppContext::prices->convert(m_symbol, fiatCurrency, amount); double conversion = AppContext::prices->convert(m_symbol, fiatCurrency, amount);
if (conversion < 0) return; if (conversion < 0) return;
ui->tickerPct->setHidden(conversion == 0 || m_hidePercent); setPercentHidden(conversion == 0);
auto markets = AppContext::prices->markets; auto markets = AppContext::prices->markets;
if(!markets.contains(m_symbol)) return; if(!markets.contains(m_symbol)) return;
@@ -88,6 +85,10 @@ void TickerWidget::removePctContainer() {
ui->tickerPct->deleteLater(); ui->tickerPct->deleteLater();
} }
void TickerWidget::setPercentHidden(bool hidden) {
ui->tickerPct->setVisible(!hidden);
}
TickerWidget::~TickerWidget() { TickerWidget::~TickerWidget() {
delete ui; delete ui;
} }
+3 -2
View File
@@ -17,7 +17,7 @@ class TickerWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit TickerWidget(QWidget *parent, QString symbol, QString title = "", bool convertBalance = false, bool hidePercent = false); explicit TickerWidget(QWidget *parent, QString symbol, QString title = "", bool convertBalance = false);
void removePctContainer(); void removePctContainer();
void setFiatText(QString &fiatCurrency, double amount); void setFiatText(QString &fiatCurrency, double amount);
void setPctText(QString &text, bool positive); void setPctText(QString &text, bool positive);
@@ -29,10 +29,11 @@ public slots:
void init(); void init();
private: private:
void setPercentHidden(bool hidden);
Ui::TickerWidget *ui; Ui::TickerWidget *ui;
QString m_symbol; QString m_symbol;
bool m_convertBalance; bool m_convertBalance;
bool m_hidePercent;
AppContext *m_ctx; AppContext *m_ctx;
}; };
+25 -6
View File
@@ -36,7 +36,7 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
// threads // threads
ui->threadSlider->setMinimum(1); ui->threadSlider->setMinimum(1);
int threads = QThread::idealThreadCount(); int threads = QThread::idealThreadCount();
m_threads = threads / 2; m_threads = (unsigned int) threads / 2;
ui->threadSlider->setMaximum(threads); ui->threadSlider->setMaximum(threads);
ui->threadSlider->setValue(m_threads); ui->threadSlider->setValue(m_threads);
ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads)); ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads));
@@ -55,12 +55,15 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
ui->check_tls->setChecked(true); ui->check_tls->setChecked(true);
ui->label_status->setTextInteractionFlags(Qt::TextSelectableByMouse); ui->label_status->setTextInteractionFlags(Qt::TextSelectableByMouse);
ui->label_status->hide(); ui->label_status->hide();
ui->pathFrame->hide();
ui->soloFrame->hide(); ui->soloFrame->hide();
ui->poolFrame->hide(); ui->poolFrame->hide();
// XMRig binary // XMRig binary
auto path = config()->get(Config::xmrigPath).toString(); auto path = config()->get(Config::xmrigPath).toString();
if(!path.isEmpty()) { if(!path.isEmpty()) {
ui->pathFrame->show();
ui->check_custompath->setChecked(true);
ui->lineEdit_path->setText(path); ui->lineEdit_path->setText(path);
} }
@@ -96,6 +99,7 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
}); });
// checkbox connects // checkbox connects
connect(ui->check_custompath, &QCheckBox::stateChanged, this, &XMRigWidget::onCustomPathChecked);
connect(ui->check_solo, &QCheckBox::stateChanged, this, &XMRigWidget::onSoloChecked); connect(ui->check_solo, &QCheckBox::stateChanged, this, &XMRigWidget::onSoloChecked);
} }
@@ -123,7 +127,7 @@ void XMRigWidget::onWalletOpened(){
} }
void XMRigWidget::onThreadsValueChanged(int threads) { void XMRigWidget::onThreadsValueChanged(int threads) {
m_threads = threads; m_threads = (unsigned int) threads;
ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads)); ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads));
} }
@@ -146,7 +150,12 @@ void XMRigWidget::onClearClicked() {
void XMRigWidget::onStartClicked() { void XMRigWidget::onStartClicked() {
QString xmrigPath; QString xmrigPath;
bool solo = ui->check_solo->isChecked(); bool solo = ui->check_solo->isChecked();
xmrigPath = config()->get(Config::xmrigPath).toString(); bool customBinary = ui->check_custompath->isChecked();
if(customBinary)
xmrigPath = config()->get(Config::xmrigPath).toString();
else
xmrigPath = m_ctx->XMRig->rigPath;
// username is receiving address usually // username is receiving address usually
auto username = m_ctx->currentWallet->getCacheAttribute("feather.xmrig_username"); auto username = m_ctx->currentWallet->getCacheAttribute("feather.xmrig_username");
@@ -155,7 +164,7 @@ void XMRigWidget::onStartClicked() {
if(username.isEmpty()) { if(username.isEmpty()) {
QString err = "Please specify a receiving address on the Settings screen"; QString err = "Please specify a receiving address on the Settings screen";
ui->console->appendPlainText(err); ui->console->appendPlainText(err);
QMessageBox::warning(this, "Error", err); Utils::showMessageBox("Error", err, true);
return; return;
} }
@@ -236,7 +245,7 @@ void XMRigWidget::onDownloads(const QJsonObject &data) {
os_assets = const_cast<QJsonArray *>(&_linux); os_assets = const_cast<QJsonArray *>(&_linux);
} }
int i = 0; unsigned int i = 0;
for(const auto &entry: *os_assets) { for(const auto &entry: *os_assets) {
auto _obj = entry.toObject(); auto _obj = entry.toObject();
auto _name = _obj.value("name").toString(); auto _name = _obj.value("name").toString();
@@ -271,6 +280,16 @@ void XMRigWidget::showContextMenu(const QPoint &pos) {
m_contextMenu->exec(ui->tableView->viewport()->mapToGlobal(pos)); m_contextMenu->exec(ui->tableView->viewport()->mapToGlobal(pos));
} }
void XMRigWidget::onCustomPathChecked(int state) {
if(state == 2) {
ui->pathFrame->show();
} else {
ui->lineEdit_path->setText("");
config()->set(Config::xmrigPath, "");
ui->pathFrame->hide();
}
}
void XMRigWidget::onSoloChecked(int state) { void XMRigWidget::onSoloChecked(int state) {
if(state == 2) { if(state == 2) {
ui->poolFrame->hide(); ui->poolFrame->hide();
@@ -286,7 +305,7 @@ void XMRigWidget::onSoloChecked(int state) {
void XMRigWidget::linkClicked() { void XMRigWidget::linkClicked() {
QModelIndex index = ui->tableView->currentIndex(); QModelIndex index = ui->tableView->currentIndex();
auto download_link = m_urls.at(index.row()); auto download_link = m_urls.at(index.row());
Utils::externalLinkWarning(this, download_link); Utils::externalLinkWarning(download_link);
} }
QStandardItemModel *XMRigWidget::model() { QStandardItemModel *XMRigWidget::model() {
+3 -2
View File
@@ -22,7 +22,7 @@ class XMRigWidget : public QWidget
public: public:
explicit XMRigWidget(AppContext *ctx, QWidget *parent = nullptr); explicit XMRigWidget(AppContext *ctx, QWidget *parent = nullptr);
~XMRigWidget() override; ~XMRigWidget();
QStandardItemModel *model(); QStandardItemModel *model();
public slots: public slots:
@@ -36,6 +36,7 @@ public slots:
void onProcessError(const QString &msg); void onProcessError(const QString &msg);
void onProcessOutput(const QByteArray &msg); void onProcessOutput(const QByteArray &msg);
void onHashrate(const QString &hashrate); void onHashrate(const QString &hashrate);
void onCustomPathChecked(int state);
void onSoloChecked(int state); void onSoloChecked(int state);
private slots: private slots:
@@ -54,7 +55,7 @@ private:
Ui::XMRigWidget *ui; Ui::XMRigWidget *ui;
QStandardItemModel *m_model; QStandardItemModel *m_model;
QMenu *m_contextMenu; QMenu *m_contextMenu;
int m_threads; unsigned int m_threads;
QStringList m_urls; QStringList m_urls;
QStringList m_pools{"pool.xmr.pt:9000", "pool.supportxmr.com:9000", "mine.xmrpool.net:443", "xmrpool.eu:9999", "xmr-eu1.nanopool.org:14433", "pool.minexmr.com:6666", "us-west.minexmr.com:6666", "monerohash.com:9999", "cryptonote.social:5555", "cryptonote.social:5556"}; QStringList m_pools{"pool.xmr.pt:9000", "pool.supportxmr.com:9000", "mine.xmrpool.net:443", "xmrpool.eu:9999", "xmr-eu1.nanopool.org:14433", "pool.minexmr.com:6666", "us-west.minexmr.com:6666", "monerohash.com:9999", "cryptonote.social:5555", "cryptonote.social:5556"};
}; };
+157 -90
View File
@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1329</width> <width>800</width>
<height>540</height> <height>556</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -161,7 +161,38 @@
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>0</width> <width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QCheckBox" name="check_solo">
<property name="text">
<string>Solo mine</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_custompath">
<property name="text">
<string>Custom XMRig executable</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height> <height>20</height>
</size> </size>
</property> </property>
@@ -190,47 +221,27 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="lineEdit_path">
<property name="placeholderText">
<string>/path/to/xmrig</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_browse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="check_tls">
<property name="text">
<string>TLS</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="relayTor">
<property name="text">
<string>Tor</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_solo">
<property name="text">
<string>Solo mine</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_12"> <layout class="QHBoxLayout" name="horizontalLayout_12">
<item> <item>
@@ -256,15 +267,15 @@
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Pool</string>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Pool</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QComboBox" name="combo_pools"> <widget class="QComboBox" name="combo_pools">
<property name="sizePolicy"> <property name="sizePolicy">
@@ -318,15 +329,15 @@
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Node address</string>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_8"> <layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Node address</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QLineEdit" name="lineEdit_solo"> <widget class="QLineEdit" name="lineEdit_solo">
<property name="text"> <property name="text">
@@ -357,51 +368,77 @@
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QFormLayout" name="formLayout"> <widget class="QLabel" name="label_2">
<item row="0" column="0"> <property name="text">
<widget class="QLabel" name="label_2"> <string>Receiving address</string>
<property name="text"> </property>
<string>Receiving address</string> </widget>
</property> </item>
</widget> <item>
</item> <widget class="QLineEdit" name="lineEdit_address"/>
<item row="0" column="1"> </item>
<widget class="QLineEdit" name="lineEdit_address"/> <item>
</item> <layout class="QVBoxLayout" name="verticalLayout_7">
<item row="1" column="0"> <item>
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Password (optional)</string> <string>Password (optional)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item>
<widget class="QLineEdit" name="lineEdit_password"/> <layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLineEdit" name="lineEdit_password"/>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>60</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item row="2" column="0"> </layout>
<widget class="QLabel" name="label"> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QCheckBox" name="check_tls">
<property name="text"> <property name="text">
<string>XMRig executable</string> <string>TLS</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <widget class="QCheckBox" name="relayTor">
<item> <property name="text">
<widget class="QLineEdit" name="lineEdit_path"> <string>Tor</string>
<property name="placeholderText"> </property>
<string>/path/to/xmrig</string> </widget>
</property> </item>
</widget> <item>
</item> <spacer name="horizontalSpacer_9">
<item> <property name="orientation">
<widget class="QPushButton" name="btn_browse"> <enum>Qt::Horizontal</enum>
<property name="text"> </property>
<string>Browse</string> <property name="sizeHint" stdset="0">
</property> <size>
</widget> <width>40</width>
</item> <height>20</height>
</layout> </size>
</property>
</spacer>
</item> </item>
</layout> </layout>
</item> </item>
@@ -457,7 +494,7 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>0</height> <height>2000</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@@ -515,6 +552,36 @@
</attribute> </attribute>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Powered by Github API v3</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>
+1 -1
View File
@@ -74,7 +74,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>by dsc &amp; tobtoht</string> <string>by dsc &amp; thotbot</string>
</property> </property>
</widget> </widget>
</item> </item>
+2 -3
View File
@@ -8,7 +8,6 @@
#include <QPushButton> #include <QPushButton>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox>
// @TODO: rescan wallet dir on wizard open // @TODO: rescan wallet dir on wizard open
@@ -28,7 +27,7 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, QWidget *parent) :
QFileInfo infoPath(path); QFileInfo infoPath(path);
if(!infoPath.isReadable()) { if(!infoPath.isReadable()) {
QMessageBox::warning(this, "Cannot read wallet file", "Permission error."); Utils::showMessageBox("Cannot read wallet file", "Permission error.", true);
return; return;
} }
@@ -68,7 +67,7 @@ int OpenWalletPage::nextId() const {
bool OpenWalletPage::validatePage() { bool OpenWalletPage::validatePage() {
QModelIndex index = ui->walletTable->currentIndex(); QModelIndex index = ui->walletTable->currentIndex();
if(!index.isValid()) { if(!index.isValid()) {
QMessageBox::warning(this, "Wallet not selected", "Please select a wallet from the list."); Utils::showMessageBox("Wallet not selected", "Please select a wallet from the list.", true);
return false; return false;
} }
QString walletPath = index.model()->data(index.siblingAtColumn(WalletKeysFilesModel::ModelColumns::Path), Qt::UserRole).toString(); QString walletPath = index.model()->data(index.siblingAtColumn(WalletKeysFilesModel::ModelColumns::Path), Qt::UserRole).toString();
+2 -2
View File
@@ -86,7 +86,7 @@ void XMRToWidget::onCreateOrder() {
auto amount = ui->lineAmount->text(); auto amount = ui->lineAmount->text();
if(amount.isEmpty()) { if(amount.isEmpty()) {
QMessageBox::warning(this, "Cannot create XMR.To order", "Invalid amount"); Utils::showMessageBox("Cannot create XMR.To order", "Invalid amount", false);
return; return;
} }
@@ -99,7 +99,7 @@ void XMRToWidget::onCreateOrder() {
auto available = m_unlockedBalance; auto available = m_unlockedBalance;
if(amount_xmr > available){ if(amount_xmr > available){
QMessageBox::warning(this, "Cannot create XMR.To order", "Not enough Monero to create order."); Utils::showMessageBox("Cannot create XMR.To order", "Not enough Monero to create order.", false);
return; return;
} }
+1 -1
View File
@@ -14,7 +14,7 @@ git submodule update --init --depth 120 monero
git submodule update --init --depth 120 --recursive monero git submodule update --init --depth 120 --recursive monero
cp "/Users/administrator/tor/libevent-2.1.7.dylib" "/Users/administrator/feather/src/assets/exec/libevent-2.1.7.dylib" cp "/Users/administrator/tor/libevent-2.1.7.dylib" "/Users/administrator/feather/src/assets/exec/libevent-2.1.7.dylib"
CMAKE_PREFIX_PATH="~/Qt/5.15.1/clang_64" TOR_BIN="/Users/administrator/tor/tor" make -j3 mac-release CMAKE_PREFIX_PATH="~/Qt/5.15.1/clang_64" TOR="/Users/administrator/tor/tor" XMRIG="/Users/administrator/xmrig/xmrig" make -j3 mac-release
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo "[+] Feather built OK" echo "[+] Feather built OK"
-52
View File
@@ -1,52 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
Ig==
=2rq8
-----END PGP PUBLIC KEY BLOCK-----
+64
View File
@@ -0,0 +1,64 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBF0bjnMBEADVgQr04Lg258KpWi42rzGemFGkzHCx7SXDWVqHApx34HUxF63s
RnknCTt42Thqcv78CJ9WQYjjvT5+FZOlxA+0kwkeatFoKNeVvBkyYFgU6gxSuVQ+
a1ZEw2IYdqRH+vUC1AKGY88KlrteTAqtqYsaGimiF5ry3y3bLBySyxLHfltCaENy
uKPJEHHvHxTZsZAD3iwVysNZkw2V/V4IS8wy8m9rq1U7OU40KMJ3EUan89DzD1qt
8sroEThsjE9IG6QMf1H9pvNIIz/QhwqSKQkGqt8obdf0W+EB4cef6ka98a+E6slc
Otw2AVB2B47ljnp5AyLwZPiYxeIXPZsO8cZbx1uBOkOZ1OkqHlk4tgJEqg+v6APO
cm625fk4iftsB+U/3MZvm4QH4Y5xfAFb3aDL2zkxN/EUCWW5tUn+Z+RaegGaojTE
N2laH91ncpeZh1M9GPvXGT/efDg3a/Nv9UNUtv9lhNn35VyVgBNaaYwNScq5+ApV
pG8b/j18x8mQR8kk7bXvOXjc/4NdCrY7QcIExA9DTWemLsDVeDM62lBvOKZGED4X
fgGehGGPtu862kf4vvCZKrrEeVkVBrTiOsxFMdHshnKqtQyyJQKXXVjl9//jhMGM
cZHJ5+D9O4JNE/aZC4h2F7hL0NpO0AVGJ0Ly5N7B07yMBZGGJaH4QXCoHwARAQAB
tEVLaXR3YXJlIEFwdCBBcmNoaXZlIEF1dG9tYXRpYyBTaWduaW5nIEtleSAoMjAy
MCkgPGRlYmlhbkBraXR3YXJlLmNvbT6JAlQEEwEKAD4WIQRtkDmVQkqDpI1C1T2o
5e86AmACaAUCXRuOcwIbAwUJBaOagAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAK
CRCo5e86AmACaLJ9D/9ly840Ko3F0HgIAAxAeWE7BzQOD09BbnL/is6F0lquXd/W
fZXUbVhONv7Q3FK9IDwzKoYHmRrwo6IpDIsy7AqiHHkWWxCdpIzVWQfE7rFg4UWa
2bNXoFBGRImYmQHaG/02EJiNnTDnsYgN7y9zzAAvz63dnSsm6GOUp9pkIoxHnt9D
WxMlM05GgVRjSeNvi4OLuPE6jHhHvAGGrMS8g9oU6TtCj9WVNryFpROchdmTteS4
P16FP4n5NczXjYXFch3S+cOfijHnsfuFzB4JanrZ+JlBd21BDfhO/VLFx8+Ljdj0
axKpwa86oHc5ALnMHPnGM2EVN+NNS88PDBngvJEpRUkECpEy4cwZ3zjCJ0jMeiRv
cFf/FjZBFeqrAapwWNFjIH0El7dJq+XYDKuA0kakMDo6GZlfTNDRobGj9vR/HA0j
/a7VD9tfW2dLr61qsQwynn6S+9B4XY/fYwc4AyYCp+FNm4ONFFjQ6ytCgdLdBEWK
X+xCMifTqDx9nm/1u/95ZqwcayAqwhKDb01hQhSTlozybz8B4trfeHJdXYoH7/s4
TLnt5R68bc2Fm0ikk4tndSTH4SUtnEeIv+nap5RkCmHI6URJ4P4kFT3C30Ooeafv
GOa18HYxhb/qnU2DvWXL1rnKoKB51p2nhrkjliDPSfMMIf6AgyZSZR4BpMoz47kC
DQRdG49RARAAyX+HK4Xh0RiiqPd0DDbgHV+8UvY1gihObyK/cqpRQzewSKEw/jwM
abwav3oqisI7IFp4FmupqhSi7uqB54eUF44LHeGZiUedZm5pAreX2ygQASr2It3g
kWr58J0ZOas6cRqUzga1mCL1eljfff9T9+1syIWiUWTjXDzEwsMgksHIn9ZGaxM0
zvkbXfTCmlzmCbvBwokHRrw9cvmXZIKaGdvAEg/S9asmkRBeA/0GgX2Tlr1H6mv5
0ZYF25t0n2IYiVuvXTOrz9OCuWxv0NQiweMFTi62sN6myjB4PC499ySTQkIhWVsf
2oa5+rvcCg6j3jpUFy4MoDA9cXl47/0ccpim+mwJo4uY4ysIsDq7mKqjN7honj45
zosvs7yd2UXrKWKay+P1e1vdsSOVP8PSSJCJV8HvdKCRfcYYdlTq3PSeloVrWC/4
PCKlnp16AzPzL+CBWtj5ruhAFTaoKveEjUnQD5IiKD4hvt9nnX6C9RT2yhKDHnoi
uup+nXOEn78UWxmoPJKu5wE1c5ZZhw81bYByEkLjHt5Bl+FS8CJN3G+56kVuBc9v
Kqa90EThcLr6bIEx3LU3mK3FBxBCh+7xEPYI4Cx/NGyrszirRkzIIM6wIxc983l5
+BtdKn14b2yDhfw2wOBsxo4aLWhGzqJGQAxuUo4sdNbElT5mpwpDxJEAEQEAAYkE
cgQYAQoAJhYhBG2QOZVCSoOkjULVPajl7zoCYAJoBQJdG49RAhsCBQkFo5qAAkAJ
EKjl7zoCYAJowXQgBBkBCgAdFiEEWbJ5MHJjJForbwaGKR+f9v04V4MFAl0bj1EA
CgkQKR+f9v04V4Mz9Q/9E0KmNCJC95HfP46enwASVnBZ7ntlHvtqQgNVZ8r0W69v
qg+FdsKK2109lR3RvRe5TAwHi4ryFW6YazmvH4k7Bd1pGxAtc5VSuehgs8lPGObo
SKI8S9EH+v3G4IAm25vaRDtnVdDpcfn5A6RrSDyTTDjdhyTp9w/f62SfMryf/0fv
yg5HS5JQSHBJdxN6mnRDqM66Ey4plfFbt4yKJIPnj5xsa19wx72Zw8hED1O6FZAV
URQ8ffE521R9wzQAfX3746pdEQ+S21Ht0lEsNjmU/HDq0WeOBElIN6S09XQyL0zG
0HrOZkByI5683v+cp6clJKxnBX7hsR0+4AxQK0+eNJEtLwLPcwObBi2ACeUG49cA
ms+BaSAvjbyCW4M7ye42zdEFbWS9hfK6T5Ry85Pv6IxgpUHAX7kvtqHxguDobuUZ
4CmSdRyBCEAN7dgjWrqrtmq7cF3Kwz5kLwzB0AeQTArLoYlBSlcx/eT/jDLZdFjQ
Ol6uqVdv63BADNriYExz++g4A02LzAfk+C0J/7syKeEs5nonIFwTfrS7VJbcs7Cn
8HkuCPuH9u1nYSJV8U7xYNCbRK3JNBr20IlO+TXAuf7M3z5IuZjED7EtG0kMyl41
vbBYCFbKMpEEjFAUUO5CsbyL4IoYJRptJij10RsDI9jRY+YfOQ+WxP4txPDv1Eei
eBAAs2PDWG7MvubB1wE3QcRUEQqvDbEIdvRfz9YIOXfGlaDfiuhBpcxsgsDG/IjQ
3c0PnJqpLpivfOMMyfynwPRW4ZiwIUSrOYJ6xhOt3zUzqf/GfIB39pCz3AI0EBxp
uicL4PJ4OeA0V3XT+IEcjbqBaVz5UCS/sVuYTykxwk8BPYaJOFlHtp4kEtn43kpL
kQHPMQCC1+skI85d0YG7Yn1w5qSqtwYJBPFU2OWpyLHtxL55S8dAWmvlkKmA1I6W
WyOPM/Y5WWdG8BUphXmv67wdeVdxp4s5V8oXKy3QQ0FA5Wt/z6l7Ei8tXcOIgDYw
nYgTgjOprZPXOY+L+6gED3YVWUvAJ6xhdYVsJazu3Ulwr4dwkHrBd1qXe7NGA3Ib
7VAkzkPzRtdPJ+OT/YX0vfh3a4VvYepoTAHIf0J6Uo2vcqBFA/Ztiby3bM4T4C30
c5AqQkLDZ/2UbBW9Yu4f9oiw7/gDdNI7C8xHaQNLFzzRzhjnEpjwBhlpeballXoU
6ShFo6T0CzZ1N46iumJ5nTor40dY2EcX+dXxGCJ2ihifIeHrbx6fKFOB9VLV3VpW
SzLJTT9ARIgvqVg5lhTFiKRiZNp5MAu9NFw5wgyCJxUjASLOWshMwkhKHHe13AZD
2Hxmkp7Qwjg6kihr/j03NQIBhOK+M068Urew/dbndYwIzsI=
=0GnF
-----END PGP PUBLIC KEY BLOCK-----