60 Commits

Author SHA1 Message Date
Some Random Crypto Guy 6b34fe88da bumped Salvium version to include more RPC and API fixes 2025-10-08 20:33:21 +01:00
Some Random Crypto Guy aa394d8509 added Carrot secrets to API calls; bumped salvium 2025-10-07 16:02:40 +01:00
Some Random Crypto Guy 59fc73d7a9 bumped salvium version 2025-10-07 15:14:23 +01:00
Some Random Crypto Guy a744e15783 updated and added various wallet API fixes 2025-10-07 14:04:08 +01:00
Some Random Crypto Guy 2b15a84077 fixed coin control patch to work with v1.0.1 2025-10-06 13:53:45 +01:00
Some Random Crypto Guy 79284e8e6a zano updates 2025-10-06 13:49:39 +01:00
Some Random Crypto Guy 23f475eb6d bumped to latest salvium version 2025-10-06 12:27:32 +01:00
Some Random Crypto Guy 45d8a8673f updated git submodule 2025-10-06 11:53:29 +01:00
Some Random Crypto Guy 606b38f999 updated checksums 2025-10-02 22:09:44 +01:00
Some Random Crypto Guy 4c6ef8696a updated libwallet2_api functions 2025-10-02 22:05:21 +01:00
Some Random Crypto Guy bc36b47870 fixed 0017 patch for v1.0.0 2025-10-02 20:27:03 +01:00
Some Random Crypto Guy b577c6ab26 bumped salvium version 2025-10-02 20:23:02 +01:00
Some Random Crypto Guy 1fc46bc09d updated zano 2025-09-30 14:48:07 +01:00
Some Random Crypto Guy 224a4665aa fixed patches for dummy device etc 2025-09-30 14:22:47 +01:00
Some Random Crypto Guy df059e02b6 added ledger functions; added serialize_cache_to_JSON() functionality 2025-09-30 09:54:09 +01:00
Some Random Crypto Guy 78c6768b51 initial import of serialize_cache_to_JSON functionality 2025-09-30 09:34:13 +01:00
Some Random Crypto Guy a621c658a8 initialised var on construction 2025-09-30 09:18:40 +01:00
cyan b814d22f97 fix: tests 2025-09-30 09:18:05 +01:00
renovate[bot] 63f0e9b137 chore(deps): update 8bitjonny/gh-get-current-pr action to v4 2025-09-30 09:18:05 +01:00
Czarek Nakamoto 8c68284aba fix: prepare for 16KB pages 2025-09-30 09:18:05 +01:00
Czarek Nakamoto 2968e45b4c serialize cache to json 2025-09-30 09:18:05 +01:00
cyan 8f10e7748f fix: icu4c.mk builds with TARGET= set by compiler 2025-09-30 09:18:05 +01:00
Czarek Nakamoto 04ec60d6df feat: enable desktop HIDAPI_DUMMY 2025-09-30 09:18:05 +01:00
Czarek Nakamoto d7cdce9994 fix: upload logic 2025-09-30 09:18:05 +01:00
Czarek Nakamoto 6cb45bf907 feat: bump android_ndk to r28
chore: bump unbound to fix build issues
2025-09-30 09:18:05 +01:00
Czarek Nakamoto 778cf30248 feat: more efficient ssh uploads 2025-09-30 09:18:05 +01:00
cyan 3aba4e8522 feat: jenkins CI initial (#142)
* feat: jenkins CI initial
* feat: publish over SSH
* feat: more details regarding build-id generation
* feat: prebuild download logic
* feat: force fast_builds on GitHub CI runs
* feat: add make clean to contrib/depends and invoke it on CI to reduce SSH upload step time
* fix: correct linux save path
* revert: make clean
* separate builds
* enhance sshPublisher
* fix: github CI: depracate GitHub cache, fix DEPENDS_UNTRUSTED_FAST_BUILDS
* fix: sha256sum logic
* chore: refactor github actions and Jenkinsfile to only execute when required
* ci: update ci to 15 and xcode to 16.4
* ci: cleanup builddir before starting
2025-09-30 09:18:05 +01:00
cyan 1a01d3f06c fix: missing _MONERO_Wallet_setLedgerCallback exp 2025-09-30 09:18:05 +01:00
Czarek Nakamoto 55b1865d38 fix: copy data in setDeviceReceivedData 2025-09-30 09:18:05 +01:00
cyan 8b3d0f2c35 feat: callback-based ledger connection (#137)
* feat: callback-based ledger connection
* int -> void use sendToLedgerDeviceCallback only when needed
* fix(ledger): fix binds, make functions static
* update ledger patch
* monero.dart: add ledger callback api
2025-09-30 09:16:58 +01:00
cyan 27dd9d3e85 oo-monerodart (#135) 2025-09-30 08:53:05 +01:00
renovate[bot] 6516ae02d0 chore(deps): update ghcr.io/cirruslabs/flutter docker tag to v3.29.3 2025-09-30 08:52:45 +01:00
cyan da6c95ff28 sdk updates (#133)
* cmake: fix minimum required version

* fix: unary_function -> __unary_function

* fix it only where it's broken

* update zano to 400

* improve ci speed, update xcode

* update dockerfile, remove zano mingw

* 16.2
2025-09-30 08:52:18 +01:00
Czarek Nakamoto 5ab515a7f7 fix cmake 4.0.0 2025-09-30 08:51:25 +01:00
renovate[bot] 02dd30d81a chore(deps): update dependency ffigen to v18 (#124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-30 08:50:14 +01:00
renovate[bot] f0a5d0bc36 chore(deps): update zano digest to ccfc032 (#126)
* chore(deps): update zano digest to ccfc032
* update zano checksum

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: cyan <cyjan@mrcyjanek.net>
2025-09-30 08:49:54 +01:00
Some Random Crypto Guy 7f3144409c bumped Salvium build 2025-09-12 16:35:36 +01:00
Some Random Crypto Guy 227cb1071f added asset() and type() methods to CoinsInfo API - part 2 2025-09-12 15:31:04 +01:00
Some Random Crypto Guy 392b0289e3 added asset() and type() methods to CoinsInfo API 2025-09-12 13:56:34 +01:00
Some Random Crypto Guy 05a4ff1014 added type and asset to the TransactionInfo methods 2025-09-11 13:45:39 +01:00
Some Random Crypto Guy 5f18f0ee0a fixed params for createStakeTransaction(); switched to #develop branch of Salvium 2025-09-10 12:47:52 +01:00
Some Random Crypto Guy f830757605 updated Salvium build 2025-09-10 09:52:27 +01:00
Some Random Crypto Guy b1edbca038 updated bindings to support asset() and type() querying 2025-08-15 11:30:40 +01:00
Some Random Crypto Guy ac72e852a5 updated Salvium build 2025-08-15 09:11:45 +01:00
Some Random Crypto Guy 8100f752e2 added asset() and type() methods to CoinsInfo API 2025-08-11 13:10:46 +01:00
Some Random Crypto Guy 808a0671c1 fixed coin-control patch to work with emplace_back() code instead of the deprecated tools::add_element() code 2025-08-11 11:27:30 +01:00
Some Random Crypto Guy 7e278fac3d updated to support asset() and type() functionality 2025-08-11 10:36:37 +01:00
Some Random Crypto Guy 1831f243ff fixed iOS RandomX crash 2025-08-08 11:11:53 +01:00
Some Random Crypto Guy af359f4151 updated patches to apply cleanly to Salvium One with the new Carrot + SPARC code 2025-08-07 12:11:47 +01:00
Some Random Crypto Guy db4e559ce5 updated to latest carrot-integration build of Salvium 2025-08-07 11:23:41 +01:00
Some Random Crypto Guy e78aa5a863 fixed polyseed patch against latest Salvium One codebase 2025-06-05 14:27:48 +01:00
Some Random Crypto Guy f31c97c303 updated patches to build against Salvium One pre-alpha codebase 2025-06-02 15:49:05 +01:00
Some Random Crypto Guy d837147a0d removed extraneous files 2025-03-18 11:09:10 +00:00
Some Random Crypto Guy c4e09d99d6 fixed calls to wallet2_api functions 2025-03-18 10:45:48 +00:00
Some Random Crypto Guy 235107fe5d updated build to include correct source files upstream; renamed codebase to use SALVIUM_ 2025-03-18 10:31:55 +00:00
Some Random Crypto Guy e79f77f0a6 patches working 2025-03-18 09:58:46 +00:00
Some Random Crypto Guy dd7d17fb23 added background sync patch 2025-03-17 21:30:14 +00:00
Some Random Crypto Guy 5d5019d58f updated patches to apply against rebase-v0.18 2025-03-17 21:26:55 +00:00
Some Random Crypto Guy fab66493eb updated a couple of patches to work against the rebased v0.18.4.0 Zero code 2025-03-17 13:21:40 +00:00
Some Random Crypto Guy a4c301a9a9 initial import of salvium submodule and associated changes (not functional) 2025-03-14 15:38:13 +00:00
81 changed files with 25261 additions and 523 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
FROM --platform=linux/amd64 ghcr.io/cirruslabs/flutter:3.24.3
FROM --platform=linux/amd64 ghcr.io/cirruslabs/flutter:3.29.3
# FROM debian:bookworm
SHELL ["/bin/bash", "-c"]
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
with:
fetch-depth: 0
submodules: recursive
- uses: 8BitJonny/gh-get-current-pr@3.0.0
- uses: 8BitJonny/gh-get-current-pr@4.0.0
id: PR
- uses: subosito/flutter-action@v2
with:
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
with:
fetch-depth: 0
submodules: recursive
- uses: 8BitJonny/gh-get-current-pr@3.0.0
- uses: 8BitJonny/gh-get-current-pr@4.0.0
id: PR
- uses: subosito/flutter-action@v2
with:
+192 -175
View File
@@ -9,6 +9,7 @@ jobs:
fail-fast: false
matrix:
coin: [monero, wownero]
target: [x86_64-w64-mingw32, i686-w64-mingw32]
runs-on: ubuntu-latest
container:
image: ubuntu:24.04
@@ -26,25 +27,19 @@ jobs:
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
./apply_patches.sh monero
./apply_patches.sh wownero
./apply_patches.sh zano
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.coin }}
- name: Cache built
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: actions/cache@v4
with:
path: |
contrib/depends/built/*
key: depends-${{ github.job }}-${{ hashFiles('contrib/depends/packages/*.mk') }}
- name: ${{ matrix.coin }}/x86_64-w64-mingw32
run: ./build_single.sh ${{ matrix.coin }} x86_64-w64-mingw32 -j$(nproc)
- name: ${{ matrix.coin }}/i686-w64-mingw32
run: ./build_single.sh ${{ matrix.coin }} i686-w64-mingw32 -j$(nproc)
key: ${{ github.job }}-${{ matrix.coin }}-${{ matrix.target }}
- name: Build ${{ matrix.coin }} for ${{ matrix.target }}
run: |
env DEPENDS_UNTRUSTED_FAST_BUILDS=forced ./build_single.sh ${{ matrix.coin }} ${{ matrix.target }} -j$(nproc)
- name: rename artifacts
run: |
mkdir release/gh/
mkdir -p release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
@@ -58,16 +53,16 @@ jobs:
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: mingw ${{ matrix.coin }}
name: mingw-${{ matrix.coin }}-${{ matrix.target }}
path: release/${{ matrix.coin }}
lib_android:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
target: [x86_64-linux-android, armv7a-linux-androideabi, aarch64-linux-android]
runs-on: ubuntu-22.04
# container:
# image: debian:bookworm
steps:
- name: Free Disk Space
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
@@ -93,27 +88,19 @@ jobs:
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
./apply_patches.sh monero
./apply_patches.sh wownero
./apply_patches.sh zano
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.coin }}
- name: Cache built
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: actions/cache@v4
with:
path: |
contrib/depends/built/*
key: depends-${{ github.job }}-${{ hashFiles('contrib/depends/packages/*.mk') }}
- name: ${{ matrix.coin }}/x86_64-linux-android
run: ./build_single.sh ${{ matrix.coin }} x86_64-linux-android -j$(nproc)
- name: ${{ matrix.coin }}/aarch64-linux-android
run: ./build_single.sh ${{ matrix.coin }} aarch64-linux-android -j$(nproc)
- name: ${{ matrix.coin }}/armv7a-linux-androideabi
run: ./build_single.sh ${{ matrix.coin }} armv7a-linux-androideabi -j$(nproc)
key: ${{ github.job }}-${{ matrix.coin }}-${{ matrix.target }}
- name: Build ${{ matrix.coin }} for ${{ matrix.target }}
run: |
env DEPENDS_UNTRUSTED_FAST_BUILDS=forced ./build_single.sh ${{ matrix.coin }} ${{ matrix.target }} -j$(nproc)
- name: rename artifacts
run: |
mkdir release/gh/
mkdir -p release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
@@ -127,17 +114,19 @@ jobs:
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: android ${{ matrix.coin }}
name: android-${{ matrix.coin }}-${{ matrix.target }}
path: release/${{ matrix.coin }}
- name: remove android_ndk
run: |
rm -rf contrib/depends/built/*/android_ndk
rm -rf contrib/depends/sources/android-ndk-r26d-linux.zip
lib_linux:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
target: [x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu]
runs-on: ubuntu-latest
container:
image: debian:bullseye
@@ -155,27 +144,19 @@ jobs:
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
./apply_patches.sh monero
./apply_patches.sh wownero
./apply_patches.sh zano
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.coin }}
- name: Cache built
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: actions/cache@v4
with:
path: |
contrib/depends/built/*
key: depends-${{ github.job }}-${{ hashFiles('contrib/depends/packages/*.mk') }}
- name: ${{ matrix.coin }}/x86_64-linux-gnu
run: ./build_single.sh ${{ matrix.coin }} x86_64-linux-gnu -j$(nproc)
- name: ${{ matrix.coin }}/aarch64-linux-gnu
run: ./build_single.sh ${{ matrix.coin }} aarch64-linux-gnu -j$(nproc)
- name: ${{ matrix.coin }}/i686-linux-gnu
run: ./build_single.sh ${{ matrix.coin }} i686-linux-gnu -j$(nproc)
key: ${{ github.job }}-${{ matrix.coin }}-${{ matrix.target }}
- name: Build ${{ matrix.coin }} for ${{ matrix.target }}
run: |
env DEPENDS_UNTRUSTED_FAST_BUILDS=forced ./build_single.sh ${{ matrix.coin }} ${{ matrix.target }} -j$(nproc)
- name: rename artifacts
run: |
mkdir release/gh/
mkdir -p release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
@@ -189,15 +170,17 @@ jobs:
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: linux ${{ matrix.coin }}
name: linux-${{ matrix.coin }}-${{ matrix.target }}
path: release/${{ matrix.coin }}
lib_macos:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
target: [aarch64-apple-darwin, x86_64-apple-darwin]
name: macos build
runs-on: macos-14
runs-on: macos-15
steps:
- name: Checkout monero_c repo
uses: actions/checkout@v4
@@ -207,36 +190,29 @@ jobs:
submodules: recursive
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '15.4'
xcode-version: '16.4'
- name: install dependencies
run: |
brew install ccache binutils pigz autoconf automake libtool pkg-config
brew uninstall cmake
brew install cmake ccache binutils pigz autoconf automake libtool pkg-config
- name: Patch sources
run: |
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
./apply_patches.sh monero
./apply_patches.sh wownero
./apply_patches.sh zano
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.coin }}
- name: Cache built
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: actions/cache@v4
with:
path: |
contrib/depends/built/*
key: depends-${{ github.job }}-${{ hashFiles('contrib/depends/packages/*.mk') }}
- name: build (aarch64-apple-darwin)
key: ${{ github.job }}-${{ matrix.coin }}-${{ matrix.target }}
- name: Build ${{ matrix.coin }} for ${{ matrix.target }}
run: |
./build_single.sh ${{ matrix.coin }} aarch64-apple-darwin -j$(sysctl -n hw.logicalcpu)
- name: build (x86_64-apple-darwin)
run: |
./build_single.sh ${{ matrix.coin }} x86_64-apple-darwin -j$(sysctl -n hw.logicalcpu)
env DEPENDS_UNTRUSTED_FAST_BUILDS=forced ./build_single.sh ${{ matrix.coin }} ${{ matrix.target }} -j$(sysctl -n hw.logicalcpu)
- name: rename artifacts
run: |
mkdir release/gh/
mkdir -p release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
@@ -250,13 +226,15 @@ jobs:
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: macos ${{ matrix.coin }}
name: macos-${{ matrix.coin }}-${{ matrix.target }}
path: release/${{ matrix.coin }}
lib_ios:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
target: [aarch64-apple-ios, aarch64-apple-iossimulator]
name: ios build
runs-on: macos-15
steps:
@@ -268,38 +246,29 @@ jobs:
submodules: recursive
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '16.1'
xcode-version: '16.4'
- name: install dependencies
run: |
brew install ccache cmake autoconf automake libtool
brew uninstall cmake
brew install cmake ccache autoconf automake libtool
- name: Patch sources
run: |
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
./apply_patches.sh monero
./apply_patches.sh wownero
./apply_patches.sh zano
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.coin }}
- name: Cache built
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: actions/cache@v4
with:
path: |
contrib/depends/built/*
key: depends-${{ github.job }}-${{ hashFiles('contrib/depends/packages/*.mk') }}
- name: build (aarch64-apple-ios)
key: ${{ github.job }}-${{ matrix.coin }}-${{ matrix.target }}
- name: Build ${{ matrix.coin }} for ${{ matrix.target }}
run: |
./build_single.sh ${{ matrix.coin }} aarch64-apple-ios -j$(sysctl -n hw.logicalcpu)
- name: build (aarch64-apple-iossimulator)
run: |
./build_single.sh ${{ matrix.coin }} aarch64-apple-iossimulator -j$(sysctl -n hw.logicalcpu)
env DEPENDS_UNTRUSTED_FAST_BUILDS=forced ./build_single.sh ${{ matrix.coin }} ${{ matrix.target }} -j$(sysctl -n hw.logicalcpu)
- name: rename artifacts
run: |
mkdir release/gh/
mkdir -p release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
@@ -313,90 +282,123 @@ jobs:
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: ios ${{ matrix.coin }}
name: ios-${{ matrix.coin }}-${{ matrix.target }}
path: release/${{ matrix.coin }}
bulk_lib_release:
name: create single release file
runs-on: ubuntu-latest
needs: [
lib_mingw, lib_android, lib_linux, lib_macos, lib_ios
]
needs: [lib_mingw, lib_android, lib_linux, lib_macos, lib_ios]
strategy:
matrix:
coin: [monero, wownero, zano]
platform: [android, ios, linux, macos]
include:
- coin: monero
platform: mingw
- coin: wownero
platform: mingw
steps:
- uses: actions/download-artifact@v4
- name: Create release directory
run: mkdir -p release/${{ matrix.coin }}
- name: Download Android artifacts
if: matrix.platform == 'android'
uses: actions/download-artifact@v4
with:
name: android monero
path: release/monero
- uses: actions/download-artifact@v4
pattern: android-${{ matrix.coin }}-*
path: temp-android
merge-multiple: true
- name: Download iOS artifacts
if: matrix.platform == 'ios'
uses: actions/download-artifact@v4
with:
name: android wownero
path: release/wownero
- uses: actions/download-artifact@v4
pattern: ios-${{ matrix.coin }}-*
path: temp-ios
merge-multiple: true
- name: Download Linux artifacts
if: matrix.platform == 'linux'
uses: actions/download-artifact@v4
with:
name: android zano
path: release/zano
- uses: actions/download-artifact@v4
pattern: linux-${{ matrix.coin }}-*
path: temp-linux
merge-multiple: true
- name: Download macOS artifacts
if: matrix.platform == 'macos'
uses: actions/download-artifact@v4
with:
name: ios monero
path: release/monero
- uses: actions/download-artifact@v4
pattern: macos-${{ matrix.coin }}-*
path: temp-macos
merge-multiple: true
- name: Download MinGW artifacts
if: matrix.platform == 'mingw' && (matrix.coin == 'monero' || matrix.coin == 'wownero')
uses: actions/download-artifact@v4
with:
name: ios wownero
path: release/wownero
- uses: actions/download-artifact@v4
pattern: mingw-${{ matrix.coin }}-*
path: temp-mingw
merge-multiple: true
- name: Copy artifacts to release directory
run: |
if [ -d "temp-${{ matrix.platform }}" ]; then
cp -r temp-${{ matrix.platform }}/* release/${{ matrix.coin }}/
fi
- name: Upload consolidated artifacts
uses: actions/upload-artifact@v4
with:
name: ios zano
path: release/zano
- uses: actions/download-artifact@v4
name: ${{ matrix.platform }}-${{ matrix.coin }}-all
path: release/${{ matrix.coin }}
final_bulk_release:
name: create final release bundle
runs-on: ubuntu-latest
needs: [bulk_lib_release]
steps:
- name: Create release directory
run: mkdir -p release/{monero,wownero,zano}
- name: Download all consolidated artifacts
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: linux zano
path: release/zano
- 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: macos zano
path: release/zano
- uses: actions/download-artifact@v4
with:
name: mingw monero
path: release/monero
- uses: actions/download-artifact@v4
with:
name: mingw wownero
path: release/wownero
pattern: "*-all"
path: temp-all
- name: Reorganize artifacts
run: |
# Move all artifacts to their respective coin directories
for coin in monero wownero zano; do
find temp-all -name "*-${coin}-all" -type d | while read dir; do
if [ -d "$dir" ]; then
cp -r "$dir"/* "release/${coin}/" 2>/dev/null || true
fi
done
done
- 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
- name: Upload final bundle
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
]
needs: [lib_linux]
steps:
- uses: actions/checkout@v4
with:
@@ -404,10 +406,13 @@ jobs:
submodules: recursive
- uses: actions/download-artifact@v4
with:
name: linux monero
path: release/monero
pattern: linux-monero-x86_64-linux-gnu
path: temp-linux-monero
merge-multiple: true
- name: unpack and move monero_c
run: |
mkdir -p release/monero
cp -r temp-linux-monero/* release/monero/
unxz -f -k release/*/*.xz
- uses: denoland/setup-deno@v1
with:
@@ -431,9 +436,7 @@ jobs:
fail-fast: false
matrix:
coin: [monero, wownero]
needs: [
lib_linux
]
needs: [lib_linux]
runs-on: ubuntu-24.04
steps:
- uses: denoland/setup-deno@v2
@@ -447,8 +450,14 @@ jobs:
- uses: actions/download-artifact@v4
with:
name: linux ${{ matrix.coin }}
path: release/${{ matrix.coin }}
pattern: linux-${{ matrix.coin }}-*
path: temp-linux-${{ matrix.coin }}
merge-multiple: true
- name: Setup release directory
run: |
mkdir -p release/${{ matrix.coin }}
cp -r temp-linux-${{ matrix.coin }}/* release/${{ matrix.coin }}/
- name: Run regression tests
run: COIN="${{ matrix.coin }}" deno test -A tests/regression.test.ts
@@ -458,10 +467,8 @@ jobs:
strategy:
matrix:
coin: [monero, wownero]
needs: [
lib_macos
]
runs-on: macos-14
needs: [lib_macos]
runs-on: macos-15
steps:
- uses: denoland/setup-deno@v2
with:
@@ -474,8 +481,14 @@ jobs:
- uses: actions/download-artifact@v4
with:
name: macos ${{ matrix.coin }}
path: release/${{ matrix.coin }}
pattern: macos-${{ matrix.coin }}-*
path: temp-macos-${{ matrix.coin }}
merge-multiple: true
- name: Setup release directory
run: |
mkdir -p release/${{ matrix.coin }}
cp -r temp-macos-${{ matrix.coin }}/* release/${{ matrix.coin }}/
- name: Run regression tests
run: COIN="${{ matrix.coin }}" deno test -A tests/regression.test.ts
@@ -485,9 +498,7 @@ jobs:
strategy:
matrix:
coin: [monero, wownero]
needs: [
lib_linux
]
needs: [lib_linux]
runs-on: ubuntu-24.04
steps:
- uses: denoland/setup-deno@v2
@@ -501,8 +512,14 @@ jobs:
- uses: actions/download-artifact@v4
with:
name: linux ${{ matrix.coin }}
path: release/${{ matrix.coin }}
pattern: linux-${{ matrix.coin }}-*
path: temp-linux-${{ matrix.coin }}
merge-multiple: true
- name: Setup release directory
run: |
mkdir -p release/${{ matrix.coin }}
cp -r temp-linux-${{ matrix.coin }}/* release/${{ matrix.coin }}/
- name: Run integration tests
run: COIN="${{ matrix.coin }}" deno test -A tests/integration.test.ts
@@ -511,16 +528,13 @@ jobs:
SECRET_WALLET_MNEMONIC: ${{ secrets.SECRET_WALLET_MNEMONIC }}
SECRET_WALLET_RESTORE_HEIGHT: ${{ secrets.SECRET_WALLET_RESTORE_HEIGHT }}
integration_tests_macos:
name: macos integration tests
strategy:
matrix:
coin: [monero, wownero]
needs: [
lib_macos
]
runs-on: macos-14
needs: [lib_macos]
runs-on: macos-15
steps:
- uses: denoland/setup-deno@v2
with:
@@ -533,8 +547,14 @@ jobs:
- uses: actions/download-artifact@v4
with:
name: macos ${{ matrix.coin }}
path: release/${{ matrix.coin }}
pattern: macos-${{ matrix.coin }}-*
path: temp-macos-${{ matrix.coin }}
merge-multiple: true
- name: Setup release directory
run: |
mkdir -p release/${{ matrix.coin }}
cp -r temp-macos-${{ matrix.coin }}/* release/${{ matrix.coin }}/
- name: Run integration tests
run: COIN="${{ matrix.coin }}" deno test -A tests/integration.test.ts
@@ -543,13 +563,10 @@ jobs:
SECRET_WALLET_MNEMONIC: ${{ secrets.SECRET_WALLET_MNEMONIC }}
SECRET_WALLET_RESTORE_HEIGHT: ${{ secrets.SECRET_WALLET_RESTORE_HEIGHT }}
comment_pr:
name: comment on pr
runs-on: ubuntu-latest
needs: [
lib_mingw, lib_android, lib_linux, lib_macos, lib_ios,
]
needs: [lib_mingw, lib_android, lib_linux, lib_macos, lib_ios]
steps:
- uses: actions/github-script@v7
continue-on-error: true
+5
View File
@@ -16,3 +16,8 @@
url = https://github.com/MrCyjaneK/wownero-seed
branch = cyjan-namespace2
shallow = true
[submodule "salvium"]
path = salvium
url = https://github.com/salvium/salvium
branch = main
shallow = true
+4 -4
View File
@@ -6,14 +6,14 @@ repo="$1"
if [[ "x$repo" == "x" ]];
then
echo "Usage: $0 monero/wownero"
echo "Usage: $0 monero/wownero/zano/salvium"
exit 1
fi
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" ]];
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" && "x$repo" != "xsalvium" ]];
then
echo "Usage: $0 monero/wownero"
echo "Invalid target given, only monero and wownero are supported targets"
echo "Usage: $0 monero/wownero/zano/salvium"
echo "Invalid target given, only monero, wownero,zano, and salvium are supported targets"
fi
if [[ ! -d "$repo" ]]
+6 -6
View File
@@ -20,13 +20,13 @@ set -e
repo=$1
if [[ "x$repo" == "x" ]];
then
echo "Usage: $0 monero/wownero/zano $(gcc -dumpmachine) -j$proccount"
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
exit 1
fi
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" ]];
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" && "x$repo" != "xsalvium" ]];
then
echo "Usage: $0 monero/wownero/zano $(gcc -dumpmachine) -j$proccount"
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
echo "Invalid target given"
exit 1
fi
@@ -41,7 +41,7 @@ fi
HOST_ABI="$2"
if [[ "x$HOST_ABI" == "x" ]];
then
echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount"
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
exit 1
fi
@@ -49,7 +49,7 @@ NPROC="$3"
if [[ "x$NPROC" == "x" ]];
then
echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount"
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
exit 1
fi
cd $(dirname $0)
@@ -59,7 +59,7 @@ pushd contrib/depends
then
echo "Not building depends, directory exists"
else
env -i PATH="$PATH" CC=gcc CXX=g++ make "$NPROC" HOST="$HOST_ABI"
env -i PATH="$PATH" CC=gcc CXX=g++ make "$NPROC" HOST="$HOST_ABI" DEPENDS_UNTRUSTED_FAST_BUILDS=$DEPENDS_UNTRUSTED_FAST_BUILDS
fi
popd
+265
View File
@@ -0,0 +1,265 @@
pipeline {
agent none
parameters {
string(
name: 'LINUX_TARGETS',
defaultValue: 'x86_64-linux-gnu,aarch64-linux-gnu,i686-linux-gnu',
description: 'Comma-separated list of Linux targets to build'
)
string(
name: 'ANDROID_TARGETS',
defaultValue: 'x86_64-linux-android,armv7a-linux-androideabi,aarch64-linux-android',
description: 'Comma-separated list of Android targets to build'
)
string(
name: 'MINGW_TARGETS',
defaultValue: 'x86_64-w64-mingw32,i686-w64-mingw32',
description: 'Comma-separated list of MinGW targets to build'
)
string(
name: 'DARWIN_TARGETS',
defaultValue: 'aarch64-apple-darwin,x86_64-apple-darwin,aarch64-apple-ios,aarch64-apple-iossimulator',
description: 'Comma-separated list of Darwin targets to build'
)
}
stages {
stage('Check Changes') {
agent any
steps {
script {
def changes = sh(
script: "git diff --name-only HEAD~1 HEAD | grep '^contrib/depends' || echo 'NO_CHANGES'",
returnStdout: true
).trim()
if (changes == 'NO_CHANGES') {
echo "No changes detected in contrib/depends directory. Skipping build."
currentBuild.result = 'NOT_BUILT'
return
} else {
echo "Changes detected in contrib/depends directory:"
echo changes
}
}
}
}
stage('Build Dependencies') {
when {
not {
equals expected: 'NOT_BUILT', actual: currentBuild.result
}
}
parallel {
stage('Linux Builds') {
agent {
dockerfile {
filename '.devcontainer/Dockerfile'
args '-v /opt/builds:/opt/builds'
label 'linux && amd64'
}
}
steps {
script {
def targets = params.LINUX_TARGETS.split(',').collect { it.trim() }
checkout scm
for (target in targets) {
echo "Building Linux dependencies for ${target}"
dir('contrib/depends') {
sh "rm -rf built/${target}/*"
sh "make HOST=${target} DEPENDS_UNTRUSTED_FAST_BUILDS=yes"
}
}
}
}
post {
always {
script {
def targets = params.LINUX_TARGETS.split(',').collect { it.trim() }
for (target in targets) {
uploadIfChanged(target)
}
}
}
}
}
stage('Android Builds') {
agent {
dockerfile {
filename '.devcontainer/Dockerfile'
args '-v /opt/builds:/opt/builds'
label 'linux && amd64'
}
}
steps {
script {
def targets = params.ANDROID_TARGETS.split(',').collect { it.trim() }
checkout scm
for (target in targets) {
echo "Building Android dependencies for ${target}"
dir('contrib/depends') {
sh "rm -rf built/${target}/*"
sh "make HOST=${target} DEPENDS_UNTRUSTED_FAST_BUILDS=yes"
}
}
}
}
post {
always {
script {
def targets = params.ANDROID_TARGETS.split(',').collect { it.trim() }
for (target in targets) {
uploadIfChanged(target)
}
}
}
}
}
stage('MinGW Builds') {
agent {
dockerfile {
filename '.devcontainer/Dockerfile'
args '-v /opt/builds:/opt/builds'
label 'linux && amd64'
}
}
steps {
script {
def targets = params.MINGW_TARGETS.split(',').collect { it.trim() }
checkout scm
for (target in targets) {
echo "Building MinGW dependencies for ${target}"
dir('contrib/depends') {
sh "rm -rf built/${target}/*"
sh "make HOST=${target} DEPENDS_UNTRUSTED_FAST_BUILDS=yes"
}
}
}
}
post {
always {
script {
def targets = params.MINGW_TARGETS.split(',').collect { it.trim() }
for (target in targets) {
uploadIfChanged(target)
}
}
}
}
}
stage('Darwin Builds') {
agent {
label 'darwin && arm64'
}
steps {
script {
def targets = params.DARWIN_TARGETS.split(',').collect { it.trim() }
checkout scm
for (target in targets) {
echo "Building dependencies for ${target}"
dir('contrib/depends') {
sh "rm -rf built/${target}/*"
sh "make HOST=${target} DEPENDS_UNTRUSTED_FAST_BUILDS=yes"
}
}
}
}
post {
always {
script {
def targets = params.DARWIN_TARGETS.split(',').collect { it.trim() }
for (target in targets) {
uploadIfChanged(target)
}
}
}
}
}
}
}
}
post {
always {
echo "Build completed."
}
}
}
def uploadIfChanged(target) {
withCredentials([sshUserPrivateKey(credentialsId: 'static-mrcyjanek-net-ssh-key', keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) {
sh """
set -e
upload_with_checksum() {
local file_path="\$1"
local remote_path="\$2"
local filename=\$(basename "\$file_path")
if [ ! -f "\$file_path" ]; then
echo "File \$file_path does not exist, skipping..."
return 0
fi
local_checksum=\$(sha256sum "\$file_path" | cut -d' ' -f1)
echo "Local checksum for \$filename: \$local_checksum"
remote_checksum=\$(ssh -i "\$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "\$SSH_USER@static.mrcyjanek.net" "cd \$remote_path && sha256sum \$filename 2>/dev/null | cut -d' ' -f1 || echo 'FILE_NOT_FOUND'")
echo "Remote checksum for \$filename: \$remote_checksum"
if [ "\$local_checksum" != "\$remote_checksum" ]; then
echo "Checksums differ, uploading \$filename..."
ssh -i "\$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "\$SSH_USER@static.mrcyjanek.net" "mkdir -p \$remote_path"
scp -i "\$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "\$file_path" "\$SSH_USER@static.mrcyjanek.net:\$remote_path/\$filename"
uploaded_checksum=\$(ssh -i "\$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "\$SSH_USER@static.mrcyjanek.net" "cd \$remote_path && sha256sum \$filename | cut -d' ' -f1")
if [ "\$local_checksum" = "\$uploaded_checksum" ]; then
echo "Upload successful for \$filename"
else
echo "Upload verification failed for \$filename"
exit 1
fi
else
echo "Checksums match, skipping upload for \$filename"
fi
}
echo "Processing target: ${target}"
for package_dir in contrib/depends/built/${target}/*/; do
if [ -d "\$package_dir" ]; then
package=\$(basename "\$package_dir")
echo "Processing package: \$package: \$(ls -la "\$package_dir")"
for file in "\$package_dir"/*.tar.gz*; do
remote_dir_base="/home/mrcyjanek/web/static.mrcyjanek.net/public_html/lfs/depends/contrib/depends/built/${target}/\$package"
echo "Uploading \$file to \$remote_dir_base"
upload_with_checksum "\$file" "\$remote_dir_base"
done
fi
done
echo "Finished processing ${target}"
"""
}
}
+38 -12
View File
@@ -13,6 +13,17 @@ DOWNLOAD_CONNECT_TIMEOUT:=30
DOWNLOAD_RETRIES:=5
HOST_ID_SALT ?= salt
BUILD_ID_SALT ?= salt
DEPENDS_UNTRUSTED_FAST_BUILDS ?=
PREBUILT_BASE_URL ?= https://static.mrcyjanek.net/lfs/depends/contrib/depends/built
ifneq ($(DEPENDS_UNTRUSTED_FAST_BUILDS),)
ifneq ($(DEPENDS_UNTRUSTED_FAST_BUILDS),yes)
ifneq ($(DEPENDS_UNTRUSTED_FAST_BUILDS),forced)
$(error DEPENDS_UNTRUSTED_FAST_BUILDS must be empty, "yes", or "forced", got "$(DEPENDS_UNTRUSTED_FAST_BUILDS)")
endif
endif
endif
# Detect the number of CPU cores
ifeq ($(shell uname), Darwin)
NUM_CORES := $(shell sysctl -n hw.ncpu)
@@ -110,19 +121,34 @@ include builders/$(build_os).mk
include builders/default.mk
include packages/packages.mk
# Legacy build ID strings (kept for debugging info)
build_id_string_legacy:=$(BUILD_ID_SALT)
build_id_string_legacy+=$(shell $(build_CC) --version 2>/dev/null)
build_id_string_legacy+=$(shell $(build_AR) --version 2>/dev/null)
build_id_string_legacy+=$(shell $(build_CXX) --version 2>/dev/null)
build_id_string_legacy+=$(shell $(build_RANLIB) --version 2>/dev/null)
build_id_string_legacy+=$(shell $(build_STRIP) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string_legacy:=$(HOST_ID_SALT)
$(host_arch)_$(host_os)_id_string_legacy+=$(shell $(host_CC) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string_legacy+=$(shell $(host_AR) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string_legacy+=$(shell $(host_CXX) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string_legacy+=$(shell $(host_RANLIB) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string_legacy+=$(shell $(host_STRIP) --version 2>/dev/null)
build_id_string:=$(BUILD_ID_SALT)
build_id_string+=$(shell $(build_CC) --version 2>/dev/null)
build_id_string+=$(shell $(build_AR) --version 2>/dev/null)
build_id_string+=$(shell $(build_CXX) --version 2>/dev/null)
build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null)
build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null)
build_id_string+=$(shell basename $(build_CC) 2>/dev/null || echo "unknown")
build_id_string+=$(shell basename $(build_AR) 2>/dev/null || echo "unknown")
build_id_string+=$(shell basename $(build_CXX) 2>/dev/null || echo "unknown")
build_id_string+=$(shell basename $(build_RANLIB) 2>/dev/null || echo "unknown")
build_id_string+=$(shell basename $(build_STRIP) 2>/dev/null || echo "unknown")
$(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell basename $(host_CC) 2>/dev/null || echo "unknown")
$(host_arch)_$(host_os)_id_string+=$(shell basename $(host_AR) 2>/dev/null || echo "unknown")
$(host_arch)_$(host_os)_id_string+=$(shell basename $(host_CXX) 2>/dev/null || echo "unknown")
$(host_arch)_$(host_os)_id_string+=$(shell basename $(host_RANLIB) 2>/dev/null || echo "unknown")
$(host_arch)_$(host_os)_id_string+=$(shell basename $(host_STRIP) 2>/dev/null || echo "unknown")
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
@@ -204,8 +230,8 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_
define check_or_remove_cached
mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \
$(build_SHA256SUM) -c $($(package)_cached_checksum) >/dev/null 2>/dev/null || \
( rm -f $($(package)_cached_checksum); \
if test -f "$($(package)_cached)"; then echo "Checksum mismatch for $(package). Forcing rebuild.."; rm -f $($(package)_cached_checksum) $($(package)_cached); fi )
( rm -f $($(package)_cached_checksum) $($(package)_cached_buildinfo); \
if test -f "$($(package)_cached)"; then echo "Checksum mismatch for $(package). Forcing rebuild.."; rm -f $($(package)_cached_checksum) $($(package)_cached) $($(package)_cached_buildinfo); fi )
endef
define check_or_remove_sources
+142 -12
View File
@@ -36,7 +36,7 @@ define fetch_file
endef
define int_get_build_recipe_hash
$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1))
$(eval $(1)_all_file_checksums:=$(shell cd $(BASEDIR) && $(build_SHA256SUM) $(subst $(BASEDIR)/,,$(meta_depends)) packages/$(1).mk $(addprefix patches/$(1)/,$($(1)_patches)) 2>/dev/null | cut -d" " -f1))
$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
endef
@@ -46,6 +46,8 @@ $(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type
$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string))
$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
$(eval $(1)_build_id_long_legacy:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string_legacy))
$(eval $(1)_build_id_legacy:=$(shell echo -n "$($(1)_build_id_long_legacy)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
final_build_id_long+=$($(package)_build_id_long)
#compute package-specific paths
@@ -59,10 +61,14 @@ $(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id
$(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version)
$(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir)
$(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.hash
$(1)_cached_buildinfo:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.txt
$(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id)
$(1)_prefixbin:=$($($(1)_type)_prefix)/bin/
$(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
$(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources)
$(1)_prebuilt_url:=$(PREBUILT_BASE_URL)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
$(1)_prebuilt_checksum_url:=$(PREBUILT_BASE_URL)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.hash
$(1)_prebuilt_buildinfo_url:=$(PREBUILT_BASE_URL)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.txt
#stamps
$(1)_fetched=$(SOURCES_PATH)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name).hash
@@ -73,6 +79,8 @@ $(1)_built=$$($(1)_build_dir)/.stamp_built
$(1)_configured=$$($(1)_build_dir)/.stamp_configured
$(1)_staged=$$($(1)_staging_dir)/.stamp_staged
$(1)_postprocessed=$$($(1)_staging_prefix_dir)/.stamp_postprocessed
$(1)_prebuilt_downloaded:=$(BASE_CACHE)/$(host)/$(1)/.stamp_prebuilt_downloaded-$($(1)_build_id)
$(1)_cached_or_prebuilt:=$(BASE_CACHE)/$(host)/$(1)/.stamp_cached_or_prebuilt-$($(1)_build_id)
$(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path))
@@ -198,61 +206,183 @@ COMPRESS_CMD := $(shell if command -v pigz >/dev/null 2>&1; then echo "pigz"; el
define int_add_cmds
$($(1)_fetched):
$(AT)echo "=== Fetching $(1) v$($(1)_version) ==="
$(AT)echo " Source directory: $($(1)_source_dir)"
$(AT)echo " Download file: $($(1)_download_file)"
$(AT)mkdir -p $$(@D) $(SOURCES_PATH)
$(AT)rm -f $$@
$(AT)touch $$@
$(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1))
$(AT)cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);)
$(AT)echo " Fetch completed: $$@"
$(AT)touch $$@
$($(1)_extracted): | $($(1)_fetched)
$(AT)echo Extracting $(1)...
$(AT)echo "=== Extracting $(1) v$($(1)_version) ==="
$(AT)echo " Build ID: $($(1)_build_id)"
$(AT)echo " Extract directory: $($(1)_extract_dir)"
$(AT)mkdir -p $$(@D)
$(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1))
$(AT)echo " Extract completed: $$@"
$(AT)touch $$@
$($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted)
$(AT)echo Preprocessing $(1)...
$(AT)echo "=== Preprocessing $(1) v$($(1)_version) ==="
$(AT)echo " Dependencies: $($(1)_dependencies)"
$(AT)echo " Patch directory: $($(1)_patch_dir)"
$(AT)echo " Patches: $($(1)_patches)"
$(AT)mkdir -p $$(@D) $($(1)_patch_dir)
$(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;)
$(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1))
$(AT)echo " Preprocessing completed: $$@"
$(AT)touch $$@
$($(1)_configured): | $($(1)_preprocessed)
$(AT)echo Configuring $(1)...
$(AT)echo "=== Configuring $(1) v$($(1)_version) ==="
$(AT)echo " Build directory: $($(1)_build_dir)"
$(AT)echo " Host prefix: $(host_prefix)"
$(AT)echo " All dependencies: $($(1)_all_dependencies)"
$(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar xf $($(package)_cached); )
$(AT)mkdir -p $$(@D)
$(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1))
$(AT)echo " Configuration completed: $$@"
$(AT)touch $$@
$($(1)_built): | $($(1)_configured)
$(AT)echo Building $(1)...
$(AT)echo "=== Building $(1) v$($(1)_version) ==="
$(AT)echo " Build directory: $($(1)_build_dir)"
$(AT)echo " Build environment: $($(1)_build_env)"
$(AT)mkdir -p $$(@D)
$(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1))
$(AT)echo " Build completed: $$@"
$(AT)touch $$@
$($(1)_staged): | $($(1)_built)
$(AT)echo Staging $(1)...
$(AT)echo "=== Staging $(1) v$($(1)_version) ==="
$(AT)echo " Staging directory: $($(1)_staging_dir)"
$(AT)echo " Staging prefix: $($(1)_staging_prefix_dir)"
$(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix)
$(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1))
$(AT)echo " Removing extract directory: $($(1)_extract_dir)"
$(AT)rm -rf $($(1)_extract_dir)
$(AT)echo " Staging completed: $$@"
$(AT)touch $$@
$($(1)_postprocessed): | $($(1)_staged)
$(AT)echo Postprocessing $(1)...
$(AT)echo "=== Postprocessing $(1) v$($(1)_version) ==="
$(AT)echo " Postprocessing directory: $($(1)_staging_prefix_dir)"
$(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds)
$(AT)echo " Postprocessing completed: $$@"
$(AT)touch $$@
$($(1)_prebuilt_downloaded): | $($(1)_dependencies)
$(AT)echo "=== Attempting to download prebuilt $(1) v$($(1)_version) ==="
$(AT)echo " Build ID: $($(1)_build_id)"
$(AT)echo " Download URL: $($(1)_prebuilt_url)"
$(AT)mkdir -p $$(@D)
$(AT)mkdir -p $(dir $($(1)_cached))
$(AT)( \
echo " Downloading $(1) prebuilt files..." && \
$(build_DOWNLOAD) "$($(1)_cached).tmp" "$($(1)_prebuilt_url)" && \
$(build_DOWNLOAD) "$($(1)_cached_checksum).tmp" "$($(1)_prebuilt_checksum_url)" && \
$(build_DOWNLOAD) "$($(1)_cached_buildinfo).tmp" "$($(1)_prebuilt_buildinfo_url)" && \
echo " Verifying checksum..." && \
cd $(dir $($(1)_cached)) && \
sed 's/$(notdir $($(1)_cached))/$(notdir $($(1)_cached)).tmp/' "$($(1)_cached_checksum).tmp" > "$($(1)_cached_checksum).tmp.verify" && \
$(build_SHA256SUM) -c "$($(1)_cached_checksum).tmp.verify" && \
rm -f "$($(1)_cached_checksum).tmp.verify" && \
echo " Moving files to final location..." && \
mv "$($(1)_cached).tmp" "$($(1)_cached)" && \
mv "$($(1)_cached_checksum).tmp" "$($(1)_cached_checksum)" && \
mv "$($(1)_cached_buildinfo).tmp" "$($(1)_cached_buildinfo)" && \
echo " Prebuilt download completed: $$@" && \
touch $$@ \
) || ( \
echo " Download failed for $(1)" && \
rm -f "$($(1)_cached).tmp" "$($(1)_cached_checksum).tmp" "$($(1)_cached_buildinfo).tmp" && \
if [ "$(DEPENDS_UNTRUSTED_FAST_BUILDS)" = "forced" ]; then \
echo " Error: DEPENDS_UNTRUSTED_FAST_BUILDS=forced but prebuilt download failed" && \
exit 1; \
else \
echo " Falling back to building from source..." && \
exit 1; \
fi \
)
$($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed)
$(AT)echo Caching $(1)...
$(AT)echo "=== Caching $(1) v$($(1)_version) ==="
$(AT)echo " Build ID: $($(1)_build_id)"
$(AT)echo " Cache file: $$@"
$(AT)echo " Compression: $(COMPRESS_CMD)"
$(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion --use-compress-program='$(COMPRESS_CMD)' -cf $$($(1)_staging_dir)/$$(@F) -T -
$(AT)mkdir -p $$(@D)
$(AT)rm -rf $$(@D) && mkdir -p $$(@D)
$(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@)
$(AT)echo " Removing staging directory: $($(1)_staging_dir)"
$(AT)rm -rf $($(1)_staging_dir)
$(AT)echo " Caching completed: $$@"
$($(1)_cached_checksum): $($(1)_cached)
$(AT)echo "=== Generating checksum for $(1) v$($(1)_version) ==="
$(AT)echo " Checksum file: $$@"
$(AT)cd $$(@D); $(build_SHA256SUM) $$(<F) > $$(@)
$(AT)echo " Checksum completed: $$@"
$(AT)echo "=== Generating build info for $(1) v$($(1)_version) ==="
$(AT)echo " Build info file: $$($(1)_cached_buildinfo)"
$(AT)echo "# Build Info for $(1) v$($(1)_version)" > $$($(1)_cached_buildinfo)
$(AT)echo "# Generated on: $$(shell date)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Package: $(1)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Version: $($(1)_version)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Host: $(host)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Release Type: $(release_type)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Build ID (current): $($(1)_build_id)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Build ID (legacy): $($(1)_build_id_legacy)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Build ID String (current): $($(1)_build_id_long)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Build ID String (legacy): $($(1)_build_id_long_legacy)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Dependencies: $($(1)_dependencies)" >> $$($(1)_cached_buildinfo)
$(AT)echo "All Dependencies: $($(1)_all_dependencies)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Recipe Hash: $($(1)_recipe_hash)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Recipe Files: $($(1)_all_file_checksums)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Toolchain (current): $($($(1)_type)_id_string)" >> $$($(1)_cached_buildinfo)
$(AT)echo "Toolchain (legacy): $($($(1)_type)_id_string_legacy)" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Build Tools (current):" >> $$($(1)_cached_buildinfo)
$(AT)echo " CC: $$(shell basename $($($(1)_type)_CC) 2>/dev/null || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " CXX: $$(shell basename $($($(1)_type)_CXX) 2>/dev/null || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " AR: $$(shell basename $($($(1)_type)_AR) 2>/dev/null || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " RANLIB: $$(shell basename $($($(1)_type)_RANLIB) 2>/dev/null || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " STRIP: $$(shell basename $($($(1)_type)_STRIP) 2>/dev/null || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Build Tools (legacy versions):" >> $$($(1)_cached_buildinfo)
$(AT)echo " CC: $$(shell $($($(1)_type)_CC) --version 2>/dev/null | head -1 || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " CXX: $$(shell $($($(1)_type)_CXX) --version 2>/dev/null | head -1 || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " AR: $$(shell $($($(1)_type)_AR) --version 2>/dev/null | head -1 || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " RANLIB: $$(shell $($($(1)_type)_RANLIB) --version 2>/dev/null | head -1 || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo " STRIP: $$(shell $($($(1)_type)_STRIP) --version 2>/dev/null | head -1 || echo "unknown")" >> $$($(1)_cached_buildinfo)
$(AT)echo "" >> $$($(1)_cached_buildinfo)
$(AT)echo "Salt Values:" >> $$($(1)_cached_buildinfo)
$(AT)echo " BUILD_ID_SALT: $(BUILD_ID_SALT)" >> $$($(1)_cached_buildinfo)
$(AT)echo " HOST_ID_SALT: $(HOST_ID_SALT)" >> $$($(1)_cached_buildinfo)
$(AT)echo " Build info completed: $$($(1)_cached_buildinfo)"
$($(1)_cached_or_prebuilt):
$(AT)mkdir -p $$(@D)
$(AT)if [ "$(DEPENDS_UNTRUSTED_FAST_BUILDS)" = "yes" ]; then \
echo "=== Trying prebuilt download for $(1) v$($(1)_version) ===" && \
($(MAKE) -f $(BASEDIR)/Makefile $($(1)_prebuilt_downloaded) && touch $$@) || \
(echo " Prebuilt download failed, falling back to building from source..." && \
$(MAKE) -f $(BASEDIR)/Makefile $($(1)_cached_checksum) && touch $$@); \
elif [ "$(DEPENDS_UNTRUSTED_FAST_BUILDS)" = "forced" ]; then \
echo "=== Forced prebuilt download for $(1) v$($(1)_version) ===" && \
$(MAKE) -f $(BASEDIR)/Makefile $($(1)_prebuilt_downloaded) && touch $$@; \
else \
echo "=== Building from source for $(1) v$($(1)_version) ===" && \
$(MAKE) -f $(BASEDIR)/Makefile $($(1)_cached_checksum) && touch $$@; \
fi
.PHONY: $(1)
$(1): | $($(1)_cached_checksum)
.SECONDARY: $($(1)_cached) $($(1)_postprocessed) $($(1)_staged) $($(1)_built) $($(1)_configured) $($(1)_preprocessed) $($(1)_extracted) $($(1)_fetched)
$(1): | $($(1)_cached_or_prebuilt)
.SECONDARY: $($(1)_cached) $($(1)_postprocessed) $($(1)_staged) $($(1)_built) $($(1)_configured) $($(1)_preprocessed) $($(1)_extracted) $($(1)_fetched) $($(1)_cached_buildinfo) $($(1)_prebuilt_downloaded) $($(1)_cached_or_prebuilt)
endef
stages = fetched extracted preprocessed configured built staged postprocessed cached cached_checksum
stages = fetched extracted preprocessed configured built staged postprocessed cached cached_checksum prebuilt_downloaded
define ext_add_stages
$(foreach stage,$(stages),
+2 -2
View File
@@ -1,8 +1,8 @@
package=android_ndk
$(package)_version=26d
$(package)_version=28c
$(package)_download_path=https://dl.google.com/android/repository/
$(package)_file_name=android-ndk-r$($(package)_version)-linux.zip
$(package)_sha256_hash=eefeafe7ccf177de7cc57158da585e7af119bb7504a63604ad719e4b2a328b54
$(package)_sha256_hash=dfb20d396df28ca02a8c708314b814a4d961dc9074f9a161932746f815aa552f
$(package)_version_apiversion=21
+2 -2
View File
@@ -15,10 +15,10 @@ define $(package)_config_cmds
mkdir buildb &&\
cd builda &&\
sh ../source/runConfigureICU Linux &&\
make &&\
TARGET= make &&\
cd ../buildb &&\
sh ../source/runConfigureICU MinGW --enable-static=yes --disable-shared --disable-layout --disable-layoutex --disable-tests --disable-samples --prefix=$(host_prefix) --with-cross-build=`pwd`/../builda &&\
$(MAKE) -j$(NUM_CORES) $($(package)_build_opts)
TARGET= $(MAKE) -j$(NUM_CORES) $($(package)_build_opts)
endef
define $(package)_stage_cmds
+5 -4
View File
@@ -1,12 +1,12 @@
package=unbound
$(package)_version=1.19.1
$(package)_version=1.23.0
$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=bc1d576f3dd846a0739adc41ffaa702404c6767d2b6082deb9f2f97cbb24a3a9
$(package)_sha256_hash=959bd5f3875316d7b3f67ee237a56de5565f5b35fc9b5fc3cea6cfe735a03bb8
$(package)_dependencies=openssl expat
$(package)_patches=disable-glibc-reallocarray.patch
# ac_cv_type_pthread_spinlock_t -> disappeared in ndk r28
define $(package)_set_vars
$(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix)
$(package)_config_opts+=--with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no
@@ -14,6 +14,7 @@ define $(package)_set_vars
$(package)_config_opts_linux=--with-pic
$(package)_config_opts_w64=--enable-static-exe --sysconfdir=/etc --prefix=$(host_prefix) --target=$(host_prefix)
$(package)_config_opts_x86_64_darwin=ac_cv_func_SHA384_Init=yes
$(package)_config_opts_android=ac_cv_type_pthread_spinlock_t=no
$(package)_build_opts_mingw32=LDFLAGS="$($(package)_ldflags) -lpthread"
$(package)_cflags_mingw32+="-D_WIN32_WINNT=0x600"
endef
@@ -24,7 +25,7 @@ define $(package)_preprocess_cmds
endef
define $(package)_config_cmds
$($(package)_autoconf) ac_cv_func_getentropy=no
$($(package)_autoconf) $($(package)_config_opts) ac_cv_func_getentropy=no
endef
define $(package)_build_cmds
+3 -5
View File
@@ -69,6 +69,9 @@ set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # Find programs on host
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # Find libs in target
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Find includes in target
add_definitions(-DHIDAPI_DUMMY=ON)
set(HIDAPI_DUMMY ON)
# specify the cross compiler to be used. Darwin uses clang provided by the SDK.
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
if(ARCHITECTURE STREQUAL "aarch64")
@@ -97,15 +100,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
SET(BUILD_64 ON)
SET(BREW OFF)
SET(PORT OFF)
SET(CMAKE_OSX_SYSROOT "@prefix@/native/SDK/")
SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
SET(CMAKE_CXX_STANDARD 14)
SET(LLVM_ENABLE_PIC OFF)
SET(LLVM_ENABLE_PIE OFF)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
add_definitions(-DUSE_DEVICE_TREZOR=OFF)
add_definitions(-DHIDAPI_DUMMY=ON)
set(HIDAPI_DUMMY ON)
SET(ANDROID TRUE)
if(ARCHITECTURE STREQUAL "armv7a")
SET(CMAKE_ANDROID_ARCH_ABI "armeabi-v7a")
@@ -132,8 +132,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
SET(CMAKE_CXX_COMPILER @CXX@)
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(USE_DEVICE_TREZOR OFF)
add_definitions(-DHIDAPI_DUMMY=ON)
set(HIDAPI_DUMMY ON)
add_definitions(-DUSE_DEVICE_LEDGER=ON)
SET(CMAKE_C_COMPILER @CC@)
SET(CMAKE_CXX_COMPILER @CXX@)
+1 -1
View File
@@ -6,7 +6,7 @@ then
function sha256sum() { shasum -a 256 "$@" ; } && export -f sha256sum
fi
for coin in monero wownero zano;
for coin in monero wownero zano salvium;
do
submodule_hash=$(git ls-tree HEAD ${coin} | xargs | awk '{ print $3 }')
COIN=$(echo "$coin" | tr a-z A-Z)
+17
View File
@@ -0,0 +1,17 @@
name: SalviumC
description: monero_c salvium bindings
output: 'lib/src/generated_bindings_salvium.g.dart'
headers:
entry-points:
- '../../salvium_libwallet2_api_c/src/main/cpp/wallet2_api_c.h'
exclude-all-by-default: true
functions:
include:
- "SALVIUM_.+"
compiler-opts:
- '-I/usr/lib/llvm-14/lib/clang/14.0.6/include'
- '-I/usr/local/include'
- '-I/usr/include/x86_64-linux-gnu'
- '-I/usr/include'
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
// ignore_for_file: constant_identifier_names
const String wallet2_api_c_h_sha256 = "9e80c4b59a0509aa02fbf01e8df2881b89f82225d1765bfa7856cbdbaf7af116";
const String wallet2_api_c_cpp_sha256 = "d229507db508e574bd2badf4819a38dbead8c16a84311ad32c22c887a6003439-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe";
const String wallet2_api_c_exp_sha256 = "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d";
const String wallet2_api_c_h_sha256 = "3515e4c9e537ca3efa664f0b364a3aeb106ff64337f542a262ce104c00b31235";
const String wallet2_api_c_cpp_sha256 = "ca44a8d4a201ba6dc0a25c857e95d07bc8d514039b38cd5b3826100e8943cbcc-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe";
const String wallet2_api_c_exp_sha256 = "0561e14606106e6b0ec49fb2aefe743ff500f7c3de07557f7041e06aef9509ce";
@@ -0,0 +1,4 @@
// ignore_for_file: constant_identifier_names
const String wallet2_api_c_h_sha256 = "93ad4f6247f0b89c17218766c960e956047b0e8032c3db2b791842d576279330";
const String wallet2_api_c_cpp_sha256 = "2d52bbe50a6db8c1bd68ce4be288c28319f35f48c6d093a3d67d888c8e4b3230-45404ecc719b916c217938f9e82ad352a4068d12";
const String wallet2_api_c_exp_sha256 = "f7ab584f1271f4d533980f403597a1d9e50bced85c233ca2b17c77f4a94ed3bc";
@@ -4351,120 +4351,83 @@ class MoneroC {
late final _MONERO_Wallet_getBytesSent = _MONERO_Wallet_getBytesSentPtr
.asFunction<int Function(ffi.Pointer<ffi.Void>)>();
bool MONERO_Wallet_getStateIsConnected(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getStateIsConnected(
wallet_ptr,
);
bool MONERO_Wallet_getStateIsConnected() {
return _MONERO_Wallet_getStateIsConnected();
}
late final _MONERO_Wallet_getStateIsConnectedPtr =
_lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Void>)>>(
_lookup<ffi.NativeFunction<ffi.Bool Function()>>(
'MONERO_Wallet_getStateIsConnected');
late final _MONERO_Wallet_getStateIsConnected =
_MONERO_Wallet_getStateIsConnectedPtr.asFunction<
bool Function(ffi.Pointer<ffi.Void>)>();
_MONERO_Wallet_getStateIsConnectedPtr.asFunction<bool Function()>();
ffi.Pointer<ffi.UnsignedChar> MONERO_Wallet_getSendToDevice(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getSendToDevice(
wallet_ptr,
);
ffi.Pointer<ffi.UnsignedChar> MONERO_Wallet_getSendToDevice() {
return _MONERO_Wallet_getSendToDevice();
}
late final _MONERO_Wallet_getSendToDevicePtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.UnsignedChar> Function(
ffi.Pointer<ffi.Void>)>>('MONERO_Wallet_getSendToDevice');
late final _MONERO_Wallet_getSendToDevice =
_MONERO_Wallet_getSendToDevicePtr.asFunction<
ffi.Pointer<ffi.UnsignedChar> Function(ffi.Pointer<ffi.Void>)>();
late final _MONERO_Wallet_getSendToDevicePtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.UnsignedChar> Function()>>(
'MONERO_Wallet_getSendToDevice');
late final _MONERO_Wallet_getSendToDevice = _MONERO_Wallet_getSendToDevicePtr
.asFunction<ffi.Pointer<ffi.UnsignedChar> Function()>();
int MONERO_Wallet_getSendToDeviceLength(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getSendToDeviceLength(
wallet_ptr,
);
int MONERO_Wallet_getSendToDeviceLength() {
return _MONERO_Wallet_getSendToDeviceLength();
}
late final _MONERO_Wallet_getSendToDeviceLengthPtr =
_lookup<ffi.NativeFunction<ffi.Size Function(ffi.Pointer<ffi.Void>)>>(
_lookup<ffi.NativeFunction<ffi.Size Function()>>(
'MONERO_Wallet_getSendToDeviceLength');
late final _MONERO_Wallet_getSendToDeviceLength =
_MONERO_Wallet_getSendToDeviceLengthPtr.asFunction<
int Function(ffi.Pointer<ffi.Void>)>();
_MONERO_Wallet_getSendToDeviceLengthPtr.asFunction<int Function()>();
ffi.Pointer<ffi.UnsignedChar> MONERO_Wallet_getReceivedFromDevice(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getReceivedFromDevice(
wallet_ptr,
);
ffi.Pointer<ffi.UnsignedChar> MONERO_Wallet_getReceivedFromDevice() {
return _MONERO_Wallet_getReceivedFromDevice();
}
late final _MONERO_Wallet_getReceivedFromDevicePtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.UnsignedChar> Function(
ffi.Pointer<ffi.Void>)>>('MONERO_Wallet_getReceivedFromDevice');
late final _MONERO_Wallet_getReceivedFromDevicePtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.UnsignedChar> Function()>>(
'MONERO_Wallet_getReceivedFromDevice');
late final _MONERO_Wallet_getReceivedFromDevice =
_MONERO_Wallet_getReceivedFromDevicePtr.asFunction<
ffi.Pointer<ffi.UnsignedChar> Function(ffi.Pointer<ffi.Void>)>();
ffi.Pointer<ffi.UnsignedChar> Function()>();
int MONERO_Wallet_getReceivedFromDeviceLength(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getReceivedFromDeviceLength(
wallet_ptr,
);
int MONERO_Wallet_getReceivedFromDeviceLength() {
return _MONERO_Wallet_getReceivedFromDeviceLength();
}
late final _MONERO_Wallet_getReceivedFromDeviceLengthPtr =
_lookup<ffi.NativeFunction<ffi.Size Function(ffi.Pointer<ffi.Void>)>>(
_lookup<ffi.NativeFunction<ffi.Size Function()>>(
'MONERO_Wallet_getReceivedFromDeviceLength');
late final _MONERO_Wallet_getReceivedFromDeviceLength =
_MONERO_Wallet_getReceivedFromDeviceLengthPtr.asFunction<
int Function(ffi.Pointer<ffi.Void>)>();
int Function()>();
bool MONERO_Wallet_getWaitsForDeviceSend(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getWaitsForDeviceSend(
wallet_ptr,
);
bool MONERO_Wallet_getWaitsForDeviceSend() {
return _MONERO_Wallet_getWaitsForDeviceSend();
}
late final _MONERO_Wallet_getWaitsForDeviceSendPtr =
_lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Void>)>>(
_lookup<ffi.NativeFunction<ffi.Bool Function()>>(
'MONERO_Wallet_getWaitsForDeviceSend');
late final _MONERO_Wallet_getWaitsForDeviceSend =
_MONERO_Wallet_getWaitsForDeviceSendPtr.asFunction<
bool Function(ffi.Pointer<ffi.Void>)>();
_MONERO_Wallet_getWaitsForDeviceSendPtr.asFunction<bool Function()>();
bool MONERO_Wallet_getWaitsForDeviceReceive(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_getWaitsForDeviceReceive(
wallet_ptr,
);
bool MONERO_Wallet_getWaitsForDeviceReceive() {
return _MONERO_Wallet_getWaitsForDeviceReceive();
}
late final _MONERO_Wallet_getWaitsForDeviceReceivePtr =
_lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Void>)>>(
_lookup<ffi.NativeFunction<ffi.Bool Function()>>(
'MONERO_Wallet_getWaitsForDeviceReceive');
late final _MONERO_Wallet_getWaitsForDeviceReceive =
_MONERO_Wallet_getWaitsForDeviceReceivePtr.asFunction<
bool Function(ffi.Pointer<ffi.Void>)>();
_MONERO_Wallet_getWaitsForDeviceReceivePtr.asFunction<bool Function()>();
void MONERO_Wallet_setDeviceReceivedData(
ffi.Pointer<ffi.Void> wallet_ptr,
ffi.Pointer<ffi.UnsignedChar> data,
int len,
) {
return _MONERO_Wallet_setDeviceReceivedData(
wallet_ptr,
data,
len,
);
@@ -4472,22 +4435,17 @@ class MoneroC {
late final _MONERO_Wallet_setDeviceReceivedDataPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.UnsignedChar>,
ffi.Void Function(ffi.Pointer<ffi.UnsignedChar>,
ffi.Size)>>('MONERO_Wallet_setDeviceReceivedData');
late final _MONERO_Wallet_setDeviceReceivedData =
_MONERO_Wallet_setDeviceReceivedDataPtr.asFunction<
void Function(
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.UnsignedChar>, int)>();
void Function(ffi.Pointer<ffi.UnsignedChar>, int)>();
void MONERO_Wallet_setDeviceSendData(
ffi.Pointer<ffi.Void> wallet_ptr,
ffi.Pointer<ffi.UnsignedChar> data,
int len,
) {
return _MONERO_Wallet_setDeviceSendData(
wallet_ptr,
data,
len,
);
@@ -4495,14 +4453,56 @@ class MoneroC {
late final _MONERO_Wallet_setDeviceSendDataPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.UnsignedChar>,
ffi.Void Function(ffi.Pointer<ffi.UnsignedChar>,
ffi.Size)>>('MONERO_Wallet_setDeviceSendData');
late final _MONERO_Wallet_setDeviceSendData =
_MONERO_Wallet_setDeviceSendDataPtr.asFunction<
void Function(ffi.Pointer<ffi.UnsignedChar>, int)>();
void MONERO_Wallet_setLedgerCallback(
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<ffi.UnsignedChar> command,
ffi.UnsignedInt cmd_len)>>
sendToLedgerDevice,
) {
return _MONERO_Wallet_setLedgerCallback(
sendToLedgerDevice,
);
}
late final _MONERO_Wallet_setLedgerCallbackPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<ffi.UnsignedChar> command,
ffi.UnsignedInt cmd_len)>>)>>(
'MONERO_Wallet_setLedgerCallback');
late final _MONERO_Wallet_setLedgerCallback =
_MONERO_Wallet_setLedgerCallbackPtr.asFunction<
void Function(
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.UnsignedChar>, int)>();
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<ffi.UnsignedChar> command,
ffi.UnsignedInt cmd_len)>>)>();
ffi.Pointer<ffi.Char> MONERO_Wallet_serializeCacheToJson(
ffi.Pointer<ffi.Void> wallet_ptr,
) {
return _MONERO_Wallet_serializeCacheToJson(
wallet_ptr,
);
}
late final _MONERO_Wallet_serializeCacheToJsonPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Void>)>>('MONERO_Wallet_serializeCacheToJson');
late final _MONERO_Wallet_serializeCacheToJson =
_MONERO_Wallet_serializeCacheToJsonPtr.asFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>)>();
ffi.Pointer<ffi.Void> MONERO_WalletManager_createWallet(
ffi.Pointer<ffi.Void> wm_ptr,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+406
View File
@@ -0,0 +1,406 @@
// ignore_for_file: non_constant_identifier_names
import 'dart:ffi';
import 'dart:io';
abstract class Wallet2 {
Wallet2WalletManagerFactory walletManagerFactory();
static String get libPath {
if (Platform.isWindows) return 'unknown_libwallet2_api_c.dll';
if (Platform.isMacOS) return 'unknown_libwallet2_api_c.dylib';
if (Platform.isIOS) return 'UnknownWallet.framework/UnknownWallet';
if (Platform.isAndroid) return 'libunknown_libwallet2_api_c.so';
return 'unknown_libwallet2_api_c.so';
}
static set libPath(String path) {
throw Exception('libPath is read-only, as isolates cannot be made aware of changes to this variable');
}
int ffiAddress();
}
abstract class Wallet2AddressBook {
int ffiAddress();
int getAll_size();
Wallet2AddressBookRow getAll_byIndex(int index);
bool addRow({required String dstAddr, required String paymentId, required String description, });
bool deleteRow({required int rowId});
bool setDescription({required int rowId, required String description, });
void refresh();
int errorCode();
int lookupPaymentID({required String paymentId});
}
abstract class Wallet2AddressBookRow {
int ffiAddress();
String extra();
String getAddress();
String getDescription();
String getPaymentId();
int getRowId();
}
abstract class Wallet2Coins {
int ffiAddress();
int count();
Wallet2CoinsInfo coin(int index);
int getAll_size();
Wallet2CoinsInfo getAll_byIndex(int index);
void refresh();
void setFrozenByPublicKey({required String publicKey});
void setFrozen({required int index});
void thaw({required int index});
void thawByPublicKey({required String publicKey});
bool isTransferUnlocked({required int unlockTime, required int blockHeight});
}
abstract class Wallet2CoinsInfo {
int ffiAddress();
int blockHeight();
String hash();
int internalOutputIndex();
int globalOutputIndex();
bool spent();
bool frozen();
int spentHeight();
int amount();
bool rct();
bool keyImageKnown();
int pkIndex();
int subaddrIndex();
int subaddrAccount();
String address();
String addressLabel();
String keyImage();
int unlockTime();
bool unlocked();
String pubKey();
bool coinbase();
String description();
}
abstract class Wallet2DeviceProgress {
int ffiAddress();
bool progress();
bool indeterminate();
}
abstract class Wallet2WalletListener {
int ffiAddress();
void resetNeedToRefresh();
bool isNeedToRefresh();
bool isNewTransactionExist();
void resetIsNewTransactionExist();
int height();
}
abstract class Wallet2Checksum {
int ffiAddress();
String checksum_wallet2_api_c_h();
String checksum_wallet2_api_c_cpp();
String checksum_wallet2_api_c_exp();
}
abstract class Wallet2Free {
int ffiAddress();
void free(Pointer<Void> wlptr);
}
abstract class Wallet2MultisigState {
int ffiAddress();
bool isMultisig(Pointer<Void> ptr);
bool isReady(Pointer<Void> ptr);
int threshold(Pointer<Void> ptr);
int total(Pointer<Void> ptr);
}
abstract class Wallet2PendingTransaction {
int ffiAddress();
int status();
String errorString();
bool commit({required String filename, required bool overwrite});
String commitUR(int max_fragment_length);
int amount();
int dust();
int fee();
String txid(String separator);
int txCount();
String subaddrAccount(String separator);
String subaddrIndices(String separator);
String multisigSignData();
void signMultisigTx();
String signersKeys(String separator);
String hex(String separator);
}
abstract class Wallet2Subaddress {
int ffiAddress();
int getAll_size();
Wallet2SubaddressRow getAll_byIndex(int index);
void addRow({required int accountIndex, required String label});
void setLabel({required int accountIndex, required int addressIndex, required String label});
void refresh({required int accountIndex, required String label});
}
abstract class Wallet2SubaddressAccount {
int ffiAddress();
int getAll_size();
Wallet2SubaddressAccountRow getAll_byIndex(int index);
void addRow({required String label});
void setLabel({required int accountIndex, required String label});
void refresh();
}
abstract class Wallet2SubaddressAccountRow {
int ffiAddress();
String extra();
String getAddress();
String getLabel();
String getBalance();
String getUnlockedBalance();
int getRowId();
}
abstract class Wallet2SubaddressRow {
int ffiAddress();
String extra();
String getAddress();
String getLabel();
int getRowId();
}
abstract class Wallet2TransactionHistory {
int ffiAddress();
int count();
Wallet2TransactionInfo transaction(int index);
Wallet2TransactionInfo transactionById(String txid);
void refresh();
void setTxNote({required String txid, required String note});
}
abstract class Wallet2TransactionInfo {
int ffiAddress();
int direction();
bool isPending();
bool isFailed();
bool isCoinbase();
int amount();
int fee();
int blockHeight();
String description();
String subaddrIndex();
int subaddrAccount();
String label();
int confirmations();
int unlockTime();
String hash();
int timestamp();
String paymentId();
int transfers_count();
int transfers_amount(int index);
String transfers_address(int index);
}
abstract class Wallet2UnsignedTransaction {
int ffiAddress();
int status();
String errorString();
String amount();
String fee();
String mixin();
String confirmationMessage();
String paymentId();
String recipientAddress();
int minMixinCount();
int txCount();
bool sign(String signedFileName);
String signUR(int max_fragment_length);
}
abstract class Wallet2Wallet {
int ffiAddress();
String seed({required String seedOffset});
String getSeedLanguage();
void setSeedLanguage({required String language});
int status();
String errorString();
bool setPassword({required String password});
String getPassword();
bool setDevicePin({required String passphrase});
String address({int accountIndex = 0, int addressIndex = 0});
String path();
int nettype();
int useForkRules({required int version, required int earlyBlocks, });
String integratedAddress({required String paymentId});
String secretViewKey();
String publicViewKey();
String secretSpendKey();
String publicSpendKey();
String publicMultisigSignerKey();
void stop();
bool store({String path = ""});
String filename();
String keysFilename();
bool init({ required String daemonAddress, int upperTransacationSizeLimit = 0, String daemonUsername = "", String daemonPassword = "", bool useSsl = false, bool lightWallet = false, String proxyAddress = "", });
bool createWatchOnly({ required String path, required String password, required String language, });
void setRefreshFromBlockHeight({required int refresh_from_block_height});
int getRefreshFromBlockHeight();
void setRecoveringFromSeed({required bool recoveringFromSeed});
void setRecoveringFromDevice({required bool recoveringFromDevice});
void setSubaddressLookahead({required int major, required int minor});
bool connectToDaemon();
int connected();
void setTrustedDaemon({required bool arg});
bool trustedDaemon();
void setProxy({required String address});
int balance({required int accountIndex});
int unlockedBalance({required int accountIndex});
int viewOnlyBalance({required int accountIndex});
bool watchOnly();
int blockChainHeight();
int approximateBlockChainHeight();
int estimateBlockChainHeight();
int daemonBlockChainHeight();
bool synchronized();
String displayAmount(int amount);
int amountFromString(String amount);
int amountFromDouble(double amount);
String genPaymentId();
bool paymentIdValid(String paymentId);
bool addressValid(String address, int networkType);
bool keyValid({required String secret_key_string, required String address_string, required bool isViewKey, required int nettype});
String keyValid_error({required String secret_key_string, required String address_string, required bool isViewKey, required int nettype});
String paymentIdFromAddress({required String strarg, required int nettype});
int maximumAllowedAmount();
void init3({ required String argv0, required String defaultLogBaseName, required String logPath, required bool console, });
String getPolyseed({required String passphrase});
String createPolyseed({ String language = "English", });
void startRefresh();
void pauseRefresh();
bool refresh();
void refreshAsync();
bool rescanBlockchain();
void rescanBlockchainAsync();
void setAutoRefreshInterval({required int millis});
int autoRefreshInterval();
void addSubaddress({required int accountIndex, String label = ""});
void addSubaddressAccount({String label = ""});
int numSubaddressAccounts();
int numSubaddresses({required int accountIndex});
String getSubaddressLabel({required int accountIndex, required int addressIndex});
void setSubaddressLabel({required int accountIndex, required int addressIndex, required String label});
Wallet2MultisigState multisig();
String getMultisigInfo();
String makeMultisig({ required List<String> info, required int threshold, });
String exchangeMultisigKeys({ required List<String> info, required bool force_update_use_with_caution, });
List<String> exportMultisigImages({ required List<String> info, });
int importMultisigImages({ required List<String> info, });
int hasMultisigPartialKeyImages();
Wallet2PendingTransaction restoreMultisigTransaction({ required String signData, });
Wallet2PendingTransaction createTransactionMultDest({ required List<String> dstAddr, String paymentId = "", required bool isSweepAll, required List<int> amounts, required int mixinCount, required int pendingTransactionPriority, required int subaddr_account, List<String> preferredInputs = const [], });
Wallet2PendingTransaction createTransaction({required String dst_addr, required String payment_id, required int amount, required int mixin_count, required int pendingTransactionPriority, required int subaddr_account, List<String> preferredInputs = const [],});
Wallet2UnsignedTransaction loadUnsignedTx({required String unsigned_filename});
Wallet2UnsignedTransaction loadUnsignedTxUR({required String input});
bool submitTransaction(String filename);
bool submitTransactionUR(String input);
bool hasUnknownKeyImages();
bool exportKeyImages(String filename, {required bool all});
String exportKeyImagesUR({ int max_fragment_length = 130, bool all = false, });
bool importKeyImages(String filename);
bool importKeyImagesUR(String input);
bool exportOutputs(String filename, {required bool all});
String exportOutputsUR({ int max_fragment_length = 130, bool all = false, });
bool importOutputs(String filename);
bool importOutputsUR(String input);
bool setupBackgroundSync({ required int backgroundSyncType, required String walletPassword, required String backgroundCachePassword, });
int getBackgroundSyncType();
bool startBackgroundSync();
bool stopBackgroundSync(String walletPassword);
bool isBackgroundSyncing();
bool isBackgroundWallet();
Wallet2TransactionHistory history();
Wallet2AddressBook addressBook();
Wallet2Coins coins();
Wallet2Subaddress subaddress();
Wallet2SubaddressAccount subaddressAccount();
int defaultMixin();
void setDefaultMixin(int arg);
bool setCacheAttribute({required String key, required String value});
String getCacheAttribute({required String key});
bool setUserNote({required String txid, required String note});
String getUserNote({required String txid});
String getTxKey({required String txid});
String signMessage({ required String message, required String address, });
bool verifySignedMessage({ required String message, required String address, required String signature, });
bool rescanSpent();
void setOffline({required bool offline});
bool isOffline();
void segregatePreForkOutputs({required bool segregate});
void segregationHeight({required int height});
void keyReuseMitigation2({required bool mitigation});
bool lockKeysFile();
bool unlockKeysFile();
bool isKeysFileLocked();
int getDeviceType();
int coldKeyImageSync({required int spent, required int unspent});
String deviceShowAddress({required int accountIndex, required int addressIndex});
bool reconnectDevice();
int getBytesReceived();
int getBytesSent();
Wallet2WalletListener getWalletListener();
}
abstract class Wallet2WalletManager {
int ffiAddress();
Wallet2Wallet createWallet({ required String path, required String password, String language = "English", int networkType = 0, });
Wallet2Wallet openWallet({ required String path, required String password, int networkType = 0, });
void closeWallet(Wallet2Wallet wallet, bool store);
Wallet2Wallet recoveryWallet({ required String path, required String password, required String mnemonic, int networkType = 0, required int restoreHeight, int kdfRounds = 0, required String seedOffset, });
Wallet2Wallet createWalletFromKeys({ required String path, required String password, String language = "English", int nettype = 1, required int restoreHeight, required String addressString, required String viewKeyString, required String spendKeyString, int kdf_rounds = 1, });
Wallet2Wallet createDeterministicWalletFromSpendKey({ required String path, required String password, String language = "English", int networkType = 0, required String spendKeyString, required bool newWallet, required int restoreHeight, int kdfRounds = 1, });
Wallet2Wallet createWalletFromDevice({ required String path, required String password, int networkType = 0, required String deviceName, int restoreHeight = 0, String subaddressLookahead = "", int kdfRounds = 1, });
Wallet2Wallet createWalletFromPolyseed({ required String path, required String password, int networkType = 0, required String mnemonic, required String seedOffset, required bool newWallet, required int restoreHeight, required int kdfRounds, });
bool walletExists(String path);
bool verifyWalletPassword({ required String keysFileName, required String password, required bool noSpendKey, required int kdfRounds, });
int queryWalletDevice({ required String keysFileName, required String password, required int kdfRounds, });
List<String> findWallets({required String path});
String errorString();
void setDaemonAddress(String address);
Future<int> blockchainHeight();
Future<int> blockchainTargetHeight();
int networkDifficulty();
double miningHashRate();
Future<int> blockTarget();
bool isMining();
bool startMining({ required String address, required int threads, required bool backgroundMining, required bool ignoreBattery, });
bool stopMining(String address);
String resolveOpenAlias({ required String address, required bool dnssecValid, });
bool setProxy(String address);
}
abstract class Wallet2WalletManagerFactory {
int ffiAddress();
void setLogLevel(int level);
void setLogCategories(String categories);
Wallet2WalletManager getWalletManager();
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -12,4 +12,4 @@ dependencies:
dev_dependencies:
lints: ^5.0.0
test: ^1.24.0
ffigen: ^14.0.0
ffigen: ^18.0.0
+1
View File
@@ -7,3 +7,4 @@ cd "$(realpath $(dirname $0))"
dart run ffigen --config ffigen_wownero.yaml
dart run ffigen --config ffigen_monero.yaml
dart run ffigen --config ffigen_zano.yaml
dart run ffigen --config ffigen_salvium.yaml
+3 -3
View File
@@ -1,5 +1,5 @@
export const moneroChecksum = {
wallet2_api_c_h_sha256: "9e80c4b59a0509aa02fbf01e8df2881b89f82225d1765bfa7856cbdbaf7af116",
wallet2_api_c_cpp_sha256: "d229507db508e574bd2badf4819a38dbead8c16a84311ad32c22c887a6003439-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe",
wallet2_api_c_exp_sha256: "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d",
wallet2_api_c_h_sha256: "3515e4c9e537ca3efa664f0b364a3aeb106ff64337f542a262ce104c00b31235",
wallet2_api_c_cpp_sha256: "ca44a8d4a201ba6dc0a25c857e95d07bc8d514039b38cd5b3826100e8943cbcc-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe",
wallet2_api_c_exp_sha256: "0561e14606106e6b0ec49fb2aefe743ff500f7c3de07557f7041e06aef9509ce",
}
+5
View File
@@ -0,0 +1,5 @@
export const salviumChecksum = {
wallet2_api_c_h_sha256: "93ad4f6247f0b89c17218766c960e956047b0e8032c3db2b791842d576279330",
wallet2_api_c_cpp_sha256: "2d52bbe50a6db8c1bd68ce4be288c28319f35f48c6d093a3d67d888c8e4b3230-45404ecc719b916c217938f9e82ad352a4068d12",
wallet2_api_c_exp_sha256: "f7ab584f1271f4d533980f403597a1d9e50bced85c233ca2b17c77f4a94ed3bc",
}
+8
View File
@@ -164,6 +164,14 @@ endif()
# ${EXTRA_LIBS_WOWNEROSEED}
# ${EXTRA_LIBS_ANDROID}")
if (${HOST_ABI} STREQUAL "x86_64-w64-mingw32" OR
${HOST_ABI} STREQUAL "i686-w64-mingw32")
target_link_options(wallet2_api_c PRIVATE "-Wl,--section-alignment,16384")
elseif(${HOST_ABI} MATCHES "-linux-")
target_link_options(wallet2_api_c PRIVATE "-Wl,-z,max-page-size=16384")
endif()
target_link_libraries( wallet2_api_c
${WALLET_TARGETS}
@@ -122,6 +122,8 @@ _MONERO_MultisigState_total
_MONERO_DeviceProgress_progress
_MONERO_DeviceProgress_indeterminate
_MONERO_Wallet_seed
_MONERO_Wallet_setLedgerCallback
_MONERO_Wallet_serializeCacheToJson
_MONERO_Wallet_getSeedLanguage
_MONERO_Wallet_setSeedLanguage
_MONERO_Wallet_status
@@ -1,6 +1,6 @@
#ifndef MONEROC_CHECKSUMS
#define MONEROC_CHECKSUMS
const char * MONERO_wallet2_api_c_h_sha256 = "9e80c4b59a0509aa02fbf01e8df2881b89f82225d1765bfa7856cbdbaf7af116";
const char * MONERO_wallet2_api_c_cpp_sha256 = "d229507db508e574bd2badf4819a38dbead8c16a84311ad32c22c887a6003439-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe";
const char * MONERO_wallet2_api_c_exp_sha256 = "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d";
const char * MONERO_wallet2_api_c_h_sha256 = "3515e4c9e537ca3efa664f0b364a3aeb106ff64337f542a262ce104c00b31235";
const char * MONERO_wallet2_api_c_cpp_sha256 = "ca44a8d4a201ba6dc0a25c857e95d07bc8d514039b38cd5b3826100e8943cbcc-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe";
const char * MONERO_wallet2_api_c_exp_sha256 = "0561e14606106e6b0ec49fb2aefe743ff500f7c3de07557f7041e06aef9509ce";
#endif
@@ -2102,62 +2102,71 @@ uint64_t MONERO_Wallet_getBytesSent(void* wallet_ptr) {
DEBUG_END()
}
bool MONERO_Wallet_getStateIsConnected(void* wallet_ptr) {
bool MONERO_Wallet_getStateIsConnected() {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getStateIsConnected();
return Monero::Wallet::getStateIsConnected();
DEBUG_END()
}
unsigned char* MONERO_Wallet_getSendToDevice(void* wallet_ptr) {
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getSendToDevice();
}
size_t MONERO_Wallet_getSendToDeviceLength(void* wallet_ptr) {
unsigned char* MONERO_Wallet_getSendToDevice() {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getSendToDeviceLength();
return Monero::Wallet::getSendToDevice();
DEBUG_END()
}
unsigned char* MONERO_Wallet_getReceivedFromDevice(void* wallet_ptr) {
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getReceivedFromDevice();
}
size_t MONERO_Wallet_getReceivedFromDeviceLength(void* wallet_ptr) {
size_t MONERO_Wallet_getSendToDeviceLength() {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getReceivedFromDeviceLength();
return Monero::Wallet::getSendToDeviceLength();
DEBUG_END()
}
bool MONERO_Wallet_getWaitsForDeviceSend(void* wallet_ptr) {
unsigned char* MONERO_Wallet_getReceivedFromDevice() {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getWaitsForDeviceSend();
return Monero::Wallet::getReceivedFromDevice();
DEBUG_END()
}
bool MONERO_Wallet_getWaitsForDeviceReceive(void* wallet_ptr) {
size_t MONERO_Wallet_getReceivedFromDeviceLength() {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->getWaitsForDeviceReceive();
return Monero::Wallet::getReceivedFromDeviceLength();
DEBUG_END()
}
void MONERO_Wallet_setDeviceReceivedData(void* wallet_ptr, unsigned char* data, size_t len) {
bool MONERO_Wallet_getWaitsForDeviceSend() {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->setDeviceReceivedData(data, len);
return Monero::Wallet::getWaitsForDeviceSend();
DEBUG_END()
}
void MONERO_Wallet_setDeviceSendData(void* wallet_ptr, unsigned char* data, size_t len) {
bool MONERO_Wallet_getWaitsForDeviceReceive() {
DEBUG_START()
return Monero::Wallet::getWaitsForDeviceReceive();
DEBUG_END()
}
void MONERO_Wallet_setDeviceReceivedData(unsigned char* data, size_t len) {
DEBUG_START()
Monero::Wallet::setDeviceReceivedData(data, len);
DEBUG_END()
}
void MONERO_Wallet_setDeviceSendData(unsigned char* data, size_t len) {
DEBUG_START()
Monero::Wallet::setDeviceSendData(data, len);
DEBUG_END()
}
void MONERO_Wallet_setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)) {
DEBUG_START()
Monero::Wallet::setLedgerCallback(sendToLedgerDevice);
DEBUG_END()
}
const char* MONERO_Wallet_serializeCacheToJson(void* wallet_ptr) {
DEBUG_START()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->setDeviceSendData(data, len);
std::string result = wallet->serializeCacheToJson();
return strdup(result.c_str());
DEBUG_END()
}
@@ -832,15 +832,17 @@ extern ADDAPI uint64_t MONERO_Wallet_getBytesReceived(void* wallet_ptr);
// virtual uint64_t getBytesSent() = 0;
extern ADDAPI uint64_t MONERO_Wallet_getBytesSent(void* wallet_ptr);
// HIDAPI_DUMMY
extern ADDAPI bool MONERO_Wallet_getStateIsConnected(void* wallet_ptr);
extern ADDAPI unsigned char* MONERO_Wallet_getSendToDevice(void* wallet_ptr);
extern ADDAPI size_t MONERO_Wallet_getSendToDeviceLength(void* wallet_ptr);
extern ADDAPI unsigned char* MONERO_Wallet_getReceivedFromDevice(void* wallet_ptr);
extern ADDAPI size_t MONERO_Wallet_getReceivedFromDeviceLength(void* wallet_ptr);
extern ADDAPI bool MONERO_Wallet_getWaitsForDeviceSend(void* wallet_ptr);
extern ADDAPI bool MONERO_Wallet_getWaitsForDeviceReceive(void* wallet_ptr);
extern ADDAPI void MONERO_Wallet_setDeviceReceivedData(void* wallet_ptr, unsigned char* data, size_t len);
extern ADDAPI void MONERO_Wallet_setDeviceSendData(void* wallet_ptr, unsigned char* data, size_t len);
extern ADDAPI bool MONERO_Wallet_getStateIsConnected();
extern ADDAPI unsigned char* MONERO_Wallet_getSendToDevice();
extern ADDAPI size_t MONERO_Wallet_getSendToDeviceLength();
extern ADDAPI unsigned char* MONERO_Wallet_getReceivedFromDevice();
extern ADDAPI size_t MONERO_Wallet_getReceivedFromDeviceLength();
extern ADDAPI bool MONERO_Wallet_getWaitsForDeviceSend();
extern ADDAPI bool MONERO_Wallet_getWaitsForDeviceReceive();
extern ADDAPI void MONERO_Wallet_setDeviceReceivedData(unsigned char* data, size_t len);
extern ADDAPI void MONERO_Wallet_setDeviceSendData(unsigned char* data, size_t len);
extern ADDAPI void MONERO_Wallet_setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
extern ADDAPI const char* MONERO_Wallet_serializeCacheToJson(void* wallet_ptr);
// };
// struct WalletManager
@@ -1,7 +1,7 @@
From 6e284a2ef552f1f47e8ca9edcf8651312c9e37dd Mon Sep 17 00:00:00 2001
From 36259ba9f88bc135b243329400bec9290abb04c6 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 2 Apr 2024 16:51:56 +0200
Subject: [PATCH 01/14] fix missing ___clear_cache when targetting iOS
Subject: [PATCH 01/17] fix missing ___clear_cache when targetting iOS
---
.gitmodules | 3 ++-
@@ -30,5 +30,5 @@ index 102f8acf9..ce72c9bb9 160000
-Subproject commit 102f8acf90a7649ada410de5499a7ec62e49e1da
+Subproject commit ce72c9bb9cb799e0d9171094b9abb009e04c5bfc
--
2.48.1
2.49.0
+3 -3
View File
@@ -1,7 +1,7 @@
From b4f4b38af1ab974872862fc20735e41941b955e9 Mon Sep 17 00:00:00 2001
From 459ac9f7a64cc527528a41dc45ed4cefe83091cb Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Sat, 11 May 2024 16:25:10 +0200
Subject: [PATCH 02/14] store crash fix
Subject: [PATCH 02/17] store crash fix
Monero wallet crashes (sometimes) when it is syncing,
while the proper solution (that can be seen in feather)
@@ -204,5 +204,5 @@ index 2f4ad52f1..daad1e940 100644
i_wallet2_callback* m_callback;
hw::device::device_type m_key_device_type;
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From a74f616e3c1671a883182b0db1c6fc11a1242c01 Mon Sep 17 00:00:00 2001
From c51ee39835aaac64da39b1c10bc068182f6e28cb Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 2 Sep 2024 16:40:31 +0200
Subject: [PATCH 03/14] uint64_t missing definition fix
Subject: [PATCH 03/17] uint64_t missing definition fix
---
contrib/epee/include/net/http_base.h | 2 +-
@@ -21,5 +21,5 @@ index 4af4da790..ae4c0d05e 100644
#include <string>
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From f9b222f1611d7cfbaf0ac52cd6194724c7554def Mon Sep 17 00:00:00 2001
From 0c1524dd9a4f6b4450b277623ffa620f69931102 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 24 Jun 2024 10:49:12 +0200
Subject: [PATCH 04/14] use proper error handling in get_seed
Subject: [PATCH 04/17] use proper error handling in get_seed
---
src/wallet/api/wallet.cpp | 17 ++++++++++++-----
@@ -67,5 +67,5 @@ index c9c2dbc82..b827b826f 100644
return true;
--
2.48.1
2.49.0
+3 -3
View File
@@ -1,7 +1,7 @@
From ff70c74c8b331758ace1f14df0ca107731dda49d Mon Sep 17 00:00:00 2001
From 467ee9154b5c1b903559bf1dbe848cbabc62ba7d Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 10:09:50 +0100
Subject: [PATCH 05/14] UR functions
Subject: [PATCH 05/17] UR functions
This commit adds UR functions for UR tasks,
I believe that the right place to get
@@ -1006,5 +1006,5 @@ index daad1e940..a752f15b9 100644
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
--
2.48.1
2.49.0
@@ -1,43 +1,59 @@
From 904fe95204ba02d1a8c81fc46c1423ba1685c94f Mon Sep 17 00:00:00 2001
From 11ddba5ab1470fb46a87ea9b702bf11f88763ecc Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Wed, 26 Jun 2024 15:04:38 +0200
Subject: [PATCH 06/14] add dummy device for ledger
Date: Thu, 8 May 2025 13:14:23 +0200
Subject: [PATCH 06/17] add dummy device for ledger
---
CMakeLists.txt | 6 +-
external/randomx | 2 +-
src/device/CMakeLists.txt | 6 +-
src/device/device.cpp | 10 ++-
src/device/device.cpp | 10 +-
src/device/device.hpp | 12 +--
src/device/device_io_dummy.cpp | 133 ++++++++++++++++++++++++++++++
src/device/device_io_dummy.hpp | 74 +++++++++++++++++
src/device/device_io_dummy.cpp | 161 ++++++++++++++++++++++++++++++
src/device/device_io_dummy.hpp | 82 +++++++++++++++
src/device/device_ledger.cpp | 6 +-
src/device/device_ledger.hpp | 7 +-
src/wallet/api/wallet.cpp | 94 +++++++++++++++++++++
src/wallet/api/wallet.h | 18 ++++
src/wallet/api/wallet2_api.h | 12 +++
src/wallet/api/wallet.cpp | 100 +++++++++++++++++++
src/wallet/api/wallet.h | 14 +++
src/wallet/api/wallet2_api.h | 13 +++
src/wallet/api/wallet_manager.cpp | 12 ++-
12 files changed, 365 insertions(+), 25 deletions(-)
13 files changed, 405 insertions(+), 26 deletions(-)
create mode 100644 src/device/device_io_dummy.cpp
create mode 100644 src/device/device_io_dummy.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c73b813d8..5c0f31cb8 100644
index c73b813d8..ce5ef4bab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -692,8 +692,12 @@ include_directories(${LMDB_INCLUDE})
@@ -692,16 +692,21 @@ include_directories(${LMDB_INCLUDE})
include_directories(${LIBUNWIND_INCLUDE})
link_directories(${LIBUNWIND_LIBRARY_DIRS})
-# Final setup for hid
-if (HIDAPI_FOUND)
- message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
- add_definitions(-DHAVE_HIDAPI)
- include_directories(${HIDAPI_INCLUDE_DIR})
- link_directories(${LIBHIDAPI_LIBRARY_DIRS})
+if (HIDAPI_DUMMY)
+ add_definitions(-DHIDAPI_DUMMY)
+endif()
else()
- message(STATUS "Could not find HIDAPI")
+ # Final setup for hid
+ if (HIDAPI_FOUND)
+ message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
+ add_definitions(-DHAVE_HIDAPI)
+ include_directories(${HIDAPI_INCLUDE_DIR})
+ link_directories(${LIBHIDAPI_LIBRARY_DIRS})
+ else()
+ message(STATUS "Could not find HIDAPI")
+ endif()
endif()
+
# Final setup for hid
-if (HIDAPI_FOUND)
+if (HIDAPI_FOUND)
message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
add_definitions(-DHAVE_HIDAPI)
include_directories(${HIDAPI_INCLUDE_DIR})
# Trezor support check
include(CheckTrezor)
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
index e4f1159b5..14d398f87 100644
--- a/src/device/CMakeLists.txt
@@ -131,10 +147,10 @@ index 392703a24..ffd419779 100644
diff --git a/src/device/device_io_dummy.cpp b/src/device/device_io_dummy.cpp
new file mode 100644
index 000000000..edb4beea3
index 000000000..01e6fc7b7
--- /dev/null
+++ b/src/device/device_io_dummy.cpp
@@ -0,0 +1,133 @@
@@ -0,0 +1,161 @@
+// Copyright (c) 2017-2022, The Monero Project
+//
+// All rights reserved.
@@ -189,6 +205,10 @@ index 000000000..edb4beea3
+size_t hw::io::device_io_dummy::receivedFromDeviceLength = 0;
+bool hw::io::device_io_dummy::waitsForDeviceSend = false;
+bool hw::io::device_io_dummy::waitsForDeviceReceive = false;
+void (*hw::io::device_io_dummy::sendToLedgerDeviceCallback)(unsigned char *command, unsigned int cmd_len) = nullptr;
+std::mutex hw::io::device_io_dummy::mutex;
+std::condition_variable hw::io::device_io_dummy::cv_send;
+std::condition_variable hw::io::device_io_dummy::cv_receive;
+
+namespace hw {
+ namespace io {
@@ -227,22 +247,29 @@ index 000000000..edb4beea3
+
+ int device_io_dummy::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) {
+ MDEBUG("exchange(): locking mutex");
+ boost::unique_lock<boost::mutex> lock(mutex);
+ std::unique_lock<std::mutex> lock(mutex);
+ sendToDevice = command;
+ sendToDeviceLength = cmd_len;
+ waitsForDeviceSend = true;
+ waitsForDeviceReceive = true;
+
+ // Call the callback if it's set
+ if (sendToLedgerDeviceCallback != nullptr) {
+ MDEBUG("exchange(): calling sendToLedgerDeviceCallback");
+ sendToLedgerDeviceCallback(command, cmd_len);
+ }
+ MDEBUG("exchange(): waitsForDeviceSend");
+ // NOTE: waitsForDeviceSend should be changed by external code
+ // Wait for the send flag to be cleared by external code
+ while (waitsForDeviceSend) {
+ usleep(1000);
+ MDEBUG("exchange(): waitsForDeviceSend (still)");
+ cv_send.wait(lock);
+ MDEBUG("exchange(): waitsForDeviceSend notified");
+ }
+
+ MDEBUG("exchange(): waitsForDeviceReceive");
+ // Wait for the receive flag to be cleared by external code
+ while (waitsForDeviceReceive) {
+ usleep(1000);
+ MDEBUG("exchange(): waitsForDeviceReceive (still)");
+ cv_receive.wait(lock);
+ MDEBUG("exchange(): waitsForDeviceReceive notified");
+ }
+
+ if (receivedFromDeviceLength > max_resp_len) {
@@ -250,7 +277,8 @@ index 000000000..edb4beea3
+ return 1;
+ }
+
+ memset(response,0,max_resp_len);
+
+ memset(response, 0, max_resp_len);
+ memcpy(response, receivedFromDevice, receivedFromDeviceLength);
+ return receivedFromDeviceLength;
+ }
@@ -263,18 +291,34 @@ index 000000000..edb4beea3
+ MDEBUG("release()");
+ }
+
+ void device_io_dummy::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)) {
+ MDEBUG("setLedgerCallback()");
+ sendToLedgerDeviceCallback = sendToLedgerDevice;
+ }
+
+ void device_io_dummy::setDeviceReceivedData(unsigned char* data, size_t len) {
+ MDEBUG("setDeviceReceivedData(len: " << len << ")");
+ std::unique_lock<std::mutex> lock(mutex);
+
+ receivedFromDevice = static_cast<unsigned char *>(malloc(len));
+ receivedFromDeviceLength = len;
+ memset(receivedFromDevice, 0, len);
+ memcpy(receivedFromDevice, data, len);
+ waitsForDeviceReceive = false;
+ waitsForDeviceSend = false;
+ cv_send.notify_all();
+ cv_receive.notify_all();
+ }
+ }
+}
+#endif // HAVE_HIDAPI
\ No newline at end of file
diff --git a/src/device/device_io_dummy.hpp b/src/device/device_io_dummy.hpp
new file mode 100644
index 000000000..a1733616d
index 000000000..1128b9c1d
--- /dev/null
+++ b/src/device/device_io_dummy.hpp
@@ -0,0 +1,74 @@
@@ -0,0 +1,82 @@
+// Copyright (c) 2017-2022, The Monero Project
+//
+// All rights reserved.
@@ -309,6 +353,8 @@ index 000000000..a1733616d
+
+#include "device_io.hpp"
+#include "device_io_hid.hpp"
+#include <mutex>
+#include <condition_variable>
+
+namespace hw {
+ namespace io {
@@ -320,9 +366,11 @@ index 000000000..a1733616d
+ };
+ class device_io_dummy : device_io {
+ private:
+ boost::mutex mutex;
+ static std::mutex mutex;
+
+ public:
+ static std::condition_variable cv_send;
+ static std::condition_variable cv_receive;
+ static bool stateIsConnected;
+ static unsigned char* sendToDevice;
+ static size_t sendToDeviceLength;
@@ -330,6 +378,7 @@ index 000000000..a1733616d
+ static size_t receivedFromDeviceLength;
+ static bool waitsForDeviceSend;
+ static bool waitsForDeviceReceive;
+ static void (*sendToLedgerDeviceCallback)(unsigned char *command, unsigned int cmd_len);
+
+ device_io_dummy() = default;
+ device_io_dummy(int a, int b, int c, int d);
@@ -343,7 +392,10 @@ index 000000000..a1733616d
+ void disconnect();
+ bool connected() const;
+
+ int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input);
+ int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input);
+
+ static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
+ static void setDeviceReceivedData(unsigned char* data, size_t len);
+ };
+ };
+};
@@ -415,7 +467,7 @@ index 03058c4f1..39454ca6d 100644
unsigned char buffer_send[BUFFER_SEND_SIZE];
unsigned int length_recv;
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 3fcd6f332..25ade04a7 100644
index 3fcd6f332..844a1c451 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -48,6 +48,9 @@
@@ -428,91 +480,87 @@ index 3fcd6f332..25ade04a7 100644
using namespace std;
using namespace cryptonote;
@@ -3178,4 +3181,95 @@ uint64_t WalletImpl::getBytesSent()
@@ -3178,4 +3181,101 @@ uint64_t WalletImpl::getBytesSent()
return m_wallet->get_bytes_sent();
}
+
+// HIDAPI_DUMMY
+bool WalletImpl::getStateIsConnected() {
+bool Wallet::getStateIsConnected() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return false;
+ #else
+ return hw::io::device_io_dummy::stateIsConnected;
+ #endif
+}
+
+unsigned char* WalletImpl::getSendToDevice() {
+unsigned char* Wallet::getSendToDevice() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return {};
+ #else
+ return hw::io::device_io_dummy::sendToDevice;
+ #endif
+}
+
+size_t WalletImpl::getSendToDeviceLength() {
+size_t Wallet::getSendToDeviceLength() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return -1;
+ #else
+ return hw::io::device_io_dummy::sendToDeviceLength;
+ #endif
+}
+
+unsigned char* WalletImpl::getReceivedFromDevice() {
+unsigned char* Wallet::getReceivedFromDevice() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return {};
+ #else
+ return hw::io::device_io_dummy::receivedFromDevice;
+ #endif
+}
+
+size_t WalletImpl::getReceivedFromDeviceLength() {
+size_t Wallet::getReceivedFromDeviceLength() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return -1;
+ #else
+ return hw::io::device_io_dummy::receivedFromDeviceLength;
+ #endif
+}
+
+bool WalletImpl::getWaitsForDeviceSend() {
+bool Wallet::getWaitsForDeviceSend() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return false;
+ #else
+ return hw::io::device_io_dummy::receivedFromDeviceLength;
+ return hw::io::device_io_dummy::waitsForDeviceSend;
+ #endif
+}
+
+bool WalletImpl::getWaitsForDeviceReceive() {
+bool Wallet::getWaitsForDeviceReceive() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return false;
+ #else
+ return hw::io::device_io_dummy::waitsForDeviceReceive;
+ #endif
+}
+
+void WalletImpl::setDeviceReceivedData(unsigned char* data, size_t len) {
+void Wallet::setDeviceReceivedData(unsigned char* data, size_t len) {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return;
+ #else
+ hw::io::device_io_dummy::receivedFromDevice = static_cast<unsigned char *>(malloc(len));
+ hw::io::device_io_dummy::receivedFromDeviceLength = len;
+ memset(hw::io::device_io_dummy::receivedFromDevice, 0, len);
+ memcpy(hw::io::device_io_dummy::receivedFromDevice, data, len);
+ hw::io::device_io_dummy::waitsForDeviceReceive = false;
+ hw::io::device_io_dummy::setDeviceReceivedData(data, len);
+ #endif
+}
+
+void WalletImpl::setDeviceSendData(unsigned char* data, size_t len) {
+void Wallet::setDeviceSendData(unsigned char* data, size_t len) {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return;
+ #else
+ hw::io::device_io_dummy::sendToDevice = static_cast<unsigned char *>(malloc(len));
@@ -520,15 +568,25 @@ index 3fcd6f332..25ade04a7 100644
+ memset(hw::io::device_io_dummy::sendToDevice, 0, len);
+ memcpy(hw::io::device_io_dummy::sendToDevice, data, len);
+ hw::io::device_io_dummy::waitsForDeviceSend = false;
+ hw::io::device_io_dummy::cv_send.notify_all();
+ #endif
+}
+
+void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)) {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return;
+ #else
+ hw::io::device_io_dummy::setLedgerCallback(sendToLedgerDevice);
+ #endif
+}
+
} // namespace
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index edf8bb8ce..4e9c21ecb 100644
index edf8bb8ce..6bfb61cb8 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -301,6 +301,24 @@ private:
@@ -301,6 +301,20 @@ private:
// cache connection status to avoid unnecessary RPC calls
mutable std::atomic<bool> m_is_connected;
boost::optional<epee::net_utils::http::login> m_daemon_login{};
@@ -546,33 +604,30 @@ index edf8bb8ce..4e9c21ecb 100644
+ bool getWaitsForDeviceSend();
+
+ bool getWaitsForDeviceReceive();
+
+ void setDeviceReceivedData(unsigned char *data, size_t len);
+
+ void setDeviceSendData(unsigned char *data, size_t len);
};
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 764adbfbf..53ec4abfc 100644
index 764adbfbf..a48a6be54 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1150,6 +1150,18 @@ struct Wallet
@@ -1150,6 +1150,19 @@ struct Wallet
//! get bytes sent
virtual uint64_t getBytesSent() = 0;
+
+ // HIDAPI_DUMMY
+ virtual bool getStateIsConnected() = 0;
+ virtual unsigned char* getSendToDevice() = 0;
+ virtual size_t getSendToDeviceLength() = 0;
+ virtual unsigned char* getReceivedFromDevice() = 0;
+ virtual size_t getReceivedFromDeviceLength() = 0;
+ virtual bool getWaitsForDeviceSend() = 0;
+ virtual bool getWaitsForDeviceReceive() = 0;
+ static bool getStateIsConnected();
+ static unsigned char* getSendToDevice();
+ static size_t getSendToDeviceLength();
+ static unsigned char* getReceivedFromDevice();
+ static size_t getReceivedFromDeviceLength();
+ static bool getWaitsForDeviceSend();
+ static bool getWaitsForDeviceReceive();
+
+ virtual void setDeviceReceivedData(unsigned char* data, size_t len) = 0;
+ virtual void setDeviceSendData(unsigned char* data, size_t len) = 0;
+ static void setDeviceReceivedData(unsigned char* data, size_t len);
+ static void setDeviceSendData(unsigned char* data, size_t len);
+ static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
};
/**
@@ -600,5 +655,5 @@ index e81b8f83a..277be6ac9 100644
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
--
2.48.1
2.49.0
+7 -7
View File
@@ -1,7 +1,7 @@
From c54ab3f0984159bd47c63b78074caaaac082727a Mon Sep 17 00:00:00 2001
From 3c3d441cabcaae9eb5d3db2f5cd6c506feb97168 Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 09:42:37 +0100
Subject: [PATCH 07/14] polyseed
Subject: [PATCH 07/17] polyseed
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
---
@@ -814,7 +814,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 25ade04a7..51911bf99 100644
index 844a1c451..050212ff7 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -728,6 +728,28 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p
@@ -902,7 +902,7 @@ index 25ade04a7..51911bf99 100644
{
return m_wallet->get_seed_language();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 4e9c21ecb..32e12284b 100644
index 6bfb61cb8..e7873dd78 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -79,9 +79,19 @@ public:
@@ -926,7 +926,7 @@ index 4e9c21ecb..32e12284b 100644
void setSeedLanguage(const std::string &arg) override;
// void setListener(Listener *) {}
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 53ec4abfc..be1c3704e 100644
index a48a6be54..8fa0bbd42 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -709,6 +709,10 @@ struct Wallet
@@ -940,7 +940,7 @@ index 53ec4abfc..be1c3704e 100644
/**
* @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
*/
@@ -1320,6 +1324,27 @@ struct WalletManager
@@ -1321,6 +1325,27 @@ struct WalletManager
uint64_t kdf_rounds = 1,
WalletListener * listener = nullptr) = 0;
@@ -1282,5 +1282,5 @@ index a752f15b9..a619bdd15 100644
uint32_t m_multisig_threshold;
std::vector<crypto::public_key> m_multisig_signers;
--
2.48.1
2.49.0
+6 -6
View File
@@ -1,7 +1,7 @@
From 753d7eee48d8e9ab5950e48dc984cc1038c11dd1 Mon Sep 17 00:00:00 2001
From 722abaf1f84d8444d40e277f8b97e54250195856 Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 11:07:57 +0100
Subject: [PATCH 08/14] coin control
Subject: [PATCH 08/17] coin control
---
src/simplewallet/simplewallet.cpp | 2 +-
@@ -504,7 +504,7 @@ index 000000000..c43e45abd
+
+#endif //FEATHER_COINS_INFO_H
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 51911bf99..933cc2531 100644
index 050212ff7..b259528ef 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -35,6 +35,7 @@
@@ -760,7 +760,7 @@ index 51911bf99..933cc2531 100644
{
return m_subaddress.get();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 32e12284b..a82f270e4 100644
index e7873dd78..bc782dd4a 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -46,6 +46,7 @@ class PendingTransactionImpl;
@@ -813,7 +813,7 @@ index 32e12284b..a82f270e4 100644
// multi-threaded refresh stuff
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index be1c3704e..013b5bcba 100644
index 8fa0bbd42..7e67f02fd 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -263,6 +263,51 @@ struct AddressBook
@@ -1095,5 +1095,5 @@ index a619bdd15..4f324c238 100644
void set_unspent(size_t idx);
bool is_spent(const transfer_details &td, bool strict = true) const;
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From 0ba0339b11d8f7f66f2d5cd27075d438a76351b4 Mon Sep 17 00:00:00 2001
From f386189cf3c5b433251b2cf493ba264a1a79fb7e Mon Sep 17 00:00:00 2001
From: M <m@cakewallet.com>
Date: Fri, 21 Apr 2023 15:43:47 -0400
Subject: [PATCH 09/14] Add hex encoding and tx key getter for
Subject: [PATCH 09/17] Add hex encoding and tx key getter for
PendingTransction in wallet api.
---
@@ -51,7 +51,7 @@ index 403bfe281..0cc6c58e9 100644
private:
friend class WalletImpl;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 013b5bcba..f421fdc05 100644
index 7e67f02fd..7f1462a44 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -127,6 +127,8 @@ struct PendingTransaction
@@ -64,5 +64,5 @@ index 013b5bcba..f421fdc05 100644
/**
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From cb02355313d504e6a44f8f70b8eb2be64167ffd4 Mon Sep 17 00:00:00 2001
From 55f5311122fb9d19e870fa4a330c59d76ca92aac Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Wed, 11 Oct 2023 16:47:59 +0200
Subject: [PATCH 10/14] Add recoverDeterministicWalletFromSpendKey
Subject: [PATCH 10/17] 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 933cc2531..d8fe108b4 100644
index b259528ef..20ccbfb35 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -824,6 +824,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
@@ -59,7 +59,7 @@ index 933cc2531..d8fe108b4 100644
{
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index a82f270e4..9e1fbb40b 100644
index bc782dd4a..bfe81c590 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -77,6 +77,10 @@ public:
@@ -74,10 +74,10 @@ index a82f270e4..9e1fbb40b 100644
const std::string &password,
const std::string &device_name);
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index f421fdc05..c8d6bb179 100644
index 7f1462a44..27e8b1426 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1323,6 +1323,25 @@ struct WalletManager
@@ -1324,6 +1324,25 @@ struct WalletManager
return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString);
}
@@ -149,5 +149,5 @@ index 28fcd36c9..be3ff8184 100644
const std::string &password,
NetworkType nettype,
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From 846d3f60093add6653d9102d841288066fc08311 Mon Sep 17 00:00:00 2001
From ec93b6bf725eeff0999fdd9d603c4578cb19ae07 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Thu, 7 Nov 2024 16:46:24 +0000
Subject: [PATCH 11/14] add monero submodule support
Subject: [PATCH 11/17] add monero submodule support
---
CMakeLists.txt | 6 +++---
@@ -61,5 +61,5 @@ index 3188c88db..9fbdb3c05 100644
if (ptx_vector.empty())
{
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From 53cc0482e55a39b5dbf2261fea11fcb160778800 Mon Sep 17 00:00:00 2001
From 73d6ad9d513f776afb1c1f5f2d74e3b06fad7eeb Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 21 Nov 2024 06:05:03 -0500
Subject: [PATCH 12/14] fix iOS depends build
Subject: [PATCH 12/17] fix iOS depends build
---
CMakeLists.txt | 4 ----
@@ -100,5 +100,5 @@ index 71b8f78cc..0f53f024e 100644
#if TARGET_OS_MAC && (!defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)
return boost::logic::tribool(IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited);
--
2.48.1
2.49.0
@@ -1,8 +1,7 @@
From 1eacd30724559749be5adeb31d763f44c3f221f9 Mon Sep 17 00:00:00 2001
From db52bcebe23b29b35ae538f01e72ed4f7f66f931 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 18 Nov 2024 10:57:37 -0500
Subject: [PATCH 13/14] include locale only when targeting WIN32
Subject: [PATCH 13/17] include locale only when targeting WIN32
---
CMakeLists.txt | 6 +++++-
@@ -10,7 +9,7 @@ Subject: [PATCH 13/14] include locale only when targeting WIN32
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1eac121db..3a4e8f7e1 100644
index 1eac121db..5938be622 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1089,7 +1089,11 @@ if(NOT Boost_FOUND)
@@ -27,7 +26,7 @@ index 1eac121db..3a4e8f7e1 100644
# Boost System is header-only since 1.69
if (Boost_VERSION_STRING VERSION_LESS 1.69.0)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index d8fe108b4..e3e838b13 100644
index 20ccbfb35..c43803033 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -46,7 +46,9 @@
@@ -41,5 +40,5 @@ index d8fe108b4..e3e838b13 100644
#include "bc-ur/src/bc-ur.hpp"
#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From 2d31234e859bff817d30d91b21d9412375668aae Mon Sep 17 00:00:00 2001
From be01eac2724d22cd7225bb17fba7a443efe8d8d6 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Wed, 29 Jan 2025 16:13:28 +0100
Subject: [PATCH 14/14] change earliest fork height message
Subject: [PATCH 14/17] change earliest fork height message
---
src/wallet/wallet2.cpp | 2 +-
@@ -21,5 +21,5 @@ index 8720e18b1..69da11d9c 100644
bool close_enough = (int64_t)height >= (int64_t)earliest_height - early_blocks && earliest_height != std::numeric_limits<uint64_t>::max(); // start using the rules that many blocks beforehand
if (close_enough)
--
2.48.1
2.49.0
@@ -1,7 +1,7 @@
From 71cf45cfbd571ec58e8b2a1d408ff74804bf7e1d Mon Sep 17 00:00:00 2001
From b62446750e904978cd1a8f90d5f2d1437a3db5a9 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 20 Feb 2025 08:36:28 +0100
Subject: [PATCH] remove trivially_copyable assert
Subject: [PATCH 15/17] remove trivially_copyable assert
---
contrib/epee/include/span.h | 1 -
@@ -20,5 +20,5 @@ index 01dc387d6..2ad733a2f 100644
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
}
--
2.48.1
2.49.0
+25
View File
@@ -0,0 +1,25 @@
From ab4e853571329b3ccb745c393220c047b03f2b2c Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 1 Apr 2025 11:30:45 +0200
Subject: [PATCH 16/17] pr-9880
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5938be622..1c4728578 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -216,7 +216,7 @@ function(forbid_undefined_symbols)
file(MAKE_DIRECTORY "${TEST_PROJECT}")
file(WRITE "${TEST_PROJECT}/CMakeLists.txt"
[=[
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.5)
project(test)
option(EXPECT_SUCCESS "" ON)
file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
--
2.49.0
@@ -0,0 +1,28 @@
From 32f2e6cc2e184bfdaa92a5d45a15983c896f6816 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 10 Apr 2025 13:28:05 +0200
Subject: [PATCH 17/17] fix: unary_function -> __unary_function
---
src/cryptonote_basic/cryptonote_basic_impl.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h
index b423573c5..a9aef7a2a 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.h
+++ b/src/cryptonote_basic/cryptonote_basic_impl.h
@@ -40,7 +40,11 @@ namespace cryptonote {
/* */
/************************************************************************/
template<class t_array>
+#ifdef __APPLE__
+ struct array_hasher: std::__unary_function<t_array&, std::size_t>
+#else
struct array_hasher: std::unary_function<t_array&, std::size_t>
+#endif
{
std::size_t operator()(const t_array& val) const
{
--
2.49.0
@@ -0,0 +1,463 @@
From 7c1d576901a56b7c315b2c54362f7985ff8df753 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 12 Aug 2025 07:09:14 -0400
Subject: [PATCH] serialize cache to JSON
---
src/wallet/CMakeLists.txt | 1 +
src/wallet/api/wallet.cpp | 5 +
src/wallet/api/wallet.h | 2 +
src/wallet/api/wallet2_api.h | 3 +
src/wallet/wallet2.h | 6 +
src/wallet/wallet_cache_to_json.cpp | 368 ++++++++++++++++++++++++++++
6 files changed, 385 insertions(+)
create mode 100644 src/wallet/wallet_cache_to_json.cpp
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index b163212b7..196ad671f 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -38,6 +38,7 @@ set(wallet_sources
message_store.cpp
message_transporter.cpp
wallet_rpc_payments.cpp
+ wallet_cache_to_json.cpp
)
monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 7d7d0f922..effb6e719 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -3475,4 +3475,9 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command
#endif
}
+std::string WalletImpl::serializeCacheToJson() const
+{
+ return std::string(m_wallet->serialize_cache_to_json());
+}
+
} // namespace
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index bfe81c590..98c03b9c1 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -335,6 +335,8 @@ private:
bool getWaitsForDeviceSend();
bool getWaitsForDeviceReceive();
+
+ virtual std::string serializeCacheToJson() const override;
};
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index fcb8187d4..3d11929f9 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1217,6 +1217,9 @@ struct Wallet
static void setDeviceReceivedData(unsigned char* data, size_t len);
static void setDeviceSendData(unsigned char* data, size_t len);
static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
+
+ //! serialize wallet cache to JSON
+ virtual std::string serializeCacheToJson() const = 0;
};
/**
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 4f324c238..bc4abc672 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1429,6 +1429,12 @@ private:
FIELD(m_background_sync_data)
END_SERIALIZE()
+ /*!
+ * \brief Serialize wallet cache fields to JSON
+ * \return const char* pointing to JSON string containing all cache fields
+ */
+ const char* serialize_cache_to_json() const;
+
/*!
* \brief Check if wallet keys and bin files exist
* \param file_path Wallet file path
diff --git a/src/wallet/wallet_cache_to_json.cpp b/src/wallet/wallet_cache_to_json.cpp
new file mode 100644
index 000000000..64687a7a6
--- /dev/null
+++ b/src/wallet/wallet_cache_to_json.cpp
@@ -0,0 +1,368 @@
+#include "wallet2.h"
+#include "serialization/binary_archive.h"
+#include "serialization/json_archive.h"
+#include "serialization/serialization.h"
+#include <sstream>
+#include <iomanip>
+
+namespace tools
+{
+
+static void write_escaped_json_string(std::ostream& os, const std::string& str)
+{
+ for (char c : str) {
+ switch (c) {
+ case '"': os << "\\\""; break;
+ case '\\': os << "\\\\"; break;
+ case '\n': os << "\\n"; break;
+ case '\r': os << "\\r"; break;
+ case '\t': os << "\\t"; break;
+ case '\b': os << "\\b"; break;
+ case '\f': os << "\\f"; break;
+ default: os << c; break;
+ }
+ }
+}
+
+static void post_process_json(std::string& json)
+{
+ // ": ," --> ": null,"
+ size_t pos = 0;
+ while ((pos = json.find(": ,", pos)) != std::string::npos) {
+ json.replace(pos, 3, ": null,");
+ pos += 7;
+ }
+
+ // ": }" --> ": null}"
+ pos = 0;
+ while ((pos = json.find(": }", pos)) != std::string::npos) {
+ json.replace(pos, 3, ": null}");
+ pos += 7;
+ }
+
+ // ": ]" --> ": null]"
+ pos = 0;
+ while ((pos = json.find(": ]", pos)) != std::string::npos) {
+ json.replace(pos, 3, ": null]");
+ pos += 7;
+ }
+
+ // "key": number"hexstring" --> "key": "numberhexstring"
+ pos = 0;
+ while (pos < json.length()) {
+ size_t colon_pos = json.find(": ", pos);
+ if (colon_pos == std::string::npos) break;
+
+ size_t value_start = colon_pos + 2;
+ if (value_start >= json.length()) break;
+
+ if (std::isdigit(json[value_start])) {
+ size_t quote_pos = json.find('"', value_start);
+ if (quote_pos != std::string::npos && quote_pos < json.find_first_of(",}]", value_start)) {
+ size_t closing_quote = json.find('"', quote_pos + 1);
+ if (closing_quote != std::string::npos && closing_quote < json.find_first_of(",}]", value_start)) {
+ std::string digits;
+ size_t digit_end = value_start;
+ while (digit_end < quote_pos && std::isdigit(json[digit_end])) {
+ digits += json[digit_end];
+ digit_end++;
+ }
+
+ if (digit_end == quote_pos && !digits.empty()) {
+ std::string hex_part = json.substr(quote_pos + 1, closing_quote - quote_pos - 1);
+
+ std::string replacement = "\"" + digits + hex_part + "\"";
+ json.replace(value_start, closing_quote - value_start + 1, replacement);
+ pos = value_start + replacement.length();
+ continue;
+ }
+ }
+ }
+ }
+
+ pos = colon_pos + 1;
+ }
+}
+
+const char* wallet2::serialize_cache_to_json() const
+{
+ static std::string json_result;
+
+ try
+ {
+ std::stringstream oss;
+ json_archive<true> ar(oss, true); // true for pretty printing
+
+ ar.begin_object();
+
+ // MAGIC_FIELD("monero wallet cache")
+ std::string magic = "monero wallet cache";
+ ar.tag("magic");
+ ar.serialize_blob((void*)magic.data(), magic.size());
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize magic field\"}";
+ return json_result.c_str();
+ }
+
+ // VERSION_FIELD(2)
+ uint32_t version = 2;
+ ar.tag("version");
+ ar.serialize_varint(version);
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize version field\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_blockchain) - hashchain type, has serialization support
+ ar.tag("m_blockchain");
+ if (!::serialization::serialize(ar, const_cast<hashchain&>(m_blockchain))) {
+ json_result = "{\"error\":\"Failed to serialize m_blockchain\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_transfers) - transfer_container (std::vector<transfer_details>)
+ ar.tag("m_transfers");
+ if (!::serialization::serialize(ar, const_cast<transfer_container&>(m_transfers))) {
+ json_result = "{\"error\":\"Failed to serialize m_transfers\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_account_public_address) - cryptonote::account_public_address
+ ar.tag("m_account_public_address");
+ if (!::serialization::serialize(ar, const_cast<cryptonote::account_public_address&>(m_account_public_address))) {
+ json_result = "{\"error\":\"Failed to serialize m_account_public_address\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_key_images) - serializable_unordered_map<crypto::key_image, size_t>
+ ar.tag("m_key_images");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::key_image, size_t>&>(m_key_images))) {
+ json_result = "{\"error\":\"Failed to serialize m_key_images\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_unconfirmed_txs) - serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>
+ ar.tag("m_unconfirmed_txs");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>&>(m_unconfirmed_txs))) {
+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_txs\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_payments) - payment_container (serializable_unordered_multimap<crypto::hash, payment_details>)
+ ar.tag("m_payments");
+ if (!::serialization::serialize(ar, const_cast<payment_container&>(m_payments))) {
+ json_result = "{\"error\":\"Failed to serialize m_payments\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_tx_keys) - serializable_unordered_map<crypto::hash, crypto::secret_key>
+ ar.tag("m_tx_keys");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, crypto::secret_key>&>(m_tx_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_keys\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_confirmed_txs) - serializable_unordered_map<crypto::hash, confirmed_transfer_details>
+ ar.tag("m_confirmed_txs");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, confirmed_transfer_details>&>(m_confirmed_txs))) {
+ json_result = "{\"error\":\"Failed to serialize m_confirmed_txs\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_tx_notes) - serializable_unordered_map<crypto::hash, std::string>
+ ar.tag("m_tx_notes");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_notes))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_notes\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_unconfirmed_payments) - serializable_unordered_multimap<crypto::hash, pool_payment_details>
+ ar.tag("m_unconfirmed_payments");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_multimap<crypto::hash, pool_payment_details>&>(m_unconfirmed_payments))) {
+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_payments\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_pub_keys) - serializable_unordered_map<crypto::public_key, size_t>
+ ar.tag("m_pub_keys");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, size_t>&>(m_pub_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_pub_keys\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_address_book) - std::vector<tools::wallet2::address_book_row>
+ ar.tag("m_address_book");
+ if (!::serialization::serialize(ar, const_cast<std::vector<tools::wallet2::address_book_row>&>(m_address_book))) {
+ json_result = "{\"error\":\"Failed to serialize m_address_book\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_scanned_pool_txs[0]) - std::unordered_set<crypto::hash>
+ ar.tag("m_scanned_pool_txs_0");
+ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[0]))) {
+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[0]\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_scanned_pool_txs[1]) - std::unordered_set<crypto::hash>
+ ar.tag("m_scanned_pool_txs_1");
+ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[1]))) {
+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[1]\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_subaddresses) - serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>
+ ar.tag("m_subaddresses");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>&>(m_subaddresses))) {
+ json_result = "{\"error\":\"Failed to serialize m_subaddresses\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_subaddress_labels) - std::vector<std::vector<std::string>> - manual JSON serialization
+ oss << ", \n \"m_subaddress_labels\": [";
+ for (size_t i = 0; i < m_subaddress_labels.size(); ++i) {
+ if (i > 0) oss << ", ";
+ oss << "\n [";
+ for (size_t j = 0; j < m_subaddress_labels[i].size(); ++j) {
+ if (j > 0) oss << ", ";
+ oss << "\"";
+ write_escaped_json_string(oss, m_subaddress_labels[i][j]);
+ oss << "\"";
+ }
+ oss << "]";
+ }
+ oss << "\n ]";
+
+ // FIELD(m_additional_tx_keys) - serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>
+ ar.tag("m_additional_tx_keys");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>&>(m_additional_tx_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_additional_tx_keys\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_attributes) - serializable_unordered_map<std::string, std::string> - manual JSON serialization
+ oss << ", \n \"m_attributes\": {";
+ bool first_attr = true;
+ for (const auto& attr : m_attributes) {
+ if (!first_attr) oss << ", ";
+ first_attr = false;
+ oss << "\n \"";
+ write_escaped_json_string(oss, attr.first);
+ oss << "\": \"";
+ write_escaped_json_string(oss, attr.second);
+ oss << "\"";
+ }
+ oss << "\n }";
+
+ // FIELD(m_account_tags) - std::pair<serializable_map<std::string, std::string>, std::vector<std::string>> - manual JSON serialization
+ oss << ", \n \"m_account_tags\": {";
+ oss << "\n \"tags_map\": {";
+ bool first_tag = true;
+ for (const auto& tag : m_account_tags.first) {
+ if (!first_tag) oss << ", ";
+ first_tag = false;
+ oss << "\n \"";
+ write_escaped_json_string(oss, tag.first);
+ oss << "\": \"";
+ write_escaped_json_string(oss, tag.second);
+ oss << "\"";
+ }
+ oss << "\n },";
+ oss << "\n \"account_list\": [";
+ for (size_t i = 0; i < m_account_tags.second.size(); ++i) {
+ if (i > 0) oss << ", ";
+ oss << "\n \"";
+ write_escaped_json_string(oss, m_account_tags.second[i]);
+ oss << "\"";
+ }
+ oss << "\n ]";
+ oss << "\n }";
+
+ // FIELD(m_ring_history_saved) - bool
+ // ar.tag("m_ring_history_saved");
+ // ar.serialize_blob(&m_ring_history_saved, sizeof(m_ring_history_saved));
+ // if (!ar.good()) {
+ // json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}";
+ // return json_result.c_str();
+ // }
+
+ // FIELD(m_last_block_reward) - uint64_t
+ ar.tag("m_last_block_reward");
+ ar.serialize_int(m_last_block_reward);
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize m_last_block_reward\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_tx_device) - serializable_unordered_map<crypto::hash, std::string>
+ ar.tag("m_tx_device");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_device))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_device\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_device_last_key_image_sync) - uint64_t
+ ar.tag("m_device_last_key_image_sync");
+ ar.serialize_int(m_device_last_key_image_sync);
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize m_device_last_key_image_sync\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_cold_key_images) - serializable_unordered_map<crypto::public_key, crypto::key_image>
+ ar.tag("m_cold_key_images");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, crypto::key_image>&>(m_cold_key_images))) {
+ json_result = "{\"error\":\"Failed to serialize m_cold_key_images\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_rpc_client_secret_key) - crypto::secret_key
+ // ar.tag("m_rpc_client_secret_key");
+ // ar.serialize_blob(&m_rpc_client_secret_key, sizeof(m_rpc_client_secret_key));
+ // if (!ar.good()) {
+ // json_result = "{\"error\":\"Failed to serialize m_rpc_client_secret_key\"}";
+ // return json_result.c_str();
+ // }
+
+ // Version-dependent fields
+ if (version >= 1) {
+ // FIELD(m_has_ever_refreshed_from_node) - bool
+ // ar.tag("m_has_ever_refreshed_from_node");
+ // ar.serialize_blob(&m_has_ever_refreshed_from_node, sizeof(m_has_ever_refreshed_from_node));
+ // if (!ar.good()) {
+ // json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}";
+ // return json_result.c_str();
+ // }
+ }
+
+ if (version >= 2) {
+ // FIELD(m_background_sync_data) - background_sync_data_t
+ ar.tag("m_background_sync_data");
+ if (!::serialization::serialize(ar, const_cast<background_sync_data_t&>(m_background_sync_data))) {
+ json_result = "{\"error\":\"Failed to serialize m_background_sync_data\"}";
+ return json_result.c_str();
+ }
+ }
+
+ ar.end_object();
+
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to finalize JSON serialization\"}";
+ return json_result.c_str();
+ }
+
+ json_result = oss.str();
+
+ // Post-process to fix malformed JSON
+ post_process_json(json_result);
+
+ return json_result.c_str();
+ }
+ catch (const std::exception& e)
+ {
+ json_result = "{\"error\":\"Failed to serialize wallet cache: " + std::string(e.what()) + "\"}";
+ return json_result.c_str();
+ }
+}
+
+} // namespace tools
\ No newline at end of file
--
2.50.1
@@ -0,0 +1,34 @@
From 6e284a2ef552f1f47e8ca9edcf8651312c9e37dd Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 2 Apr 2024 16:51:56 +0200
Subject: [PATCH 01/14] fix missing ___clear_cache when targetting iOS
---
.gitmodules | 3 ++-
external/randomx | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/.gitmodules b/.gitmodules
index 721cce3b4..ffb73fe9a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -9,7 +9,8 @@
url = https://github.com/trezor/trezor-common.git
[submodule "external/randomx"]
path = external/randomx
- url = https://github.com/tevador/RandomX
+ url = https://github.com/MrCyjaneK/RandomX
+ branch = cyjan-fix-ios
[submodule "external/supercop"]
path = external/supercop
url = https://github.com/monero-project/supercop
diff --git a/external/randomx b/external/randomx
index 102f8acf9..ce72c9bb9 160000
--- a/external/randomx
+++ b/external/randomx
@@ -1 +1 @@
-Subproject commit 102f8acf90a7649ada410de5499a7ec62e49e1da
+Subproject commit ce72c9bb9cb799e0d9171094b9abb009e04c5bfc
--
2.48.1
+208
View File
@@ -0,0 +1,208 @@
From b4f4b38af1ab974872862fc20735e41941b955e9 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Sat, 11 May 2024 16:25:10 +0200
Subject: [PATCH 02/14] store crash fix
Monero wallet crashes (sometimes) when it is syncing,
while the proper solution (that can be seen in feather)
is to not store wallet while it is being synced, this is not
acceptable for mobile wallets where OS can just come
and kill the wallet because it felt like it.
This patch depends on the background-sync patch, but
to use it as a standalone fix grabbing the definition for the
LOCK_REFRESH macro should be enough.
tobtoht suggested:
_say you want to store every 15 minutes during background sync. you stop the refresh every 15 minutes. then do something like this in the callback:_
```
// Make sure this doesn't run in the refresh thread
onRefreshed() {
if (hasItBeen15MinutesSinceWeStored()) {
store();
}
if (shouldWeContinueRefreshing()) {
startRefresh();
}
}
```
which works for crashes after the wallet is initially synced
but doesn't solve the issue for wallet that are syncing (it
would just wait for it to finish before actually storing).
Also imo store() functin should store the wallet, no matter
the current state.
---
src/wallet/api/wallet.cpp | 25 ++++++++++++-------------
src/wallet/api/wallet.h | 1 -
src/wallet/wallet2.cpp | 11 ++++++++++-
src/wallet/wallet2.h | 3 +++
4 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 8fda0bab7..67b170e3d 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -55,8 +55,8 @@ using namespace cryptonote;
#define MONERO_DEFAULT_LOG_CATEGORY "WalletAPI"
#define LOCK_REFRESH() \
- bool refresh_enabled = m_refreshEnabled; \
- m_refreshEnabled = false; \
+ bool refresh_enabled = m_wallet->get_refresh_enabled(); \
+ m_wallet->set_refresh_enabled(false); \
m_wallet->stop(); \
m_refreshCV.notify_one(); \
boost::mutex::scoped_lock lock(m_refreshMutex); \
@@ -466,7 +466,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
m_wallet2Callback.reset(new Wallet2CallbackImpl(this));
m_wallet->callback(m_wallet2Callback.get());
m_refreshThreadDone = false;
- m_refreshEnabled = false;
+ m_wallet->set_refresh_enabled(false);
m_addressBook.reset(new AddressBookImpl(this));
m_subaddress.reset(new SubaddressImpl(this));
m_subaddressAccount.reset(new SubaddressAccountImpl(this));
@@ -962,6 +962,7 @@ void WalletImpl::stop()
bool WalletImpl::store(const std::string &path)
{
clearStatus();
+ LOCK_REFRESH();
try {
if (path.empty()) {
m_wallet->store();
@@ -2448,10 +2449,10 @@ void WalletImpl::refreshThreadFunc()
}
LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired...");
- LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled);
+ LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_wallet->get_refresh_enabled());
LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << status());
LOG_PRINT_L3(__FUNCTION__ << ": m_refreshShouldRescan: " << m_refreshShouldRescan);
- if (m_refreshEnabled) {
+ if (m_wallet->get_refresh_enabled()) {
LOG_PRINT_L3(__FUNCTION__ << ": refreshing...");
doRefresh();
}
@@ -2481,12 +2482,12 @@ void WalletImpl::doRefresh()
}
m_wallet->find_and_save_rings(false);
} else {
- LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced");
+ LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced");
}
} catch (const std::exception &e) {
setStatusError(e.what());
break;
- }while(!rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested
+ }while(m_wallet->get_refresh_enabled() && !rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested
if (m_wallet2Callback->getListener()) {
m_wallet2Callback->getListener()->refreshed();
@@ -2496,9 +2497,9 @@ void WalletImpl::doRefresh()
void WalletImpl::startRefresh()
{
- if (!m_refreshEnabled) {
+ if (!m_wallet->get_refresh_enabled()) {
LOG_PRINT_L2(__FUNCTION__ << ": refresh started/resumed...");
- m_refreshEnabled = true;
+ m_wallet->set_refresh_enabled(true);
m_refreshCV.notify_one();
}
}
@@ -2508,7 +2509,7 @@ void WalletImpl::startRefresh()
void WalletImpl::stopRefresh()
{
if (!m_refreshThreadDone) {
- m_refreshEnabled = false;
+ m_wallet->set_refresh_enabled(false);
m_refreshThreadDone = true;
m_refreshCV.notify_one();
m_refreshThread.join();
@@ -2519,9 +2520,7 @@ void WalletImpl::pauseRefresh()
{
LOG_PRINT_L2(__FUNCTION__ << ": refresh paused...");
// TODO synchronize access
- if (!m_refreshThreadDone) {
- m_refreshEnabled = false;
- }
+ m_wallet->set_refresh_enabled(false);
}
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 1f199a72c..ac7ce2f6a 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -273,7 +273,6 @@ private:
std::unique_ptr<SubaddressAccountImpl> m_subaddressAccount;
// multi-threaded refresh stuff
- std::atomic<bool> m_refreshEnabled;
std::atomic<bool> m_refreshThreadDone;
std::atomic<int> m_refreshIntervalMillis;
std::atomic<bool> m_refreshShouldRescan;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index dfb8b23cb..c9c2dbc82 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1192,6 +1192,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_upper_transaction_weight_limit(0),
m_run(true),
m_callback(0),
+ m_refreshEnabled(false),
m_trusted_daemon(false),
m_nettype(nettype),
m_multisig_rounds_passed(0),
@@ -1412,6 +1413,14 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u
return ret;
}
//----------------------------------------------------------------------------------------------------
+bool wallet2::get_refresh_enabled() {
+ return m_refreshEnabled;
+}
+//----------------------------------------------------------------------------------------------------
+void wallet2::set_refresh_enabled(bool val) {
+ m_refreshEnabled = val;
+}
+//----------------------------------------------------------------------------------------------------
bool wallet2::set_proxy(const std::string &address)
{
return m_http_client->set_proxy(address);
@@ -4107,7 +4116,7 @@ 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;
- while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks)
+ while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks && m_refreshEnabled)
{
uint64_t next_blocks_start_height;
std::vector<cryptonote::block_complete_entry> next_blocks;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 2f4ad52f1..daad1e940 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1078,6 +1078,8 @@ private:
epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect,
const std::string &proxy = "");
bool set_proxy(const std::string &address);
+ bool get_refresh_enabled();
+ void set_refresh_enabled(bool val);
void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); }
@@ -1989,6 +1991,7 @@ private:
boost::recursive_mutex m_daemon_rpc_mutex;
+ bool m_refreshEnabled;
bool m_trusted_daemon;
i_wallet2_callback* m_callback;
hw::device::device_type m_key_device_type;
--
2.48.1
@@ -0,0 +1,25 @@
From a74f616e3c1671a883182b0db1c6fc11a1242c01 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 2 Sep 2024 16:40:31 +0200
Subject: [PATCH 03/14] 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.48.1
@@ -0,0 +1,71 @@
From f9b222f1611d7cfbaf0ac52cd6194724c7554def Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 24 Jun 2024 10:49:12 +0200
Subject: [PATCH 04/14] use proper error handling in get_seed
---
src/wallet/api/wallet.cpp | 17 ++++++++++++-----
src/wallet/wallet2.cpp | 5 ++++-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 67b170e3d..89df5c517 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -763,12 +763,19 @@ bool WalletImpl::close(bool store)
std::string WalletImpl::seed(const std::string& seed_offset) const
{
- if (checkBackgroundSync("cannot get seed"))
+ if (checkBackgroundSync("cannot get seed")) {
+ setStatusError("cannot get seed");
return std::string();
- epee::wipeable_string seed;
- if (m_wallet)
- m_wallet->get_seed(seed, seed_offset);
- return std::string(seed.data(), seed.size()); // TODO
+ }
+ try {
+ epee::wipeable_string seed;
+ if (m_wallet)
+ m_wallet->get_seed(seed, seed_offset);
+ return std::string(seed.data(), seed.size()); // TODO
+ } catch (const std::exception &e) {
+ setStatusError(e.what());
+ return std::string();
+ }
}
std::string WalletImpl::getSeedLanguage() const
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index c9c2dbc82..b827b826f 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1428,11 +1428,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
bool keys_deterministic = is_deterministic();
if (!keys_deterministic)
{
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, "This is not a deterministic wallet");
std::cout << "This is not a deterministic wallet" << std::endl;
return false;
}
if (seed_language.empty())
{
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, "seed_language not set");
std::cout << "seed_language not set" << std::endl;
return false;
}
@@ -1444,8 +1446,9 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
key = cryptonote::encrypt_key(key, passphrase);
if (!crypto::ElectrumWords::bytes_to_words(key, electrum_words, seed_language))
{
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Failed to create seed from key for language: "+seed_language+", falling back to English.");
std::cout << "Failed to create seed from key for language: " << seed_language << std::endl;
- return false;
+ crypto::ElectrumWords::bytes_to_words(key, electrum_words, "English");
}
return true;
--
2.48.1
+986
View File
@@ -0,0 +1,986 @@
From ff70c74c8b331758ace1f14df0ca107731dda49d Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 10:09:50 +0100
Subject: [PATCH 05/14] UR functions
This commit adds UR functions for UR tasks,
I believe that the right place to get
UR strings is the wallet code itself,
especially because it allows us to
skip the part when we have to store
things to file to encode them later.
Now we are fully in memory
Things broken in the commit
- ledger support.
AUTO_LOCK_CMD macro causes compile time
issues with this patch. I don't know why
just yet, this is a issue that I'll fix
later. However (considering the purpose
of this patch) it is not a dealbreaker.
---
.gitmodules | 4 +
CMakeLists.txt | 4 +-
external/CMakeLists.txt | 1 +
external/bc-ur | 1 +
src/device/device_ledger.cpp | 5 +-
src/wallet/CMakeLists.txt | 1 +
src/wallet/api/pending_transaction.cpp | 33 +++
src/wallet/api/pending_transaction.h | 1 +
src/wallet/api/unsigned_transaction.cpp | 42 ++++
src/wallet/api/unsigned_transaction.h | 1 +
src/wallet/api/wallet.cpp | 309 +++++++++++++++++++++++-
src/wallet/api/wallet.h | 8 +
src/wallet/api/wallet2_api.h | 22 +-
src/wallet/wallet2.cpp | 141 +++++++----
src/wallet/wallet2.h | 3 +
15 files changed, 519 insertions(+), 57 deletions(-)
create mode 160000 external/bc-ur
diff --git a/.gitmodules b/.gitmodules
index ffb73fe9a..72af74d55 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -11,6 +11,10 @@
path = external/supercop
url = https://github.com/monero-project/supercop
branch = monero
+[submodule "external/bc-ur"]
+ path = external/bc-ur
+ url = https://github.com/MrCyjaneK/bc-ur
+ branch = misc
[submodule "external/miniupnp"]
path = external/miniupnp
url = https://github.com/miniupnp/miniupnp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index db69b1b04..c73b813d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -100,6 +100,7 @@ enable_language(C ASM)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 17)
+add_definitions(-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) # boost: no template named 'unary_function' in namespace 'std'; did you mean '__unary_function'?
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
@@ -367,6 +368,7 @@ if(NOT MANUAL_SUBMODULES)
endfunction ()
message(STATUS "Checking submodules")
+# check_submodule(external/bc-ur)
check_submodule(external/miniupnp)
check_submodule(external/rapidjson)
check_submodule(external/trezor-common)
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index 538e4d215..074e23f16 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -69,4 +69,5 @@ endif()
add_subdirectory(db_drivers)
add_subdirectory(easylogging++)
add_subdirectory(qrcodegen)
+add_subdirectory(bc-ur)
add_subdirectory(randomx EXCLUDE_FROM_ALL)
diff --git a/external/bc-ur b/external/bc-ur
new file mode 160000
index 000000000..d82e7c753
--- /dev/null
+++ b/external/bc-ur
@@ -0,0 +1,1 @@
+Subproject commit d82e7c753e710b8000706dc3383b498438795208
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index 6095f99d5..b163212b7 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -50,6 +50,7 @@ monero_add_library(wallet
target_link_libraries(wallet
PUBLIC
rpc_base
+ bc-ur
multisig
carrot_impl
common
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
index 70a702796..9c3c26ee5 100644
--- a/src/wallet/api/pending_transaction.cpp
+++ b/src/wallet/api/pending_transaction.cpp
@@ -42,6 +42,8 @@
#include <boost/format.hpp>
#include <boost/filesystem.hpp>
+#include "bc-ur/src/bc-ur.hpp"
+
using namespace std;
namespace Monero {
@@ -162,6 +164,37 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
return m_status == Status_Ok;
}
+std::string PendingTransactionImpl::commitUR(int max_fragment_length) {
+
+ LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size());
+
+ try {
+ std::string ptx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx);
+ m_status = Status_Ok;
+ auto urMessage = ur::string_to_bytes(ptx);
+ ur::ByteVector cbor;
+ ur::CborLite::encodeBytes(cbor, urMessage);
+ std::string type;
+ if (m_wallet.watchOnly()) {
+ type = "xmr-txunsigned";
+ } else {
+ type = "xmr-txsigned";
+ }
+ ur::UR urData = ur::UR(type, cbor);
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
+ std::string output;
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
+ output.append("\n"+encoder.next_part());
+ }
+ return output;
+ } catch (const std::exception &e) {
+ m_errorString = string(tr("Unknown exception: ")) + e.what();
+ m_status = Status_Error;
+ return "";
+ }
+}
+
+
uint64_t PendingTransactionImpl::amount() const
{
uint64_t result = 0;
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
index 0a9779c07..403bfe281 100644
--- a/src/wallet/api/pending_transaction.h
+++ b/src/wallet/api/pending_transaction.h
@@ -46,6 +46,7 @@ public:
int status() const override;
std::string errorString() const override;
bool commit(const std::string &filename = "", bool overwrite = false) override;
+ std::string commitUR(int max_fragment_length = 130) override;
uint64_t amount() const override;
uint64_t dust() const override;
uint64_t fee() const override;
diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp
index 6165a2240..fd03e959d 100644
--- a/src/wallet/api/unsigned_transaction.cpp
+++ b/src/wallet/api/unsigned_transaction.cpp
@@ -40,6 +40,8 @@
#include <sstream>
#include <boost/format.hpp>
+#include "bc-ur/src/bc-ur.hpp"
+
using namespace std;
namespace Monero {
@@ -96,6 +98,46 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName)
return true;
}
+std::string UnsignedTransactionImpl::signUR(int max_fragment_length)
+{
+ if(m_wallet.watchOnly())
+ {
+ m_errorString = tr("This is a watch only wallet");
+ m_status = Status_Error;
+ return "";
+ }
+ std::vector<tools::wallet2::pending_tx> ptx;
+ try
+ {
+ tools::wallet2::signed_tx_set signed_txes;
+ std::string signedTx = m_wallet.m_wallet->sign_tx_dump_to_str(m_unsigned_tx_set, ptx, signed_txes);
+ if (signedTx.empty())
+ {
+ m_errorString = tr("Failed to sign transaction");
+ m_status = Status_Error;
+ return "";
+ }
+ auto urMessage = ur::string_to_bytes(signedTx);
+ ur::ByteVector cbor;
+ ur::CborLite::encodeBytes(cbor, urMessage);
+ std::string type = "xmr-txsigned";
+ ur::UR urData = ur::UR(type, cbor);
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
+ std::string output;
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
+ output.append("\n"+encoder.next_part());
+ }
+ return output;
+ }
+ catch (const std::exception &e)
+ {
+ m_errorString = string(tr("Failed to sign transaction")) + e.what();
+ m_status = Status_Error;
+ return "";
+ }
+ return "";
+}
+
//----------------------------------------------------------------------------------------------------
bool UnsignedTransactionImpl::checkLoadedTx(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)
{
diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h
index 30065a7fa..a94b23f75 100644
--- a/src/wallet/api/unsigned_transaction.h
+++ b/src/wallet/api/unsigned_transaction.h
@@ -53,6 +53,7 @@ public:
uint64_t txCount() const override;
// sign txs and save to file
bool sign(const std::string &signedFileName) override;
+ std::string signUR(int max_fragment_length = 130) override;
std::string confirmationMessage() const override {return m_confirmationMessage;}
uint64_t minMixinCount() const override;
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 89df5c517..3fcd6f332 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -48,6 +48,7 @@
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>
+#include "bc-ur/src/bc-ur.hpp"
using namespace std;
using namespace cryptonote;
@@ -961,6 +962,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const
return m_wallet->unlocked_balance(accountIndex, asset, false);
}
+uint64_t WalletImpl::viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images, const std::string& asset) const
+{
+ clearStatus();
+
+ std::vector<crypto::key_image> kis;
+ for (const auto &key_image : key_images) {
+ crypto::key_image ki;
+ if (!epee::string_tools::hex_to_pod(key_image, ki))
+ {
+ setStatusError(tr("failed to parse key image"));
+ return 0;
+ }
+ kis.push_back(ki);
+ }
+
+ return m_wallet->view_only_balance(accountIndex, kis, asset);
+}
+
uint64_t WalletImpl::blockChainHeight() const
{
return m_wallet->get_blockchain_current_height();
@@ -1139,6 +1158,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return transaction;
}
+
+UnsignedTransaction *WalletImpl::loadUnsignedTxUR(const std::string &input) {
+ clearStatus();
+ UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this);
+ auto decoder = ur::URDecoder();
+
+ std::string delimiter = "\n";
+ std::string inp = input;
+ size_t pos = 0;
+ std::string token;
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
+ token = inp.substr(0, pos);
+ decoder.receive_part(token);
+ inp.erase(0, pos + delimiter.length());
+ }
+ decoder.receive_part(inp);
+
+ if (decoder.is_failure()) {
+ setStatusError(decoder.result_error().what());
+ transaction->m_status = UnsignedTransaction::Status::Status_Error;
+ transaction->m_errorString = errorString();
+ return transaction;
+ }
+
+ if (!decoder.is_complete()) {
+ setStatusError("file ended but ur didn't complete");
+ transaction->m_status = UnsignedTransaction::Status::Status_Error;
+ transaction->m_errorString = errorString();
+ return transaction;
+ }
+
+ std::string data;
+ auto cbor = decoder.result_ur().cbor();
+ auto i = cbor.begin();
+ auto end = cbor.end();
+ ur::CborLite::decodeBytes(i, end, data);
+
+ if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){
+ setStatusError(tr("Failed to load unsigned transactions"));
+ transaction->m_status = UnsignedTransaction::Status::Status_Error;
+ transaction->m_errorString = errorString();
+
+ return transaction;
+ }
+
+ // Check tx data and construct confirmation message
+ std::string extra_message;
+ if (!std::get<2>(transaction->m_unsigned_tx_set.transfers).empty())
+ extra_message = (boost::format("%u outputs to import. ") % (unsigned)std::get<2>(transaction->m_unsigned_tx_set.transfers).size()).str();
+ transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message);
+ setStatus(transaction->status(), transaction->errorString());
+
+ return transaction;
+}
+
bool WalletImpl::submitTransaction(const string &fileName) {
clearStatus();
if (checkBackgroundSync("cannot submit tx"))
@@ -1159,6 +1233,61 @@ bool WalletImpl::submitTransaction(const string &fileName) {
return true;
}
+
+bool WalletImpl::submitTransactionUR(const string &input) {
+ clearStatus();
+ auto decoder = ur::URDecoder();
+
+ std::string delimiter = "\n";
+ std::string inp = input;
+ size_t pos = 0;
+ std::string token;
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
+ token = inp.substr(0, pos);
+ decoder.receive_part(token);
+ inp.erase(0, pos + delimiter.length());
+ }
+ decoder.receive_part(inp);
+
+ if (decoder.is_failure()) {
+ setStatusError(decoder.result_error().what());
+ return false;
+ }
+
+ if (!decoder.is_complete()) {
+ setStatusError("file ended but ur didn't complete");
+ return false;
+ }
+
+ std::string data;
+ auto cbor = decoder.result_ur().cbor();
+ auto i = cbor.begin();
+ auto end = cbor.end();
+ ur::CborLite::decodeBytes(i, end, data);
+ if (checkBackgroundSync("cannot submit tx"))
+ return false;
+ std::unique_ptr<PendingTransactionImpl> transaction(new PendingTransactionImpl(*this));
+
+ bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL);
+ if (!r) {
+ setStatus(Status_Ok, tr("Failed to load transaction from file"));
+ return false;
+ }
+
+ if(!transaction->commit()) {
+ setStatusError(transaction->m_errorString);
+ return false;
+ }
+
+ return true;
+}
+
+
+bool WalletImpl::hasUnknownKeyImages() const
+{
+ return m_wallet->has_unknown_key_images();
+}
+
bool WalletImpl::exportKeyImages(const string &filename, bool all)
{
if (m_wallet->watch_only())
@@ -1186,6 +1318,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
return true;
}
+std::string WalletImpl::exportKeyImagesUR(size_t max_fragment_length, bool all)
+{
+ if (m_wallet->watch_only())
+ {
+ setStatusError(tr("Wallet is view only"));
+ return "";
+ }
+ if (checkBackgroundSync("cannot export key images"))
+ return "";
+
+ try
+ {
+ std::string keyImages = m_wallet->export_key_images_str(all);
+ auto urMessage = ur::string_to_bytes(keyImages);
+ ur::ByteVector cbor;
+ ur::CborLite::encodeBytes(cbor, urMessage);
+ ur::UR urData = ur::UR("xmr-keyimage", cbor);
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
+ std::string output;
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
+ output.append("\n"+encoder.next_part());
+ }
+ return output;
+ }
+ catch (const std::exception &e)
+ {
+ LOG_ERROR("Error exporting key images: " << e.what());
+ setStatusError(e.what());
+ return "";
+ }
+ return "";
+}
+
bool WalletImpl::importKeyImages(const string &filename)
{
if (checkBackgroundSync("cannot import key images"))
@@ -1211,6 +1373,62 @@ bool WalletImpl::importKeyImages(const string &filename)
return true;
}
+
+bool WalletImpl::importKeyImagesUR(const string &input)
+{
+ if (checkBackgroundSync("cannot import key images"))
+ return false;
+ if (!trustedDaemon()) {
+ setStatusError(tr("Key images can only be imported with a trusted daemon"));
+ return false;
+ }
+ try
+ {
+ auto decoder = ur::URDecoder();
+ std::string delimiter = "\n";
+ std::string inp = input;
+ size_t pos = 0;
+ std::string token;
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
+ token = inp.substr(0, pos);
+ decoder.receive_part(token);
+ inp.erase(0, pos + delimiter.length());
+ }
+ decoder.receive_part(inp);
+
+ if (decoder.is_failure()) {
+ setStatusError(decoder.result_error().what());
+ return false;
+ }
+
+ if (!decoder.is_complete()) {
+ setStatusError("file ended but ur didn't complete");
+ return false;
+ }
+
+ std::string data;
+ auto cbor = decoder.result_ur().cbor();
+ auto i = cbor.begin();
+ auto end = cbor.end();
+ ur::CborLite::decodeBytes(i, end, data);
+
+ uint64_t spent = 0, unspent = 0;
+
+ uint64_t height = m_wallet->import_key_images_str(data, spent, unspent);
+ LOG_PRINT_L2("Signed key images imported to height " << height << ", "
+ << print_money(spent) << " spent, " << print_money(unspent) << " unspent");
+ }
+ catch (const std::exception &e)
+ {
+ LOG_ERROR("Error exporting key images: " << e.what());
+ setStatusError(string(tr("Failed to import key images: ")) + e.what());
+ return false;
+ }
+
+ return true;
+}
+
+
bool WalletImpl::exportOutputs(const string &filename, bool all)
{
if (checkBackgroundSync("cannot export outputs"))
@@ -1243,6 +1461,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
return true;
}
+std::string WalletImpl::exportOutputsUR(size_t max_fragment_length, bool all)
+{
+
+ if (checkBackgroundSync("cannot export outputs"))
+ return "";
+ if (m_wallet->key_on_device())
+ {
+ setStatusError(string(tr("Not supported on HW wallets.")));
+ return "";
+ }
+
+ try
+ {
+ std::string data = m_wallet->export_outputs_to_str(all);
+ auto urMessage = ur::string_to_bytes(data);
+ ur::ByteVector cbor;
+ ur::CborLite::encodeBytes(cbor, urMessage);
+ ur::UR urData = ur::UR("xmr-output", cbor);
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
+ std::string output;
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
+ output.append("\n"+encoder.next_part());
+ }
+ return output;
+ }
+ catch (const std::exception &e)
+ {
+ LOG_ERROR("Error exporting outputs: " << e.what());
+ setStatusError(string(tr("Error exporting outputs: ")) + e.what());
+ return "";
+ }
+}
+
+
bool WalletImpl::importOutputs(const string &filename)
{
if (checkBackgroundSync("cannot import outputs"))
@@ -1277,6 +1529,61 @@ bool WalletImpl::importOutputs(const string &filename)
return true;
}
+
+bool WalletImpl::importOutputsUR(const string &input)
+{
+ if (checkBackgroundSync("cannot import outputs"))
+ return false;
+ if (m_wallet->key_on_device())
+ {
+ setStatusError(string(tr("Not supported on HW wallets.")));
+ return false;
+ }
+
+ try
+ {
+ auto decoder = ur::URDecoder();
+
+ std::string delimiter = "\n";
+ std::string inp = input;
+ size_t pos = 0;
+ std::string token;
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
+ token = inp.substr(0, pos);
+ decoder.receive_part(token);
+ inp.erase(0, pos + delimiter.length());
+ }
+ decoder.receive_part(inp);
+
+ if (decoder.is_failure()) {
+ setStatusError(decoder.result_error().what());
+ return false;
+ }
+
+ if (!decoder.is_complete()) {
+ setStatusError("file ended but ur didn't complete");
+ return false;
+ }
+
+ std::string data;
+ auto cbor = decoder.result_ur().cbor();
+ auto i = cbor.begin();
+ auto end = cbor.end();
+ ur::CborLite::decodeBytes(i, end, data);
+ size_t n_outputs = m_wallet->import_outputs_from_str(std::string(data));
+ LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported");
+ }
+ catch (const std::exception &e)
+ {
+ LOG_ERROR("Failed to import outputs: " << e.what());
+ setStatusError(string(tr("Failed to import outputs: ")) + e.what());
+ return false;
+ }
+
+ return true;
+}
+
+
bool WalletImpl::scanTransactions(const std::vector<std::string> &txids)
{
if (checkBackgroundSync("cannot scan transactions"))
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index ac7ce2f6a..edf8bb8ce 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -113,6 +113,7 @@ public:
bool setProxy(const std::string &address) override;
uint64_t balance(const std::string& asset, uint32_t accountIndex = 0) const override;
uint64_t unlockedBalance(const std::string& asset, uint32_t accountIndex = 0) const override;
+ uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images, const std::string& asset = "SAL1") const override;
uint64_t blockChainHeight() const override;
uint64_t approximateBlockChainHeight() const override;
uint64_t estimateBlockChainHeight() const override;
@@ -177,11 +178,18 @@ public:
std::set<uint32_t> subaddr_indices = {}) override;
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
+ bool submitTransactionUR(const std::string &input) override;
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
+ virtual UnsignedTransaction * loadUnsignedTxUR(const std::string &input) override;
+ bool hasUnknownKeyImages() const override;
bool exportKeyImages(const std::string &filename, bool all = false) override;
+ std::string exportKeyImagesUR(size_t max_fragment_length, bool all = false) override;
bool importKeyImages(const std::string &filename) override;
+ bool importKeyImagesUR(const std::string &input) override;
bool exportOutputs(const std::string &filename, bool all = false) override;
+ std::string exportOutputsUR(size_t max_fragment_length, bool all) override;
bool importOutputs(const std::string &filename) override;
+ bool importOutputsUR(const std::string &filename) override;
bool scanTransactions(const std::vector<std::string> &txids) override;
bool setupBackgroundSync(const BackgroundSyncType background_sync_type, const std::string &wallet_password, const optional<std::string> &background_cache_password = optional<std::string>()) override;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index e349df176..764adbfbf 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -92,6 +92,7 @@ struct PendingTransaction
virtual std::string errorString() const = 0;
// commit transaction or save to file if filename is provided.
virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0;
+ virtual std::string commitUR(int max_fragment_length = 130) = 0;
virtual uint64_t amount() const = 0;
virtual uint64_t dust() const = 0;
virtual uint64_t fee() const = 0;
@@ -195,7 +196,8 @@ struct UnsignedTransaction
* @param signedFileName
* return - true on success
*/
- virtual bool sign(const std::string &signedFileName) = 0;
+ virtual bool sign(const std::string &signedFileName) = 0;
+ virtual std::string signUR(int max_fragment_length = 130) = 0;
};
/**
@@ -668,6 +670,7 @@ struct Wallet
result += unlockedBalance(asset, i);
return result;
}
+ virtual uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images = {}, const std::string& asset = "SAL1") const = 0;
/**
* @brief watchOnly - checks if wallet is watch only
@@ -965,13 +968,15 @@ struct Wallet
* after object returned
*/
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
-
- /*!
+ virtual UnsignedTransaction * loadUnsignedTxUR(const std::string &input) = 0;
+
+ /*!
* \brief submitTransaction - submits transaction in signed tx file
* \return - true on success
*/
virtual bool submitTransaction(const std::string &fileName) = 0;
-
+ virtual bool submitTransactionUR(const std::string &input) = 0;
+
/*!
* \brief disposeTransaction - destroys transaction object
@@ -987,6 +992,8 @@ struct Wallet
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
PendingTransaction::Priority priority) const = 0;
+ virtual bool hasUnknownKeyImages() const = 0;
+
/*!
* \brief exportKeyImages - exports key images to file
* \param filename
@@ -994,20 +1001,22 @@ struct Wallet
* \return - true on success
*/
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
-
+ virtual std::string exportKeyImagesUR(size_t max_fragment_length, bool all = false) = 0;
/*!
* \brief importKeyImages - imports key images from file
* \param filename
* \return - true on success
*/
virtual bool importKeyImages(const std::string &filename) = 0;
+ virtual bool importKeyImagesUR(const std::string &input) = 0;
/*!
- * \brief importOutputs - exports outputs to file
+ * \brief exportOutputs - exports outputs to file
* \param filename
* \return - true on success
*/
virtual bool exportOutputs(const std::string &filename, bool all = false) = 0;
+ virtual std::string exportOutputsUR(size_t max_fragment_length, bool all = false) = 0;
/*!
* \brief importOutputs - imports outputs from file
@@ -1015,6 +1024,7 @@ struct Wallet
* \return - true on success
*/
virtual bool importOutputs(const std::string &filename) = 0;
+ virtual bool importOutputsUR(const std::string &filename) = 0;
/*!
* \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 b827b826f..765cefb32 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -945,6 +945,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
return idx + extra;
}
+bool is_preferred_input(const std::vector<crypto::key_image>& preferred_input_list, const crypto::key_image& input) {
+ if (!preferred_input_list.empty()) {
+ auto it = std::find(preferred_input_list.begin(), preferred_input_list.end(), input);
+ if (it == preferred_input_list.end()) {
+ return false;
+ }
+ }
+ return true;
+}
+
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);
@@ -7088,6 +7098,29 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, const std::string& asse
return amount;
}
//----------------------------------------------------------------------------------------------------
+uint64_t wallet2::view_only_balance(uint32_t index_major, const std::vector<crypto::key_image>& selected_inputs, const std::string& asset_type)
+{
+ uint64_t amount = 0;
+ if (m_transfers_indices.count(asset_type) > 0) {
+ for (const auto& idx: m_transfers_indices.at(asset_type))
+ {
+ const transfer_details& td = m_transfers[idx];
+ if (is_preferred_input(selected_inputs, td.m_key_image) &&
+ !is_spent(td, false) &&
+ !td.m_frozen &&
+ !td.m_key_image_partial &&
+ td.m_key_image_known &&
+ td.is_rct() &&
+ is_transfer_unlocked(td) &&
+ td.m_subaddr_index.major == index_major)
+ {
+ amount += td.m_amount;
+ }
+ }
+ }
+ return amount;
+}
+//----------------------------------------------------------------------------------------------------
std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_major, const std::string& asset_type, bool strict) const
{
std::map<uint32_t, uint64_t> amount_per_subaddr;
@@ -7963,9 +7992,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;
- // compute public keys from out secret keys
- crypto::public_key tx_pub_key;
- crypto::secret_key_to_public_key(txs[n].tx_key, tx_pub_key);
+ crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
std::vector<crypto::public_key> additional_tx_pub_keys;
for (const crypto::secret_key &skey: txs[n].additional_tx_keys)
{
@@ -10880,7 +10907,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
continue;
}
- if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
+ if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && td.m_key_image_known && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
{
if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
{
@@ -10930,9 +10957,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Starting with " << num_nondust_outputs << " non-dust outputs and " << num_dust_outputs << " dust outputs");
- if (unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty())
- return std::vector<wallet2::pending_tx>();
+ // use tobotoht's code path on view-only wallet, otherwise default to upstream
+ bool throwOnNoEnotes = m_account.get_device().device_protocol() == hw::device::PROTOCOL_COLD || m_watch_only || m_multisig || m_is_background_wallet;
+ if (throwOnNoEnotes) {
+ THROW_WALLET_EXCEPTION_IF(unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty(), error::wallet_internal_error, "No enotes available to spend")
+ } else {
+ if (unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty())
+ return std::vector<wallet2::pending_tx>();
+ }
// if empty, put dummy entry so that the front can be referenced later in the loop
if (unused_dust_indices_per_subaddr.empty())
unused_dust_indices_per_subaddr.push_back({});
@@ -13742,33 +13775,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
{
- PERF_TIMER(export_key_images);
- std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(all);
- std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
- const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
- const uint32_t offset = ski.first;
+ std::string data = export_key_images_str(all);
+ return save_to_file(filename, data);
+}
- std::string data;
- data.reserve(4 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)) + 2 * sizeof(crypto::public_key));
- data.resize(4);
- data[0] = offset & 0xff;
- data[1] = (offset >> 8) & 0xff;
- data[2] = (offset >> 16) & 0xff;
- data[3] = (offset >> 24) & 0xff;
- data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
- data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
- for (const auto &i: ski.second)
- {
- data += std::string((const char *)&i.first, sizeof(crypto::key_image));
- data += std::string((const char *)&i.second, sizeof(crypto::signature));
- }
+std::string wallet2::export_key_images_str(bool all) const
+{
+ PERF_TIMER(export_key_images);
+ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(all);
+ std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
+ const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
+ const uint32_t offset = ski.first;
- // encrypt data, keep magic plaintext
- PERF_TIMER(export_key_images_encrypt);
- std::string ciphertext = encrypt_with_view_secret_key(data);
- return save_to_file(filename, magic + ciphertext);
+ std::string data;
+ data.reserve(4 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)) + 2 * sizeof(crypto::public_key));
+ data.resize(4);
+ data[0] = offset & 0xff;
+ data[1] = (offset >> 8) & 0xff;
+ data[2] = (offset >> 16) & 0xff;
+ data[3] = (offset >> 24) & 0xff;
+ data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
+ data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
+ for (const auto &i: ski.second)
+ {
+ data += std::string((const char *)&i.first, sizeof(crypto::key_image));
+ data += std::string((const char *)&i.second, sizeof(crypto::signature));
+ }
+
+ // encrypt data, keep magic plaintext
+ PERF_TIMER(export_key_images_encrypt);
+ std::string ciphertext = encrypt_with_view_secret_key(data);
+ return magic + ciphertext;
}
+
//----------------------------------------------------------------------------------------------------
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> wallet2::export_key_images(bool all) const
{
@@ -13828,53 +13868,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
return std::make_pair(offset, ski);
}
-uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent)
+uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent) {
+ std::string data;
+
+ bool r = load_from_file(filename, data);
+
+ THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
+
+ return import_key_images_str(data, spent, unspent);
+}
+
+uint64_t wallet2::import_key_images_str(const std::string &data, uint64_t &spent, uint64_t &unspent)
{
PERF_TIMER(import_key_images_fsu);
- std::string data;
- bool r = load_from_file(filename, data);
-
- THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
+ std::string data_local = data;
const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC);
if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen))
{
- THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename);
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic"));
}
try
{
PERF_TIMER(import_key_images_decrypt);
- data = decrypt_with_view_secret_key(std::string(data, magiclen));
+ data_local = decrypt_with_view_secret_key(std::string(data, magiclen));
}
catch (const std::exception &e)
{
- THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what());
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + ": " + e.what());
}
const size_t headerlen = 4 + 2 * sizeof(crypto::public_key);
- THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename);
- const uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24);
- const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4];
- const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)];
+ THROW_WALLET_EXCEPTION_IF(data_local.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file "));
+ const uint32_t offset = (uint8_t)data_local[0] | (((uint8_t)data_local[1]) << 8) | (((uint8_t)data_local[2]) << 16) | (((uint8_t)data_local[3]) << 24);
+ const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data_local[4];
+ const crypto::public_key &public_view_key = *(const crypto::public_key*)&data_local[4 + sizeof(crypto::public_key)];
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key)
{
- THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account");
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + " are for a different account");
}
THROW_WALLET_EXCEPTION_IF(offset > m_transfers.size(), error::wallet_internal_error, "Offset larger than known outputs");
const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature);
- THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size,
- error::wallet_internal_error, std::string("Bad data size from file ") + filename);
- size_t nki = (data.size() - headerlen) / record_size;
+ THROW_WALLET_EXCEPTION_IF((data_local.size() - headerlen) % record_size,
+ error::wallet_internal_error, std::string("Bad data size from file "));
+ size_t nki = (data_local.size() - headerlen) / record_size;
std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
ski.reserve(nki);
for (size_t n = 0; n < nki; ++n)
{
- crypto::key_image key_image = *reinterpret_cast<const crypto::key_image*>(&data[headerlen + n * record_size]);
- crypto::signature signature = *reinterpret_cast<const crypto::signature*>(&data[headerlen + n * record_size + sizeof(crypto::key_image)]);
+ crypto::key_image key_image = *reinterpret_cast<const crypto::key_image*>(&data_local[headerlen + n * record_size]);
+ crypto::signature signature = *reinterpret_cast<const crypto::signature*>(&data_local[headerlen + n * record_size + sizeof(crypto::key_image)]);
ski.push_back(std::make_pair(key_image, signature));
}
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index daad1e940..a752f15b9 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1112,6 +1112,7 @@ private:
// locked & unlocked balance of given or current subaddress account
uint64_t balance(uint32_t subaddr_index_major, const std::string& asset_type, bool strict) const;
uint64_t unlocked_balance(uint32_t subaddr_index_major, const std::string& asset_type, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL);
+ uint64_t view_only_balance(uint32_t index_major, const std::vector<crypto::key_image>& selected_inputs = {}, const std::string& asset_type = "SAL1");
// locked & unlocked balance per subaddress of given or current subaddress account
std::map<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, const std::string& asset_type, 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, const std::string& asset_type, bool strict);
@@ -1596,9 +1597,11 @@ private:
std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> export_blockchain() const;
void import_blockchain(const std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> &bc);
bool export_key_images(const std::string &filename, bool all = false) const;
+ std::string export_key_images_str(bool all) const;
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> export_key_images(bool all = false) const;
uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true);
uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent);
+ uint64_t import_key_images_str(const std::string &data, uint64_t &spent, uint64_t &unspent);
bool import_key_images(std::vector<crypto::key_image> key_images, size_t offset=0, boost::optional<std::unordered_set<size_t>> selected_transfers=boost::none);
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
--
2.48.1
@@ -0,0 +1,661 @@
From 11ddba5ab1470fb46a87ea9b702bf11f88763ecc Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 8 May 2025 13:14:23 +0200
Subject: [PATCH 06/17] add dummy device for ledger
---
CMakeLists.txt | 6 +-
external/randomx | 2 +-
src/device/CMakeLists.txt | 6 +-
src/device/device.cpp | 10 +-
src/device/device.hpp | 12 +--
src/device/device_io_dummy.cpp | 161 ++++++++++++++++++++++++++++++
src/device/device_io_dummy.hpp | 82 +++++++++++++++
src/device/device_ledger.cpp | 6 +-
src/device/device_ledger.hpp | 7 +-
src/wallet/api/wallet.cpp | 100 +++++++++++++++++++
src/wallet/api/wallet.h | 14 +++
src/wallet/api/wallet2_api.h | 13 +++
src/wallet/api/wallet_manager.cpp | 12 ++-
13 files changed, 405 insertions(+), 26 deletions(-)
create mode 100644 src/device/device_io_dummy.cpp
create mode 100644 src/device/device_io_dummy.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c73b813d8..ce5ef4bab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -692,16 +692,21 @@ include_directories(${LMDB_INCLUDE})
include_directories(${LIBUNWIND_INCLUDE})
link_directories(${LIBUNWIND_LIBRARY_DIRS})
-# Final setup for hid
-if (HIDAPI_FOUND)
- message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
- add_definitions(-DHAVE_HIDAPI)
- include_directories(${HIDAPI_INCLUDE_DIR})
- link_directories(${LIBHIDAPI_LIBRARY_DIRS})
+if (HIDAPI_DUMMY)
+ add_definitions(-DHIDAPI_DUMMY)
else()
- message(STATUS "Could not find HIDAPI")
+ # Final setup for hid
+ if (HIDAPI_FOUND)
+ message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
+ add_definitions(-DHAVE_HIDAPI)
+ include_directories(${HIDAPI_INCLUDE_DIR})
+ link_directories(${LIBHIDAPI_LIBRARY_DIRS})
+ else()
+ message(STATUS "Could not find HIDAPI")
+ endif()
endif()
+
# Trezor support check
include(CheckTrezor)
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
index e4f1159b5..14d398f87 100644
--- a/src/device/CMakeLists.txt
+++ b/src/device/CMakeLists.txt
@@ -29,10 +29,11 @@
set(device_sources
device.cpp
device_default.cpp
+ device_io_dummy.cpp
log.cpp
)
-if(HIDAPI_FOUND)
+if(HIDAPI_FOUND OR HIDAPI_DUMMY)
set(device_sources
${device_sources}
device_ledger.cpp
@@ -45,10 +46,11 @@ set(device_headers
device_io.hpp
device_default.hpp
device_cold.hpp
+ device_io_dummy.hpp
log.hpp
)
-if(HIDAPI_FOUND)
+if(HIDAPI_FOUND OR HIDAPI_DUMMY)
set(device_headers
${device_headers}
device_ledger.hpp
diff --git a/src/device/device.cpp b/src/device/device.cpp
index e6cd358b6..dd0701e0c 100644
--- a/src/device/device.cpp
+++ b/src/device/device.cpp
@@ -29,7 +29,7 @@
#include "device.hpp"
#include "device_default.hpp"
-#ifdef WITH_DEVICE_LEDGER
+#if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
#include "device_ledger.hpp"
#endif
#include "misc_log_ex.h"
@@ -57,7 +57,7 @@ namespace hw {
device_registry::device_registry(){
hw::core::register_all(registry);
- #ifdef WITH_DEVICE_LEDGER
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
hw::ledger::register_all(registry);
#endif
atexit(clear_device_registry);
@@ -83,11 +83,13 @@ namespace hw {
auto device = registry.find(device_descriptor_lookup);
if (device == registry.end()) {
- MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: ");
+ std::stringstream ss("Device not found in registry: '" + device_descriptor + "'. Known devices: ");
+ MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: \n");
for( const auto& sm_pair : registry ) {
+ ss << "\n- " + sm_pair.first;
MERROR(" - " << sm_pair.first);
}
- throw std::runtime_error("device not found: " + device_descriptor);
+ throw std::runtime_error("device not found: " + device_descriptor + "\n" + ss.str());
}
return *device->second;
}
diff --git a/src/device/device.hpp b/src/device/device.hpp
index 392703a24..ffd419779 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -34,17 +34,7 @@
#include "ringct/rctTypes.h"
#include "cryptonote_config.h"
-
-#ifndef USE_DEVICE_LEDGER
-#define USE_DEVICE_LEDGER 1
-#endif
-
-#if !defined(HAVE_HIDAPI)
-#undef USE_DEVICE_LEDGER
-#define USE_DEVICE_LEDGER 0
-#endif
-
-#if USE_DEVICE_LEDGER
+#if defined(HAVE_HIDAPI) || defined(HIDAPI_DUMMY)
#define WITH_DEVICE_LEDGER
#endif
diff --git a/src/device/device_io_dummy.cpp b/src/device/device_io_dummy.cpp
new file mode 100644
index 000000000..01e6fc7b7
--- /dev/null
+++ b/src/device/device_io_dummy.cpp
@@ -0,0 +1,161 @@
+// Copyright (c) 2017-2022, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// device_io_dummy
+// Main goal of device_io_dummy is to emulate a hw::io::device_io without the need to actually
+// connect a device.
+// Many operating systems do not support giving raw USB access to a process (android), or don't
+// support that at all (hi iOS), therefore other means of connection can be used, either USB
+// abstraction provided by the OS (monerujo), or BLE (also monerujo).
+// Monerujo implementation is written in Java, which makes it a nice fit for iOS, but makes the
+// code extremely unportable, so for this reason the code in here is written in CPP.
+// Data transport is made available in wallet2_api.h, so wallet developers can easily plug their
+// own USB/BLE/other transport layer.
+
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
+#include <boost/scope_exit.hpp>
+#include "log.hpp"
+#include "device_io_dummy.hpp"
+#include "device_ledger.hpp"
+
+
+bool hw::io::device_io_dummy::stateIsConnected = false;
+unsigned char* hw::io::device_io_dummy::sendToDevice = {};
+size_t hw::io::device_io_dummy::sendToDeviceLength = 0;
+unsigned char* hw::io::device_io_dummy::receivedFromDevice = {};
+size_t hw::io::device_io_dummy::receivedFromDeviceLength = 0;
+bool hw::io::device_io_dummy::waitsForDeviceSend = false;
+bool hw::io::device_io_dummy::waitsForDeviceReceive = false;
+void (*hw::io::device_io_dummy::sendToLedgerDeviceCallback)(unsigned char *command, unsigned int cmd_len) = nullptr;
+std::mutex hw::io::device_io_dummy::mutex;
+std::condition_variable hw::io::device_io_dummy::cv_send;
+std::condition_variable hw::io::device_io_dummy::cv_receive;
+
+namespace hw {
+ namespace io {
+
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "device.io_dummy"
+ device_io_dummy::device_io_dummy(int a, int b, int c, int d) {
+ MDEBUG("device_io_dummy(a: " << a << ", b: " << b << ", c: " << c << ", d: " << d <<")");
+ }
+
+ void device_io_dummy::init() {
+ MDEBUG("init()");
+ }
+
+ void device_io_dummy::connect(void *params) {
+ MDEBUG("connect(" << params << ")");
+ stateIsConnected = true;
+ }
+
+ void device_io_dummy::connect(const std::vector<hw::io::hid_conn_params>& known_devices) {
+ MDEBUG("connect([");
+ for (const auto &item: known_devices) {
+ MDEBUG("{ interface_number: " << item.interface_number);
+ MDEBUG(" pid : " << item.pid);
+ MDEBUG(" usage_page : " << item.usage_page);
+ MDEBUG(" vid : " << item.vid << " },");
+ }
+ MDEBUG("])");
+ stateIsConnected = true;
+ }
+
+ bool device_io_dummy::connected() const {
+ MDEBUG("connected()");
+ return stateIsConnected;
+ }
+
+ int device_io_dummy::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) {
+ MDEBUG("exchange(): locking mutex");
+ std::unique_lock<std::mutex> lock(mutex);
+ sendToDevice = command;
+ sendToDeviceLength = cmd_len;
+ waitsForDeviceSend = true;
+ waitsForDeviceReceive = true;
+
+ // Call the callback if it's set
+ if (sendToLedgerDeviceCallback != nullptr) {
+ MDEBUG("exchange(): calling sendToLedgerDeviceCallback");
+ sendToLedgerDeviceCallback(command, cmd_len);
+ }
+ MDEBUG("exchange(): waitsForDeviceSend");
+ // Wait for the send flag to be cleared by external code
+ while (waitsForDeviceSend) {
+ cv_send.wait(lock);
+ MDEBUG("exchange(): waitsForDeviceSend notified");
+ }
+
+ MDEBUG("exchange(): waitsForDeviceReceive");
+ // Wait for the receive flag to be cleared by external code
+ while (waitsForDeviceReceive) {
+ cv_receive.wait(lock);
+ MDEBUG("exchange(): waitsForDeviceReceive notified");
+ }
+
+ if (receivedFromDeviceLength > max_resp_len) {
+ MDEBUG("exchange(): receivedFromDeviceLength ("<<receivedFromDeviceLength<<") is larger than max_resp_len ("<<max_resp_len<<")");
+ return 1;
+ }
+
+
+ memset(response, 0, max_resp_len);
+ memcpy(response, receivedFromDevice, receivedFromDeviceLength);
+ return receivedFromDeviceLength;
+ }
+
+ void device_io_dummy::disconnect() {
+ MDEBUG("disconnect()");
+ }
+
+ void device_io_dummy::release() {
+ MDEBUG("release()");
+ }
+
+ void device_io_dummy::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)) {
+ MDEBUG("setLedgerCallback()");
+ sendToLedgerDeviceCallback = sendToLedgerDevice;
+ }
+
+ void device_io_dummy::setDeviceReceivedData(unsigned char* data, size_t len) {
+ MDEBUG("setDeviceReceivedData(len: " << len << ")");
+ std::unique_lock<std::mutex> lock(mutex);
+
+ receivedFromDevice = static_cast<unsigned char *>(malloc(len));
+ receivedFromDeviceLength = len;
+ memset(receivedFromDevice, 0, len);
+ memcpy(receivedFromDevice, data, len);
+ waitsForDeviceReceive = false;
+ waitsForDeviceSend = false;
+ cv_send.notify_all();
+ cv_receive.notify_all();
+ }
+ }
+}
+#endif // HAVE_HIDAPI
\ No newline at end of file
diff --git a/src/device/device_io_dummy.hpp b/src/device/device_io_dummy.hpp
new file mode 100644
index 000000000..1128b9c1d
--- /dev/null
+++ b/src/device/device_io_dummy.hpp
@@ -0,0 +1,82 @@
+// Copyright (c) 2017-2022, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+#ifdef HIDAPI_DUMMY
+
+#pragma once
+
+#include "device_io.hpp"
+#include "device_io_hid.hpp"
+#include <mutex>
+#include <condition_variable>
+
+namespace hw {
+ namespace io {
+ struct hid_conn_params {
+ unsigned int vid;
+ unsigned int pid;
+ int interface_number;
+ unsigned short usage_page;
+ };
+ class device_io_dummy : device_io {
+ private:
+ static std::mutex mutex;
+
+ public:
+ static std::condition_variable cv_send;
+ static std::condition_variable cv_receive;
+ static bool stateIsConnected;
+ static unsigned char* sendToDevice;
+ static size_t sendToDeviceLength;
+ static unsigned char* receivedFromDevice;
+ static size_t receivedFromDeviceLength;
+ static bool waitsForDeviceSend;
+ static bool waitsForDeviceReceive;
+ static void (*sendToLedgerDeviceCallback)(unsigned char *command, unsigned int cmd_len);
+
+ device_io_dummy() = default;
+ device_io_dummy(int a, int b, int c, int d);
+ ~device_io_dummy() = default;
+
+ void init();
+ void release();
+
+ void connect(void *parms);
+ void connect(const std::vector<hw::io::hid_conn_params>& known_devices);
+ void disconnect();
+ bool connected() const;
+
+ int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input);
+
+ static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
+ static void setDeviceReceivedData(unsigned char* data, size_t len);
+ };
+ };
+};
+
+#endif // HAVE_HIDAPI
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index bb5b6f497..046201a1e 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -41,7 +41,7 @@ namespace hw {
namespace ledger {
- #ifdef WITH_DEVICE_LEDGER
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
namespace {
bool apdu_verbose =true;
@@ -299,7 +299,7 @@ namespace hw {
device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) {
this->id = device_id++;
- this->reset_buffer();
+ this->reset_buffer();
this->mode = NONE;
this->has_view_key = false;
this->tx_in_progress = false;
@@ -533,7 +533,9 @@ namespace hw {
bool device_ledger::connect(void) {
this->disconnect();
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
hw_device.connect(known_devices);
+ #endif
this->reset();
#ifdef DEBUG_HWDEVICE
cryptonote::account_public_address pubkey;
diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp
index 03058c4f1..39454ca6d 100644
--- a/src/device/device_ledger.hpp
+++ b/src/device/device_ledger.hpp
@@ -35,6 +35,7 @@
#include "device.hpp"
#include "log.hpp"
#include "device_io_hid.hpp"
+#include "device_io_dummy.hpp"
#include <mutex>
namespace hw {
@@ -56,7 +57,7 @@ namespace hw {
void register_all(std::map<std::string, std::unique_ptr<device>> &registry);
- #ifdef WITH_DEVICE_LEDGER
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
// Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h
#define SW_OK 0x9000
@@ -142,7 +143,11 @@ namespace hw {
mutable std::mutex command_locker;
//IO
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
+ hw::io::device_io_dummy hw_device;
+#else
hw::io::device_io_hid hw_device;
+#endif
unsigned int length_send;
unsigned char buffer_send[BUFFER_SEND_SIZE];
unsigned int length_recv;
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 3fcd6f332..844a1c451 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -49,6 +49,9 @@
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>
#include "bc-ur/src/bc-ur.hpp"
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
+#include "device/device_io_dummy.hpp"
+#endif
using namespace std;
using namespace cryptonote;
@@ -3178,6 +3181,103 @@ uint64_t WalletImpl::getBytesSent()
return m_wallet->get_bytes_sent();
}
+
+// HIDAPI_DUMMY
+bool Wallet::getStateIsConnected() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return false;
+ #else
+ return hw::io::device_io_dummy::stateIsConnected;
+ #endif
+}
+
+unsigned char* Wallet::getSendToDevice() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return {};
+ #else
+ return hw::io::device_io_dummy::sendToDevice;
+ #endif
+}
+
+size_t Wallet::getSendToDeviceLength() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return -1;
+ #else
+ return hw::io::device_io_dummy::sendToDeviceLength;
+ #endif
+}
+
+unsigned char* Wallet::getReceivedFromDevice() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return {};
+ #else
+ return hw::io::device_io_dummy::receivedFromDevice;
+ #endif
+}
+
+size_t Wallet::getReceivedFromDeviceLength() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return -1;
+ #else
+ return hw::io::device_io_dummy::receivedFromDeviceLength;
+ #endif
+}
+
+bool Wallet::getWaitsForDeviceSend() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return false;
+ #else
+ return hw::io::device_io_dummy::waitsForDeviceSend;
+ #endif
+}
+
+bool Wallet::getWaitsForDeviceReceive() {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return false;
+ #else
+ return hw::io::device_io_dummy::waitsForDeviceReceive;
+ #endif
+}
+
+void Wallet::setDeviceReceivedData(unsigned char* data, size_t len) {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return;
+ #else
+ hw::io::device_io_dummy::setDeviceReceivedData(data, len);
+ #endif
+}
+
+void Wallet::setDeviceSendData(unsigned char* data, size_t len) {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return;
+ #else
+ hw::io::device_io_dummy::sendToDevice = static_cast<unsigned char *>(malloc(len));
+ hw::io::device_io_dummy::sendToDeviceLength = len;
+ memset(hw::io::device_io_dummy::sendToDevice, 0, len);
+ memcpy(hw::io::device_io_dummy::sendToDevice, data, len);
+ hw::io::device_io_dummy::waitsForDeviceSend = false;
+ hw::io::device_io_dummy::cv_send.notify_all();
+ #endif
+}
+
+void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)) {
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
+ return;
+ #else
+ hw::io::device_io_dummy::setLedgerCallback(sendToLedgerDevice);
+ #endif
+}
+
YieldInfo * WalletImpl::getYieldInfo()
{
auto yi = new YieldInfoImpl(*this);
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index edf8bb8ce..6bfb61cb8 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -315,6 +315,20 @@ private:
// cache connection status to avoid unnecessary RPC calls
mutable std::atomic<bool> m_is_connected;
boost::optional<epee::net_utils::http::login> m_daemon_login{};
+
+ bool getStateIsConnected();
+
+ unsigned char *getSendToDevice();
+
+ size_t getSendToDeviceLength();
+
+ unsigned char *getReceivedFromDevice();
+
+ size_t getReceivedFromDeviceLength();
+
+ bool getWaitsForDeviceSend();
+
+ bool getWaitsForDeviceReceive();
};
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 764adbfbf..a48a6be54 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1231,6 +1231,19 @@ struct Wallet
//! get bytes sent
virtual uint64_t getBytesSent() = 0;
+
+ // HIDAPI_DUMMY
+ static bool getStateIsConnected();
+ static unsigned char* getSendToDevice();
+ static size_t getSendToDeviceLength();
+ static unsigned char* getReceivedFromDevice();
+ static size_t getReceivedFromDeviceLength();
+ static bool getWaitsForDeviceSend();
+ static bool getWaitsForDeviceReceive();
+
+ static void setDeviceReceivedData(unsigned char* data, size_t len);
+ static void setDeviceSendData(unsigned char* data, size_t len);
+ static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
//! get yield information
virtual YieldInfo * getYieldInfo() = 0;
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index e81b8f83a..277be6ac9 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -188,10 +188,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name,
bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const
{
- hw::device::device_type type;
- bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
- device_type = static_cast<Wallet::Device>(type);
- return r;
+ try {
+ hw::device::device_type type;
+ bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
+ device_type = static_cast<Wallet::Device>(type);
+ return r;
+ } catch (...) {
+ return false;
+ }
}
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
--
2.49.0
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,68 @@
From 0ba0339b11d8f7f66f2d5cd27075d438a76351b4 Mon Sep 17 00:00:00 2001
From: M <m@cakewallet.com>
Date: Fri, 21 Apr 2023 15:43:47 -0400
Subject: [PATCH 09/14] Add hex encoding and tx key getter for
PendingTransction in wallet api.
---
src/wallet/api/pending_transaction.cpp | 16 ++++++++++++++++
src/wallet/api/pending_transaction.h | 2 ++
src/wallet/api/wallet2_api.h | 2 ++
3 files changed, 20 insertions(+)
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
index 9c3c26ee5..1f714d229 100644
--- a/src/wallet/api/pending_transaction.cpp
+++ b/src/wallet/api/pending_transaction.cpp
@@ -80,6 +80,22 @@ std::vector<std::string> PendingTransactionImpl::txid() const
return txid;
}
+std::vector<std::string> PendingTransactionImpl::hex() const
+{
+ std::vector<std::string> hexs;
+ for (const auto &pt: m_pending_tx)
+ hexs.push_back(epee::string_tools::buff_to_hex_nodelimer(cryptonote::tx_to_blob(pt.tx)));
+ return hexs;
+}
+
+std::vector<std::string> PendingTransactionImpl::txKey() const
+{
+ std::vector<std::string> keys;
+ for (const auto& pt: m_pending_tx)
+ keys.push_back(epee::string_tools::pod_to_hex(pt.tx_key));
+ return keys;
+}
+
bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
{
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
index 403bfe281..0cc6c58e9 100644
--- a/src/wallet/api/pending_transaction.h
+++ b/src/wallet/api/pending_transaction.h
@@ -59,6 +59,8 @@ public:
std::string multisigSignData() override;
void signMultisigTx() override;
std::vector<std::string> signersKeys() const override;
+ std::vector<std::string> hex() const override;
+ std::vector<std::string> txKey() const override;
private:
friend class WalletImpl;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 013b5bcba..f421fdc05 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -127,6 +127,8 @@ struct PendingTransaction
* @return vector of base58-encoded signers' public keys
*/
virtual std::vector<std::string> signersKeys() const = 0;
+ virtual std::vector<std::string> hex() const = 0;
+ virtual std::vector<std::string> txKey() const = 0;
};
/**
--
2.48.1
@@ -0,0 +1,153 @@
From cb02355313d504e6a44f8f70b8eb2be64167ffd4 Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Wed, 11 Oct 2023 16:47:59 +0200
Subject: [PATCH 10/14] Add recoverDeterministicWalletFromSpendKey
This function is used by Cake Wallet to enable polyseed (dart implementation)
support.
Sourced from the following commit:
https://github.com/cake-tech/monero/commit/cb6fb5ab218878702ed151c0e3d5d68eb2732788
Co-authored-by: Godwin Asuquo <godilite@gmail.com>
---
src/wallet/api/wallet.cpp | 29 +++++++++++++++++++++++++++++
src/wallet/api/wallet.h | 4 ++++
src/wallet/api/wallet2_api.h | 19 +++++++++++++++++++
src/wallet/api/wallet_manager.cpp | 16 ++++++++++++++++
src/wallet/api/wallet_manager.h | 7 +++++++
5 files changed, 75 insertions(+)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 933cc2531..d8fe108b4 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -824,6 +824,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
return status() == Status_Ok;
}
+bool WalletImpl::recoverDeterministicWalletFromSpendKey(const std::string &path, const std::string &password, const std::string &language, const std::string &spendkey_string)
+{
+ clearStatus();
+ m_errorString.clear();
+
+ m_recoveringFromSeed = true;
+ m_recoveringFromDevice = false;
+
+ // parse spend key
+ crypto::secret_key spendkey;
+ if (!spendkey_string.empty()) {
+ cryptonote::blobdata spendkey_data;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key))
+ {
+ setStatusError(tr("failed to parse secret spend key"));
+ return false;
+ }
+ spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
+ }
+
+ try {
+ m_wallet->generate(path, password, spendkey, true, false);
+ setSeedLanguage(language);
+ } catch (const std::exception &e) {
+ setStatusCritical(e.what());
+ }
+ return status() == Status_Ok;
+}
+
bool WalletImpl::close(bool store)
{
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index a82f270e4..9e1fbb40b 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -77,6 +77,10 @@ public:
const std::string &address_string,
const std::string &viewkey_string,
const std::string &spendkey_string = "");
+ bool recoverDeterministicWalletFromSpendKey(const std::string &path,
+ const std::string &password,
+ const std::string &language,
+ const std::string &spendkey_string);
bool recoverFromDevice(const std::string &path,
const std::string &password,
const std::string &device_name);
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index f421fdc05..c8d6bb179 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1323,6 +1323,25 @@ struct WalletManager
return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString);
}
+ /*!
+ * \brief recover deterministic wallet from spend key.
+ * \param path Name of wallet file to be created
+ * \param password Password of wallet file
+ * \param language language
+ * \param nettype Network type
+ * \param restoreHeight restore from start height
+ * \param spendKeyString spend key
+ * \param kdf_rounds Number of rounds for key derivation function
+ * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
+ */
+ virtual Wallet * createDeterministicWalletFromSpendKey(const std::string &path,
+ const std::string &password,
+ const std::string &language,
+ NetworkType nettype,
+ uint64_t restoreHeight,
+ const std::string &spendKeyString,
+ uint64_t kdf_rounds = 1) = 0;
+
/*!
* \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead
* \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index da2056d8a..c200f52ae 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -127,6 +127,22 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
return wallet;
}
+Wallet *WalletManagerImpl::createDeterministicWalletFromSpendKey(const std::string &path,
+ const std::string &password,
+ const std::string &language,
+ NetworkType nettype,
+ uint64_t restoreHeight,
+ const std::string &spendkey_string,
+ uint64_t kdf_rounds)
+{
+ WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
+ if(restoreHeight > 0){
+ wallet->setRefreshFromBlockHeight(restoreHeight);
+ }
+ wallet->recoverDeterministicWalletFromSpendKey(path, password, language, spendkey_string);
+ return wallet;
+}
+
Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
const std::string &password,
NetworkType nettype,
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 28fcd36c9..be3ff8184 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -67,6 +67,13 @@ public:
const std::string &addressString,
const std::string &viewKeyString,
const std::string &spendKeyString = "") override;
+ virtual Wallet * createDeterministicWalletFromSpendKey(const std::string &path,
+ const std::string &password,
+ const std::string &language,
+ NetworkType nettype,
+ uint64_t restoreHeight,
+ const std::string &spendkey_string,
+ uint64_t kdf_rounds) override;
virtual Wallet * createWalletFromDevice(const std::string &path,
const std::string &password,
NetworkType nettype,
--
2.48.1
@@ -0,0 +1,65 @@
From 846d3f60093add6653d9102d841288066fc08311 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Thu, 7 Nov 2024 16:46:24 +0000
Subject: [PATCH 11/14] add monero submodule support
---
CMakeLists.txt | 6 +++---
cmake/CheckLinkerFlag.cmake | 2 +-
src/wallet/wallet_rpc_server.cpp | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f0630ef9b..9406e57b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -226,9 +226,9 @@ function(forbid_undefined_symbols)
cmake_minimum_required(VERSION 3.5)
project(test)
option(EXPECT_SUCCESS "" ON)
-file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
+file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
if (EXPECT_SUCCESS)
- file(APPEND "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
+ file(APPEND "${CMAKE_CURRENT_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
endif()
add_library(l0 SHARED incorrect_source.cpp)
add_library(l1 MODULE incorrect_source.cpp)
@@ -390,7 +390,7 @@ else()
endif()
list(INSERT CMAKE_MODULE_PATH 0
- "${CMAKE_SOURCE_DIR}/cmake")
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if (NOT DEFINED ENV{DEVELOPER_LOCAL_TOOLS})
message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)")
diff --git a/cmake/CheckLinkerFlag.cmake b/cmake/CheckLinkerFlag.cmake
index 7ecf5f610..89fb9d167 100644
--- a/cmake/CheckLinkerFlag.cmake
+++ b/cmake/CheckLinkerFlag.cmake
@@ -6,7 +6,7 @@ macro(CHECK_LINKER_FLAG flag VARIABLE)
message(STATUS "Looking for ${flag} linker flag")
endif()
- set(_cle_source ${CMAKE_SOURCE_DIR}/cmake/CheckLinkerFlag.c)
+ set(_cle_source ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CheckLinkerFlag.c)
set(saved_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_C_FLAGS "${flag}")
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 3188c88db..9fbdb3c05 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -1286,7 +1286,7 @@ namespace tools
{
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, req.source_asset, req.dest_asset, type, 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, req.source_asset, req.dest_asset, type, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, {}, req.subtract_fee_from_outputs);
if (ptx_vector.empty())
{
--
2.48.1
@@ -0,0 +1,104 @@
From 53cc0482e55a39b5dbf2261fea11fcb160778800 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 21 Nov 2024 06:05:03 -0500
Subject: [PATCH 12/14] fix iOS depends build
---
CMakeLists.txt | 4 ----
src/checkpoints/CMakeLists.txt | 6 +++++-
src/cryptonote_basic/CMakeLists.txt | 6 +++++-
src/cryptonote_basic/miner.cpp | 8 ++++----
4 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9406e57b4..1eac121db 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,10 +39,6 @@ include(CheckLibraryExists)
endif()
include(FindPythonInterp)
-if (IOS)
- INCLUDE(CmakeLists_IOS.txt)
-endif()
-
project(salvium)
option (USE_CCACHE "Use ccache if a usable instance is found" ON)
diff --git a/src/checkpoints/CMakeLists.txt b/src/checkpoints/CMakeLists.txt
index 665441f62..841df3256 100644
--- a/src/checkpoints/CMakeLists.txt
+++ b/src/checkpoints/CMakeLists.txt
@@ -28,7 +28,11 @@
if(APPLE)
if(DEPENDS)
- list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
+ if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
+ else()
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
+ endif()
else()
find_library(IOKIT_LIBRARY IOKit)
mark_as_advanced(IOKIT_LIBRARY)
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
index 414936a05..81c81767f 100644
--- a/src/cryptonote_basic/CMakeLists.txt
+++ b/src/cryptonote_basic/CMakeLists.txt
@@ -28,7 +28,11 @@
if(APPLE)
if(DEPENDS)
- list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
+ if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
+ else()
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
+ endif()
else()
find_library(IOKIT_LIBRARY IOKit)
mark_as_advanced(IOKIT_LIBRARY)
diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp
index 71b8f78cc..0f53f024e 100644
--- a/src/cryptonote_basic/miner.cpp
+++ b/src/cryptonote_basic/miner.cpp
@@ -45,7 +45,7 @@
#include "boost/logic/tribool.hpp"
#include <boost/filesystem.hpp>
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
#include <sys/times.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/ps/IOPSKeys.h>
@@ -883,7 +883,7 @@ namespace cryptonote
return true;
- #elif defined(__APPLE__)
+ #elif defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
mach_msg_type_number_t count;
kern_return_t status;
@@ -949,7 +949,7 @@ namespace cryptonote
return true;
}
- #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || defined(__APPLE__) || defined(__FreeBSD__)
+ #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || (defined(__APPLE__) && !defined(TARGET_OS_IPHONE)) || defined(__FreeBSD__)
struct tms tms;
if ( times(&tms) != (clock_t)-1 )
@@ -978,7 +978,7 @@ namespace cryptonote
return boost::logic::tribool(power_status.ACLineStatus != 1);
}
- #elif defined(__APPLE__)
+ #elif defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
#if TARGET_OS_MAC && (!defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)
return boost::logic::tribool(IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited);
--
2.48.1
@@ -0,0 +1,27 @@
From 1eacd30724559749be5adeb31d763f44c3f221f9 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 18 Nov 2024 10:57:37 -0500
Subject: [PATCH 13/14] include locale only when targeting WIN32
---
src/wallet/api/wallet.cpp | 2 ++
1 files changed, 2 insertions(+), 0 deletion(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index d8fe108b4..e3e838b13 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -46,7 +46,9 @@
#include <sstream>
#include <unordered_map>
+#ifdef WIN32
#include <boost/locale.hpp>
+#endif
#include <boost/filesystem.hpp>
#include "bc-ur/src/bc-ur.hpp"
#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
--
2.48.1
@@ -0,0 +1,25 @@
From 2d31234e859bff817d30d91b21d9412375668aae Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Wed, 29 Jan 2025 16:13:28 +0100
Subject: [PATCH 14/14] change earliest fork height message
---
src/wallet/wallet2.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 8720e18b1..69da11d9c 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -12365,7 +12365,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks)
boost::optional<std::string> result = m_node_rpc_proxy.get_height(height);
THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get height");
result = m_node_rpc_proxy.get_earliest_height(version, earliest_height);
- THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height");
+ THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height. Please check your connection and/or switch node you are connected to currently.");
bool close_enough = (int64_t)height >= (int64_t)earliest_height - early_blocks && earliest_height != std::numeric_limits<uint64_t>::max(); // start using the rules that many blocks beforehand
if (close_enough)
--
2.48.1
@@ -0,0 +1,24 @@
From 71cf45cfbd571ec58e8b2a1d408ff74804bf7e1d Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 20 Feb 2025 08:36:28 +0100
Subject: [PATCH] remove trivially_copyable assert
---
contrib/epee/include/span.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h
index 01dc387d6..2ad733a2f 100644
--- a/contrib/epee/include/span.h
+++ b/contrib/epee/include/span.h
@@ -162,7 +162,6 @@ namespace epee
{
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
static_assert(std::is_standard_layout<T>(), "type must have standard layout");
- static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
static_assert(alignof(T) == 1, "type may have padding");
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
}
--
2.48.1
@@ -0,0 +1,42 @@
Subject: [PATCH] ios no randomx JIT
From: julian <julian@cypherstack.com>
---
Index: src/cryptonote_core/cryptonote_tx_utils.cpp
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp (revision f9f0a43b1f5d9ec9f444bafa88073f1ddaf6e344)
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp (date 1752524175340)
@@ -1410,16 +1410,24 @@
bool get_block_longhash(const Blockchain *pbc, const blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, const int miners)
{
- crypto::hash hash;
if (pbc != NULL)
{
+ crypto::hash hash;
const uint64_t seed_height = rx_seedheight(height);
hash = seed_hash ? *seed_hash : pbc->get_pending_block_id_by_height(seed_height);
- } else
- {
- memset(&hash, 0, sizeof(hash)); // only happens when generating genesis block
- }
- rx_slow_hash(hash.data, bd.data(), bd.size(), res.data);
+ rx_slow_hash(hash.data, bd.data(), bd.size(), res.data);
+ } else
+ {
+ // only happens when generating genesis block
+ // Hardcoded genesis for ios compat
+ const char* hex = "4ade63d5ccb8cfae075e8b882514c471f35da95f85dd1b20fdcd6f3a95caabc5";
+ char bytes[32];
+ for (int i = 0; i < 32; i++) {
+ char byte_str[3] = { hex[i * 2], hex[i * 2 + 1], '\0' };
+ bytes[i] = (char)strtol(byte_str, NULL, 16);
+ }
+ memcpy(res.data, bytes, sizeof(bytes));
+ }
return true;
}
@@ -0,0 +1,466 @@
From 7c1d576901a56b7c315b2c54362f7985ff8df753 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 12 Aug 2025 07:09:14 -0400
Subject: [PATCH] serialize cache to JSON
---
src/wallet/CMakeLists.txt | 1 +
src/wallet/api/wallet.cpp | 5 +
src/wallet/api/wallet.h | 2 +
src/wallet/api/wallet2_api.h | 3 +
src/wallet/wallet2.h | 6 +
src/wallet/wallet_cache_to_json.cpp | 368 ++++++++++++++++++++++++++++
6 files changed, 385 insertions(+)
create mode 100644 src/wallet/wallet_cache_to_json.cpp
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index b163212b7..196ad671f 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -38,6 +38,7 @@ set(wallet_sources
message_store.cpp
message_transporter.cpp
wallet_rpc_payments.cpp
+ wallet_cache_to_json.cpp
tx_builder.cpp
)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 7d7d0f922..effb6e719 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -3475,6 +3475,11 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command
#endif
}
+std::string WalletImpl::serializeCacheToJson() const
+{
+ return std::string(m_wallet->serialize_cache_to_json());
+}
+
YieldInfo * WalletImpl::getYieldInfo()
{
auto yi = new YieldInfoImpl(*this);
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index bfe81c590..98c03b9c1 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -335,6 +335,8 @@ private:
bool getWaitsForDeviceSend();
bool getWaitsForDeviceReceive();
+
+ virtual std::string serializeCacheToJson() const override;
};
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index fcb8187d4..3d11929f9 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1217,7 +1217,10 @@ struct Wallet
static void setDeviceReceivedData(unsigned char* data, size_t len);
static void setDeviceSendData(unsigned char* data, size_t len);
static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
+
+ //! serialize wallet cache to JSON
+ virtual std::string serializeCacheToJson() const = 0;
//! get yield information
virtual YieldInfo * getYieldInfo() = 0;
};
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 4f324c238..bc4abc672 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1544,6 +1544,12 @@ private:
FIELD(m_return_output_info)
END_SERIALIZE()
+ /*!
+ * \brief Serialize wallet cache fields to JSON
+ * \return const char* pointing to JSON string containing all cache fields
+ */
+ const char* serialize_cache_to_json() const;
+
/*!
* \brief Check if wallet keys and bin files exist
* \param file_path Wallet file path
diff --git a/src/wallet/wallet_cache_to_json.cpp b/src/wallet/wallet_cache_to_json.cpp
new file mode 100644
index 000000000..64687a7a6
--- /dev/null
+++ b/src/wallet/wallet_cache_to_json.cpp
@@ -0,0 +1,368 @@
+#include "wallet2.h"
+#include "serialization/binary_archive.h"
+#include "serialization/json_archive.h"
+#include "serialization/serialization.h"
+#include <sstream>
+#include <iomanip>
+
+namespace tools
+{
+
+static void write_escaped_json_string(std::ostream& os, const std::string& str)
+{
+ for (char c : str) {
+ switch (c) {
+ case '"': os << "\\\""; break;
+ case '\\': os << "\\\\"; break;
+ case '\n': os << "\\n"; break;
+ case '\r': os << "\\r"; break;
+ case '\t': os << "\\t"; break;
+ case '\b': os << "\\b"; break;
+ case '\f': os << "\\f"; break;
+ default: os << c; break;
+ }
+ }
+}
+
+static void post_process_json(std::string& json)
+{
+ // ": ," --> ": null,"
+ size_t pos = 0;
+ while ((pos = json.find(": ,", pos)) != std::string::npos) {
+ json.replace(pos, 3, ": null,");
+ pos += 7;
+ }
+
+ // ": }" --> ": null}"
+ pos = 0;
+ while ((pos = json.find(": }", pos)) != std::string::npos) {
+ json.replace(pos, 3, ": null}");
+ pos += 7;
+ }
+
+ // ": ]" --> ": null]"
+ pos = 0;
+ while ((pos = json.find(": ]", pos)) != std::string::npos) {
+ json.replace(pos, 3, ": null]");
+ pos += 7;
+ }
+
+ // "key": number"hexstring" --> "key": "numberhexstring"
+ pos = 0;
+ while (pos < json.length()) {
+ size_t colon_pos = json.find(": ", pos);
+ if (colon_pos == std::string::npos) break;
+
+ size_t value_start = colon_pos + 2;
+ if (value_start >= json.length()) break;
+
+ if (std::isdigit(json[value_start])) {
+ size_t quote_pos = json.find('"', value_start);
+ if (quote_pos != std::string::npos && quote_pos < json.find_first_of(",}]", value_start)) {
+ size_t closing_quote = json.find('"', quote_pos + 1);
+ if (closing_quote != std::string::npos && closing_quote < json.find_first_of(",}]", value_start)) {
+ std::string digits;
+ size_t digit_end = value_start;
+ while (digit_end < quote_pos && std::isdigit(json[digit_end])) {
+ digits += json[digit_end];
+ digit_end++;
+ }
+
+ if (digit_end == quote_pos && !digits.empty()) {
+ std::string hex_part = json.substr(quote_pos + 1, closing_quote - quote_pos - 1);
+
+ std::string replacement = "\"" + digits + hex_part + "\"";
+ json.replace(value_start, closing_quote - value_start + 1, replacement);
+ pos = value_start + replacement.length();
+ continue;
+ }
+ }
+ }
+ }
+
+ pos = colon_pos + 1;
+ }
+}
+
+const char* wallet2::serialize_cache_to_json() const
+{
+ static std::string json_result;
+
+ try
+ {
+ std::stringstream oss;
+ json_archive<true> ar(oss, true); // true for pretty printing
+
+ ar.begin_object();
+
+ // MAGIC_FIELD("monero wallet cache")
+ std::string magic = "monero wallet cache";
+ ar.tag("magic");
+ ar.serialize_blob((void*)magic.data(), magic.size());
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize magic field\"}";
+ return json_result.c_str();
+ }
+
+ // VERSION_FIELD(2)
+ uint32_t version = 2;
+ ar.tag("version");
+ ar.serialize_varint(version);
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize version field\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_blockchain) - hashchain type, has serialization support
+ ar.tag("m_blockchain");
+ if (!::serialization::serialize(ar, const_cast<hashchain&>(m_blockchain))) {
+ json_result = "{\"error\":\"Failed to serialize m_blockchain\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_transfers) - transfer_container (std::vector<transfer_details>)
+ ar.tag("m_transfers");
+ if (!::serialization::serialize(ar, const_cast<transfer_container&>(m_transfers))) {
+ json_result = "{\"error\":\"Failed to serialize m_transfers\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_account_public_address) - cryptonote::account_public_address
+ ar.tag("m_account_public_address");
+ if (!::serialization::serialize(ar, const_cast<cryptonote::account_public_address&>(m_account_public_address))) {
+ json_result = "{\"error\":\"Failed to serialize m_account_public_address\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_key_images) - serializable_unordered_map<crypto::key_image, size_t>
+ ar.tag("m_key_images");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::key_image, size_t>&>(m_key_images))) {
+ json_result = "{\"error\":\"Failed to serialize m_key_images\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_unconfirmed_txs) - serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>
+ ar.tag("m_unconfirmed_txs");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>&>(m_unconfirmed_txs))) {
+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_txs\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_payments) - payment_container (serializable_unordered_multimap<crypto::hash, payment_details>)
+ ar.tag("m_payments");
+ if (!::serialization::serialize(ar, const_cast<payment_container&>(m_payments))) {
+ json_result = "{\"error\":\"Failed to serialize m_payments\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_tx_keys) - serializable_unordered_map<crypto::hash, crypto::secret_key>
+ ar.tag("m_tx_keys");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, crypto::secret_key>&>(m_tx_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_keys\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_confirmed_txs) - serializable_unordered_map<crypto::hash, confirmed_transfer_details>
+ ar.tag("m_confirmed_txs");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, confirmed_transfer_details>&>(m_confirmed_txs))) {
+ json_result = "{\"error\":\"Failed to serialize m_confirmed_txs\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_tx_notes) - serializable_unordered_map<crypto::hash, std::string>
+ ar.tag("m_tx_notes");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_notes))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_notes\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_unconfirmed_payments) - serializable_unordered_multimap<crypto::hash, pool_payment_details>
+ ar.tag("m_unconfirmed_payments");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_multimap<crypto::hash, pool_payment_details>&>(m_unconfirmed_payments))) {
+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_payments\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_pub_keys) - serializable_unordered_map<crypto::public_key, size_t>
+ ar.tag("m_pub_keys");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, size_t>&>(m_pub_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_pub_keys\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_address_book) - std::vector<tools::wallet2::address_book_row>
+ ar.tag("m_address_book");
+ if (!::serialization::serialize(ar, const_cast<std::vector<tools::wallet2::address_book_row>&>(m_address_book))) {
+ json_result = "{\"error\":\"Failed to serialize m_address_book\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_scanned_pool_txs[0]) - std::unordered_set<crypto::hash>
+ ar.tag("m_scanned_pool_txs_0");
+ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[0]))) {
+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[0]\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_scanned_pool_txs[1]) - std::unordered_set<crypto::hash>
+ ar.tag("m_scanned_pool_txs_1");
+ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[1]))) {
+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[1]\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_subaddresses) - serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>
+ ar.tag("m_subaddresses");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>&>(m_subaddresses))) {
+ json_result = "{\"error\":\"Failed to serialize m_subaddresses\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_subaddress_labels) - std::vector<std::vector<std::string>> - manual JSON serialization
+ oss << ", \n \"m_subaddress_labels\": [";
+ for (size_t i = 0; i < m_subaddress_labels.size(); ++i) {
+ if (i > 0) oss << ", ";
+ oss << "\n [";
+ for (size_t j = 0; j < m_subaddress_labels[i].size(); ++j) {
+ if (j > 0) oss << ", ";
+ oss << "\"";
+ write_escaped_json_string(oss, m_subaddress_labels[i][j]);
+ oss << "\"";
+ }
+ oss << "]";
+ }
+ oss << "\n ]";
+
+ // FIELD(m_additional_tx_keys) - serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>
+ ar.tag("m_additional_tx_keys");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>&>(m_additional_tx_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_additional_tx_keys\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_attributes) - serializable_unordered_map<std::string, std::string> - manual JSON serialization
+ oss << ", \n \"m_attributes\": {";
+ bool first_attr = true;
+ for (const auto& attr : m_attributes) {
+ if (!first_attr) oss << ", ";
+ first_attr = false;
+ oss << "\n \"";
+ write_escaped_json_string(oss, attr.first);
+ oss << "\": \"";
+ write_escaped_json_string(oss, attr.second);
+ oss << "\"";
+ }
+ oss << "\n }";
+
+ // FIELD(m_account_tags) - std::pair<serializable_map<std::string, std::string>, std::vector<std::string>> - manual JSON serialization
+ oss << ", \n \"m_account_tags\": {";
+ oss << "\n \"tags_map\": {";
+ bool first_tag = true;
+ for (const auto& tag : m_account_tags.first) {
+ if (!first_tag) oss << ", ";
+ first_tag = false;
+ oss << "\n \"";
+ write_escaped_json_string(oss, tag.first);
+ oss << "\": \"";
+ write_escaped_json_string(oss, tag.second);
+ oss << "\"";
+ }
+ oss << "\n },";
+ oss << "\n \"account_list\": [";
+ for (size_t i = 0; i < m_account_tags.second.size(); ++i) {
+ if (i > 0) oss << ", ";
+ oss << "\n \"";
+ write_escaped_json_string(oss, m_account_tags.second[i]);
+ oss << "\"";
+ }
+ oss << "\n ]";
+ oss << "\n }";
+
+ // FIELD(m_ring_history_saved) - bool
+ // ar.tag("m_ring_history_saved");
+ // ar.serialize_blob(&m_ring_history_saved, sizeof(m_ring_history_saved));
+ // if (!ar.good()) {
+ // json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}";
+ // return json_result.c_str();
+ // }
+
+ // FIELD(m_last_block_reward) - uint64_t
+ ar.tag("m_last_block_reward");
+ ar.serialize_int(m_last_block_reward);
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize m_last_block_reward\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_tx_device) - serializable_unordered_map<crypto::hash, std::string>
+ ar.tag("m_tx_device");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_device))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_device\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_device_last_key_image_sync) - uint64_t
+ ar.tag("m_device_last_key_image_sync");
+ ar.serialize_int(m_device_last_key_image_sync);
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to serialize m_device_last_key_image_sync\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_cold_key_images) - serializable_unordered_map<crypto::public_key, crypto::key_image>
+ ar.tag("m_cold_key_images");
+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, crypto::key_image>&>(m_cold_key_images))) {
+ json_result = "{\"error\":\"Failed to serialize m_cold_key_images\"}";
+ return json_result.c_str();
+ }
+
+ // FIELD(m_rpc_client_secret_key) - crypto::secret_key
+ // ar.tag("m_rpc_client_secret_key");
+ // ar.serialize_blob(&m_rpc_client_secret_key, sizeof(m_rpc_client_secret_key));
+ // if (!ar.good()) {
+ // json_result = "{\"error\":\"Failed to serialize m_rpc_client_secret_key\"}";
+ // return json_result.c_str();
+ // }
+
+ // Version-dependent fields
+ if (version >= 1) {
+ // FIELD(m_has_ever_refreshed_from_node) - bool
+ // ar.tag("m_has_ever_refreshed_from_node");
+ // ar.serialize_blob(&m_has_ever_refreshed_from_node, sizeof(m_has_ever_refreshed_from_node));
+ // if (!ar.good()) {
+ // json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}";
+ // return json_result.c_str();
+ // }
+ }
+
+ if (version >= 2) {
+ // FIELD(m_background_sync_data) - background_sync_data_t
+ ar.tag("m_background_sync_data");
+ if (!::serialization::serialize(ar, const_cast<background_sync_data_t&>(m_background_sync_data))) {
+ json_result = "{\"error\":\"Failed to serialize m_background_sync_data\"}";
+ return json_result.c_str();
+ }
+ }
+
+ ar.end_object();
+
+ if (!ar.good()) {
+ json_result = "{\"error\":\"Failed to finalize JSON serialization\"}";
+ return json_result.c_str();
+ }
+
+ json_result = oss.str();
+
+ // Post-process to fix malformed JSON
+ post_process_json(json_result);
+
+ return json_result.c_str();
+ }
+ catch (const std::exception& e)
+ {
+ json_result = "{\"error\":\"Failed to serialize wallet cache: " + std::string(e.what()) + "\"}";
+ return json_result.c_str();
+ }
+}
+
+} // namespace tools
\ No newline at end of file
--
2.50.1
@@ -21,23 +21,38 @@ Subject: [PATCH 08/15] add dummy device for ledger
create mode 100644 src/device/device_io_dummy.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88335ee9d..86000f811 100644
index c73b813d8..ce5ef4bab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -693,8 +693,12 @@ include_directories(${LMDB_INCLUDE})
@@ -692,16 +692,21 @@ include_directories(${LMDB_INCLUDE})
include_directories(${LIBUNWIND_INCLUDE})
link_directories(${LIBUNWIND_LIBRARY_DIRS})
-# Final setup for hid
-if (HIDAPI_FOUND)
- message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
- add_definitions(-DHAVE_HIDAPI)
- include_directories(${HIDAPI_INCLUDE_DIR})
- link_directories(${LIBHIDAPI_LIBRARY_DIRS})
+if (HIDAPI_DUMMY)
+ add_definitions(-DHIDAPI_DUMMY)
+endif()
else()
- message(STATUS "Could not find HIDAPI")
+ # Final setup for hid
+ if (HIDAPI_FOUND)
+ message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
+ add_definitions(-DHAVE_HIDAPI)
+ include_directories(${HIDAPI_INCLUDE_DIR})
+ link_directories(${LIBHIDAPI_LIBRARY_DIRS})
+ else()
+ message(STATUS "Could not find HIDAPI")
+ endif()
endif()
+
# Final setup for hid
-if (HIDAPI_FOUND)
+if (HIDAPI_FOUND)
message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
add_definitions(-DHAVE_HIDAPI)
include_directories(${HIDAPI_INCLUDE_DIR})
# Trezor support check
include(CheckTrezor)
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
index e4f1159b5..14d398f87 100644
--- a/src/device/CMakeLists.txt
@@ -235,13 +250,13 @@ index 000000000..edb4beea3
+ MDEBUG("exchange(): waitsForDeviceSend");
+ // NOTE: waitsForDeviceSend should be changed by external code
+ while (waitsForDeviceSend) {
+ usleep(1000);
+ std::this_thread::sleep_for(std::chrono::microseconds(1000));
+ MDEBUG("exchange(): waitsForDeviceSend (still)");
+ }
+
+ MDEBUG("exchange(): waitsForDeviceReceive");
+ while (waitsForDeviceReceive) {
+ usleep(1000);
+ std::this_thread::sleep_for(std::chrono::microseconds(1000));
+ MDEBUG("exchange(): waitsForDeviceReceive (still)");
+ }
+
+25
View File
@@ -0,0 +1,25 @@
From 31ef09596a9d8d547905577823ff52d33e10a3d2 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 1 Apr 2025 11:30:45 +0200
Subject: [PATCH] pr-9880
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5938be6..1c47285 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -216,7 +216,7 @@ function(forbid_undefined_symbols)
file(MAKE_DIRECTORY "${TEST_PROJECT}")
file(WRITE "${TEST_PROJECT}/CMakeLists.txt"
[=[
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.5)
project(test)
option(EXPECT_SUCCESS "" ON)
file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
--
2.49.0
@@ -0,0 +1,28 @@
From e488eaa7397d388cee6e914e10d23790f005f6f7 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 10 Apr 2025 13:28:06 +0200
Subject: [PATCH] fix: unary_function -> __unary_function
---
src/cryptonote_basic/cryptonote_basic_impl.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h
index b423573..a9aef7a 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.h
+++ b/src/cryptonote_basic/cryptonote_basic_impl.h
@@ -40,7 +40,11 @@ namespace cryptonote {
/* */
/************************************************************************/
template<class t_array>
+#ifdef __APPLE__
+ struct array_hasher: std::__unary_function<t_array&, std::size_t>
+#else
struct array_hasher: std::unary_function<t_array&, std::size_t>
+#endif
{
std::size_t operator()(const t_array& val) const
{
--
2.49.0
Submodule
+1
Submodule salvium added at 119a7fab57
+179
View File
@@ -0,0 +1,179 @@
cmake_minimum_required(VERSION 3.5)
project(wallet2_api_c)
message(STATUS ABI_INFO = ${HOST_ABI})
set(MD_LIBRARY "")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-lto")
if(${HOST_ABI} STREQUAL "x86_64-w64-mingw32")
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_LINKER "x86_64-w64-mingw32-ld")
set(TARGET "x86_64-w64-mingw32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lssp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lssp")
elseif(${HOST_ABI} STREQUAL "i686-w64-mingw32")
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_LINKER "i686-w64-mingw32-ld")
set(TARGET "i686-w64-mingw32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lssp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lssp")
elseif(${HOST_ABI} STREQUAL "host-apple-ios" OR
${HOST_ABI} STREQUAL "aarch64-apple-ios")
set(CMAKE_SYSTEM_NAME iOS)
elseif(${HOST_ABI} STREQUAL "host-apple-darwin" OR
${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR
${HOST_ABI} STREQUAL "aarch64-host-apple-darwin")
set(CMAKE_SYSTEM_NAME Darwin)
endif()
if (${HOST_ABI} STREQUAL "host-apple-darwin" OR
${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR
${HOST_ABI} STREQUAL "aarch64-host-apple-darwin")
EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE )
if (NOT ${ARCHITECTURE} STREQUAL arm64)
set(CMAKE_OSX_ARCHITECTURES x86_64)
endif()
endif()
if(${HOST_ABI} STREQUAL "x86_64-linux-android" OR
${HOST_ABI} STREQUAL "i686-linux-android" OR
${HOST_ABI} STREQUAL "aarch64-linux-android" OR
${HOST_ABI} STREQUAL "armv7a-linux-androideabi")
add_link_options(-stdlib=libc++ -static-libstdc++)
set(EXTRA_LIBS_ANDROID log)
endif()
add_library( wallet2_api_c
SHARED
src/main/cpp/helpers.cpp
src/main/cpp/wallet2_api_c.cpp )
if(${HOST_ABI} STREQUAL "x86_64-linux-android" OR
${HOST_ABI} STREQUAL "i686-linux-android" OR
${HOST_ABI} STREQUAL "aarch64-linux-android" OR
${HOST_ABI} STREQUAL "armv7a-linux-androideabi")
set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,-z,noexecstack")
endif()
if(${HOST_ABI} STREQUAL "x86_64-linux-gnu" OR
${HOST_ABI} STREQUAL "i686-linux-gnu" OR
${HOST_ABI} STREQUAL "aarch64-linux-gnu" OR
${HOST_ABI} STREQUAL "armv7a-linux-gnu")
set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,-z,noexecstack")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set(MONERO_DIR ${CMAKE_SOURCE_DIR}/../${MONERO_FLAVOR})
set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../contrib/depends/${HOST_ABI})
if (${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin11")
set(EXTRA_LIBS_APPLE "-framework IOKit" "-framework CoreFoundation" "-framework Cocoa" hidapi)
# set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks")
elseif(${HOST_ABI} STREQUAL "host-apple-darwin" OR
${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR
${HOST_ABI} STREQUAL "aarch64-host-apple-darwin")
set(EXTRA_LIBS_APPLE "-framework IOKit" "-framework CoreFoundation" "-framework Cocoa" apple_nghttp2)
elseif(${HOST_ABI} STREQUAL "host-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-ios" OR ${HOST_ABI} STREQUAL "arm64-apple-ios" OR ${HOST_ABI} STREQUAL "arm64-apple-iossimulator" OR ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
set(EXTRA_LIBS_APPLE "-framework IOKit" "-framework CoreFoundation" iconv )
endif()
if(${HOST_ABI} STREQUAL "x86_64-w64-mingw32" OR ${HOST_ABI} STREQUAL "i686-w64-mingw32")
target_link_options(wallet2_api_c PRIVATE -static-libgcc -static-libstdc++)
endif()
if(${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin11" OR ${HOST_ABI} STREQUAL "host-apple-darwin" OR ${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "aarch64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "host-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-ios" OR ${HOST_ABI} STREQUAL "arm64-apple-iossimulator" OR ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
set_target_properties(wallet2_api_c PROPERTIES SUFFIX ".dylib")
set_target_properties(wallet2_api_c PROPERTIES NO_SONAME 1)
endif()
if (${MONERO_FLAVOR} STREQUAL "monero")
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_MONERO)
set(BCUR_ENABLED bc-ur)
elseif(${MONERO_FLAVOR} STREQUAL "wownero")
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_WOWNERO)
elseif(${MONERO_FLAVOR} STREQUAL "zano")
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_ZANO)
elseif(${MONERO_FLAVOR} STREQUAL "salvium")
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_SALVIUM)
set(BCUR_ENABLED bc-ur)
endif()
if(NOT ${HOST_ABI} STREQUAL "x86_64-apple-darwin11" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-darwin11" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "x86_64-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "host-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "aarch64-host-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "host-apple-ios" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-ios" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-iossimulator" AND NOT ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,--exclude-libs,ALL")
endif()
if (${MONERO_FLAVOR} STREQUAL "zano")
include_directories(
${CMAKE_SOURCE_DIR}/build/${HOST_ABI}/zano_build/contrib/zlib
)
endif()
add_subdirectory("${CMAKE_SOURCE_DIR}/../${MONERO_FLAVOR}" ${CMAKE_BINARY_DIR}/${MONERO_FLAVOR}_build EXCLUDE_FROM_ALL)
if(${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin11" OR ${HOST_ABI} STREQUAL "x86_64-apple-darwin" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin" OR ${HOST_ABI} STREQUAL "host-apple-darwin" OR ${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "aarch64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "host-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-iossimulator" OR ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
if (${MONERO_FLAVOR} STREQUAL "monero")
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/monero_libwallet2_api_c.exp)
elseif(${MONERO_FLAVOR} STREQUAL "wownero")
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/wownero_libwallet2_api_c.exp)
elseif(${MONERO_FLAVOR} STREQUAL "zano")
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/zano_libwallet2_api_c.exp)
elseif(${MONERO_FLAVOR} STREQUAL "salvium")
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/salvium_libwallet2_api_c.exp)
endif()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${EXPORTED_SYMBOLS_FILE}")
set_target_properties(${TARGET} PROPERTIES LINK_DEPENDS ${EXPORTED_SYMBOLS_FILE})
endif()
if (${MONERO_FLAVOR} STREQUAL "monero")
set(WALLET_TARGETS wallet_api ${wallet_api_LIB_DEPENDS}) # wallet_api_LIB_DEPENDS
elseif(${MONERO_FLAVOR} STREQUAL "wownero")
set(WALLET_TARGETS wallet_api ${wallet_api_LIB_DEPENDS}) # wallet_api_LIB_DEPENDS
elseif(${MONERO_FLAVOR} STREQUAL "zano")
find_package(Boost 1.71 REQUIRED COMPONENTS system filesystem thread timer date_time chrono regex serialization atomic program_options)
find_package(OpenSSL REQUIRED)
set(WALLET_TARGETS
wallet
general
tor-connect
crypto
currency_core
common
zlibstatic
${Boost_LIBRARIES}
${OpenSSL_LIBRARIES})
elseif(${MONERO_FLAVOR} STREQUAL "salvium")
set(WALLET_TARGETS wallet_api ${wallet_api_LIB_DEPENDS}) # wallet_api_LIB_DEPENDS
endif()
if(${MONERO_FLAVOR} STREQUAL "wownero")
add_subdirectory(wownero-seed EXCLUDE_FROM_ALL)
set(EXTRA_LIBS_WOWNEROSEED wownero-seed)
endif()
#get_cmake_property(_variableNames VARIABLES)
#list (SORT _variableNames)
#foreach (_variableName ${_variableNames})
# message(STATUS "${_variableName}=${${_variableName}}")
#endforeach()
#message(SEND_ERROR "${Boost_LIBRARIES}")
#message(SEND_ERROR "${WALLET_TARGETS}
# ${EXTRA_LIBS_WOWNEROSEED}
# ${EXTRA_LIBS_ANDROID}")
target_link_libraries( wallet2_api_c
${WALLET_TARGETS}
${EXTRA_LIBS_WOWNEROSEED}
${EXTRA_LIBS_ANDROID}
)
@@ -0,0 +1,319 @@
_SALVIUM_PendingTransaction_status
_SALVIUM_PendingTransaction_errorString
_SALVIUM_PendingTransaction_commit
_SALVIUM_PendingTransaction_commitUR
_SALVIUM_PendingTransaction_amount
_SALVIUM_PendingTransaction_dust
_SALVIUM_PendingTransaction_fee
_SALVIUM_PendingTransaction_txid
_SALVIUM_PendingTransaction_txCount
_SALVIUM_PendingTransaction_subaddrAccount
_SALVIUM_PendingTransaction_subaddrIndices
_SALVIUM_PendingTransaction_multisigSignData
_SALVIUM_PendingTransaction_signMultisigTx
_SALVIUM_PendingTransaction_signersKeys
_SALVIUM_PendingTransaction_hex
_SALVIUM_UnsignedTransaction_status
_SALVIUM_UnsignedTransaction_errorString
_SALVIUM_UnsignedTransaction_amount
_SALVIUM_UnsignedTransaction_fee
_SALVIUM_UnsignedTransaction_mixin
_SALVIUM_UnsignedTransaction_confirmationMessage
_SALVIUM_UnsignedTransaction_paymentId
_SALVIUM_UnsignedTransaction_recipientAddress
_SALVIUM_UnsignedTransaction_minMixinCount
_SALVIUM_UnsignedTransaction_txCount
_SALVIUM_UnsignedTransaction_sign
_SALVIUM_UnsignedTransaction_signUR
_SALVIUM_TransactionInfo_asset
_SALVIUM_TransactionInfo_direction
_SALVIUM_TransactionInfo_isPending
_SALVIUM_TransactionInfo_isFailed
_SALVIUM_TransactionInfo_isCoinbase
_SALVIUM_TransactionInfo_type
_SALVIUM_TransactionInfo_amount
_SALVIUM_TransactionInfo_fee
_SALVIUM_TransactionInfo_blockHeight
_SALVIUM_TransactionInfo_description
_SALVIUM_TransactionInfo_subaddrIndex
_SALVIUM_TransactionInfo_subaddrAccount
_SALVIUM_TransactionInfo_label
_SALVIUM_TransactionInfo_confirmations
_SALVIUM_TransactionInfo_unlockTime
_SALVIUM_TransactionInfo_hash
_SALVIUM_TransactionInfo_timestamp
_SALVIUM_TransactionInfo_paymentId
_SALVIUM_TransactionInfo_transfers_count
_SALVIUM_TransactionInfo_transfers_amount
_SALVIUM_TransactionInfo_transfers_address
_SALVIUM_TransactionHistory_count
_SALVIUM_TransactionHistory_transaction
_SALVIUM_TransactionHistory_transactionById
_SALVIUM_TransactionHistory_refresh
_SALVIUM_TransactionHistory_setTxNote
_SALVIUM_AddressBookRow_extra
_SALVIUM_AddressBookRow_getAddress
_SALVIUM_AddressBookRow_getDescription
_SALVIUM_AddressBookRow_getPaymentId
_SALVIUM_AddressBookRow_getRowId
_SALVIUM_AddressBook_getAll_size
_SALVIUM_AddressBook_getAll_byIndex
_SALVIUM_AddressBook_addRow
_SALVIUM_AddressBook_deleteRow
_SALVIUM_AddressBook_setDescription
_SALVIUM_AddressBook_refresh
_SALVIUM_AddressBook_errorString
_SALVIUM_AddressBook_errorCode
_SALVIUM_AddressBook_lookupPaymentID
_SALVIUM_CoinsInfo_blockHeight
_SALVIUM_CoinsInfo_hash
_SALVIUM_CoinsInfo_internalOutputIndex
_SALVIUM_CoinsInfo_globalOutputIndex
_SALVIUM_CoinsInfo_spent
_SALVIUM_CoinsInfo_frozen
_SALVIUM_CoinsInfo_spentHeight
_SALVIUM_CoinsInfo_amount
_SALVIUM_CoinsInfo_type
_SALVIUM_CoinsInfo_rct
_SALVIUM_CoinsInfo_keyImageKnown
_SALVIUM_CoinsInfo_pkIndex
_SALVIUM_CoinsInfo_subaddrIndex
_SALVIUM_CoinsInfo_subaddrAccount
_SALVIUM_CoinsInfo_address
_SALVIUM_CoinsInfo_addressLabel
_SALVIUM_CoinsInfo_keyImage
_SALVIUM_CoinsInfo_unlockTime
_SALVIUM_CoinsInfo_unlocked
_SALVIUM_CoinsInfo_pubKey
_SALVIUM_CoinsInfo_coinbase
_SALVIUM_CoinsInfo_description
_SALVIUM_CoinsInfo_asset
_SALVIUM_Coins_count
_SALVIUM_Coins_coin
_SALVIUM_Coins_getAll_size
_SALVIUM_Coins_getAll_byIndex
_SALVIUM_Coins_refresh
_SALVIUM_Coins_setFrozenByPublicKey
_SALVIUM_Coins_setFrozen
_SALVIUM_Coins_thaw
_SALVIUM_Coins_thawByPublicKey
_SALVIUM_Coins_isTransferUnlocked
_SALVIUM_Coins_setDescription
_SALVIUM_SubaddressRow_extra
_SALVIUM_SubaddressRow_getAddress
_SALVIUM_SubaddressRow_getLabel
_SALVIUM_SubaddressRow_getRowId
_SALVIUM_Subaddress_getAll_size
_SALVIUM_Subaddress_getAll_byIndex
_SALVIUM_Subaddress_addRow
_SALVIUM_Subaddress_setLabel
_SALVIUM_Subaddress_refresh
_SALVIUM_SubaddressAccountRow_extra
_SALVIUM_SubaddressAccountRow_getAddress
_SALVIUM_SubaddressAccountRow_getLabel
_SALVIUM_SubaddressAccountRow_getBalance
_SALVIUM_SubaddressAccountRow_getUnlockedBalance
_SALVIUM_SubaddressAccountRow_getRowId
_SALVIUM_SubaddressAccount_getAll_size
_SALVIUM_SubaddressAccount_getAll_byIndex
_SALVIUM_SubaddressAccount_addRow
_SALVIUM_SubaddressAccount_setLabel
_SALVIUM_SubaddressAccount_refresh
_SALVIUM_MultisigState_isMultisig
_SALVIUM_MultisigState_isReady
_SALVIUM_MultisigState_threshold
_SALVIUM_MultisigState_total
_SALVIUM_DeviceProgress_progress
_SALVIUM_DeviceProgress_indeterminate
_SALVIUM_Wallet_seed
_SALVIUM_Wallet_setLedgerCallback
_SALVIUM_Wallet_serializeCacheToJson
_SALVIUM_Wallet_getSeedLanguage
_SALVIUM_Wallet_setSeedLanguage
_SALVIUM_Wallet_status
_SALVIUM_Wallet_errorString
_SALVIUM_Wallet_setPassword
_SALVIUM_Wallet_getPassword
_SALVIUM_Wallet_setDevicePin
_SALVIUM_Wallet_setDevicePassphrase
_SALVIUM_Wallet_address
_SALVIUM_Wallet_path
_SALVIUM_Wallet_nettype
_SALVIUM_Wallet_useForkRules
_SALVIUM_Wallet_integratedAddress
_SALVIUM_Wallet_secretViewKey
_SALVIUM_Wallet_publicViewKey
_SALVIUM_Wallet_secretSpendKey
_SALVIUM_Wallet_publicSpendKey
_SALVIUM_Wallet_publicMultisigSignerKey
_SALVIUM_Wallet_secretViewBalance
_SALVIUM_Wallet_secretProveSpend
_SALVIUM_Wallet_secretGenerateAddress
_SALVIUM_Wallet_secretGenerateImage
_SALVIUM_Wallet_stop
_SALVIUM_Wallet_store
_SALVIUM_Wallet_filename
_SALVIUM_Wallet_keysFilename
_SALVIUM_Wallet_init
_SALVIUM_Wallet_createWatchOnly
_SALVIUM_Wallet_setRefreshFromBlockHeight
_SALVIUM_Wallet_getRefreshFromBlockHeight
_SALVIUM_Wallet_setRecoveringFromSeed
_SALVIUM_Wallet_setRecoveringFromDevice
_SALVIUM_Wallet_setSubaddressLookahead
_SALVIUM_Wallet_connectToDaemon
_SALVIUM_Wallet_connected
_SALVIUM_Wallet_setTrustedDaemon
_SALVIUM_Wallet_trustedDaemon
_SALVIUM_Wallet_setProxy
_SALVIUM_Wallet_balance
_SALVIUM_Wallet_unlockedBalance
_SALVIUM_Wallet_viewOnlyBalance
_SALVIUM_Wallet_watchOnly
_SALVIUM_Wallet_isDeterministic
_SALVIUM_Wallet_blockChainHeight
_SALVIUM_Wallet_approximateBlockChainHeight
_SALVIUM_Wallet_estimateBlockChainHeight
_SALVIUM_Wallet_daemonBlockChainHeight
_SALVIUM_Wallet_daemonBlockChainTargetHeight
_SALVIUM_Wallet_synchronized
_SALVIUM_Wallet_displayAmount
_SALVIUM_Wallet_amountFromString
_SALVIUM_Wallet_amountFromDouble
_SALVIUM_Wallet_genPaymentId
_SALVIUM_Wallet_paymentIdValid
_SALVIUM_Wallet_addressValid
_SALVIUM_Wallet_keyValid
_SALVIUM_Wallet_keyValid_error
_SALVIUM_Wallet_paymentIdFromAddress
_SALVIUM_Wallet_maximumAllowedAmount
_SALVIUM_Wallet_init3
_SALVIUM_Wallet_getPolyseed
_SALVIUM_Wallet_createPolyseed
_SALVIUM_Wallet_startRefresh
_SALVIUM_Wallet_pauseRefresh
_SALVIUM_Wallet_refresh
_SALVIUM_Wallet_refreshAsync
_SALVIUM_Wallet_rescanBlockchain
_SALVIUM_Wallet_rescanBlockchainAsync
_SALVIUM_Wallet_setAutoRefreshInterval
_SALVIUM_Wallet_autoRefreshInterval
_SALVIUM_Wallet_addSubaddressAccount
_SALVIUM_Wallet_numSubaddressAccounts
_SALVIUM_Wallet_numSubaddresses
_SALVIUM_Wallet_addSubaddress
_SALVIUM_Wallet_getSubaddressLabel
_SALVIUM_Wallet_setSubaddressLabel
_SALVIUM_Wallet_multisig
_SALVIUM_Wallet_getMultisigInfo
_SALVIUM_Wallet_makeMultisig
_SALVIUM_Wallet_exchangeMultisigKeys
_SALVIUM_Wallet_exportMultisigImages
_SALVIUM_Wallet_importMultisigImages
_SALVIUM_Wallet_hasMultisigPartialKeyImages
_SALVIUM_Wallet_restoreMultisigTransaction
_SALVIUM_Wallet_createTransactionMultDest
_SALVIUM_Wallet_createTransaction
_SALVIUM_Wallet_createStakeTransaction
_SALVIUM_Wallet_loadUnsignedTx
_SALVIUM_Wallet_loadUnsignedTxUR
_SALVIUM_Wallet_submitTransaction
_SALVIUM_Wallet_submitTransactionUR
_SALVIUM_Wallet_hasUnknownKeyImages
_SALVIUM_Wallet_exportKeyImages
_SALVIUM_Wallet_exportKeyImagesUR
_SALVIUM_Wallet_importKeyImages
_SALVIUM_Wallet_importKeyImagesUR
_SALVIUM_Wallet_exportOutputs
_SALVIUM_Wallet_exportOutputsUR
_SALVIUM_Wallet_importOutputs
_SALVIUM_Wallet_importOutputsUR
_SALVIUM_Wallet_setupBackgroundSync
_SALVIUM_Wallet_getBackgroundSyncType
_SALVIUM_Wallet_startBackgroundSync
_SALVIUM_Wallet_stopBackgroundSync
_SALVIUM_Wallet_isBackgroundSyncing
_SALVIUM_Wallet_isBackgroundWallet
_SALVIUM_Wallet_history
_SALVIUM_Wallet_addressBook
_SALVIUM_Wallet_coins
_SALVIUM_Wallet_subaddress
_SALVIUM_Wallet_subaddressAccount
_SALVIUM_Wallet_defaultMixin
_SALVIUM_Wallet_setDefaultMixin
_SALVIUM_Wallet_setCacheAttribute
_SALVIUM_Wallet_getCacheAttribute
_SALVIUM_Wallet_setUserNote
_SALVIUM_Wallet_getUserNote
_SALVIUM_Wallet_getTxKey
_SALVIUM_Wallet_signMessage
_SALVIUM_Wallet_verifySignedMessage
_SALVIUM_Wallet_rescanSpent
_SALVIUM_Wallet_setOffline
_SALVIUM_Wallet_isOffline
_SALVIUM_Wallet_segregatePreForkOutputs
_SALVIUM_Wallet_segregationHeight
_SALVIUM_Wallet_keyReuseMitigation2
_SALVIUM_Wallet_lockKeysFile
_SALVIUM_Wallet_unlockKeysFile
_SALVIUM_Wallet_isKeysFileLocked
_SALVIUM_Wallet_getDeviceType
_SALVIUM_Wallet_coldKeyImageSync
_SALVIUM_Wallet_deviceShowAddress
_SALVIUM_Wallet_reconnectDevice
_SALVIUM_Wallet_getBytesReceived
_SALVIUM_Wallet_getBytesSent
_SALVIUM_Wallet_getStateIsConnected
_SALVIUM_Wallet_getSendToDevice
_SALVIUM_Wallet_getSendToDeviceLength
_SALVIUM_Wallet_getReceivedFromDevice
_SALVIUM_Wallet_getReceivedFromDeviceLength
_SALVIUM_Wallet_getWaitsForDeviceSend
_SALVIUM_Wallet_getWaitsForDeviceReceive
_SALVIUM_Wallet_setDeviceReceivedData
_SALVIUM_Wallet_setDeviceSendData
_SALVIUM_WalletManager_createWallet
_SALVIUM_WalletManager_openWallet
_SALVIUM_WalletManager_recoveryWallet
_SALVIUM_WalletManager_createWalletFromKeys
_SALVIUM_WalletManager_createDeterministicWalletFromSpendKey
_SALVIUM_WalletManager_createWalletFromDevice
_SALVIUM_WalletManager_createWalletFromPolyseed
_SALVIUM_WalletManager_closeWallet
_SALVIUM_WalletManager_walletExists
_SALVIUM_WalletManager_verifyWalletPassword
_SALVIUM_WalletManager_queryWalletDevice
_SALVIUM_WalletManager_findWallets
_SALVIUM_WalletManager_errorString
_SALVIUM_WalletManager_setDaemonAddress
_SALVIUM_WalletManager_blockchainHeight
_SALVIUM_WalletManager_blockchainTargetHeight
_SALVIUM_WalletManager_networkDifficulty
_SALVIUM_WalletManager_miningHashRate
_SALVIUM_WalletManager_blockTarget
_SALVIUM_WalletManager_isMining
_SALVIUM_WalletManager_startMining
_SALVIUM_WalletManager_stopMining
_SALVIUM_WalletManager_resolveOpenAlias
_SALVIUM_WalletManager_setProxy
_SALVIUM_WalletManagerFactory_getWalletManager
_SALVIUM_WalletManagerFactory_setLogLevel
_SALVIUM_WalletManagerFactory_setLogCategories
_SALVIUM_DEBUG_test0
_SALVIUM_DEBUG_test1
_SALVIUM_DEBUG_test2
_SALVIUM_DEBUG_test3
_SALVIUM_DEBUG_test4
_SALVIUM_DEBUG_test5
_SALVIUM_DEBUG_test5_std
_SALVIUM_DEBUG_isPointerNull
_SALVIUM_cw_getWalletListener
_SALVIUM_cw_WalletListener_resetNeedToRefresh
_SALVIUM_cw_WalletListener_isNeedToRefresh
_SALVIUM_cw_WalletListener_isNewTransactionExist
_SALVIUM_cw_WalletListener_resetIsNewTransactionExist
_SALVIUM_cw_WalletListener_height
_SALVIUM_free
_SALVIUM_checksum_wallet2_api_c_h
_SALVIUM_checksum_wallet2_api_c_cpp
_SALVIUM_checksum_wallet2_api_c_exp
@@ -0,0 +1,265 @@
#include <inttypes.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <vector>
#include <string>
#include "helpers.hpp"
#include <set>
#include <sstream>
#include <cstring>
#include <thread>
#include <iostream>
#include <stdexcept>
#ifdef __ANDROID__
#include <android/log.h>
#define LOG_TAG "moneroc"
#define BUFFER_SIZE 1024*32
static int stdoutToLogcat(const char *buf, int size) {
__android_log_write(ANDROID_LOG_INFO, LOG_TAG, buf);
return size;
}
static int stderrToLogcat(const char *buf, int size) {
__android_log_write(ANDROID_LOG_ERROR, LOG_TAG, buf);
return size;
}
void redirectStdoutThread(int pipe_stdout[2]) {
char bufferStdout[BUFFER_SIZE];
while (true) {
int read_size = read(pipe_stdout[0], bufferStdout, sizeof(bufferStdout) - 1);
if (read_size > 0) {
bufferStdout[read_size] = '\0';
stdoutToLogcat(bufferStdout, read_size);
}
}
}
void redirectStderrThread(int pipe_stderr[2]) {
char bufferStderr[BUFFER_SIZE];
while (true) {
int read_size = read(pipe_stderr[0], bufferStderr, sizeof(bufferStderr) - 1);
if (read_size > 0) {
bufferStderr[read_size] = '\0';
stderrToLogcat(bufferStderr, read_size);
}
}
}
void setupAndroidLogging() {
static int pfdStdout[2];
static int pfdStderr[2];
pipe(pfdStdout);
pipe(pfdStderr);
dup2(pfdStdout[1], STDOUT_FILENO);
dup2(pfdStderr[1], STDERR_FILENO);
std::thread stdoutThread(redirectStdoutThread, pfdStdout);
std::thread stderrThread(redirectStderrThread, pfdStderr);
stdoutThread.detach();
stderrThread.detach();
}
#endif // __ANDROID__
__attribute__((constructor))
void library_init() {
#ifdef __ANDROID__
setupAndroidLogging(); // This will now run automatically when the library is loaded
#endif
}
const char* vectorToString(const std::vector<std::string>& vec, const std::string separator) {
// Check if the vector is empty
if (vec.empty()) {
return "";
}
// Concatenate all strings in the vector
std::string result;
for (size_t i = 0; i < vec.size() - 1; ++i) {
result += vec[i];
result += separator;
}
result += vec.back(); // Append the last string without the separator
std::string str = result;
const std::string::size_type size = str.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, str.c_str(), size + 1);
return buffer;
}
const char* vectorToString(const std::vector<uint32_t>& vec, const std::string separator) {
// Calculate the size needed for the result string
size_t size = 0;
for (size_t i = 0; i < vec.size(); ++i) {
// Calculate the number of digits in each element
size += snprintf(nullptr, 0, "%u", vec[i]);
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
size += separator.size(); // comma and space
}
}
// Allocate memory for the result string
char* result = static_cast<char*>(malloc(size + 1));
if (result == nullptr) {
// Handle memory allocation failure
return nullptr;
}
// Fill in the result string
char* current = result;
for (size_t i = 0; i < vec.size(); ++i) {
// Convert each element to string and copy to the result string
int written = snprintf(current, size + 1, "%u", vec[i]);
current += written;
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
strcpy(current, separator.c_str());
current += separator.size();
}
}
return result;
}
const char* vectorToString(const std::vector<uint64_t>& vec, const std::string separator) {
// Calculate the size needed for the result string
size_t size = 0;
for (size_t i = 0; i < vec.size(); ++i) {
// Calculate the number of digits in each element
size += snprintf(nullptr, 0, "%llu", vec[i]);
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
size += separator.size(); // comma and space
}
}
// Allocate memory for the result string
char* result = static_cast<char*>(malloc(size + 1));
if (result == nullptr) {
// Handle memory allocation failure
return nullptr;
}
// Fill in the result string
char* current = result;
for (size_t i = 0; i < vec.size(); ++i) {
// Convert each element to string and copy to the result string
int written = snprintf(current, size + 1, "%llu", vec[i]);
current += written;
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
strcpy(current, separator.c_str());
current += separator.size();
}
}
return result;
}
const char* vectorToString(const std::vector<std::set<uint32_t>>& vec, const std::string separator) {
// Check if the vector is empty
if (vec.empty()) {
return "";
}
// Use a stringstream to concatenate sets with commas and individual elements with spaces
std::ostringstream oss;
oss << "{";
for (auto it = vec.begin(); it != vec.end(); ++it) {
if (it != vec.begin()) {
oss << separator;
}
oss << "{";
for (auto setIt = it->begin(); setIt != it->end(); ++setIt) {
if (setIt != it->begin()) {
oss << separator;
}
oss << *setIt;
}
oss << "}";
}
oss << "}";
std::string str = oss.str();
const std::string::size_type size = str.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, str.c_str(), size + 1);
return buffer;
}
// Function to convert std::set<uint32_t> to a string
const char* vectorToString(const std::set<uint32_t>& intSet, const std::string separator) {
// Check if the set is empty
if (intSet.empty()) {
return "";
}
// Use a stringstream to concatenate elements with commas
std::ostringstream oss;
auto it = intSet.begin();
oss << *it;
for (++it; it != intSet.end(); ++it) {
oss << ", " << *it;
}
std::string str = oss.str();
const std::string::size_type size = str.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, str.c_str(), size + 1);
return buffer;
}
std::set<std::string> splitString(const std::string& str, const std::string& delim) {
std::set<std::string> tokens;
if (str.empty()) return tokens;
size_t pos = 0;
std::string token;
std::string content = str; // Copy of str so we can safely erase content
while ((pos = content.find(delim)) != std::string::npos) {
token = content.substr(0, pos);
tokens.insert(token);
content.erase(0, pos + delim.length());
}
tokens.insert(content); // Inserting the last token
return tokens;
}
std::vector<std::string> splitStringVector(const std::string& str, const std::string& delim) {
std::vector<std::string> tokens;
if (str.empty()) return tokens;
size_t pos = 0;
std::string content = str; // Copy of str so we can safely erase content
while ((pos = content.find(delim)) != std::string::npos) {
tokens.push_back(content.substr(0, pos));
content.erase(0, pos + delim.length());
}
tokens.push_back(content); // Inserting the last token
return tokens;
}
std::vector<uint64_t> splitStringUint(const std::string& str, const std::string& delim) {
std::vector<uint64_t> tokens;
if (str.empty()) return tokens;
size_t pos = 0;
std::string token;
std::string content = str; // Copy of str so we can safely erase content
while ((pos = content.find(delim)) != std::string::npos) {
token = content.substr(0, pos);
tokens.push_back(std::stoull(token)); // Convert string to uint64_t and push to vector
content.erase(0, pos + delim.length());
}
tokens.push_back(std::stoull(content)); // Inserting the last token
return tokens;
}
@@ -0,0 +1,32 @@
#include <vector>
#include <string>
#include <set>
#include <sstream>
#include <cstdlib>
#include <iostream>
// Debug macros
#define DEBUG_START() \
try {
#define DEBUG_END() \
} catch (const std::exception &e) { \
std::cerr << "Exception caught in function: " << __FUNCTION__ \
<< " at " << __FILE__ << ":" << __LINE__ << std::endl \
<< "Message: " << e.what() << std::endl; \
std::abort(); \
} catch (...) { \
std::cerr << "Unknown exception caught in function: " << __FUNCTION__ \
<< " at " << __FILE__ << ":" << __LINE__ << std::endl; \
std::abort(); \
}
const char* vectorToString(const std::vector<std::string>& vec, const std::string separator);
const char* vectorToString(const std::vector<uint32_t>& vec, const std::string separator);
const char* vectorToString(const std::vector<uint64_t>& vec, const std::string separator);
const char* vectorToString(const std::vector<std::set<uint32_t>>& vec, const std::string separator);
const char* vectorToString(const std::set<uint32_t>& intSet, const std::string separator);
std::set<std::string> splitString(const std::string& str, const std::string& delim);
std::vector<uint64_t> splitStringUint(const std::string& str, const std::string& delim);
std::vector<std::string> splitStringVector(const std::string& str, const std::string& delim);
@@ -0,0 +1,6 @@
#ifndef MONEROC_CHECKSUMS
#define MONEROC_CHECKSUMS
const char * SALVIUM_wallet2_api_c_h_sha256 = "93ad4f6247f0b89c17218766c960e956047b0e8032c3db2b791842d576279330";
const char * SALVIUM_wallet2_api_c_cpp_sha256 = "2d52bbe50a6db8c1bd68ce4be288c28319f35f48c6d093a3d67d888c8e4b3230-45404ecc719b916c217938f9e82ad352a4068d12";
const char * SALVIUM_wallet2_api_c_exp_sha256 = "f7ab584f1271f4d533980f403597a1d9e50bced85c233ca2b17c77f4a94ed3bc";
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -31,7 +31,7 @@ export function getFileInfo(
return fileInfo;
}
async function sha256(buffer: Uint8Array): Promise<string> {
async function sha256(buffer: Uint8Array<ArrayBuffer>): Promise<string> {
const hashed = new Uint8Array(await crypto.subtle.digest("SHA-256", buffer));
return Array.from(hashed).map((i) => i.toString(16).padStart(2, "0")).join("");
}
@@ -72,7 +72,7 @@ async function tryToDownloadFile(
async function validFileExists(filePath: string, fileInfo: FileInfo): Promise<boolean> {
const [mainFileName] = fileInfo.names;
let fileBuffer: Uint8Array;
let fileBuffer: Uint8Array<ArrayBuffer>;
try {
fileBuffer = await Deno.readFile(filePath);
} catch {