summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Ullrich <konstantinullrich12@gmail.com>2024-10-07 12:37:30 +0200
committerKonstantin Ullrich <konstantinullrich12@gmail.com>2024-10-07 12:37:30 +0200
commit98272ee381bd07081502dd426226f58c879300a6 (patch)
tree672f6f06727dbc1c84270973ce13e9403913e481
parent04b29d84a2c368c677cf5ec946269203622ca170 (diff)
parent67f4baa015a4407d096e35b6e5a81d72932fb55f (diff)
Merge branch 'master' into ledger
# Conflicts: # .github/workflows/full_check.yaml # impls/monero.dart/lib/monero.dart # impls/monero.dart/pubspec.yaml # patches/monero/0016-add-dummy-device-for-ledger.patch
-rw-r--r--.devcontainer/Dockerfile2
-rw-r--r--.github/workflows/full_check.yaml213
-rw-r--r--.gitmodules3
-rw-r--r--.vscode/settings.json3
-rwxr-xr-xapply_patches.sh2
m---------external/OpenSSL-for-iPhone0
m---------external/ios-cmake0
-rwxr-xr-xexternal/ios/libsodium_apple-ios.sh4
m---------external/libexpat0
m---------external/libsodium0
m---------external/libzmq0
-rwxr-xr-xgenerate_checksum.sh17
-rw-r--r--impls/monero.c#/README.md7
-rw-r--r--impls/monero.c#/monero_wrapper.cs184
-rw-r--r--impls/monero.dart/lib/monero.dart55
-rw-r--r--impls/monero.dart/lib/src/checksum_monero.dart2
-rw-r--r--impls/monero.dart/lib/src/checksum_wownero.dart2
-rw-r--r--impls/monero.dart/lib/wownero.dart46
-rw-r--r--impls/monero.dart/pubspec.yaml4
-rw-r--r--impls/monero.ts/.gitignore2
-rw-r--r--impls/monero.ts/README.md42
-rw-r--r--impls/monero.ts/checksum.ts65
-rw-r--r--impls/monero.ts/checksum_monero.ts5
-rw-r--r--impls/monero.ts/checksum_wownero.ts5
-rw-r--r--impls/monero.ts/deno.jsonc5
-rw-r--r--impls/monero.ts/mod.ts6
-rw-r--r--impls/monero.ts/src/bindings.ts562
-rw-r--r--impls/monero.ts/src/pending_transaction.ts81
-rw-r--r--impls/monero.ts/src/transaction_history.ts38
-rw-r--r--impls/monero.ts/src/transaction_info.ts104
-rw-r--r--impls/monero.ts/src/utils.ts25
-rw-r--r--impls/monero.ts/src/wallet.ts304
-rw-r--r--impls/monero.ts/src/wallet_manager.ts27
m---------monero0
-rw-r--r--monero_libwallet2_api_c/src/main/cpp/monero_checksum.h2
-rw-r--r--monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp3
-rw-r--r--patches/monero/0001-polyseed.patch78
-rw-r--r--patches/monero/0002-wallet-background-sync-with-just-the-view-key.patch303
-rw-r--r--patches/monero/0003-airgap.patch16
-rw-r--r--patches/monero/0004-coin-control.patch63
-rw-r--r--patches/monero/0005-fix-build-issues.patch6
-rw-r--r--patches/monero/0006-macos-build-fix.patch23
-rw-r--r--patches/monero/0007-fix-make-debug-test-target.patch61
-rw-r--r--patches/monero/0008-fix-missing-___clear_cache-when-targetting-iOS.patch6
-rw-r--r--patches/monero/0009-Add-recoverDeterministicWalletFromSpendKey.patch8
-rw-r--r--patches/monero/0010-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch6
-rw-r--r--patches/monero/0011-store-crash-fix.patch24
-rw-r--r--patches/monero/0012-WIP-UR-functions.patch14
-rw-r--r--patches/monero/0013-android-ndk-version-bump.patch4
-rw-r--r--patches/monero/0014-rename-arm-armv7a.patch (renamed from patches/monero/0013-rename-arm-armv7a.patch)4
-rw-r--r--patches/monero/0015-use-proper-error-handling-in-get_seed.patch (renamed from patches/monero/0014-use-proper-error-handling-in-get_seed.patch)8
-rw-r--r--patches/monero/0016-add-dummy-device-for-ledger.patch (renamed from patches/monero/0015-add-dummy-device-for-ledger.patch)2
-rw-r--r--patches/monero/0016-uint64_t-missing-definition-fix.patch25
-rw-r--r--patches/monero/0017-added-deps.patch29
-rw-r--r--patches/monero/0018-fix-coin-control-patch.patch30
-rw-r--r--patches/wownero/0015-uint64_t-missing-definition-fix.patch25
-rw-r--r--wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.cpp3
-rw-r--r--wownero_libwallet2_api_c/src/main/cpp/wownero_checksum.h2
58 files changed, 2119 insertions, 441 deletions
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 75d07e0..adebed0 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
diff --git a/.github/workflows/full_check.yaml b/.github/workflows/full_check.yaml
index 7b0ccaa..8f85df0 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: |
@@ -631,6 +631,12 @@ 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
+ 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: |
@@ -654,68 +660,179 @@ 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]
+ #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
+ 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
- - 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
+ name: linux monero
+ path: release/monero
+ - name: unpack and move monero_c
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: |
- main_dir=$PWD
- 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
- sed -i '/ monero:/,/path:/c\ monero:\n path: '"$main_dir/impls/monero.dart" pubspec.yaml
- 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
+ unxz -f -k release/*/*.xz
+ - uses: denoland/setup-deno@v1
with:
- name: ${{ matrix.coin }} xmruw apk
- path: unnamed_monero_wallet/build/app/outputs/flutter-apk/*.apk
+ 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
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
@@ -762,4 +879,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/.gitmodules b/.gitmodules
index d9a8e69..a49395d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -20,10 +20,11 @@
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
+ branch = stable
[submodule "external/unbound"]
path = external/unbound
url = https://github.com/NLnetLabs/unbound.git
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..b943dbc
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "deno.enable": true
+} \ No newline at end of file
diff --git a/apply_patches.sh b/apply_patches.sh
index 3ce6856..22c3bba 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/external/OpenSSL-for-iPhone b/external/OpenSSL-for-iPhone
-Subproject 394bac11f4347cc21b4ba976c1c0629afaf67c5
+Subproject d3ec433a47708594d18ef6e248b66e3d64f00f0
diff --git a/external/ios-cmake b/external/ios-cmake
-Subproject 06465b27698424cf4a04a5ca4904d50a3c966c4
+Subproject ad96a372b168930c2a1ff9455e1a9ccb1302161
diff --git a/external/ios/libsodium_apple-ios.sh b/external/ios/libsodium_apple-ios.sh
index 8a47a16..963ba32 100755
--- a/external/ios/libsodium_apple-ios.sh
+++ b/external/ios/libsodium_apple-ios.sh
@@ -100,7 +100,9 @@ build_ios() {
mkdir -p "${PREFIX}/tmp"
-echo "Building for iOS..."
+echo "Building for iOS... ($LOG_FILE)"
+./autogen.sh
+./configure
build_ios >"$LOG_FILE" 2>&1 || exit 1
echo "Adding the Clibsodium module map for Swift..."
diff --git a/external/libexpat b/external/libexpat
-Subproject 3bab6c09bbe8bf42d84b81563ddbcf4cca4be83
+Subproject 46cf63aef169f8f12ea09579db883c5251bd47d
diff --git a/external/libsodium b/external/libsodium
-Subproject 443617d7507498f7477703f0b51cb596d453926
+Subproject fb80cbfa59cb97c7e867074416bfde3ec337c05
diff --git a/external/libzmq b/external/libzmq
-Subproject b95d94935ed107679fd0ad9efd2f3d47309b6fd
+Subproject 90b4f410a07222fa2e9a5f53b454a09d4533e45
diff --git a/generate_checksum.sh b/generate_checksum.sh
index c6f9524..4b82e53 100755
--- a/generate_checksum.sh
+++ b/generate_checksum.sh
@@ -1,14 +1,18 @@
#!/bin/bash
cd "$(realpath $(dirname $0))"
+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 }')
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
@@ -24,5 +28,12 @@ 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.c#/README.md b/impls/monero.c#/README.md
new file mode 100644
index 0000000..bfbb3b7
--- /dev/null
+++ b/impls/monero.c#/README.md
@@ -0,0 +1,7 @@
+# monero.c#
+
+> C# port for monero
+
+This is not a ready-to-use package (as opposed to monero.dart and monero.ts), but it works. You can check the `monero_wrapper.cs`.
+
+Currently C# code is optimized to be used in Godot.., if you are not planning to use it there - simply do not extend Node class and remove Godot import, if you are planning to use it in production, please let me know - we can work on a better approach to using monero with proper package code in here. \ No newline at end of file
diff --git a/impls/monero.c#/monero_wrapper.cs b/impls/monero.c#/monero_wrapper.cs
new file mode 100644
index 0000000..ce7749d
--- /dev/null
+++ b/impls/monero.c#/monero_wrapper.cs
@@ -0,0 +1,184 @@
+using Godot;
+using System;
+using System.Runtime.InteropServices;
+
+public partial class monero_wrapper : Node
+{
+ public static IntPtr wmPtr = MONERO_WalletManagerFactory_getWalletManager();
+ public static IntPtr wPtr;
+ public static IntPtr pendingTx;
+ public static IntPtr txHistory;
+ public string path = "";
+
+ // Called when the node enters the scene tree for the first time.
+ public override void _Ready()
+ {
+ }
+
+ // Called every frame. 'delta' is the elapsed time since the previous frame.
+ public override void _Process(double delta)
+ {
+ }
+
+ public static bool openWallet(string path, string password) {
+ MONERO_WalletManager_createWallet(wmPtr, path, password, "English", 0);
+ wPtr = MONERO_WalletManager_openWallet(wmPtr, path, password, 0);
+ return MONERO_Wallet_status(wPtr) == 0;
+ }
+
+ public static void initWallet(string daemonAddress, bool useSsl, String proxyString) {
+ //MONERO_Wallet_init(string daemon_password, bool use_ssl, bool lightWallet, string proxy_address);
+ MONERO_Wallet_init(wPtr, daemonAddress, 0, "", "", useSsl, false, proxyString);
+ GD.Print(lastError());
+ MONERO_Wallet_init3(wPtr, "", "", "/dev/shm/godot_moneroc.log", false);
+ GD.Print(lastError());
+ MONERO_Wallet_setTrustedDaemon(wPtr, true);
+ GD.Print(lastError());
+ MONERO_Wallet_refreshAsync(wPtr);
+ GD.Print(lastError());
+ MONERO_Wallet_startRefresh(wPtr);
+ GD.Print(lastError());
+ }
+
+ public static void storeWallet() {
+ MONERO_Wallet_store(wPtr);
+ }
+
+ public static string lastError() {
+ IntPtr resultPtr = MONERO_Wallet_errorString(wPtr);
+ string result = Marshal.PtrToStringAnsi(resultPtr);
+ return result;
+ }
+
+ public static int lastErrorCode() {
+ return MONERO_Wallet_status(wPtr);
+ }
+
+ public static string lastTxError() {
+ IntPtr resultPtr = MONERO_PendingTransaction_errorString(pendingTx);
+ string result = Marshal.PtrToStringAnsi(resultPtr);
+ return result;
+ }
+
+ public static int lastTxErrorCode() {
+ return MONERO_PendingTransaction_status(pendingTx);
+ }
+
+ public static string getAddress(ulong accountIndex, ulong addressIndex) {
+ IntPtr resultPtr = MONERO_Wallet_address(wPtr, accountIndex, addressIndex);
+ string result = Marshal.PtrToStringAnsi(resultPtr);
+ return result;
+ }
+
+ public static ulong getBalance(uint accountIndex) {
+ return MONERO_Wallet_balance(wPtr, accountIndex);
+ }
+
+ public static void createTransaction(string address, ulong amount) {
+ pendingTx = MONERO_Wallet_createTransaction(wPtr, address, "", amount, 0, 0, 0, "", "");
+ MONERO_PendingTransaction_commit(pendingTx, "", false);
+ }
+
+ public static int getTransactionCount() {
+ txHistory = MONERO_Wallet_history(wPtr);
+ MONERO_TransactionHistory_refresh(txHistory);
+ return MONERO_TransactionHistory_count(txHistory);
+ }
+
+ public static int getTransactionDirection(int index) {
+ txHistory = MONERO_Wallet_history(wPtr);
+ IntPtr txPtr = MONERO_TransactionHistory_transaction(txHistory, index);
+ return MONERO_TransactionInfo_direction(txPtr);
+ }
+
+ public static ulong getTransactionAmount(int index) {
+ txHistory = MONERO_Wallet_history(wPtr);
+ IntPtr txPtr = MONERO_TransactionHistory_transaction(txHistory, index);
+ return MONERO_TransactionInfo_amount(txPtr);
+ }
+
+ public static ulong getTransactionTimestamp(int index) {
+ txHistory = MONERO_Wallet_history(wPtr);
+ IntPtr txPtr = MONERO_TransactionHistory_transaction(txHistory, index);
+ return MONERO_TransactionInfo_timestamp(txPtr);
+ }
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern ulong MONERO_TransactionInfo_timestamp(IntPtr txPtr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_TransactionHistory_transaction(IntPtr txHistory, int index);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern int MONERO_TransactionInfo_direction(IntPtr txPtr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern int MONERO_TransactionHistory_count(IntPtr txHistory);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern ulong MONERO_TransactionInfo_amount(IntPtr txPtr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_Wallet_history(IntPtr wm_ptr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_TransactionHistory_refresh(IntPtr txHistory);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_WalletManager_createWallet(IntPtr wm_ptr, string path, string password, string language, int networkType);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_WalletManager_openWallet(IntPtr wm_ptr, string path, string password, int networkType);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_WalletManagerFactory_getWalletManager();
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern int MONERO_Wallet_status(IntPtr wPtr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern int MONERO_PendingTransaction_status(IntPtr wPtr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern bool MONERO_WalletManager_walletExists(IntPtr wmPtr, string path);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_Wallet_errorString(IntPtr wPtr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_PendingTransaction_errorString(IntPtr pendingTx);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern ulong MONERO_Wallet_balance(IntPtr wPtr, uint accountIndex);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_Wallet_address(IntPtr wPtr, ulong accountIndex, ulong addressIndex);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern IntPtr MONERO_Wallet_createTransaction(IntPtr wallet_ptr, string dst_addr, string payment_id,
+ ulong amount, uint mixin_count,
+ int pendingTransactionPriority,
+ uint subaddr_account,
+ string preferredInputs, string separator);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern bool MONERO_PendingTransaction_commit(IntPtr pendingTx_ptr, string filename, bool overwrite);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern bool MONERO_Wallet_init(IntPtr wallet_ptr, string daemon_address, ulong upper_transaction_size_limit, string daemon_username, string daemon_password, bool use_ssl, bool lightWallet, string proxy_address);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern bool MONERO_Wallet_init3(IntPtr wallet_ptr, string argv0, string default_log_base_name, string log_path, bool console);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern void MONERO_Wallet_setTrustedDaemon(IntPtr wallet_ptr, bool arg);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern void MONERO_Wallet_startRefresh(IntPtr wallet_ptr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern void MONERO_Wallet_refreshAsync(IntPtr wallet_ptr);
+
+ [DllImport("/usr/lib/monero_libwallet2_api_c.so")]
+ public static extern bool MONERO_Wallet_store(IntPtr wallet_ptr);
+}
diff --git a/impls/monero.dart/lib/monero.dart b/impls/monero.dart/lib/monero.dart
index 8a0eea4..7b6eac3 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] ??= <int>[];
- debugCallLength[call]!.add(sw.elapsedMicroseconds);
+ try {
+ if (printStarts) print("MONERO: $call");
+ debugCallLength[call] ??= <int>[];
+ 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"] ??= <int>[];
+ 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");
@@ -3586,11 +3608,11 @@ bool WalletManager_verifyWalletPassword(
}
int WalletManager_queryWalletDevice(
- WalletManager wm_ptr, {
- required String keysFileName,
- required String password,
- required int kdfRounds,
-}) {
+ WalletManager wm_ptr, {
+ required String keysFileName,
+ required String password,
+ required int kdfRounds,
+ }) {
debugStart?.call('MONERO_WalletManager_queryWalletDevice');
lib ??= MoneroC(DynamicLibrary.open(libPath));
final keysFileName_ = keysFileName.toNativeUtf8().cast<Char>();
@@ -3603,7 +3625,8 @@ int WalletManager_queryWalletDevice(
return s;
}
-String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) {
+List<String> WalletManager_findWallets(WalletManager wm_ptr,
+ {required String path}) {
debugStart?.call('MONERO_WalletManager_findWallets');
lib ??= MoneroC(DynamicLibrary.open(libPath));
try {
@@ -3613,13 +3636,15 @@ String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) {
.cast<Utf8>();
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/src/checksum_monero.dart b/impls/monero.dart/lib/src/checksum_monero.dart
index 9e553f9..4ab72a3 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 = "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 f4ed1e7..7d501c6 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 = "07d67f34a07869aaa4af6ca04e142dbad2fb1fba0e2ebdefd22bc333fd982e25-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795";
const String wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4";
diff --git a/impls/monero.dart/lib/wownero.dart b/impls/monero.dart/lib/wownero.dart
index 5a0a288..d355005 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] ??= <int>[];
- debugCallLength[call]!.add(sw.elapsedMicroseconds);
+ try {
+ if (printStarts) print("MONERO: $call");
+ debugCallLength[call] ??= <int>[];
+ 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"] ??= <int>[];
+ 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");
@@ -3220,7 +3242,8 @@ bool WalletManager_verifyWalletPassword(
return s;
}
-String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) {
+List<String> WalletManager_findWallets(WalletManager wm_ptr,
+ {required String path}) {
debugStart?.call('WOWNERO_WalletManager_findWallets');
lib ??= WowneroC(DynamicLibrary.open(libPath));
try {
@@ -3230,13 +3253,15 @@ String WalletManager_findWallets(WalletManager wm_ptr, {required String path}) {
.cast<Utf8>();
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 +3631,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));
diff --git a/impls/monero.dart/pubspec.yaml b/impls/monero.dart/pubspec.yaml
index 67dc577..577dcbe 100644
--- a/impls/monero.dart/pubspec.yaml
+++ b/impls/monero.dart/pubspec.yaml
@@ -11,6 +11,6 @@ dependencies:
ledger_flutter_plus: ^1.2.5
dev_dependencies:
- lints: ^4.0.0
+ lints: ^5.0.0
test: ^1.24.0
- ffigen: ^13.0.0
+ ffigen: ^14.0.0
diff --git a/impls/monero.ts/.gitignore b/impls/monero.ts/.gitignore
new file mode 100644
index 0000000..8b61d3b
--- /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 0000000..e3b20f6
--- /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 0000000..22d3038
--- /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<ChecksumError | null> {
+ 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 0000000..88406a0
--- /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 0000000..8b2899c
--- /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 0000000..a7b75ec
--- /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 0000000..1eca773
--- /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 0000000..b854f7d
--- /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<typeof symbols>;
+
+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 0000000..cf48721
--- /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<number> {
+ return await dylib.symbols.MONERO_PendingTransaction_status(this.#pendingTxPtr);
+ }
+
+ async errorString(): Promise<string | null> {
+ 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<void> {
+ const maybeError = await this.errorString();
+ if (maybeError) {
+ if (sanitize) this.sanitizer?.();
+ throw new Error(maybeError);
+ }
+ }
+
+ async commit(fileName: string, overwrite: boolean, sanitize = true): Promise<boolean> {
+ const bool = await dylib.symbols.MONERO_PendingTransaction_commit(
+ this.#pendingTxPtr,
+ CString(fileName),
+ overwrite,
+ );
+ await this.throwIfError(sanitize);
+ return bool;
+ }
+
+ async commitUR(maxFragmentLength: number): Promise<string | null> {
+ 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<bigint> {
+ return await dylib.symbols.MONERO_PendingTransaction_amount(this.#pendingTxPtr);
+ }
+
+ async dust(): Promise<bigint> {
+ return await dylib.symbols.MONERO_PendingTransaction_dust(this.#pendingTxPtr);
+ }
+
+ async fee(): Promise<bigint> {
+ return await dylib.symbols.MONERO_PendingTransaction_fee(this.#pendingTxPtr);
+ }
+
+ async txid(separator: string, sanitize = true): Promise<string | null> {
+ 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<bigint> {
+ 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 0000000..cc76fc2
--- /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<number> {
+ return await dylib.symbols.MONERO_TransactionHistory_count(this.#txHistoryPtr);
+ }
+
+ async transaction(index: number): Promise<TransactionInfo> {
+ return new TransactionInfo(
+ (await dylib.symbols.MONERO_TransactionHistory_transaction(
+ this.#txHistoryPtr,
+ index,
+ )) as TransactionInfoPtr,
+ );
+ }
+
+ async refresh(): Promise<void> {
+ await dylib.symbols.MONERO_TransactionHistory_refresh(this.#txHistoryPtr);
+ }
+
+ async setTxNote(transactionId: string, note: string): Promise<void> {
+ 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 0000000..7db45f5
--- /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<boolean> {
+ return await dylib.symbols.MONERO_TransactionInfo_isPending(this.#txInfoPtr);
+ }
+
+ async isFailed(): Promise<boolean> {
+ return await dylib.symbols.MONERO_TransactionInfo_isFailed(this.#txInfoPtr);
+ }
+
+ async isCoinbase(): Promise<boolean> {
+ return await dylib.symbols.MONERO_TransactionInfo_isCoinbase(this.#txInfoPtr);
+ }
+
+ async amount(): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_amount(this.#txInfoPtr);
+ }
+
+ async fee(): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_fee(this.#txInfoPtr);
+ }
+
+ async blockHeight(): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_blockHeight(this.#txInfoPtr);
+ }
+
+ async description(): Promise<string> {
+ const description = await dylib.symbols.MONERO_TransactionInfo_description(this.#txInfoPtr);
+ return await readCString(description) || "";
+ }
+
+ async subaddrIndex(): Promise<string> {
+ const subaddrIndex = await dylib.symbols.MONERO_TransactionInfo_subaddrIndex(this.#txInfoPtr);
+ return await readCString(subaddrIndex) || "";
+ }
+
+ async subaddrAccount(): Promise<number> {
+ return await dylib.symbols.MONERO_TransactionInfo_subaddrAccount(this.#txInfoPtr);
+ }
+
+ async label(): Promise<string> {
+ const label = await dylib.symbols.MONERO_TransactionInfo_label(this.#txInfoPtr);
+ return await readCString(label) || "";
+ }
+
+ async confirmations(): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_confirmations(this.#txInfoPtr);
+ }
+
+ async unlockTime(): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_unlockTime(this.#txInfoPtr);
+ }
+
+ async hash(): Promise<string> {
+ const hash = await dylib.symbols.MONERO_TransactionInfo_hash(this.#txInfoPtr);
+ return await readCString(hash) || "";
+ }
+
+ async timestamp(): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_timestamp(this.#txInfoPtr);
+ }
+
+ async paymentId(): Promise<string> {
+ const paymentId = await dylib.symbols.MONERO_TransactionInfo_paymentId(this.#txInfoPtr);
+ return await readCString(paymentId) || "";
+ }
+
+ async transfersCount(): Promise<number> {
+ return await dylib.symbols.MONERO_TransactionInfo_transfers_count(this.#txInfoPtr);
+ }
+
+ async transfersAmount(index: number): Promise<bigint> {
+ return await dylib.symbols.MONERO_TransactionInfo_transfers_amount(this.#txInfoPtr, index);
+ }
+
+ async transfersAddress(index: number): Promise<string> {
+ 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 0000000..6fa640f
--- /dev/null
+++ b/impls/monero.ts/src/utils.ts
@@ -0,0 +1,25 @@
+import { dylib } from "../mod.ts";
+
+export type Sanitizer = () => void | PromiseLike<void>;
+
+const textEncoder = new TextEncoder();
+export function CString(string: string): Deno.PointerValue<string> {
+ 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<string>;
+export async function readCString(pointer: Deno.PointerValue, free?: boolean): Promise<string | null>;
+export async function readCString(pointer: Deno.PointerValue, free = true): Promise<string | null> {
+ 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 0000000..07c40ce
--- /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<boolean> {
+ const bool = await dylib.symbols.MONERO_Wallet_store(this.#walletPtr, CString(path));
+ await this.throwIfError();
+ return bool;
+ }
+
+ async initWallet(): Promise<void> {
+ 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<void> {
+ await dylib.symbols.MONERO_WalletManager_setDaemonAddress(
+ this.#walletManagerPtr,
+ CString(address),
+ );
+ }
+
+ async startRefresh(): Promise<void> {
+ await dylib.symbols.MONERO_Wallet_startRefresh(this.#walletPtr);
+ await this.throwIfError();
+ }
+
+ async refreshAsync(): Promise<void> {
+ await dylib.symbols.MONERO_Wallet_refreshAsync(this.#walletPtr);
+ await this.throwIfError();
+ }
+
+ async init(): Promise<boolean> {
+ 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<void> {
+ await dylib.symbols.MONERO_Wallet_setTrustedDaemon(this.#walletPtr, value);
+ }
+
+ static async create(
+ walletManager: WalletManager,
+ path: string,
+ password: string,
+ sanitizeError = true,
+ ): Promise<Wallet> {
+ // 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<Wallet> {
+ // 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<Wallet> {
+ // 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<string> {
+ 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 ?? "<Error unknown>"}`);
+ }
+ return await readCString(address);
+ }
+
+ async balance(accountIndex = 0): Promise<bigint> {
+ return await dylib.symbols.MONERO_Wallet_balance(this.#walletPtr, accountIndex);
+ }
+
+ async unlockedBalance(accountIndex = 0): Promise<bigint> {
+ return await dylib.symbols.MONERO_Wallet_unlockedBalance(this.#walletPtr, accountIndex);
+ }
+
+ status(): Promise<number> {
+ return dylib.symbols.MONERO_Wallet_status(this.#walletPtr);
+ }
+
+ async errorString(): Promise<string | null> {
+ 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<void> {
+ const maybeError = await this.errorString();
+ if (maybeError) {
+ if (sanitize) this.sanitizer?.();
+ throw new Error(maybeError);
+ }
+ }
+
+ async synchronized(): Promise<boolean> {
+ const synchronized = await dylib.symbols.MONERO_Wallet_synchronized(this.#walletPtr);
+ await this.throwIfError();
+ return synchronized;
+ }
+
+ async blockChainHeight(): Promise<bigint> {
+ const height = await dylib.symbols.MONERO_Wallet_blockChainHeight(this.#walletPtr);
+ await this.throwIfError();
+ return height;
+ }
+
+ async daemonBlockChainHeight(): Promise<bigint> {
+ const height = await dylib.symbols.MONERO_Wallet_daemonBlockChainHeight(this.#walletPtr);
+ await this.throwIfError();
+ return height;
+ }
+
+ async managerBlockChainHeight(): Promise<bigint> {
+ const height = await dylib.symbols.MONERO_WalletManager_blockchainHeight(this.#walletManagerPtr);
+ await this.throwIfError();
+ return height;
+ }
+
+ async managerTargetBlockChainHeight(): Promise<bigint> {
+ const height = await dylib.symbols.MONERO_WalletManager_blockchainTargetHeight(this.#walletManagerPtr);
+ await this.throwIfError();
+ return height;
+ }
+
+ async addSubaddressAccount(label: string): Promise<void> {
+ await dylib.symbols.MONERO_Wallet_addSubaddressAccount(
+ this.#walletPtr,
+ CString(label),
+ );
+ await this.throwIfError();
+ }
+
+ async numSubaddressAccounts(): Promise<bigint> {
+ const accountsLen = await dylib.symbols.MONERO_Wallet_numSubaddressAccounts(this.#walletPtr);
+ await this.throwIfError();
+ return accountsLen;
+ }
+
+ async addSubaddress(accountIndex: number, label: string): Promise<void> {
+ await dylib.symbols.MONERO_Wallet_addSubaddress(
+ this.#walletPtr,
+ accountIndex,
+ CString(label),
+ );
+ await this.throwIfError();
+ }
+
+ async numSubaddresses(accountIndex: number): Promise<bigint> {
+ const address = await dylib.symbols.MONERO_Wallet_numSubaddresses(
+ this.#walletPtr,
+ accountIndex,
+ );
+ await this.throwIfError();
+ return address;
+ }
+
+ async getSubaddressLabel(accountIndex: number, addressIndex: number): Promise<string> {
+ 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 ?? "<Error unknown>"}`);
+ }
+ return await readCString(label);
+ }
+
+ async setSubaddressLabel(accountIndex: number, addressIndex: number, label: string): Promise<void> {
+ await dylib.symbols.MONERO_Wallet_setSubaddressLabel(
+ this.#walletPtr,
+ accountIndex,
+ addressIndex,
+ CString(label),
+ );
+ await this.throwIfError();
+ }
+
+ async getHistory(): Promise<TransactionHistory> {
+ 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<PendingTransaction> {
+ 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<bigint> {
+ 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 0000000..ad9cf31
--- /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);
+ }
+}
diff --git a/monero b/monero
-Subproject 81d4db08eb75ce5392c65ca6571e7b08e41b7c9
+Subproject b089f9ee69924882c5d14dd1a6991deb05d9d1c
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 56b583f..20cbeae 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 = "dca52ac9ee009fda9fb5726543a454885e61d8eb74fb33112288029ed625bec5-b089f9ee69924882c5d14dd1a6991deb05d9d1cd";
const char * MONERO_wallet2_api_c_exp_sha256 = "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c";
#endif
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 f577f57..0cc2f9f 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<Monero::Wallet*>(wallet_ptr);
- std::set<std::string> dst_addr_ = splitString(std::string(dst_addr_list), std::string(dst_addr_list_separator));
- std::vector<std::string> dst_addr(dst_addr_.begin(), dst_addr_.end());
+ std::vector<std::string> dst_addr = splitStringVector(std::string(dst_addr_list), std::string(dst_addr_list_separator));
Monero::optional<std::vector<uint64_t>> optAmount;
if (!amount_sweep_all) {
diff --git a/patches/monero/0001-polyseed.patch b/patches/monero/0001-polyseed.patch
index 2db45e5..8164403 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 <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 09:42:37 +0100
-Subject: [PATCH 01/10] polyseed
+Subject: [PATCH 01/16] polyseed
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
---
- .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 <cyjan@mrcyjanek.net>
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::keys_file_data> wallet2::get_keys_file_data(const epee:
+@@ -4630,6 +4647,9 @@ boost::optional<wallet2::keys_file_data> 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<rapidjson::StringBuffer> 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<crypto::public_key> 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 f5d87b6..16fe77f 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 <justinberman@protonmail.com>
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<std::string>(version >> 16) + "." + boost::lexical_cast<std::string>(version & 0xffff);
-@@ -812,6 +863,7 @@ bool simple_wallet::spendkey(const std::vector<std::string> &args/* = std::vecto
+@@ -805,6 +856,7 @@ bool simple_wallet::spendkey(const std::vector<std::string> &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<std::string> &args/* = s
+@@ -913,6 +966,7 @@ bool simple_wallet::seed_set_language(const std::vector<std::string> &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<std::string> &args,
+@@ -1059,6 +1113,7 @@ bool simple_wallet::prepare_multisig_main(const std::vector<std::string> &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<std::string> &args)
+@@ -2195,6 +2250,7 @@ bool simple_wallet::save_known_rings(const std::vector<std::string> &args)
bool simple_wallet::freeze_thaw(const std::vector<std::string> &args, bool freeze)
{
@@ -221,7 +221,7 @@ index f2eaf6b13..341b0e448 100644
if (args.empty())
{
fail_msg_writer() << boost::format(tr("usage: %s <key_image>|<pubkey>")) % (freeze ? "freeze" : "thaw");
-@@ -2241,6 +2297,7 @@ bool simple_wallet::thaw(const std::vector<std::string> &args)
+@@ -2234,6 +2290,7 @@ bool simple_wallet::thaw(const std::vector<std::string> &args)
bool simple_wallet::frozen(const std::vector<std::string> &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<std::string> &args/* = std:
+@@ -3005,6 +3062,56 @@ bool simple_wallet::set_track_uses(const std::vector<std::string> &args/* = std:
return true;
}
@@ -286,7 +286,7 @@ index f2eaf6b13..341b0e448 100644
bool simple_wallet::set_show_wallet_name_when_locked(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
const auto pwd_container = get_and_verify_password();
-@@ -3244,6 +3351,7 @@ bool simple_wallet::apropos(const std::vector<std::string> &args)
+@@ -3237,6 +3344,7 @@ bool simple_wallet::apropos(const std::vector<std::string> &args)
bool simple_wallet::scan_tx(const std::vector<std::string> &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 <device_name[:device_spec]>\n "
-@@ -3891,6 +4001,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
+@@ -3876,6 +3986,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &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<std::string> &args)
+@@ -3894,6 +4005,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &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<std::string> &args)
+@@ -3947,6 +4059,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &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<tools::password_container> 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<epee::wipeable_string> simple_wallet::open_wallet(const boost::p
+@@ -5203,6 +5319,8 @@ boost::optional<epee::wipeable_string> 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<std::string>& args)
+@@ -6275,6 +6397,7 @@ bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::rescan_spent(const std::vector<std::string> &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<std:
- bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::string> &args_, bool called_by_mms)
+@@ -6576,6 +6724,7 @@ bool simple_wallet::on_command(bool (simple_wallet::*cmd)(const std::vector<std:
+ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool called_by_mms)
{
// "transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]"
+ 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<std::stri
+@@ -7004,6 +7153,7 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
//----------------------------------------------------------------------------------------------------
bool simple_wallet::transfer(const std::vector<std::string> &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<std::string> &args_)
- //----------------------------------------------------------------------------------------------------
- bool simple_wallet::locked_transfer(const std::vector<std::string> &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<std::string> &args_)
- //----------------------------------------------------------------------------------------------------
- bool simple_wallet::locked_sweep_all(const std::vector<std::string> &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<std::string> &args_)
+@@ -7016,6 +7166,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
bool simple_wallet::sweep_unmixable(const std::vector<std::string> &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<std::string> &args_)
+@@ -7123,6 +7274,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
- bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector<std::string> &args_)
+ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, const std::vector<std::string> &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<std::string> &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<std::string> &args_)
+@@ -7642,12 +7795,14 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sweep_all(const std::vector<std::string> &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<std::string> &args_)
+@@ -7668,6 +7823,7 @@ bool simple_wallet::sweep_account(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sweep_below(const std::vector<std::string> &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<std::string> &args_)
+@@ -7686,6 +7842,7 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::donate(const std::vector<std::string> &args_)
{
@@ -501,7 +485,7 @@ index f2eaf6b13..341b0e448 100644
std::vector<std::string> local_args = args_;
if(local_args.empty() || local_args.size() > 5)
{
-@@ -7864,6 +8023,7 @@ bool simple_wallet::donate(const std::vector<std::string> &args_)
+@@ -7747,6 +7904,7 @@ bool simple_wallet::donate(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &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<std::string> &args_)
+@@ -7927,6 +8085,7 @@ bool simple_wallet::sign_transfer(const std::vector<std::string> &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<crypto::sec
+@@ -8034,6 +8193,8 @@ std::string get_tx_key_stream(crypto::secret_key tx_key, std::vector<crypto::sec
bool simple_wallet::get_tx_key(const std::vector<std::string> &args_)
{
@@ -526,7 +510,7 @@ index f2eaf6b13..341b0e448 100644
std::vector<std::string> 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<std::string> &args_)
+@@ -8074,6 +8235,8 @@ bool simple_wallet::get_tx_key(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::set_tx_key(const std::vector<std::string> &args_)
{
@@ -535,7 +519,7 @@ index f2eaf6b13..341b0e448 100644
std::vector<std::string> 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<std::string> &args_)
+@@ -8150,6 +8313,8 @@ bool simple_wallet::set_tx_key(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::get_tx_proof(const std::vector<std::string> &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<std::string> &args)
+@@ -8356,6 +8521,7 @@ bool simple_wallet::check_tx_proof(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::get_spend_proof(const std::vector<std::string> &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<std::string> &args)
+@@ -8440,6 +8606,7 @@ bool simple_wallet::check_spend_proof(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::get_reserve_proof(const std::vector<std::string> &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<std::string> &args_)
+@@ -9126,6 +9293,8 @@ bool simple_wallet::unspent_outputs(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::rescan_blockchain(const std::vector<std::string> &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<std::string> &args/* = std::vector
+@@ -9423,6 +9592,7 @@ bool simple_wallet::account(const std::vector<std::string> &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<std::string> &args/* = std::vector
+@@ -9453,6 +9623,7 @@ bool simple_wallet::account(const std::vector<std::string> &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<std::string> &args/* = std::vector
+@@ -9474,6 +9645,7 @@ bool simple_wallet::account(const std::vector<std::string> &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<uint32_t> account_indices;
for (size_t i = 1; i < local_args.size(); ++i)
-@@ -9615,6 +9789,7 @@ bool simple_wallet::account(const std::vector<std::string> &args/* = std::vector
+@@ -9498,6 +9670,7 @@ bool simple_wallet::account(const std::vector<std::string> &args/* = std::vector
}
else if (command == "untag" && local_args.size() >= 1)
{
@@ -601,7 +585,7 @@ index f2eaf6b13..341b0e448 100644
std::set<uint32_t> account_indices;
for (size_t i = 0; i < local_args.size(); ++i)
{
-@@ -9638,6 +9813,7 @@ bool simple_wallet::account(const std::vector<std::string> &args/* = std::vector
+@@ -9521,6 +9694,7 @@ bool simple_wallet::account(const std::vector<std::string> &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<std::string> &args/* = std::
+@@ -9638,6 +9812,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &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<std::string> &args/* = std::
+@@ -9650,6 +9825,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &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<std::string> &args/* = std::
+@@ -9675,6 +9851,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &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<std::string> &args/* = std::
+@@ -9693,6 +9870,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &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<std::string> &arg
+@@ -9839,6 +10017,8 @@ bool simple_wallet::print_integrated_address(const std::vector<std::string> &arg
//----------------------------------------------------------------------------------------------------
bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
@@ -650,7 +634,7 @@ index f2eaf6b13..341b0e448 100644
if (args.size() == 0)
{
}
-@@ -10016,6 +10198,8 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
+@@ -9899,6 +10079,8 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
//----------------------------------------------------------------------------------------------------
bool simple_wallet::set_tx_note(const std::vector<std::string> &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<std::string> &args)
+@@ -9927,6 +10109,8 @@ bool simple_wallet::set_tx_note(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::get_tx_note(const std::vector<std::string> &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<std::string> &args)
+@@ -9952,6 +10136,8 @@ bool simple_wallet::get_tx_note(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::set_description(const std::vector<std::string> &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<std::string> &args)
+@@ -9968,6 +10154,8 @@ bool simple_wallet::set_description(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::get_description(const std::vector<std::string> &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<std::string> &args)
+@@ -10026,6 +10214,8 @@ bool simple_wallet::wallet_info(const std::vector<std::string> &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<std::string> &args)
+@@ -10037,6 +10227,7 @@ bool simple_wallet::wallet_info(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sign(const std::vector<std::string> &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<std::string> &args_)
+@@ -10144,6 +10335,7 @@ bool simple_wallet::export_key_images(const std::vector<std::string> &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<std::string> &args)
+@@ -10197,6 +10389,7 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &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<std::string> &args_)
+@@ -10305,6 +10498,7 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &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<std::string> &args)
+@@ -10354,6 +10548,7 @@ bool simple_wallet::import_outputs(const std::vector<std::string> &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<std::string> &args = std::vector<std::string>());
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
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<std::pair<uint64_t, uint64_
+@@ -4342,8 +4433,12 @@ void wallet2::handle_reorg(uint64_t height, std::map<std::pair<uint64_t, uint64_
// C
THROW_WALLET_EXCEPTION_IF(height < m_blockchain.offset() && m_blockchain.size() > 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<wallet2::keys_file_data> 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::keys_file_data> 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::keys_file_data> wallet2::get_keys_file_data(const epee:
+@@ -4590,6 +4724,9 @@ boost::optional<wallet2::keys_file_data> 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::keys_file_data> wallet2::get_keys_file_data(const epee:
+@@ -4649,6 +4786,11 @@ boost::optional<wallet2::keys_file_data> 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<wallet2::cache_file_data> 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::cache_file_data> wallet2::get_cache_file_data()
-@@ -6569,7 +6997,7 @@ boost::optional<wallet2::cache_file_data> wallet2::get_cache_file_data()
+@@ -6570,7 +6998,7 @@ boost::optional<wallet2::cache_file_data> wallet2::get_cache_file_data()
std::string cipher;
cipher.resize(cache_file_data.get().cache_data.size());
cache_file_data.get().iv = crypto::rand<crypto::chacha_iv>();
@@ -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<std::vector<tools::wallet2::get_outs_entry>> &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<crypto::public_key> &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<std::pair<uint32_t, uint64_t>> 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<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> 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<std::pair<crypto::key_image, crypto::signature>> 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<crypto::hash> txids;
std::list<std::string>::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 e3aeae9..eebe097 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 <tob@featherwallet.org>
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<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_major, bool strict) const
{
std::map<uint32_t, uint64_t> amount_per_subaddr;
-@@ -7887,9 +7916,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
+@@ -7889,9 +7918,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
crypto::key_derivation derivation;
std::vector<crypto::key_derivation> 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<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const;
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> 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 fd777c3..1700a61 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 <tob@featherwallet.org>
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::vector<stri
- fake_outs_count = m_wallet->adjust_mixin(mixin_count);
-
- if (amount) {
-+ // (std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs, const std::vector<crypto::key_image>& 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<stri
+@@ -1920,10 +1935,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
}
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, optional<uint64_t> 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::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
-+std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list, const unique_index_container& subtract_fee_from_outputs)
+-std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
++std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& 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::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+@@ -11400,7 +11435,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// will get us a known fee.
uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
total_needed_money = needed_money + (subtract_fee_from_outputs.size() ? 0 : estimated_fee);
@@ -844,16 +827,16 @@ index 700816da6..5331f90fc 100644
if (!preferred_inputs.empty())
{
string s;
-@@ -11874,7 +11909,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
+@@ -11879,7 +11914,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
return true;
}
--std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
-+std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
+-std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
++std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
{
std::vector<size_t> unused_transfers_indices;
std::vector<size_t> unused_dust_indices;
-@@ -11903,6 +11938,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
+@@ -11908,6 +11943,9 @@ std::vector<wallet2::pending_tx> 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<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
bool parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
-- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
-- std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
-+ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
-+ std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
- std::vector<wallet2::pending_tx> 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<uint8_t>& extra);
- std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
+- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
+- std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
++ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
++ std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
+ std::vector<wallet2::pending_tx> 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<uint8_t>& extra);
+ std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, const std::vector<cryptonote::tx_destination_entry>& 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 2215c99..985df3e 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 <cyjan@mrcyjanek.net>
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 c149232..f7c48b9 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 <you@example.com>
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 <cyjan@mrcyjanek.net>
+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 25827bb..f39c49e 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 <cyjan@mrcyjanek.net>
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::vector<std::stri
- return false;
- }
- unlock_block = bc_height + locked_blocks;
-- 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);
-+ 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<std::string> &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<wallet2::pending_tx> 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<wallet2::pending_tx> 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<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
+ bool parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
+- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
++ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
+ std::vector<wallet2::pending_tx> 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<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
+ std::vector<wallet2::pending_tx> 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<uint8_t>& extra);
+ std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& 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 cdd4ef2..5b46d7c 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 <cyjan@mrcyjanek.net>
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 3c2510e..0ef9900 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 <konstantinullrich12@gmail.com>
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 <godilite@gmail.com>
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 502de5e..e317627 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 <m@cakewallet.com>
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 dfb96e2..1ddae67 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 <cyjan@mrcyjanek.net>
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<int> m_refreshIntervalMillis;
std::atomic<bool> 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<cryptonote::block_complete_entry> next_blocks;
std::vector<parsed_block> 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 d6dc1bd..564be97 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 <cyjan@mrcyjanek.net>
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<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> wallet2::export_key_images(bool all) const
{
-@@ -14132,53 +14139,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
+@@ -14137,53 +14144,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
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 dce3536..2b741a0 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 <cyjan@mrcyjanek.net>
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
index 7049065..20e2822 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 <cyjan@mrcyjanek.net>
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
index 892a827..aef7dcf 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 <cyjan@mrcyjanek.net>
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
index e168139..364d6fd 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 77f328ba6befb9b964f764a27f8a03b71bf9095d Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
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 +-
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 0000000..e555829
--- /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 <cyjan@mrcyjanek.net>
+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 <stdint.h>
+ #include <boost/utility/string_ref.hpp>
+
+ #include <string>
+--
+2.43.0
+
diff --git a/patches/monero/0017-added-deps.patch b/patches/monero/0017-added-deps.patch
new file mode 100644
index 0000000..4edacce
--- /dev/null
+++ b/patches/monero/0017-added-deps.patch
@@ -0,0 +1,29 @@
+From 8f0b07a685b5971f4deb66bb8c53e6da4065370c Mon Sep 17 00:00:00 2001
+From: cyan <cyjan@mrcyjanek.net>
+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/patches/monero/0018-fix-coin-control-patch.patch b/patches/monero/0018-fix-coin-control-patch.patch
new file mode 100644
index 0000000..001a1c0
--- /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 <cyjan@mrcyjanek.net>
+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::vector<stri
+ if (amount) {
+ transaction->m_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)
+
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 0000000..e555829
--- /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 <cyjan@mrcyjanek.net>
+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 <stdint.h>
+ #include <boost/utility/string_ref.hpp>
+
+ #include <string>
+--
+2.43.0
+
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 9e953b5..19a14ba 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<Monero::Wallet*>(wallet_ptr);
- std::set<std::string> dst_addr_ = splitString(std::string(dst_addr_list), std::string(dst_addr_list_separator));
- std::vector<std::string> dst_addr(dst_addr_.begin(), dst_addr_.end());
+ std::vector<std::string> dst_addr = splitStringVector(std::string(dst_addr_list), std::string(dst_addr_list_separator));
Monero::optional<std::vector<uint64_t>> 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 a28e9fd..40723cc 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 = "07d67f34a07869aaa4af6ca04e142dbad2fb1fba0e2ebdefd22bc333fd982e25-e25963cbc11ca0a0fe5eb34b9bd7c72e4f51b795";
const char * WOWNERO_wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4";
#endif