From 4212040f0b601c85640a6c955cbfb0cd6d10971e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:28:28 +0000 Subject: [PATCH 01/28] chore(deps): update external/libzmq digest to b95d949 --- external/libzmq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libzmq b/external/libzmq index 59c91227..b95d9493 160000 --- a/external/libzmq +++ b/external/libzmq @@ -1 +1 @@ -Subproject commit 59c91227b46b60b7f965816544b25fe0a3cc8bbe +Subproject commit b95d94935ed107679fd0ad9efd2f3d47309b6fd3 From 8102efa72b720c92f1b3b6f3771394d1003c3d11 Mon Sep 17 00:00:00 2001 From: cyan Date: Fri, 2 Aug 2024 18:04:56 +0200 Subject: [PATCH 02/28] add action to check for invalid dependencies (#28) * add action to check for invalid dependencies * downgrate polyseed to v2.0.0 --- .github/workflows/dependencies_matches.yaml | 74 +++++++++++++++++++++ external/polyseed | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/dependencies_matches.yaml diff --git a/.github/workflows/dependencies_matches.yaml b/.github/workflows/dependencies_matches.yaml new file mode 100644 index 00000000..5552539b --- /dev/null +++ b/.github/workflows/dependencies_matches.yaml @@ -0,0 +1,74 @@ +name: Check if dependencies match +# Sometimes we have the libraries in two (or more) places +# at the same time, this check makes sure that we do use +# the same version of said libraries. +on: [push] + +jobs: + wownero-seed: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + - name: Patch sources + run: | + git config --global --add safe.directory '*' + git config --global user.email "ci@mrcyjanek.net" + git config --global user.name "CI mrcyjanek.net" + ./apply_patches.sh monero + ./apply_patches.sh wownero + - name: obtain hashes + run: | + set -x + pushd external/wownero-seed + echo "EXTERNAL_WOWNEROSEED=$(git rev-parse HEAD)" >> $GITHUB_ENV + popd + echo "WOWNERO_WOWNEROSEED=$(cat wownero/contrib/depends/packages/wownero_seed.mk | grep _download_file | tr '=.' '\n' | head -2 | tail -1)" >> $GITHUB_ENV + - name: compare hashes + run: | + if [[ "x$WOWNERO_WOWNEROSEED" == "x" ]]; + then + echo "Unable to obtain wownero seed from wownero repo" + exit 1 + fi + if [[ ! "x$EXTERNAL_WOWNEROSEED" == "x$WOWNERO_WOWNEROSEED" ]]; + then + echo "external/wownero-seed doesn't match wownero/contrib/depends/packages/wownero_seed.mk checksum" + exit 1 + fi + polyseed: + strategy: + matrix: + coin: [monero, wownero] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + - name: Patch sources + run: | + git config --global --add safe.directory '*' + git config --global user.email "ci@mrcyjanek.net" + git config --global user.name "CI mrcyjanek.net" + ./apply_patches.sh ${{ matrix.coin }} + - name: prepare + run: | + set -x + pushd ${{ matrix.coin }}/contrib/depends + make download # sorry, this is the easiest way + mkdir sources/polyseed + pushd sources/polyseed + tar xzf ../polyseed*.tar.gz + popd + popd + - name: diff + run: | + OUTPUT=$(diff -ra external/polyseed ${{ matrix.coin }}/contrib/depends/sources/polyseed/* | grep -v .git | wc -l) + if [[ ! "x$OUTPUT" == "x0" ]]; + then + diff -ra external/polyseed ${{ matrix.coin }}/contrib/depends/sources/polyseed/* + exit 1 + fi diff --git a/external/polyseed b/external/polyseed index b7c35bb3..3ef36699 160000 --- a/external/polyseed +++ b/external/polyseed @@ -1 +1 @@ -Subproject commit b7c35bb3c6b91e481ecb04fc235eaff69c507fa1 +Subproject commit 3ef366993258a6f1c837d4908e3e4afb2cfefff7 From d56b480abe497c39ffdfdc4c827040569f0dd0e9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:05:42 +0000 Subject: [PATCH 03/28] chore(deps): update ghcr.io/cirruslabs/flutter docker tag to v3.22.3 --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 232e912c..da945f39 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/cirruslabs/flutter:3.22.2 +FROM ghcr.io/cirruslabs/flutter:3.22.3 # FROM debian:bookworm # Install dependencies From bcb328a4956105dc182afd0ce2e48fe263f5f20b Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Fri, 2 Aug 2024 19:26:48 +0200 Subject: [PATCH 04/28] bump java version in cake wallet ci --- .github/workflows/cake_wallet.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cake_wallet.yaml b/.github/workflows/cake_wallet.yaml index f4bc4626..9ca355a8 100644 --- a/.github/workflows/cake_wallet.yaml +++ b/.github/workflows/cake_wallet.yaml @@ -64,7 +64,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: "11.x" + java-version: "17.x" - name: Configure placeholder git details run: | git config --global user.email "CI@cakewallet.com" @@ -246,4 +246,4 @@ jobs: with: issue-number: ${{steps.get_issue_number.outputs.result}} body: | - [download cake_wallet #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) \ No newline at end of file + [download cake_wallet #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) From 5de323b1ba7387cf73973042f06383d4dbe619f5 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Mon, 12 Aug 2024 15:12:37 +0200 Subject: [PATCH 05/28] fix macos rosseta builds --- .gitmodules | 3 +++ README.md | 2 +- build_single.sh | 34 ++++++++++++++++++++------------- external/libexpat | 1 + external/macos/build_unbound.sh | 22 ++++++++++++++++----- external/macos/config.sh | 5 +++-- 6 files changed, 46 insertions(+), 21 deletions(-) create mode 160000 external/libexpat diff --git a/.gitmodules b/.gitmodules index cbb27ebe..d9a8e69e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "external/libzmq"] path = external/libzmq url = https://github.com/zeromq/libzmq +[submodule "external/libexpat"] + path = external/libexpat + url = https://github.com/libexpat/libexpat.git diff --git a/README.md b/README.md index 4092b65b..3a9b1a5b 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ While building I aim to compile the code at oldest supported release of debian, | x86_64-w64-mingw32 | debian:buster | -"- | | x86_64-apple-darwin11 | debian:bookworm | extra build step: `${HOST_ABI}-ranlib $PWD/$repo/contrib/depends/${HOST_ABI}/lib/libpolyseed.a` | | aarch64-apple-darwin11 | debian:bookworm | -"- | -| host-apple-darwin | arm64-apple-darwin23 | dependencies: `brew install unbound boost@1.76 zmq && brew link boost@1.76` | +| host-apple-darwin | arm64-apple-darwin23 | dependencies: `brew install unbound boost@1.76 zmq cmake ccache autoconf automake libtool && brew link boost@1.76` | | host-apple-ios | arm64-apple-darwin23 | | ## Design diff --git a/build_single.sh b/build_single.sh index d98af2a9..a8368daf 100755 --- a/build_single.sh +++ b/build_single.sh @@ -2,6 +2,15 @@ cd "$(realpath $(dirname $0))" +proccount=1 +if [[ "x$(uname)" == "xDarwin" ]]; +then + proccount=$(sysctl -n hw.physicalcpu) +elif [[ "x$(uname)" == "xLinux" ]]; +then + proccount=$(nproc) +fi + function verbose_copy() { echo "==> cp $1 $2" cp $1 $2 @@ -11,13 +20,13 @@ set -e repo=$1 if [[ "x$repo" == "x" ]]; then - echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$(nproc)" + echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount" exit 1 fi if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" ]]; then - echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$(nproc)" + echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount" echo "Invalid target given, only monero and wownero are supported targets" fi @@ -31,7 +40,7 @@ fi HOST_ABI="$2" if [[ "x$HOST_ABI" == "x" ]]; then - echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$(nproc)" + echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount" exit 1 fi @@ -39,7 +48,7 @@ NPROC="$3" if [[ "x$NPROC" == "x" ]]; then - echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$(nproc)" + echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount" exit 1 fi cd $(dirname $0) @@ -181,20 +190,19 @@ pushd $repo/contrib/depends make $NPROC popd fi - pushd ../../../external/macos - ./build_unbound.sh - popd MACOS_LIBS_DIR="${PWD}/${HOST_ABI}" rm -rf ${MACOS_LIBS_DIR} mkdir -p ${MACOS_LIBS_DIR}/lib - if [[ "x$HOMEBREW_PREFIX" == "x" ]]; + if [[ "$(uname -m)" == "arm64" ]]; then - export HOMEBREW_PREFIX=/opt/homebrew - if [[ ! -d "$HOMEBREW_PREFIX" ]]; - then - export HOMEBREW_PREFIX=/usr/local - fi + export HOMEBREW_PREFIX="/opt/homebrew" + elif [[ "$(uname -m)" == "x86_64" ]]; + then + export HOMEBREW_PREFIX="/usr/local" fi + pushd ../../../external/macos + ./build_unbound.sh + popd # NOTE: we can use unbound from brew but app store rejects the app because of nghttp2 symbols being included # verbose_copy "${HOMEBREW_PREFIX}/lib/libunbound.a" ${MACOS_LIBS_DIR}/lib/libunbound.a verbose_copy "../../../external/macos/build/MACOS/lib/libunbound.a" ${MACOS_LIBS_DIR}/lib/libunbound.a diff --git a/external/libexpat b/external/libexpat new file mode 160000 index 00000000..3bab6c09 --- /dev/null +++ b/external/libexpat @@ -0,0 +1 @@ +Subproject commit 3bab6c09bbe8bf42d84b81563ddbcf4cca4be838 diff --git a/external/macos/build_unbound.sh b/external/macos/build_unbound.sh index e9e1ff87..d1c3825e 100755 --- a/external/macos/build_unbound.sh +++ b/external/macos/build_unbound.sh @@ -9,9 +9,15 @@ EXPAT_VERSION=R_2_4_8 EXPAT_HASH="3bab6c09bbe8bf42d84b81563ddbcf4cca4be838" EXPAT_SRC_DIR=${EXTERNAL_MACOS_SOURCE_DIR}/libexpat rm -rf $EXPAT_SRC_DIR -git clone https://github.com/libexpat/libexpat.git -b ${EXPAT_VERSION} ${EXPAT_SRC_DIR} +if [ -d "$EXPAT_SRC_DIR" ]; then + echo "Unbound directory already exists." +else + echo "Cloning Unbound from $Unbound_URL" + mkdir -p ${EXPAT_SRC_DIR} || true + rm -rf ${EXPAT_SRC_DIR} + cp -r "${MONEROC_DIR}/external/libexpat" ${EXPAT_SRC_DIR} +fi cd $EXPAT_SRC_DIR -test `git rev-parse HEAD` = ${EXPAT_HASH} || exit 1 cd $EXPAT_SRC_DIR/expat ./buildconf.sh @@ -28,10 +34,16 @@ UNBOUND_DIR_PATH="${EXTERNAL_MACOS_SOURCE_DIR}/unbound-1.16.2" echo "============================ Unbound ============================" rm -rf ${UNBOUND_DIR_PATH} -git clone https://github.com/NLnetLabs/unbound.git -b ${UNBOUND_VERSION} ${UNBOUND_DIR_PATH} +# Check if the directory already exists. +if [ -d "$UNBOUND_DIR_PATH" ]; then + echo "Unbound directory already exists." +else + echo "Cloning Unbound from $Unbound_URL" + mkdir -p ${UNBOUND_DIR_PATH} || true + rm -rf ${UNBOUND_DIR_PATH} + cp -r "${MONEROC_DIR}/external/unbound" ${UNBOUND_DIR_PATH} +fi cd $UNBOUND_DIR_PATH -test `git rev-parse HEAD` = ${UNBOUND_HASH} || exit 1 - ./configure --prefix="${EXTERNAL_MACOS_DIR}" \ --with-ssl="${HOMEBREW_PREFIX}" \ --with-libexpat="${EXTERNAL_MACOS_DIR}" \ diff --git a/external/macos/config.sh b/external/macos/config.sh index dcdf4624..3c406255 100755 --- a/external/macos/config.sh +++ b/external/macos/config.sh @@ -7,6 +7,7 @@ export EXTERNAL_MACOS_DIR="${EXTERNAL_DIR}/MACOS" export EXTERNAL_MACOS_SOURCE_DIR="${EXTERNAL_MACOS_DIR}/sources" export EXTERNAL_MACOS_LIB_DIR="${EXTERNAL_MACOS_DIR}/lib" export EXTERNAL_MACOS_INCLUDE_DIR="${EXTERNAL_MACOS_DIR}/include" +export MONEROC_DIR="$(pwd)/../.." -mkdir -p "$EXTERNAL_MACOS_LIB_DIR" -mkdir -p "$EXTERNAL_MACOS_INCLUDE_DIR" \ No newline at end of file +mkdir -p "$EXTERNAL_MACOS_LIB_DIR" || true +mkdir -p "$EXTERNAL_MACOS_INCLUDE_DIR" || true \ No newline at end of file From 06208221de515e75136c882b97dc7623487d17c8 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 14 Aug 2024 13:41:11 +0200 Subject: [PATCH 06/28] fix cakewallet ci (#30) --- .github/workflows/cake_wallet.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cake_wallet.yaml b/.github/workflows/cake_wallet.yaml index 9ca355a8..987a7cc5 100644 --- a/.github/workflows/cake_wallet.yaml +++ b/.github/workflows/cake_wallet.yaml @@ -177,7 +177,7 @@ jobs: - name: Rename app run: | - echo -e "id=com.cakewallet.moneroc_${{ env.PR_NUMBER }}\nname=${{ github.ref_name }}" | tr '/-' '_' > /opt/android/cake_wallet/android/app.properties + echo -e "id=com.cakewallet.moneroc_${{ env.PR_NUMBER }}\nname=${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9=\n.]//g' > /opt/android/cake_wallet/android/app.properties - name: Build run: | @@ -188,7 +188,7 @@ jobs: run: | cd /opt/android/cake_wallet/build/app/outputs/flutter-apk mkdir test-apk - cp app-arm64-v8a-release.apk "test-apk/$(echo ${{ github.ref_name }} | tr '/-' '_').apk" + cp app-arm64-v8a-release.apk "test-apk/$(echo ${{ github.ref_name }} | sed 's/[^a-zA-Z0-9]//g').apk" - name: Upload Artifact uses: kittaakos/upload-artifact-as-is@v0 From cfc9fc2d7a2330873ff5f49416dac866fad08c27 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 14 Aug 2024 16:49:49 +0200 Subject: [PATCH 07/28] new ci scripts (#37) --- .github/workflows/cake_wallet.yaml | 249 ----------------- .../{compat.yaml => full_check.yaml} | 254 +++++++++++++++++- .github/workflows/xmruw.yaml | 106 -------- 3 files changed, 241 insertions(+), 368 deletions(-) delete mode 100644 .github/workflows/cake_wallet.yaml rename .github/workflows/{compat.yaml => full_check.yaml} (64%) delete mode 100644 .github/workflows/xmruw.yaml diff --git a/.github/workflows/cake_wallet.yaml b/.github/workflows/cake_wallet.yaml deleted file mode 100644 index 987a7cc5..00000000 --- a/.github/workflows/cake_wallet.yaml +++ /dev/null @@ -1,249 +0,0 @@ -name: Build cake_wallet for android -on: [push] -permissions: - issues: write - pull-requests: write - -jobs: - cake_wallet: - runs-on: ubuntu-20.04 - env: - STORE_PASS: test@cake_wallet - KEY_PASS: test@cake_wallet - PR_NUMBER: ${{ github.ref_name }} - - steps: - - name: set branch name - run: echo "BRANCH_NAME=${{ github.ref_name }}" >> $GITHUB_ENV - - - uses: actions/checkout@v4 - with: - repository: MrCyjaneK/monero_c - fetch-depth: 0 - submodules: recursive - - - name: Patch sources - run: | - git config --global --add safe.directory '*' - git config --global user.email "ci@mrcyjanek.net" - git config --global user.name "CI mrcyjanek.net" - ./apply_patches.sh monero - ./apply_patches.sh wownero - - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: ${{ github.job }}-monero - - - name: Cache built - if: ${{ !startsWith(github.ref, 'refs/tags/v') }} - uses: actions/cache@v4 - with: - path: | - */contrib/depends/built/* - key: depends-${{ github.job }}-monero-${{ hashFiles('*/contrib/depends/packages/*.mk') }} - - - name: build monero_c - run: | - ./build_single.sh monero aarch64-linux-android -j$(nproc) - ./build_single.sh wownero aarch64-linux-android -j$(nproc) - unxz -f -k release/*/*.xz - mv release /opt/monero_c_release - - - name: Free Disk Space (Ubuntu) - uses: insightsengineering/disk-space-reclaimer@v1 - with: - tools-cache: true - android: false - dotnet: true - haskell: true - large-packages: true - swap-storage: true - docker-images: true - - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: "17.x" - - name: Configure placeholder git details - run: | - git config --global user.email "CI@cakewallet.com" - git config --global user.name "Cake Github Actions" - - name: Flutter action - uses: subosito/flutter-action@v2 - with: - flutter-version: "3.19.6" - channel: stable - - - name: Install package dependencies - run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang - - - name: Execute Build and Setup Commands - run: | - sudo mkdir -p /opt/android - sudo chown $USER /opt/android - cd /opt/android - -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - cargo install cargo-ndk - git clone https://github.com/cake-tech/cake_wallet.git --branch main --depth=1 - cd cake_wallet/scripts/android/ - ./install_ndk.sh - source ./app_env.sh cakewallet - chmod +x pubspec_gen.sh - ./app_config.sh - mkdir -p /opt/android/cake_wallet/scripts/monero_c - mv /opt/monero_c_release /opt/android/cake_wallet/scripts/monero_c/release - - - name: Install Flutter dependencies - run: | - cd /opt/android/cake_wallet - flutter pub get - - - name: Generate KeyStore - run: | - cd /opt/android/cake_wallet/android/app - keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS - - - name: Generate key properties - run: | - cd /opt/android/cake_wallet - flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS - - - name: Generate localization - run: | - cd /opt/android/cake_wallet - flutter packages pub run tool/generate_localization.dart - - - name: Build generated code - run: | - cd /opt/android/cake_wallet - ./model_generator.sh - - - name: Add secrets - run: | - cd /opt/android/cake_wallet - touch lib/.secrets.g.dart - touch cw_evm/lib/.secrets.g.dart - touch cw_solana/lib/.secrets.g.dart - touch cw_core/lib/.secrets.g.dart - touch cw_nano/lib/.secrets.g.dart - touch cw_tron/lib/.secrets.g.dart - echo "const salt = 'd551f8841584b0ce37edf6fd59177d35';" > lib/.secrets.g.dart - echo "const keychainSalt = '34c626b6a4f8cb6789897c09';" >> lib/.secrets.g.dart - echo "const key = 'd8ab7230137ebadeb1c4e429395eced1';" >> lib/.secrets.g.dart - echo "const walletSalt = 'a9a49562';" >> lib/.secrets.g.dart - echo "const shortKey = 'c1b21c5050527842350dc8f5';" >> lib/.secrets.g.dart - echo "const backupSalt = 'b3e42404f90ca8e8';" >> lib/.secrets.g.dart - echo "const backupKeychainSalt = '9e0f3c4d347bc99509695a86';" >> lib/.secrets.g.dart - echo "const changeNowApiKey = '';" >> lib/.secrets.g.dart - echo "const changeNowApiKeyDesktop = '';" >> lib/.secrets.g.dart - echo "const wyreSecretKey = '';" >> lib/.secrets.g.dart - echo "const wyreApiKey = '';" >> lib/.secrets.g.dart - echo "const wyreAccountId = '';" >> lib/.secrets.g.dart - echo "const moonPayApiKey = '';" >> lib/.secrets.g.dart - echo "const moonPaySecretKey = '';" >> lib/.secrets.g.dart - echo "const sideShiftAffiliateId = '';" >> lib/.secrets.g.dart - echo "const simpleSwapApiKey = '';" >> lib/.secrets.g.dart - echo "const simpleSwapApiKeyDesktop = '';" >> lib/.secrets.g.dart - echo "const onramperApiKey = '';" >> lib/.secrets.g.dart - echo "const anypayToken = '';" >> lib/.secrets.g.dart - echo "const ioniaClientId = '';" >> lib/.secrets.g.dart - echo "const twitterBearerToken = '';" >> lib/.secrets.g.dart - echo "const trocadorApiKey = '';" >> lib/.secrets.g.dart - echo "const trocadorExchangeMarkup = '';" >> lib/.secrets.g.dart - echo "const anonPayReferralCode = '';" >> lib/.secrets.g.dart - echo "const fiatApiKey = '';" >> lib/.secrets.g.dart - echo "const payfuraApiKey = '';" >> lib/.secrets.g.dart - echo "const ankrApiKey = '';" >> lib/.secrets.g.dart - echo "const etherScanApiKey = '';" >> cw_evm/lib/.secrets.g.dart - echo "const moralisApiKey = '';" >> cw_evm/lib/.secrets.g.dart - echo "const chatwootWebsiteToken = '';" >> lib/.secrets.g.dart - echo "const exolixApiKey = '';" >> lib/.secrets.g.dart - echo "const robinhoodApplicationId = '';" >> lib/.secrets.g.dart - echo "const exchangeHelperApiKey = '';" >> lib/.secrets.g.dart - echo "const walletConnectProjectId = '';" >> lib/.secrets.g.dart - echo "const moralisApiKey = '';" >> lib/.secrets.g.dart - echo "const polygonScanApiKey = '';" >> cw_evm/lib/.secrets.g.dart - echo "const ankrApiKey = '';" >> cw_solana/lib/.secrets.g.dart - echo "const testCakePayApiKey = '';" >> lib/.secrets.g.dart - echo "const cakePayApiKey = '';" >> lib/.secrets.g.dart - echo "const authorization = '';" >> lib/.secrets.g.dart - echo "const CSRFToken = '';" >> lib/.secrets.g.dart - echo "const quantexExchangeMarkup = '';" >> lib/.secrets.g.dart - echo "const nano2ApiKey = '';" >> cw_nano/lib/.secrets.g.dart - echo "const nanoNowNodesApiKey = '';" >> cw_nano/lib/.secrets.g.dart - echo "const tronGridApiKey = '';" >> cw_tron/lib/.secrets.g.dart - echo "const tronNowNodesApiKey = '';" >> cw_tron/lib/.secrets.g.dart - - - name: Rename app - run: | - echo -e "id=com.cakewallet.moneroc_${{ env.PR_NUMBER }}\nname=${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9=\n.]//g' > /opt/android/cake_wallet/android/app.properties - - - name: Build - run: | - cd /opt/android/cake_wallet - flutter build apk --release --split-per-abi - - - name: Rename apk file - run: | - cd /opt/android/cake_wallet/build/app/outputs/flutter-apk - mkdir test-apk - cp app-arm64-v8a-release.apk "test-apk/$(echo ${{ github.ref_name }} | sed 's/[^a-zA-Z0-9]//g').apk" - - - name: Upload Artifact - uses: kittaakos/upload-artifact-as-is@v0 - with: - path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/ - - - name: remove android_ndk - run: | - rm -rf monero/contrib/depends/built/*/android_ndk - rm -rf monero/contrib/depends/sources/android-ndk-r26d-linux.zip - rm -rf wownero/contrib/depends/built/*/android_ndk - rm -rf wownero/contrib/depends/sources/android-ndk-r26d-linux.zip - - uses: actions/github-script@v7 - continue-on-error: true - id: get_issue_number - with: - script: | - if (context.issue.number) { - // Return issue number if present - return context.issue.number; - } else { - // Otherwise return issue number from commit - return ( - await github.rest.repos.listPullRequestsAssociatedWithCommit({ - commit_sha: context.sha, - owner: context.repo.owner, - repo: context.repo.repo, - }) - ).data[0].number; - } - result-encoding: string - - name: Find Comment - continue-on-error: true - uses: peter-evans/find-comment@v3 - id: fc - with: - issue-number: ${{steps.get_issue_number.outputs.result}} - comment-author: 'github-actions[bot]' - body-includes: download cake_wallet - - - name: Create or update comment - continue-on-error: true - if: steps.fc.outcome == 'success' - uses: peter-evans/create-or-update-comment@v4 - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{steps.get_issue_number.outputs.result}} - body: | - [download cake_wallet #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) - edit-mode: replace - - name: Create comment - continue-on-error: true - if: steps.fc.outcome == 'failure' - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{steps.get_issue_number.outputs.result}} - body: | - [download cake_wallet #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) diff --git a/.github/workflows/compat.yaml b/.github/workflows/full_check.yaml similarity index 64% rename from .github/workflows/compat.yaml rename to .github/workflows/full_check.yaml index df42742d..3c8dd88a 100644 --- a/.github/workflows/compat.yaml +++ b/.github/workflows/full_check.yaml @@ -1,10 +1,10 @@ -name: compatibility check +name: full compatibility check on: [push] permissions: issues: write pull-requests: write jobs: - mingw: + lib_mingw: strategy: matrix: coin: [monero, wownero] @@ -59,7 +59,7 @@ jobs: with: name: mingw ${{ matrix.coin }} path: release/${{ matrix.coin }} - android: + lib_android: strategy: matrix: coin: [monero, wownero] @@ -131,7 +131,7 @@ jobs: run: | rm -rf ${{ matrix.coin }}/contrib/depends/built/*/android_ndk rm -rf ${{ matrix.coin }}/contrib/depends/sources/android-ndk-r26d-linux.zip - linux: + lib_linux: strategy: matrix: coin: [monero, wownero] @@ -188,7 +188,7 @@ jobs: with: name: linux ${{ matrix.coin }} path: release/${{ matrix.coin }} - sailfishos_aarch64: + lib_sailfishos_aarch64: strategy: matrix: coin: [monero, wownero] @@ -243,7 +243,7 @@ jobs: with: name: sfos aarch64 ${{ matrix.coin }} path: release/${{ matrix.coin }} - sailfishos_i486: + lib_sailfishos_i486: strategy: matrix: coin: [monero, wownero] @@ -291,7 +291,7 @@ jobs: with: name: sfos_i486 ${{ matrix.coin }} path: release/${{ matrix.coin }} - darwin: + lib_darwin: strategy: matrix: coin: [monero, wownero] @@ -353,7 +353,7 @@ jobs: rm -rf ${{ matrix.coin }}/contrib/depends/built/*/native_clang rm -rf ${{ matrix.coin }}/contrib/depends/sources/clang-llvm*.tar.xz rm -rf ${{ matrix.coin }}/contrib/depends/sources/MacOSX*sdk.tar.xz - macos: + lib_macos: strategy: matrix: coin: [monero, wownero] @@ -410,7 +410,7 @@ jobs: with: name: macos ${{ matrix.coin }} path: release/${{ matrix.coin }} - ios: + lib_ios: strategy: matrix: coin: [monero, wownero] @@ -467,11 +467,239 @@ jobs: with: name: ios ${{ matrix.coin }} path: release/${{ matrix.coin }} + + # Extra stuff below, not strictly required for monero_c, but we do want to ensure + # that nothing really broke the app when we work on some feature. + + wallet_cake_android: + needs: [ lib_android ] + runs-on: ubuntu-20.04 + env: + STORE_PASS: test@cake_wallet + KEY_PASS: test@cake_wallet + PR_NUMBER: ${{ github.ref_name }} + + steps: + - name: set branch name + run: echo "BRANCH_NAME=${{ github.ref_name }}" >> $GITHUB_ENV + + - uses: actions/download-artifact@v4 + with: + name: android monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: android wownero + path: release/wownero + + - name: unpack and move monero_c + run: | + unxz -f -k release/*/*.xz + mv release /opt/monero_c_release + + - name: Free Disk Space (Ubuntu) + uses: insightsengineering/disk-space-reclaimer@v1 + with: + tools-cache: true + android: false + dotnet: true + haskell: true + large-packages: true + swap-storage: true + docker-images: true + + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: "17.x" + - name: Configure placeholder git details + run: | + git config --global user.email "CI@cakewallet.com" + git config --global user.name "Cake Github Actions" + - name: Flutter action + uses: subosito/flutter-action@v2 + with: + flutter-version: "3.19.6" + channel: stable + + - name: Install package dependencies + run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang + + - name: Execute Build and Setup Commands + run: | + sudo mkdir -p /opt/android + sudo chown $USER /opt/android + cd /opt/android + -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + cargo install cargo-ndk + git clone https://github.com/cake-tech/cake_wallet.git --branch main --depth=1 + cd cake_wallet/scripts/android/ + ./install_ndk.sh + source ./app_env.sh cakewallet + chmod +x pubspec_gen.sh + ./app_config.sh + mkdir -p /opt/android/cake_wallet/scripts/monero_c + mv /opt/monero_c_release /opt/android/cake_wallet/scripts/monero_c/release + + - name: Install Flutter dependencies + run: | + cd /opt/android/cake_wallet + flutter pub get + + - name: Generate KeyStore + run: | + cd /opt/android/cake_wallet/android/app + keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS + + - name: Generate key properties + run: | + cd /opt/android/cake_wallet + flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS + + - name: Generate localization + run: | + cd /opt/android/cake_wallet + flutter packages pub run tool/generate_localization.dart + + - name: Build generated code + run: | + cd /opt/android/cake_wallet + ./model_generator.sh + + - name: Add secrets + run: | + cd /opt/android/cake_wallet + touch lib/.secrets.g.dart + touch cw_evm/lib/.secrets.g.dart + touch cw_solana/lib/.secrets.g.dart + touch cw_core/lib/.secrets.g.dart + touch cw_nano/lib/.secrets.g.dart + touch cw_tron/lib/.secrets.g.dart + echo "const salt = 'd551f8841584b0ce37edf6fd59177d35';" > lib/.secrets.g.dart + echo "const keychainSalt = '34c626b6a4f8cb6789897c09';" >> lib/.secrets.g.dart + echo "const key = 'd8ab7230137ebadeb1c4e429395eced1';" >> lib/.secrets.g.dart + echo "const walletSalt = 'a9a49562';" >> lib/.secrets.g.dart + echo "const shortKey = 'c1b21c5050527842350dc8f5';" >> lib/.secrets.g.dart + echo "const backupSalt = 'b3e42404f90ca8e8';" >> lib/.secrets.g.dart + echo "const backupKeychainSalt = '9e0f3c4d347bc99509695a86';" >> lib/.secrets.g.dart + echo "const changeNowApiKey = '';" >> lib/.secrets.g.dart + echo "const changeNowApiKeyDesktop = '';" >> lib/.secrets.g.dart + echo "const wyreSecretKey = '';" >> lib/.secrets.g.dart + echo "const wyreApiKey = '';" >> lib/.secrets.g.dart + echo "const wyreAccountId = '';" >> lib/.secrets.g.dart + echo "const moonPayApiKey = '';" >> lib/.secrets.g.dart + echo "const moonPaySecretKey = '';" >> lib/.secrets.g.dart + echo "const sideShiftAffiliateId = '';" >> lib/.secrets.g.dart + echo "const simpleSwapApiKey = '';" >> lib/.secrets.g.dart + echo "const simpleSwapApiKeyDesktop = '';" >> lib/.secrets.g.dart + echo "const onramperApiKey = '';" >> lib/.secrets.g.dart + echo "const anypayToken = '';" >> lib/.secrets.g.dart + echo "const ioniaClientId = '';" >> lib/.secrets.g.dart + echo "const twitterBearerToken = '';" >> lib/.secrets.g.dart + echo "const trocadorApiKey = '';" >> lib/.secrets.g.dart + echo "const trocadorExchangeMarkup = '';" >> lib/.secrets.g.dart + echo "const anonPayReferralCode = '';" >> lib/.secrets.g.dart + echo "const fiatApiKey = '';" >> lib/.secrets.g.dart + echo "const payfuraApiKey = '';" >> lib/.secrets.g.dart + echo "const ankrApiKey = '';" >> lib/.secrets.g.dart + echo "const etherScanApiKey = '';" >> cw_evm/lib/.secrets.g.dart + echo "const moralisApiKey = '';" >> cw_evm/lib/.secrets.g.dart + echo "const chatwootWebsiteToken = '';" >> lib/.secrets.g.dart + echo "const exolixApiKey = '';" >> lib/.secrets.g.dart + echo "const robinhoodApplicationId = '';" >> lib/.secrets.g.dart + echo "const exchangeHelperApiKey = '';" >> lib/.secrets.g.dart + echo "const walletConnectProjectId = '';" >> lib/.secrets.g.dart + echo "const moralisApiKey = '';" >> lib/.secrets.g.dart + echo "const polygonScanApiKey = '';" >> cw_evm/lib/.secrets.g.dart + echo "const ankrApiKey = '';" >> cw_solana/lib/.secrets.g.dart + echo "const testCakePayApiKey = '';" >> lib/.secrets.g.dart + echo "const cakePayApiKey = '';" >> lib/.secrets.g.dart + echo "const authorization = '';" >> lib/.secrets.g.dart + echo "const CSRFToken = '';" >> lib/.secrets.g.dart + echo "const quantexExchangeMarkup = '';" >> lib/.secrets.g.dart + echo "const nano2ApiKey = '';" >> cw_nano/lib/.secrets.g.dart + echo "const nanoNowNodesApiKey = '';" >> cw_nano/lib/.secrets.g.dart + echo "const tronGridApiKey = '';" >> cw_tron/lib/.secrets.g.dart + echo "const tronNowNodesApiKey = '';" >> cw_tron/lib/.secrets.g.dart + + - name: Rename app + run: | + echo -e "id=com.cakewallet.moneroc_${{ env.PR_NUMBER }}\nname=${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9=\n.]//g' > /opt/android/cake_wallet/android/app.properties + + - name: Build + run: | + cd /opt/android/cake_wallet + flutter build apk --release --split-per-abi + + - name: Upload APK + uses: actions/upload-artifact@v4 + with: + name: cake wallet android + path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/*.apk + + - name: remove android_ndk + run: | + rm -rf monero/contrib/depends/built/*/android_ndk + rm -rf monero/contrib/depends/sources/android-ndk-r26d-linux.zip + rm -rf wownero/contrib/depends/built/*/android_ndk + rm -rf wownero/contrib/depends/sources/android-ndk-r26d-linux.zip + + wallet_xmruw_android: + needs: [ lib_android ] + strategy: + matrix: + coin: [monero, wownero] + runs-on: ubuntu-latest + steps: + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 libtinfo5 gperf unzip python-is-python3 jq + - uses: actions/download-artifact@v4 + with: + name: android ${{ matrix.coin }} + path: release/${{ matrix.coin }} + - name: clone xmruw + run: | + git clone https://github.com/mrcyjanek/unnamed_monero_wallet + cd unnamed_monero_wallet + cp -a .fvm* .. + - uses: kuhnroyal/flutter-fvm-config-action@v2 + id: fvm-config-action + - uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} + channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + - name: build xmruw (${{ matrix.coin }}) + run: | + cd unnamed_monero_wallet + if [[ "${{ matrix.coin }}" == "monero" ]]; then ./codegen.sh -DCOIN_MONERO -DLIBSTEALTH_DISABLED; fi + if [[ "${{ matrix.coin }}" == "wownero" ]]; then ./codegen.sh -DCOIN_WOWNERO -DLIBSTEALTH_DISABLED; fi + flutter pub get + make version + ./build_changelog.sh + cp ../release/${{ matrix.coin }}/aarch64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/arm64-v8a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz + cp ../release/${{ matrix.coin }}/x86_64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/x86_64/lib${{ matrix.coin }}_libwallet2_api_c.so.xz + cp ../release/${{ matrix.coin }}/armv7a-linux-androideabi_libwallet2_api_c.so.xz android/app/src/main/jniLibs/armeabi-v7a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz + unxz -f android/app/src/main/jniLibs/*/*.xz + flutter build apk --release --flavor clean_${{ matrix.coin }} + - name: Upload APK + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.coin }} xmruw apk + path: unnamed_monero_wallet/build/app/outputs/flutter-apk/*.apk + comment_pr: name: comment on pr runs-on: ubuntu-latest needs: [ - mingw, android, linux, sailfishos_aarch64, sailfishos_i486, darwin, macos, ios + lib_mingw, lib_android, lib_linux, lib_sailfishos_aarch64, lib_sailfishos_i486, lib_darwin, lib_macos, lib_ios, + wallet_cake_android, + wallet_xmruw_android ] steps: - uses: actions/github-script@v7 @@ -500,7 +728,7 @@ jobs: with: issue-number: ${{steps.get_issue_number.outputs.result}} comment-author: 'github-actions[bot]' - body-includes: download libraries + body-includes: download artifacts - name: Update comment continue-on-error: true if: steps.fc.outcome == 'success' @@ -509,7 +737,7 @@ jobs: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{steps.get_issue_number.outputs.result}} body: | - [download libraries #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) + [download artifacts #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) edit-mode: replace - name: Create comment continue-on-error: true @@ -518,4 +746,4 @@ jobs: with: issue-number: ${{steps.get_issue_number.outputs.result}} body: | - [download libraries #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) \ No newline at end of file + [download artifacts #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) \ No newline at end of file diff --git a/.github/workflows/xmruw.yaml b/.github/workflows/xmruw.yaml deleted file mode 100644 index fd349339..00000000 --- a/.github/workflows/xmruw.yaml +++ /dev/null @@ -1,106 +0,0 @@ -name: Build xmruw -on: [push] -permissions: - issues: write - pull-requests: write - -jobs: - android: - strategy: - matrix: - coin: [monero, wownero] - runs-on: ubuntu-latest - steps: - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 libtinfo5 gperf unzip python-is-python3 jq - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: recursive - - name: Patch sources - run: | - git config --global --add safe.directory '*' - git config --global user.email "ci@mrcyjanek.net" - git config --global user.name "CI mrcyjanek.net" - ./apply_patches.sh ${{ matrix.coin }} - - name: ${{ matrix.coin }}/aarch64-linux-android - run: ./build_single.sh ${{ matrix.coin }} aarch64-linux-android -j$(nproc) - - name: clone xmruw - run: | - git clone https://github.com/mrcyjanek/unnamed_monero_wallet - cd unnamed_monero_wallet - cp -a .fvm* .. - - uses: kuhnroyal/flutter-fvm-config-action@v2 - id: fvm-config-action - - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} - channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '17' - - name: build xmruw (${{ matrix.coin }}) - run: | - cd unnamed_monero_wallet - if [[ "${{ matrix.coin }}" == "monero" ]]; then ./codegen.sh -DCOIN_MONERO -DLIBSTEALTH_DISABLED; fi - if [[ "${{ matrix.coin }}" == "wownero" ]]; then ./codegen.sh -DCOIN_WOWNERO -DLIBSTEALTH_DISABLED; fi - flutter pub get - make version - ./build_changelog.sh - cp ../release/${{ matrix.coin }}/aarch64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/arm64-v8a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz - unxz -f android/app/src/main/jniLibs/arm64-v8a/*.xz - flutter build apk --debug --flavor clean_${{ matrix.coin }} - - name: Upload APK - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.coin }} xmruw apk - path: unnamed_monero_wallet/build/app/outputs/flutter-apk/*.apk - - uses: actions/github-script@v7 - continue-on-error: true - id: get_issue_number - with: - script: | - if (context.issue.number) { - // Return issue number if present - return context.issue.number; - } else { - // Otherwise return issue number from commit - return ( - await github.rest.repos.listPullRequestsAssociatedWithCommit({ - commit_sha: context.sha, - owner: context.repo.owner, - repo: context.repo.repo, - }) - ).data[0].number; - } - result-encoding: string - - name: Find Comment - continue-on-error: true - uses: peter-evans/find-comment@v3 - id: fc - with: - issue-number: ${{steps.get_issue_number.outputs.result}} - comment-author: 'github-actions[bot]' - body-includes: download xmruw - - - name: Update comment - continue-on-error: true - if: steps.fc.outcome == 'success' - uses: peter-evans/create-or-update-comment@v4 - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{steps.get_issue_number.outputs.result}} - body: | - [download xmruw #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) - edit-mode: replace - - name: Create comment - continue-on-error: true - if: steps.fc.outcome == 'failure' - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{steps.get_issue_number.outputs.result}} - body: | - [download xmruw #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this link will update whenever you push) \ No newline at end of file From 41c58acb959c58f23b35dbf347918094ba6c1e9d Mon Sep 17 00:00:00 2001 From: cyan Date: Fri, 16 Aug 2024 21:01:02 +0200 Subject: [PATCH 08/28] Link wallet-crypto on android (#36) * Link wallet-crypto on android * build wallet-crypto for android x86_64 --- build_single.sh | 2 +- monero_libwallet2_api_c/CMakeLists.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build_single.sh b/build_single.sh index a8368daf..4f0c5ad5 100755 --- a/build_single.sh +++ b/build_single.sh @@ -319,7 +319,7 @@ pushd $repo/build/${HOST_ABI} env CC="${CC}" CXX="${CXX}" cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_TOOLCHAIN_FILE=$PWD/../../contrib/depends/${HOST_ABI}/share/toolchain.cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64="ON" -D CMAKE_BUILD_TYPE=$buildType -D ANDROID=false -D BUILD_TAG="linux-armv8" -D CMAKE_SYSTEM_NAME="Linux" ../.. ;; "x86_64-linux-android") - env CC="${CC}" CXX="${CXX}" cmake -DHIDAPI_DUMMY=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_TOOLCHAIN_FILE=$PWD/../../contrib/depends/${HOST_ABI}/share/toolchain.cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH="x86-64" -D STATIC=ON -D BUILD_64="ON" -D CMAKE_BUILD_TYPE=$buildType -D ANDROID=true -D BUILD_TAG="android-x86_64" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_ARCH_ABI="x86_64" ../.. + env CC="${CC}" CXX="${CXX}" cmake -DMONERO_WALLET_CRYPTO_LIBRARY=amd64-64-24k -DHIDAPI_DUMMY=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_TOOLCHAIN_FILE=$PWD/../../contrib/depends/${HOST_ABI}/share/toolchain.cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH="x86-64" -D STATIC=ON -D BUILD_64="ON" -D CMAKE_BUILD_TYPE=$buildType -D ANDROID=true -D BUILD_TAG="android-x86_64" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_ARCH_ABI="x86_64" ../.. ;; "i686-linux-android") env CC="${CC}" CXX="${CXX}" cmake -DHIDAPI_DUMMY=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_TOOLCHAIN_FILE=$PWD/../../contrib/depends/${HOST_ABI}/share/toolchain.cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH="x86" -D STATIC=ON -D BUILD_64="OFF" -D CMAKE_BUILD_TYPE=$buildType -D ANDROID=true -D BUILD_TAG="android-x86" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_ARCH_ABI="x86" ../.. diff --git a/monero_libwallet2_api_c/CMakeLists.txt b/monero_libwallet2_api_c/CMakeLists.txt index 724c20d8..eb1714ef 100644 --- a/monero_libwallet2_api_c/CMakeLists.txt +++ b/monero_libwallet2_api_c/CMakeLists.txt @@ -320,7 +320,8 @@ include_directories( ${EXTERNAL_LIBS_DIR}/include ) message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR}) if(${HOST_ABI} STREQUAL "x86_64-linux-gnu" OR - ${HOST_ABI} STREQUAL "x86_64-apple-darwin11") + ${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR + ${HOST_ABI} STREQUAL "x86_64-linux-android") set(EXTRA_LIBS "wallet-crypto") else() set(EXTRA_LIBS "") From 9c5459c51ed966f77e1bc22e787e858cd2c53c86 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 23:30:05 +0000 Subject: [PATCH 09/28] chore(deps): update ghcr.io/cirruslabs/flutter docker tag to v3.24.1 --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index da945f39..75d07e0c 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/cirruslabs/flutter:3.22.3 +FROM ghcr.io/cirruslabs/flutter:3.24.1 # FROM debian:bookworm # Install dependencies From d7a38301ece1a166af7b230e34be6e950e0aeb3c Mon Sep 17 00:00:00 2001 From: cyan Date: Mon, 26 Aug 2024 06:57:16 +0200 Subject: [PATCH 10/28] Monero v0.18.3.4 (#38) * updated monero dependency * update patches for v0.18.3.4 * update generate checksum to include version of submodule as well --- apply_patches.sh | 2 +- generate_checksum.sh | 5 +- .../monero.dart/lib/src/checksum_monero.dart | 2 +- .../monero.dart/lib/src/checksum_wownero.dart | 2 +- monero | 2 +- .../src/main/cpp/monero_checksum.h | 2 +- patches/monero/0001-polyseed.patch | 78 ++--- ...ckground-sync-with-just-the-view-key.patch | 303 +++++++++--------- patches/monero/0003-airgap.patch | 16 +- patches/monero/0004-coin-control.patch | 63 ++-- patches/monero/0005-fix-build-issues.patch | 6 +- patches/monero/0006-macos-build-fix.patch | 23 +- .../0007-fix-make-debug-test-target.patch | 61 ++-- ...g-___clear_cache-when-targetting-iOS.patch | 6 +- ...coverDeterministicWalletFromSpendKey.patch | 8 +- ...-and-tx-key-getter-for-PendingTransc.patch | 6 +- patches/monero/0011-store-crash-fix.patch | 24 +- patches/monero/0012-WIP-UR-functions.patch | 14 +- .../0013-android-ndk-version-bump.patch | 4 +- ...v7a.patch => 0014-rename-arm-armv7a.patch} | 4 +- ...e-proper-error-handling-in-get_seed.patch} | 8 +- ...=> 0016-add-dummy-device-for-ledger.patch} | 8 +- patches/monero/0017-added-deps.patch | 29 ++ .../src/main/cpp/wownero_checksum.h | 2 +- 24 files changed, 316 insertions(+), 362 deletions(-) rename patches/monero/{0013-rename-arm-armv7a.patch => 0014-rename-arm-armv7a.patch} (97%) rename patches/monero/{0014-use-proper-error-handling-in-get_seed.patch => 0015-use-proper-error-handling-in-get_seed.patch} (92%) rename patches/monero/{0015-add-dummy-device-for-ledger.patch => 0016-add-dummy-device-for-ledger.patch} (98%) create mode 100644 patches/monero/0017-added-deps.patch diff --git a/apply_patches.sh b/apply_patches.sh index 3ce68561..22c3bbac 100755 --- a/apply_patches.sh +++ b/apply_patches.sh @@ -31,7 +31,7 @@ fi set -e cd $repo -git am -3 ../patches/$repo/*.patch +git am -3 --whitespace=fix --reject ../patches/$repo/*.patch if [[ "$repo" == "wownero" ]]; then pushd external/randomwow diff --git a/generate_checksum.sh b/generate_checksum.sh index c6f9524b..7fcca708 100755 --- a/generate_checksum.sh +++ b/generate_checksum.sh @@ -3,12 +3,11 @@ cd "$(realpath $(dirname $0))" for coin in monero wownero; do + submodule_hash=$(git ls-tree HEAD ${coin} | xargs | awk '{ print $3 }') COIN=$(echo "$coin" | tr a-z A-Z) COIN_wallet2_api_c_h_sha256=$(sha256sum ${coin}_libwallet2_api_c/src/main/cpp/wallet2_api_c.h | xargs | awk '{ print $1 }') - COIN_wallet2_api_c_cpp_sha256=$(sha256sum ${coin}_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp | xargs | awk '{ print $1 }') + COIN_wallet2_api_c_cpp_sha256=$(sha256sum ${coin}_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp | xargs | awk '{ print $1 }')-${submodule_hash} COIN_wallet2_api_c_exp_sha256=$(sha256sum ${coin}_libwallet2_api_c/${coin}_libwallet2_api_c.exp | xargs | awk '{ print $1 }') - COIN_libwallet2_api_c_version=$(git log --exclude=${coin}_checksum.h --oneline -- ${coin}_libwallet2_api_c | wc -l) - COIN_libwallet2_api_c_date=$(git log --exclude=${coin}_checksum.h -1 --format=%ai -- ${coin}_libwallet2_api_c) cat > ${coin}_libwallet2_api_c/src/main/cpp/${coin}_checksum.h << EOF #ifndef MONEROC_CHECKSUMS diff --git a/impls/monero.dart/lib/src/checksum_monero.dart b/impls/monero.dart/lib/src/checksum_monero.dart index 9e553f94..364e6189 100644 --- a/impls/monero.dart/lib/src/checksum_monero.dart +++ b/impls/monero.dart/lib/src/checksum_monero.dart @@ -1,4 +1,4 @@ // ignore_for_file: constant_identifier_names const String wallet2_api_c_h_sha256 = "e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad"; -const String wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666"; +const String wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666-b089f9ee69924882c5d14dd1a6991deb05d9d1cd"; const String wallet2_api_c_exp_sha256 = "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c"; diff --git a/impls/monero.dart/lib/src/checksum_wownero.dart b/impls/monero.dart/lib/src/checksum_wownero.dart index f4ed1e77..5b71c284 100644 --- a/impls/monero.dart/lib/src/checksum_wownero.dart +++ b/impls/monero.dart/lib/src/checksum_wownero.dart @@ -1,4 +1,4 @@ // ignore_for_file: constant_identifier_names const String wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; -const String wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739"; +const String wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; const String wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; diff --git a/monero b/monero index 81d4db08..b089f9ee 160000 --- a/monero +++ b/monero @@ -1 +1 @@ -Subproject commit 81d4db08eb75ce5392c65ca6571e7b08e41b7c95 +Subproject commit b089f9ee69924882c5d14dd1a6991deb05d9d1cd diff --git a/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h b/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h index 56b583fe..f07cafe3 100644 --- a/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h +++ b/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h @@ -1,6 +1,6 @@ #ifndef MONEROC_CHECKSUMS #define MONEROC_CHECKSUMS const char * MONERO_wallet2_api_c_h_sha256 = "e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad"; -const char * MONERO_wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666"; +const char * MONERO_wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666-b089f9ee69924882c5d14dd1a6991deb05d9d1cd"; const char * MONERO_wallet2_api_c_exp_sha256 = "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c"; #endif diff --git a/patches/monero/0001-polyseed.patch b/patches/monero/0001-polyseed.patch index 2db45e50..81644034 100644 --- a/patches/monero/0001-polyseed.patch +++ b/patches/monero/0001-polyseed.patch @@ -1,18 +1,15 @@ -From b9fac308d903e9dd79b95d6db73c37807e1219b7 Mon Sep 17 00:00:00 2001 +From 8324040dfb89bd90b414ea685b2aa758a461fbc4 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 12 Mar 2024 09:42:37 +0100 -Subject: [PATCH 01/10] polyseed +Subject: [PATCH 01/16] polyseed Co-authored-by: Czarek Nakamoto --- - .github/workflows/build.yml | 4 +- .gitmodules | 6 + CMakeLists.txt | 4 +- contrib/epee/include/wipeable_string.h | 7 + contrib/epee/src/wipeable_string.cpp | 10 ++ external/CMakeLists.txt | 2 + - external/polyseed | 1 + - external/utf8proc | 1 + src/CMakeLists.txt | 1 + src/cryptonote_basic/CMakeLists.txt | 1 + src/cryptonote_basic/account.cpp | 23 +++- @@ -30,30 +27,13 @@ Co-authored-by: Czarek Nakamoto src/wallet/api/wallet_manager.h | 10 ++ src/wallet/wallet2.cpp | 102 ++++++++++++-- src/wallet/wallet2.h | 30 +++- - 25 files changed, 809 insertions(+), 21 deletions(-) - create mode 160000 external/polyseed - create mode 160000 external/utf8proc + 22 files changed, 805 insertions(+), 19 deletions(-) create mode 100644 src/polyseed/CMakeLists.txt create mode 100644 src/polyseed/pbkdf2.c create mode 100644 src/polyseed/pbkdf2.h create mode 100644 src/polyseed/polyseed.cpp create mode 100644 src/polyseed/polyseed.hpp -diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml -index 4c1e381c0..70bea03b3 100644 ---- a/.github/workflows/build.yml -+++ b/.github/workflows/build.yml -@@ -124,8 +124,8 @@ jobs: - - name: build - run: | - ${{env.CCACHE_SETTINGS}} -- cmake . -- make wallet_api -j3 -+ cmake -S . -B build -+ cmake --build build wallet_api -j3 - - test-ubuntu: - needs: build-ubuntu diff --git a/.gitmodules b/.gitmodules index 721cce3b4..73a23fb35 100644 --- a/.gitmodules @@ -148,20 +128,6 @@ index 5b7f69a56..1b9761d70 100644 +add_subdirectory(polyseed EXCLUDE_FROM_ALL) +add_subdirectory(utf8proc EXCLUDE_FROM_ALL) \ No newline at end of file -diff --git a/external/polyseed b/external/polyseed -new file mode 160000 -index 000000000..9d4f1a032 ---- /dev/null -+++ b/external/polyseed -@@ -0,0 +1 @@ -+Subproject commit 9d4f1a032585656e1a642ee70cdf929001badba6 -diff --git a/external/utf8proc b/external/utf8proc -new file mode 160000 -index 000000000..1cb28a66c ---- /dev/null -+++ b/external/utf8proc -@@ -0,0 +1 @@ -+Subproject commit 1cb28a66ca79a0845e99433fd1056257456cef8b diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3335d3c21..06b708cf0 100644 --- a/src/CMakeLists.txt @@ -468,7 +434,7 @@ index 000000000..f6253b9d7 \ No newline at end of file diff --git a/src/polyseed/polyseed.cpp b/src/polyseed/polyseed.cpp new file mode 100644 -index 000000000..0a8852777 +index 000000000..231a48a94 --- /dev/null +++ b/src/polyseed/polyseed.cpp @@ -0,0 +1,182 @@ @@ -520,7 +486,7 @@ index 000000000..0a8852777 + if (result < 0 || result > (POLYSEED_STR_SIZE - 1)) { + throw std::runtime_error("Unicode normalization failed"); + } -+ ++ + result = utf8proc_reencode(buffer, result, options); + if (result < 0 || result > POLYSEED_STR_SIZE) { + throw std::runtime_error("Unicode normalization failed"); @@ -829,7 +795,7 @@ index 000000000..2c8c777a7 +#endif //POLYSEED_HPP \ No newline at end of file diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 8d7364cba..472f05016 100644 +index fc4f89128..d96ea97ea 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -690,6 +690,28 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p @@ -876,7 +842,7 @@ index 8d7364cba..472f05016 100644 + } + + bool result = m_wallet->get_polyseed(seed_words_epee, passphrase_epee); -+ ++ + seed_words.assign(seed_words_epee.data(), seed_words_epee.size()); + passphrase.assign(passphrase_epee.data(), passphrase_epee.size()); + @@ -898,7 +864,7 @@ index 8d7364cba..472f05016 100644 +bool Wallet::createPolyseed(std::string &seed_words, std::string &err, const std::string &language) +{ + epee::wipeable_string seed_words_epee(seed_words.c_str(), seed_words.size()); -+ ++ + try { + polyseed::data polyseed(POLYSEED_COIN); + polyseed.create(0); @@ -1026,7 +992,7 @@ index a223e1df9..28fcd36c9 100644 bool walletExists(const std::string &path) override; bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index f34b10988..e4e02c782 100644 +index 64f486e71..9e95f44d6 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -92,6 +92,7 @@ using namespace epee; @@ -1074,7 +1040,7 @@ index f34b10988..e4e02c782 100644 return true; } //---------------------------------------------------------------------------------------------------- -@@ -4629,6 +4646,9 @@ boost::optional wallet2::get_keys_file_data(const epee: +@@ -4630,6 +4647,9 @@ boost::optional wallet2::get_keys_file_data(const epee: value2.SetInt(m_enable_multisig ? 1 : 0); json.AddMember("enable_multisig", value2, json.GetAllocator()); @@ -1084,7 +1050,7 @@ index f34b10988..e4e02c782 100644 // Serialize the JSON object rapidjson::StringBuffer buffer; rapidjson::Writer writer(buffer); -@@ -4776,6 +4796,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -4777,6 +4797,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_credits_target = 0; m_enable_multisig = false; m_allow_mismatched_daemon_version = false; @@ -1092,7 +1058,7 @@ index f34b10988..e4e02c782 100644 } else if(json.IsObject()) { -@@ -5012,6 +5033,8 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -5013,6 +5034,8 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_credits_target = field_credits_target; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, enable_multisig, int, Int, false, false); m_enable_multisig = field_enable_multisig; @@ -1101,7 +1067,7 @@ index f34b10988..e4e02c782 100644 } else { -@@ -5284,6 +5307,48 @@ void wallet2::init_type(hw::device::device_type device_type) +@@ -5285,6 +5308,48 @@ void wallet2::init_type(hw::device::device_type device_type) m_key_device_type = device_type; } @@ -1150,7 +1116,7 @@ index f34b10988..e4e02c782 100644 /*! * \brief Generates a wallet or restores one. Assumes the multisig setup * has already completed for the provided multisig info. -@@ -5411,7 +5476,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip +@@ -5412,7 +5477,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip return retval; } @@ -1159,7 +1125,7 @@ index f34b10988..e4e02c782 100644 { // -1 month for fluctuations in block time and machine date/time setup. // avg seconds per block -@@ -5435,7 +5500,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip +@@ -5436,7 +5501,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip // the daemon is currently syncing. // If we use the approximate height we subtract one month as // a safety margin. @@ -1168,7 +1134,7 @@ index f34b10988..e4e02c782 100644 uint64_t target_height = get_daemon_blockchain_target_height(err); if (err.empty()) { if (target_height < height) -@@ -13135,7 +13200,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err) +@@ -13133,7 +13198,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err) return target_height; } @@ -1177,16 +1143,16 @@ index f34b10988..e4e02c782 100644 { // time of v2 fork const time_t fork_time = m_nettype == TESTNET ? 1448285909 : m_nettype == STAGENET ? 1520937818 : 1458748658; -@@ -13144,7 +13209,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const +@@ -13142,7 +13207,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const // avg seconds per block const int seconds_per_block = DIFFICULTY_TARGET_V2; // Calculated blockchain height - uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block; + uint64_t approx_blockchain_height = fork_block + ((t > 0 ? t : time(NULL)) - fork_time)/seconds_per_block; // testnet and stagenet got some huge rollbacks, so the estimation is way off - static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : 30000; + static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : m_nettype == STAGENET ? 60000 : 30000; if ((m_nettype == TESTNET || m_nettype == STAGENET) && approx_blockchain_height > approximate_rolled_back_blocks) -@@ -14862,15 +14927,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin +@@ -14860,15 +14925,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin //---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, uint8_t day) { @@ -1202,7 +1168,7 @@ index f34b10988..e4e02c782 100644 std::tm date = { 0, 0, 0, 0, 0, 0, 0, 0 }; date.tm_year = year - 1900; date.tm_mon = month - 1; -@@ -14879,7 +14935,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui +@@ -14877,7 +14933,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui { throw std::runtime_error("month or day out of range"); } @@ -1227,7 +1193,7 @@ index f34b10988..e4e02c782 100644 uint64_t height_min = 0; uint64_t height_max = get_daemon_blockchain_height(err) - 1; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 3144a8fd3..b540eff6b 100644 +index c38d77675..91ec72e0f 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -72,6 +72,7 @@ @@ -1303,5 +1269,5 @@ index 3144a8fd3..b540eff6b 100644 uint32_t m_multisig_threshold; std::vector m_multisig_signers; -- -2.44.0 +2.39.2 diff --git a/patches/monero/0002-wallet-background-sync-with-just-the-view-key.patch b/patches/monero/0002-wallet-background-sync-with-just-the-view-key.patch index f5d87b65..16fe77fc 100644 --- a/patches/monero/0002-wallet-background-sync-with-just-the-view-key.patch +++ b/patches/monero/0002-wallet-background-sync-with-just-the-view-key.patch @@ -1,7 +1,7 @@ -From f1cf1d2378a5bb6313eef9a58325b03cb4ac0f85 Mon Sep 17 00:00:00 2001 +From 56fed429a25773c760b8490b3e0fb908c832e6e5 Mon Sep 17 00:00:00 2001 From: j-berman Date: Thu, 13 Oct 2022 18:33:33 -0700 -Subject: [PATCH 02/10] wallet: background sync with just the view key +Subject: [PATCH 02/16] wallet: background sync with just the view key - When background syncing, the wallet wipes the spend key from memory and processes all new transactions. The wallet saves @@ -30,7 +30,7 @@ cache. src/cryptonote_basic/account.cpp | 11 + src/cryptonote_basic/account.h | 1 + src/cryptonote_config.h | 2 + - src/simplewallet/simplewallet.cpp | 205 +++- + src/simplewallet/simplewallet.cpp | 203 +++- src/simplewallet/simplewallet.h | 1 + src/wallet/api/wallet.cpp | 213 +++- src/wallet/api/wallet.h | 12 + @@ -47,7 +47,7 @@ cache. tests/functional_tests/wallet.py | 43 +- tests/unit_tests/wipeable_string.cpp | 12 + utils/python-rpc/framework/wallet.py | 42 + - 20 files changed, 2337 insertions(+), 130 deletions(-) + 20 files changed, 2335 insertions(+), 130 deletions(-) diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index 4931c3740..2d556f285 100644 @@ -97,7 +97,7 @@ index 8e1a07110..3af3a63a1 100644 const unsigned char HASH_KEY_MEMORY = 'k'; const unsigned char HASH_KEY_MULTISIG[] = {'M', 'u', 'l', 't' , 'i', 's', 'i', 'g', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp -index f2eaf6b13..341b0e448 100644 +index b9e30f9d9..f8ed6659c 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -155,6 +155,17 @@ typedef cryptonote::simple_wallet sw; @@ -115,10 +115,10 @@ index f2eaf6b13..341b0e448 100644 + } \ + } while (0) + - enum TransferType { - Transfer, - TransferLocked, -@@ -332,7 +343,7 @@ namespace + static std::string get_human_readable_timespan(std::chrono::seconds seconds); + static std::string get_human_readable_timespan(uint64_t seconds); + +@@ -325,7 +336,7 @@ namespace auto pwd_container = tools::password_container::prompt(verify, prompt); if (!pwd_container) { @@ -127,7 +127,7 @@ index f2eaf6b13..341b0e448 100644 } return pwd_container; } -@@ -342,6 +353,11 @@ namespace +@@ -335,6 +346,11 @@ namespace return password_prompter(verify ? sw::tr("Enter a new password for the wallet") : sw::tr("Wallet password"), verify); } @@ -139,7 +139,7 @@ index f2eaf6b13..341b0e448 100644 inline std::string interpret_rpc_response(bool ok, const std::string& status) { std::string err; -@@ -459,6 +475,41 @@ namespace +@@ -452,6 +468,41 @@ namespace return "invalid"; } @@ -181,7 +181,7 @@ index f2eaf6b13..341b0e448 100644 std::string get_version_string(uint32_t version) { return boost::lexical_cast(version >> 16) + "." + boost::lexical_cast(version & 0xffff); -@@ -812,6 +863,7 @@ bool simple_wallet::spendkey(const std::vector &args/* = std::vecto +@@ -805,6 +856,7 @@ bool simple_wallet::spendkey(const std::vector &args/* = std::vecto fail_msg_writer() << tr("wallet is watch-only and has no spend key"); return true; } @@ -189,7 +189,7 @@ index f2eaf6b13..341b0e448 100644 // don't log PAUSE_READLINE(); if (m_wallet->key_on_device()) { -@@ -843,6 +895,7 @@ bool simple_wallet::print_seed(bool encrypted) +@@ -836,6 +888,7 @@ bool simple_wallet::print_seed(bool encrypted) fail_msg_writer() << tr("wallet is watch-only and has no seed"); return true; } @@ -197,7 +197,7 @@ index f2eaf6b13..341b0e448 100644 multisig = m_wallet->multisig(&ready); if (multisig) -@@ -920,6 +973,7 @@ bool simple_wallet::seed_set_language(const std::vector &args/* = s +@@ -913,6 +966,7 @@ bool simple_wallet::seed_set_language(const std::vector &args/* = s fail_msg_writer() << tr("wallet is watch-only and has no seed"); return true; } @@ -205,7 +205,7 @@ index f2eaf6b13..341b0e448 100644 epee::wipeable_string password; { -@@ -1066,6 +1120,7 @@ bool simple_wallet::prepare_multisig_main(const std::vector &args, +@@ -1059,6 +1113,7 @@ bool simple_wallet::prepare_multisig_main(const std::vector &args, fail_msg_writer() << tr("wallet is watch-only and cannot be made multisig"); return false; } @@ -213,7 +213,7 @@ index f2eaf6b13..341b0e448 100644 if(m_wallet->get_num_transfer_details()) { -@@ -2202,6 +2257,7 @@ bool simple_wallet::save_known_rings(const std::vector &args) +@@ -2195,6 +2250,7 @@ bool simple_wallet::save_known_rings(const std::vector &args) bool simple_wallet::freeze_thaw(const std::vector &args, bool freeze) { @@ -221,7 +221,7 @@ index f2eaf6b13..341b0e448 100644 if (args.empty()) { fail_msg_writer() << boost::format(tr("usage: %s |")) % (freeze ? "freeze" : "thaw"); -@@ -2241,6 +2297,7 @@ bool simple_wallet::thaw(const std::vector &args) +@@ -2234,6 +2290,7 @@ bool simple_wallet::thaw(const std::vector &args) bool simple_wallet::frozen(const std::vector &args) { @@ -229,7 +229,7 @@ index f2eaf6b13..341b0e448 100644 if (args.empty()) { size_t ntd = m_wallet->get_num_transfer_details(); -@@ -3012,6 +3069,56 @@ bool simple_wallet::set_track_uses(const std::vector &args/* = std: +@@ -3005,6 +3062,56 @@ bool simple_wallet::set_track_uses(const std::vector &args/* = std: return true; } @@ -286,7 +286,7 @@ index f2eaf6b13..341b0e448 100644 bool simple_wallet::set_show_wallet_name_when_locked(const std::vector &args/* = std::vector()*/) { const auto pwd_container = get_and_verify_password(); -@@ -3244,6 +3351,7 @@ bool simple_wallet::apropos(const std::vector &args) +@@ -3237,6 +3344,7 @@ bool simple_wallet::apropos(const std::vector &args) bool simple_wallet::scan_tx(const std::vector &args) { @@ -294,7 +294,7 @@ index f2eaf6b13..341b0e448 100644 if (args.empty()) { PRINT_USAGE(USAGE_SCAN_TX); -@@ -3473,6 +3581,8 @@ simple_wallet::simple_wallet() +@@ -3458,6 +3566,8 @@ simple_wallet::simple_wallet() " Ignore outputs of amount below this threshold when spending.\n " "track-uses <1|0>\n " " Whether to keep track of owned outputs uses.\n " @@ -303,7 +303,7 @@ index f2eaf6b13..341b0e448 100644 "setup-background-mining <1|0>\n " " Whether to enable background mining. Set this to support the network and to get a chance to receive new monero.\n " "device-name \n " -@@ -3891,6 +4001,7 @@ bool simple_wallet::set_variable(const std::vector &args) +@@ -3876,6 +3986,7 @@ bool simple_wallet::set_variable(const std::vector &args) success_msg_writer() << "ignore-outputs-above = " << cryptonote::print_money(m_wallet->ignore_outputs_above()); success_msg_writer() << "ignore-outputs-below = " << cryptonote::print_money(m_wallet->ignore_outputs_below()); success_msg_writer() << "track-uses = " << m_wallet->track_uses(); @@ -311,7 +311,7 @@ index f2eaf6b13..341b0e448 100644 success_msg_writer() << "setup-background-mining = " << setup_background_mining_string; success_msg_writer() << "device-name = " << m_wallet->device_name(); success_msg_writer() << "export-format = " << (m_wallet->export_format() == tools::wallet2::ExportFormat::Ascii ? "ascii" : "binary"); -@@ -3909,6 +4020,7 @@ bool simple_wallet::set_variable(const std::vector &args) +@@ -3894,6 +4005,7 @@ bool simple_wallet::set_variable(const std::vector &args) } else { @@ -319,7 +319,7 @@ index f2eaf6b13..341b0e448 100644 #define CHECK_SIMPLE_VARIABLE(name, f, help) do \ if (args[0] == name) { \ -@@ -3962,6 +4074,7 @@ bool simple_wallet::set_variable(const std::vector &args) +@@ -3947,6 +4059,7 @@ bool simple_wallet::set_variable(const std::vector &args) CHECK_SIMPLE_VARIABLE("ignore-outputs-above", set_ignore_outputs_above, tr("amount")); CHECK_SIMPLE_VARIABLE("ignore-outputs-below", set_ignore_outputs_below, tr("amount")); CHECK_SIMPLE_VARIABLE("track-uses", set_track_uses, tr("0 or 1")); @@ -327,7 +327,7 @@ index f2eaf6b13..341b0e448 100644 CHECK_SIMPLE_VARIABLE("show-wallet-name-when-locked", set_show_wallet_name_when_locked, tr("1 or 0")); CHECK_SIMPLE_VARIABLE("inactivity-lock-timeout", set_inactivity_lock_timeout, tr("unsigned integer (seconds, 0 to disable)")); CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no")); -@@ -4915,7 +5028,10 @@ std::string simple_wallet::get_mnemonic_language() +@@ -4900,7 +5013,10 @@ std::string simple_wallet::get_mnemonic_language() //---------------------------------------------------------------------------------------------------- boost::optional simple_wallet::get_and_verify_password() const { @@ -339,7 +339,7 @@ index f2eaf6b13..341b0e448 100644 if (!pwd_container) return boost::none; -@@ -5218,6 +5334,8 @@ boost::optional simple_wallet::open_wallet(const boost::p +@@ -5203,6 +5319,8 @@ boost::optional simple_wallet::open_wallet(const boost::p prefix = tr("Opened watch-only wallet"); else if (m_wallet->multisig(&ready, &threshold, &total)) prefix = (boost::format(tr("Opened %u/%u multisig wallet%s")) % threshold % total % (ready ? "" : " (not yet finalized)")).str(); @@ -348,7 +348,7 @@ index f2eaf6b13..341b0e448 100644 else prefix = tr("Opened wallet"); message_writer(console_color_white, true) << -@@ -5426,6 +5544,10 @@ void simple_wallet::stop_background_mining() +@@ -5411,6 +5529,10 @@ void simple_wallet::stop_background_mining() //---------------------------------------------------------------------------------------------------- void simple_wallet::check_background_mining(const epee::wipeable_string &password) { @@ -359,7 +359,7 @@ index f2eaf6b13..341b0e448 100644 tools::wallet2::BackgroundMiningSetupType setup = m_wallet->setup_background_mining(); if (setup == tools::wallet2::BackgroundMiningNo) { -@@ -6290,6 +6412,7 @@ bool simple_wallet::show_blockchain_height(const std::vector& args) +@@ -6275,6 +6397,7 @@ bool simple_wallet::show_blockchain_height(const std::vector& args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::rescan_spent(const std::vector &args) { @@ -367,7 +367,7 @@ index f2eaf6b13..341b0e448 100644 if (!m_wallet->is_trusted_daemon()) { fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon"); -@@ -6547,10 +6670,27 @@ void simple_wallet::check_for_inactivity_lock(bool user) +@@ -6532,10 +6655,27 @@ void simple_wallet::check_for_inactivity_lock(bool user) " || ||" << std::endl << "" << std::endl; } @@ -396,7 +396,7 @@ index f2eaf6b13..341b0e448 100644 const bool show_wallet_name = m_wallet->show_wallet_name_when_locked(); if (show_wallet_name) -@@ -6563,8 +6703,16 @@ void simple_wallet::check_for_inactivity_lock(bool user) +@@ -6548,8 +6688,16 @@ void simple_wallet::check_for_inactivity_lock(bool user) } try { @@ -414,15 +414,15 @@ index f2eaf6b13..341b0e448 100644 } catch (...) { /* do nothing, just let the loop loop */ } } -@@ -6591,6 +6739,7 @@ bool simple_wallet::on_command(bool (simple_wallet::*cmd)(const std::vector &args_, bool called_by_mms) +@@ -6576,6 +6724,7 @@ bool simple_wallet::on_command(bool (simple_wallet::*cmd)(const std::vector &args_, bool called_by_mms) { // "transfer [index=[,,...]] [] []
[]" + CHECK_IF_BACKGROUND_SYNCING("cannot transfer"); if (!try_connect_to_daemon()) return false; -@@ -7064,6 +7213,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector &args_, bool ca //---------------------------------------------------------------------------------------------------- bool simple_wallet::transfer(const std::vector &args_) { @@ -430,23 +430,7 @@ index f2eaf6b13..341b0e448 100644 if (args_.size() < 1) { PRINT_USAGE(USAGE_TRANSFER); -@@ -7075,6 +7225,7 @@ bool simple_wallet::transfer(const std::vector &args_) - //---------------------------------------------------------------------------------------------------- - bool simple_wallet::locked_transfer(const std::vector &args_) - { -+ CHECK_IF_BACKGROUND_SYNCING("cannot transfer"); - if (args_.size() < 1) - { - PRINT_USAGE(USAGE_LOCKED_TRANSFER); -@@ -7086,6 +7237,7 @@ bool simple_wallet::locked_transfer(const std::vector &args_) - //---------------------------------------------------------------------------------------------------- - bool simple_wallet::locked_sweep_all(const std::vector &args_) - { -+ CHECK_IF_BACKGROUND_SYNCING("cannot sweep"); - if (args_.size() < 1) - { - PRINT_USAGE(USAGE_LOCKED_SWEEP_ALL); -@@ -7098,6 +7250,7 @@ bool simple_wallet::locked_sweep_all(const std::vector &args_) +@@ -7016,6 +7166,7 @@ bool simple_wallet::transfer(const std::vector &args_) bool simple_wallet::sweep_unmixable(const std::vector &args_) { @@ -454,15 +438,15 @@ index f2eaf6b13..341b0e448 100644 if (!try_connect_to_daemon()) return true; -@@ -7205,6 +7358,7 @@ bool simple_wallet::sweep_unmixable(const std::vector &args_) +@@ -7123,6 +7274,7 @@ bool simple_wallet::sweep_unmixable(const std::vector &args_) //---------------------------------------------------------------------------------------------------- - bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector &args_) + bool simple_wallet::sweep_main(uint32_t account, uint64_t below, const std::vector &args_) { + CHECK_IF_BACKGROUND_SYNCING("cannot sweep"); auto print_usage = [this, account, below]() { if (below) -@@ -7521,6 +7675,7 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co +@@ -7404,6 +7556,7 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, const std::vect //---------------------------------------------------------------------------------------------------- bool simple_wallet::sweep_single(const std::vector &args_) { @@ -470,12 +454,12 @@ index f2eaf6b13..341b0e448 100644 if (!try_connect_to_daemon()) return true; -@@ -7759,12 +7914,14 @@ bool simple_wallet::sweep_single(const std::vector &args_) +@@ -7642,12 +7795,14 @@ bool simple_wallet::sweep_single(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::sweep_all(const std::vector &args_) { + CHECK_IF_BACKGROUND_SYNCING("cannot sweep"); - sweep_main(m_current_subaddress_account, 0, false, args_); + sweep_main(m_current_subaddress_account, 0, args_); return true; } //---------------------------------------------------------------------------------------------------- @@ -485,7 +469,7 @@ index f2eaf6b13..341b0e448 100644 auto local_args = args_; if (local_args.empty()) { -@@ -7785,6 +7942,7 @@ bool simple_wallet::sweep_account(const std::vector &args_) +@@ -7668,6 +7823,7 @@ bool simple_wallet::sweep_account(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::sweep_below(const std::vector &args_) { @@ -493,7 +477,7 @@ index f2eaf6b13..341b0e448 100644 uint64_t below = 0; if (args_.size() < 1) { -@@ -7803,6 +7961,7 @@ bool simple_wallet::sweep_below(const std::vector &args_) +@@ -7686,6 +7842,7 @@ bool simple_wallet::sweep_below(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::donate(const std::vector &args_) { @@ -501,7 +485,7 @@ index f2eaf6b13..341b0e448 100644 std::vector local_args = args_; if(local_args.empty() || local_args.size() > 5) { -@@ -7864,6 +8023,7 @@ bool simple_wallet::donate(const std::vector &args_) +@@ -7747,6 +7904,7 @@ bool simple_wallet::donate(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, const std::function &get_tx, const std::string &extra_message) { @@ -509,7 +493,7 @@ index f2eaf6b13..341b0e448 100644 // gather info to ask the user uint64_t amount = 0, amount_to_dests = 0, change = 0; size_t min_ring_size = ~0; -@@ -8044,6 +8204,7 @@ bool simple_wallet::sign_transfer(const std::vector &args_) +@@ -7927,6 +8085,7 @@ bool simple_wallet::sign_transfer(const std::vector &args_) fail_msg_writer() << tr("This is a watch only wallet"); return true; } @@ -517,7 +501,7 @@ index f2eaf6b13..341b0e448 100644 bool export_raw = false; std::string unsigned_filename = "unsigned_monero_tx"; -@@ -8151,6 +8312,8 @@ std::string get_tx_key_stream(crypto::secret_key tx_key, std::vector &args_) { @@ -526,7 +510,7 @@ index f2eaf6b13..341b0e448 100644 std::vector local_args = args_; if (m_wallet->key_on_device() && m_wallet->get_account().get_device().get_type() != hw::device::TREZOR) -@@ -8191,6 +8354,8 @@ bool simple_wallet::get_tx_key(const std::vector &args_) +@@ -8074,6 +8235,8 @@ bool simple_wallet::get_tx_key(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::set_tx_key(const std::vector &args_) { @@ -535,7 +519,7 @@ index f2eaf6b13..341b0e448 100644 std::vector local_args = args_; if(local_args.size() != 2 && local_args.size() != 3) { -@@ -8267,6 +8432,8 @@ bool simple_wallet::set_tx_key(const std::vector &args_) +@@ -8150,6 +8313,8 @@ bool simple_wallet::set_tx_key(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_tx_proof(const std::vector &args) { @@ -544,7 +528,7 @@ index f2eaf6b13..341b0e448 100644 if (args.size() != 2 && args.size() != 3) { PRINT_USAGE(USAGE_GET_TX_PROOF); -@@ -8473,6 +8640,7 @@ bool simple_wallet::check_tx_proof(const std::vector &args) +@@ -8356,6 +8521,7 @@ bool simple_wallet::check_tx_proof(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_spend_proof(const std::vector &args) { @@ -552,7 +536,7 @@ index f2eaf6b13..341b0e448 100644 if (m_wallet->key_on_device()) { fail_msg_writer() << tr("command not supported by HW wallet"); -@@ -8557,6 +8725,7 @@ bool simple_wallet::check_spend_proof(const std::vector &args) +@@ -8440,6 +8606,7 @@ bool simple_wallet::check_spend_proof(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_reserve_proof(const std::vector &args) { @@ -560,7 +544,7 @@ index f2eaf6b13..341b0e448 100644 if (m_wallet->key_on_device()) { fail_msg_writer() << tr("command not supported by HW wallet"); -@@ -9243,6 +9412,8 @@ bool simple_wallet::unspent_outputs(const std::vector &args_) +@@ -9126,6 +9293,8 @@ bool simple_wallet::unspent_outputs(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::rescan_blockchain(const std::vector &args_) { @@ -569,7 +553,7 @@ index f2eaf6b13..341b0e448 100644 uint64_t start_height = 0; ResetType reset_type = ResetSoft; -@@ -9540,6 +9711,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector +@@ -9423,6 +9592,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector if (command == "new") { // create a new account and switch to it @@ -577,7 +561,7 @@ index f2eaf6b13..341b0e448 100644 std::string label = boost::join(local_args, " "); if (label.empty()) label = tr("(Untitled account)"); -@@ -9570,6 +9742,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector +@@ -9453,6 +9623,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector else if (command == "label" && local_args.size() >= 1) { // set label of the specified account @@ -585,7 +569,7 @@ index f2eaf6b13..341b0e448 100644 uint32_t index_major; if (!epee::string_tools::get_xtype_from_string(index_major, local_args[0])) { -@@ -9591,6 +9764,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector +@@ -9474,6 +9645,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector } else if (command == "tag" && local_args.size() >= 2) { @@ -593,7 +577,7 @@ index f2eaf6b13..341b0e448 100644 const std::string tag = local_args[0]; std::set account_indices; for (size_t i = 1; i < local_args.size(); ++i) -@@ -9615,6 +9789,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector +@@ -9498,6 +9670,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector } else if (command == "untag" && local_args.size() >= 1) { @@ -601,7 +585,7 @@ index f2eaf6b13..341b0e448 100644 std::set account_indices; for (size_t i = 0; i < local_args.size(); ++i) { -@@ -9638,6 +9813,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector +@@ -9521,6 +9694,7 @@ bool simple_wallet::account(const std::vector &args/* = std::vector } else if (command == "tag_description" && local_args.size() >= 1) { @@ -609,7 +593,7 @@ index f2eaf6b13..341b0e448 100644 const std::string tag = local_args[0]; std::string description; if (local_args.size() > 1) -@@ -9755,6 +9931,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: +@@ -9638,6 +9812,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: } else if (local_args[0] == "new") { @@ -617,7 +601,7 @@ index f2eaf6b13..341b0e448 100644 local_args.erase(local_args.begin()); std::string label; if (local_args.size() > 0) -@@ -9767,6 +9944,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: +@@ -9650,6 +9825,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: } else if (local_args[0] == "mnew") { @@ -625,7 +609,7 @@ index f2eaf6b13..341b0e448 100644 local_args.erase(local_args.begin()); if (local_args.size() != 1) { -@@ -9792,6 +9970,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: +@@ -9675,6 +9851,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: } else if (local_args[0] == "one-off") { @@ -633,7 +617,7 @@ index f2eaf6b13..341b0e448 100644 local_args.erase(local_args.begin()); std::string label; if (local_args.size() != 2) -@@ -9810,6 +9989,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: +@@ -9693,6 +9870,7 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: } else if (local_args.size() >= 2 && local_args[0] == "label") { @@ -641,7 +625,7 @@ index f2eaf6b13..341b0e448 100644 if (!epee::string_tools::get_xtype_from_string(index, local_args[1])) { fail_msg_writer() << tr("failed to parse index: ") << local_args[1]; -@@ -9956,6 +10136,8 @@ bool simple_wallet::print_integrated_address(const std::vector &arg +@@ -9839,6 +10017,8 @@ bool simple_wallet::print_integrated_address(const std::vector &arg //---------------------------------------------------------------------------------------------------- bool simple_wallet::address_book(const std::vector &args/* = std::vector()*/) { @@ -650,7 +634,7 @@ index f2eaf6b13..341b0e448 100644 if (args.size() == 0) { } -@@ -10016,6 +10198,8 @@ bool simple_wallet::address_book(const std::vector &args/* = std::v +@@ -9899,6 +10079,8 @@ bool simple_wallet::address_book(const std::vector &args/* = std::v //---------------------------------------------------------------------------------------------------- bool simple_wallet::set_tx_note(const std::vector &args) { @@ -659,7 +643,7 @@ index f2eaf6b13..341b0e448 100644 if (args.size() == 0) { PRINT_USAGE(USAGE_SET_TX_NOTE); -@@ -10044,6 +10228,8 @@ bool simple_wallet::set_tx_note(const std::vector &args) +@@ -9927,6 +10109,8 @@ bool simple_wallet::set_tx_note(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_tx_note(const std::vector &args) { @@ -668,7 +652,7 @@ index f2eaf6b13..341b0e448 100644 if (args.size() != 1) { PRINT_USAGE(USAGE_GET_TX_NOTE); -@@ -10069,6 +10255,8 @@ bool simple_wallet::get_tx_note(const std::vector &args) +@@ -9952,6 +10136,8 @@ bool simple_wallet::get_tx_note(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::set_description(const std::vector &args) { @@ -677,7 +661,7 @@ index f2eaf6b13..341b0e448 100644 // 0 arguments allowed, for setting the description to empty string std::string description = ""; -@@ -10085,6 +10273,8 @@ bool simple_wallet::set_description(const std::vector &args) +@@ -9968,6 +10154,8 @@ bool simple_wallet::set_description(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_description(const std::vector &args) { @@ -686,7 +670,7 @@ index f2eaf6b13..341b0e448 100644 if (args.size() != 0) { PRINT_USAGE(USAGE_GET_DESCRIPTION); -@@ -10143,6 +10333,8 @@ bool simple_wallet::wallet_info(const std::vector &args) +@@ -10026,6 +10214,8 @@ bool simple_wallet::wallet_info(const std::vector &args) type = tr("Watch only"); else if (m_wallet->multisig(&ready, &threshold, &total)) type = (boost::format(tr("%u/%u multisig%s")) % threshold % total % (ready ? "" : " (not yet finalized)")).str(); @@ -695,7 +679,7 @@ index f2eaf6b13..341b0e448 100644 else type = tr("Normal"); message_writer() << tr("Type: ") << type; -@@ -10154,6 +10346,7 @@ bool simple_wallet::wallet_info(const std::vector &args) +@@ -10037,6 +10227,7 @@ bool simple_wallet::wallet_info(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::sign(const std::vector &args) { @@ -703,7 +687,7 @@ index f2eaf6b13..341b0e448 100644 if (m_wallet->key_on_device()) { fail_msg_writer() << tr("command not supported by HW wallet"); -@@ -10261,6 +10454,7 @@ bool simple_wallet::export_key_images(const std::vector &args_) +@@ -10144,6 +10335,7 @@ bool simple_wallet::export_key_images(const std::vector &args_) fail_msg_writer() << tr("command not supported by HW wallet"); return true; } @@ -711,7 +695,7 @@ index f2eaf6b13..341b0e448 100644 auto args = args_; if (m_wallet->watch_only()) -@@ -10314,6 +10508,7 @@ bool simple_wallet::import_key_images(const std::vector &args) +@@ -10197,6 +10389,7 @@ bool simple_wallet::import_key_images(const std::vector &args) fail_msg_writer() << tr("command not supported by HW wallet"); return true; } @@ -719,7 +703,7 @@ index f2eaf6b13..341b0e448 100644 if (!m_wallet->is_trusted_daemon()) { fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon"); -@@ -10422,6 +10617,7 @@ bool simple_wallet::export_outputs(const std::vector &args_) +@@ -10305,6 +10498,7 @@ bool simple_wallet::export_outputs(const std::vector &args_) fail_msg_writer() << tr("command not supported by HW wallet"); return true; } @@ -727,7 +711,7 @@ index f2eaf6b13..341b0e448 100644 auto args = args_; bool all = false; -@@ -10471,6 +10667,7 @@ bool simple_wallet::import_outputs(const std::vector &args) +@@ -10354,6 +10548,7 @@ bool simple_wallet::import_outputs(const std::vector &args) fail_msg_writer() << tr("command not supported by HW wallet"); return true; } @@ -736,7 +720,7 @@ index f2eaf6b13..341b0e448 100644 { PRINT_USAGE(USAGE_IMPORT_OUTPUTS); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h -index 7c45d45e8..79c739cdd 100644 +index 652708f5a..159da2c45 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -147,6 +147,7 @@ namespace cryptonote @@ -748,7 +732,7 @@ index 7c45d45e8..79c739cdd 100644 bool set_inactivity_lock_timeout(const std::vector &args = std::vector()); bool set_setup_background_mining(const std::vector &args = std::vector()); diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 472f05016..1a9c6f674 100644 +index d96ea97ea..7d430b655 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -54,6 +54,40 @@ using namespace cryptonote; @@ -1310,7 +1294,7 @@ index 9ea753083..4268b656e 100644 virtual AddressBook * addressBook() = 0; virtual Subaddress * subaddress() = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index e4e02c782..c7cbdbbe6 100644 +index 9e95f44d6..f2381740a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -158,6 +158,8 @@ static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1"; @@ -1537,7 +1521,7 @@ index e4e02c782..c7cbdbbe6 100644 bool updated = false; if (m_pool_info_query_time != 0 && try_incremental) { -@@ -4182,6 +4263,8 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo +@@ -4183,6 +4264,8 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo } m_first_refresh_done = true; @@ -1546,7 +1530,7 @@ index e4e02c782..c7cbdbbe6 100644 LOG_PRINT_L1("Refresh done, blocks received: " << blocks_fetched << ", balance (all accounts): " << print_money(balance_all(false)) << ", unlocked: " << print_money(unlocked_balance_all(false))); } -@@ -4267,6 +4350,14 @@ wallet2::detached_blockchain_data wallet2::detach_blockchain(uint64_t height, st +@@ -4268,6 +4351,14 @@ wallet2::detached_blockchain_data wallet2::detach_blockchain(uint64_t height, st td.m_uses.pop_back(); } @@ -1561,7 +1545,7 @@ index e4e02c782..c7cbdbbe6 100644 if (output_tracker_cache) output_tracker_cache->clear(); -@@ -4341,8 +4432,12 @@ void wallet2::handle_reorg(uint64_t height, std::map m_blockchain.offset(), error::wallet_internal_error, "Daemon claims reorg below last checkpoint"); @@ -1574,7 +1558,7 @@ index e4e02c782..c7cbdbbe6 100644 if (m_callback) m_callback->on_reorg(height, dbd.detached_blockchain.size(), dbd.detached_tx_hashes.size()); } -@@ -4352,6 +4447,7 @@ bool wallet2::deinit() +@@ -4353,6 +4448,7 @@ bool wallet2::deinit() if(m_is_initialized) { m_is_initialized = false; unlock_keys_file(); @@ -1582,7 +1566,7 @@ index e4e02c782..c7cbdbbe6 100644 m_account.deinit(); } return true; -@@ -4378,6 +4474,7 @@ bool wallet2::clear() +@@ -4379,6 +4475,7 @@ bool wallet2::clear() m_device_last_key_image_sync = 0; m_pool_info_query_time = 0; m_skip_to_height = 0; @@ -1590,7 +1574,7 @@ index e4e02c782..c7cbdbbe6 100644 return true; } //---------------------------------------------------------------------------------------------------- -@@ -4396,13 +4493,30 @@ void wallet2::clear_soft(bool keep_key_images) +@@ -4397,13 +4494,30 @@ void wallet2::clear_soft(bool keep_key_images) m_scanned_pool_txs[1].clear(); m_pool_info_query_time = 0; m_skip_to_height = 0; @@ -1622,7 +1606,7 @@ index e4e02c782..c7cbdbbe6 100644 /*! * \brief Stores wallet information to wallet file. * \param keys_file_name Name of wallet file -@@ -4414,16 +4528,35 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable +@@ -4415,16 +4529,35 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable { boost::optional keys_file_data = get_keys_file_data(password, watch_only); CHECK_AND_ASSERT_MES(keys_file_data != boost::none, false, "failed to generate wallet keys data"); @@ -1662,7 +1646,7 @@ index e4e02c782..c7cbdbbe6 100644 if (e) { boost::filesystem::remove(tmp_file_name); -@@ -4435,26 +4568,27 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable +@@ -4436,26 +4569,27 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable } //---------------------------------------------------------------------------------------------------- boost::optional wallet2::get_keys_file_data(const epee::wipeable_string& password, bool watch_only) @@ -1698,7 +1682,7 @@ index e4e02c782..c7cbdbbe6 100644 account.forget_spend_key(); account.encrypt_keys(key); -@@ -4589,6 +4723,9 @@ boost::optional wallet2::get_keys_file_data(const epee: +@@ -4590,6 +4724,9 @@ boost::optional wallet2::get_keys_file_data(const epee: value2.SetInt(m_track_uses ? 1 : 0); json.AddMember("track_uses", value2, json.GetAllocator()); @@ -1708,7 +1692,7 @@ index e4e02c782..c7cbdbbe6 100644 value2.SetInt(m_show_wallet_name_when_locked ? 1 : 0); json.AddMember("show_wallet_name_when_locked", value2, json.GetAllocator()); -@@ -4648,6 +4785,11 @@ boost::optional wallet2::get_keys_file_data(const epee: +@@ -4649,6 +4786,11 @@ boost::optional wallet2::get_keys_file_data(const epee: value2.SetInt(m_polyseed ? 1 : 0); json.AddMember("polyseed", value2, json.GetAllocator()); @@ -1720,7 +1704,7 @@ index e4e02c782..c7cbdbbe6 100644 // Serialize the JSON object rapidjson::StringBuffer buffer; -@@ -4675,13 +4817,81 @@ void wallet2::setup_keys(const epee::wipeable_string &password) +@@ -4676,13 +4818,81 @@ void wallet2::setup_keys(const epee::wipeable_string &password) m_account.decrypt_viewkey(key); } @@ -1803,7 +1787,7 @@ index e4e02c782..c7cbdbbe6 100644 if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only) decrypt_keys(original_password); setup_keys(new_password); -@@ -4740,8 +4950,24 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -4741,8 +4951,24 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st std::string account_data; account_data.resize(keys_file_data.account_data.size()); crypto::chacha20(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]); @@ -1829,7 +1813,7 @@ index e4e02c782..c7cbdbbe6 100644 // The contents should be JSON if the wallet follows the new format. if (json.Parse(account_data.c_str()).HasParseError()) { -@@ -4779,6 +5005,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -4780,6 +5006,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_ignore_outputs_above = MONEY_SUPPLY; m_ignore_outputs_below = 0; m_track_uses = false; @@ -1837,7 +1821,7 @@ index e4e02c782..c7cbdbbe6 100644 m_show_wallet_name_when_locked = false; m_inactivity_lock_timeout = DEFAULT_INACTIVITY_LOCK_TIMEOUT; m_setup_background_mining = BackgroundMiningMaybe; -@@ -4797,6 +5024,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -4798,6 +5025,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_enable_multisig = false; m_allow_mismatched_daemon_version = false; m_polyseed = false; @@ -1845,7 +1829,7 @@ index e4e02c782..c7cbdbbe6 100644 } else if(json.IsObject()) { -@@ -5035,6 +5263,39 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -5036,6 +5264,39 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_enable_multisig = field_enable_multisig; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, polyseed, int, Int, false, false); m_polyseed = field_polyseed; @@ -1885,7 +1869,7 @@ index e4e02c782..c7cbdbbe6 100644 } else { -@@ -5098,12 +5359,17 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -5099,12 +5360,17 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st const cryptonote::account_keys& keys = m_account.get_keys(); hw::device &hwdev = m_account.get_device(); r = r && hwdev.verify_keys(keys.m_view_secret_key, keys.m_account_address.m_view_public_key); @@ -1905,7 +1889,7 @@ index e4e02c782..c7cbdbbe6 100644 return true; } -@@ -5118,11 +5384,12 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st +@@ -5119,11 +5385,12 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st * can be used prior to rewriting wallet keys file, to ensure user has entered the correct password * */ @@ -1920,7 +1904,7 @@ index e4e02c782..c7cbdbbe6 100644 lock_keys_file(); return r; } -@@ -5140,7 +5407,7 @@ bool wallet2::verify_password(const epee::wipeable_string& password) +@@ -5141,7 +5408,7 @@ bool wallet2::verify_password(const epee::wipeable_string& password) * can be used prior to rewriting wallet keys file, to ensure user has entered the correct password * */ @@ -1929,7 +1913,7 @@ index e4e02c782..c7cbdbbe6 100644 { rapidjson::Document json; wallet2::keys_file_data keys_file_data; -@@ -5157,9 +5424,22 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip +@@ -5158,9 +5425,22 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip std::string account_data; account_data.resize(keys_file_data.account_data.size()); crypto::chacha20(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]); @@ -1953,7 +1937,7 @@ index e4e02c782..c7cbdbbe6 100644 // The contents should be JSON if the wallet follows the new format. if (json.Parse(account_data.c_str()).HasParseError()) { -@@ -5184,6 +5464,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip +@@ -5185,6 +5465,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip r = r && hwdev.verify_keys(keys.m_view_secret_key, keys.m_account_address.m_view_public_key); if(!no_spend_key) r = r && hwdev.verify_keys(keys.m_spend_secret_key, keys.m_account_address.m_spend_public_key); @@ -1961,7 +1945,7 @@ index e4e02c782..c7cbdbbe6 100644 return r; } -@@ -5195,9 +5476,7 @@ void wallet2::encrypt_keys(const crypto::chacha_key &key) +@@ -5196,9 +5477,7 @@ void wallet2::encrypt_keys(const crypto::chacha_key &key) void wallet2::decrypt_keys(const crypto::chacha_key &key) { @@ -1972,7 +1956,7 @@ index e4e02c782..c7cbdbbe6 100644 m_account.encrypt_viewkey(key); m_account.decrypt_keys(key); -@@ -5915,11 +6194,30 @@ void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_strin +@@ -5916,11 +6195,30 @@ void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_strin { if (wallet_name.empty()) return; @@ -2003,7 +1987,7 @@ index e4e02c782..c7cbdbbe6 100644 } /*! * \brief Writes to a file named based on the normal wallet (doesn't generate key, assumes it's already there) -@@ -5953,6 +6251,16 @@ bool wallet2::wallet_valid_path_format(const std::string& file_path) +@@ -5954,6 +6252,16 @@ bool wallet2::wallet_valid_path_format(const std::string& file_path) return !file_path.empty(); } //---------------------------------------------------------------------------------------------------- @@ -2020,7 +2004,7 @@ index e4e02c782..c7cbdbbe6 100644 bool wallet2::parse_long_payment_id(const std::string& payment_id_str, crypto::hash& payment_id) { cryptonote::blobdata payment_id_data; -@@ -6188,10 +6496,81 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass +@@ -6189,10 +6497,81 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass THROW_WALLET_EXCEPTION_IF(true, error::file_read_error, "failed to load keys from buffer"); } @@ -2103,7 +2087,7 @@ index e4e02c782..c7cbdbbe6 100644 bool cache_missing = use_fs ? (!boost::filesystem::exists(m_wallet_file, e) || e) : cache_buf.empty(); if (cache_missing) { -@@ -6205,7 +6584,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass +@@ -6206,7 +6585,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass bool r = true; if (use_fs) { @@ -2112,7 +2096,7 @@ index e4e02c782..c7cbdbbe6 100644 THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file); } -@@ -6218,7 +6597,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass +@@ -6219,7 +6598,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "internal error: failed to deserialize \"" + m_wallet_file + '\"'); std::string cache_data; cache_data.resize(cache_file_data.cache_data.size()); @@ -2121,7 +2105,7 @@ index e4e02c782..c7cbdbbe6 100644 try { bool loaded = false; -@@ -6308,60 +6687,76 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass +@@ -6309,60 +6688,76 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass m_account_public_address.m_view_public_key != m_account.get_keys().m_account_address.m_view_public_key, error::wallet_files_doesnt_correspond, m_keys_file, m_wallet_file); } @@ -2240,7 +2224,7 @@ index e4e02c782..c7cbdbbe6 100644 } } //---------------------------------------------------------------------------------------------------- -@@ -6443,6 +6838,8 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas +@@ -6444,6 +6839,8 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas same_file = canonical_old_path == canonical_new_path; } @@ -2249,7 +2233,7 @@ index e4e02c782..c7cbdbbe6 100644 if (!same_file) { -@@ -6459,6 +6856,21 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas +@@ -6460,6 +6857,21 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas } } } @@ -2271,7 +2255,7 @@ index e4e02c782..c7cbdbbe6 100644 // get wallet cache data boost::optional cache_file_data = get_cache_file_data(); -@@ -6552,6 +6964,22 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas +@@ -6553,6 +6965,22 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas // store should only exist if the MMS is really active m_message_store.write_to_file(get_multisig_wallet_state(), m_mms_file); } @@ -2294,7 +2278,7 @@ index e4e02c782..c7cbdbbe6 100644 } //---------------------------------------------------------------------------------------------------- boost::optional wallet2::get_cache_file_data() -@@ -6569,7 +6997,7 @@ boost::optional wallet2::get_cache_file_data() +@@ -6570,7 +6998,7 @@ boost::optional wallet2::get_cache_file_data() std::string cipher; cipher.resize(cache_file_data.get().cache_data.size()); cache_file_data.get().iv = crypto::rand(); @@ -2303,7 +2287,7 @@ index e4e02c782..c7cbdbbe6 100644 cache_file_data.get().cache_data = cipher; return cache_file_data; } -@@ -8645,6 +9073,34 @@ bool wallet2::is_keys_file_locked() const +@@ -8646,6 +9074,34 @@ bool wallet2::is_keys_file_locked() const return m_keys_file_locker->locked(); } @@ -2338,7 +2322,7 @@ index e4e02c782..c7cbdbbe6 100644 bool wallet2::tx_add_fake_output(std::vector> &outs, uint64_t global_index, const crypto::public_key& output_public_key, const rct::key& mask, uint64_t real_index, bool unlocked, std::unordered_set &valid_public_keys_cache) const { if (!unlocked) // don't add locked outs -@@ -13980,6 +14436,413 @@ bool wallet2::import_key_images(signed_tx_set & signed_tx, size_t offset, bool o +@@ -13978,6 +14434,413 @@ bool wallet2::import_key_images(signed_tx_set & signed_tx, size_t offset, bool o return import_key_images(signed_tx.key_images, offset, only_selected_transfers ? boost::make_optional(selected_transfers) : boost::none); } @@ -2753,7 +2737,7 @@ index e4e02c782..c7cbdbbe6 100644 { payment_container payments; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index b540eff6b..d37332dd1 100644 +index 91ec72e0f..56cc118f4 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -257,6 +257,20 @@ private: @@ -3063,7 +3047,7 @@ index b540eff6b..d37332dd1 100644 } diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h -index 1f7e1c75d..d17b721a9 100644 +index c077313d4..c54cd3499 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -63,6 +63,7 @@ namespace tools @@ -3074,7 +3058,7 @@ index 1f7e1c75d..d17b721a9 100644 // refresh_error * // acc_outs_lookup_error // block_parse_error -@@ -96,6 +97,9 @@ namespace tools +@@ -97,6 +98,9 @@ namespace tools // wallet_files_doesnt_correspond // scan_tx_error * // wont_reprocess_recent_txs_via_untrusted_daemon @@ -3084,7 +3068,7 @@ index 1f7e1c75d..d17b721a9 100644 // // * - class with protected ctor -@@ -303,6 +307,16 @@ namespace tools +@@ -304,6 +308,16 @@ namespace tools std::string to_string() const { return wallet_logic_error::to_string(); } }; @@ -3101,7 +3085,7 @@ index 1f7e1c75d..d17b721a9 100644 //---------------------------------------------------------------------------------------------------- struct invalid_pregenerated_random : public wallet_logic_error { -@@ -944,6 +958,31 @@ namespace tools +@@ -947,6 +961,31 @@ namespace tools } }; //---------------------------------------------------------------------------------------------------- @@ -3134,7 +3118,7 @@ index 1f7e1c75d..d17b721a9 100644 #if !defined(_MSC_VER) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp -index 4e42d64cd..822fc828b 100644 +index b1419949f..d24b4c563 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -73,6 +73,54 @@ using namespace epee; @@ -3299,7 +3283,7 @@ index 4e42d64cd..822fc828b 100644 crypto::hash8 integrated_payment_id = crypto::null_hash8; std::string extra_nonce; for (auto it = destinations.begin(); it != destinations.end(); it++) -@@ -1192,6 +1256,7 @@ namespace tools +@@ -1204,6 +1268,7 @@ namespace tools } CHECK_MULTISIG_ENABLED(); @@ -3307,7 +3291,7 @@ index 4e42d64cd..822fc828b 100644 cryptonote::blobdata blob; if (!epee::string_tools::parse_hexstr_to_binbuff(req.unsigned_txset, blob)) -@@ -1273,6 +1338,7 @@ namespace tools +@@ -1285,6 +1350,7 @@ namespace tools er.message = "command not supported by watch-only wallet"; return false; } @@ -3315,7 +3299,7 @@ index 4e42d64cd..822fc828b 100644 if(req.unsigned_txset.empty() && req.multisig_txset.empty()) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; -@@ -1542,6 +1608,7 @@ namespace tools +@@ -1554,6 +1620,7 @@ namespace tools } CHECK_MULTISIG_ENABLED(); @@ -3323,7 +3307,7 @@ index 4e42d64cd..822fc828b 100644 try { -@@ -2091,6 +2158,7 @@ namespace tools +@@ -2115,6 +2182,7 @@ namespace tools er.message = "The wallet is watch-only. Cannot retrieve seed."; return false; } @@ -3331,7 +3315,7 @@ index 4e42d64cd..822fc828b 100644 if (!m_wallet->is_deterministic()) { er.code = WALLET_RPC_ERROR_CODE_NON_DETERMINISTIC; -@@ -2119,6 +2187,7 @@ namespace tools +@@ -2143,6 +2211,7 @@ namespace tools er.message = "The wallet is watch-only. Cannot retrieve spend key."; return false; } @@ -3339,7 +3323,7 @@ index 4e42d64cd..822fc828b 100644 epee::wipeable_string key = epee::to_hex::wipeable_string(m_wallet->get_account().get_keys().m_spend_secret_key); res.key = std::string(key.data(), key.size()); } -@@ -2140,6 +2209,7 @@ namespace tools +@@ -2164,6 +2233,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3347,7 +3331,7 @@ index 4e42d64cd..822fc828b 100644 try { -@@ -2153,6 +2223,79 @@ namespace tools +@@ -2177,6 +2247,79 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -3427,7 +3411,7 @@ index 4e42d64cd..822fc828b 100644 bool wallet_rpc_server::on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); -@@ -2162,6 +2305,7 @@ namespace tools +@@ -2186,6 +2329,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3435,7 +3419,7 @@ index 4e42d64cd..822fc828b 100644 tools::wallet2::message_signature_type_t signature_type = tools::wallet2::sign_with_spend_key; if (req.signature_type == "spend" || req.signature_type == "") -@@ -2254,6 +2398,7 @@ namespace tools +@@ -2278,6 +2422,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3443,7 +3427,7 @@ index 4e42d64cd..822fc828b 100644 if (req.txids.size() != req.notes.size()) { -@@ -2326,6 +2471,7 @@ namespace tools +@@ -2350,6 +2495,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3451,7 +3435,7 @@ index 4e42d64cd..822fc828b 100644 m_wallet->set_attribute(req.key, req.value); -@@ -2353,6 +2499,7 @@ namespace tools +@@ -2377,6 +2523,7 @@ namespace tools bool wallet_rpc_server::on_get_tx_key(const wallet_rpc::COMMAND_RPC_GET_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_GET_TX_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -3459,7 +3443,7 @@ index 4e42d64cd..822fc828b 100644 crypto::hash txid; if (!epee::string_tools::hex_to_pod(req.txid, txid)) -@@ -2444,6 +2591,7 @@ namespace tools +@@ -2468,6 +2615,7 @@ namespace tools bool wallet_rpc_server::on_get_tx_proof(const wallet_rpc::COMMAND_RPC_GET_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_TX_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -3467,7 +3451,7 @@ index 4e42d64cd..822fc828b 100644 crypto::hash txid; if (!epee::string_tools::hex_to_pod(req.txid, txid)) -@@ -2560,6 +2708,7 @@ namespace tools +@@ -2584,6 +2732,7 @@ namespace tools bool wallet_rpc_server::on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -3475,7 +3459,7 @@ index 4e42d64cd..822fc828b 100644 boost::optional> account_minreserve; if (!req.all) -@@ -2802,6 +2951,7 @@ namespace tools +@@ -2826,6 +2975,7 @@ namespace tools er.message = "command not supported by HW wallet"; return false; } @@ -3483,7 +3467,7 @@ index 4e42d64cd..822fc828b 100644 try { -@@ -2831,6 +2981,7 @@ namespace tools +@@ -2855,6 +3005,7 @@ namespace tools er.message = "command not supported by HW wallet"; return false; } @@ -3491,7 +3475,7 @@ index 4e42d64cd..822fc828b 100644 cryptonote::blobdata blob; if (!epee::string_tools::parse_hexstr_to_binbuff(req.outputs_data_hex, blob)) -@@ -2856,6 +3007,7 @@ namespace tools +@@ -2880,6 +3031,7 @@ namespace tools bool wallet_rpc_server::on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -3499,7 +3483,7 @@ index 4e42d64cd..822fc828b 100644 try { std::pair>> ski = m_wallet->export_key_images(req.all); -@@ -2892,6 +3044,7 @@ namespace tools +@@ -2916,6 +3068,7 @@ namespace tools er.message = "This command requires a trusted daemon."; return false; } @@ -3507,7 +3491,7 @@ index 4e42d64cd..822fc828b 100644 try { std::vector> ski; -@@ -2960,6 +3113,7 @@ namespace tools +@@ -2984,6 +3137,7 @@ namespace tools bool wallet_rpc_server::on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -3515,7 +3499,7 @@ index 4e42d64cd..822fc828b 100644 const auto ab = m_wallet->get_address_book(); if (req.entries.empty()) { -@@ -3005,6 +3159,7 @@ namespace tools +@@ -3029,6 +3183,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3523,7 +3507,7 @@ index 4e42d64cd..822fc828b 100644 cryptonote::address_parse_info info; er.message = ""; -@@ -3047,6 +3202,7 @@ namespace tools +@@ -3071,6 +3226,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3531,7 +3515,7 @@ index 4e42d64cd..822fc828b 100644 const auto ab = m_wallet->get_address_book(); if (req.index >= ab.size()) -@@ -3109,6 +3265,7 @@ namespace tools +@@ -3133,6 +3289,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3539,7 +3523,7 @@ index 4e42d64cd..822fc828b 100644 const auto ab = m_wallet->get_address_book(); if (req.index >= ab.size()) -@@ -3179,6 +3336,7 @@ namespace tools +@@ -3203,6 +3360,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3547,7 +3531,7 @@ index 4e42d64cd..822fc828b 100644 std::unordered_set txids; std::list::const_iterator i = req.txids.begin(); -@@ -3218,6 +3376,7 @@ namespace tools +@@ -3242,6 +3400,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3555,7 +3539,7 @@ index 4e42d64cd..822fc828b 100644 try { m_wallet->rescan_spent(); -@@ -3482,6 +3641,7 @@ namespace tools +@@ -3506,6 +3665,7 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } @@ -3563,7 +3547,7 @@ index 4e42d64cd..822fc828b 100644 if (m_wallet->verify_password(req.old_password)) { try -@@ -4009,6 +4169,7 @@ namespace tools +@@ -4033,6 +4193,7 @@ namespace tools er.message = "wallet is watch-only and cannot be made multisig"; return false; } @@ -3571,7 +3555,7 @@ index 4e42d64cd..822fc828b 100644 res.multisig_info = m_wallet->get_multisig_first_kex_msg(); return true; -@@ -4036,6 +4197,7 @@ namespace tools +@@ -4060,6 +4221,7 @@ namespace tools er.message = "wallet is watch-only and cannot be made multisig"; return false; } @@ -3678,15 +3662,16 @@ index b6098d95c..a44b56ed6 100644 } } diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h -index 734229380..b964036bd 100644 +index 541d29f86..6e88f6967 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h -@@ -79,3 +79,5 @@ - #define WALLET_RPC_ERROR_CODE_ZERO_AMOUNT -46 - #define WALLET_RPC_ERROR_CODE_INVALID_SIGNATURE_TYPE -47 +@@ -81,3 +81,5 @@ #define WALLET_RPC_ERROR_CODE_DISABLED -48 -+#define WALLET_RPC_ERROR_CODE_IS_BACKGROUND_WALLET -49 -+#define WALLET_RPC_ERROR_CODE_IS_BACKGROUND_SYNCING -50 + #define WALLET_RPC_ERROR_CODE_PROXY_ALREADY_DEFINED -49 + #define WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME -50 ++#define WALLET_RPC_ERROR_CODE_IS_BACKGROUND_WALLET -51 ++#define WALLET_RPC_ERROR_CODE_IS_BACKGROUND_SYNCING -52 +\ No newline at end of file diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py index 4063911f4..60eb09a10 100755 --- a/tests/functional_tests/transfer.py @@ -4327,5 +4312,5 @@ index 1e10e1f86..bff33a561 100644 + } + return self.rpc.send_json_rpc_request(stop_background_sync) -- -2.44.0 +2.39.2 diff --git a/patches/monero/0003-airgap.patch b/patches/monero/0003-airgap.patch index e3aeae9d..eebe0976 100644 --- a/patches/monero/0003-airgap.patch +++ b/patches/monero/0003-airgap.patch @@ -1,7 +1,7 @@ -From 5c1727c760557c0fd83ba1e4e66be2d10c58e890 Mon Sep 17 00:00:00 2001 +From 5385d085c547b675adfccb64314d1c6f7bf2d508 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 12 Mar 2024 10:09:50 +0100 -Subject: [PATCH] airgap +Subject: [PATCH 03/16] airgap --- src/wallet/api/wallet.cpp | 23 ++++++++++++++++++ @@ -12,7 +12,7 @@ Subject: [PATCH] airgap 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 1a9c6f674..42887dced 100644 +index 7d430b655..837b98e6b 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1129,6 +1129,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const @@ -94,7 +94,7 @@ index 4268b656e..4edaefefd 100644 * \brief exportKeyImages - exports key images to file * \param filename diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index c7cbdbbe6..794992b2e 100644 +index f2381740a..41cf1fd41 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -949,6 +949,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra) @@ -114,7 +114,7 @@ index c7cbdbbe6..794992b2e 100644 static void setup_shim(hw::wallet_shim * shim, tools::wallet2 * wallet) { shim->get_tx_pub_key_from_received_outs = std::bind(&tools::wallet2::get_tx_pub_key_from_received_outs, wallet, std::placeholders::_1); -@@ -7037,6 +7047,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t * +@@ -7038,6 +7048,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t * return amount; } //---------------------------------------------------------------------------------------------------- @@ -140,7 +140,7 @@ index c7cbdbbe6..794992b2e 100644 std::map wallet2::balance_per_subaddress(uint32_t index_major, bool strict) const { std::map amount_per_subaddr; -@@ -7887,9 +7916,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector additional_derivations; @@ -179,7 +179,7 @@ index c7cbdbbe6..794992b2e 100644 if (unused_dust_indices_per_subaddr.empty()) unused_dust_indices_per_subaddr.push_back({}); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index d37332dd1..fc69b3d36 100644 +index 56cc118f4..b9aa7a00d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1172,6 +1172,7 @@ private: @@ -191,5 +191,5 @@ index d37332dd1..fc69b3d36 100644 std::map balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; std::map>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict); -- -2.43.0 +2.39.2 diff --git a/patches/monero/0004-coin-control.patch b/patches/monero/0004-coin-control.patch index fd777c3e..1700a617 100644 --- a/patches/monero/0004-coin-control.patch +++ b/patches/monero/0004-coin-control.patch @@ -1,7 +1,7 @@ -From 8e069a8b7c15794b843471487c12c2c753d3afe2 Mon Sep 17 00:00:00 2001 +From d6d52b6156f1e83a69474a871043d414e4488f62 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Tue, 12 Mar 2024 11:07:57 +0100 -Subject: [PATCH 04/10] coin control +Subject: [PATCH 04/16] coin control --- src/wallet/api/CMakeLists.txt | 8 +- @@ -9,12 +9,12 @@ Subject: [PATCH 04/10] coin control src/wallet/api/coins.h | 40 ++++++++ src/wallet/api/coins_info.cpp | 122 ++++++++++++++++++++++ src/wallet/api/coins_info.h | 71 +++++++++++++ - src/wallet/api/wallet.cpp | 31 +++++- + src/wallet/api/wallet.cpp | 26 ++++- src/wallet/api/wallet.h | 10 +- src/wallet/api/wallet2_api.h | 52 +++++++++- src/wallet/wallet2.cpp | 46 ++++++++- src/wallet/wallet2.h | 11 +- - 10 files changed, 558 insertions(+), 18 deletions(-) + 10 files changed, 555 insertions(+), 16 deletions(-) create mode 100644 src/wallet/api/coins.cpp create mode 100644 src/wallet/api/coins.h create mode 100644 src/wallet/api/coins_info.cpp @@ -489,7 +489,7 @@ index 000000000..c43e45abd + +#endif //FEATHER_COINS_INFO_H diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 42887dced..2fe0d1d29 100644 +index 837b98e6b..2106dbd07 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -35,6 +35,7 @@ @@ -537,24 +537,7 @@ index 42887dced..2fe0d1d29 100644 if (error) { break; } -@@ -1833,13 +1848,14 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vectoradjust_mixin(mixin_count); - - if (amount) { -+ // (std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs, const std::vector& preferred_input_list) - transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, - adjusted_priority, -- extra, subaddr_account, subaddr_indices); -+ extra, subaddr_account, subaddr_indices, preferred_input_list); - } else { - transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count, 0 /* unlock_time */, - adjusted_priority, -- extra, subaddr_account, subaddr_indices); -+ extra, subaddr_account, subaddr_indices, preferred_input_list); - } - pendingTxPostProcess(transaction); - -@@ -1920,10 +1936,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector amount, uint32_t mixin_count, @@ -567,7 +550,7 @@ index 42887dced..2fe0d1d29 100644 } PendingTransaction *WalletImpl::createSweepUnmixableTransaction() -@@ -2048,6 +2064,11 @@ AddressBook *WalletImpl::addressBook() +@@ -2048,6 +2063,11 @@ AddressBook *WalletImpl::addressBook() return m_addressBook.get(); } @@ -717,7 +700,7 @@ index 4edaefefd..8a5c4135e 100644 virtual SubaddressAccount * subaddressAccount() = 0; virtual void setListener(WalletListener *) = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index 700816da6..5331f90fc 100644 +index 41cf1fd41..61601f70c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2083,12 +2083,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const @@ -820,8 +803,8 @@ index 700816da6..5331f90fc 100644 // This system allows for sending (almost) the entire balance, since it does // not generate spurious change in all txes, thus decreasing the instantaneous // usable balance. --std::vector wallet2::create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs) -+std::vector wallet2::create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list, const unique_index_container& subtract_fee_from_outputs) +-std::vector wallet2::create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs) ++std::vector wallet2::create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list, const unique_index_container& subtract_fee_from_outputs) { //ensure device is let in NONE mode in any case hw::device &hwdev = m_account.get_device(); @@ -835,7 +818,7 @@ index 700816da6..5331f90fc 100644 if (m_ignore_fractional_outputs && td.amount() < fractional_threshold) { MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold)); -@@ -11393,7 +11428,7 @@ std::vector wallet2::create_transactions_2(std::vector wallet2::create_transactions_2(std::vector &ptx_vector, c +@@ -11879,7 +11914,7 @@ bool wallet2::sanity_check(const std::vector &ptx_vector, c return true; } --std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices) -+std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list) +-std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices) ++std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list) { std::vector unused_transfers_indices; std::vector unused_dust_indices; -@@ -11903,6 +11938,9 @@ std::vector wallet2::create_transactions_all(uint64_t below +@@ -11908,6 +11943,9 @@ std::vector wallet2::create_transactions_all(uint64_t below for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; @@ -864,19 +847,19 @@ index 700816da6..5331f90fc 100644 { MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold)); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index fc69b3d36..52886fb85 100644 +index b9aa7a00d..67ed81383 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1207,8 +1207,8 @@ private: bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const; bool load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func = NULL); bool parse_tx_from_str(const std::string &signed_tx_st, std::vector &ptx, std::function accept_func); -- std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose -- std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices); -+ std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose -+ std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}); - std::vector create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra); - std::vector create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra); +- std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose +- std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices); ++ std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose ++ std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}); + std::vector create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); + std::vector create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); bool sanity_check(const std::vector &ptx_vector, const std::vector& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const; @@ -1560,6 +1560,7 @@ private: uint64_t get_num_rct_outputs(); @@ -915,5 +898,5 @@ index fc69b3d36..52886fb85 100644 void set_unspent(size_t idx); bool is_spent(const transfer_details &td, bool strict = true) const; -- -2.44.0 +2.39.2 diff --git a/patches/monero/0005-fix-build-issues.patch b/patches/monero/0005-fix-build-issues.patch index 2215c999..985df3ed 100644 --- a/patches/monero/0005-fix-build-issues.patch +++ b/patches/monero/0005-fix-build-issues.patch @@ -1,7 +1,7 @@ -From a24797410dcda06617ff2a81de3129d38b69f2a2 Mon Sep 17 00:00:00 2001 +From 0f1d5e1296dc1e8c9ee323fa7bdf706ff76df2a7 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Tue, 12 Mar 2024 17:59:13 +0100 -Subject: [PATCH 05/10] fix build issues +Subject: [PATCH 05/16] fix build issues --- contrib/depends/hosts/linux.mk | 8 +++---- @@ -133,5 +133,5 @@ index 000000000..f05cb2b6a + #else + #ifdef POLYSEED_SHARED -- -2.44.0 +2.39.2 diff --git a/patches/monero/0006-macos-build-fix.patch b/patches/monero/0006-macos-build-fix.patch index c1492324..f7c48b9f 100644 --- a/patches/monero/0006-macos-build-fix.patch +++ b/patches/monero/0006-macos-build-fix.patch @@ -1,13 +1,13 @@ -From bc3d91b07d77893983bbed0b165ce41e034579a7 Mon Sep 17 00:00:00 2001 +From 3343e3fbbd05546b3858c98afe3bad4673f250c8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 28 Mar 2024 02:03:08 +0100 -Subject: [PATCH 06/10] macos build fix +Subject: [PATCH 06/16] macos build fix --- contrib/depends/hosts/darwin.mk | 2 + contrib/depends/packages/polyseed.mk | 13 +++-- - .../polyseed/0001-disable-soname.patch | 49 +++++++++++++++++++ - 3 files changed, 60 insertions(+), 4 deletions(-) + .../polyseed/0001-disable-soname.patch | 48 +++++++++++++++++++ + 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 contrib/depends/patches/polyseed/0001-disable-soname.patch diff --git a/contrib/depends/hosts/darwin.mk b/contrib/depends/hosts/darwin.mk @@ -57,10 +57,10 @@ index 2ddeac621..0071b20f3 100644 define $(package)_stage_cmds diff --git a/contrib/depends/patches/polyseed/0001-disable-soname.patch b/contrib/depends/patches/polyseed/0001-disable-soname.patch new file mode 100644 -index 000000000..a261636e8 +index 000000000..bd97dd394 --- /dev/null +++ b/contrib/depends/patches/polyseed/0001-disable-soname.patch -@@ -0,0 +1,49 @@ +@@ -0,0 +1,48 @@ +From aabafcfc0572651436d024a635483c49042fad7f Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Thu, 28 Mar 2024 00:32:51 +0100 @@ -81,7 +81,7 @@ index 000000000..a261636e8 ++ NO_SONAME 1 + C_STANDARD 11 + C_STANDARD_REQUIRED ON) -+ ++ +@@ -45,16 +46,17 @@ include_directories(polyseed_static + include/) + target_compile_definitions(polyseed_static PRIVATE POLYSEED_STATIC) @@ -89,7 +89,7 @@ index 000000000..a261636e8 ++ NO_SONAME 1 + C_STANDARD 11 + C_STANDARD_REQUIRED ON) -+ ++ +-add_executable(polyseed-tests +- tests/tests.c) +-include_directories(polyseed-tests @@ -104,12 +104,11 @@ index 000000000..a261636e8 ++# target_compile_definitions(polyseed-tests PRIVATE POLYSEED_STATIC) ++# target_link_libraries(polyseed-tests ++# PRIVATE polyseed_static) -+ ++ + include(GNUInstallDirs) + install(TARGETS polyseed polyseed_static -+-- ++-- +2.39.2 -+ -- -2.44.0 +2.39.2 diff --git a/patches/monero/0007-fix-make-debug-test-target.patch b/patches/monero/0007-fix-make-debug-test-target.patch index 25827bb2..f39c49ed 100644 --- a/patches/monero/0007-fix-make-debug-test-target.patch +++ b/patches/monero/0007-fix-make-debug-test-target.patch @@ -1,46 +1,39 @@ -From 14b4c210a11e0c333087026775cf22fcccf46a40 Mon Sep 17 00:00:00 2001 +From 8945e9865ef831f85ef58ba3d269f4b17d0270b5 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Tue, 2 Apr 2024 01:13:12 +0200 -Subject: [PATCH 07/10] fix `make debug-test` target +Subject: [PATCH 07/16] fix `make debug-test` target --- - src/simplewallet/simplewallet.cpp | 4 ++-- - src/wallet/wallet_rpc_server.cpp | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) + src/simplewallet/simplewallet.cpp | 2 +- + src/wallet/wallet2.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp -index 341b0e448..c2e16da4c 100644 +index f8ed6659c..0aa76b668 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp -@@ -6976,13 +6976,13 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vectorcreate_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); -+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs); - break; - default: - LOG_ERROR("Unknown transfer method, using default"); - /* FALLTHRU */ - case Transfer: -- ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); -+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs); - break; - } +@@ -6929,7 +6929,7 @@ bool simple_wallet::transfer_main(const std::vector &args_, bool ca + { + // figure out what tx will be necessary + auto ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, priority, extra, +- m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); ++ m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs); -diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp -index 822fc828b..caa23e636 100644 ---- a/src/wallet/wallet_rpc_server.cpp -+++ b/src/wallet/wallet_rpc_server.cpp -@@ -1157,7 +1157,7 @@ namespace tools + if (ptx_vector.empty()) { - uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); - uint32_t priority = m_wallet->adjust_priority(req.priority); -- std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs); -+ std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, {}, req.subtract_fee_from_outputs); - - if (ptx_vector.empty()) - { +diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h +index 67ed81383..fdc1a6212 100644 +--- a/src/wallet/wallet2.h ++++ b/src/wallet/wallet2.h +@@ -1207,7 +1207,7 @@ private: + bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const; + bool load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func = NULL); + bool parse_tx_from_str(const std::string &signed_tx_st, std::vector &ptx, std::function accept_func); +- std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose ++ std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose + std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const std::vector& preferred_input_list = {}); + std::vector create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); + std::vector create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); -- -2.44.0 +2.39.2 diff --git a/patches/monero/0008-fix-missing-___clear_cache-when-targetting-iOS.patch b/patches/monero/0008-fix-missing-___clear_cache-when-targetting-iOS.patch index cdd4ef27..5b46d7c8 100644 --- a/patches/monero/0008-fix-missing-___clear_cache-when-targetting-iOS.patch +++ b/patches/monero/0008-fix-missing-___clear_cache-when-targetting-iOS.patch @@ -1,7 +1,7 @@ -From d3a704bfb62bede87d5da0261585f62f19f858c1 Mon Sep 17 00:00:00 2001 +From c7f8510fb4bfb54707053603f5cbcaa8c0bf72d2 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Tue, 2 Apr 2024 16:51:56 +0200 -Subject: [PATCH 08/10] fix missing ___clear_cache when targetting iOS +Subject: [PATCH 08/16] fix missing ___clear_cache when targetting iOS --- .gitmodules | 2 +- @@ -29,5 +29,5 @@ index 102f8acf9..ce72c9bb9 160000 -Subproject commit 102f8acf90a7649ada410de5499a7ec62e49e1da +Subproject commit ce72c9bb9cb799e0d9171094b9abb009e04c5bfc -- -2.44.0 +2.39.2 diff --git a/patches/monero/0009-Add-recoverDeterministicWalletFromSpendKey.patch b/patches/monero/0009-Add-recoverDeterministicWalletFromSpendKey.patch index 3c2510e1..0ef99002 100644 --- a/patches/monero/0009-Add-recoverDeterministicWalletFromSpendKey.patch +++ b/patches/monero/0009-Add-recoverDeterministicWalletFromSpendKey.patch @@ -1,7 +1,7 @@ -From 8db1b159445a8aaca702a8bacb9476abe3aebcf1 Mon Sep 17 00:00:00 2001 +From ff4d7f9500e6aca57a78d94599a70b7823ea6ecd Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Wed, 11 Oct 2023 16:47:59 +0200 -Subject: [PATCH 09/10] Add recoverDeterministicWalletFromSpendKey +Subject: [PATCH 09/16] Add recoverDeterministicWalletFromSpendKey This function is used by Cake Wallet to enable polyseed (dart implementation) support. @@ -19,7 +19,7 @@ Co-authored-by: Godwin Asuquo 5 files changed, 75 insertions(+) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 2fe0d1d29..2411d948c 100644 +index 2106dbd07..ec4ae51ff 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -820,6 +820,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c @@ -149,5 +149,5 @@ index 28fcd36c9..be3ff8184 100644 const std::string &password, NetworkType nettype, -- -2.44.0 +2.39.2 diff --git a/patches/monero/0010-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch b/patches/monero/0010-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch index 502de5e0..e3176271 100644 --- a/patches/monero/0010-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch +++ b/patches/monero/0010-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch @@ -1,7 +1,7 @@ -From db90a0218d581276fcede6f188cc951499095a2f Mon Sep 17 00:00:00 2001 +From 3cc8b1f822f642b574fe38ff27627b362002eab7 Mon Sep 17 00:00:00 2001 From: M Date: Fri, 21 Apr 2023 15:43:47 -0400 -Subject: [PATCH 10/10] Add hex encoding and tx key getter for +Subject: [PATCH 10/16] Add hex encoding and tx key getter for PendingTransction in wallet api. --- @@ -64,5 +64,5 @@ index a585c8212..1c3a11c39 100644 /** -- -2.44.0 +2.39.2 diff --git a/patches/monero/0011-store-crash-fix.patch b/patches/monero/0011-store-crash-fix.patch index dfb96e2b..1ddae67d 100644 --- a/patches/monero/0011-store-crash-fix.patch +++ b/patches/monero/0011-store-crash-fix.patch @@ -1,7 +1,7 @@ -From 0fe816689af4bce256eae2efa6a8eee0cb8b8097 Mon Sep 17 00:00:00 2001 +From 238c847c153c74953b094d83bfe181a596771d37 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Sat, 11 May 2024 16:25:10 +0200 -Subject: [PATCH] store crash fix +Subject: [PATCH 11/16] store crash fix Monero wallet crashes (sometimes) when it is syncing, while the proper solution (that can be seen in feather) @@ -43,7 +43,7 @@ the current state. 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 2411d948c..90e107137 100644 +index ec4ae51ff..306c9b8ae 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -56,8 +56,8 @@ using namespace cryptonote; @@ -74,7 +74,7 @@ index 2411d948c..90e107137 100644 try { if (path.empty()) { m_wallet->store(); -@@ -2592,10 +2593,10 @@ void WalletImpl::refreshThreadFunc() +@@ -2591,10 +2592,10 @@ void WalletImpl::refreshThreadFunc() } LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired..."); @@ -87,7 +87,7 @@ index 2411d948c..90e107137 100644 LOG_PRINT_L3(__FUNCTION__ << ": refreshing..."); doRefresh(); } -@@ -2625,12 +2626,12 @@ void WalletImpl::doRefresh() +@@ -2624,12 +2625,12 @@ void WalletImpl::doRefresh() } m_wallet->find_and_save_rings(false); } else { @@ -102,7 +102,7 @@ index 2411d948c..90e107137 100644 if (m_wallet2Callback->getListener()) { m_wallet2Callback->getListener()->refreshed(); -@@ -2640,9 +2641,9 @@ void WalletImpl::doRefresh() +@@ -2639,9 +2640,9 @@ void WalletImpl::doRefresh() void WalletImpl::startRefresh() { @@ -114,7 +114,7 @@ index 2411d948c..90e107137 100644 m_refreshCV.notify_one(); } } -@@ -2652,7 +2653,7 @@ void WalletImpl::startRefresh() +@@ -2651,7 +2652,7 @@ void WalletImpl::startRefresh() void WalletImpl::stopRefresh() { if (!m_refreshThreadDone) { @@ -123,7 +123,7 @@ index 2411d948c..90e107137 100644 m_refreshThreadDone = true; m_refreshCV.notify_one(); m_refreshThread.join(); -@@ -2663,9 +2664,7 @@ void WalletImpl::pauseRefresh() +@@ -2662,9 +2663,7 @@ void WalletImpl::pauseRefresh() { LOG_PRINT_L2(__FUNCTION__ << ": refresh paused..."); // TODO synchronize access @@ -147,7 +147,7 @@ index d0f443abc..2ad2b62a4 100644 std::atomic m_refreshIntervalMillis; std::atomic m_refreshShouldRescan; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index 5331f90fc..e5773a26b 100644 +index 61601f70c..4de226a4a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1203,6 +1203,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std @@ -173,7 +173,7 @@ index 5331f90fc..e5773a26b 100644 bool wallet2::set_proxy(const std::string &address) { return m_http_client->set_proxy(address); -@@ -4145,8 +4154,9 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo +@@ -4146,8 +4155,9 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo // infer when we get an incoming output bool first = true, last = false; @@ -185,7 +185,7 @@ index 5331f90fc..e5773a26b 100644 std::vector next_blocks; std::vector next_parsed_blocks; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 52886fb85..0d9a9298f 100644 +index fdc1a6212..3ce710433 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1086,6 +1086,8 @@ private: @@ -206,5 +206,5 @@ index 52886fb85..0d9a9298f 100644 i_wallet2_callback* m_callback; hw::device::device_type m_key_device_type; -- -2.45.0 +2.39.2 diff --git a/patches/monero/0012-WIP-UR-functions.patch b/patches/monero/0012-WIP-UR-functions.patch index d6dc1bda..564be97d 100644 --- a/patches/monero/0012-WIP-UR-functions.patch +++ b/patches/monero/0012-WIP-UR-functions.patch @@ -1,7 +1,7 @@ -From f91e92ddaa7c12dcc8f38ac37ff852446bd10722 Mon Sep 17 00:00:00 2001 +From 1b938a3f98468de3fa06b21a458104cf32831586 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Thu, 16 May 2024 17:28:59 +0200 -Subject: [PATCH] WIP: UR functions +Subject: [PATCH 12/16] WIP: UR functions This commit adds UR functions for UR tasks, I believe that the right place to get @@ -283,7 +283,7 @@ index 30065a7fa..a94b23f75 100644 uint64_t minMixinCount() const override; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 90e107137..ac3e6d51e 100644 +index 306c9b8ae..5ca190c7d 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -48,6 +48,7 @@ @@ -726,10 +726,10 @@ index 1c3a11c39..2bbb32c8b 100644 /*! * \brief scanTransactions - scan a list of transaction ids, this operation may reveal the txids to the remote node and affect your privacy diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index e5773a26b..23b56810e 100644 +index 4de226a4a..7d97e683b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp -@@ -14051,33 +14051,40 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle +@@ -14056,33 +14056,40 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle bool wallet2::export_key_images(const std::string &filename, bool all) const { @@ -793,7 +793,7 @@ index e5773a26b..23b56810e 100644 //---------------------------------------------------------------------------------------------------- std::pair>> wallet2::export_key_images(bool all) const { -@@ -14132,53 +14139,60 @@ std::pair> +@@ -14137,53 +14144,60 @@ std::pair> return std::make_pair(offset, ski); } @@ -873,7 +873,7 @@ index e5773a26b..23b56810e 100644 ski.push_back(std::make_pair(key_image, signature)); } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 0d9a9298f..539d5056c 100644 +index 3ce710433..9ff169a40 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1650,9 +1650,11 @@ private: diff --git a/patches/monero/0013-android-ndk-version-bump.patch b/patches/monero/0013-android-ndk-version-bump.patch index dce35368..2b741a0a 100644 --- a/patches/monero/0013-android-ndk-version-bump.patch +++ b/patches/monero/0013-android-ndk-version-bump.patch @@ -1,7 +1,7 @@ -From 5815bf9d5dd2420915fafb73a3314eb467a489a7 Mon Sep 17 00:00:00 2001 +From 1b978a697e1bdb3144bc08f998d125ac593fa971 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Thu, 23 May 2024 08:02:49 +0200 -Subject: [PATCH] android ndk version bump +Subject: [PATCH 13/16] android ndk version bump --- contrib/depends/hosts/android.mk | 16 +++++++++++++--- diff --git a/patches/monero/0013-rename-arm-armv7a.patch b/patches/monero/0014-rename-arm-armv7a.patch similarity index 97% rename from patches/monero/0013-rename-arm-armv7a.patch rename to patches/monero/0014-rename-arm-armv7a.patch index 7049065d..20e28224 100644 --- a/patches/monero/0013-rename-arm-armv7a.patch +++ b/patches/monero/0014-rename-arm-armv7a.patch @@ -1,7 +1,7 @@ -From 9b7623e565a31db296f20cac00ddde58e8e83fe2 Mon Sep 17 00:00:00 2001 +From 2dfa0442a096f61fe16a5bc569a4d0ab9ddb7de5 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Wed, 12 Jun 2024 15:48:01 +0200 -Subject: [PATCH] rename arm -> armv7a +Subject: [PATCH 14/16] rename arm -> armv7a --- contrib/depends/hosts/android.mk | 2 +- diff --git a/patches/monero/0014-use-proper-error-handling-in-get_seed.patch b/patches/monero/0015-use-proper-error-handling-in-get_seed.patch similarity index 92% rename from patches/monero/0014-use-proper-error-handling-in-get_seed.patch rename to patches/monero/0015-use-proper-error-handling-in-get_seed.patch index 892a827a..aef7dcf7 100644 --- a/patches/monero/0014-use-proper-error-handling-in-get_seed.patch +++ b/patches/monero/0015-use-proper-error-handling-in-get_seed.patch @@ -1,7 +1,7 @@ -From 50e09195fcb79debf5951c69717b9d4f239ed8e1 Mon Sep 17 00:00:00 2001 +From 6e7a9770e4f18f931f5caca7dec2a197e779afbc Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Mon, 24 Jun 2024 10:49:12 +0200 -Subject: [PATCH] use proper error handling in get_seed +Subject: [PATCH 15/16] use proper error handling in get_seed --- src/wallet/api/wallet.cpp | 17 ++++++++++++----- @@ -9,7 +9,7 @@ Subject: [PATCH] use proper error handling in get_seed 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index ac3e6d51e..8bdd75a5a 100644 +index 5ca190c7d..a307d35a7 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -880,12 +880,19 @@ bool WalletImpl::close(bool store) @@ -38,7 +38,7 @@ index ac3e6d51e..8bdd75a5a 100644 bool WalletImpl::getPolyseed(std::string &seed_words, std::string &passphrase) const diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index 23b56810e..f7bdf2429 100644 +index 7d97e683b..8e44806fc 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1452,11 +1452,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab diff --git a/patches/monero/0015-add-dummy-device-for-ledger.patch b/patches/monero/0016-add-dummy-device-for-ledger.patch similarity index 98% rename from patches/monero/0015-add-dummy-device-for-ledger.patch rename to patches/monero/0016-add-dummy-device-for-ledger.patch index 4f88774b..d4ab5fea 100644 --- a/patches/monero/0015-add-dummy-device-for-ledger.patch +++ b/patches/monero/0016-add-dummy-device-for-ledger.patch @@ -1,7 +1,7 @@ -From 07f41c8afda9eafca519d44f5c6c34316f5ebb71 Mon Sep 17 00:00:00 2001 +From 6b40191d35df998280e1d6e19ff9bf4bce54d5bf Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Wed, 26 Jun 2024 15:04:38 +0200 -Subject: [PATCH] add dummy device for ledger +Subject: [PATCH 16/16] add dummy device for ledger --- CMakeLists.txt | 6 +- @@ -414,7 +414,7 @@ index 03058c4f1..506f27c4a 100644 unsigned char buffer_send[BUFFER_SEND_SIZE]; unsigned int length_recv; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp -index 8bdd75a5a..d8661b213 100644 +index a307d35a7..3ead385ec 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -49,6 +49,9 @@ @@ -427,7 +427,7 @@ index 8bdd75a5a..d8661b213 100644 using namespace std; using namespace cryptonote; -@@ -3299,4 +3302,94 @@ uint64_t WalletImpl::getBytesSent() +@@ -3298,4 +3301,94 @@ uint64_t WalletImpl::getBytesSent() return m_wallet->get_bytes_sent(); } diff --git a/patches/monero/0017-added-deps.patch b/patches/monero/0017-added-deps.patch new file mode 100644 index 00000000..4edacce6 --- /dev/null +++ b/patches/monero/0017-added-deps.patch @@ -0,0 +1,29 @@ +From 8f0b07a685b5971f4deb66bb8c53e6da4065370c Mon Sep 17 00:00:00 2001 +From: cyan +Date: Thu, 25 Jul 2024 20:06:29 +0000 +Subject: [PATCH] added deps + +--- + external/polyseed | 1 + + external/utf8proc | 1 + + 2 files changed, 2 insertions(+) + create mode 160000 external/polyseed + create mode 160000 external/utf8proc + +diff --git a/external/polyseed b/external/polyseed +new file mode 160000 +index 000000000..dfb05d8ed +--- /dev/null ++++ b/external/polyseed +@@ -0,0 +1 @@ ++Subproject commit dfb05d8edb682b0e8f743b1b70c9131712ff4157 +diff --git a/external/utf8proc b/external/utf8proc +new file mode 160000 +index 000000000..5568eff49 +--- /dev/null ++++ b/external/utf8proc +@@ -0,0 +1 @@ ++Subproject commit 5568eff49a6bf417b6fdef2808df9db8d3d68a76 +-- +2.39.2 + diff --git a/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h b/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h index a28e9fdf..9a6f5526 100644 --- a/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h +++ b/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h @@ -1,6 +1,6 @@ #ifndef MONEROC_CHECKSUMS #define MONEROC_CHECKSUMS const char * WOWNERO_wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; -const char * WOWNERO_wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739"; +const char * WOWNERO_wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; const char * WOWNERO_wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; #endif From 1a3b381e5f3200463b025fe4b3f9e331db976ba5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 04:59:29 +0000 Subject: [PATCH 11/28] chore(deps): update external/ios-cmake digest to ad96a37 --- external/ios-cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/ios-cmake b/external/ios-cmake index 06465b27..ad96a372 160000 --- a/external/ios-cmake +++ b/external/ios-cmake @@ -1 +1 @@ -Subproject commit 06465b27698424cf4a04a5ca4904d50a3c966c45 +Subproject commit ad96a372b168930c2a1ff9455e1a9ccb13021617 From e6d6131c09a8f93bd1b7e99dea18a128aa519cde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 04:58:15 +0000 Subject: [PATCH 12/28] chore(deps): update external/libexpat digest to ed4090a --- external/libexpat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libexpat b/external/libexpat index 3bab6c09..ed4090af 160000 --- a/external/libexpat +++ b/external/libexpat @@ -1 +1 @@ -Subproject commit 3bab6c09bbe8bf42d84b81563ddbcf4cca4be838 +Subproject commit ed4090af841ebd8a7b2e367280407d74e748a7dd From 294b593db30e8803586dfd0f47e716ce1200c766 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 06:46:43 +0000 Subject: [PATCH 13/28] chore(deps): update external/libzmq digest to 0ed7a08 --- external/libzmq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libzmq b/external/libzmq index b95d9493..0ed7a08c 160000 --- a/external/libzmq +++ b/external/libzmq @@ -1 +1 @@ -Subproject commit b95d94935ed107679fd0ad9efd2f3d47309b6fd3 +Subproject commit 0ed7a08cd946e0832ac4655b7a76c09ac221f63b From b1f49d4b99aed681c8a96bf48a1fc56108babb3b Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Wed, 28 Aug 2024 09:12:32 +0200 Subject: [PATCH 14/28] fix multdest mixing --- monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp | 3 +-- wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp b/monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp index 13f99d50..407d7007 100644 --- a/monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp +++ b/monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp @@ -1311,8 +1311,7 @@ void* MONERO_Wallet_createTransactionMultDest(void* wallet_ptr, const char* dst_ uint32_t subaddr_account, const char* preferredInputs, const char* preferredInputs_separator) { Monero::Wallet *wallet = reinterpret_cast(wallet_ptr); - std::set dst_addr_ = splitString(std::string(dst_addr_list), std::string(dst_addr_list_separator)); - std::vector dst_addr(dst_addr_.begin(), dst_addr_.end()); + std::vector dst_addr = splitStringVector(std::string(dst_addr_list), std::string(dst_addr_list_separator)); Monero::optional> optAmount; if (!amount_sweep_all) { diff --git a/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp b/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp index 9e953b52..23474964 100644 --- a/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp +++ b/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp @@ -1252,8 +1252,7 @@ void* WOWNERO_Wallet_createTransactionMultDest(void* wallet_ptr, const char* dst uint32_t subaddr_account, const char* preferredInputs, const char* preferredInputs_separator) { Monero::Wallet *wallet = reinterpret_cast(wallet_ptr); - std::set dst_addr_ = splitString(std::string(dst_addr_list), std::string(dst_addr_list_separator)); - std::vector dst_addr(dst_addr_.begin(), dst_addr_.end()); + std::set dst_addr = splitStringVector(std::string(dst_addr_list), std::string(dst_addr_list_separator)); Monero::optional> optAmount; if (!amount_sweep_all) { From 00a935025e1f405ae84f0618669011b12e6a6514 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Wed, 28 Aug 2024 11:07:35 +0200 Subject: [PATCH 15/28] update checksum --- generate_checksum.sh | 2 +- impls/monero.dart/lib/src/checksum_monero.dart | 2 +- impls/monero.dart/lib/src/checksum_wownero.dart | 2 +- monero_libwallet2_api_c/src/main/cpp/monero_checksum.h | 2 +- wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/generate_checksum.sh b/generate_checksum.sh index 7fcca708..5847ff51 100755 --- a/generate_checksum.sh +++ b/generate_checksum.sh @@ -1,6 +1,6 @@ #!/bin/bash cd "$(realpath $(dirname $0))" - +function sha256sum() { shasum -a 256 "$@" ; } && export -f sha256sum for coin in monero wownero; do submodule_hash=$(git ls-tree HEAD ${coin} | xargs | awk '{ print $3 }') diff --git a/impls/monero.dart/lib/src/checksum_monero.dart b/impls/monero.dart/lib/src/checksum_monero.dart index 364e6189..4ab72a38 100644 --- a/impls/monero.dart/lib/src/checksum_monero.dart +++ b/impls/monero.dart/lib/src/checksum_monero.dart @@ -1,4 +1,4 @@ // ignore_for_file: constant_identifier_names const String wallet2_api_c_h_sha256 = "e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad"; -const String wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666-b089f9ee69924882c5d14dd1a6991deb05d9d1cd"; +const String wallet2_api_c_cpp_sha256 = "dca52ac9ee009fda9fb5726543a454885e61d8eb74fb33112288029ed625bec5-b089f9ee69924882c5d14dd1a6991deb05d9d1cd"; const String wallet2_api_c_exp_sha256 = "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c"; diff --git a/impls/monero.dart/lib/src/checksum_wownero.dart b/impls/monero.dart/lib/src/checksum_wownero.dart index 5b71c284..8d08889f 100644 --- a/impls/monero.dart/lib/src/checksum_wownero.dart +++ b/impls/monero.dart/lib/src/checksum_wownero.dart @@ -1,4 +1,4 @@ // ignore_for_file: constant_identifier_names const String wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; -const String wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; +const String wallet2_api_c_cpp_sha256 = "28e4d44c565cd7d97d3f18cdd322be48f89dc9fded82fb533af56a8eaa4e0bda-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; const String wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; diff --git a/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h b/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h index f07cafe3..20cbeaeb 100644 --- a/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h +++ b/monero_libwallet2_api_c/src/main/cpp/monero_checksum.h @@ -1,6 +1,6 @@ #ifndef MONEROC_CHECKSUMS #define MONEROC_CHECKSUMS const char * MONERO_wallet2_api_c_h_sha256 = "e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad"; -const char * MONERO_wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666-b089f9ee69924882c5d14dd1a6991deb05d9d1cd"; +const char * MONERO_wallet2_api_c_cpp_sha256 = "dca52ac9ee009fda9fb5726543a454885e61d8eb74fb33112288029ed625bec5-b089f9ee69924882c5d14dd1a6991deb05d9d1cd"; const char * MONERO_wallet2_api_c_exp_sha256 = "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c"; #endif diff --git a/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h b/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h index 9a6f5526..b7ff10c2 100644 --- a/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h +++ b/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h @@ -1,6 +1,6 @@ #ifndef MONEROC_CHECKSUMS #define MONEROC_CHECKSUMS const char * WOWNERO_wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; -const char * WOWNERO_wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; +const char * WOWNERO_wallet2_api_c_cpp_sha256 = "28e4d44c565cd7d97d3f18cdd322be48f89dc9fded82fb533af56a8eaa4e0bda-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; const char * WOWNERO_wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; #endif From 3cb38bee9385faf46b03fd73aab85f3ac4115bf7 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Wed, 28 Aug 2024 11:08:19 +0200 Subject: [PATCH 16/28] std::set -> std::vector --- impls/monero.dart/lib/src/checksum_wownero.dart | 2 +- wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp | 2 +- wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/impls/monero.dart/lib/src/checksum_wownero.dart b/impls/monero.dart/lib/src/checksum_wownero.dart index 8d08889f..7d501c61 100644 --- a/impls/monero.dart/lib/src/checksum_wownero.dart +++ b/impls/monero.dart/lib/src/checksum_wownero.dart @@ -1,4 +1,4 @@ // ignore_for_file: constant_identifier_names const String wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; -const String wallet2_api_c_cpp_sha256 = "28e4d44c565cd7d97d3f18cdd322be48f89dc9fded82fb533af56a8eaa4e0bda-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; +const String wallet2_api_c_cpp_sha256 = "07d67f34a07869aaa4af6ca04e142dbad2fb1fba0e2ebdefd22bc333fd982e25-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; const String wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; diff --git a/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp b/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp index 23474964..19a14ba5 100644 --- a/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp +++ b/wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp @@ -1252,7 +1252,7 @@ void* WOWNERO_Wallet_createTransactionMultDest(void* wallet_ptr, const char* dst uint32_t subaddr_account, const char* preferredInputs, const char* preferredInputs_separator) { Monero::Wallet *wallet = reinterpret_cast(wallet_ptr); - std::set dst_addr = splitStringVector(std::string(dst_addr_list), std::string(dst_addr_list_separator)); + std::vector dst_addr = splitStringVector(std::string(dst_addr_list), std::string(dst_addr_list_separator)); Monero::optional> optAmount; if (!amount_sweep_all) { diff --git a/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h b/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h index b7ff10c2..40723cc8 100644 --- a/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h +++ b/wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h @@ -1,6 +1,6 @@ #ifndef MONEROC_CHECKSUMS #define MONEROC_CHECKSUMS const char * WOWNERO_wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; -const char * WOWNERO_wallet2_api_c_cpp_sha256 = "28e4d44c565cd7d97d3f18cdd322be48f89dc9fded82fb533af56a8eaa4e0bda-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; +const char * WOWNERO_wallet2_api_c_cpp_sha256 = "07d67f34a07869aaa4af6ca04e142dbad2fb1fba0e2ebdefd22bc333fd982e25-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795"; const char * WOWNERO_wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; #endif From 811ade01161acdf8dd9d8d5354aac989007466ce Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Mon, 2 Sep 2024 16:43:05 +0200 Subject: [PATCH 17/28] Fix build issues on latest ubuntu --- ...0016-uint64_t-missing-definition-fix.patch | 25 +++++++++++++++++++ ...0015-uint64_t-missing-definition-fix.patch | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 patches/monero/0016-uint64_t-missing-definition-fix.patch create mode 100644 patches/wownero/0015-uint64_t-missing-definition-fix.patch diff --git a/patches/monero/0016-uint64_t-missing-definition-fix.patch b/patches/monero/0016-uint64_t-missing-definition-fix.patch new file mode 100644 index 00000000..e555829d --- /dev/null +++ b/patches/monero/0016-uint64_t-missing-definition-fix.patch @@ -0,0 +1,25 @@ +From 9fe376e0024dfdbea47219477e797cb20c56305f Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Mon, 2 Sep 2024 16:40:31 +0200 +Subject: [PATCH] uint64_t missing definition fix + +--- + contrib/epee/include/net/http_base.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h +index 4af4da790..ae4c0d05e 100644 +--- a/contrib/epee/include/net/http_base.h ++++ b/contrib/epee/include/net/http_base.h +@@ -28,7 +28,7 @@ + + #pragma once + #include "memwipe.h" +- ++#include + #include + + #include +-- +2.43.0 + diff --git a/patches/wownero/0015-uint64_t-missing-definition-fix.patch b/patches/wownero/0015-uint64_t-missing-definition-fix.patch new file mode 100644 index 00000000..e555829d --- /dev/null +++ b/patches/wownero/0015-uint64_t-missing-definition-fix.patch @@ -0,0 +1,25 @@ +From 9fe376e0024dfdbea47219477e797cb20c56305f Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Mon, 2 Sep 2024 16:40:31 +0200 +Subject: [PATCH] uint64_t missing definition fix + +--- + contrib/epee/include/net/http_base.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h +index 4af4da790..ae4c0d05e 100644 +--- a/contrib/epee/include/net/http_base.h ++++ b/contrib/epee/include/net/http_base.h +@@ -28,7 +28,7 @@ + + #pragma once + #include "memwipe.h" +- ++#include + #include + + #include +-- +2.43.0 + From 1e22390f512f97c89b6b4c75da4958c16316da22 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 4 Sep 2024 14:57:12 +0200 Subject: [PATCH 18/28] fix find wallets (#46) * Update WalletManager_findWallets * prevent crash when there are no wallets found * return List instead of colon separated String --- impls/monero.dart/lib/monero.dart | 11 +++++++---- impls/monero.dart/lib/wownero.dart | 12 +++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/impls/monero.dart/lib/monero.dart b/impls/monero.dart/lib/monero.dart index b30bd3fb..997f1b61 100644 --- a/impls/monero.dart/lib/monero.dart +++ b/impls/monero.dart/lib/monero.dart @@ -3585,7 +3585,8 @@ bool WalletManager_verifyWalletPassword( return s; } -String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) { +List WalletManager_findWallets(WalletManager wm_ptr, + {required String path}) { debugStart?.call('MONERO_WalletManager_findWallets'); lib ??= MoneroC(DynamicLibrary.open(libPath)); try { @@ -3595,13 +3596,15 @@ String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) { .cast(); final str = strPtr.toDartString(); calloc.free(path_); - MONERO_free(strPtr.cast()); + if (str.isNotEmpty) { + MONERO_free(strPtr.cast()); + } debugEnd?.call('MONERO_WalletManager_findWallets'); - return str; + return str.split(";"); } catch (e) { errorHandler?.call('MONERO_WalletManager_findWallets', e); debugEnd?.call('MONERO_WalletManager_findWallets'); - return ""; + return []; } } diff --git a/impls/monero.dart/lib/wownero.dart b/impls/monero.dart/lib/wownero.dart index 5a0a288a..e87488cc 100644 --- a/impls/monero.dart/lib/wownero.dart +++ b/impls/monero.dart/lib/wownero.dart @@ -3220,7 +3220,8 @@ bool WalletManager_verifyWalletPassword( return s; } -String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) { +List WalletManager_findWallets(WalletManager wm_ptr, + {required String path}) { debugStart?.call('WOWNERO_WalletManager_findWallets'); lib ??= WowneroC(DynamicLibrary.open(libPath)); try { @@ -3230,13 +3231,15 @@ String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) { .cast(); final str = strPtr.toDartString(); calloc.free(path_); - WOWNERO_free(strPtr.cast()); + if (str.isNotEmpty) { + WOWNERO_free(strPtr.cast()); + } debugEnd?.call('WOWNERO_WalletManager_findWallets'); - return str; + return str.split(";"); } catch (e) { errorHandler?.call('WOWNERO_WalletManager_findWallets', e); debugEnd?.call('WOWNERO_WalletManager_findWallets'); - return ""; + return []; } } @@ -3606,7 +3609,6 @@ int WOWNERO_deprecated_14WordSeedHeight({ return s; } - String WOWNERO_checksum_wallet2_api_c_h() { debugStart?.call('WOWNERO_checksum_wallet2_api_c_h'); lib ??= WowneroC(DynamicLibrary.open(libPath)); From 4f844740bced43b5653d3152717f8b1e10b13293 Mon Sep 17 00:00:00 2001 From: cyan Date: Sun, 8 Sep 2024 17:52:09 +0200 Subject: [PATCH 19/28] use less memory for debugCallLength Map (#48) * use less memory for debugCallLength Map * ignore errors in default debug functions --- impls/monero.dart/lib/monero.dart | 34 ++++++++++++++++++++++++------ impls/monero.dart/lib/wownero.dart | 34 ++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/impls/monero.dart/lib/monero.dart b/impls/monero.dart/lib/monero.dart index 997f1b61..4fcc9709 100644 --- a/impls/monero.dart/lib/monero.dart +++ b/impls/monero.dart/lib/monero.dart @@ -101,14 +101,36 @@ final Stopwatch sw = Stopwatch()..start(); bool printStarts = false; void Function(String call)? debugStart = (call) { - if (printStarts) print("MONERO: $call"); - debugCallLength[call] ??= []; - debugCallLength[call]!.add(sw.elapsedMicroseconds); + try { + if (printStarts) print("MONERO: $call"); + debugCallLength[call] ??= []; + debugCallLength[call]!.add(sw.elapsedMicroseconds); + } catch (e) {} }; +void debugChores() { + for (var key in debugCallLength.keys) { + if (debugCallLength[key]!.length > 1000000) { + final elm = + debugCallLength[key]!.reduce((value, element) => value + element); + debugCallLength[key]!.clear(); + debugCallLength["${key}_1M"] ??= []; + debugCallLength["${key}_1M"]!.add(elm); + } + } +} + +int debugCount = 0; + void Function(String call)? debugEnd = (call) { - final id = debugCallLength[call]!.length - 1; - debugCallLength[call]![id] = - sw.elapsedMicroseconds - debugCallLength[call]![id]; + try { + final id = debugCallLength[call]!.length - 1; + if (++debugCount > 1000000) { + debugCount = 0; + debugChores(); + } + debugCallLength[call]![id] = + sw.elapsedMicroseconds - debugCallLength[call]![id]; + } catch (e) {} }; void Function(String call, dynamic error)? errorHandler = (call, error) { print("$call: $error"); diff --git a/impls/monero.dart/lib/wownero.dart b/impls/monero.dart/lib/wownero.dart index e87488cc..d355005b 100644 --- a/impls/monero.dart/lib/wownero.dart +++ b/impls/monero.dart/lib/wownero.dart @@ -101,14 +101,36 @@ final Stopwatch sw = Stopwatch()..start(); bool printStarts = false; void Function(String call)? debugStart = (call) { - if (printStarts) print("MONERO: $call"); - debugCallLength[call] ??= []; - debugCallLength[call]!.add(sw.elapsedMicroseconds); + try { + if (printStarts) print("MONERO: $call"); + debugCallLength[call] ??= []; + debugCallLength[call]!.add(sw.elapsedMicroseconds); + } catch (e) {} }; +void debugChores() { + for (var key in debugCallLength.keys) { + if (debugCallLength[key]!.length > 1000000) { + final elm = + debugCallLength[key]!.reduce((value, element) => value + element); + debugCallLength[key]!.clear(); + debugCallLength["${key}_1M"] ??= []; + debugCallLength["${key}_1M"]!.add(elm); + } + } +} + +int debugCount = 0; + void Function(String call)? debugEnd = (call) { - final id = debugCallLength[call]!.length - 1; - debugCallLength[call]![id] = - sw.elapsedMicroseconds - debugCallLength[call]![id]; + try { + final id = debugCallLength[call]!.length - 1; + if (++debugCount > 1000000) { + debugCount = 0; + debugChores(); + } + debugCallLength[call]![id] = + sw.elapsedMicroseconds - debugCallLength[call]![id]; + } catch (e) {} }; void Function(String call, dynamic error)? errorHandler = (call, error) { print("$call: $error"); From 0868b9bc3c4a59ddc5bfff13462e8840cffb7084 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:57:39 +0000 Subject: [PATCH 20/28] chore(deps): update dependency ffigen to v14 --- impls/monero.dart/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impls/monero.dart/pubspec.yaml b/impls/monero.dart/pubspec.yaml index 4f48698c..d85d6009 100644 --- a/impls/monero.dart/pubspec.yaml +++ b/impls/monero.dart/pubspec.yaml @@ -12,4 +12,4 @@ dependencies: dev_dependencies: lints: ^4.0.0 test: ^1.24.0 - ffigen: ^13.0.0 \ No newline at end of file + ffigen: ^14.0.0 \ No newline at end of file From 9d9a83a735633f9c45d428137c8d7fc7bf6cf5f5 Mon Sep 17 00:00:00 2001 From: cyan Date: Mon, 9 Sep 2024 09:04:47 +0000 Subject: [PATCH 21/28] add missing secrets --- .github/workflows/full_check.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/full_check.yaml b/.github/workflows/full_check.yaml index 3c8dd88a..c2c460f2 100644 --- a/.github/workflows/full_check.yaml +++ b/.github/workflows/full_check.yaml @@ -621,6 +621,8 @@ jobs: echo "const nanoNowNodesApiKey = '';" >> cw_nano/lib/.secrets.g.dart echo "const tronGridApiKey = '';" >> cw_tron/lib/.secrets.g.dart echo "const tronNowNodesApiKey = '';" >> cw_tron/lib/.secrets.g.dart + echo "const stealthExBearerToken = '';" >> lib/.secrets.g.dart + echo "const stealthExAdditionalFeePercent = '';" >> lib/.secrets.g.dart - name: Rename app run: | From 51e4a30a34f74eb0ecc4dd167cddec4f60dcfe0f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:57:19 +0000 Subject: [PATCH 22/28] chore(deps): update external/libzmq digest to 64db7d2 --- external/libzmq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libzmq b/external/libzmq index 0ed7a08c..64db7d28 160000 --- a/external/libzmq +++ b/external/libzmq @@ -1 +1 @@ -Subproject commit 0ed7a08cd946e0832ac4655b7a76c09ac221f63b +Subproject commit 64db7d28fea695132834f6d2c5949cfea2f22d01 From f90b1f57b1337671b145e53e95ff5c2ecf67224d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:55:11 +0000 Subject: [PATCH 23/28] chore(deps): update external/libexpat digest to 624da0f --- external/libexpat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libexpat b/external/libexpat index ed4090af..624da0f5 160000 --- a/external/libexpat +++ b/external/libexpat @@ -1 +1 @@ -Subproject commit ed4090af841ebd8a7b2e367280407d74e748a7dd +Subproject commit 624da0f593bb8d7e146b9f42b06d8e6c80d032a3 From 0b91e91d19d4a11d753f9bdda56398bcfcdb4260 Mon Sep 17 00:00:00 2001 From: cyan Date: Mon, 16 Sep 2024 17:15:43 +0000 Subject: [PATCH 24/28] add cakewallet secrets --- .github/workflows/full_check.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/full_check.yaml b/.github/workflows/full_check.yaml index c2c460f2..a7edcc00 100644 --- a/.github/workflows/full_check.yaml +++ b/.github/workflows/full_check.yaml @@ -623,6 +623,10 @@ jobs: echo "const tronNowNodesApiKey = '';" >> cw_tron/lib/.secrets.g.dart echo "const stealthExBearerToken = '';" >> lib/.secrets.g.dart echo "const stealthExAdditionalFeePercent = '';" >> lib/.secrets.g.dart + echo "const letsExchangeBearerToken = '';" >> lib/.secrets.g.dart + echo "const letsExchangeAffiliateId = '';" >> lib/.secrets.g.dart + echo "const etherScanApiKey = '';" >> lib/.secrets.g.dart + echo "const polygonScanApiKey = '';" >> lib/.secrets.g.dart - name: Rename app run: | From d1940944943cd79ce1f2b2080456dd28bec5c36f Mon Sep 17 00:00:00 2001 From: cyan Date: Thu, 19 Sep 2024 10:59:07 +0200 Subject: [PATCH 25/28] feat: deno ffi bindings (#40) * initial ts commit * monero.ts improvements * test on latest, build on debian:bookworm * feat: upstream changes to bindings * chore: update checksums * feat: allow manually loading dylib * chore: add readme * fix: free strings after being read to prevent potential memory leaks * fix: load dylib * fix: checksum checks segfaulting because of freeing const variables --------- Co-authored-by: Mateusz Franik <47059999+Im-Beast@users.noreply.github.com> Co-authored-by: Im-Beast --- .github/workflows/full_check.yaml | 121 ++++- .vscode/settings.json | 3 + generate_checksum.sh | 14 +- impls/monero.ts/.gitignore | 2 + impls/monero.ts/README.md | 42 ++ impls/monero.ts/checksum.ts | 65 +++ impls/monero.ts/checksum_monero.ts | 5 + impls/monero.ts/checksum_wownero.ts | 5 + impls/monero.ts/deno.jsonc | 5 + impls/monero.ts/mod.ts | 6 + impls/monero.ts/src/bindings.ts | 562 +++++++++++++++++++++ impls/monero.ts/src/pending_transaction.ts | 81 +++ impls/monero.ts/src/transaction_history.ts | 38 ++ impls/monero.ts/src/transaction_info.ts | 104 ++++ impls/monero.ts/src/utils.ts | 25 + impls/monero.ts/src/wallet.ts | 304 +++++++++++ impls/monero.ts/src/wallet_manager.ts | 27 + 17 files changed, 1406 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 impls/monero.ts/.gitignore create mode 100644 impls/monero.ts/README.md create mode 100644 impls/monero.ts/checksum.ts create mode 100644 impls/monero.ts/checksum_monero.ts create mode 100644 impls/monero.ts/checksum_wownero.ts create mode 100644 impls/monero.ts/deno.jsonc create mode 100644 impls/monero.ts/mod.ts create mode 100644 impls/monero.ts/src/bindings.ts create mode 100644 impls/monero.ts/src/pending_transaction.ts create mode 100644 impls/monero.ts/src/transaction_history.ts create mode 100644 impls/monero.ts/src/transaction_info.ts create mode 100644 impls/monero.ts/src/utils.ts create mode 100644 impls/monero.ts/src/wallet.ts create mode 100644 impls/monero.ts/src/wallet_manager.ts diff --git a/.github/workflows/full_check.yaml b/.github/workflows/full_check.yaml index a7edcc00..03e6f377 100644 --- a/.github/workflows/full_check.yaml +++ b/.github/workflows/full_check.yaml @@ -137,7 +137,7 @@ jobs: coin: [monero, wownero] runs-on: ubuntu-latest container: - image: debian:bookworm + image: debian:bullseye steps: - name: Install dependencies run: | @@ -698,6 +698,123 @@ jobs: with: name: ${{ matrix.coin }} xmruw apk path: unnamed_monero_wallet/build/app/outputs/flutter-apk/*.apk + bulk_lib_release: + name: create single release file + runs-on: ubuntu-latest + needs: [ + lib_mingw, lib_android, lib_linux, lib_sailfishos_aarch64, lib_sailfishos_i486, lib_darwin, lib_macos, lib_ios + ] + steps: + - uses: actions/download-artifact@v4 + with: + name: android monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: android wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: darwin monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: darwin wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: ios monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: ios wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: linux monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: linux wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: macos monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: macos wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: mingw monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: mingw wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: sfos aarch64 monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: sfos aarch64 wownero + path: release/wownero + - uses: actions/download-artifact@v4 + with: + name: sfos_i486 monero + path: release/monero + - uses: actions/download-artifact@v4 + with: + name: sfos_i486 wownero + path: release/wownero + - name: zip release dir + run: zip -r release-bundle.zip release + - name: Release + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + files: release-bundle.zip + token: ${{ secrets.CUSTOM_GITHUB_TOKEN }} + - name: Upload lib + uses: actions/upload-artifact@v4 + with: + name: release-bulk + path: release + deno_monerots_test_linux: + name: test ts library + runs-on: ubuntu-24.04 + needs: [ + lib_linux + ] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + - uses: actions/download-artifact@v4 + with: + name: linux monero + path: release/monero + - name: unpack and move monero_c + run: | + unxz -f -k release/*/*.xz + - uses: denoland/setup-deno@v1 + with: + deno-version: vx.x.x + - name: Create symlink + run: | + cd impls/monero.ts + mkdir lib + cd lib + ln -s ../../../release/monero/x86_64-linux-gnu_libwallet2_api_c.so + mv x86_64-linux-gnu_libwallet2_api_c.so monero_libwallet2_api_c.so + cd .. + - name: Run tests + run: | + cd impls/monero.ts + deno run --unstable-ffi --allow-ffi checksum.ts comment_pr: name: comment on pr @@ -752,4 +869,4 @@ jobs: with: issue-number: ${{steps.get_issue_number.outputs.result}} body: | - [download artifacts #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) \ No newline at end of file + [download artifacts #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..b943dbc7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} \ No newline at end of file diff --git a/generate_checksum.sh b/generate_checksum.sh index 5847ff51..4b82e53d 100755 --- a/generate_checksum.sh +++ b/generate_checksum.sh @@ -1,6 +1,11 @@ #!/bin/bash cd "$(realpath $(dirname $0))" -function sha256sum() { shasum -a 256 "$@" ; } && export -f sha256sum + +if [[ "$(uname)" == "Darwin" ]]; +then + function sha256sum() { shasum -a 256 "$@" ; } && export -f sha256sum +fi + for coin in monero wownero; do submodule_hash=$(git ls-tree HEAD ${coin} | xargs | awk '{ print $3 }') @@ -22,6 +27,13 @@ EOF const String wallet2_api_c_h_sha256 = "${COIN_wallet2_api_c_h_sha256}"; const String wallet2_api_c_cpp_sha256 = "${COIN_wallet2_api_c_cpp_sha256}"; const String wallet2_api_c_exp_sha256 = "${COIN_wallet2_api_c_exp_sha256}"; +EOF + cat > impls/monero.ts/checksum_${coin}.ts << EOF +export const ${coin}Checksum = { + wallet2_api_c_h_sha256: "${COIN_wallet2_api_c_h_sha256}", + wallet2_api_c_cpp_sha256: "${COIN_wallet2_api_c_cpp_sha256}", + wallet2_api_c_exp_sha256: "${COIN_wallet2_api_c_exp_sha256}", +} EOF done diff --git a/impls/monero.ts/.gitignore b/impls/monero.ts/.gitignore new file mode 100644 index 00000000..8b61d3b7 --- /dev/null +++ b/impls/monero.ts/.gitignore @@ -0,0 +1,2 @@ +*_libwallet2_api_c.* +lib diff --git a/impls/monero.ts/README.md b/impls/monero.ts/README.md new file mode 100644 index 00000000..e3b20f6b --- /dev/null +++ b/impls/monero.ts/README.md @@ -0,0 +1,42 @@ +# monero.ts + +`monero_c` bindings for Deno. + +## Usage + +This library does not ship with `monero_c` libraries.\ +To use these bindings you have to bring your own `monero_c` libraries.\ +There are at least two ways to do so: +- Ahead-of-time, during builds where you only ship necessary library for a given platform.\ + See [monero-tui](https://github.com/Im-Beast/monero-tui/blob/main/.github/workflows/dev-build.yml) build workflow as an example of doing so. + ```ts + import { loadDylib, Wallet, WalletManager } from "https://raw.githubusercontent.com/MrCyjaneK/monero_c/master/impls/monero.ts/mod.ts"; + + // Try to load dylib from the default lib/* path + loadDylib(); + + const wm = await WalletManager.new(); + const wallet = await Wallet.create(wm, "./my_wallet", "password"); + + console.log(await wallet.address()); + + await wallet.store(); + ``` +- Just-in-time, where you download and cache the library at runtime.\ + You can use something like [plug](https://jsr.io/@denosaurs/plug) to achieve the result. + ```ts + import { dlopen } from "jsr:@denosaurs/plug"; + // It's recommened to put the monero.ts github link into your import_map to reduce the url clutter + import { loadDylib, symbols, Wallet, WalletManager } from "https://raw.githubusercontent.com/MrCyjaneK/monero_c/master/impls/monero.ts/mod.ts"; + + // Load dylib loaded by plug + const lib = await dlopen(..., symbols); + loadDylib(lib); + + const wm = await WalletManager.new(); + const wallet = await Wallet.create(wm, "./my_wallet", "password"); + + console.log(await wallet.address()); + + await wallet.store(); + ``` diff --git a/impls/monero.ts/checksum.ts b/impls/monero.ts/checksum.ts new file mode 100644 index 00000000..22d30383 --- /dev/null +++ b/impls/monero.ts/checksum.ts @@ -0,0 +1,65 @@ +import { moneroChecksum } from "./checksum_monero.ts"; +import { readCString } from "./src/utils.ts"; +import { dylib, loadDylib } from "./src/bindings.ts"; + +loadDylib(); + +export class ChecksumError extends Error { + readonly code: number; + readonly errors: string[]; + + constructor(code: number, errors: string[]) { + super("MoneroC binding checksum failed:\n" + errors.join("\n")); + this.code = code; + this.errors = errors; + } +} + +/** + * Validates MoneroC checksums + * @returns {null} if checksums are correct + * @returns {ChecksumError} which contains information about why checksum failed + */ +export async function validateChecksum(): Promise { + const cppHeaderHash = await readCString(await dylib.symbols.MONERO_checksum_wallet2_api_c_h(), false); + const tsHeaderHash = moneroChecksum.wallet2_api_c_h_sha256; + + const errors: string[] = []; + + let errorCode = 0; + if (cppHeaderHash !== tsHeaderHash) { + errors.push("ERR: Header file check mismatch"); + errorCode++; + } + + const cppSourceHash = await readCString(await dylib.symbols.MONERO_checksum_wallet2_api_c_cpp(), false); + const tsSourceHash = moneroChecksum.wallet2_api_c_cpp_sha256; + if (cppSourceHash !== tsSourceHash) { + errors.push(`ERR: CPP source file check mismatch ${cppSourceHash} == ${tsSourceHash}`); + errorCode++; + } + + const cppExportHash = await readCString(await dylib.symbols.MONERO_checksum_wallet2_api_c_exp(), false); + const tsExportHash = moneroChecksum.wallet2_api_c_exp_sha256; + if (cppExportHash !== tsExportHash) { + if (Deno.build.os !== "darwin") { + errors.push("WARN: EXP source file check mismatch"); + } else { + errors.push(`ERR: EXP source file check mismatch ${cppExportHash} == ${tsExportHash}`); + } + errorCode++; + } + + if (errorCode) { + return new ChecksumError(errorCode, errors); + } + + return null; +} + +if (import.meta.main) { + const maybeError = await validateChecksum(); + if (maybeError) { + throw maybeError; + } +} diff --git a/impls/monero.ts/checksum_monero.ts b/impls/monero.ts/checksum_monero.ts new file mode 100644 index 00000000..88406a0c --- /dev/null +++ b/impls/monero.ts/checksum_monero.ts @@ -0,0 +1,5 @@ +export const moneroChecksum = { + wallet2_api_c_h_sha256: "e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad", + wallet2_api_c_cpp_sha256: "dca52ac9ee009fda9fb5726543a454885e61d8eb74fb33112288029ed625bec5-b089f9ee69924882c5d14dd1a6991deb05d9d1cd", + wallet2_api_c_exp_sha256: "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c", +} diff --git a/impls/monero.ts/checksum_wownero.ts b/impls/monero.ts/checksum_wownero.ts new file mode 100644 index 00000000..8b2899c6 --- /dev/null +++ b/impls/monero.ts/checksum_wownero.ts @@ -0,0 +1,5 @@ +export const wowneroChecksum = { + wallet2_api_c_h_sha256: "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77", + wallet2_api_c_cpp_sha256: "07d67f34a07869aaa4af6ca04e142dbad2fb1fba0e2ebdefd22bc333fd982e25-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795", + wallet2_api_c_exp_sha256: "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4", +} diff --git a/impls/monero.ts/deno.jsonc b/impls/monero.ts/deno.jsonc new file mode 100644 index 00000000..a7b75eca --- /dev/null +++ b/impls/monero.ts/deno.jsonc @@ -0,0 +1,5 @@ +{ + "fmt": { + "lineWidth": 120 + } +} diff --git a/impls/monero.ts/mod.ts b/impls/monero.ts/mod.ts new file mode 100644 index 00000000..1eca7734 --- /dev/null +++ b/impls/monero.ts/mod.ts @@ -0,0 +1,6 @@ +export * from "./src/bindings.ts"; +export * from "./src/pending_transaction.ts"; +export * from "./src/transaction_history.ts"; +export * from "./src/transaction_info.ts"; +export * from "./src/wallet.ts"; +export * from "./src/wallet_manager.ts"; diff --git a/impls/monero.ts/src/bindings.ts b/impls/monero.ts/src/bindings.ts new file mode 100644 index 00000000..b854f7d3 --- /dev/null +++ b/impls/monero.ts/src/bindings.ts @@ -0,0 +1,562 @@ +export const symbols = { + "MONERO_WalletManagerFactory_getWalletManager": { + nonblocking: true, + parameters: [], + // void* + result: "pointer", + }, + + //#region WalletManager + "MONERO_WalletManager_createWallet": { + nonblocking: true, + // void* wm_ptr, const char* path, const char* password, const char* language, int networkType + parameters: ["pointer", "pointer", "pointer", "pointer", "i32"], + // void* + result: "pointer", + }, + "MONERO_WalletManager_openWallet": { + nonblocking: true, + // void* wm_ptr, const char* path, const char* password, int networkType + "parameters": ["pointer", "pointer", "pointer", "i32"], + // void* + result: "pointer", + }, + "MONERO_WalletManager_recoveryWallet": { + nonblocking: true, + // void* wm_ptr, const char* path, const char* password, const char* mnemonic, + // int networkType, uint64_t restoreHeight, uint64_t kdfRounds, const char* seedOffset + parameters: ["pointer", "pointer", "pointer", "pointer", "i32", "u64", "u64", "pointer"], + // void* + result: "pointer", + }, + "MONERO_WalletManager_blockchainHeight": { + nonblocking: true, + // void* wm_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_WalletManager_blockchainTargetHeight": { + nonblocking: true, + // void* wm_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_WalletManager_setDaemonAddress": { + nonblocking: true, + // void* wm_ptr, const char* address + parameters: ["pointer", "pointer"], + // void + result: "void", + }, + //#endregion + + //#region Wallet + "MONERO_Wallet_init": { + nonblocking: true, + // void* wallet_ptr, const char* daemon_address, uint64_t upper_transaction_size_limit, + // const char* daemon_username, const char* daemon_password, bool use_ssl, bool lightWallet, + // const char* proxy_address + parameters: ["pointer", "pointer", "u64", "pointer", "pointer", "bool", "bool", "pointer"], + // bool + result: "bool", + }, + "MONERO_Wallet_init3": { + nonblocking: true, + // void* wallet_ptr, const char* argv0, const char* default_log_base_name, + // const char* log_path, bool console + parameters: ["pointer", "pointer", "pointer", "pointer", "bool"], + // void + result: "void", + }, + "MONERO_Wallet_setTrustedDaemon": { + nonblocking: true, + // void* wallet_ptr, bool arg + parameters: ["pointer", "bool"], + // void + result: "void", + }, + "MONERO_Wallet_startRefresh": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // void + result: "void", + }, + "MONERO_Wallet_refreshAsync": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // void + result: "void", + }, + "MONERO_Wallet_blockChainHeight": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_Wallet_daemonBlockChainHeight": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_Wallet_synchronized": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // bool + result: "bool", + }, + "MONERO_Wallet_store": { + nonblocking: true, + // void* wallet_ptr, const char* path + parameters: ["pointer", "pointer"], + // bool + result: "bool", + }, + "MONERO_Wallet_address": { + nonblocking: true, + // void* wallet_ptr, uint64_t accountIndex, uint64_t addressIndex + parameters: ["pointer", "u64", "u64"], + // char* + result: "pointer", + }, + "MONERO_Wallet_balance": { + nonblocking: true, + // void* wallet_ptr, uint32_t accountIndex + parameters: ["pointer", "u32"], + // uint64_t + result: "u64", + }, + "MONERO_Wallet_unlockedBalance": { + nonblocking: true, + // void* wallet_ptr, uint32_t accountIndex + parameters: ["pointer", "u32"], + // uint64_t + result: "u64", + }, + "MONERO_Wallet_addSubaddressAccount": { + nonblocking: true, + // void* wallet_ptr, const char* label + parameters: ["pointer", "pointer"], + // void + result: "void", + }, + "MONERO_Wallet_numSubaddressAccounts": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // size_t + result: "usize", + }, + "MONERO_Wallet_addSubaddress": { + nonblocking: true, + // void* wallet_ptr, uint32_t accountIndex, const char* label + parameters: ["pointer", "u32", "pointer"], + // void + result: "void", + }, + "MONERO_Wallet_numSubaddresses": { + nonblocking: true, + // void* wallet_ptr, uint32_t accountIndex + parameters: ["pointer", "u32"], + // size_t + result: "usize", + }, + "MONERO_Wallet_getSubaddressLabel": { + nonblocking: true, + // void* wallet_ptr, uint32_t accountIndex, uint32_t addressIndex + parameters: ["pointer", "u32", "u32"], + // const char* + result: "pointer", + }, + "MONERO_Wallet_setSubaddressLabel": { + nonblocking: true, + // void* wallet_ptr, uint32_t accountIndex, uint32_t addressIndex, const char* label + parameters: ["pointer", "u32", "u32", "pointer"], + // void + result: "void", + }, + "MONERO_Wallet_status": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // int + result: "i32", + }, + "MONERO_Wallet_errorString": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // char* + result: "pointer", + }, + "MONERO_Wallet_history": { + nonblocking: true, + // void* wallet_ptr + parameters: ["pointer"], + // void* + result: "pointer", + }, + "MONERO_Wallet_createTransaction": { + nonblocking: true, + // void* wallet_ptr, const char* dst_addr, const char* payment_id + // uint64_t amount, uint32_t mixin_count, int pendingTransactionPriority, + // uint32_t subaddr_account, const char* preferredInputs, const char* separator + parameters: ["pointer", "pointer", "pointer", "u64", "u32", "i32", "u32", "pointer", "pointer"], + // void* + result: "pointer", + }, + "MONERO_Wallet_amountFromString": { + nonblocking: true, + // const char* amount + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + //#endregion + + //#region TransactionHistory + "MONERO_TransactionHistory_count": { + nonblocking: true, + // void* txHistory_ptr + parameters: ["pointer"], + // int + result: "i32", + }, + "MONERO_TransactionHistory_transaction": { + nonblocking: true, + // void* txHistory_ptr, int index + parameters: ["pointer", "i32"], + // void* + result: "pointer", + }, + "MONERO_TransactionHistory_transactionById": { + nonblocking: true, + // void* txHistory_ptr, const char* id + parameters: ["pointer", "pointer"], + // void* + result: "pointer", + }, + "MONERO_TransactionHistory_refresh": { + nonblocking: true, + // void* txHistory_ptr + parameters: ["pointer"], + // void + result: "void", + }, + "MONERO_TransactionHistory_setTxNote": { + nonblocking: true, + // void* txHistory_ptr, const char* txid, const char* note + parameters: ["pointer", "pointer", "pointer"], + // void + result: "void", + }, + //#endregion + + //#region TransactionInfo + "MONERO_TransactionInfo_direction": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // int + result: "i32", + }, + "MONERO_TransactionInfo_isPending": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // bool + result: "bool", + }, + "MONERO_TransactionInfo_isFailed": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // bool + result: "bool", + }, + "MONERO_TransactionInfo_isCoinbase": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // bool + result: "bool", + }, + "MONERO_TransactionInfo_amount": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_fee": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_blockHeight": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_description": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_TransactionInfo_subaddrIndex": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_TransactionInfo_subaddrAccount": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint32_t + result: "u32", + }, + "MONERO_TransactionInfo_label": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_TransactionInfo_confirmations": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_unlockTime": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_hash": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_TransactionInfo_timestamp": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_paymentId": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_TransactionInfo_transfers_count": { + nonblocking: true, + // void* txInfo_ptr + parameters: ["pointer"], + // int + result: "i32", + }, + "MONERO_TransactionInfo_transfers_amount": { + nonblocking: true, + // void* txInfo_ptr, int index + parameters: ["pointer", "i32"], + // uint64_t + result: "u64", + }, + "MONERO_TransactionInfo_transfers_address": { + nonblocking: true, + // void* txInfo_ptr, int index + parameters: ["pointer", "i32"], + // const char* + result: "pointer", + }, + //#endregion + + //#region PendingTransaction + "MONERO_PendingTransaction_status": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // int + result: "i32", + }, + "MONERO_PendingTransaction_errorString": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_commit": { + nonblocking: true, + // void* pendingTx_ptr, const char* filename, bool overwrite + parameters: ["pointer", "pointer", "bool"], + // bool + result: "bool", + }, + "MONERO_PendingTransaction_commitUR": { + nonblocking: true, + // void* pendingTx_ptr, int max_fragment_length + parameters: ["pointer", "i32"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_amount": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_PendingTransaction_dust": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_PendingTransaction_fee": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_PendingTransaction_txid": { + nonblocking: true, + // void* pendingTx_ptr, const char* separator + parameters: ["pointer", "pointer"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_txCount": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // uint64_t + result: "u64", + }, + "MONERO_PendingTransaction_subaddrAccount": { + nonblocking: true, + // void* pendingTx_ptr, const char* separator + parameters: ["pointer", "pointer"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_subaddrIndices": { + nonblocking: true, + // void* pendingTx_ptr, const char* separator + parameters: ["pointer", "pointer"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_multisigSignData": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_signMultisigTx": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // void + result: "void", + }, + "MONERO_PendingTransaction_signersKeys": { + nonblocking: true, + // void* pendingTx_ptr + parameters: ["pointer"], + // const char* + result: "pointer", + }, + "MONERO_PendingTransaction_hex": { + nonblocking: true, + // void* pendingTx_ptr, const char* separator + parameters: ["pointer", "pointer"], + // const char* + result: "pointer", + }, + //#endregion + + //#region Checksum + "MONERO_checksum_wallet2_api_c_h": { + nonblocking: true, + parameters: [], + // const char* + result: "pointer", + }, + "MONERO_checksum_wallet2_api_c_cpp": { + nonblocking: true, + parameters: [], + // const char* + result: "pointer", + }, + "MONERO_checksum_wallet2_api_c_exp": { + nonblocking: true, + parameters: [], + // const char* + result: "pointer", + }, + //#endregion + + "MONERO_free": { + nonblocking: true, + // void* ptr + parameters: ["pointer"], + // void + result: "void", + }, +} as const; + +type MoneroTsDylib = Deno.DynamicLibrary; + +export let dylib: MoneroTsDylib; +export function loadDylib(newDylib?: MoneroTsDylib) { + if (newDylib) { + dylib = newDylib; + return; + } + + let libPath: string; + switch (Deno.build.os) { + case "darwin": + libPath = "./lib/monero_libwallet2_api_c.dylib"; + break; + case "android": + libPath = "./lib/libmonero_libwallet2_api_c.so"; + break; + case "windows": + libPath = "./lib/monero_libwallet2_api_c.dll"; + break; + default: + libPath = "./lib/monero_libwallet2_api_c.so"; + break; + } + + dylib = Deno.dlopen(libPath, symbols); +} diff --git a/impls/monero.ts/src/pending_transaction.ts b/impls/monero.ts/src/pending_transaction.ts new file mode 100644 index 00000000..cf487218 --- /dev/null +++ b/impls/monero.ts/src/pending_transaction.ts @@ -0,0 +1,81 @@ +import { dylib } from "./bindings.ts"; +import { CString, readCString, type Sanitizer } from "./utils.ts"; + +export type PendingTransactionPtr = Deno.PointerObject<"transactionInfo">; + +export class PendingTransaction { + #pendingTxPtr: PendingTransactionPtr; + sanitizer?: Sanitizer; + + constructor(pendingTxPtr: PendingTransactionPtr, sanitizer?: Sanitizer) { + this.sanitizer = sanitizer; + this.#pendingTxPtr = pendingTxPtr; + } + + async status(): Promise { + return await dylib.symbols.MONERO_PendingTransaction_status(this.#pendingTxPtr); + } + + async errorString(): Promise { + if (!await this.status()) return null; + + const error = await dylib.symbols.MONERO_PendingTransaction_errorString(this.#pendingTxPtr); + if (!error) return null; + + return await readCString(error) || null; + } + + async throwIfError(sanitize = true): Promise { + const maybeError = await this.errorString(); + if (maybeError) { + if (sanitize) this.sanitizer?.(); + throw new Error(maybeError); + } + } + + async commit(fileName: string, overwrite: boolean, sanitize = true): Promise { + const bool = await dylib.symbols.MONERO_PendingTransaction_commit( + this.#pendingTxPtr, + CString(fileName), + overwrite, + ); + await this.throwIfError(sanitize); + return bool; + } + + async commitUR(maxFragmentLength: number): Promise { + const result = await dylib.symbols.MONERO_PendingTransaction_commitUR( + this.#pendingTxPtr, + maxFragmentLength, + ); + if (!result) return null; + await this.throwIfError(); + return await readCString(result) || null; + } + + async amount(): Promise { + return await dylib.symbols.MONERO_PendingTransaction_amount(this.#pendingTxPtr); + } + + async dust(): Promise { + return await dylib.symbols.MONERO_PendingTransaction_dust(this.#pendingTxPtr); + } + + async fee(): Promise { + return await dylib.symbols.MONERO_PendingTransaction_fee(this.#pendingTxPtr); + } + + async txid(separator: string, sanitize = true): Promise { + const result = await dylib.symbols.MONERO_PendingTransaction_txid( + this.#pendingTxPtr, + CString(separator), + ); + if (!result) return null; + await this.throwIfError(sanitize); + return await readCString(result) || null; + } + + async txCount(): Promise { + return await dylib.symbols.MONERO_PendingTransaction_txCount(this.#pendingTxPtr); + } +} diff --git a/impls/monero.ts/src/transaction_history.ts b/impls/monero.ts/src/transaction_history.ts new file mode 100644 index 00000000..cc76fc25 --- /dev/null +++ b/impls/monero.ts/src/transaction_history.ts @@ -0,0 +1,38 @@ +import { dylib } from "./bindings.ts"; +import { TransactionInfo, TransactionInfoPtr } from "./transaction_info.ts"; +import { CString } from "./utils.ts"; + +export type TransactionHistoryPtr = Deno.PointerObject<"transactionHistory">; + +export class TransactionHistory { + #txHistoryPtr: TransactionHistoryPtr; + + constructor(txHistoryPtr: TransactionHistoryPtr) { + this.#txHistoryPtr = txHistoryPtr; + } + + async count(): Promise { + return await dylib.symbols.MONERO_TransactionHistory_count(this.#txHistoryPtr); + } + + async transaction(index: number): Promise { + return new TransactionInfo( + (await dylib.symbols.MONERO_TransactionHistory_transaction( + this.#txHistoryPtr, + index, + )) as TransactionInfoPtr, + ); + } + + async refresh(): Promise { + await dylib.symbols.MONERO_TransactionHistory_refresh(this.#txHistoryPtr); + } + + async setTxNote(transactionId: string, note: string): Promise { + await dylib.symbols.MONERO_TransactionHistory_setTxNote( + this.#txHistoryPtr, + CString(transactionId), + CString(note), + ); + } +} diff --git a/impls/monero.ts/src/transaction_info.ts b/impls/monero.ts/src/transaction_info.ts new file mode 100644 index 00000000..7db45f5d --- /dev/null +++ b/impls/monero.ts/src/transaction_info.ts @@ -0,0 +1,104 @@ +import { dylib } from "./bindings.ts"; +import { readCString, Sanitizer } from "./utils.ts"; + +export type TransactionInfoPtr = Deno.PointerObject<"transactionInfo">; + +export class TransactionInfo { + #txInfoPtr: TransactionInfoPtr; + sanitizer?: Sanitizer; + + constructor(txInfoPtr: TransactionInfoPtr, sanitizer?: Sanitizer) { + this.#txInfoPtr = txInfoPtr; + this.sanitizer = sanitizer; + } + + async direction(): Promise<"in" | "out"> { + switch (await dylib.symbols.MONERO_TransactionInfo_direction(this.#txInfoPtr)) { + case 0: + return "in"; + case 1: + return "out"; + default: + await this.sanitizer?.(); + throw new Error("Invalid TransactionInfo direction"); + } + } + + async isPending(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_isPending(this.#txInfoPtr); + } + + async isFailed(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_isFailed(this.#txInfoPtr); + } + + async isCoinbase(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_isCoinbase(this.#txInfoPtr); + } + + async amount(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_amount(this.#txInfoPtr); + } + + async fee(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_fee(this.#txInfoPtr); + } + + async blockHeight(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_blockHeight(this.#txInfoPtr); + } + + async description(): Promise { + const description = await dylib.symbols.MONERO_TransactionInfo_description(this.#txInfoPtr); + return await readCString(description) || ""; + } + + async subaddrIndex(): Promise { + const subaddrIndex = await dylib.symbols.MONERO_TransactionInfo_subaddrIndex(this.#txInfoPtr); + return await readCString(subaddrIndex) || ""; + } + + async subaddrAccount(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_subaddrAccount(this.#txInfoPtr); + } + + async label(): Promise { + const label = await dylib.symbols.MONERO_TransactionInfo_label(this.#txInfoPtr); + return await readCString(label) || ""; + } + + async confirmations(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_confirmations(this.#txInfoPtr); + } + + async unlockTime(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_unlockTime(this.#txInfoPtr); + } + + async hash(): Promise { + const hash = await dylib.symbols.MONERO_TransactionInfo_hash(this.#txInfoPtr); + return await readCString(hash) || ""; + } + + async timestamp(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_timestamp(this.#txInfoPtr); + } + + async paymentId(): Promise { + const paymentId = await dylib.symbols.MONERO_TransactionInfo_paymentId(this.#txInfoPtr); + return await readCString(paymentId) || ""; + } + + async transfersCount(): Promise { + return await dylib.symbols.MONERO_TransactionInfo_transfers_count(this.#txInfoPtr); + } + + async transfersAmount(index: number): Promise { + return await dylib.symbols.MONERO_TransactionInfo_transfers_amount(this.#txInfoPtr, index); + } + + async transfersAddress(index: number): Promise { + const transfersAddress = await dylib.symbols.MONERO_TransactionInfo_transfers_address(this.#txInfoPtr, index); + return await readCString(transfersAddress) || ""; + } +} diff --git a/impls/monero.ts/src/utils.ts b/impls/monero.ts/src/utils.ts new file mode 100644 index 00000000..6fa640f6 --- /dev/null +++ b/impls/monero.ts/src/utils.ts @@ -0,0 +1,25 @@ +import { dylib } from "../mod.ts"; + +export type Sanitizer = () => void | PromiseLike; + +const textEncoder = new TextEncoder(); +export function CString(string: string): Deno.PointerValue { + return Deno.UnsafePointer.of(textEncoder.encode(`${string}\x00`)); +} + +/** + * This method reads string from the given pointer and frees the string. + * + * SAFETY: Do not use readCString twice on the same pointer as it will cause double free\ + * If you want to read CString without freeing it set the {@linkcode free} parameter to false + */ +export async function readCString(pointer: Deno.PointerObject, free?: boolean): Promise; +export async function readCString(pointer: Deno.PointerValue, free?: boolean): Promise; +export async function readCString(pointer: Deno.PointerValue, free = true): Promise { + if (!pointer) return null; + const string = new Deno.UnsafePointerView(pointer).getCString(); + if (free) { + await dylib.symbols.MONERO_free(pointer); + } + return string; +} diff --git a/impls/monero.ts/src/wallet.ts b/impls/monero.ts/src/wallet.ts new file mode 100644 index 00000000..07c40ceb --- /dev/null +++ b/impls/monero.ts/src/wallet.ts @@ -0,0 +1,304 @@ +import { dylib } from "./bindings.ts"; +import { CString, readCString, Sanitizer } from "./utils.ts"; +import { WalletManager, type WalletManagerPtr } from "./wallet_manager.ts"; +import { TransactionHistory, TransactionHistoryPtr } from "./transaction_history.ts"; + +import { PendingTransaction } from "./pending_transaction.ts"; +import { PendingTransactionPtr } from "./pending_transaction.ts"; + +export type WalletPtr = Deno.PointerObject<"walletManager">; + +export class Wallet { + #walletManagerPtr: WalletManagerPtr; + #walletPtr: WalletPtr; + sanitizer?: Sanitizer; + + constructor(walletManagerPtr: WalletManager, walletPtr: WalletPtr, sanitizer?: Sanitizer) { + this.#walletPtr = walletPtr; + this.#walletManagerPtr = walletManagerPtr.getPointer(); + this.sanitizer = sanitizer; + } + + async store(path = ""): Promise { + const bool = await dylib.symbols.MONERO_Wallet_store(this.#walletPtr, CString(path)); + await this.throwIfError(); + return bool; + } + + async initWallet(): Promise { + await this.init(); + await this.setTrustedDaemon(true); + await this.setDaemonAddress("http://nodex.monerujo.io:18081"); + await this.startRefresh(); + await this.refreshAsync(); + await this.throwIfError(); + } + + async setDaemonAddress(address: string): Promise { + await dylib.symbols.MONERO_WalletManager_setDaemonAddress( + this.#walletManagerPtr, + CString(address), + ); + } + + async startRefresh(): Promise { + await dylib.symbols.MONERO_Wallet_startRefresh(this.#walletPtr); + await this.throwIfError(); + } + + async refreshAsync(): Promise { + await dylib.symbols.MONERO_Wallet_refreshAsync(this.#walletPtr); + await this.throwIfError(); + } + + async init(): Promise { + const bool = await dylib.symbols.MONERO_Wallet_init( + this.#walletPtr, + CString("http://nodex.monerujo.io:18081"), + 0n, + CString(""), + CString(""), + false, + false, + CString(""), + ); + await this.throwIfError(); + return bool; + } + + async setTrustedDaemon(value: boolean): Promise { + await dylib.symbols.MONERO_Wallet_setTrustedDaemon(this.#walletPtr, value); + } + + static async create( + walletManager: WalletManager, + path: string, + password: string, + sanitizeError = true, + ): Promise { + // We assign holder of the pointer in Wallet constructor + const walletManagerPtr = walletManager.getPointer(); + + const walletPtr = await dylib.symbols.MONERO_WalletManager_createWallet( + walletManagerPtr, + CString(path), + CString(password), + CString("English"), + 0, + ); + + const wallet = new Wallet(walletManager, walletPtr as WalletPtr, walletManager.sanitizer); + await wallet.throwIfError(sanitizeError); + await wallet.initWallet(); + + return wallet; + } + + static async open( + walletManager: WalletManager, + path: string, + password: string, + sanitizeError = true, + ): Promise { + // We assign holder of the pointer in Wallet constructor + const walletManagerPtr = walletManager.getPointer(); + + const walletPtr = await dylib.symbols.MONERO_WalletManager_openWallet( + walletManagerPtr, + CString(path), + CString(password), + 0, + ); + + const wallet = new Wallet(walletManager, walletPtr as WalletPtr, walletManager.sanitizer); + await wallet.throwIfError(sanitizeError); + await wallet.initWallet(); + + return wallet; + } + + static async recover( + walletManager: WalletManager, + path: string, + password: string, + mnemonic: string, + restoreHeight: bigint, + seedOffset: string = "", + sanitizeError = true, + ): Promise { + // We assign holder of the pointer in Wallet constructor + const walletManagerPtr = walletManager.getPointer(); + + const walletPtr = await dylib.symbols.MONERO_WalletManager_recoveryWallet( + walletManagerPtr, + CString(path), + CString(password), + CString(mnemonic), + 0, + restoreHeight, + 1n, + CString(seedOffset), + ); + + const wallet = new Wallet(walletManager, walletPtr as WalletPtr, walletManager.sanitizer); + await wallet.throwIfError(sanitizeError); + await wallet.initWallet(); + + return wallet; + } + + async address(accountIndex = 0n, addressIndex = 0n): Promise { + const address = await dylib.symbols.MONERO_Wallet_address(this.#walletPtr, accountIndex, addressIndex); + if (!address) { + const error = await this.errorString(); + throw new Error(`Failed getting address from a wallet: ${error ?? ""}`); + } + return await readCString(address); + } + + async balance(accountIndex = 0): Promise { + return await dylib.symbols.MONERO_Wallet_balance(this.#walletPtr, accountIndex); + } + + async unlockedBalance(accountIndex = 0): Promise { + return await dylib.symbols.MONERO_Wallet_unlockedBalance(this.#walletPtr, accountIndex); + } + + status(): Promise { + return dylib.symbols.MONERO_Wallet_status(this.#walletPtr); + } + + async errorString(): Promise { + if (!await this.status()) return null; + + const error = await dylib.symbols.MONERO_Wallet_errorString(this.#walletPtr); + if (!error) return null; + + return await readCString(error) || null; + } + + async throwIfError(sanitize = true): Promise { + const maybeError = await this.errorString(); + if (maybeError) { + if (sanitize) this.sanitizer?.(); + throw new Error(maybeError); + } + } + + async synchronized(): Promise { + const synchronized = await dylib.symbols.MONERO_Wallet_synchronized(this.#walletPtr); + await this.throwIfError(); + return synchronized; + } + + async blockChainHeight(): Promise { + const height = await dylib.symbols.MONERO_Wallet_blockChainHeight(this.#walletPtr); + await this.throwIfError(); + return height; + } + + async daemonBlockChainHeight(): Promise { + const height = await dylib.symbols.MONERO_Wallet_daemonBlockChainHeight(this.#walletPtr); + await this.throwIfError(); + return height; + } + + async managerBlockChainHeight(): Promise { + const height = await dylib.symbols.MONERO_WalletManager_blockchainHeight(this.#walletManagerPtr); + await this.throwIfError(); + return height; + } + + async managerTargetBlockChainHeight(): Promise { + const height = await dylib.symbols.MONERO_WalletManager_blockchainTargetHeight(this.#walletManagerPtr); + await this.throwIfError(); + return height; + } + + async addSubaddressAccount(label: string): Promise { + await dylib.symbols.MONERO_Wallet_addSubaddressAccount( + this.#walletPtr, + CString(label), + ); + await this.throwIfError(); + } + + async numSubaddressAccounts(): Promise { + const accountsLen = await dylib.symbols.MONERO_Wallet_numSubaddressAccounts(this.#walletPtr); + await this.throwIfError(); + return accountsLen; + } + + async addSubaddress(accountIndex: number, label: string): Promise { + await dylib.symbols.MONERO_Wallet_addSubaddress( + this.#walletPtr, + accountIndex, + CString(label), + ); + await this.throwIfError(); + } + + async numSubaddresses(accountIndex: number): Promise { + const address = await dylib.symbols.MONERO_Wallet_numSubaddresses( + this.#walletPtr, + accountIndex, + ); + await this.throwIfError(); + return address; + } + + async getSubaddressLabel(accountIndex: number, addressIndex: number): Promise { + const label = await dylib.symbols.MONERO_Wallet_getSubaddressLabel(this.#walletPtr, accountIndex, addressIndex); + if (!label) { + const error = await this.errorString(); + throw new Error(`Failed getting subaddress label from a wallet: ${error ?? ""}`); + } + return await readCString(label); + } + + async setSubaddressLabel(accountIndex: number, addressIndex: number, label: string): Promise { + await dylib.symbols.MONERO_Wallet_setSubaddressLabel( + this.#walletPtr, + accountIndex, + addressIndex, + CString(label), + ); + await this.throwIfError(); + } + + async getHistory(): Promise { + const transactionHistoryPointer = await dylib.symbols.MONERO_Wallet_history(this.#walletPtr); + await this.throwIfError(); + return new TransactionHistory(transactionHistoryPointer as TransactionHistoryPtr); + } + + async createTransaction( + destinationAddress: string, + amount: bigint, + pendingTransactionPriority = 0 | 1 | 2 | 3, + subaddressAccount: number, + sanitize = true, + prefferedInputs = "", + mixinCount = 0, + paymentId = "", + separator = ",", + ): Promise { + const pendingTxPtr = await dylib.symbols.MONERO_Wallet_createTransaction( + this.#walletPtr, + CString(destinationAddress), + CString(paymentId), + amount, + mixinCount, + pendingTransactionPriority, + subaddressAccount, + CString(prefferedInputs), + CString(separator), + ); + await this.throwIfError(sanitize); + return new PendingTransaction(pendingTxPtr as PendingTransactionPtr); + } + + async amountFromString(amount: string): Promise { + return await dylib.symbols.MONERO_Wallet_amountFromString(CString(amount)); + } +} diff --git a/impls/monero.ts/src/wallet_manager.ts b/impls/monero.ts/src/wallet_manager.ts new file mode 100644 index 00000000..ad9cf315 --- /dev/null +++ b/impls/monero.ts/src/wallet_manager.ts @@ -0,0 +1,27 @@ +import { dylib } from "./bindings.ts"; +import { Sanitizer } from "./utils.ts"; + +export type WalletManagerPtr = Deno.PointerObject<"walletManager">; + +export class WalletManager { + #ptr: WalletManagerPtr; + sanitizer?: Sanitizer; + + constructor(walletManagerPtr: WalletManagerPtr, sanitizer?: Sanitizer) { + this.#ptr = walletManagerPtr; + this.sanitizer = sanitizer; + } + + getPointer(): WalletManagerPtr { + return this.#ptr; + } + + static async new(sanitizer?: Sanitizer) { + const ptr = await dylib.symbols.MONERO_WalletManagerFactory_getWalletManager(); + if (!ptr) { + sanitizer?.(); + throw new Error("Failed retrieving wallet manager"); + } + return new WalletManager(ptr as WalletManagerPtr, sanitizer); + } +} From 3071824c0f90512df0633e5eeec80b187e619356 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:57:44 +0000 Subject: [PATCH 26/28] chore(deps): update ghcr.io/cirruslabs/flutter docker tag to v3.24.3 --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 75d07e0c..adebed0a 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/cirruslabs/flutter:3.24.1 +FROM ghcr.io/cirruslabs/flutter:3.24.3 # FROM debian:bookworm # Install dependencies From 50adbbc4096c900942366336295e231499c08a47 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Fri, 27 Sep 2024 18:16:49 +0200 Subject: [PATCH 27/28] update OpenSSL-for-iPhone --- .gitmodules | 2 +- external/OpenSSL-for-iPhone | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index d9a8e69e..42bd1b79 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ branch = build [submodule "external/OpenSSL-for-iPhone"] path = external/OpenSSL-for-iPhone - url = https://github.com/x2on/OpenSSL-for-iPhone.git + url = https://github.com/MrCyjaneK/OpenSSL-for-iPhone.git [submodule "external/libsodium"] path = external/libsodium url = https://github.com/jedisct1/libsodium.git diff --git a/external/OpenSSL-for-iPhone b/external/OpenSSL-for-iPhone index 394bac11..d3ec433a 160000 --- a/external/OpenSSL-for-iPhone +++ b/external/OpenSSL-for-iPhone @@ -1 +1 @@ -Subproject commit 394bac11f4347cc21b4ba976c1c0629afaf67c54 +Subproject commit d3ec433a47708594d18ef6e248b66e3d64f00f0f From 6eb571ea498ed7b854934785f00fabfd0dadf75b Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Fri, 27 Sep 2024 12:27:23 +0200 Subject: [PATCH 28/28] fix coin control drop xmruw ci for the time being --- .github/workflows/full_check.yaml | 100 +++++++++--------- .../monero/0018-fix-coin-control-patch.patch | 30 ++++++ 2 files changed, 80 insertions(+), 50 deletions(-) create mode 100644 patches/monero/0018-fix-coin-control-patch.patch diff --git a/.github/workflows/full_check.yaml b/.github/workflows/full_check.yaml index 03e6f377..67e86a19 100644 --- a/.github/workflows/full_check.yaml +++ b/.github/workflows/full_check.yaml @@ -650,54 +650,54 @@ jobs: rm -rf wownero/contrib/depends/built/*/android_ndk rm -rf wownero/contrib/depends/sources/android-ndk-r26d-linux.zip - wallet_xmruw_android: - needs: [ lib_android ] - strategy: - matrix: - coin: [monero, wownero] - runs-on: ubuntu-latest - steps: - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 libtinfo5 gperf unzip python-is-python3 jq - - uses: actions/download-artifact@v4 - with: - name: android ${{ matrix.coin }} - path: release/${{ matrix.coin }} - - name: clone xmruw - run: | - git clone https://github.com/mrcyjanek/unnamed_monero_wallet - cd unnamed_monero_wallet - cp -a .fvm* .. - - uses: kuhnroyal/flutter-fvm-config-action@v2 - id: fvm-config-action - - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} - channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '17' - - name: build xmruw (${{ matrix.coin }}) - run: | - cd unnamed_monero_wallet - if [[ "${{ matrix.coin }}" == "monero" ]]; then ./codegen.sh -DCOIN_MONERO -DLIBSTEALTH_DISABLED; fi - if [[ "${{ matrix.coin }}" == "wownero" ]]; then ./codegen.sh -DCOIN_WOWNERO -DLIBSTEALTH_DISABLED; fi - flutter pub get - make version - ./build_changelog.sh - cp ../release/${{ matrix.coin }}/aarch64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/arm64-v8a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz - cp ../release/${{ matrix.coin }}/x86_64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/x86_64/lib${{ matrix.coin }}_libwallet2_api_c.so.xz - cp ../release/${{ matrix.coin }}/armv7a-linux-androideabi_libwallet2_api_c.so.xz android/app/src/main/jniLibs/armeabi-v7a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz - unxz -f android/app/src/main/jniLibs/*/*.xz - flutter build apk --release --flavor clean_${{ matrix.coin }} - - name: Upload APK - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.coin }} xmruw apk - path: unnamed_monero_wallet/build/app/outputs/flutter-apk/*.apk + #wallet_xmruw_android: + # needs: [ lib_android ] + # strategy: + # matrix: + # coin: [monero, wownero] + # runs-on: ubuntu-latest + # steps: + # - name: Install dependencies + # run: | + # sudo apt update + # sudo apt install -y build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 libtinfo5 gperf unzip python-is-python3 jq + # - uses: actions/download-artifact@v4 + # with: + # name: android ${{ matrix.coin }} + # path: release/${{ matrix.coin }} + # - name: clone xmruw + # run: | + # git clone https://github.com/mrcyjanek/unnamed_monero_wallet + # cd unnamed_monero_wallet + # cp -a .fvm* .. + # - uses: kuhnroyal/flutter-fvm-config-action@v2 + # id: fvm-config-action + # - uses: subosito/flutter-action@v2 + # with: + # flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} + # channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} + # - uses: actions/setup-java@v4 + # with: + # distribution: 'zulu' + # java-version: '17' + # - name: build xmruw (${{ matrix.coin }}) + # run: | + # cd unnamed_monero_wallet + # if [[ "${{ matrix.coin }}" == "monero" ]]; then ./codegen.sh -DCOIN_MONERO -DLIBSTEALTH_DISABLED; fi + # if [[ "${{ matrix.coin }}" == "wownero" ]]; then ./codegen.sh -DCOIN_WOWNERO -DLIBSTEALTH_DISABLED; fi + # flutter pub get + # make version + # ./build_changelog.sh + # cp ../release/${{ matrix.coin }}/aarch64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/arm64-v8a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz + # cp ../release/${{ matrix.coin }}/x86_64-linux-android_libwallet2_api_c.so.xz android/app/src/main/jniLibs/x86_64/lib${{ matrix.coin }}_libwallet2_api_c.so.xz + # cp ../release/${{ matrix.coin }}/armv7a-linux-androideabi_libwallet2_api_c.so.xz android/app/src/main/jniLibs/armeabi-v7a/lib${{ matrix.coin }}_libwallet2_api_c.so.xz + # unxz -f android/app/src/main/jniLibs/*/*.xz + # flutter build apk --release --flavor clean_${{ matrix.coin }} + # - name: Upload APK + # uses: actions/upload-artifact@v4 + # with: + # name: ${{ matrix.coin }} xmruw apk + # path: unnamed_monero_wallet/build/app/outputs/flutter-apk/*.apk bulk_lib_release: name: create single release file runs-on: ubuntu-latest @@ -821,8 +821,8 @@ jobs: runs-on: ubuntu-latest needs: [ lib_mingw, lib_android, lib_linux, lib_sailfishos_aarch64, lib_sailfishos_i486, lib_darwin, lib_macos, lib_ios, - wallet_cake_android, - wallet_xmruw_android + wallet_cake_android #, + #wallet_xmruw_android ] steps: - uses: actions/github-script@v7 diff --git a/patches/monero/0018-fix-coin-control-patch.patch b/patches/monero/0018-fix-coin-control-patch.patch new file mode 100644 index 00000000..001a1c08 --- /dev/null +++ b/patches/monero/0018-fix-coin-control-patch.patch @@ -0,0 +1,30 @@ +From 3d99b4efb5a79d7c52d596c349de25d1ca34c264 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto +Date: Fri, 27 Sep 2024 12:20:49 +0200 +Subject: [PATCH] fix coin control patch + +--- + src/wallet/api/wallet.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp +index 3ead385ec..ec7d60ec0 100644 +--- a/src/wallet/api/wallet.cpp ++++ b/src/wallet/api/wallet.cpp +@@ -2174,11 +2174,11 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vectorm_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, + adjusted_priority, +- extra, subaddr_account, subaddr_indices); ++ extra, subaddr_account, subaddr_indices, preferred_input_list); + } else { + transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count, + adjusted_priority, +- extra, subaddr_account, subaddr_indices); ++ extra, subaddr_account, subaddr_indices, preferred_input_list); + } + pendingTxPostProcess(transaction); + +-- +2.39.5 (Apple Git-154) +